KMHeaderFooterPreviewController.swift 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285
  1. //
  2. // KMHeaderFooterPreviewController.swift
  3. // PDF Master
  4. //
  5. // Created by tangchao on 2022/12/26.
  6. //
  7. import Cocoa
  8. /// 页眉页脚 预览控制器
  9. class KMHeaderFooterPreviewController: KMWatermarkAdjectivePreViewBaseController {
  10. override func viewDidLoad() {
  11. super.viewDidLoad()
  12. let itemTitles = [[NSLocalizedString("Add HeaderAndFooter", comment: ""), NSLocalizedString("Delete HeaderAndFooter", comment: "")], [NSLocalizedString("Batch", comment: "")]]
  13. var itemModels: Array<Array<KMWatermarkAdjectiveTopBarItemModel>> = []
  14. for items in itemTitles {
  15. var array: Array<KMWatermarkAdjectiveTopBarItemModel> = []
  16. for title in items {
  17. let model = KMWatermarkAdjectiveTopBarItemModel()
  18. model.iconName = ""
  19. model.itemTitle = title
  20. array.append(model)
  21. }
  22. itemModels.append(array)
  23. }
  24. self.topBarView.initItemData(itemArrays: itemModels)
  25. self.topBarView.selectTopItem(index: 0)
  26. let preView: KMWatermarkPDFView_OC = KMWatermarkPDFView_OC()
  27. self.preView = preView
  28. self.preView.frame = self.preViewBox.contentView!.bounds
  29. self.preView.autoresizingMask = [.width, .height]
  30. self.preViewBox.contentView?.addSubview(self.preView)
  31. self.preView.setDisplay(.singlePage)
  32. let controller = KMHeaderFooterPropertyMainController()
  33. controller.view.frame = self.rightBox.contentView!.bounds
  34. controller.view.autoresizingMask = [.width, .height]
  35. self.right_gotoViewController(viewController: controller)
  36. controller.modelDidChange = { [weak self] model in
  37. if (model == nil || (model as! KMHeaderFooterModel).hasVaild == false) {
  38. self!.topBarView.isCanApply(can: false)
  39. self!.model = nil
  40. } else {
  41. self!.topBarView.isCanApply(can: true)
  42. self!.model = model
  43. self?.model?.pageCount = Int((self?.preView.document.pageCount)!)
  44. }
  45. (self?.preView as! KMWatermarkPDFView_OC).model = model
  46. }
  47. }
  48. override func viewDidAppear() {
  49. super.viewDidAppear()
  50. (self.rightViewController as! KMHeaderFooterPropertyMainController).pageCount = Int(self.preView.document.pageCount)
  51. }
  52. override func topItemClick(index: Int) {
  53. if (index == 0) { /// 添加
  54. return
  55. }
  56. if (index == 2) { /// 批量
  57. KMBatchWindowController.openFile(nil, .HeaderAndFooter)
  58. return
  59. }
  60. if (index == 2) { /// 批量
  61. KMBatchWindowController.openFile(nil, .HeaderAndFooter)
  62. return
  63. }
  64. /// 移除
  65. self.beginLoading()
  66. self.deleteHeaderFooter(toPath: self.preView.document.documentURL.path) {
  67. result in
  68. self.endLoading()
  69. if (result) {
  70. DispatchQueue.main.async {
  71. self.preView.document = CPDFDocument(url: self.preView.document.documentURL)
  72. }
  73. } else {
  74. let alert = NSAlert()
  75. alert.alertStyle = .critical
  76. alert.messageText = NSLocalizedString("Failure", comment: "")
  77. alert.runModal()
  78. }
  79. }
  80. }
  81. override func applyAction() {
  82. if (self.model == nil) {
  83. let alert = NSAlert()
  84. alert.alertStyle = .critical
  85. alert.messageText = NSLocalizedString("Failure", comment: "")
  86. alert.runModal()
  87. return
  88. }
  89. self.beginLoading()
  90. self.addHeaderFooter(model: self.model! as! KMHeaderFooterModel, toPath: self.preView.document.documentURL.path, completion: {
  91. result in
  92. DispatchQueue.main.async {
  93. self.preView.layoutDocumentView()
  94. self.preView.setNeedsDisplayForVisiblePages()
  95. }
  96. self.endLoading()
  97. if (result) {
  98. guard let callback = self.itemClick else {
  99. return
  100. }
  101. callback(1, nil)
  102. } else {
  103. let alert = NSAlert()
  104. alert.alertStyle = .critical
  105. alert.messageText = NSLocalizedString("Failure", comment: "")
  106. alert.runModal()
  107. }
  108. })
  109. }
  110. private func addHeaderFooter(model: KMHeaderFooterModel, toPath: String, completion: @escaping (_ result: Bool) -> ()) {
  111. DispatchQueue.global().async {
  112. let document: CPDFDocument = self.preView.document
  113. var property = document.headerFooter()
  114. var fontSize = 0.0
  115. var fontName: String = ""
  116. switch model.textFont {
  117. case .font(name: let name, size: let size):
  118. fontSize = size
  119. fontName = name
  120. break
  121. default:
  122. break
  123. }
  124. let font = NSFont.boldSystemFont(ofSize:fontSize)
  125. let style = NSMutableParagraphStyle()
  126. style.alignment = .center
  127. style.lineBreakMode = .byCharWrapping
  128. let size: NSSize = "text".boundingRect(with: NSSize(width: 1000, height: 1000), options: NSString.DrawingOptions(rawValue: 3), attributes: [NSAttributedString.Key.font : font, NSAttributedString.Key.paragraphStyle : style]).size
  129. property?.margin = NSEdgeInsetsMake(max(model.topMargin-size.height, 0), model.leftMargin, max(model.bottomMargin-size.height, 0), model.rightMargin)
  130. let strings = KMHeaderFooterPreviewController.parseModel(model: model, pageCount: Int(self.preView.document.pageCount))
  131. var count: Int = 0
  132. var color: NSColor!
  133. switch model.textColor {
  134. case .color(red: let red, green: let green, blue: let blue, alpha: let alpha):
  135. color = NSColor(red: red, green: green, blue: blue, alpha: alpha)
  136. default:
  137. break
  138. }
  139. if (color == nil) {
  140. color = NSColor.black
  141. }
  142. for text in strings {
  143. property?.setText(text, at: UInt(count))
  144. property?.setTextColor(color, at: UInt(count))
  145. property?.setFontSize(fontSize, at: UInt(count))
  146. property?.setFontName(fontName, at: UInt(count))
  147. count += 1
  148. }
  149. let pagesString = self.findPagesString(model)
  150. if (pagesString.isEmpty) {
  151. property?.pageString = "0-\(document.pageCount-1)"
  152. } else {
  153. property?.pageString = pagesString
  154. }
  155. property?.update()
  156. /// 保存到临时路径
  157. let documentPath = NSTemporaryDirectory()
  158. let tempPath: String = "\(documentPath)/\(toPath.lastPathComponent)"
  159. if (FileManager.default.fileExists(atPath: tempPath)) {
  160. try?FileManager.default.removeItem(atPath: tempPath)
  161. }
  162. let result = document.write(to: URL(fileURLWithPath: tempPath))
  163. if (result) {
  164. if (FileManager.default.fileExists(atPath: toPath)) {
  165. try?FileManager.default.removeItem(atPath: toPath)
  166. }
  167. try?FileManager.default.moveItem(atPath: tempPath, toPath: toPath)
  168. } else {
  169. try?FileManager.default.removeItem(atPath: tempPath)
  170. }
  171. DispatchQueue.main.async {
  172. completion(result)
  173. }
  174. }
  175. }
  176. func deleteHeaderFooter(toPath: String, completion: @escaping (_ result: Bool) -> ()) {
  177. if (self.preView.document.allowsPrinting == false || self.preView.document.allowsCopying == false) {
  178. let alert = NSAlert()
  179. alert.alertStyle = .critical
  180. alert.messageText = NSLocalizedString("This PDF document's user permissions does not allow modifying, content copying and printing.", comment: "")
  181. alert.runModal()
  182. completion(false)
  183. return
  184. }
  185. DispatchQueue.global().async {
  186. let document: CPDFDocument = self.preView.document
  187. var property = document.headerFooter()
  188. property?.clear()
  189. /// 保存到临时路径
  190. let documentPath = NSTemporaryDirectory()
  191. let tempPath: String = "\(documentPath)/\(toPath.lastPathComponent)"
  192. if (FileManager.default.fileExists(atPath: tempPath)) {
  193. try?FileManager.default.removeItem(atPath: tempPath)
  194. }
  195. let result = document.write(to: URL(fileURLWithPath: tempPath))
  196. if (result) {
  197. if (FileManager.default.fileExists(atPath: toPath)) {
  198. try?FileManager.default.removeItem(atPath: toPath)
  199. }
  200. try?FileManager.default.moveItem(atPath: tempPath, toPath: toPath)
  201. } else {
  202. try?FileManager.default.removeItem(atPath: tempPath)
  203. }
  204. DispatchQueue.main.async {
  205. completion(result)
  206. }
  207. }
  208. }
  209. static func parseModel(model: KMHeaderFooterModel, pageCount: Int) -> [String] {
  210. var topLeftString: String = ""
  211. if (!model.topLeftString.isEmpty) {
  212. var string = KMWatermarkAdjectiveTools.parsePageFormat(formatString: model.topLeftString, startPage: model.startString, pageCount: "\(pageCount)")
  213. string = KMWatermarkAdjectiveTools.parseDateFormat(formatString: string)
  214. topLeftString = string
  215. }
  216. var topCenterString: String = ""
  217. if (!model.topCenterString.isEmpty) {
  218. var string = KMWatermarkAdjectiveTools.parsePageFormat(formatString: model.topCenterString, startPage: model.startString, pageCount: "\(pageCount)")
  219. string = KMWatermarkAdjectiveTools.parseDateFormat(formatString: string)
  220. topCenterString = string
  221. }
  222. var topRightString: String = ""
  223. if (!model.topRightString.isEmpty) {
  224. var string = KMWatermarkAdjectiveTools.parsePageFormat(formatString: model.topRightString, startPage: model.startString, pageCount: "\(pageCount)")
  225. string = KMWatermarkAdjectiveTools.parseDateFormat(formatString: string)
  226. topRightString = string
  227. }
  228. var bottomLeftString: String = ""
  229. if (!model.bottomLeftString.isEmpty) {
  230. var string = KMWatermarkAdjectiveTools.parsePageFormat(formatString: model.bottomLeftString, startPage: model.startString, pageCount: "\(pageCount)")
  231. string = KMWatermarkAdjectiveTools.parseDateFormat(formatString: string)
  232. bottomLeftString = string
  233. }
  234. var bottomCenterString: String = ""
  235. if (!model.bottomCenterString.isEmpty) {
  236. var string = KMWatermarkAdjectiveTools.parsePageFormat(formatString: model.bottomCenterString, startPage: model.startString, pageCount: "\(pageCount)")
  237. string = KMWatermarkAdjectiveTools.parseDateFormat(formatString: string)
  238. bottomCenterString = string
  239. }
  240. var bottomRightString: String = ""
  241. if (!model.bottomRightString.isEmpty) {
  242. var string = KMWatermarkAdjectiveTools.parsePageFormat(formatString: model.bottomRightString, startPage: model.startString, pageCount: "\(pageCount)")
  243. string = KMWatermarkAdjectiveTools.parseDateFormat(formatString: string)
  244. bottomRightString = string
  245. }
  246. return [topLeftString, topCenterString, topRightString, bottomLeftString, bottomCenterString, bottomRightString]
  247. }
  248. }