KMNThumbnailBaseViewController+Action.swift 19 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443
  1. //
  2. // KMMainViewController+Action.swift
  3. // PDF Reader Pro
  4. //
  5. // Created by wanjun on 2022/12/15.
  6. //
  7. import Foundation
  8. extension KMNThumbnailBaseViewController {
  9. private func undoDeleteIndexPaths(deleteIndexPath: Set<IndexPath>) {
  10. var changeIndex:IndexSet = []
  11. for targetIndexPath in deleteIndexPath {
  12. changeIndex.insert(targetIndexPath.item)
  13. }
  14. showDocument?.removePage(at: changeIndex)
  15. refreshDatas()
  16. collectionView.reloadData()
  17. }
  18. private func undoInsertPages(insertPages:[CPDFPage],deleteIndexs: [Int]) {
  19. var indexpaths = Set<IndexPath>()
  20. for (i, page) in insertPages.enumerated() {
  21. let index = deleteIndexs[i]
  22. showDocument?.insertPageObject(page, at: UInt(index))
  23. indexpaths.insert(IndexPath(item: index, section: 0))
  24. }
  25. refreshDatas()
  26. collectionView.reloadData()
  27. collectionView.scrollToItems(at: indexpaths, scrollPosition: .centeredVertically)
  28. collectionView.selectionIndexPaths = indexpaths
  29. }
  30. private func undoRotatePages(indexPaths: Set<IndexPath>, rotateAngle: Int) {
  31. var tIndexPaths: Set<IndexPath> = []
  32. tIndexPaths = indexPaths
  33. for targetIndexPath in indexPaths {
  34. if let page = showDocument?.page(at: UInt(targetIndexPath.item)) {
  35. var pageRotate = page.rotation + rotateAngle
  36. if(pageRotate == -90) {
  37. pageRotate = 270
  38. } else if (pageRotate == 450) {
  39. pageRotate = 90
  40. }
  41. page.rotation = pageRotate
  42. }
  43. }
  44. collectionView.reloadItems(at: tIndexPaths) // Ensure correct type conversion
  45. collectionView.selectionIndexPaths = tIndexPaths
  46. }
  47. private func undoReplacePages(replacePages:[CPDFPage],orgPages:[CPDFPage]) {
  48. }
  49. private func undomovePages(movePages:[CPDFPage],orgIndexs:[Int]) {
  50. }
  51. private func undoReversePages(indexs: IndexSet) {
  52. }
  53. func insertFileComplete(newSelectIndexs: Set<IndexPath>){
  54. refreshDatas()
  55. collectionView.reloadData()
  56. collectionView.selectionIndexPaths = newSelectIndexs
  57. if newSelectIndexs.isEmpty { return }
  58. let firstIndexPath = newSelectIndexs.first
  59. collectionView.scrollToItems(at: [firstIndexPath ?? IndexPath(item: 0, section: 0)], scrollPosition: .top)
  60. }
  61. public func insertFormPages(insertPages: [CPDFPage],pageDex:Int) {
  62. var pageIndexDex: Int = pageDex
  63. var indexpaths = Set<IndexPath>()
  64. let page = insertPages.first
  65. if page?.document == showDocument {
  66. for (i, page) in insertPages.enumerated() {
  67. let isSuccessFul:Bool = showDocument?.insertPageObject(page, at: UInt(pageIndexDex+i)) == true
  68. if(isSuccessFul == true) {
  69. indexpaths.insert(IndexPath(item: pageIndexDex+i, section: 0))
  70. }
  71. }
  72. } else {
  73. if let pasteDocument = page?.document {
  74. var indexs: IndexSet = IndexSet()
  75. for (i, page) in insertPages.enumerated() {
  76. indexs.insert(Int(pasteDocument.index(for: page)))
  77. indexpaths.insert(IndexPath(item: pageIndexDex+i, section: 0))
  78. }
  79. let isSuccessFul:Bool = showDocument?.importPages(indexs, from: pasteDocument, at: UInt(pageIndexDex)) == true
  80. if(isSuccessFul == false){
  81. return
  82. }
  83. }
  84. }
  85. refreshDatas()
  86. collectionView.reloadData()
  87. collectionView.scrollToItems(at: indexpaths, scrollPosition: .centeredVertically)
  88. collectionView.selectionIndexPaths = indexpaths
  89. }
  90. public func insertBlankSize(pageSize: CGSize,pageDex:Int) {
  91. var indexpaths = Set<IndexPath>()
  92. let isSuccessFul = showDocument?.insertBlankPage(pageSize: pageSize, at: pageDex)
  93. if(isSuccessFul == true) {
  94. indexpaths.insert(IndexPath(item: pageDex, section: 0))
  95. }
  96. refreshDatas()
  97. collectionView.reloadData()
  98. collectionView.scrollToItems(at: indexpaths, scrollPosition: .centeredVertically)
  99. collectionView.selectionIndexPaths = indexpaths
  100. }
  101. public func insertImageFilePath(imagePath:String,pageDex:Int)->Bool{
  102. var isSuccessFul:Bool = false
  103. if (FileManager.default.fileExists(atPath: imagePath)) {
  104. if let image = NSImage(contentsOfFile: imagePath) {
  105. isSuccessFul = showDocument?.km_insertPage(image.size, withImage: imagePath, at: UInt(pageDex)) == true
  106. }
  107. }
  108. return isSuccessFul
  109. }
  110. public func rotatePages(indexPaths: Set<IndexPath>, rotateAngle: Int) {
  111. var tIndexPaths: Set<IndexPath> = []
  112. tIndexPaths = indexPaths
  113. for targetIndexPath in indexPaths {
  114. if let page = showDocument?.page(at: UInt(targetIndexPath.item)) {
  115. var pageRotate = page.rotation + rotateAngle
  116. if(pageRotate == -90) {
  117. pageRotate = 270
  118. } else if (pageRotate == 450) {
  119. pageRotate = 90
  120. }
  121. page.rotation = pageRotate
  122. let cellView = collectionView.item(at: targetIndexPath) as? KMNThumbnailCollectionViewItem
  123. if(cellView != nil) {
  124. cellView?.thumbnailMode.removeCacheImage()
  125. }
  126. }
  127. }
  128. collectionView.reloadItems(at: tIndexPaths) // Ensure correct type conversion
  129. collectionView.selectionIndexPaths = tIndexPaths
  130. }
  131. public func reversePages(indexs: IndexSet) {
  132. if let doc = showDocument {
  133. var theIdxs = indexs
  134. var res = false
  135. for _ in 0 ..< indexs.count {
  136. guard let first = theIdxs.first else {
  137. break
  138. }
  139. guard let last = theIdxs.last else {
  140. break
  141. }
  142. if first == last {
  143. break
  144. }
  145. res = doc.exchangePage(at: UInt(first), withPageAt: UInt(last))
  146. if res {
  147. theIdxs.remove(first)
  148. theIdxs.remove(last)
  149. }
  150. }
  151. if res {
  152. refreshDatas()
  153. let selected_indexpaths = KMNTools.indexsToIndexpaths(indexs: indexs)
  154. collectionView.reloadItems(at: selected_indexpaths)
  155. collectionView.selectionIndexPaths = selected_indexpaths
  156. }
  157. }
  158. }
  159. public func replacePages(of targetIndexpaths: Set<IndexPath>, with documents: [CPDFDocument]) {
  160. if (targetIndexpaths.count == 0 || documents.count == 0) {
  161. KMPrint("replace invalid.")
  162. return
  163. }
  164. var index = targetIndexpaths.sorted().first!.item
  165. var tIndexPaths: Set<IndexPath> = []
  166. var indexSet = KMNTools.indexpathsToIndexs(indexpaths: targetIndexpaths)
  167. showDocument?.removePage(at: indexSet)
  168. for document in documents {
  169. for i in 0 ..< document.pageCount {
  170. let page = document.page(at: i)
  171. showDocument?.insertPageObject(page, at: UInt(index))
  172. tIndexPaths.insert(IndexPath(item: index, section: 0))
  173. index += 1
  174. }
  175. thumbnailBaseViewDelegate?.insertPDFThumbnailViewControlle?(pageEditVC: self, pdfDocment: document)
  176. }
  177. refreshDatas()
  178. collectionView.reloadData()
  179. collectionView.selectionIndexPaths = tIndexPaths
  180. }
  181. public func deletePages(indexpaths:Set<IndexPath>) {
  182. var changeIndex:IndexSet = []
  183. var deletePages:[CPDFPage] = []
  184. for targetIndexPath in indexpaths {
  185. let dex = targetIndexPath.item
  186. deletePages.append(showDocument?.page(at: UInt(targetIndexPath.item)) ?? CPDFPage())
  187. changeIndex.insert(targetIndexPath.item)
  188. }
  189. showDocument?.removePage(at: changeIndex)
  190. refreshDatas()
  191. collectionView.reloadData()
  192. }
  193. public func movePages(pages:[CPDFPage],destinationDex:Int) {
  194. var destinationIndex = destinationDex
  195. for dragPage in dragLocalityPages {
  196. let dragIndex = dragPage.pageIndex()
  197. if destinationIndex > dragIndex {
  198. destinationIndex -= 1
  199. showDocument?.movePage(at: dragIndex, withPageAt: UInt(destinationIndex))
  200. } else {
  201. showDocument?.movePage(at: dragIndex, withPageAt: UInt(destinationIndex))
  202. }
  203. destinationIndex += 1
  204. }
  205. var selectIndexPaths: Set<IndexPath> = []
  206. for dragPage in dragLocalityPages {
  207. let dragIndex = dragPage.pageIndex()
  208. selectIndexPaths.insert(IndexPath(item: Int(dragIndex), section: 0))
  209. }
  210. refreshDatas()
  211. collectionView.reloadData()
  212. collectionView.selectionIndexPaths = selectIndexPaths
  213. if selectIndexPaths.isEmpty { return }
  214. let firstIndexPath = selectIndexPaths.first
  215. collectionView.scrollToItems(at: [firstIndexPath ?? IndexPath(item: 0, section: 0)], scrollPosition: .top)
  216. }
  217. public func insertFromFilePath(fileNames:[String],formDex:Int,indexDex:UInt,selectIndexs:Set<IndexPath>,completionBlock:@escaping (Set<IndexPath>)->Void)-> Void {
  218. let path = fileNames[formDex]
  219. var insertDex = indexDex
  220. var tSelectIndex = selectIndexs
  221. let pathExtension = URL(fileURLWithPath: path).pathExtension.lowercased()
  222. if pathExtension == "pdf", let pdf = CPDFDocument(url: URL(fileURLWithPath: path)) {
  223. if pdf.isLocked {
  224. KMNBaseWindowController.checkPassword(url: pdf.documentURL, type: .owner) { success, resultPassword in
  225. if (resultPassword.isEmpty == false) {
  226. pdf.unlock(withPassword: resultPassword)
  227. for i in 0 ..< pdf.pageCount {
  228. let insertPage = pdf.page(at: i)
  229. self.showDocument?.insertPageObject(insertPage, at: insertDex)
  230. tSelectIndex.insert(IndexPath(item: Int(insertDex), section:0))
  231. insertDex += 1
  232. }
  233. var tFormDex = formDex
  234. tFormDex += 1
  235. self.thumbnailBaseViewDelegate?.insertPDFThumbnailViewControlle?(pageEditVC: self, pdfDocment: pdf)
  236. if(tFormDex < fileNames.count) {
  237. return self.insertFromFilePath(fileNames: fileNames, formDex: tFormDex, indexDex: indexDex, selectIndexs: tSelectIndex,completionBlock: completionBlock)
  238. } else {
  239. self.insertFileComplete(newSelectIndexs: tSelectIndex)
  240. return completionBlock(tSelectIndex)
  241. }
  242. }
  243. }
  244. } else {
  245. for i in 0 ..< pdf.pageCount {
  246. let insertPage = pdf.page(at: i)
  247. showDocument?.insertPageObject(insertPage ?? CPDFPage(), at: insertDex)
  248. tSelectIndex.insert(IndexPath(item: Int(insertDex), section:0))
  249. insertDex += 1
  250. }
  251. var tFormDex = formDex
  252. tFormDex += 1
  253. thumbnailBaseViewDelegate?.insertPDFThumbnailViewControlle?(pageEditVC: self, pdfDocment: pdf)
  254. if(tFormDex < fileNames.count) {
  255. return insertFromFilePath(fileNames: fileNames, formDex: tFormDex, indexDex: indexDex, selectIndexs: tSelectIndex,completionBlock: completionBlock)
  256. } else {
  257. insertFileComplete(newSelectIndexs: tSelectIndex)
  258. return completionBlock(tSelectIndex)
  259. }
  260. }
  261. } else if supportDragFileTypes().contains(pathExtension) {
  262. if KMConvertPDFManager.supportImages().contains(pathExtension) {
  263. let isSueccessFul = insertImageFilePath(imagePath: path, pageDex: Int(indexDex))
  264. if(isSueccessFul) {
  265. tSelectIndex.insert(IndexPath(item: Int(insertDex), section:0))
  266. insertDex += 1
  267. }
  268. var tFormDex = formDex
  269. tFormDex += 1
  270. if(tFormDex < fileNames.count) {
  271. return insertFromFilePath(fileNames: fileNames, formDex: tFormDex, indexDex: indexDex, selectIndexs: tSelectIndex,completionBlock: completionBlock)
  272. } else {
  273. insertFileComplete(newSelectIndexs: tSelectIndex)
  274. return completionBlock(tSelectIndex)
  275. }
  276. } else {
  277. KMNConvertTool.convertOffice(filePath: path) { convertPDFPath in
  278. if (convertPDFPath != nil) {
  279. let pathExtension = URL(fileURLWithPath: convertPDFPath!).pathExtension.lowercased()
  280. if pathExtension == "pdf", let pdf = CPDFDocument(url: URL(fileURLWithPath: convertPDFPath!)) {
  281. for i in 0 ..< pdf.pageCount {
  282. let insertPage = pdf.page(at: i)
  283. self.showDocument?.insertPageObject(insertPage, at: insertDex)
  284. tSelectIndex.insert(IndexPath(item: Int(insertDex), section:0))
  285. insertDex += 1
  286. }
  287. self.thumbnailBaseViewDelegate?.insertPDFThumbnailViewControlle?(pageEditVC: self, pdfDocment: pdf)
  288. var tFormDex = formDex
  289. tFormDex += 1
  290. if(tFormDex < fileNames.count) {
  291. return self.insertFromFilePath(fileNames: fileNames, formDex: tFormDex, indexDex: indexDex, selectIndexs: tSelectIndex,completionBlock: completionBlock)
  292. } else {
  293. self.insertFileComplete(newSelectIndexs: tSelectIndex)
  294. return completionBlock(tSelectIndex)
  295. }
  296. }
  297. }
  298. }
  299. }
  300. }
  301. }
  302. public func extractPages(indexpaths: Set<IndexPath>, oneDocumentPerPage: Bool, callback: @escaping KMResultBlock) {
  303. let pageIndexs = KMNTools.indexpathsToIndexs(indexpaths: indexpaths)
  304. let oneDocument = !oneDocumentPerPage
  305. let document = self.showDocument!
  306. /// 提取的页面
  307. var extractPages: Array<CPDFPage> = []
  308. for i in pageIndexs {
  309. extractPages.append(document.page(at: UInt(i)))
  310. }
  311. if (oneDocument) { /// 提取为一个文档
  312. var fileName = document.documentURL.deletingPathExtension().lastPathComponent
  313. fileName.append(" pages ")
  314. fileName.append(KMNTools.newParseSelectedIndexs(selectedIndex: pageIndexs.sorted()))
  315. fileName.append(".pdf")
  316. NSPanel.savePanel(self.view.window!, true) { panel in
  317. panel.nameFieldStringValue = fileName
  318. } completion: { response, url, isOpen in
  319. if (response != .OK) {
  320. callback(.cancel)
  321. return
  322. }
  323. DispatchQueue.main.asyncAfter(deadline: .now() + 0.5) {
  324. DispatchQueue.global().async {
  325. var success = false
  326. let pdf = CPDFDocument.init()
  327. success = pdf!.extractAsOneDocument(withPages: extractPages, savePath: url!.path)
  328. DispatchQueue.main.async {
  329. if (success == false) {
  330. callback(.failure)
  331. return
  332. }
  333. if (isOpen == false) {
  334. NSWorkspace.shared.activateFileViewerSelecting([url!])
  335. } else {
  336. NSDocumentController.shared.km_safe_openDocument(withContentsOf: url!, display: true) { _, _, _ in
  337. }
  338. }
  339. callback(.success, [url!])
  340. }
  341. }
  342. }
  343. }
  344. } else {
  345. let panel = NSOpenPanel()
  346. panel.canChooseFiles = false
  347. panel.canChooseDirectories = true
  348. panel.canCreateDirectories = true
  349. panel.allowsMultipleSelection = false
  350. panel.beginSheetModal(for: self.view.window!) { response in
  351. if response != .OK {
  352. callback(.cancel)
  353. return
  354. }
  355. DispatchQueue.main.asyncAfter(deadline: .now() + 0.5) {
  356. let outputURL = panel.url
  357. DispatchQueue.global().async {
  358. let folderName = String((document.documentURL.lastPathComponent.split(separator: ".")[0])) + "_extract"
  359. var filePath = URL(fileURLWithPath: outputURL!.path).appendingPathComponent(folderName).path
  360. var i = 1
  361. let testFilePath = filePath
  362. while FileManager.default.fileExists(atPath: filePath) {
  363. filePath = testFilePath + "\(i)"
  364. i += 1
  365. }
  366. try? FileManager.default.createDirectory(atPath: filePath, withIntermediateDirectories: false, attributes: nil)
  367. var successArray: [URL]?
  368. successArray = document.extractPerPageDocument(withPages: extractPages, folerPath: filePath)
  369. DispatchQueue.main.async {
  370. if successArray!.count == 0 {
  371. callback(.failure)
  372. return
  373. }
  374. NSWorkspace.shared.activateFileViewerSelecting(successArray!)
  375. callback(.success, successArray ?? NSURL())
  376. }
  377. }
  378. }
  379. }
  380. }
  381. }
  382. }