181 lines
8.4 KiB
Swift
181 lines
8.4 KiB
Swift
//
|
|
// Document.swift
|
|
// Graphic Analysis 2
|
|
//
|
|
// Created by Kilian Hofmann on 15.06.17.
|
|
// Copyright © 2017 Kilian Hofmann. All rights reserved.
|
|
//
|
|
|
|
import Cocoa
|
|
|
|
class Document: NSDocument {
|
|
|
|
var year: FileWrapper?
|
|
var months: [FileWrapper?] = [nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil]
|
|
var days: [[FileWrapper?]] = []
|
|
var yearDatasource: CollectionViewYear = CollectionViewYear()
|
|
var monthDatasource: CollectionViewMonth = CollectionViewMonth()
|
|
var windowController: NSWindowController = NSWindowController()
|
|
|
|
var pdfWindows: [Data] = [Data(), Data(), Data(), Data(), Data(), Data(), Data(), Data(), Data(), Data(), Data(), Data()]
|
|
var pdfBegin: Bool = false
|
|
var name: String = ""
|
|
|
|
@IBOutlet var collectionViewYear: NSCollectionView!
|
|
@IBOutlet var collectionViewMonth: NSCollectionView!
|
|
@IBOutlet var progress: NSProgressIndicator!
|
|
@IBOutlet var exportProgress: NSProgressIndicator!
|
|
|
|
override class var autosavesInPlace: Bool {
|
|
return false;
|
|
}
|
|
|
|
override init() {
|
|
super.init()
|
|
for _ in 0..<12 {
|
|
var temp: [FileWrapper?] = []
|
|
for _ in 0..<31 {
|
|
temp.append(nil)
|
|
}
|
|
days.append(temp)
|
|
}
|
|
}
|
|
|
|
override var windowNibName: NSNib.Name? {
|
|
return "Document"
|
|
}
|
|
|
|
override func read(from fileWrapper: FileWrapper, ofType typeName: String) throws {
|
|
name = (fileWrapper.filename! as NSString).deletingPathExtension
|
|
year = fileWrapper
|
|
for entry in fileWrapper.fileWrappers! {
|
|
guard let month = Int(entry.key) else { continue }
|
|
months[month-1] = entry.value
|
|
for entry2 in entry.value.fileWrappers! {
|
|
guard let day = Int(entry2.key) else { continue }
|
|
days[month-1][day-1] = entry2.value
|
|
}
|
|
}
|
|
//throw NSError(domain: NSOSStatusErrorDomain, code: unimpErr, userInfo: nil)
|
|
}
|
|
|
|
override func windowControllerDidLoadNib(_ windowController: NSWindowController) {
|
|
// Setup collection layout
|
|
let flowLayout = NSCollectionViewFlowLayout()
|
|
flowLayout.itemSize = NSSize(width: 228, height: 211)
|
|
flowLayout.sectionInset = NSEdgeInsets(top: 10, left: 0, bottom: 10, right: 0)
|
|
flowLayout.minimumInteritemSpacing = 10
|
|
flowLayout.minimumLineSpacing = 10
|
|
collectionViewYear.collectionViewLayout = flowLayout
|
|
let flowLayout2 = NSCollectionViewFlowLayout()
|
|
flowLayout2.itemSize = NSSize(width: 135, height: 132)
|
|
flowLayout2.sectionInset = NSEdgeInsets(top: 2, left: 2, bottom: 2, right: 2)
|
|
flowLayout2.minimumInteritemSpacing = 2
|
|
flowLayout2.minimumLineSpacing = 2
|
|
collectionViewMonth.collectionViewLayout = flowLayout2
|
|
// Performance
|
|
windowController.window?.contentView?.wantsLayer = true
|
|
self.windowController = windowController
|
|
// Data sources and delegate
|
|
monthDatasource = CollectionViewMonth(days: days, document: self)
|
|
yearDatasource = CollectionViewYear(months: months, dataSourceMonth: monthDatasource, collectionViewMonth: collectionViewMonth, document: self)
|
|
collectionViewYear.dataSource = yearDatasource
|
|
collectionViewYear.delegate = yearDatasource
|
|
collectionViewMonth.dataSource = monthDatasource
|
|
collectionViewMonth.delegate = monthDatasource
|
|
}
|
|
|
|
override func shouldCloseWindowController(_ windowController: NSWindowController, delegate: Any?, shouldClose shouldCloseSelector: Selector?, contextInfo: UnsafeMutableRawPointer?) {
|
|
pthread_mutex_lock(&(NSApp.delegate as! AppDelegate).lock)
|
|
if !pdfBegin {
|
|
super.shouldCloseWindowController(windowController, delegate: delegate, shouldClose: shouldCloseSelector, contextInfo: contextInfo)
|
|
} else {
|
|
let alert = NSAlert()
|
|
alert.messageText = "Warning"
|
|
alert.informativeText = "PDF export active. Please wait until completed."
|
|
alert.alertStyle = NSAlert.Style.warning
|
|
alert.addButton(withTitle: "OK")
|
|
alert.runModal()
|
|
}
|
|
pthread_mutex_unlock(&(NSApp.delegate as! AppDelegate).lock)
|
|
}
|
|
|
|
override func printOperation(withSettings printSettings: [NSPrintInfo.AttributeKey : Any]) throws -> NSPrintOperation {
|
|
let printOperation: NSPrintOperation = NSPrintOperation(view: collectionViewMonth)
|
|
printOperation.printInfo.orientation = .landscape
|
|
printOperation.printInfo.horizontalPagination = .fit
|
|
printOperation.printInfo.verticalPagination = .fit
|
|
printOperation.printInfo.topMargin = 1
|
|
printOperation.printInfo.rightMargin = 1
|
|
printOperation.printInfo.bottomMargin = 1
|
|
printOperation.printInfo.leftMargin = 1
|
|
return printOperation
|
|
}
|
|
|
|
@IBAction func exportPDF(sender: Any) {
|
|
(sender as! NSMenuItem).isEnabled = false
|
|
let savePanel: NSSavePanel = NSSavePanel()
|
|
savePanel.allowedFileTypes = ["pdf"]
|
|
savePanel.nameFieldStringValue = name
|
|
savePanel.canCreateDirectories = true
|
|
savePanel.beginSheetModal(for: windowController.window!) { result in
|
|
if result.rawValue == NSFileHandlingPanelOKButton {
|
|
self.exportProgress.doubleValue = 0
|
|
self.exportProgress.isHidden = false
|
|
let operationQueue: OperationQueue = OperationQueue()
|
|
let d_group: DispatchGroup = DispatchGroup()
|
|
let bg_queue: DispatchQueue = DispatchQueue.global()
|
|
|
|
operationQueue.addOperation {
|
|
pthread_mutex_lock(&(NSApp.delegate as! AppDelegate).lock)
|
|
self.pdfBegin = true
|
|
pthread_mutex_unlock(&(NSApp.delegate as! AppDelegate).lock)
|
|
var bounds: NSRect = NSMakeRect(0, 0, 964, 675)
|
|
let data: NSMutableData = NSMutableData()
|
|
let dataConsumer: CGDataConsumer = CGDataConsumer(data: data)!
|
|
let context: CGContext = CGContext(consumer: dataConsumer, mediaBox: &bounds, nil)!
|
|
|
|
context.beginPDFPage(nil)
|
|
let window: PDFTitle = PDFTitle(title: "Monthly loss overview of year \(self.name)")
|
|
let providerTitle: CGDataProvider = CGDataProvider(data: (window.window?.contentView?.dataWithPDF(inside: (window.window?.contentView?.bounds)!))! as CFData)!
|
|
let titlePDF: CGPDFDocument = CGPDFDocument(providerTitle)!
|
|
let titlePage: CGPDFPage = titlePDF.page(at: 1)!
|
|
context.drawPDFPage(titlePage)
|
|
context.endPDFPage()
|
|
|
|
for i in 0..<12 {
|
|
bg_queue.async(group: d_group, qos: DispatchQoS(qosClass: .background, relativePriority: 0), flags: .barrier) {
|
|
let window: PDFDraw = PDFDraw(month: i)
|
|
window.days = self.days[i]
|
|
self.pdfWindows[i] = (window.window?.contentView?.dataWithPDF(inside: (window.window?.contentView?.bounds)!))!
|
|
DispatchQueue.main.async {
|
|
self.exportProgress.increment(by: 100/13)
|
|
}
|
|
}
|
|
}
|
|
let _: DispatchTimeoutResult = d_group.wait(timeout: .distantFuture)
|
|
for i in 0..<12 {
|
|
context.beginPDFPage(nil)
|
|
let montDataProvider: CGDataProvider = CGDataProvider(data: self.pdfWindows[i] as CFData)!
|
|
let monthPDF: CGPDFDocument = CGPDFDocument(montDataProvider)!
|
|
let page: CGPDFPage = monthPDF.page(at: 1)!
|
|
context.drawPDFPage(page)
|
|
context.endPDFPage()
|
|
}
|
|
context.closePDF()
|
|
data.write(to: savePanel.url!, atomically: true)
|
|
DispatchQueue.main.async {
|
|
self.exportProgress.increment(by: 100/13)
|
|
}
|
|
pthread_mutex_lock(&(NSApp.delegate as! AppDelegate).lock)
|
|
self.pdfBegin = false
|
|
pthread_mutex_unlock(&(NSApp.delegate as! AppDelegate).lock)
|
|
self.exportProgress.isHidden = true
|
|
(sender as! NSMenuItem).isEnabled = true
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|