123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502 |
- //
- // KMMainViewController+Action.swift
- // PDF Reader Pro
- //
- // Created by wanjun on 2022/12/15.
- //
- import Foundation
- extension KMNThumbnailBaseViewController {
- public func fileNameWithSelectedPages(_ itemIndexes: IndexSet) -> String {
- var pagesName = ""
- if (itemIndexes.count > 1) {
- pagesName.append(" pages")
- } else {
- pagesName.append(" page")
- }
-
- let docmentName = showDocument?.documentURL.deletingPathExtension().lastPathComponent ?? ""
- let tFileName = String(format: "%@ %@", pagesName,KMNTools.parseIndexSet(indexSet: itemIndexes))
- return String(format: "%@%@", docmentName,tFileName)
- }
-
- private func convertTIFFDataToPDF(_ tiffData: Data) -> Data? {
- guard let imsrc = CGImageSourceCreateWithData(tiffData as CFData, [kCGImageSourceTypeIdentifierHint: kUTTypeTIFF] as CFDictionary), CGImageSourceGetCount(imsrc) > 0, let cgImage = CGImageSourceCreateImageAtIndex(imsrc, 0, nil) else { return nil }
- let pdfData = NSMutableData(capacity: tiffData.count)
- let consumer = CGDataConsumer(data: pdfData! as CFMutableData)!
-
- var rect = CGRect(x: 0, y: 0, width: CGFloat(cgImage.width), height: CGFloat(cgImage.height))
- let ctxt = CGContext(consumer: consumer, mediaBox: &rect, nil)
- ctxt!.beginPDFPage(nil)
- ctxt!.draw(cgImage, in: rect)
- ctxt!.endPDFPage()
- ctxt!.closePDF()
-
- return pdfData as? Data
- }
-
- public func selectPages(with array: [Int]) {
- var selectIndexPaths: Set<IndexPath> = []
- for i in 0..<(showDocument?.pageCount ?? 0) {
- if array.contains(Int(i)) {
- selectIndexPaths.insert(IndexPath(item: Int(i), section: 0))
- }
- }
- collectionView.selectionIndexPaths = selectIndexPaths
- if selectIndexPaths.isEmpty { return }
-
- let firstIndexPath = selectIndexPaths.first
- collectionView.scrollToItems(at: [firstIndexPath ?? IndexPath(item: 0, section: 0)], scrollPosition: .top)
- }
-
- public func indexpathsToIndexs(indexpaths: Set<IndexPath>) -> IndexSet {
- var indexs = IndexSet()
- for indexPath in indexpaths {
- indexs.insert(indexPath.item)
- }
- return indexs
- }
-
- public func indexsToIndexpaths(indexs: IndexSet) -> Set<IndexPath> {
- var indexpaths = Set<IndexPath>()
- for index in indexs {
- indexpaths.insert(IndexPath(item: index, section: 0))
- }
- return indexpaths
- }
-
- public func insertFormPDF(insertPages: [CPDFPage],pageDex:Int) {
- var pageIndexDex: Int = pageDex
- var indexpaths = Set<IndexPath>()
- for page in insertPages {
- let isSuccessFul = showDocument?.insertPageObject(page, at: UInt(pageIndexDex))
- if(isSuccessFul == true) {
- indexpaths.insert(IndexPath(item: pageIndexDex, section: 0))
- pageIndexDex += 1
- }
- }
- refreshDatas()
- collectionView.reloadData()
- collectionView.scrollToItems(at: indexpaths, scrollPosition: .centeredVertically)
- collectionView.selectionIndexPaths = indexpaths
- }
-
- public func insertBlankPage(pageSize: CGSize,pageDex:Int) {
- var indexpaths = Set<IndexPath>()
- let isSuccessFul = showDocument?.insertBlankPage(pageSize: pageSize, at: pageDex)
- if(isSuccessFul == true) {
- indexpaths.insert(IndexPath(item: pageDex, section: 0))
- }
- refreshDatas()
- collectionView.reloadData()
- collectionView.scrollToItems(at: indexpaths, scrollPosition: .centeredVertically)
- collectionView.selectionIndexPaths = indexpaths
- }
-
- public func openDocumentWithImageFromPasteboard(_ pboard: NSPasteboard, error outError: AutoreleasingUnsafeMutablePointer<NSError?>?) -> CPDFDocument? {
- var document: CPDFDocument? = nil
- var data: Data? = nil
-
- if pboard.canReadItem(withDataConformingToTypes: [NSPasteboard.PasteboardType.pdf.rawValue]) {
- data = pboard.data(forType: NSPasteboard.PasteboardType.pdf)
- } else if pboard.canReadItem(withDataConformingToTypes: [NSPasteboard.PasteboardType.postScript.rawValue]) {
- data = pboard.data(forType: NSPasteboard.PasteboardType.postScript)
- } else if pboard.canReadItem(withDataConformingToTypes: [NSPasteboard.PasteboardType.tiff.rawValue]) {
- data = convertTIFFDataToPDF(pboard.data(forType: NSPasteboard.PasteboardType.tiff) ?? Data())
- } else {
- let images = pboard.readObjects(forClasses: [NSImage.self], options: [:])
- let strings = pboard.readObjects(forClasses: [NSAttributedString.self], options: [:])
- if images?.count ?? 0 > 0 {
- data = convertTIFFDataToPDF((images![0] as AnyObject).tiffRepresentation!)
- } else if strings?.count ?? 0 > 0 {
- data = KMOCTool.convertStringsToPDF(withString: strings ?? [""]) // convertStringsToPDF(strings!)
- }
- }
-
- if let data = data {
- document = CPDFDocument(data: data)
-
- } else if let outError = outError {
- outError.pointee = NSError(domain: "SKDocumentErrorDomain", code: 3, userInfo: [NSLocalizedDescriptionKey: NSLocalizedString("Unable to load data from clipboard", comment: "Error description")])
- }
-
- return document
- }
-
- public func insertImageFilePath(imagePath:String,pageDex:Int)->Bool{
- var isSuccessFul:Bool = false
- if (FileManager.default.fileExists(atPath: imagePath)) {
- if let image = NSImage(contentsOfFile: imagePath) {
- isSuccessFul = showDocument?.km_insertPage(image.size, withImage: imagePath, at: UInt(pageDex)) == true
- }
- }
- return isSuccessFul
- }
-
- public func rotatePages(indexPaths: Set<IndexPath>, rotateAngle: Int) {
- var tIndexPaths: Set<IndexPath> = []
- tIndexPaths = indexPaths
- for targetIndexPath in indexPaths {
- if let page = showDocument?.page(at: UInt(targetIndexPath.item)) {
- var pageRotate = page.rotation + rotateAngle
- if(pageRotate == -90) {
- pageRotate = 270
- } else if (pageRotate == 450) {
- pageRotate = 90
- }
- page.rotation = pageRotate
-
- let cellView = collectionView.item(at: targetIndexPath) as? KMNThumbnailCollectionViewItem
- if(cellView != nil) {
- cellView?.thumbnailMode.removeCacheImage()
- }
- }
- }
-
- collectionView.reloadItems(at: tIndexPaths) // Ensure correct type conversion
- collectionView.selectionIndexPaths = tIndexPaths
- }
-
- public func reversePages(indexs: IndexSet) {
- if let doc = showDocument {
- var theIdxs = indexs
- var res = false
- for _ in 0 ..< indexs.count {
- guard let first = theIdxs.first else {
- break
- }
- guard let last = theIdxs.last else {
- break
- }
- if first == last {
- break
- }
- res = doc.exchangePage(at: UInt(first), withPageAt: UInt(last))
- if res {
- theIdxs.remove(first)
- theIdxs.remove(last)
-
- }
- }
- if res {
- refreshDatas()
- let selected_indexpaths = self.indexsToIndexpaths(indexs: indexs)
- collectionView.reloadItems(at: selected_indexpaths)
-
- collectionView.selectionIndexPaths = selected_indexpaths
- }
- }
- }
-
- public func replacePages(of targetIndexpaths: Set<IndexPath>, with documents: [CPDFDocument]) {
- if (targetIndexpaths.count == 0 || documents.count == 0) {
- KMPrint("replace invalid.")
- return
- }
- var index = targetIndexpaths.sorted().first!.item
- var tIndexPaths: Set<IndexPath> = []
-
- var indexSet = indexpathsToIndexs(indexpaths: targetIndexpaths)
-
- showDocument?.removePage(at: indexSet)
- for document in documents {
- for i in 0 ..< document.pageCount {
- let page = document.page(at: i)
- self.showDocument?.insertPageObject(page, at: UInt(index))
- tIndexPaths.insert(IndexPath(item: index, section: 0))
- index += 1
- }
- thumbnailBaseViewDelegate?.insertPDFThumbnailViewControlle?(pageEditVC: self, pdfDocment: document)
- }
-
- refreshDatas()
- collectionView.reloadData()
-
- collectionView.selectionIndexPaths = tIndexPaths
- }
-
- public func deletePages(indexpaths:Set<IndexPath>) {
- var changeIndex:IndexSet = []
- var tIndexPaths: Set<IndexPath> = []
- tIndexPaths = indexpaths
- for targetIndexPath in tIndexPaths {
- changeIndex.insert(targetIndexPath.item)
-
- let cellView = collectionView.item(at: targetIndexPath) as? KMNThumbnailCollectionViewItem
- if(cellView != nil) {
- cellView?.thumbnailMode.removeCacheImage()
- }
- }
- showDocument?.removePage(at: changeIndex)
- refreshDatas()
- collectionView.deleteItems(at: tIndexPaths)
- }
-
- public func movePages(pages:[CPDFPage],destinationDex:Int) {
- var destinationIndex = destinationDex
-
- for dragPage in dragLocalityPages {
- let dragIndex = dragPage.pageIndex()
- if destinationIndex > dragIndex {
- destinationIndex -= 1
- showDocument?.movePage(at: dragIndex, withPageAt: UInt(destinationIndex))
- } else {
- showDocument?.movePage(at: dragIndex, withPageAt: UInt(destinationIndex))
- }
- destinationIndex += 1
- }
-
- var selectArray:[Int] = []
- for dragPage in dragLocalityPages {
- let dragIndex = dragPage.pageIndex()
- selectArray.append(Int(dragIndex))
- }
-
- refreshDatas()
- collectionView.reloadData()
- self.selectPages(with: selectArray)
- }
-
- public func insertFromFilePath(fileNames:[String],formDex:Int,indexDex:UInt,selectIndexs:[Int],completionBlock:@escaping ([Int])->Void)-> Void {
- let path = fileNames[formDex]
- var insertDex = indexDex
- var tSelectIndex = selectIndexs
-
- let pathExtension = URL(fileURLWithPath: path).pathExtension.lowercased()
- if pathExtension == "pdf", let pdf = CPDFDocument(url: URL(fileURLWithPath: path)) {
- if pdf.isLocked {
- KMNBaseWindowController.checkPassword(url: pdf.documentURL, type: .owner) { success, resultPassword in
- if (resultPassword.isEmpty == false) {
- pdf.unlock(withPassword: resultPassword)
-
- for i in 0 ..< pdf.pageCount {
- let insertPage = pdf.page(at: i)
- self.showDocument?.insertPageObject(insertPage, at: insertDex)
- tSelectIndex.append(Int(insertDex))
- insertDex += 1
- }
-
- var tFormDex = formDex
- tFormDex += 1
- self.thumbnailBaseViewDelegate?.insertPDFThumbnailViewControlle?(pageEditVC: self, pdfDocment: pdf)
- if(tFormDex < fileNames.count) {
- return self.insertFromFilePath(fileNames: fileNames, formDex: tFormDex, indexDex: indexDex, selectIndexs: tSelectIndex,completionBlock: completionBlock)
- } else {
- return completionBlock(tSelectIndex)
- }
- }
- }
- } else {
- for i in 0 ..< pdf.pageCount {
- let insertPage = pdf.page(at: i)
- showDocument?.insertPageObject(insertPage ?? CPDFPage(), at: insertDex)
- tSelectIndex.append(Int(insertDex))
- insertDex += 1
- }
- var tFormDex = formDex
- tFormDex += 1
- self.thumbnailBaseViewDelegate?.insertPDFThumbnailViewControlle?(pageEditVC: self, pdfDocment: pdf)
- if(tFormDex < fileNames.count) {
- return self.insertFromFilePath(fileNames: fileNames, formDex: tFormDex, indexDex: indexDex, selectIndexs: tSelectIndex,completionBlock: completionBlock)
- } else {
- return completionBlock(tSelectIndex)
- }
-
- }
- } else if supportDragFileTypes().contains(pathExtension) {
- if KMConvertPDFManager.supportImages().contains(pathExtension) {
- let isSueccessFul = insertImageFilePath(imagePath: path, pageDex: Int(indexDex))
- if(isSueccessFul) {
- tSelectIndex.append(Int(insertDex))
- insertDex += 1
- }
-
- var tFormDex = formDex
- tFormDex += 1
- if(tFormDex < fileNames.count) {
- return self.insertFromFilePath(fileNames: fileNames, formDex: tFormDex, indexDex: indexDex, selectIndexs: tSelectIndex,completionBlock: completionBlock)
- } else {
- return completionBlock(tSelectIndex)
- }
-
- } else {
- convertOffice(filePath: path) { convertPDFPath in
- if (convertPDFPath != nil) {
- let pathExtension = URL(fileURLWithPath: convertPDFPath!).pathExtension.lowercased()
- if pathExtension == "pdf", let pdf = CPDFDocument(url: URL(fileURLWithPath: convertPDFPath!)) {
- for i in 0 ..< pdf.pageCount {
- let insertPage = pdf.page(at: i)
- self.showDocument?.insertPageObject(insertPage, at: insertDex)
- tSelectIndex.append(Int(insertDex))
- insertDex += 1
- }
- self.thumbnailBaseViewDelegate?.insertPDFThumbnailViewControlle?(pageEditVC: self, pdfDocment: pdf)
- var tFormDex = formDex
- tFormDex += 1
- if(tFormDex < fileNames.count) {
- return self.insertFromFilePath(fileNames: fileNames, formDex: tFormDex, indexDex: indexDex, selectIndexs: tSelectIndex,completionBlock: completionBlock)
- } else {
- return completionBlock(tSelectIndex)
- }
-
- }
- }
- }
- }
-
- }
- }
-
- private func convertOffice(filePath: String, completionBlock:@escaping (String?)->Void) -> Void {
- let today = Date()
- let dateFormatter = DateFormatter()
- dateFormatter.dateFormat = "yyyy-MM-dd HH:mm:ss"
- let dateString = dateFormatter.string(from: today)
- let folderPath = "convertToPDF_office_" + dateString + "." + "pdf"
- let savePath: String? = folderPath.kUrlToPDFFolderPath() as String
-
- KMConvertPDFManager.convertFile(filePath, savePath: savePath!) { success, errorDic in
- if errorDic != nil || !success || !FileManager.default.fileExists(atPath: savePath!) {
-
- if FileManager.default.fileExists(atPath: savePath!) {
- try?FileManager.default.removeItem(atPath: savePath!)
- }
- let alert = NSAlert.init()
- alert.alertStyle = .critical
- var infoString = ""
- if errorDic != nil {
- for key in (errorDic! as Dictionary).keys {
- infoString = infoString.appendingFormat("%@\n", errorDic![key] as! CVarArg)
- }
- }
- alert.informativeText = NSLocalizedString("Please install Microsoft Office to create PDFs from Office files", comment: "")
- alert.messageText = NSLocalizedString("Failed to Create PDF", comment: "")
- alert.addButton(withTitle: NSLocalizedString("OK", comment: ""))
- alert.runModal()
- completionBlock(nil)
- return
- }
-
- if !savePath!.isPDFValid() {
- let alert = NSAlert()
- alert.alertStyle = .critical
- alert.messageText = NSLocalizedString("An error occurred while opening this document. The file is damaged and could not be repaired.", comment: "")
- alert.runModal()
- completionBlock(nil)
- return
- }
- completionBlock(savePath)
- }
-
- }
-
- public func extractPages(indexpaths: Set<IndexPath>, oneDocumentPerPage: Bool, callback: @escaping KMResultBlock) {
- let pageIndexs = self.indexpathsToIndexs(indexpaths: indexpaths)
- let oneDocument = !oneDocumentPerPage
- let document = self.showDocument!
- /// 提取的页面
- var extractPages: Array<CPDFPage> = []
- for i in pageIndexs {
- extractPages.append(document.page(at: UInt(i)))
- }
-
- if (oneDocument) { /// 提取为一个文档
- var fileName = document.documentURL.deletingPathExtension().lastPathComponent
- fileName.append(" pages ")
- fileName.append(KMNTools.newParseSelectedIndexs(selectedIndex: pageIndexs.sorted()))
- fileName.append(".pdf")
- NSPanel.savePanel(self.view.window!, true) { panel in
- panel.nameFieldStringValue = fileName
- } completion: { response, url, isOpen in
- if (response != .OK) {
- callback(.cancel)
- return
- }
-
- DispatchQueue.main.asyncAfter(deadline: .now() + 0.5) {
- DispatchQueue.global().async {
- var success = false
- let pdf = CPDFDocument.init()
- success = pdf!.extractAsOneDocument(withPages: extractPages, savePath: url!.path)
- DispatchQueue.main.async {
- if (success == false) {
- callback(.failure)
- return
- }
-
- if (isOpen == false) {
- NSWorkspace.shared.activateFileViewerSelecting([url!])
- } else {
- NSDocumentController.shared.km_safe_openDocument(withContentsOf: url!, display: true) { _, _, _ in
- }
- }
- callback(.success, [url!])
- }
- }
- }
- }
- return
- } else {
- let panel = NSOpenPanel()
- panel.canChooseFiles = false
- panel.canChooseDirectories = true
- panel.canCreateDirectories = true
- panel.allowsMultipleSelection = false
- panel.beginSheetModal(for: self.view.window!) { response in
- if response != .OK {
- callback(.cancel)
- return
- }
- DispatchQueue.main.asyncAfter(deadline: .now() + 0.5) {
- let outputURL = panel.url
- DispatchQueue.global().async {
- let folderName = String((document.documentURL.lastPathComponent.split(separator: ".")[0])) + "_extract"
-
- var filePath = URL(fileURLWithPath: outputURL!.path).appendingPathComponent(folderName).path
- var i = 1
- let testFilePath = filePath
- while FileManager.default.fileExists(atPath: filePath) {
- filePath = testFilePath + "\(i)"
- i += 1
- }
-
- try? FileManager.default.createDirectory(atPath: filePath, withIntermediateDirectories: false, attributes: nil)
-
- var successArray: [URL]?
- successArray = document.extractPerPageDocument(withPages: extractPages, folerPath: filePath)
-
- DispatchQueue.main.async {
- if successArray!.count == 0 {
- callback(.failure)
- return
- }
- NSWorkspace.shared.activateFileViewerSelecting(successArray!)
-
- callback(.success, successArray ?? NSURL())
- }
- }
- }
- }
- }
-
- }
-
- }
|