123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343 |
- //
- // KMURLToPDFWindowController.swift
- // PDF Reader Pro
- //
- // Created by wanjun on 2023/1/29.
- //
- import Cocoa
- let kUrlToPDFFolderPath = (try? FileManager.default.url(for: .applicationSupportDirectory, in: .userDomainMask, appropriateFor: nil, create: true).appendingPathComponent(Bundle.main.bundleIdentifier ?? "").appendingPathComponent("WebPage"))?.path ?? ""
- typealias KMURLToPDFWindowControllerComplete = (_ filePath: String) -> Void
- class KMURLToPDFWindowController: NSWindowController, NSTextFieldDelegate {
- @IBOutlet var urlBtn: NSButton!
- @IBOutlet var localHtmlBtn: NSButton!
- @IBOutlet var outputBackView: NSView!
- @IBOutlet var outputText: NSTextField!
- @IBOutlet var outputButton: NSButton!
- @IBOutlet var pageSizeComboBox: NSComboBox!
- @IBOutlet var pageViewLabel: NSTextField!
- @IBOutlet var pageSizeLabel: NSTextField!
- @IBOutlet var pageGapLabel: NSTextField!
- @IBOutlet var pageGapTextField: NSTextField!
- @IBOutlet var pagesGapStepper: NSStepper!
- @IBOutlet var btnConvert: NSButton!
- @IBOutlet var btnCancel: NSButton!
- @IBOutlet var urlTextField: NSTextField!
-
- var filePath: String?
- var posterMaskView: KMBookletMaskView?
- var gap: CGFloat = 0
- var pageSize: CGSize = NSMakeSize(298, 420)
-
- var handler: KMURLToPDFWindowControllerComplete?
- var beginWindow: NSWindow?
- override init(window: NSWindow?) {
- super.init(window: window)
- }
- required init?(coder: NSCoder) {
- super.init(coder: coder)
- }
- override func windowDidLoad() {
- super.windowDidLoad()
- window?.title = NSLocalizedString("Web Page To PDF", comment: "")
-
- pageViewLabel.stringValue = NSLocalizedString("Page View", comment: "")
- pageSizeLabel.stringValue = NSLocalizedString("Page size:", comment: "")
- pageGapLabel.stringValue = "\(NSLocalizedString("Spacing", comment: "")):"
-
- urlBtn.title = NSLocalizedString("URL", comment: "")
- localHtmlBtn.title = NSLocalizedString("File", comment: "")
- btnConvert.title = NSLocalizedString("Save as PDF", comment: "")
- btnCancel.title = NSLocalizedString("Cancel", comment: "")
- outputButton.title = NSLocalizedString("Choose...", comment: "")
-
- outputBackView.wantsLayer = true
- outputBackView.layer?.borderWidth = 0.8
- outputBackView.layer?.borderColor = NSColor(red: 177.0/255, green: 178.0/255, blue: 177.0/255, alpha: 1).cgColor
- urlTextField.placeholderString = "https://www.pdfreaderpro.com"
- urlTextField.delegate = self
- outputText.isEditable = false
- pageSizeComboBox.addItems(withObjectValues: [
- NSLocalizedString("Automatically Resize", comment: "Menu item title"),
- "4A0 1682 × 2378 mm",
- "2A0 1189 × 1682 mm",
- "A0 841 × 1189 mm",
- "A1 594 × 841 mm",
- "A2 420 × 594 mm",
- "A3 297 × 420 mm",
- "A4 210 × 297 mm",
- "A5 148 × 210 mm",
- "A6 105 × 148 mm",
- "A7 74 × 105 mm",
- "A8 52 × 74 mm",
- "A9 37 × 52 mm",
- "A10 26 × 37 mm"
- ])
- pageSizeComboBox.selectItem(at: 0)
- pageSizeComboBox.isEditable = false
- pageSize = NSMakeSize(298, 420)
- gap = 0
- pagesGapStepper.stringValue = "0"
- pagesGapStepper.isEnabled = false
- pageGapTextField.isEnabled = false
- if urlBtn.state == .on {
- if urlTextField.stringValue.count > 0 {
- btnConvert.isEnabled = true
- } else {
- btnConvert.isEnabled = false
- }
- } else {
- if outputText.stringValue.count > 0 {
- btnConvert.isEnabled = true
- } else {
- btnConvert.isEnabled = false
- }
- }
- outputText.placeholderString = "\(NSLocalizedString("Select a File", comment: "")) (.html, .webarchive)"
- outputButton.isEnabled = false
- }
- func isUrl(_ urlString: String?) -> Bool {
- guard let urlString = urlString else { return false }
-
- // 实现方法有问题,暂不使用
- var url: String
- if urlString.count > 4, urlString.prefix(4) == "www." {
- url = "http://\(urlString)"
- } else {
- url = urlString
- }
- let urlRegex = "\\bhttps?://[a-zA-Z0-9\\-.]+(?::(\\d+))?(?:(?:/[a-zA-Z0-9\\-._?,'+\\&%$=~*!():@\\\\]*)+)?"
- let urlTest = NSPredicate(format: "SELF MATCHES %@", urlRegex)
- return urlTest.evaluate(with: url)
- }
- func beginSheetModalForWindow(_ window: NSWindow, completionHandler handler: ((String) -> Void)?) {
- self.handler = handler
- self.beginWindow = window
- self.beginWindow?.beginSheet(self.window!) { response in
- self.handler?(self.filePath ?? "")
- }
- }
- @IBAction func buttonItemClicked_Cancel(_ sender: NSButton) {
- self.beginWindow?.endSheet(self.window!)
- self.window?.orderOut(self)
- }
- func urlValueEncode(_ str: String) -> String? {
- let allowedCharacterSet = CharacterSet(charactersIn: "!*'();:@&=+$,?%#[]{}").inverted
- return str.addingPercentEncoding(withAllowedCharacters: allowedCharacterSet)
- }
- @IBAction func buttonItemClicked_Start(_ sender: NSButton) {
- if !FileManager.default.fileExists(atPath: kUrlToPDFFolderPath) {
- try? FileManager.default.createDirectory(atPath: kUrlToPDFFolderPath, withIntermediateDirectories: false, attributes: nil)
- }
- var url: URL?
- var fileName: String?
- if urlBtn.state == .on {
- let urlString = urlTextField.stringValue
- var tUrl = URL(string: urlString)
- if tUrl?.scheme?.count ?? 0 < 1 {
- tUrl = URL(string: "http://\(urlString)")
- }
- url = tUrl
- } else {
- url = URL(fileURLWithPath: outputText.stringValue)
- fileName = outputText.stringValue.deletingPathExtension.lastPathComponent
- }
- let string = pageGapTextField.stringValue
- let unitScale: CGFloat = (595.0 / 21.0) * 2.54
- if string.stringToCGFloat() <= 0 {
- pageGapTextField.stringValue = "0"
- } else if string.stringToCGFloat() * unitScale > pageSize.width / 2 {
- let maxF = pageSize.width / (string.stringToCGFloat() * 2)
- pageGapTextField.stringValue = "\(maxF)"
- }
-
- gap = formatFloat(Float(string.stringToCGFloat() * unitScale)).stringToCGFloat()
- if let url = url {
- showWaitting()
- let convert = KMConvertURLToPDF.shareInstance()
- convert.fileName = fileName ?? ""
- convert.convertUrl(toPDF: [url], toPath: kUrlToPDFFolderPath, pageSize: pageSize, gap: gap, progress: { value in
- // Progress update
- }, completionHandler: { successArray, failArray in
- self.hideWaitting()
- if failArray.isEmpty {
- if let filePath = successArray.first as? String, FileManager.default.fileExists(atPath: filePath) {
- self.filePath = filePath
- NSApp.endSheet(self.window!, returnCode: sender.tag)
- self.window?.orderOut(self)
- }
- } else {
- let alert = NSAlert()
- alert.alertStyle = .critical
- alert.informativeText = NSLocalizedString("Conversion Failed", comment: "")
- alert.messageText = ""
- alert.addButton(withTitle: NSLocalizedString("OK", comment: ""))
- alert.runModal()
- }
- })
- }
- }
- @IBAction func buttonItemClick_Add(_ sender: Any) {
- urlBtn.state = .off
- localHtmlBtn.state = .on
- urlTextField.isEditable = false
- urlTextField.stringValue = ""
- btnConvert.isEnabled = false
- let panel = NSOpenPanel()
- panel.canChooseFiles = true
- panel.canChooseDirectories = false
- panel.allowsMultipleSelection = false
- panel.allowedFileTypes = ["HTML", "html", "webarchive", "htm"]
- panel.beginSheetModal(for: window!) { response in
- if response == .OK {
- self.outputText.stringValue = panel.url?.path ?? ""
- self.btnConvert.isEnabled = true
- }
- }
- }
- @IBAction func buttonItemClick_ChangeType(_ sender: NSButton) {
- if urlBtn.state == .on {
- urlTextField.isEditable = true
- urlTextField.becomeFirstResponder()
- outputText.stringValue = ""
- outputButton.isEnabled = false
- if urlTextField.stringValue.count > 0 {
- btnConvert.isEnabled = true
- } else {
- btnConvert.isEnabled = false
- }
- } else {
- urlTextField.isEditable = false
- urlTextField.stringValue = ""
- outputButton.isEnabled = true
- if outputText.stringValue.count > 0 {
- btnConvert.isEnabled = true
- } else {
- btnConvert.isEnabled = false
- }
- }
- }
- @IBAction func comboBoxItemClick_PageSize(_ sender: NSComboBox) {
- switch sender.indexOfSelectedItem {
- case 0:
- pageSize = NSMakeSize(298, 420)
- case 1:
- pageSize = CGSize(width: 4760, height: 6736)
- case 2:
- pageSize = CGSize(width: 3368, height: 4760)
- case 3:
- pageSize = CGSize(width: 2380, height: 3368)
- case 4:
- pageSize = CGSize(width: 1684, height: 2380)
- case 5:
- pageSize = CGSize(width: 1190, height: 1684)
- case 6:
- pageSize = CGSize(width: 842, height: 1190)
- case 7:
- pageSize = CGSize(width: 595, height: 842)
- case 8:
- pageSize = CGSize(width: 420, height: 595)
- case 9:
- pageSize = CGSize(width: 297, height: 420)
- default:
- pageSize = CGSize(width: 210, height: 297)
- }
-
- if sender.indexOfSelectedItem != 0 {
- pagesGapStepper.stringValue = "0"
- pageGapTextField.stringValue = "0"
- pageGapTextField.isEnabled = true
- pagesGapStepper.isEnabled = true
- } else {
- pagesGapStepper.stringValue = "0"
- pageGapTextField.stringValue = ""
- pageGapTextField.isEnabled = false
- pagesGapStepper.isEnabled = false
- }
- }
- @IBAction func stepperItemClick_Gap(_ sender: NSStepper) {
- let unitScale: CGFloat = (595.0 / 21.0) * 2.54
- pageGapTextField.stringValue = String(format: "%.2f", pagesGapStepper.floatValue)
- gap = formatFloat(pagesGapStepper.floatValue * Float(unitScale)).stringToCGFloat()
- }
- func controlTextDidEndEditing(_ obj: Notification) {
- if let object = obj.object as? NSTextField, object == pageGapTextField {
- let unitScale: CGFloat = (595.0 / 21.0) * 2.54
- if object.stringValue.stringToCGFloat() <= 0 {
- pageGapTextField.stringValue = "0"
- } else if object.stringValue.stringToCGFloat() * unitScale > pageSize.width / 2 {
- let maxF = pageSize.width / (object.stringValue.stringToCGFloat() * 2)
- pageGapTextField.stringValue = "\(maxF)"
- }
- gap = formatFloat(Float(object.stringValue.stringToCGFloat() * unitScale)).stringToCGFloat()
- pagesGapStepper.floatValue = Float(object.stringValue.stringToCGFloat())
- }
- }
- func controlTextDidChange(_ notification: Notification) {
- if urlBtn.state == .on {
- if urlTextField.stringValue.count > 0 {
- btnConvert.isEnabled = true
- } else {
- btnConvert.isEnabled = false
- }
- } else {
- if outputText.stringValue.count > 0 {
- btnConvert.isEnabled = true
- } else {
- btnConvert.isEnabled = false
- }
- }
- }
- func formatFloat(_ f: Float) -> String {
- if f.truncatingRemainder(dividingBy: 1) == 0 {
- return String(format: "%.0f", f)
- } else if (f * 10).truncatingRemainder(dividingBy: 1) == 0 {
- return String(format: "%.1f", f)
- } else {
- return String(format: "%.2f", f)
- }
- }
- func showWaitting() {
- if posterMaskView == nil {
- posterMaskView = KMBookletMaskView(frame: NSMakeRect(0, 0, window?.frame.size.width ?? 0, window?.frame.size.height ?? 0))
- }
- window?.contentView?.addSubview(posterMaskView!)
- }
- func hideWaitting() {
- posterMaskView?.removeFromSuperview()
- }
- }
|