NCViewerPDFSearch.swift 5.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163
  1. //
  2. // NCViewerPDFSearch.swift
  3. // Nextcloud
  4. //
  5. // Created by Marino Faggiana on 23/03/2020.
  6. // Copyright © 2020 Marino Faggiana. All rights reserved.
  7. //
  8. // Author Marino Faggiana <marino.faggiana@nextcloud.com>
  9. //
  10. // This program is free software: you can redistribute it and/or modify
  11. // it under the terms of the GNU General Public License as published by
  12. // the Free Software Foundation, either version 3 of the License, or
  13. // (at your option) any later version.
  14. //
  15. // This program is distributed in the hope that it will be useful,
  16. // but WITHOUT ANY WARRANTY; without even the implied warranty of
  17. // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  18. // GNU General Public License for more details.
  19. //
  20. // You should have received a copy of the GNU General Public License
  21. // along with this program. If not, see <http://www.gnu.org/licenses/>.
  22. //
  23. import UIKit
  24. import PDFKit
  25. @objc protocol NCViewerPDFSearchDelegate: AnyObject {
  26. func searchPdfSelection(_ pdfSelection: PDFSelection)
  27. }
  28. class NCViewerPDFSearch: UITableViewController, UISearchBarDelegate, PDFDocumentDelegate {
  29. var searchBar = UISearchBar()
  30. var pdfDocument: PDFDocument?
  31. var searchResultArray: [PDFSelection] = []
  32. weak var delegate: NCViewerPDFSearchDelegate?
  33. // MARK: - View Life Cycle
  34. override func viewDidLoad() {
  35. super.viewDidLoad()
  36. searchBar.delegate = self
  37. searchBar.sizeToFit()
  38. searchBar.searchBarStyle = .minimal
  39. navigationItem.titleView = searchBar
  40. tableView.dataSource = self
  41. tableView.delegate = self
  42. tableView.register(UINib(nibName: "NCViewerPDFSearchCell", bundle: nil), forCellReuseIdentifier: "Cell")
  43. }
  44. override func viewWillAppear(_ animated: Bool) {
  45. super.viewWillAppear(animated)
  46. searchBar.becomeFirstResponder()
  47. }
  48. // MARK: - UITableView DataSource / Delegate
  49. override func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
  50. return 82
  51. }
  52. override func numberOfSections(in tableView: UITableView) -> Int {
  53. return 1
  54. }
  55. override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
  56. return self.searchResultArray.count
  57. }
  58. override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
  59. guard let cell = tableView.dequeueReusableCell(withIdentifier: "Cell", for: indexPath) as? NCViewerPDFSearchCell else { return UITableViewCell() }
  60. let pdfSelection = searchResultArray[indexPath.row] as PDFSelection
  61. let pdfPage = pdfSelection.pages.first
  62. let pageNumber = pdfPage?.pageRef?.pageNumber ?? 0
  63. cell.pageNumberLabel.text = NSLocalizedString("_scan_document_pdf_page_", comment: "") + ": " + String(pageNumber)
  64. if let extendSelection = pdfSelection.copy() as? PDFSelection {
  65. extendSelection.extend(atStart: 10)
  66. extendSelection.extend(atEnd: 90)
  67. extendSelection.extendForLineBoundaries()
  68. let nsRange = NSString(string: extendSelection.string!).range(of: pdfSelection.string!, options: String.CompareOptions.caseInsensitive)
  69. if nsRange.location != NSNotFound {
  70. let attributedSubString = NSAttributedString(string: NSString(string: extendSelection.string!).substring(with: nsRange), attributes: [NSAttributedString.Key.font: UIFont.boldSystemFont(ofSize: 17), NSAttributedString.Key.foregroundColor: UIColor.systemBlue])
  71. let attributedString = NSMutableAttributedString(string: extendSelection.string!)
  72. attributedString.replaceCharacters(in: nsRange, with: attributedSubString)
  73. cell.searchResultTextLabel.attributedText = attributedString
  74. }
  75. }
  76. return cell
  77. }
  78. override func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
  79. let pdfSelection = searchResultArray[indexPath.row]
  80. delegate?.searchPdfSelection(pdfSelection)
  81. dismiss(animated: true)
  82. }
  83. // MARK: - PDFSelection Delegate
  84. func didMatchString(_ instance: PDFSelection) {
  85. searchResultArray.append(instance)
  86. tableView.reloadData()
  87. }
  88. // MARK: - UIScrollView Delegate
  89. override func scrollViewWillBeginDragging(_ scrollView: UIScrollView) {
  90. searchBar.resignFirstResponder()
  91. }
  92. // MARK: - UISearchBarDelegate
  93. func searchBarSearchButtonClicked(_ searchBar: UISearchBar) {
  94. searchBar.resignFirstResponder()
  95. }
  96. func searchBarCancelButtonClicked(_ searchBar: UISearchBar) {
  97. pdfDocument?.cancelFindString()
  98. navigationItem.setRightBarButton(nil, animated: false)
  99. dismiss(animated: true)
  100. }
  101. func searchBar(_ searchBar: UISearchBar, textDidChange searchText: String) {
  102. if searchText.count < 2 { return }
  103. searchResultArray.removeAll()
  104. tableView.reloadData()
  105. pdfDocument?.cancelFindString()
  106. pdfDocument?.delegate = self
  107. pdfDocument?.beginFindString(searchText, withOptions: .caseInsensitive)
  108. }
  109. func searchBarShouldBeginEditing(_ searchBar: UISearchBar) -> Bool {
  110. let cancelBarButtonItem = UIBarButtonItem(title: NSLocalizedString("_cancel_", comment: ""), style: .plain, target: self, action: #selector(cancelBarButtonItemClicked))
  111. navigationItem.setRightBarButton(cancelBarButtonItem, animated: true)
  112. return true
  113. }
  114. @objc func cancelBarButtonItemClicked() {
  115. searchBarCancelButtonClicked(searchBar)
  116. }
  117. }
  118. class NCViewerPDFSearchCell: UITableViewCell {
  119. @IBOutlet weak var outlineLabel: UILabel!
  120. @IBOutlet weak var pageNumberLabel: UILabel!
  121. @IBOutlet weak var searchResultTextLabel: UILabel!
  122. override func awakeFromNib() {
  123. super.awakeFromNib()
  124. }
  125. }