KMWatermarkAdjectivePreViewBaseController.swift 19 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521
  1. //
  2. // KMWatermarkAdjectiveBaseController.swift
  3. // PDF Reader Pro
  4. //
  5. // Created by tangchao on 2022/12/15.
  6. //
  7. import Cocoa
  8. class KMWatermarkTestWindow: NSWindow {
  9. var controller: KMWatermarkAdjectivePreViewBaseController!
  10. override init(contentRect: NSRect, styleMask style: NSWindow.StyleMask, backing backingStoreType: NSWindow.BackingStoreType, defer flag: Bool) {
  11. super.init(contentRect: contentRect, styleMask: style, backing: backingStoreType, defer: flag);
  12. isReleasedWhenClosed = false
  13. let controller_: KMCropPreviewController = KMCropPreviewController()
  14. contentView?.addSubview(controller_.view)
  15. controller_.view.frame = CGRect(x: 0, y: 0, width: contentRect.size.width, height: contentRect.size.height)
  16. controller = controller_
  17. }
  18. }
  19. typealias KMWatermarkAdjectivePageNumberViewCallback = (_ value: String) -> ()
  20. class KMWatermarkAdjectivePageNumberView: NSView , NSTextFieldDelegate{
  21. var numberTextField = NSTextField()
  22. var rightLabel = NSTextField(labelWithString: "")
  23. var callback: KMWatermarkAdjectivePageNumberViewCallback?
  24. override init(frame frameRect: NSRect) {
  25. super.init(frame: frameRect)
  26. self.initSubViews()
  27. }
  28. required init?(coder: NSCoder) {
  29. super.init(coder: coder)
  30. self.initSubViews()
  31. }
  32. func initSubViews() {
  33. self.addSubview(self.numberTextField)
  34. self.addSubview(self.rightLabel)
  35. self.numberTextField.alignment = .center
  36. self.rightLabel.alignment = .left
  37. self.numberTextField.textColor = NSColor.white
  38. self.rightLabel.textColor = NSColor.white
  39. self.numberTextField.isBordered = false
  40. self.numberTextField.drawsBackground = false
  41. self.numberTextField.focusRingType = .none
  42. self.numberTextField.delegate = self
  43. self.numberTextField.formatter = TextFieldFormatter()
  44. self.numberTextField.maximumNumberOfLines = 1
  45. self.numberTextField.lineBreakMode = .byTruncatingTail
  46. }
  47. override func layout() {
  48. super.layout()
  49. let width: CGFloat = NSWidth(self.bounds)
  50. let height: CGFloat = NSHeight(self.bounds)
  51. let contentH: CGFloat = 20
  52. let contentY: CGFloat = (height-contentH) * 0.5
  53. self.numberTextField.frame = NSRect(x: 10, y: contentY, width: width * 0.5-10, height: contentH)
  54. self.rightLabel.frame = NSRect(x: width * 0.5, y: contentY, width: width * 0.5, height: contentH)
  55. }
  56. func controlTextDidChange(_ obj: Notification) {
  57. if (self.numberTextField.isEqual(to: obj.object)) {
  58. guard let callback = self.callback else {
  59. return
  60. }
  61. callback(self.numberTextField.stringValue)
  62. }
  63. }
  64. }
  65. typealias KMWatermarkAdjectivePreViewItemClick = (_ index: Int, _ param: Any?) -> ()
  66. /// 水印相关 预览控制器(基类)
  67. class KMWatermarkAdjectivePreViewBaseController: NSViewController {
  68. @IBOutlet weak var topBarBox: NSBox!
  69. lazy var topBarView: KMWatermarkAdjectiveTopBarView = {
  70. let view = KMWatermarkAdjectiveTopBarView()
  71. return view
  72. }()
  73. @IBOutlet weak var splitView: NSSplitView!
  74. @IBOutlet weak var pageInputBox: NSBox!
  75. @IBOutlet weak var preViewBox: NSBox!
  76. var preView: CPDFView!
  77. var documentURL: URL!
  78. var applyDocument: CPDFDocument?
  79. var pageNumberView = KMWatermarkAdjectivePageNumberView()
  80. var watermarkArray: Array<KMWatermarkModel> = []
  81. @IBOutlet weak var rightBox: NSBox!
  82. var rightViewController: NSViewController!
  83. @IBOutlet weak var tipBox: NSBox!
  84. private var maskView: NSButton!
  85. private var indicator: NSProgressIndicator!
  86. var itemClick: KMWatermarkAdjectivePreViewItemClick?
  87. var model: KMWatermarkAdjectiveBaseModel?
  88. init() {
  89. super.init(nibName: "KMWatermarkAdjectivePreViewBaseController", bundle: nil)
  90. }
  91. required init?(coder: NSCoder) {
  92. super.init(nibName: "KMWatermarkAdjectivePreViewBaseController", bundle: nil)
  93. }
  94. override func viewDidLoad() {
  95. super.viewDidLoad()
  96. self.topBarView.frame = self.topBarBox.contentView!.bounds
  97. self.topBarView.autoresizingMask = NSView.AutoresizingMask(rawValue: 18)
  98. self.topBarBox.contentView?.addSubview(self.topBarView)
  99. self.topBarBox.fillColor = NSColor.white
  100. self.view.wantsLayer = true
  101. self.view.layer?.backgroundColor = NSColor.white.cgColor
  102. self.topBarView.isCanApply(can: false)
  103. self.topBarView.cancelClick = {
  104. [unowned self] in
  105. self.cancelAction()
  106. }
  107. self.topBarView.applyClick = {
  108. [unowned self] in
  109. self.applyAction()
  110. }
  111. self.topBarView.itemClick = { [weak self] section, item in
  112. self!.topItemClick(index: item)
  113. }
  114. self.rightBox.fillColor = NSColor(white: 243.0/255.0, alpha: 1.0)
  115. self.splitView.isVertical = true
  116. self.splitView.dividerStyle = .thin
  117. self.splitView.delegate = self
  118. // self.splitView.arrangedSubviews.first?.frame = NSMakeRect(0, 0, self.splitView.frame.size.width-260, self.splitView.frame.size.height)
  119. // self.splitView.arrangedSubviews.last?.frame = NSMakeRect(self.splitView.frame.size.width-260, 0, 260, self.splitView.frame.size.height)
  120. let pageNumberView = self.pageNumberView
  121. pageNumberView.frame = self.pageInputBox.contentView!.bounds
  122. pageNumberView.autoresizingMask = [.width, .height]
  123. self.pageInputBox.contentView?.addSubview(pageNumberView)
  124. self.pageInputBox.fillColor = NSColor.black
  125. self.pageNumberView.callback = { [weak self] string in
  126. var number: Int = 0
  127. if (string.isEmpty) {
  128. number = 1
  129. } else {
  130. number = Int(string)!
  131. if (number <= 0) {
  132. number = 1
  133. } else if (number > (self?.preView.document.pageCount)!) {
  134. number = Int((self?.preView.document.pageCount)!)
  135. }
  136. }
  137. self?.pageNumberView.numberTextField.stringValue = "\(number)"
  138. self?.preView.go(toPageIndex: number-1, animated: true)
  139. }
  140. }
  141. override func viewWillAppear() {
  142. super.viewWillAppear()
  143. if (self.documentURL != nil) {
  144. self.preView.document = CPDFDocument(url: self.documentURL)
  145. self.pageNumberView.numberTextField.stringValue = "1"
  146. self.pageNumberView.rightLabel.stringValue = "/ \(self.preView.document.pageCount)"
  147. }
  148. }
  149. func cancelAction() {
  150. guard let callback = self.itemClick else {
  151. return
  152. }
  153. callback(0, nil)
  154. }
  155. func applyAction() {
  156. }
  157. func topItemClick(index: Int) {
  158. }
  159. func right_gotoViewController(viewController: NSViewController) {
  160. for subview in self.rightBox.contentView!.subviews {
  161. subview.removeFromSuperview()
  162. }
  163. viewController.view.frame = self.rightBox.contentView!.bounds
  164. viewController.view.autoresizingMask = NSView.AutoresizingMask(rawValue: 18)
  165. self.rightBox.contentView?.addSubview(viewController.view)
  166. self.rightViewController = viewController
  167. }
  168. func addWatermark(model: KMWatermarkModel, toPath: String, completion: @escaping (_ result: Bool) -> ()) {
  169. DispatchQueue.global().async {
  170. var property: CPDFWatermark!
  171. var scale: CGFloat = model.scale
  172. if (!model.text.isEmpty) {
  173. property = CPDFWatermark(document: self.preView.document, type: .text)
  174. property.text = model.text
  175. property.textColor = model.getTextColor()
  176. scale = model.getTextFontSize() / 24.0
  177. } else {
  178. property = CPDFWatermark(document: self.preView.document, type: .image)
  179. property.image = model.image
  180. }
  181. property.scale = scale
  182. property.rotation = -model.rotation
  183. property.opacity = model.opacity
  184. property.tx = model.horizontalSpace
  185. property.ty = model.verticalSpace
  186. property.isFront = model.isFront
  187. var pageString: String = ""
  188. if (model.pageRangeType == .all) {
  189. for i in 0 ..< self.preView.document.pageCount {
  190. pageString.append("\(i)")
  191. if (i != self.preView.document.pageCount-1) {
  192. pageString.append(",")
  193. }
  194. }
  195. } else if (model.pageRangeType == .odd) {
  196. for i in 0 ..< self.preView.document.pageCount {
  197. if (i % 2 == 0) {
  198. pageString.append("\(i)")
  199. } else {
  200. continue
  201. }
  202. if (i != self.preView.document.pageCount-1) {
  203. pageString.append(",")
  204. }
  205. }
  206. } else if (model.pageRangeType == .even) {
  207. for i in 0 ..< self.preView.document.pageCount {
  208. if (i % 2 == 1) {
  209. pageString.append("\(i)")
  210. } else {
  211. continue
  212. }
  213. if (i != self.preView.document.pageCount-1) {
  214. pageString.append(",")
  215. }
  216. }
  217. } else {
  218. pageString = model.pagesString
  219. }
  220. property.pageString = pageString
  221. property.isTilePage = model.isTilePage
  222. property.horizontalSpacing = model.tileHorizontalSpace / scale
  223. property.verticalSpacing = model.tileVerticalSpace / scale
  224. if (model.verticalMode == 0) {
  225. property.verticalPosition = .top
  226. } else if (model.verticalMode == 1) {
  227. property.verticalPosition = .center
  228. } else if (model.verticalMode == 2) {
  229. property.verticalPosition = .bottom
  230. }
  231. if (model.horizontalMode == 0) {
  232. property.horizontalPosition = .left
  233. } else if (model.horizontalMode == 1) {
  234. property.horizontalPosition = .center
  235. } else if (model.horizontalMode == 2) {
  236. property.horizontalPosition = .right
  237. }
  238. model.watermark = property
  239. self.preView.document.addWatermark(property)
  240. /// 保存到临时路径
  241. let documentPath = NSTemporaryDirectory()
  242. let tempPath: String = "\(documentPath)/\(toPath.lastPathComponent)"
  243. if (FileManager.default.fileExists(atPath: tempPath)) {
  244. try?FileManager.default.removeItem(atPath: tempPath)
  245. }
  246. let result = self.preView.document.write(to: URL(fileURLWithPath: tempPath))
  247. if (result) {
  248. if (FileManager.default.fileExists(atPath: toPath)) {
  249. try?FileManager.default.removeItem(atPath: toPath)
  250. }
  251. try?FileManager.default.moveItem(atPath: tempPath, toPath: toPath)
  252. } else {
  253. try?FileManager.default.removeItem(atPath: tempPath)
  254. }
  255. DispatchQueue.main.async {
  256. completion(result)
  257. }
  258. }
  259. func loadAllWatermarks() {
  260. self.watermarkArray.removeAll()
  261. let watermarks: Array<CPDFWatermark> = self.preView.document.watermarks()
  262. for watermark in watermarks {
  263. let model = KMWatermarkModel()
  264. model.scale = watermark.scale
  265. model.rotation = -watermark.rotation
  266. model.opacity = watermark.opacity
  267. model.verticalSpace = watermark.tx
  268. model.horizontalSpace = watermark.ty
  269. model.pagesString = watermark.pageString
  270. // model.textColor = watermark.textColor
  271. model.isFront = watermark.isFront
  272. model.isTilePage = watermark.isTilePage
  273. model.tileVerticalSpace = watermark.verticalSpacing
  274. model.tileHorizontalSpace = watermark.horizontalSpacing
  275. if (watermark.type == .text) {
  276. model.text = watermark.text
  277. // model.textFont
  278. model.scale = watermark.scale * 24
  279. } else if (watermark.type == .image) {
  280. model.image = watermark.image
  281. }
  282. if (watermark.verticalPosition == .top) {
  283. model.verticalMode = 0
  284. } else if (watermark.verticalPosition == .center) {
  285. model.verticalMode = 1
  286. } else if (watermark.verticalPosition == .bottom) {
  287. model.verticalMode = 2
  288. }
  289. if (watermark.horizontalPosition == .left) {
  290. model.horizontalMode = 0
  291. } else if (watermark.horizontalPosition == .center) {
  292. model.horizontalMode = 1
  293. } else if (watermark.horizontalPosition == .right) {
  294. model.horizontalMode = 2
  295. }
  296. model.watermark = watermark
  297. self.watermarkArray.append(model)
  298. }
  299. }
  300. }
  301. func deleteWatermarks(toPath: String, completion: @escaping (_ result: Bool) -> ()) -> () {
  302. if (self.preView.document.watermarks().count <= 0) {
  303. completion(false)
  304. }
  305. DispatchQueue.global().async {
  306. let array: Array<CPDFWatermark> = self.preView.document.watermarks()
  307. for model in array {
  308. self.preView.document.removeWatermark(model)
  309. }
  310. /// 保存到临时路径
  311. let documentPath = NSTemporaryDirectory()
  312. let tempPath: String = "\(documentPath)/\(toPath.lastPathComponent)"
  313. if (FileManager.default.fileExists(atPath: tempPath)) {
  314. try?FileManager.default.removeItem(atPath: tempPath)
  315. }
  316. let result = self.preView.document.write(to: URL(fileURLWithPath: tempPath))
  317. if (result) {
  318. if (FileManager.default.fileExists(atPath: toPath)) {
  319. try?FileManager.default.removeItem(atPath: toPath)
  320. }
  321. try?FileManager.default.moveItem(atPath: tempPath, toPath: toPath)
  322. } else {
  323. try?FileManager.default.removeItem(atPath: tempPath)
  324. }
  325. DispatchQueue.main.async {
  326. completion(result)
  327. }
  328. }
  329. }
  330. /// 开始加载loading
  331. func beginLoading() {
  332. DispatchQueue.main.async { [self] in
  333. self.maskView = NSButton()
  334. self.maskView.isBordered = false
  335. self.maskView.title = ""
  336. self.maskView.wantsLayer = true
  337. self.maskView.layer?.backgroundColor = NSColor(white: 1, alpha: 0.3 ).cgColor
  338. self.maskView.target = self
  339. self.maskView.action = #selector(maskViewClick)
  340. self.maskView.frame = (self.view.bounds)
  341. self.maskView.autoresizingMask = NSView.AutoresizingMask(rawValue: 18)
  342. self.view.addSubview(self.maskView)
  343. self.indicator = NSProgressIndicator()
  344. self.indicator.style = .spinning
  345. self.indicator.controlSize = .regular
  346. self.indicator.isIndeterminate = true
  347. self.view.addSubview(self.indicator)
  348. let indicatorSize: CGFloat = 32
  349. self.indicator.frame = NSMakeRect(0.5*(NSWidth((self.view.frame))-indicatorSize), 0.5*(NSHeight((self.view.frame))-indicatorSize), indicatorSize, indicatorSize)
  350. self.maskView.autoresizingMask = NSView.AutoresizingMask(rawValue: 45)
  351. self.indicator.startAnimation(nil)
  352. }
  353. }
  354. /// 结束加载loading
  355. func endLoading() {
  356. DispatchQueue.main.async {
  357. self.indicator.stopAnimation(nil)
  358. self.indicator.removeFromSuperview()
  359. self.indicator = nil
  360. self.maskView.removeFromSuperview()
  361. self.maskView = nil
  362. }
  363. }
  364. @objc func maskViewClick() {
  365. }
  366. func findPagesString(_ model: KMWatermarkAdjectiveBaseModel) -> String{
  367. if (model.pageRangeType == .all) { /// 全部页面
  368. return "0-\(model.pageCount-1)"
  369. } else if (model.pageRangeType == .odd) { /// 奇数页面
  370. var string: String = ""
  371. for i in 0 ..< model.pageCount {
  372. if (i % 2 == 1) {
  373. continue
  374. }
  375. string.append("\(i)")
  376. if (i != model.pageCount-1) {
  377. string.append(",")
  378. }
  379. }
  380. return string
  381. } else if (model.pageRangeType == .even) { /// 偶数页面
  382. var string: String = ""
  383. for i in 0 ..< model.pageCount {
  384. if (i % 2 == 0) {
  385. continue
  386. }
  387. string.append("\(i)")
  388. if (i != model.pageCount-1) {
  389. string.append(",")
  390. }
  391. }
  392. return string
  393. } else { /// 自定义
  394. return model.pageRangeString
  395. }
  396. }
  397. }
  398. extension KMWatermarkAdjectivePreViewBaseController: NSSplitViewDelegate {
  399. // func splitView(_ splitView: NSSplitView, constrainMinCoordinate proposedMinimumPosition: CGFloat, ofSubviewAt dividerIndex: Int) -> CGFloat {
  400. // if (dividerIndex == 0) {
  401. // return NSWidth(splitView.frame)-260
  402. // }
  403. // return proposedMinimumPosition
  404. // }
  405. //
  406. // func splitView(_ splitView: NSSplitView, constrainMaxCoordinate proposedMaximumPosition: CGFloat, ofSubviewAt dividerIndex: Int) -> CGFloat {
  407. // if (dividerIndex == 0) {
  408. // return NSWidth(splitView.frame)-260
  409. // }
  410. // return proposedMaximumPosition
  411. // }
  412. func splitView(_ splitView: NSSplitView, shouldAdjustSizeOfSubview view: NSView) -> Bool {
  413. return true
  414. }
  415. func splitView(_ splitView: NSSplitView, shouldHideDividerAt dividerIndex: Int) -> Bool {
  416. return true
  417. }
  418. func splitView(_ splitView: NSSplitView, resizeSubviewsWithOldSize oldSize: NSSize) {
  419. let dividerThickness: CGFloat = splitView.dividerThickness
  420. var leftRect: NSRect = splitView.subviews.first!.frame
  421. var rightRect: NSRect = splitView.subviews.last!.frame
  422. let newFrame: NSRect = splitView.frame
  423. rightRect.size.height = newFrame.size.height
  424. leftRect.origin.x = 0
  425. leftRect.size.width = newFrame.size.width-rightRect.size.width-dividerThickness
  426. leftRect.size.height = newFrame.size.height
  427. rightRect.origin.x = leftRect.size.width
  428. splitView.subviews.first?.frame = leftRect
  429. splitView.subviews.last?.frame = rightRect
  430. }
  431. }