KMConvertBaseWindowController.swift 38 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004
  1. //
  2. // KMConvertBaseWindowController.swift
  3. // PDF Reader Pro
  4. //
  5. // Created by tangchao on 2022/12/5.
  6. //
  7. import PDFKit
  8. typealias KMConvertBaseWindowControllerItemClick = (Int) -> ()
  9. class KMConvertBaseWindowController: KMNBaseWindowController {
  10. @IBOutlet weak var titleLabel: NSTextField!
  11. @IBOutlet weak var leftBox: NSBox!
  12. @IBOutlet weak var prePDFView: KMNPDFPreView?
  13. @IBOutlet weak var numberBox: NSView!
  14. @IBOutlet weak var numberTextField: NSTextField!
  15. @IBOutlet weak var perLabel: NSTextField!
  16. @IBOutlet weak var totalNumberLabel: NSTextField!
  17. @IBOutlet weak var backBox: NSBox!
  18. @IBOutlet weak var nextBox: NSBox!
  19. @IBOutlet weak var rightScrollView: NSScrollView!
  20. @IBOutlet weak var batchButton: NSButton!
  21. @IBOutlet weak var canelBox: NSBox!
  22. @IBOutlet weak var convertBox: NSBox!
  23. @IBOutlet weak var rightBoxHeightConst: NSLayoutConstraint!
  24. var canelButtonVC: KMDesignButton?
  25. var convertButtonVC: KMDesignButton?
  26. var backButtonVC: KMDesignButton?
  27. var nextButtonVC: KMDesignButton?
  28. var itemClick: KMConvertBaseWindowControllerItemClick?
  29. var documentModel: KMDocumentModel?
  30. var currentPageIndex: Int = 1
  31. var pageRange = KMPageRange.all
  32. var pageRangeString: String = ""
  33. var settingView: KMConvertSettingView?
  34. var subType: Int = 0
  35. var fileExtension: String {
  36. get {
  37. return ""
  38. }
  39. }
  40. var progressController: SKProgressController?
  41. var pdfPreView: KMNPreView?
  42. private var convert: KMPDFConvert?
  43. var limit = true
  44. // 是否限制次数
  45. var limitCount = true
  46. var oriDocumentUrl: URL?
  47. var subscribeWaterMarkType: KMSubscribeWaterMarkType?
  48. deinit {
  49. KMPrint("KMConvertBaseWindowController 已释放")
  50. self.prePDFView?.removeFromSuperview()
  51. self.prePDFView = nil
  52. #if VERSION_DMG
  53. NotificationCenter.default.removeObserver(self)
  54. #endif
  55. }
  56. convenience init() {
  57. self.init(windowNibName: "KMConvertBaseWindowController")
  58. }
  59. override func awakeFromNib() {
  60. super.awakeFromNib()
  61. DispatchQueue.main.async {
  62. self.window?.makeFirstResponder(nil)
  63. }
  64. }
  65. override func windowDidLoad() {
  66. super.windowDidLoad()
  67. // if (self.convertCountIsReach()) {
  68. // Swift.debugPrint("转档次数已达到限制. count: \(self.getConvertCount())")
  69. // }
  70. // #if VERSION_DMG
  71. NotificationCenter.default.addObserver(self, selector: #selector(km_windowWillCloseNotifation), name: NSWindow.willCloseNotification, object: nil)
  72. // #endif
  73. let view = KMNPreView.createFromNib()
  74. leftBox.contentView = view
  75. self.pdfPreView = view
  76. if (self.documentModel != nil) {
  77. // let document = CPDFDocument(url: self.documentModel!.documentURL)
  78. // if (document!.isLocked) {
  79. // document?.unlock(withPassword: self.documentModel!.password)
  80. // }
  81. // self.prePDFView?.document = document!
  82. // self.prePDFView?.setFileUrl(self.documentModel!.documentURL, password: self.documentModel?.password)
  83. pdfPreView?.setFileUrl(self.documentModel!.documentURL, password: self.documentModel?.password)
  84. // let number: Int = Int((self.prePDFView?.document.pageCount)!)
  85. // let string = "\(number)"
  86. // totalNumberLabel.stringValue = string
  87. // self.prePDFView?.go(toPageIndex: self.documentModel!.currentIndex, animated: false)
  88. }
  89. // if (self.prePDFView?.documentView() != nil) {
  90. // self.prePDFView?.documentView().enclosingScrollView?.hasVerticalScroller = false
  91. // self.prePDFView?.documentView().enclosingScrollView?.hasHorizontalScroller = false
  92. // }
  93. // if let pageCount = self.prePDFView?.document.pageCount {
  94. // self.settingView?.pageCount = Int(pageCount)
  95. // }
  96. batchButton.title = NSLocalizedString("Batch", comment: "")
  97. batchButton.isBordered = false
  98. batchButton.wantsLayer = true
  99. batchButton.layer?.borderWidth = 1
  100. batchButton.layer?.cornerRadius = 4
  101. batchButton.target = self
  102. batchButton.action = #selector(batchButtonAction)
  103. batchButton.isHidden = true
  104. self.prePDFView?.currentPageDidChanged = { [weak self] preView, idx in
  105. guard let pdfView = preView?.pdfView else {
  106. return
  107. }
  108. let currentIndex = pdfView.currentPageIndex
  109. self?.currentPageIndex = currentIndex + 1
  110. self?.numberTextField.stringValue = "\(currentIndex+1)"
  111. self?.updateBackAndNextButtonState()
  112. }
  113. self.updateBackAndNextButtonState()
  114. }
  115. override func initSubViews() {
  116. super.initSubViews()
  117. let view = self.initSettingView()
  118. // view?.frame = self.rightScrollView.bounds
  119. // view?.autoresizingMask = [.width, .height]
  120. self.settingView = view
  121. self.rightScrollView.documentView = view
  122. self.rightScrollView.verticalScrollElasticity = .none
  123. self.rightScrollView.horizontalScrollElasticity = .none
  124. view?.km_add_inset_constraint()
  125. view?.currentLanguage = self.getCurrentLanguage()
  126. view?.lanugageDidSelected = { [weak self] value, _ in
  127. guard let index = value as? Int else {
  128. return
  129. }
  130. self?.saveLanugageSelectedIndex(index: index)
  131. }
  132. view?.pageRangeDidChange = { [weak self] pageRange in
  133. self?.pageRange = pageRange
  134. if (pageRange != .custom) {
  135. self?.updatePreView(pageRange: pageRange)
  136. }
  137. }
  138. view?.pageRangeDidInputFinishCallback = { [unowned self] string in
  139. self.pageRangeString = string
  140. let array = self.findSelectPage(pageRangeString: string)
  141. if array.count == 0 {
  142. let alert = NSAlert()
  143. alert.alertStyle = .warning
  144. alert.messageText = NSLocalizedString("Invalid page range or the page number is out of range. Please try again.", comment: "")
  145. alert.runModal()
  146. self.settingView?.pageRangeItemView?.pageSizeVC?.stringValue = ""
  147. } else {
  148. self.updatePreView(pageRange: .custom, pageString: string)
  149. }
  150. }
  151. view?.tipView?.itemClick = { [unowned self] _, _ in
  152. #if VERSION_DMG
  153. KMTools.openPurchaseProductWebsite()
  154. #else
  155. Task { @MainActor in
  156. if await (KMLightMemberManager.manager.canPayFunction() == false) {
  157. let _ = KMSubscribeWaterMarkWindowController.show(window: self.window!) { isSubscribeSuccess, isWaterMarkExport, isClose in
  158. if (isSubscribeSuccess) {
  159. self.refreshUI()
  160. }
  161. }
  162. }
  163. }
  164. #endif
  165. }
  166. self.settingView?.tipView?.isHidden = true
  167. Task { @MainActor in
  168. if await (KMLightMemberManager.manager.canUseAdvanced() == false) {
  169. self.limitCount = true
  170. } else {
  171. self.limitCount = false
  172. }
  173. if await (KMLightMemberManager.manager.canPayFunction() == false) {
  174. #if VERSION_DMG
  175. if (self.limitCount) { // 未登录
  176. self.settingView?.tipView?.isHidden = true
  177. } else {
  178. self.settingView?.tipView?.isHidden = false
  179. }
  180. #else
  181. self.settingView?.tipView?.isHidden = false
  182. #endif
  183. } else {
  184. self.limit = false
  185. }
  186. }
  187. self.backButtonVC = KMDesignButton.init(withType: .Image)
  188. self.backBox.contentView = self.backButtonVC!.view
  189. self.nextButtonVC = KMDesignButton.init(withType: .Image)
  190. self.nextBox.contentView = self.nextButtonVC!.view
  191. self.canelButtonVC = KMDesignButton.init(withType: .Text)
  192. self.canelBox.contentView = self.canelButtonVC!.view
  193. self.convertButtonVC = KMDesignButton.init(withType: .Text)
  194. self.convertBox.contentView = self.convertButtonVC!.view
  195. }
  196. override func initDefaultValue() {
  197. super.initDefaultValue()
  198. self.totalNumberLabel.lineBreakMode = .byTruncatingTail
  199. // self.prePDFView?.setDisplay(.singlePage)
  200. // self.prePDFView?.layoutDocumentView()
  201. // self.prePDFView?.autoScales = true
  202. // self.prePDFView?.delegate = self
  203. self.backBox.fillColor = .clear
  204. self.backButtonVC?.target = self
  205. self.backButtonVC?.action = #selector(backButtonAction)
  206. self.backButtonVC?.image = NSImage(named: "KMImageNamePreviousPageImage")!
  207. self.backButtonVC?.image_disabled = NSImage(named: "KMImageNamePreviousPageImageDisable")!
  208. self.backButtonVC?.pagination()
  209. self.numberBox.wantsLayer = true
  210. self.numberBox.layer?.backgroundColor = NSColor.white.cgColor
  211. self.numberBox.layer?.borderWidth = 1
  212. self.numberBox.layer?.cornerRadius = 4
  213. self.numberTextField.focusRingType = .none
  214. self.numberTextField.delegate = self
  215. self.numberTextField.isBordered = false
  216. self.nextBox.fillColor = .clear
  217. self.nextButtonVC?.target = self
  218. self.nextButtonVC?.action = #selector(nextButtonAction)
  219. self.nextButtonVC?.image = NSImage(named: "KMImageNameNextPageImage")!
  220. self.nextButtonVC?.image_disabled = NSImage(named: "KMImageNameNextPageImageDisable")!
  221. self.nextButtonVC?.pagination()
  222. self.canelBox.fillColor = .clear
  223. self.canelButtonVC?.target = self
  224. self.canelButtonVC?.action = #selector(cancelButtonAction)
  225. self.canelButtonVC?.stringValue = NSLocalizedString("Cancel", comment: "")
  226. self.canelButtonVC?.button(type: .Sec, size: .m)
  227. self.canelButtonVC?.button.keyEquivalent = KMKeyEquivalent.esc.string()
  228. self.convertBox.fillColor = .clear
  229. self.convertButtonVC?.target = self
  230. self.convertButtonVC?.action = #selector(convertButtonAction)
  231. self.convertButtonVC?.stringValue = NSLocalizedString("Convert", comment: "")
  232. self.convertButtonVC?.button(type: .Cta, size: .m)
  233. // convertButtonVC.button.keyEquivalent = KMKeyEquivalent.enter
  234. self.rightScrollView.hasVerticalScroller = false
  235. self.rightScrollView.hasHorizontalScroller = false
  236. self.initUIProperty()
  237. }
  238. private func initUIProperty() {
  239. self.titleLabel.textColor = NSColor.titleColor()
  240. self.titleLabel.font = .SFProTextSemiboldFont(16)
  241. self.leftBox.fillColor = NSColor.km_init(hex: "#F7F8FA")
  242. // self.prePDFView?.backgroundColor = NSColor.km_init(hex: "#F7F8FA")
  243. self.numberBox.layer?.borderColor = NSColor.km_init(hex: "#DFE1E5").cgColor
  244. self.perLabel.textColor = NSColor.titleColor()
  245. self.perLabel.font = .SFProTextRegularFont(12)
  246. self.totalNumberLabel.textColor = NSColor.titleColor()
  247. self.totalNumberLabel.font = .SFProTextRegularFont(12)
  248. self.batchButton.setTitleColor(NSColor.buttonTitleColor())
  249. self.batchButton.layer?.borderColor = NSColor.buttonBorderColor().cgColor
  250. self.batchButton.font = .SFProTextRegularFont(14)
  251. }
  252. func initSettingView() -> KMConvertSettingView? {
  253. let settingView = KMConvertSettingView.createFromNib()
  254. return settingView
  255. }
  256. public func initConvert() -> KMPDFConvert {
  257. return KMPDFConvert()
  258. }
  259. func setupContentHeight(height: CGFloat, animated: Bool = false) {
  260. if (animated) {
  261. self.rightBoxHeightConst.animator().constant = height
  262. } else {
  263. self.rightBoxHeightConst.constant = height
  264. }
  265. }
  266. func refreshUI() {
  267. }
  268. @objc func backButtonAction() {
  269. // if let _ = self.prePDFView?.canGoToPreviousPage() {
  270. // self.currentPageIndex -= 1
  271. // self.prePDFView?.goToPreviousPage(nil)
  272. //
  273. // self.numberTextField.stringValue = "\(self.prePDFView!.currentPageIndex+1)"
  274. // self.updateBackAndNextButtonState()
  275. // }
  276. }
  277. @objc func nextButtonAction() {
  278. // if let _ = self.prePDFView?.canGoToNextPage() {
  279. // self.currentPageIndex += 1
  280. // self.prePDFView?.goToNextPage(nil)
  281. //
  282. // self.numberTextField.stringValue = "\(self.prePDFView!.currentPageIndex+1)"
  283. // self.updateBackAndNextButtonState()
  284. // }
  285. }
  286. @objc func batchButtonAction() {
  287. guard let callback = itemClick else {
  288. return
  289. }
  290. callback(1)
  291. }
  292. @objc func cancelButtonAction() {
  293. self._clearData()
  294. guard let callback = itemClick else {
  295. return
  296. }
  297. callback(2)
  298. }
  299. @objc func convertButtonAction() {
  300. self.window?.makeFirstResponder(nil)
  301. if (self.pageRange == .custom) {
  302. let array = self.findSelectPage(pageRangeString: self.pageRangeString)
  303. if (array.count <= 0) {
  304. self.window?.makeFirstResponder(self.settingView?.pageRangeItemView?.pageSizeVC?.textField)
  305. return
  306. }
  307. }
  308. var pages: [Int] = []
  309. let filePath = self.getConvertFileSavePath()
  310. if (FileManager.default.fileExists(atPath: filePath)) {
  311. try?FileManager.default.removeItem(atPath: filePath)
  312. }
  313. // if ((self.prePDFView?.document?.writeDecrypt(to: URL(fileURLWithPath: filePath)))!) {
  314. // for i in 0 ..< self.prePDFView!.document.pageCount {
  315. // pages.append(Int(i)+1)
  316. // }
  317. // }
  318. if (pages.count <= 0) {
  319. let alert = NSAlert()
  320. alert.alertStyle = .warning
  321. alert.messageText = NSLocalizedString("Invalid page range or the page number is out of range. Please try again.", comment: "")
  322. alert.runModal()
  323. return
  324. }
  325. Task { @MainActor in
  326. #if VERSION_DMG
  327. if (await (KMLightMemberManager.manager.canUseAdvanced() == false)) {
  328. let _ = KMComparativeTableViewController.show(window: self.window!, .convert)
  329. return
  330. }
  331. #endif
  332. if await (KMLightMemberManager.manager.canPayFunction() == false) {
  333. var isContinue = false
  334. if pages.count <= 10 {
  335. isContinue = true
  336. }
  337. var limit = self.convertCountIsReach()
  338. if (!self.limitCount) { // 登录
  339. limit = false
  340. }
  341. if (limit) {
  342. isContinue = false
  343. }
  344. let _ = KMSubscribeWaterMarkWindowController.show(window: self.window!, isContinue: isContinue, limit: limit, type: self.subscribeWaterMarkType!) { isSubscribeSuccess, isWaterMarkExport, isClose in
  345. if (isClose) {
  346. return
  347. }
  348. if (isSubscribeSuccess) {
  349. self._convertButtonAction()
  350. return
  351. }
  352. if (isWaterMarkExport && !limit) {
  353. self._convertButtonAction(limit: true)
  354. return
  355. }
  356. }
  357. return
  358. }
  359. self._convertButtonAction()
  360. }
  361. }
  362. func convertModelAppendParams(convert: KMPDFConvert) -> () {
  363. if let isAllowOCR = self.settingView?.ocrEnabled {
  364. convert.isAllowOCR = isAllowOCR
  365. if let idx = self.settingView?.ocrItemView?.languageIndex {
  366. // convert.ocrLanguage = KMPDFConvertManager.defaultManager.languages_asc[idx]
  367. }
  368. } else {
  369. convert.isAllowOCR = false
  370. }
  371. }
  372. func getConvertFileSavePath() -> String {
  373. var path = NSSearchPathForDirectoriesInDomains(FileManager.SearchPathDirectory.applicationSupportDirectory, FileManager.SearchPathDomainMask.userDomainMask, true).last
  374. path?.append("/")
  375. path?.append(Bundle.main.bundleIdentifier!)
  376. if (FileManager.default.fileExists(atPath: path!) == false) {
  377. try?FileManager.default.createDirectory(atPath: path!, withIntermediateDirectories: false)
  378. }
  379. path?.append("/")
  380. path?.append("convert.pdf")
  381. return path!
  382. }
  383. func isValidPagesString(pagesString: String)-> Bool {
  384. var valid = false
  385. for ch in pagesString {
  386. if ch != "0" && ch != "1" && ch != "2" && ch != "3" && ch != "4" && ch != "5" && ch != "6" && ch != "7" && ch != "8" && ch != "9" && ch != "," && ch != "-" {
  387. valid = false
  388. break
  389. } else {
  390. valid = true
  391. }
  392. }
  393. return valid
  394. }
  395. func findSelectPage(pageRangeString: String) -> ([Int]) {
  396. if !isValidPagesString(pagesString: pageRangeString) {
  397. return []
  398. }
  399. var result: [Int] = []
  400. let array = pageRangeString.components(separatedBy: ",")
  401. for string in array {
  402. if string.isEmpty {
  403. return []
  404. } else {
  405. let pages = string .components(separatedBy: "-")
  406. if pages.count > 2 {
  407. return []
  408. } else if pages.count == 1 {
  409. let page = pages[0]
  410. if page.isEmpty || Int(page)! > self.documentModel!.pageCount || Int(page)! == 0 {
  411. return []
  412. } else {
  413. var hasSame: Bool = false
  414. for i in result {
  415. if i == Int(page)! {
  416. hasSame = true
  417. return []
  418. }
  419. }
  420. if !hasSame {
  421. result.append(Int(page)!)
  422. }
  423. }
  424. } else if pages.count == 2 {
  425. let page1 = pages[0]
  426. let page2 = pages[1]
  427. if page1.isEmpty || page2.isEmpty || Int(page1)! >= Int(page2)! || Int(page2)! > self.documentModel!.pageCount || Int(page1)! == 0 {
  428. return []
  429. } else {
  430. var hasSame: Bool = false
  431. for i in Int(page1)! ... Int(page2)! {
  432. for j in result {
  433. if j == i {
  434. hasSame = true
  435. return []
  436. }
  437. }
  438. }
  439. if !hasSame {
  440. for i in Int(page1)! ... Int(page2)! {
  441. result.append(i)
  442. }
  443. }
  444. }
  445. }
  446. }
  447. }
  448. return result
  449. }
  450. // MARK: -
  451. // MARK: Private Methods
  452. private func updateBackAndNextButtonState() {
  453. var nextEnabled = false
  454. // if let result = self.prePDFView?.canGoToNextPage() {
  455. // nextEnabled = result
  456. // }
  457. var backEnabled = false
  458. // if let result = self.prePDFView?.canGoToPreviousPage() {
  459. // backEnabled = result
  460. // }
  461. if (Thread.isMainThread) {
  462. self.backButtonVC?.state = backEnabled ? .Norm : .Disabled
  463. self.nextButtonVC?.state = nextEnabled ? .Norm : .Disabled
  464. } else {
  465. DispatchQueue.main.async {
  466. self.backButtonVC?.state = backEnabled ? .Norm : .Disabled
  467. self.nextButtonVC?.state = nextEnabled ? .Norm : .Disabled
  468. }
  469. }
  470. }
  471. internal func updatePreView(pageRange: KMPageRange, pageString: String = "") {
  472. // let pages = self.getPages(pageRange, pageString: pageString)
  473. // if (pages == nil || pages!.isEmpty) {
  474. // let alert = NSAlert()
  475. // alert.alertStyle = .warning
  476. // alert.messageText = NSLocalizedString("Invalid page range or the page number is out of range. Please try again.", comment: "")
  477. // alert.runModal()
  478. // return
  479. // }
  480. // var indexs = IndexSet()
  481. // for i in 0 ..< self.prePDFView!.document.pageCount {
  482. // indexs.insert(IndexSet.Element(i))
  483. // }
  484. // self.prePDFView?.document.removePage(at: indexs)
  485. //
  486. // #if DEBUG
  487. // let pageIndexs = self.getPageIndexs(pageRange, pageString: pageString)
  488. // if (pageIndexs != nil) {
  489. // for i in pageIndexs! {
  490. //
  491. // KMPrint(i)
  492. // }
  493. // }
  494. // #endif
  495. //// self.prePDFView.document?.importPages(pageIndexs!, from: self.documentModel.document, at: 0)
  496. // for page in pages! {
  497. // self.prePDFView?.document.insertPageObject(page, at: self.prePDFView!.document.pageCount)
  498. // }
  499. // DispatchQueue.main.async {
  500. // self.prePDFView?.layoutDocumentView()
  501. // self.prePDFView?.setNeedsDisplayForVisiblePages()
  502. // self.prePDFView?.goToFirstPage(nil)
  503. //
  504. // let number: Int = Int(self.prePDFView!.document!.pageCount)
  505. // self.totalNumberLabel.stringValue = "\(number)"
  506. // self.currentPageIndex = 1
  507. // self.numberTextField.stringValue = "1"
  508. //
  509. // self.updateBackAndNextButtonState()
  510. // }
  511. }
  512. private func getPageIndexs(_ pageRange: KMPageRange, pageString: String = "") -> IndexSet? {
  513. guard let pageCount = self.documentModel?.pageCount, pageCount > 0 else {
  514. return nil
  515. }
  516. var indexs = IndexSet()
  517. if (pageRange == .all) {
  518. for i in 0 ..< pageCount {
  519. indexs.insert(i)
  520. }
  521. } else if (pageRange == .odd) {
  522. for i in 0 ..< pageCount {
  523. if ((i % 2) == 1) {
  524. continue
  525. }
  526. indexs.insert(i)
  527. }
  528. } else if (pageRange == .even) {
  529. for i in 0 ..< pageCount {
  530. if ((i % 2) == 0) {
  531. continue
  532. }
  533. indexs.insert(i)
  534. }
  535. } else if (pageRange == .current) {
  536. if (self.currentPageIndex >= 1 && self.currentPageIndex <= pageCount) {
  537. indexs.insert(self.currentPageIndex-1)
  538. }
  539. } else if (pageRange == .custom) {
  540. let array = self.findSelectPage(pageRangeString: pageString)
  541. if array.count == 0 {
  542. } else {
  543. for i in 0 ..< array.count {
  544. let index = array[i]
  545. if (index > pageCount || index < 1) {
  546. continue
  547. }
  548. indexs.insert(index-1)
  549. }
  550. }
  551. }
  552. return indexs
  553. }
  554. private func getPages(_ pageRange: KMPageRange, pageString: String = "") -> [CPDFPage]? {
  555. guard let pageCount = self.documentModel?.pageCount, pageCount > 0 else {
  556. return nil
  557. }
  558. var pages: [CPDFPage] = []
  559. if (pageRange == .all) {
  560. for i in 0 ..< pageCount {
  561. let page = self.documentModel!.document?.page(at: UInt(i))
  562. if (page == nil) {
  563. continue
  564. }
  565. pages.append(page!)
  566. }
  567. } else if (pageRange == .odd) {
  568. for i in 0 ..< pageCount {
  569. if ((i % 2) == 1) {
  570. continue
  571. }
  572. let page = self.documentModel!.document?.page(at: UInt(i))
  573. if (page == nil) {
  574. continue
  575. }
  576. pages.append(page!)
  577. }
  578. } else if (pageRange == .even) {
  579. for i in 0 ..< pageCount {
  580. if ((i % 2) == 0) {
  581. continue
  582. }
  583. let page = self.documentModel!.document?.page(at: UInt(i))
  584. if (page == nil) {
  585. continue
  586. }
  587. pages.append(page!)
  588. }
  589. } else if (pageRange == .current) {
  590. // let page = self.prePDFView?.currentPage()
  591. // if (page != nil) {
  592. // pages.append(page!)
  593. // }
  594. } else if (pageRange == .custom) {
  595. let array = self.findSelectPage(pageRangeString: pageString)
  596. if array.count == 0 {
  597. } else {
  598. for i in 0 ..< array.count {
  599. let index = array[i]
  600. if (index > pageCount || index < 1) {
  601. continue
  602. }
  603. let page = self.documentModel?.document?.page(at: UInt(index-1))
  604. if (page == nil) {
  605. continue
  606. }
  607. pages.append(page!)
  608. }
  609. }
  610. }
  611. return pages
  612. }
  613. private func _convertButtonAction(limit: Bool = false) {
  614. var pages: [Int] = []
  615. let filePath = self.getConvertFileSavePath()
  616. if (FileManager.default.fileExists(atPath: filePath)) {
  617. try?FileManager.default.removeItem(atPath: filePath)
  618. }
  619. if (limit) {
  620. // if let _ = KMTools.saveWatermarkDocument(document: self.prePDFView!.document, to: URL(fileURLWithPath: filePath), removePWD: true) {
  621. // for i in 0 ..< self.prePDFView!.document.pageCount {
  622. // if (i >= 10) {
  623. // break
  624. // }
  625. // pages.append(Int(i)+1)
  626. // }
  627. // }
  628. } else {
  629. // if ((self.prePDFView?.document?.writeDecrypt(to: URL(fileURLWithPath: filePath)))!) {
  630. // for i in 0 ..< self.prePDFView!.document.pageCount {
  631. // pages.append(Int(i)+1)
  632. // }
  633. // }
  634. }
  635. if (pages.count <= 0) {
  636. let alert = NSAlert()
  637. alert.alertStyle = .warning
  638. alert.messageText = NSLocalizedString("Invalid page range or the page number is out of range. Please try again.", comment: "")
  639. alert.runModal()
  640. return
  641. }
  642. DispatchQueue.main.async {
  643. NSPanel.savePanel(self.window!) { panel in
  644. // var url: URL = self.prePDFView!.document.documentURL
  645. // if (self.oriDocumentUrl != nil) {
  646. // url = self.oriDocumentUrl!
  647. // }
  648. // let name = url.deletingPathExtension().lastPathComponent
  649. // panel.nameFieldStringValue = name
  650. // panel.allowedFileTypes = [self.fileExtension]
  651. } completion: { response, url in
  652. if (response == .cancel) {
  653. return
  654. }
  655. let outputFolderPath = url!.deletingLastPathComponent().path
  656. let convert = self.initConvert()
  657. self.convert = convert
  658. convert.password = self.documentModel!.password
  659. convert.outputFolderPath = outputFolderPath
  660. convert.filePath = filePath
  661. convert.pages = pages
  662. var fileName = url!.deletingPathExtension().lastPathComponent
  663. if (self.fileExtension.isEmpty) {
  664. fileName = url!.lastPathComponent
  665. }
  666. // if (fileName.isEmpty) {
  667. // fileName = NSLocalizedString("Untitled", comment: "")
  668. // }
  669. convert.outputFileName = fileName
  670. self.convertModelAppendParams(convert: convert)
  671. DispatchQueue.main.async {
  672. self.showProgressWindow()
  673. self.progressController?.maxValue = Double(convert.pages.count)
  674. }
  675. #if VERSION_DMG
  676. if self.settingView?.ocrItemView?.checkVC?.state == .Checked {
  677. let bundlePath = kResourcePath?.stringByAppendingPathComponent("DocumentAI.bundle")
  678. CPDFConvertKit.setOCRModelPath(bundlePath)
  679. }
  680. #else
  681. let bundlePath = Bundle.main.path(forResource: "DocumentAI", ofType: "bundle")
  682. CPDFConvertKit.setOCRModelPath(bundlePath)
  683. #endif
  684. DispatchQueue.global().async {
  685. KMPDFConvertManager.defaultManager.convert(convert: convert, progress: { index in
  686. DispatchQueue.main.async {
  687. self.progressController?.increment(by: 1.0)
  688. }
  689. }) { [unowned self] finished, error in
  690. self.hiddenProgressWindow()
  691. // 清除临时文件
  692. if (FileManager.default.fileExists(atPath: filePath)) {
  693. try?FileManager.default.removeItem(atPath: filePath)
  694. }
  695. if finished {
  696. self._clearData()
  697. self.recordConvertCount()
  698. cancelButtonAction()
  699. if FileManager.default.fileExists(atPath: convert.outputFilePath) {
  700. NSWorkspace.shared.activateFileViewerSelecting([URL(fileURLWithPath: convert.outputFilePath)])
  701. }
  702. } else {
  703. var errorString = ""
  704. let myError: NSError? = error as? NSError
  705. if myError?.code == 1 {
  706. errorString = NSLocalizedString("Password required or incorrect password. Please re-enter your password and try again", comment: "")
  707. } else if myError?.code == 2 {
  708. errorString = NSLocalizedString("The license doesn't allow the permission", comment: "")
  709. } else if myError?.code == 3 {
  710. errorString = NSLocalizedString("Malloc failure", comment: "")
  711. } else if myError?.code == 4 {
  712. errorString = NSLocalizedString("Unknown error in processing conversion. Please try again later", comment: "")
  713. } else if myError?.code == 5 {
  714. errorString = NSLocalizedString("Unknown error in processing PDF. Please try again later", comment: "")
  715. } else if myError?.code == 6 {
  716. errorString = NSLocalizedString("File not found or could not be opened. Check if your file exists or choose another file to convert", comment: "")
  717. } else if myError?.code == 7 {
  718. errorString = NSLocalizedString("File not in PDF format or corruptead. Change a PDF file and try again", comment: "")
  719. } else if myError?.code == 8 {
  720. errorString = NSLocalizedString("Unsupported security scheme", comment: "")
  721. } else if myError?.code == 9 {
  722. errorString = NSLocalizedString("Page not found or content error", comment: "")
  723. } else {
  724. errorString = NSLocalizedString("Table not found", comment: "")
  725. }
  726. let alert = NSAlert()
  727. alert.alertStyle = .critical
  728. alert.messageText = NSLocalizedString("Conversion Failed", comment: "")
  729. alert.informativeText = errorString
  730. alert.addButton(withTitle: NSLocalizedString("OK", comment: ""))
  731. alert.runModal()
  732. }
  733. }
  734. }
  735. }
  736. }
  737. }
  738. // MARK: - Notifation Methods
  739. @objc private func km_windowWillCloseNotifation() {
  740. Task { @MainActor in
  741. if await (KMLightMemberManager.manager.canUseAdvanced() == false) {
  742. self.limitCount = true
  743. } else {
  744. self.limitCount = false
  745. }
  746. if await (KMLightMemberManager.manager.canPayFunction() == false) {
  747. #if VERSION_DMG
  748. if (self.limitCount) { // 未登录
  749. self.settingView?.tipView?.isHidden = true
  750. } else {
  751. self.settingView?.tipView?.isHidden = false
  752. }
  753. #else
  754. self.settingView?.tipView?.isHidden = false
  755. #endif
  756. } else {
  757. self.limit = false
  758. }
  759. }
  760. }
  761. // MARK: Progress
  762. func showProgressWindow() {
  763. self.hiddenProgressWindow()
  764. let progress = SKProgressController()
  765. progress.window?.backgroundColor = NSColor.km_init(hex: "#36383B")
  766. progress.window?.contentView?.wantsLayer = true
  767. progress.window?.contentView?.layer?.backgroundColor = NSColor.km_init(hex: "#36383B").cgColor
  768. progress.progressField.textColor = NSColor.white
  769. progress.message = NSLocalizedString("Converting...", comment: "")
  770. progress.closeBlock = { [weak self] in
  771. if let convert = self?.convert {
  772. KMPDFConvertManager.defaultManager.cancel(convert: convert)
  773. }
  774. }
  775. self.progressController = progress
  776. self.window?.beginSheet(progress.window!)
  777. }
  778. func hiddenProgressWindow() {
  779. if (self.progressController != nil) {
  780. self.window?.endSheet((self.progressController?.window)!)
  781. self.progressController = nil
  782. }
  783. }
  784. func getCurrentLanguage() -> String {
  785. // return Bundle.main.preferredLocalizations.first!
  786. let array: [String] = UserDefaults.standard.object(forKey: "AppleLanguages") as! [String]
  787. return array.first!
  788. }
  789. /// 存储用户的选择的语言
  790. func saveLanugageSelectedIndex(index: Int) {
  791. UserDefaults.standard.setValue("\(index)", forKey: kKMConvertLanugageSelectedIndex)
  792. UserDefaults.standard.synchronize()
  793. }
  794. private func _clearData() {
  795. if let _ = self.oriDocumentUrl {
  796. // if let data = self.prePDFView?.document.documentURL.path, FileManager.default.fileExists(atPath: data) {
  797. // try?FileManager.default.removeItem(atPath: data)
  798. // }
  799. }
  800. }
  801. }
  802. extension KMConvertBaseWindowController: NSTextFieldDelegate {
  803. func controlTextDidChange(_ obj: Notification) {
  804. if numberTextField.isEqual(to: obj.object) {
  805. let textField: NSTextField = obj.object as! NSTextField
  806. var value: String = ""
  807. for ch in textField.stringValue {
  808. if ch != "0" && ch != "1" && ch != "2" && ch != "3" && ch != "4" && ch != "5" && ch != "6" && ch != "7" && ch != "8" && ch != "9" {
  809. } else {
  810. if value.isEmpty && ch == "0" {
  811. } else {
  812. value.append(ch)
  813. }
  814. }
  815. }
  816. if value.isEmpty {
  817. value.append("1")
  818. } else {
  819. // if Int(value)! <= 0 {
  820. // value = "1"
  821. // } else if Int(value)! > self.prePDFView!.document!.pageCount {
  822. // let number: Int = Int(self.prePDFView!.document!.pageCount)
  823. // value = "\(number)"
  824. // }
  825. }
  826. numberTextField.stringValue = value
  827. }
  828. }
  829. func controlTextDidEndEditing(_ obj: Notification) {
  830. if numberTextField.isEqual(to: obj.object) {
  831. if (numberTextField.stringValue.isEmpty) {
  832. numberTextField.stringValue = "1"
  833. // self.prePDFView?.go(toPageIndex: 0, animated: false)
  834. self.currentPageIndex = 1
  835. self.updateBackAndNextButtonState()
  836. return
  837. }
  838. let number: Int = Int(numberTextField.stringValue)!
  839. // if number > 0 && number <= self.prePDFView!.document!.pageCount {
  840. // guard let page = self.prePDFView?.document?.page(at: UInt(number-1)) else {
  841. // return
  842. // }
  843. // self.prePDFView?.go(to: page)
  844. // currentPageIndex = number
  845. //
  846. // self.updateBackAndNextButtonState()
  847. // }
  848. }
  849. }
  850. }
  851. let kKMConvertCountKey = "KMConvertCountKey"
  852. let kKMConvertCountMax = 2
  853. extension KMConvertBaseWindowController {
  854. func convertCountIsReach() -> Bool {
  855. #if VERSION_DMG
  856. return false
  857. #else
  858. let cnt = self.getConvertCount()
  859. if (cnt >= kKMConvertCountMax) {
  860. return true
  861. }
  862. return false
  863. #endif
  864. }
  865. func recordConvertCount() {
  866. let cnt = self.getConvertCount()
  867. UserDefaults.standard.setValue(cnt+1, forKey: kKMConvertCountKey)
  868. UserDefaults.standard.synchronize()
  869. }
  870. func clearConvertRecordCount() {
  871. UserDefaults.standard.setValue(0, forKey: kKMConvertCountKey)
  872. UserDefaults.standard.synchronize()
  873. }
  874. private func getConvertCount() -> Int {
  875. return UserDefaults.standard.integer(forKey: kKMConvertCountKey)
  876. }
  877. }