// // KMConvertWindowController.swift // PDF Reader Pro // // Created by liujiajie on 2023/11/8. // import Cocoa typealias convertBatchCallBack = () -> Void let kPreviewMaxWidth = 237.0 let kPreviewMaxHeight = 325.0 let kConvertFileSavePath = (kTempSavePath?.stringByAppendingPathComponent("convert.pdf")) @objcMembers class KMConvertWindowController: NSWindowController, NSTextFieldDelegate, NSWindowDelegate{ @IBOutlet var prePDFViewHeight: NSLayoutConstraint! @IBOutlet var prePDFViewWidth: NSLayoutConstraint! var prePDFView: CPDFView! @IBOutlet var prePdfBGView: NSView! @IBOutlet var currentPageIndexTextField: NSTextField! @IBOutlet var totalPageCountLabel: NSTextField! @IBOutlet var formatLabel: NSTextField! @IBOutlet var formatSelectButton: NSPopUpButton! @IBOutlet var imageDPISelectButton: NSPopUpButton! @IBOutlet var moreButton: NSButton! @IBOutlet var buttonBottemOffset: NSLayoutConstraint! @IBOutlet var buttonTopOffset: NSLayoutConstraint! @IBOutlet var moreConvertBox: NSBox! @IBOutlet var moreConvertLabel: NSTextField! @IBOutlet var pageRangLabel: NSTextField! @IBOutlet var allPageButton: NSButton! @IBOutlet var currentPageButton: NSButton! @IBOutlet var oddPageButton: NSButton! @IBOutlet var evenPageButton: NSButton! @IBOutlet var handInputButton: NSButton! @IBOutlet var pageRangeTextField: NSTextField! @IBOutlet var convertButton: NSButton! @IBOutlet var cancelButton: NSButton! @IBOutlet var batchButton: NSButton! @IBOutlet var upgradeButton: NSButton! @IBOutlet var separateStypeTopOffset: NSLayoutConstraint! @IBOutlet var separateButton: NSButton! @IBOutlet var singleButton: NSButton! @IBOutlet var separateStypeBox: NSBox! @IBOutlet var extractTableButton: NSButton! @IBOutlet var extractTableTopOffset: NSLayoutConstraint! @IBOutlet var separateStypeLabel: NSTextField! @IBOutlet var excelStyleBox: NSBox! @IBOutlet var onlyTextBtn: NSButton! @IBOutlet var onlyTableBtn: NSButton! @IBOutlet var allContentBtn: NSButton! @IBOutlet var tableMenu1: NSMenuItem! @IBOutlet var tableMenu2: NSMenuItem! @IBOutlet var tableMenu3: NSMenuItem! @IBOutlet var allContentMenu2: NSMenuItem! @IBOutlet var allContentMenu3: NSMenuItem! @IBOutlet var tableMenu: NSPopUpButton! @IBOutlet var allContentMenu: NSPopUpButton! @IBOutlet var box: NSBox! var isAllInOneSheet = false var modalSession: NSApplication.ModalSession? var pdfDocument: CPDFDocument? var maskView: KMBookletMaskView? var convertType: KMConvertType = .Word var imageDPINumber: Int = 0 var callBackBlock: convertBatchCallBack? var currentPage: CPDFPage? var savePath: String = "" var lockPassword: String = "" var tempPDFDocument: CPDFDocument? var excelContentOption: CPDFConvertExcelContentOptions? var excelWorksheetOption: CPDFConvertExcelWorksheetOptions? private var fileAttri_: KMFileAttribute? deinit { #if DEBUG NSLog("====KMConvertWindowController==deinit") #endif } convenience init(documemtV:CPDFDocument, currentPage:CPDFPage, convertT:KMConvertType, handle:@escaping convertBatchCallBack) { self.init(windowNibName: "KMConvertWindowController") if (documemtV.documentURL != nil) { let pageIndex = documemtV.index(for: currentPage) self.pdfDocument = CPDFDocument(url: documemtV.documentURL) let isLoc: Bool = self.pdfDocument!.isLocked if (!documemtV.isLocked && isLoc) { self.lockPassword = documemtV.password self.pdfDocument?.unlock(withPassword: self.lockPassword) } self.currentPage = self.pdfDocument?.page(at: pageIndex ) } else { self.pdfDocument = documemtV self.currentPage = currentPage } self.callBackBlock = handle if convertT.rawValue > 15 || convertT.rawValue < 0 { self.convertType = .Word } else { self.convertType = convertT } } convenience init(localPath:String, handle:@escaping convertBatchCallBack) { self.init(windowNibName: "KMConvertWindowController") self.pdfDocument = CPDFDocument(url: URL(fileURLWithPath: localPath)) self.callBackBlock = handle let isLoc: Bool = self.pdfDocument!.isLocked if (isLoc) { DispatchQueue.main.asyncAfter(deadline: DispatchTime.now() + 0.5) { let url = self.pdfDocument?.documentURL KMBaseWindowController.checkPassword(url: url!, type: .owner) { [unowned self] success, resultPassword in if success { self.lockPassword = resultPassword self.pdfDocument?.unlock(withPassword: resultPassword) self.currentPage = self.pdfDocument?.page(at: 0) self.convertType = .Word } } } } } override func windowDidLoad() { super.windowDidLoad() let preView: CPDFView = CPDFView(frame: self.prePdfBGView.bounds) self.prePdfBGView.addSubview(preView) self.prePDFView = preView self.box.fillColor = .gridColor localizedLanguage() self.currentPageIndexTextField.delegate = self; self.pageRangeTextField.delegate = self; let isLoc: Bool = self.pdfDocument!.isLocked if (isLoc) { self.showWaitting() DispatchQueue.main.asyncAfter(deadline: .now() + 0.5) { let url = URL(fileURLWithPath: self.pdfDocument!.documentURL.path) KMBaseWindowController.checkPassword(url: url, type: .owner) { result, password in self.hideWaitting() if password.count > 0 { let unlockSuccess: Bool = ((self.pdfDocument?.unlock(withPassword: password)) != nil) self.lockPassword = password if unlockSuccess { self.currentPage = self.pdfDocument?.page(at: 0) } self.configuView() } else { self.buttonClicked_Cancel(self.cancelButton) } } } } else { self.configuView() } if #available(macOS 10.14, *) { let appearanceName = NSApp.effectiveAppearance.bestMatch(from: [.aqua, .darkAqua]) if appearanceName == .darkAqua { moreConvertLabel.textColor = NSColor.white } } isAllInOneSheet = false separateButton.state = .on singleButton.state = .off allPageButton.state = .on allContentBtn.state = .on allContentMenu.isEnabled = true tableMenu.isEnabled = false excelContentOption = .allContent excelWorksheetOption = .forEachPage NotificationCenter.default.addObserver(self, selector: #selector(PDFViewDocumentChangedNotification(notification:)), name: NSNotification.Name.CPDFViewPageChanged, object: nil) } @objc func PDFViewDocumentChangedNotification(notification: NSNotification) { let pageIndex = self.prePDFView.currentPageIndex+1 self.currentPageIndexTextField.stringValue = "\(pageIndex)" } func windowShouldClose(_ sender: NSWindow) -> Bool { self.dismissSheet() return true } func localizedLanguage() { formatLabel.stringValue = KMLocalizedString("Format:", nil) separateButton.title = KMLocalizedString("Convert each page to a separate worksheet", nil) singleButton.title = KMLocalizedString("Convert all pages to a single worksheet", nil) box.title = KMLocalizedString("Page Range:", nil) separateStypeLabel.stringValue = KMLocalizedString("Excel Worksheet Settings", nil) extractTableButton.title = KMLocalizedString("Extract Tables Only", nil) allPageButton.title = KMLocalizedString("All Pages", nil) currentPageButton.title = KMLocalizedString("Current Page", nil) oddPageButton.title = KMLocalizedString("Odd Pages Only", nil) evenPageButton.title = KMLocalizedString("Even Pages Only", nil) pageRangeTextField.placeholderString = KMLocalizedString("e.g. 1,3-5,10", nil) batchButton.title = KMLocalizedString("Batch", nil) cancelButton.title = KMLocalizedString("Cancel", nil) convertButton.title = KMLocalizedString("Convert", nil) upgradeButton.title = KMLocalizedString("Upgrade", nil) onlyTextBtn.title = KMLocalizedString("Only Text", nil) onlyTableBtn.title = KMLocalizedString("Only Table", nil) allContentBtn.title = KMLocalizedString("All Content", nil) tableMenu1.title = KMLocalizedString("Create Sheet for each Table", nil) tableMenu2.title = KMLocalizedString("Create Sheet for each Page", nil) allContentMenu2.title = KMLocalizedString("Create Sheet for each Page", nil) tableMenu3.title = KMLocalizedString("Create single Sheet for File", nil) allContentMenu3.title = KMLocalizedString("Create single Sheet for File", nil) } func hideWaitting() { maskView?.removeFromSuperview() } func showWaitting() { if maskView == nil { maskView = KMBookletMaskView(frame: CGRect(x: 0, y: 0, width: self.window?.frame.size.width ?? 0, height: self.window?.frame.size.height ?? 0)) } self.window?.contentView?.addSubview(maskView!) } func configuView() { self.prePDFView.autoScales = true self.prePDFView.wantsLayer = true self.prePDFView.document = self.pdfDocument self.imageDPISelectButton.removeAllItems() self.formatSelectButton.removeAllItems() let dpiArray = ["50 dpi", "72 dpi", "96 dpi", "150 dpi", "300 dpi", "600 dpi"] let formArray = ["Excel (.xlsx)", "PowerPoint (.pptx)", "RTF (.rtf)", "CSV (.csv)", "Html (.html)", "Text (.txt)", "JPEG (.jpeg)", "JPG (.jpg)", "PNG (.png)", "GIF (.gif)", "TIFF (.tiff)", "TGA (.tga)", "BMP (.bmp)", "JPEG-2000 (.jp2)"] for (index, string) in formArray.enumerated() { let item = NSMenuItem() item.title = string item.target = self item.tag = index + 1 self.formatSelectButton.menu?.addItem(item) } var isShowAdvanced = false let wordItem = NSMenuItem() wordItem.title = "Word (.docx)" wordItem.target = self var isShowUpgrade = false var convertSample: KMConvertType = .Word #if VERSION_FREE #if VERSION_DMG // 桌机版 wordItem.tag = convertSample.rawValue isShowAdvanced = true if IAPProductsManager.default().isAvailableAllFunction() { if IAPProductsManager.default().isAvailableAdvancedPDFToOffice() { convertSample = .AdvancedWord wordItem.tag = convertSample.rawValue isShowAdvanced = false } else { isShowUpgrade = true } } else { isShowUpgrade = true } #else // 免费版 convertSample = .Word wordItem.tag = convertSample.rawValue isShowAdvanced = true if IAPProductsManager.default().isAvailableAllFunction() { if IAPProductsManager.default().isAvailableAdvancedPDFToOffice() { convertSample = .AdvancedWord wordItem.tag = convertSample.rawValue isShowAdvanced = false } else { isShowUpgrade = true } } else { isShowUpgrade = true } #endif #else convertSample = .Word wordItem.tag = convertSample.rawValue // 付费版 isShowAdvanced = true if IAPProductsManager.default().isAvailableAdvancedPDFToOffice() { isShowAdvanced = false convertSample = .AdvancedWord wordItem.tag = convertSample.rawValue } else { isShowUpgrade = true } #endif if wordItem.title != "" { if isShowAdvanced { let originStr = " \(KMLocalizedString("Standard", nil)) " let str = KMLocalizedString("Word (.docx)", nil) let attributedStr = NSMutableAttributedString(string: "\(str) \(originStr)") attributedStr.addAttribute(NSAttributedString.Key.backgroundColor, value: NSColor(red: 40/255.0, green: 193.0/255.0, blue: 107.0/255.0, alpha: 1.0), range: NSMakeRange(str.count + 2, originStr.count)) attributedStr.addAttribute(NSAttributedString.Key.foregroundColor, value: NSColor.white, range: NSMakeRange(str.count + 2, originStr.count)) let item = NSMenuItem() item.attributedTitle = attributedStr item.target = self item.tag = wordItem.tag self.formatSelectButton.menu?.insertItem(item, at: 0) } else { self.formatSelectButton.menu?.insertItem(wordItem, at: 0) } } if !isShowUpgrade { self.upgradeButton.isHidden = true } var selectIndex = 0 if isShowAdvanced { let originStr = " \(NSLocalizedString("Advanced", comment: "")) " let str = NSLocalizedString("Word (.docx)", comment: "") let attributedStr = NSMutableAttributedString(string: "\(str) \(originStr)") attributedStr.addAttribute(NSAttributedString.Key.backgroundColor, value: NSColor(red: 245.0/255.0, green: 142.0/255.0, blue: 38.0/255.0, alpha: 1.0), range: NSMakeRange(str.count + 2, originStr.count)) attributedStr.addAttribute(NSAttributedString.Key.foregroundColor, value: NSColor.white, range: NSMakeRange(str.count + 2, originStr.count)) let item = NSMenuItem() item.attributedTitle = attributedStr item.target = self convertSample = .AdvancedWord item.tag = convertSample.rawValue self.formatSelectButton.menu?.insertItem(item, at: 0) } if self.convertType == .Word { selectIndex = 0 } else { selectIndex = self.convertType.rawValue if isShowAdvanced { selectIndex += 1 } if wordItem.title == "" { selectIndex -= 1 } } self.formatSelectButton.selectItem(at: selectIndex) let item = self.formatSelectButton.selectedItem self.convertType = KMConvertType(rawValue: item?.tag ?? 0) ?? .Word self.imageDPISelectButton.isHidden = true self.buttonTopOffset.constant = -26 self.imageDPISelectButton.addItems(withTitles: dpiArray) self.imageDPISelectButton.selectItem(at: 3) self.imageDPINumber = 150 self.totalPageCountLabel.stringValue = " / \(self.pdfDocument?.pageCount ?? 1)" self.totalPageCountLabel.textColor = KMAppearance.Layout.h2Color() self.updataView() self.prePDFView.go(to: currentPage) let pageIndex = self.prePDFView.currentPageIndex+1 self.currentPageIndexTextField.stringValue = "\(pageIndex)" if let documentURL = self.pdfDocument?.documentURL{ self.pdfDocument = CPDFDocument(url: documentURL) if !lockPassword.isEmpty && lockPassword.count > 0{ self.pdfDocument?.unlock(withPassword: lockPassword) } self.prePDFView.document = self.pdfDocument self.fileAttri_ = KMFileAttribute() self.fileAttri_?.filePath = documentURL.path } self.prePDFView.setDisplay(.singlePage) self.prePDFView.layoutDocumentView() } func updataView() { var moreLabelString: String = "" var offset: CGFloat = 0 excelStyleBox.isHidden = true #if VERSION_FREE // 座机版 if !IAPProductsManager.default().isAvailableAllFunction() { moreLabelString = String(format: "%@ %@", KMLocalizedString("The first 10 pages for free"), KMLocalizedString("Unlimited Convert")) } else { if !IAPProductsManager.default().isAvailableAdvancedPDFToOffice() { if .Word == self.convertType || self.convertType == .AdvancedWord || .Excel == self.convertType || .PPT == self.convertType || .CSV == self.convertType || .RTF == self.convertType || .GIF == self.convertType || .TIFF == self.convertType || .JP2 == self.convertType || .BMP == self.convertType || .TGA == self.convertType { moreLabelString = String(format: "%@ %@", KMLocalizedString("The first 10 pages for free"), KMLocalizedString("Unlimited Convert")) } } } #else // 付费版 if !(IAPProductsManager.default().isAvailableAdvancedPDFToOffice()) { if .Word == self.convertType || self.convertType == .AdvancedWord || .Excel == self.convertType || .PPT == self.convertType || .CSV == self.convertType || .RTF == self.convertType || .GIF == self.convertType || .TIFF == self.convertType || .JP2 == self.convertType || .BMP == self.convertType || .TGA == self.convertType { moreLabelString = String(format: "%@ %@", KMLocalizedString("The first 10 pages for free"), KMLocalizedString("Unlimited Convert")) } } #endif if convertType.rawValue >= 7 && convertType.rawValue <= 14 { offset += imageDPISelectButton.frame.size.height imageDPISelectButton.isHidden = false buttonTopOffset.constant = 5 } else { imageDPISelectButton.isHidden = true buttonTopOffset.constant = -26 } if moreLabelString.count < 1 { offset += 5 moreConvertBox.isHidden = true moreButton.isHidden = true } else { offset += (moreButton.frame.size.height + 5) moreConvertBox.isHidden = false moreButton.isHidden = false moreConvertLabel.stringValue = moreLabelString if let range = moreLabelString.range(of: NSLocalizedString("Unlimited Convert", comment: "")) { let newR: NSRange = moreLabelString.nsRange(from: range)! let attributedStr = NSMutableAttributedString(string: moreLabelString) attributedStr.addAttribute(.foregroundColor, value: NSColor.labelColor, range: NSRange(location: 0, length: newR.location - 1)) attributedStr.addAttribute(.foregroundColor, value: NSColor(red: 8/255, green: 124/255, blue: 1, alpha: 1), range: newR) attributedStr.addAttribute(.underlineStyle, value: NSUnderlineStyle.single.rawValue, range: newR) moreConvertLabel.attributedStringValue = attributedStr } } if .Excel == convertType { separateStypeTopOffset.constant = separateStypeBox.frame.size.height + 58 + 16 extractTableTopOffset.constant = separateStypeBox.frame.size.height + 50 separateStypeBox.isHidden = true extractTableButton.isHidden = true excelStyleBox.isHidden = false separateStypeLabel.isHidden = false separateStypeLabel.stringValue = NSLocalizedString("Excel Worksheet Settings", comment: "") separateButton.title = NSLocalizedString("Convert each page to a separate worksheet", comment: "") singleButton.title = NSLocalizedString("Convert all pages to a single worksheet", comment: "") buttonClicked_extractTable(extractTableButton) } else if .AdvancedWord == convertType { singleButton.setTitleColor(NSColor.labelColor) separateButton.setTitleColor(NSColor.labelColor) separateStypeLabel.textColor = NSColor.labelColor separateButton.state = NSControl.StateValue.on singleButton.isEnabled = true separateButton.isEnabled = true isAllInOneSheet = false separateStypeTopOffset.constant = separateStypeBox.frame.size.height + 40 extractTableButton.isHidden = true separateStypeBox.isHidden = false separateStypeLabel.isHidden = false separateStypeLabel.stringValue = NSLocalizedString("Layout Settings", comment: "") separateButton.title = NSLocalizedString("Retain Flowing Text", comment: "") singleButton.title = NSLocalizedString("Retain Page Layout", comment: "") } else if .CSV == convertType { separateStypeTopOffset.constant = extractTableButton.frame.size.height + 30 extractTableTopOffset.constant = 12 extractTableButton.isHidden = false separateStypeBox.isHidden = true separateStypeLabel.isHidden = true } else { separateStypeTopOffset.constant = 15 separateStypeBox.isHidden = true extractTableButton.isHidden = true separateStypeLabel.isHidden = true } buttonBottemOffset.constant = offset } @IBAction func buttonClicked_extractTable(_ sender: NSButton) { if extractTableButton.state == .on { singleButton.setTitleColor(KMAppearance.Layout.b15_1Color()) separateButton.setTitleColor(KMAppearance.Layout.b15_1Color()) separateStypeLabel.textColor = KMAppearance.Layout.b15_1Color() singleButton.isEnabled = false separateButton.isEnabled = false separateButton.state = .off singleButton.state = .off } else { singleButton.setTitleColor(NSColor.labelColor) separateButton.setTitleColor(NSColor.labelColor) separateStypeLabel.textColor = NSColor.labelColor separateButton.state = .on singleButton.isEnabled = true separateButton.isEnabled = true isAllInOneSheet = false } } @IBAction func buttonClicked_Cancel(_ sender: NSButton) { dismissSheet() } func dismissSheet() { if FileManager.default.fileExists(atPath: kConvertFileSavePath ?? "") { do { try FileManager.default.removeItem(atPath: kConvertFileSavePath ?? "") } catch { print("Error removing item at path: (error.localizedDescription)") } } // if self.prePDFView.document != nil { // self.prePDFView.document = nil // } // if self.tempPDFDocument != nil { // self.tempPDFDocument = nil // } self.km_quick_endSheet() } func showCriticalAlert(_ alertMsg: String?) { let alert = NSAlert() alert.alertStyle = .critical if let msg = alertMsg { alert.informativeText = msg } else { let st = self.pdfDocument?.documentURL.lastPathComponent.count ?? 0 > 0 ? self.pdfDocument?.documentURL.lastPathComponent : KMLocalizedString("Untitled.pdf", nil) alert.messageText = String(format: "%@ %@", st!, KMLocalizedString("Invalid page range or the page number is out of range. Please try again.", nil)) } alert.runModal() } func produceNewPDF(with pagesArray: [CPDFPage]) { tempPDFDocument = nil // if self.tempPDFDocument == nil || self.tempPDFDocument!.isLocked { self.tempPDFDocument = CPDFDocument() // } var indexs = IndexSet() let pageCount = self.pdfDocument?.pageCount ?? 0 for addedPage in pagesArray { // tempPDFDocument?.insertPageObject(addedPage, at: tempPDFDocument!.pageCount) let idx = addedPage.pageIndex() if idx >= 0 && idx < pageCount { indexs.insert(IndexSet.Element(idx)) } } // self.tempPDFDocument?.removePage(at: IndexSet(integersIn: 0..<(Int(self.tempPDFDocument?.pageCount ?? 0)))) _ = self.tempPDFDocument?.importPages(indexs, from: self.pdfDocument, at: 0) self.prePDFView.document = self.tempPDFDocument self.prePDFView.layoutDocumentView() self.prePDFView.goToFirstPage(nil) self.currentPageIndexTextField.stringValue = "1" self.totalPageCountLabel.stringValue = " / \(self.tempPDFDocument!.pageCount)" } func pageRangeSetON(_ sender: NSButton) { allPageButton.state = .off oddPageButton.state = .off evenPageButton.state = .off handInputButton.state = .off currentPageButton.state = .off sender.state = .on if sender == handInputButton { pageRangeTextField.isEditable = true pageRangeTextField.isSelectable = true // self.pageRangeTextField.textColor = NSColor.textColor window?.makeFirstResponder(pageRangeTextField) } else { pageRangeTextField.isEditable = false pageRangeTextField.isSelectable = false // self.pageRangeTextField.textColor = NSColor.lightGrayColor window?.makeFirstResponder(self) } } @IBAction func buttonClicked_FormatSelect(_ sender: NSButton) { guard let item = self.formatSelectButton.selectedItem else { return } self.convertType = KMConvertType(rawValue: item.tag) ?? .Word updataView() } func transform(with string: String) { if string == KMLocalizedString("Create Sheet for each Table", nil) { self.excelWorksheetOption = .forEachTable } else if string == KMLocalizedString("Create Sheet for each Page", nil) { self.excelWorksheetOption = .forEachPage } else if string == KMLocalizedString("Create single Sheet for File", nil) { self.excelWorksheetOption = .forTheDocument } } @IBAction func buttonClicked_excelStyle(_ sender: NSButton) { if sender.isEqual(self.onlyTextBtn) { self.tableMenu.isEnabled = false self.allContentMenu.isEnabled = false self.excelContentOption = .onlyText self.excelWorksheetOption = .forEachTable } else if (sender.isEqual(self.onlyTableBtn)) { self.tableMenu.isEnabled = true self.allContentMenu.isEnabled = false self.excelContentOption = .onlyTable transform(with: self.tableMenu.selectedItem?.title ?? "") } else if (sender.isEqual(self.allContentBtn)) { self.tableMenu.isEnabled = false self.allContentMenu.isEnabled = true self.excelContentOption = .allContent transform(with: self.allContentMenu.selectedItem?.title ?? "") } } @IBAction func buttonClicked_tableMenu(_ sender: NSButton) { transform(with: self.tableMenu.selectedItem?.title ?? "") } @IBAction func buttonClicked_allContentMenu(_ sender: NSButton) { transform(with: self.allContentMenu.selectedItem?.title ?? "") } @IBAction func buttonClicked_PageSelect(_ sender: NSButton) { pageRangeSetON(sender) self.lockPassword = "" let pagesArray = NSMutableArray() for i in 0..<(self.pdfDocument?.pageCount ?? 0) { let copyPage = self.pdfDocument?.page(at: i) pagesArray.add(copyPage!) } if sender.isEqual(self.oddPageButton) { pagesArray.subArray(type: .Odd) } else if (sender.isEqual(self.evenPageButton)) { pagesArray.subArray(type: .Even) } else if (sender.isEqual(self.currentPageButton)) { pagesArray.removeAllObjects() let page = self.prePDFView.currentPage() if (page != nil) { pagesArray.add(page as Any) } } produceNewPDF(with: pagesArray as! [CPDFPage]) // perform(#selector(produceNewPDF(with:)), with: pagesArray, afterDelay: 2) // performSelector(produceNewPDF(with:), withObject: pagesArray, afterDelay: 2) } @IBAction func buttonClicked_DpiSelect(_ sender: NSPopUpButton) { let index = sender.indexOfSelectedItem var dpi = 0 if index == 0 { dpi = 50 } else if index == 1 { dpi = 72 } else if index == 2 { dpi = 96 } else if index == 3 { dpi = 150 } else if index == 4 { dpi = 300 } else if index == 5 { dpi = 600 } self.imageDPINumber = dpi } @IBAction func buttonClick_PreviousPage(_ sender: NSButton) { if self.prePDFView.canGoToPreviousPage() { self.prePDFView.goToPreviousPage(nil) let currentIndex = self.prePDFView.document?.index(for: self.prePDFView.currentPage()) ?? 0 self.currentPageIndexTextField.stringValue = "\(currentIndex + 1)" } } @IBAction func buttonClicked_NextPage(_ sender: NSButton) { if self.prePDFView.canGoToNextPage() { self.prePDFView.goToNextPage(nil) let currentIndex = self.prePDFView.document?.index(for: self.prePDFView.currentPage()) self.currentPageIndexTextField.stringValue = "\((currentIndex ?? 0) + 1)" } } @IBAction func buttonClicked_Batch(_ sender: NSButton) { if !IAPProductsManager.default().isAvailableAllFunction() { KMPurchaseCompareWindowController.sharedInstance().showWindow(nil) return } if self.pdfDocument?.documentURL == nil { NSSound.beep() return } if self.callBackBlock != nil { self.callBackBlock!() self.callBackBlock = nil } dismissSheet() } @IBAction func buttonClicked_Convert(_ sender: Any) { self.window?.makeFirstResponder(self.prePDFView) if self.handInputButton.state == .on { if self.fileAttri_ == nil { self.fileAttri_ = KMFileAttribute() self.fileAttri_?.filePath = self.pdfDocument?.documentURL.path ?? "" } // fileAttri_.pdfDocument = self.pdfDocument self.fileAttri_?.bAllPage = false self.fileAttri_?.pagesType = .custom self.fileAttri_?.pagesString = self.pageRangeTextField.stringValue let pages = self.fileAttri_?.fetchSelectPages() ?? [] if pages.isEmpty { return } } let openPanel = NSOpenPanel() openPanel.canChooseFiles = false openPanel.canChooseDirectories = true openPanel.canCreateDirectories = true openPanel.beginSheetModal(for: self.window!) { result in if result == .OK { self.savePath = openPanel.url!.path self.beginConvert() } } } func beginConvert() { var isLimitConvert = false #if VERSION_FREE #if VERSION_DMG // 桌机版 if IAPProductsManager.default().isAvailableAllFunction() { if IAPProductsManager.default().isAvailableAdvancedPDFToOffice() { isLimitConvert = false } else { if (.PNG == self.convertType || .JPEG == self.convertType || .JPG == self.convertType || .HTML == self.convertType || .Text == self.convertType || .Word == self.convertType) { isLimitConvert = false } else { isLimitConvert = true } } } else { isLimitConvert = true } #else // 免费版 if IAPProductsManager.default().isAvailableAdvancedPDFToOffice() == false { isLimitConvert = true } #endif #else // 付费版 if IAPProductsManager.default().isAvailableAdvancedPDFToOffice() { isLimitConvert = false } else { if (.PNG == self.convertType || .JPEG == self.convertType || .JPG == self.convertType || .HTML == self.convertType || .Text == self.convertType || .Word == self.convertType) { isLimitConvert = false } else { isLimitConvert = true } } #endif self.showWaitting() let pages = NSMutableArray() DispatchQueue.global(qos: .background).async { [self] in let filePath = getConvertFileSavePath() if (FileManager.default.fileExists(atPath: filePath)) { try?FileManager.default.removeItem(atPath: filePath) } if self.prePDFView.document.write(toFile: filePath) { for i in 0..= 10 { for i in 0..<10 { selectPages.append(pages[i] as! Int) } } else { selectPages = pages as! [Int] } } else { selectPages = pages as! [Int] } let convert = KMPDFConvert() convert.filePath = filePath convert.pages = selectPages convert.isAllInOneSheet = self.isAllInOneSheet if self.convertType == .Word { convert.type = 0 } else { convert.type = 1 } convert.isExtractTable = self.extractTableButton.state == .on convert.outputFolderPath = self.savePath convert.outputFileName = (self.pdfDocument?.documentURL.deletingPathExtension().lastPathComponent) ?? NSLocalizedString("Untitled", comment: "") if self.convertType == .AdvancedWord { convert.convertType = .word } else if self.convertType == .JPEG || self.convertType == .JPG || self.convertType == .PNG || self.convertType == .GIF || self.convertType == .TIFF || self.convertType == .TGA || self.convertType == .BMP || self.convertType == .JP2 { convert.convertType = KMPDFConvertType(rawValue: self.convertType.rawValue) ?? .word convert.options = [KMPDFConvertOptionsKeyImageDPI : self.imageDPINumber, KMPDFConvertOptionsKeyImageWithAnnotation : true] as [String : Any] } else { convert.convertType = KMPDFConvertType(rawValue: self.convertType.rawValue) ?? .word } if self.convertType == .Excel { convert.excelContentOption = self.excelContentOption convert.excelWorksheetOption = self.excelWorksheetOption } convert.password = self.lockPassword KMPDFConvertManager.defaultManager.convert(convert: convert) { [weak self] (finished, error) in self?.hideWaitting() if finished { self?.dismissSheet() if FileManager.default.fileExists(atPath: convert.outputFilePath) { let workspace = NSWorkspace.shared let url = URL(fileURLWithPath: convert.outputFilePath) workspace.activateFileViewerSelecting([url]) } } else if let error = error { let err: NSError = error as NSError var erroeString = "" switch err.code { case CPDFConverterEncryptError: erroeString = NSLocalizedString("Password required or incorrect password. Please re-enter your password and try again", comment: "") break case CPDFConverterPermissionError: erroeString = NSLocalizedString("The license doesn't allow the permission", comment: "") break case CPDFConverterMallocError: erroeString = NSLocalizedString("Malloc failure", comment: "") break case CPDFConverterUnknownError: erroeString = NSLocalizedString("Unknown error in processing conversion. Please try again later", comment: "") break case CPDFConverterPDFUnknownError: erroeString = NSLocalizedString("Unknown error in processing PDF. Please try again later", comment: "") break case CPDFConverterPDFFileError: erroeString = NSLocalizedString("File not found or could not be opened. Check if your file exists or choose another file to convert", comment: "") break case CPDFConverterPDFFormatError: erroeString = NSLocalizedString("File not in PDF format or corruptead. Change a PDF file and try again", comment: "") break case CPDFConverterPDFSecurityError: erroeString = NSLocalizedString("Unsupported security scheme", comment: "") break case CPDFConverterPDFPageError: erroeString = NSLocalizedString("Page not found or content error", comment: "") break default: erroeString = NSLocalizedString("Table not found", comment: "") break } let alert = NSAlert() alert.alertStyle = .critical alert.messageText = NSLocalizedString("Conversion Failed", comment: "") alert.informativeText = erroeString alert.addButton(withTitle: NSLocalizedString("OK", comment: "")) if #available(OSX 10.14, *) { alert.beginSheetModal(for: self?.window! ?? NSWindow.currentWindow(), completionHandler: nil) } else { alert.runModal() } } } } } } func getConvertFileSavePath() -> String { var path = NSSearchPathForDirectoriesInDomains(FileManager.SearchPathDirectory.applicationSupportDirectory, FileManager.SearchPathDomainMask.userDomainMask, true).last path?.append("/") path?.append(Bundle.main.bundleIdentifier!) if (FileManager.default.fileExists(atPath: path!) == false) { try?FileManager.default.createDirectory(atPath: path!, withIntermediateDirectories: false) } path?.append("/") path?.append("convert.pdf") return path! } @IBAction func buttonClicked_MoreConvert(_ sender: NSButton) { if sender == self.moreButton { FMTrackEventManager.defaultManager.trackEvent(event: "PUW", withProperties: ["PUW_Btn": "Btn_PUW_Converter_Premium_UnlimitedConvertw"]) } else if sender == self.upgradeButton { FMTrackEventManager.defaultManager.trackEvent(event: "PUW", withProperties: ["PUW_Btn": "Btn_PUW_Converter_Premium_Upgrade"]) } #if VERSION_DMG if IAPProductsManager.default().isAvailableAllFunction() && !IAPProductsManager.default().isAvailableAdvancedPDFToOffice() { let limitWC = KMPurchaseLimitWindowController.currentLimitWC() limitWC.continueBlock = { windowController in } limitWC.window?.center() limitWC.showWindow(nil) } else { KMPurchaseCompareWindowController.sharedInstance().showWindow(nil) } #else if IAPProductsManager.default().isAvailableAllFunction() { var vc: KMToolCompareWindowController? = nil if convertType == .Word || convertType == .AdvancedWord { // vc = KMToolCompareWindowController(toolType: .Convert, selectNum: 1) vc = KMToolCompareWindowController.toolCompare(toolType: .Convert, selectNum: 1) } else if convertType == .Excel { // vc = KMToolCompareWindowController(toolType: .Convert, selectNum: 2) vc = KMToolCompareWindowController.toolCompare(toolType: .Convert, selectNum: 2) } else if convertType == .PPT { // vc = KMToolCompareWindowController(toolType: .Convert, selectNum: 3) vc = KMToolCompareWindowController.toolCompare(toolType: .Convert, selectNum: 3) } else if convertType.rawValue < 15 && convertType.rawValue > 7 { // vc = KMToolCompareWindowController(toolType: .Convert, selectNum: 4) vc = KMToolCompareWindowController.toolCompare(toolType: .Convert, selectNum: 4) } else { // vc = KMToolCompareWindowController(toolType: .Convert, selectNum: 0) vc = KMToolCompareWindowController.toolCompare(toolType: .Convert, selectNum: 0) } vc?.showWindow(nil) } else { KMPurchaseCompareWindowController.sharedInstance().showWindow(nil) } #endif self.buttonClicked_Cancel(self.cancelButton) } @IBAction func buttonItemClick_SepSingle(_ sender: Any) { if .on == self.singleButton.state { self.isAllInOneSheet = true } else { self.isAllInOneSheet = false } } func controlTextDidEndEditing(_ obj: Notification) { let object = obj.object if (object as AnyObject).isEqual(self.currentPageIndexTextField) == true { let num: Int = Int(self.currentPageIndexTextField.stringValue) ?? 1 let targetPage = self.prePDFView.document.page(at: UInt(num - 1)) self.prePDFView.go(to: targetPage) } else if (object as AnyObject).isEqual(self.pageRangeTextField) == true { guard self.handInputButton.state == .on else { return } if self.fileAttri_ == nil { self.fileAttri_ = KMFileAttribute() self.fileAttri_?.filePath = self.pdfDocument?.documentURL.path ?? "" } // fileAttribute.pdfDocument = self.pdfDocument self.fileAttri_?.bAllPage = false self.fileAttri_?.pagesType = .custom self.fileAttri_?.pagesString = self.pageRangeTextField.stringValue let pages = self.fileAttri_?.fetchSelectPages() ?? [] if pages.count > 0 { let pagesArray = NSMutableArray() for pageNum in pages { let tpage = self.pdfDocument?.page(at: UInt(pageNum - 1)) pagesArray.add(tpage as Any) } self.produceNewPDF(with: pagesArray as! [CPDFPage]) } else { self.showCriticalAlert(nil) } } } func controlTextDidChange(_ obj: Notification) { if let textField = obj.object as? NSTextField { if textField.isEqual(self.currentPageIndexTextField) { if let stringValue = self.currentPageIndexTextField.formatter?.string(for: NSNumber(value: Float(self.currentPageIndexTextField.stringValue) ?? 0)) { if let integerValue = Int(stringValue) { var string = stringValue if integerValue > self.prePDFView.document.pageCount { string = "(self.prePDFView.document.pageCount)" } else if integerValue <= 0 { string = "1" } self.currentPageIndexTextField.stringValue = string } } } } } } @objc enum KMSubArrayType: Int { case Odd = 0 case Even } extension NSMutableArray{ func subArray(type: KMSubArrayType) { if self.count == 0 { return } if type.rawValue > 1 || type.rawValue < 0 { return } let newArray = NSMutableArray() for i in 0..