Geen omschrijving

PrintService.swift 3.3KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394
  1. import Cocoa
  2. import PDFKit
  3. import UniformTypeIdentifiers
  4. enum PrintService {
  5. static func print(urls: [URL]) {
  6. guard !urls.isEmpty else { return }
  7. for url in urls {
  8. let accessed = url.startAccessingSecurityScopedResource()
  9. defer {
  10. if accessed { url.stopAccessingSecurityScopedResource() }
  11. }
  12. printFile(at: url)
  13. }
  14. }
  15. private static func printFile(at url: URL) {
  16. let type = UTType(filenameExtension: url.pathExtension) ?? .data
  17. if type.conforms(to: .pdf), let document = PDFDocument(url: url) {
  18. printPDF(document)
  19. } else if type.conforms(to: .image), let image = NSImage(contentsOf: url) {
  20. printImage(image)
  21. } else if type.conforms(to: .plainText) || type.conforms(to: .text),
  22. let text = try? String(contentsOf: url, encoding: .utf8) {
  23. printText(text)
  24. } else if type.conforms(to: .rtf),
  25. let data = try? Data(contentsOf: url),
  26. let attributed = NSAttributedString(rtf: data, documentAttributes: nil) {
  27. printAttributedText(attributed)
  28. } else if type.conforms(to: .html),
  29. let data = try? Data(contentsOf: url),
  30. let attributed = NSAttributedString(html: data, documentAttributes: nil) {
  31. printAttributedText(attributed)
  32. } else {
  33. showUnsupportedAlert(for: url)
  34. }
  35. }
  36. private static func printPDF(_ document: PDFDocument) {
  37. let printInfo = configuredPrintInfo()
  38. guard let operation = document.printOperation(
  39. for: printInfo,
  40. scalingMode: .pageScaleToFit,
  41. autoRotate: true
  42. ) else { return }
  43. operation.run()
  44. }
  45. private static func printImage(_ image: NSImage) {
  46. let size = image.size
  47. guard size.width > 0, size.height > 0 else { return }
  48. let imageView = NSImageView(frame: NSRect(origin: .zero, size: size))
  49. imageView.image = image
  50. imageView.imageScaling = .scaleProportionallyUpOrDown
  51. let operation = NSPrintOperation(view: imageView, printInfo: configuredPrintInfo())
  52. operation.run()
  53. }
  54. private static func printText(_ text: String) {
  55. printAttributedText(NSAttributedString(string: text))
  56. }
  57. private static func printAttributedText(_ text: NSAttributedString) {
  58. let textView = NSTextView(frame: NSRect(x: 0, y: 0, width: 612, height: 792))
  59. textView.textStorage?.setAttributedString(text)
  60. textView.isEditable = false
  61. let operation = NSPrintOperation(view: textView, printInfo: configuredPrintInfo())
  62. operation.run()
  63. }
  64. private static func configuredPrintInfo() -> NSPrintInfo {
  65. let printInfo = NSPrintInfo.shared.copy() as! NSPrintInfo
  66. let printerName = AppSettings.effectiveDefaultPrinter
  67. if let printer = NSPrinter(name: printerName) {
  68. printInfo.printer = printer
  69. }
  70. return printInfo
  71. }
  72. private static func showUnsupportedAlert(for url: URL) {
  73. let alert = NSAlert()
  74. alert.messageText = "Unsupported File"
  75. alert.informativeText = "\"\(url.lastPathComponent)\" cannot be printed."
  76. alert.alertStyle = .warning
  77. alert.addButton(withTitle: "OK")
  78. alert.runModal()
  79. }
  80. }