KMAnnotationSelectLinkViewController.swift 28 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675
  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. // if mouseBox == self.linkUrlBox {
  112. // KMProductCompareWC.shared.orientation = false
  113. // let winC = KMProductCompareWC.shared
  114. // winC.kEventName = "Reading_WebsiteLink_BuyNow"
  115. // } else if mouseBox == self.linkEmailBox {
  116. // KMProductCompareWC.shared.orientation = false
  117. // let winC = KMProductCompareWC.shared
  118. // winC.kEventName = "Reading_EmailLink_BuyNow"
  119. // }
  120. //
  121. // KMProductCompareWC.shared.orientation = false
  122. // KMProductCompareWC.shared.showWindow(nil)
  123. // return
  124. // }
  125. // }
  126. if KMMemberInfo.shared.isMemberAllFunction == false {
  127. if mouseBox == self.linkUrlBox || mouseBox == self.linkEmailBox {
  128. if mouseBox == self.linkUrlBox {
  129. let winC = KMProductCompareWC.shared
  130. winC.kEventName = "Reading_WebsiteLink_BuyNow"
  131. } else if mouseBox == self.linkEmailBox {
  132. let winC = KMProductCompareWC.shared
  133. winC.kEventName = "Reading_EmailLink_BuyNow"
  134. }
  135. KMMemberInfo.shared.advancedFunctionUsage()
  136. return
  137. }
  138. }
  139. if self.mouseDownBox == mouseBox {
  140. return
  141. }
  142. var mouseDownInt = 0
  143. if mouseBox == self.linkPageBox {
  144. self.inputPageTextField.stringValue = ""
  145. self.linkType = .page
  146. mouseDownInt = 0
  147. } else if mouseBox == self.linkUrlBox {
  148. self.inputUrlTextField.stringValue = ""
  149. self.linkType = .url
  150. mouseDownInt = 1
  151. } else if mouseBox == self.linkEmailBox {
  152. self.inputUrlTextField.stringValue = ""
  153. self.linkType = .email
  154. mouseDownInt = 2
  155. }
  156. UserDefaults.standard.set(mouseDownInt, forKey: "kmLinkSelectIndex")
  157. UserDefaults.standard.synchronize()
  158. self.mouseDownBox = mouseBox
  159. }
  160. }
  161. }
  162. isGo = true
  163. pageLabel.stringValue = NSLocalizedString("Page Number:", comment: "")
  164. pageLabel.textColor = KMAppearance.Layout.h1Color()
  165. allPageLabel.textColor = KMAppearance.Layout.h2Color()
  166. goButton.title = NSLocalizedString("Go", comment: "")
  167. goButton.setTitleColor(KMAppearance.Layout.w0Color())
  168. goButton.wantsLayer = true
  169. goButton.layer?.backgroundColor = KMAppearance.Interactive.m0Color().cgColor
  170. goButton.setTitleColor(KMAppearance.Layout.w0Color())
  171. inputPageTextField.backgroundColor = KMAppearance.Layout.l1Color()
  172. inputUrlTextField.backgroundColor = KMAppearance.Layout.l1Color()
  173. inputPageTextField.wantsLayer = true
  174. inputUrlTextField.wantsLayer = true
  175. inputPageTextField.layer?.borderWidth = 1.0
  176. inputUrlTextField.layer?.borderWidth = 1.0
  177. inputPageTextField.layer?.borderColor = KMAppearance.Interactive.a0Color().cgColor
  178. inputUrlTextField.layer?.borderColor = KMAppearance.Interactive.a0Color().cgColor
  179. inputPageTextField.layer?.cornerRadius = 1.0
  180. inputUrlTextField.layer?.cornerRadius = 1.0
  181. // inputUrlTextField.inputContext?.allowedInputSourceLocales = [NSAllRomanInputSourcesLocaleIdentifier]
  182. let cell = self.inputUrlTextField.cell as? NSTextFieldCell
  183. cell?.allowedInputSourceLocales = [NSAllRomanInputSourcesLocaleIdentifier]
  184. if let annotationURL = annotation?.url() {
  185. var urlString = annotationURL.fileURL.absoluteString
  186. if annotationURL.hasPrefix("mailto:") {
  187. linkType = .email
  188. mouseDownBox = linkEmailBox
  189. } else {
  190. linkType = .url
  191. mouseDownBox = linkUrlBox
  192. }
  193. } else {
  194. linkType = .page
  195. mouseDownBox = linkPageBox
  196. }
  197. }
  198. override func viewDidAppear() {
  199. super.viewDidAppear()
  200. inputPageTextField.delegate = self
  201. inputUrlTextField.delegate = self
  202. if let url = annotation?.url {
  203. inputUrlTextField.becomeFirstResponder()
  204. } else {
  205. inputPageTextField.becomeFirstResponder()
  206. }
  207. }
  208. // MARK: Get & Set
  209. var linkType: KMAnnotationLinkType {
  210. set {
  211. _linkType = newValue
  212. contentBoxLayoutConstraint.constant = 46.0
  213. switch _linkType {
  214. case .page:
  215. contentBoxLayoutConstraint.constant = 24.0
  216. createLinkPageView()
  217. contentBox.contentView = pageView
  218. inputPageTextField.becomeFirstResponder()
  219. case .url:
  220. createLinkURLView()
  221. contentBox.contentView = urlView
  222. inputUrlTextField.becomeFirstResponder()
  223. case .email:
  224. createLinkEmailView()
  225. contentBox.contentView = urlView
  226. inputUrlTextField.becomeFirstResponder()
  227. default:
  228. break
  229. }
  230. }
  231. get {
  232. return _linkType
  233. }
  234. }
  235. weak var pdfview: CPDFListView? {
  236. set {
  237. _pdfview = newValue
  238. // startPage = _pdfview?.currentPage().label
  239. self.startPage = "\((self._pdfview?.currentPage().pageIndex() ?? 1)+1)"
  240. }
  241. get {
  242. return _pdfview
  243. }
  244. }
  245. var annotations: [CPDFAnnotation]? {
  246. set {
  247. _annotations = newValue
  248. annotation = _annotations?.first as? CPDFLinkAnnotation
  249. }
  250. get {
  251. return _annotations
  252. }
  253. }
  254. // MARK: Private
  255. func getURLViewHeightLayoutConstraint() -> CGFloat {
  256. return urlLabel.frame.height + 4 + inputUrlTextField.frame.height
  257. }
  258. func getPageViewHeightLayoutConstraint() -> CGFloat {
  259. return inputPageTextField.frame.height
  260. }
  261. func createLinkPageView() {
  262. annotationLinkSelectBox(linkPageBox)
  263. inputPageTextField.formatter = NumberFormatter()
  264. if pdfDocument!.pageCount > 1 {
  265. inputPageTextField.placeholderString = "1-\(pdfDocument!.pageCount)"
  266. } else {
  267. inputPageTextField.placeholderString = "1"
  268. }
  269. allPageLabel.stringValue = "/\(pdfDocument!.pageCount)"
  270. if let destination = annotation?.destination() {
  271. if let page = destination.page() {
  272. let pageIndex = page.document?.index(for: page) ?? 0
  273. inputPageTextField.stringValue = "\(pageIndex + 1)"
  274. pageRecord = "\(pageIndex + 1)"
  275. }
  276. }
  277. if inputPageTextField.stringValue.isEmpty {
  278. inputPageTextField.stringValue = pageRecord!
  279. }
  280. let pageFloat = Float(inputPageTextField.stringValue) ?? 0
  281. if pageFloat < 1 || UInt(pageFloat) > self.pdfDocument!.pageCount {
  282. goButton.layer!.backgroundColor = KMAppearance.Interactive.m0Color().withAlphaComponent(0.4).cgColor
  283. goButton.setTitleColor(KMAppearance.Layout.w0Color().withAlphaComponent(0.4))
  284. } else {
  285. goButton.layer!.backgroundColor = KMAppearance.Interactive.m0Color().cgColor
  286. goButton.setTitleColor(KMAppearance.Layout.w0Color())
  287. }
  288. }
  289. func createLinkURLView() {
  290. annotationLinkSelectBox(linkUrlBox)
  291. urlLabel.stringValue = NSLocalizedString("URL:", comment: "")
  292. urlLabel.textColor = KMAppearance.Layout.h1Color()
  293. inputUrlTextField.placeholderString = "https://www.pdfreaderpro.com"
  294. if let annotationURL = annotation?.url() {
  295. var urlString = annotationURL.fileURL.absoluteString
  296. if !annotationURL.hasPrefix("mailto:") {
  297. if urlString.hasPrefix("http://") {
  298. urlString = String(urlString.suffix(from: urlString.index(urlString.startIndex, offsetBy: 7)))
  299. } else if urlString.hasPrefix("https://") {
  300. urlString = String(urlString.suffix(from: urlString.index(urlString.startIndex, offsetBy: 8)))
  301. }
  302. inputUrlTextField.stringValue = annotationURL//urlString
  303. urlRecord = urlString
  304. }else {
  305. inputUrlTextField.stringValue = ""
  306. }
  307. }else {
  308. inputUrlTextField.stringValue = ""
  309. }
  310. if urlRecord!.isEmpty {
  311. goButton.layer!.backgroundColor = KMAppearance.Interactive.m0Color().withAlphaComponent(0.4).cgColor
  312. goButton.setTitleColor(KMAppearance.Layout.w0Color().withAlphaComponent(0.4))
  313. } else {
  314. goButton.layer!.backgroundColor = KMAppearance.Interactive.m0Color().cgColor
  315. goButton.setTitleColor(KMAppearance.Layout.w0Color())
  316. }
  317. }
  318. func createLinkEmailView() {
  319. annotationLinkSelectBox(linkEmailBox)
  320. urlLabel.stringValue = NSLocalizedString("Email:", comment: "")
  321. urlLabel.textColor = KMAppearance.Layout.h1Color()
  322. inputUrlTextField.placeholderString = "support@pdfreaderpro.com"
  323. if let annotationURL = annotation?.url() {
  324. // if let urlString = annotation?.url().fileURL.absoluteString, urlString.hasPrefix("mailto:") {
  325. // let trimmedString = String(urlString.suffix(from: urlString.index(urlString.startIndex, offsetBy: 7)))
  326. // inputUrlTextField.stringValue = trimmedString
  327. // emailRecord = trimmedString
  328. // }
  329. var urlString = annotationURL.fileURL.absoluteString
  330. if annotationURL.hasPrefix("mailto:") {
  331. let trimmedString = String(urlString.suffix(from: urlString.index(urlString.startIndex, offsetBy: 7)))
  332. inputUrlTextField.stringValue = annotationURL
  333. emailRecord = trimmedString
  334. }
  335. }else {
  336. inputUrlTextField.stringValue = ""
  337. }
  338. if emailRecord!.count > 0 {
  339. goButton.layer?.backgroundColor = KMAppearance.Interactive.m0Color().cgColor
  340. goButton.setTitleColor(KMAppearance.Layout.w0Color())
  341. } else {
  342. goButton.layer?.backgroundColor = KMAppearance.Interactive.m0Color().withAlphaComponent(0.4).cgColor
  343. goButton.setTitleColor(KMAppearance.Layout.w0Color().withAlphaComponent(0.4))
  344. }
  345. }
  346. func isValidateEmail(_ email: String) -> Bool {
  347. let emailRegex = "[A-Z0-9a-z._%+-]+@[A-Za-z0-9.-]+\\.[A-Za-z]{2,4}"
  348. let emailTest = NSPredicate(format: "SELF MATCHES %@", emailRegex)
  349. return emailTest.evaluate(with: email)
  350. }
  351. func judgeWebURL(_ urlString: String) -> String {
  352. var modifiedURLString = urlString
  353. if !modifiedURLString.hasPrefix("http://") && !modifiedURLString.hasPrefix("https://") {
  354. if modifiedURLString.hasPrefix("smb://") {
  355. } else {
  356. modifiedURLString = "https://" + modifiedURLString
  357. }
  358. }
  359. if modifiedURLString == "https://" {
  360. modifiedURLString = ""
  361. }
  362. return modifiedURLString
  363. }
  364. func judgeEmailURL(_ urlString: String) -> String {
  365. var modifiedURLString = urlString
  366. if !modifiedURLString.hasPrefix("mailto:") {
  367. modifiedURLString = "mailto:" + modifiedURLString
  368. }
  369. if modifiedURLString == "mailto:" {
  370. modifiedURLString = ""
  371. }
  372. return modifiedURLString
  373. }
  374. func annotationLinkSelectBox(_ box: KMBox) {
  375. if box.isEqual(linkPageBox) {
  376. linkPageBox.fillColor = KMAppearance.Status.selColor()
  377. linkUrlBox.fillColor = NSColor.clear
  378. linkEmailBox.fillColor = NSColor.clear
  379. linkPageImageView.image = NSImage(named: "KMImageNameUXIconPropertybarLinkPageSel")
  380. linkUrlImageView.image = NSImage(named: "KMImageNameUXIconPropertybarLinkUrl")
  381. linkEmailImageView.image = NSImage(named: "KMImageNameUXIconPropertybarLinkEmail")
  382. linkPageLabel.textColor = KMAppearance.Layout.h0Color()
  383. linkUrlLabel.textColor = KMAppearance.Layout.h1Color()
  384. linkEmailLabel.textColor = KMAppearance.Layout.h1Color()
  385. if let dexPage = Int(pageRecord!), pageRecord!.count >= 1 {
  386. if dexPage < 1 || dexPage > self.pdfDocument!.pageCount {
  387. errorLabel.isHidden = false
  388. } else {
  389. errorLabel.isHidden = true
  390. }
  391. }
  392. } else if box.isEqual(linkUrlBox) {
  393. linkUrlBox.fillColor = KMAppearance.Status.selColor()
  394. linkPageBox.fillColor = NSColor.clear
  395. linkEmailBox.fillColor = NSColor.clear
  396. linkPageImageView.image = NSImage(named: "KMImageNameUXIconPropertybarLinkPage")
  397. linkUrlImageView.image = NSImage(named: "KMImageNameUXIconPropertybarLinkUrlSel")
  398. linkEmailImageView.image = NSImage(named: "KMImageNameUXIconPropertybarLinkEmail")
  399. linkUrlLabel.textColor = KMAppearance.Layout.h0Color()
  400. linkPageLabel.textColor = KMAppearance.Layout.h1Color()
  401. linkEmailLabel.textColor = KMAppearance.Layout.h1Color()
  402. errorLabel.isHidden = true
  403. } else if box.isEqual(linkEmailBox) {
  404. linkEmailBox.fillColor = KMAppearance.Status.selColor()
  405. linkPageBox.fillColor = NSColor.clear
  406. linkUrlBox.fillColor = NSColor.clear
  407. linkPageImageView.image = NSImage(named: "KMImageNameUXIconPropertybarLinkPage")
  408. linkUrlImageView.image = NSImage(named: "KMImageNameUXIconPropertybarLinkUrl")
  409. linkEmailImageView.image = NSImage(named: "KMImageNameUXIconPropertybarLinkEmailSel")
  410. linkEmailLabel.textColor = KMAppearance.Layout.h0Color()
  411. linkPageLabel.textColor = KMAppearance.Layout.h1Color()
  412. linkUrlLabel.textColor = KMAppearance.Layout.h1Color()
  413. errorLabel.isHidden = true
  414. }
  415. }
  416. // MARK: Public Method
  417. // MARK: Action
  418. @IBAction func goButtonAction(_ sender: Any) {
  419. if linkType == .page {
  420. guard let pageFloat = Float(inputPageTextField.stringValue) else {
  421. return
  422. }
  423. if pageFloat < 1 || UInt(pageFloat) > self.pdfDocument!.pageCount {
  424. return
  425. }
  426. } else if linkType == .url {
  427. if urlRecord!.count <= 0 {
  428. return
  429. }
  430. } else if linkType == .email {
  431. if emailRecord!.count <= 0 {
  432. return
  433. }
  434. }
  435. goButton.layer?.backgroundColor = KMAppearance.Interactive.m0Color().cgColor
  436. Timer.scheduledTimer(timeInterval: 0.1, target: self, selector: #selector(timered(_:)), userInfo: nil, repeats: false)
  437. switch linkType {
  438. case .page:
  439. guard let activeAnnotation = pdfview?.activeAnnotation as? CPDFLinkAnnotation else { return }
  440. activeAnnotation.setURL(nil)
  441. let dexPage: Int
  442. if isGo {
  443. isGo = false
  444. dexPage = Int(inputPageTextField.stringValue) ?? 0
  445. goButton.title = NSLocalizedString("Go Back", comment: "Tool tip message")
  446. } else {
  447. isGo = true
  448. dexPage = Int(startPage!) ?? 0
  449. goButton.title = NSLocalizedString("Go", comment: "")
  450. }
  451. goButton.setTitleColor(KMAppearance.Layout.w0Color())
  452. guard dexPage >= 1 && dexPage <= pdfDocument!.pageCount else {
  453. let alert = NSAlert()
  454. alert.alertStyle = .critical
  455. alert.messageText = NSLocalizedString("Invalid page range or the page number is out of range. Please try again.", comment: "")
  456. alert.runModal()
  457. return
  458. }
  459. let goPage = Int(inputPageTextField.stringValue) ?? 0
  460. if let page = pdfDocument!.page(at: UInt(goPage - 1)) {
  461. let bounds = page.bounds(for: .cropBox)
  462. let destination = CPDFDestination(page: page, at: NSPoint(x: 0, y: bounds.size.height))
  463. (pdfview?.activeAnnotation as! CPDFLinkAnnotation as CPDFLinkAnnotation).setDestination(destination)
  464. pdfview!.needsDisplay = true
  465. }
  466. if let page = pdfDocument!.page(at: UInt(dexPage - 1)) {
  467. let bounds = page.bounds(for: .cropBox)
  468. let dest = CPDFDestination(page: page, at: NSPoint(x: 0, y: bounds.size.height))
  469. pdfview!.go(to: dest)
  470. }
  471. case .url:
  472. guard let activeAnnotation = pdfview?.activeAnnotation as? CPDFLinkAnnotation else { return }
  473. activeAnnotation.setDestination(nil)
  474. let linkUrlPath = judgeWebURL(inputUrlTextField.stringValue)
  475. activeAnnotation.setURL(linkUrlPath)
  476. pdfview!.needsDisplay = true
  477. if let url = (pdfview?.activeAnnotation as! CPDFLinkAnnotation).url() {
  478. if let data = URL(string: url) {
  479. NSWorkspace.shared.open(data)
  480. }
  481. }
  482. case .email:
  483. guard let activeAnnotation = pdfview?.activeAnnotation as? CPDFLinkAnnotation else { return }
  484. activeAnnotation.setDestination(nil)
  485. if !isValidateEmail(inputUrlTextField.stringValue) {
  486. let alert = NSAlert()
  487. alert.alertStyle = .critical
  488. alert.messageText = NSLocalizedString("Invalid Email. Please try again.", comment: "")
  489. alert.runModal()
  490. return
  491. }
  492. let linkUrlPath = judgeEmailURL(inputUrlTextField.stringValue)
  493. activeAnnotation.setURL(linkUrlPath)
  494. pdfview!.needsDisplay = true
  495. if let url = (pdfview?.activeAnnotation as! CPDFLinkAnnotation).url() {
  496. NSWorkspace.shared.open(URL(string: url)!)
  497. }
  498. default:
  499. break
  500. }
  501. }
  502. @objc func timered(_ timer: Timer) {
  503. goButton.layer!.backgroundColor = KMAppearance.Interactive.m0Color().cgColor
  504. goButton.setTitleColor(KMAppearance.Layout.w0Color())
  505. }
  506. // MARK: NSTextFieldDelegate Methods
  507. @objc func controlTextDidChange(_ notification: Notification) {
  508. guard let textField = notification.object as? NSTextField else { return }
  509. var string = textField.stringValue.replacingOccurrences(of: "\n", with: "")
  510. string = string.replacingOccurrences(of: "\r", with: "")
  511. textField.stringValue = string
  512. if mouseDownBox!.isEqual(linkPageBox) {
  513. pageRecord = string
  514. } else if mouseDownBox!.isEqual(linkUrlBox) {
  515. urlRecord = string
  516. } else if mouseDownBox!.isEqual(linkEmailBox) {
  517. emailRecord = string
  518. }
  519. if linkType == KMAnnotationLinkType.page {
  520. (pdfview?.activeAnnotation as? CPDFLinkAnnotation)?.setURL(nil)
  521. let dexPage = Int(inputPageTextField.stringValue) ?? 0
  522. if (dexPage < 1 || dexPage > pdfDocument!.pageCount) && pageRecord!.count > 0 {
  523. goButton.layer!.backgroundColor = KMAppearance.Interactive.m0Color().withAlphaComponent(0.4).cgColor
  524. goButton.setTitleColor(KMAppearance.Layout.w0Color().withAlphaComponent(0.4))
  525. errorLabel.isHidden = false
  526. return
  527. } else if pageRecord!.count > 0 {
  528. goButton.layer!.backgroundColor = KMAppearance.Interactive.m0Color().cgColor
  529. goButton.setTitleColor(KMAppearance.Layout.w0Color())
  530. errorLabel.isHidden = true
  531. } else {
  532. goButton.layer!.backgroundColor = KMAppearance.Interactive.m0Color().withAlphaComponent(0.4).cgColor
  533. goButton.setTitleColor(KMAppearance.Layout.w0Color().withAlphaComponent(0.4))
  534. }
  535. let pageIndex = UInt(max(dexPage-1, 0))
  536. let page = pdfDocument!.page(at: pageIndex)
  537. let bounds = page?.bounds(for: .cropBox) ?? .zero
  538. let destination = CPDFDestination(page: page, at: NSMakePoint(0, bounds.size.height))
  539. (pdfview?.activeAnnotation as? CPDFLinkAnnotation)?.setDestination(destination)
  540. pdfview?.setNeedsDisplay(pdfview!.visibleRect)
  541. } else if linkType == KMAnnotationLinkType.url {
  542. (pdfview?.activeAnnotation as? CPDFLinkAnnotation)?.setDestination(nil)
  543. let linkUrlPath: String = judgeWebURL(urlRecord!)
  544. if linkUrlPath == "" {
  545. (pdfview?.activeAnnotation as? CPDFLinkAnnotation)?.setURL(nil)
  546. } else {
  547. (pdfview?.activeAnnotation as? CPDFLinkAnnotation)?.setURL(linkUrlPath)
  548. }
  549. if urlRecord!.count > 0 {
  550. goButton.layer!.backgroundColor = KMAppearance.Interactive.m0Color().cgColor
  551. goButton.setTitleColor(KMAppearance.Layout.w0Color())
  552. } else {
  553. goButton.layer!.backgroundColor = KMAppearance.Interactive.m0Color().withAlphaComponent(0.4).cgColor
  554. goButton.setTitleColor(KMAppearance.Layout.w0Color().withAlphaComponent(0.4))
  555. }
  556. pdfview!.setNeedsDisplay(pdfview!.visibleRect)
  557. } else if linkType == KMAnnotationLinkType.email {
  558. (pdfview?.activeAnnotation as? CPDFLinkAnnotation)?.setDestination(nil)
  559. let linkUrlPath: String = judgeEmailURL(emailRecord!)
  560. if linkUrlPath == "" {
  561. (pdfview?.activeAnnotation as? CPDFLinkAnnotation)?.setURL(nil)
  562. } else {
  563. (pdfview?.activeAnnotation as? CPDFLinkAnnotation)?.setURL(linkUrlPath)
  564. }
  565. if emailRecord!.count > 0 {
  566. goButton.layer!.backgroundColor = KMAppearance.Interactive.m0Color().cgColor
  567. goButton.setTitleColor(KMAppearance.Layout.w0Color())
  568. } else {
  569. goButton.layer!.backgroundColor = KMAppearance.Interactive.m0Color().withAlphaComponent(0.4).cgColor
  570. goButton.setTitleColor(KMAppearance.Layout.w0Color().withAlphaComponent(0.4))
  571. }
  572. pdfview?.setNeedsDisplay(pdfview!.visibleRect)
  573. }
  574. }
  575. }