// // KMBackgroundManager.swift // PDF Master // // Created by tangchao on 2022/12/23. // import Cocoa class KMBackgroundManager: NSObject { let kBackgroundFolderPath = NSSearchPathForDirectoriesInDomains(FileManager.SearchPathDirectory.applicationSupportDirectory, FileManager.SearchPathDomainMask.userDomainMask, true).last?.stringByAppendingPathComponent(Bundle.main.bundleIdentifier!).stringByAppendingPathComponent("background") let kBackgroundPlistPath = NSSearchPathForDirectoriesInDomains(FileManager.SearchPathDirectory.applicationSupportDirectory, FileManager.SearchPathDomainMask.userDomainMask, true).last?.stringByAppendingPathComponent(Bundle.main.bundleIdentifier!).stringByAppendingPathComponent("background").stringByAppendingPathComponent("background.plist") var datas: Array = [] static let defaultManager = KMBackgroundManager() override init() { super.init() if (FileManager.default.fileExists(atPath: kBackgroundPlistPath!)) { let dataDict = NSDictionary(contentsOfFile: kBackgroundPlistPath!) if (dataDict == nil) { return } var deleteKeys: Array = [] for keyIndex in 0 ..< (dataDict?.allKeys.count)! { let key: String = dataDict?.allKeys[keyIndex] as! String let backgroundDict: NSDictionary = dataDict?.object(forKey: key) as! NSDictionary let model = parseDictionary(dict: backgroundDict) /// 赋值id model.backgroundID = key if (model.type == .file) { if (model.image == nil) { deleteKeys.append(key) } else { self.datas.append(model) } } else { self.datas.append(model) } } if (deleteKeys.count > 0) { var newDict: NSMutableDictionary = NSMutableDictionary(dictionary: dataDict!) for key in deleteKeys { newDict.removeObject(forKey: key) } newDict.write(toFile: kBackgroundPlistPath!, atomically: true) } } } func addTemplate(model: KMBackgroundModel) -> Bool { if (!FileManager.default.fileExists(atPath: kBackgroundFolderPath!)) { let create: ()? = try?FileManager.default.createDirectory(atPath: kBackgroundFolderPath!, withIntermediateDirectories: false) if (create == nil) { return false } } if (!FileManager.default.fileExists(atPath: kBackgroundPlistPath!)) { let create = try?FileManager.default.createFile(atPath: kBackgroundPlistPath!, contents: nil) if (create == nil) { return false } } let dict = NSDictionary(contentsOfFile: kBackgroundPlistPath!) var newDict:NSMutableDictionary! if (dict != nil) { newDict = NSMutableDictionary(dictionary: dict!) } else { newDict = NSMutableDictionary() } let backgroundDict = self.parseModel(model: model) if (backgroundDict.isEmpty) { let alert = NSAlert() alert.alertStyle = .critical alert.messageText = NSLocalizedString("文件\(model.imagePath.lastPathComponent)已损坏", comment: "") alert.runModal() return false } let tag = tagString() newDict.addEntries(from: [tag : backgroundDict]) model.backgroundID = tag let result = newDict.write(toFile: kBackgroundPlistPath!, atomically: true) if (result) { if (self.datas.count < 1) { self.datas.append(model) } else { self.datas.insert(model, at: 0) } } return result } func deleteTemplate(model: KMBackgroundModel) -> Bool { if (model.backgroundID.isEmpty) { return false } if (!FileManager.default.fileExists(atPath: kBackgroundPlistPath!)) { return false } let key: String = model.backgroundID let dictionary = NSDictionary(contentsOfFile: kBackgroundPlistPath!) var newDictionary: NSMutableDictionary! if (dictionary != nil) { newDictionary = NSMutableDictionary(dictionary: dictionary!) } else { newDictionary = NSMutableDictionary() } newDictionary.removeObject(forKey: key) let result = newDictionary.write(toFile: kBackgroundPlistPath!, atomically: true) if (result) { if (model.type == .file) { let filePath: String = model.imagePath try?FileManager.default.removeItem(atPath: filePath) } if (self.datas.contains(model)) { self.datas.removeObject(model) } } return result } func deleteAllTemplates() -> Bool { if (!FileManager.default.fileExists(atPath: kBackgroundPlistPath!)) { return false } let dictionary = NSDictionary(contentsOfFile: kBackgroundPlistPath!) var newDictionary: NSMutableDictionary! if (dictionary != nil) { newDictionary = NSMutableDictionary(dictionary: dictionary!) } else { newDictionary = NSMutableDictionary() } newDictionary.removeAllObjects() let result = newDictionary.write(toFile: kBackgroundPlistPath!, atomically: true) if (result) { self.datas.removeAll() } return result } func deleteAllColorTemplates() -> Bool { if (!FileManager.default.fileExists(atPath: kBackgroundPlistPath!)) { return false } let dictionary = NSDictionary(contentsOfFile: kBackgroundPlistPath!) var newDictionary: NSMutableDictionary! if (dictionary != nil) { newDictionary = NSMutableDictionary(dictionary: dictionary!) } else { newDictionary = NSMutableDictionary() } let count = self.datas.count-1 var deleteArray: Array = [] for i in 0 ... count { let model = self.datas[i] if (model.type == .color) { newDictionary.removeObject(forKey: model.backgroundID as Any) deleteArray.append(model) } } let result = newDictionary.write(toFile: kBackgroundPlistPath!, atomically: true) if (result) { for model in deleteArray { self.datas.removeObject(model) } } return result } func deleteAllFileTemplates() -> Bool { if (!FileManager.default.fileExists(atPath: kBackgroundPlistPath!)) { return false } let dictionary = NSDictionary(contentsOfFile: kBackgroundPlistPath!) var newDictionary: NSMutableDictionary! if (dictionary != nil) { newDictionary = NSMutableDictionary(dictionary: dictionary!) } else { newDictionary = NSMutableDictionary() } let count = self.datas.count-1 var deleteArray: Array = [] for i in 0 ... count { let model = self.datas[i] if (model.type == .file) { newDictionary.removeObject(forKey: model.backgroundID as Any) deleteArray.append(model) } } let result = newDictionary.write(toFile: kBackgroundPlistPath!, atomically: true) if (result) { for model in deleteArray { self.datas.removeObject(model) } } return result } func updateTemplate(model: KMBackgroundModel) -> Bool { if (!FileManager.default.fileExists(atPath: kBackgroundFolderPath!)) { let create = try?FileManager.default.createDirectory(atPath: kBackgroundFolderPath!, withIntermediateDirectories: false) if (create == nil) { return false } } if (!FileManager.default.fileExists(atPath: kBackgroundPlistPath!)) { let create = try?FileManager.default.createFile(atPath: kBackgroundPlistPath!, contents: nil) if (create == nil) { return false } } var flagModel: KMBackgroundModel! for model_ in self.datas { if (model_.backgroundID == model.backgroundID) { flagModel = model_ break } } if (flagModel == nil) { return false } let dict = NSDictionary(contentsOfFile: kBackgroundPlistPath!) var newDict:NSMutableDictionary! if (dict != nil) { newDict = NSMutableDictionary(dictionary: dict!) } else { newDict = NSMutableDictionary() } let modelDict = self.parseModel(model: model) if (modelDict.isEmpty) { let alert = NSAlert() alert.alertStyle = .critical alert.messageText = NSLocalizedString("文件\(model.imagePath.lastPathComponent)已损坏", comment: "") alert.runModal() return false } newDict.setObject(modelDict, forKey: flagModel.backgroundID as NSCopying) let result = newDict.write(toFile: kBackgroundPlistPath!, atomically: true) if (result) { let index = self.datas.index(of: flagModel) self.datas[index!] = model } return result } /** `Private Methods` */ private func parseModel(model: KMBackgroundModel) -> Dictionary { let tag = tagString() var dict: [String : Any] = [:] if (model.type == .color) { var red: CGFloat = 0.0 var green: CGFloat = 0.0 var blue: CGFloat = 0.0 model.color!.usingColorSpaceName(NSColorSpaceName.calibratedRGB)?.getRed(&red, green: &green, blue: &blue, alpha: nil) dict["red"] = red dict["green"] = green dict["blue"] = blue } else { if (!FileManager.default.fileExists(atPath: kBackgroundFolderPath!)) { try?FileManager.default.createDirectory(atPath: kBackgroundFolderPath!, withIntermediateDirectories: false) } let path = kBackgroundFolderPath?.stringByAppendingPathComponent("\(tag).png") let image = model.image let data = image?.tiffRepresentation let imageRep = NSBitmapImageRep(data: data!) imageRep?.size = image!.size var imageData: Data! let pathExtension = model.imagePath.components(separatedBy: ".").last if (pathExtension?.lowercased() == "png") { imageData = imageRep?.representation(using: NSBitmapImageRep.FileType.png, properties: [:]) } else { imageData = imageRep?.representation(using: NSBitmapImageRep.FileType.jpeg, properties: [:]) } do { try imageData.write(to: URL(fileURLWithPath: path!)) dict["imagePath"] = path?.lastPathComponent } catch { KMPrint("Failed to write to disk.") return [:] } } dict["type"] = model.type.rawValue dict["scale"] = model.scale dict["opacity"] = model.opacity dict["rotation"] = model.rotation dict["horizontalMode"] = model.horizontalMode dict["horizontalSpace"] = model.horizontalSpace dict["verticalMode"] = model.verticalMode dict["verticalSpace"] = model.verticalSpace dict["pageRangeType"] = model.pageRangeType dict["pagesString"] = model.pagesString return dict } private func parseDictionary(dict: NSDictionary) -> KMBackgroundModel { let model = KMBackgroundModel() model.type = KMBackgroundType(rawValue: dict.object(forKey: "type") as! Int)! if (model.type == .file) { let path = kBackgroundFolderPath?.stringByAppendingPathComponent(dict.object(forKey: "imagePath") as! String) if (FileManager.default.fileExists(atPath: path!)) { model.image = NSImage(contentsOfFile: path!) model.imagePath = path! } else { model.image = nil } } else { let red: CGFloat = dict.object(forKey: "red") as! CGFloat let green: CGFloat = dict.object(forKey: "green") as! CGFloat let blue: CGFloat = dict.object(forKey: "blue") as! CGFloat model.color = NSColor(red: red, green: green, blue: blue, alpha: 1.0) } model.scale = dict.object(forKey: "scale") as! CGFloat model.rotation = Int(dict.object(forKey: "rotation") as! CGFloat) model.opacity = (dict.object(forKey: "opacity") as! CGFloat) model.verticalMode = (dict.object(forKey: "verticalMode") as! Int) model.verticalSpace = (dict.object(forKey: "verticalSpace") as! CGFloat) model.horizontalMode = (dict.object(forKey: "horizontalMode") as! Int) model.horizontalSpace = (dict.object(forKey: "horizontalSpace") as! CGFloat) model.pageRangeType = (dict.object(forKey: "pageRangeType") as! Int) model.pagesString = (dict.object(forKey: "pagesString") as! String) return model } private func tagString() -> String { var result: String = "" let dateFormatter = DateFormatter() dateFormatter.dateFormat = "yyMMddHHmmss" result.append(dateFormatter.string(from: Date())) result = result.appendingFormat("%04d", arc4random()%10000) return result } }