// // KMBackgroundManager.swift // PDF Reader Pro // // Created by tangchao on 2022/12/23. // import Cocoa /* Pro Mac -> New New !-> Pro Mac 1.Pro Mac New 更新 Pro Mac 的模板,会新建新的 New 模板(原数据保存不变) 会出现两个 2.Pro Mac 删除 */ 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") let kBackgroundImageFolder = NSSearchPathForDirectoriesInDomains(FileManager.SearchPathDirectory.applicationSupportDirectory, FileManager.SearchPathDomainMask.userDomainMask, true).last?.stringByAppendingPathComponent(Bundle.main.bundleIdentifier!).stringByAppendingPathComponent("background").stringByAppendingPathComponent("image") static let defaultManager = KMBackgroundManager() static let kRemovedKey = "KMBackgroundRemovedKey" var datas: Array = [] var defaultModel: KMBackgroundModel = KMBackgroundModel() //新增模板时的数据。 override init() { super.init() print("kBackgroundFolderPath = \(kBackgroundFolderPath ?? "")") if (!FileManager.default.fileExists(atPath: kBackgroundFolderPath!)) { let create: ()? = try?FileManager.default.createDirectory(atPath: kBackgroundFolderPath!, withIntermediateDirectories: false) } if (!FileManager.default.fileExists(atPath: kBackgroundImageFolder!)) { let create: ()? = try?FileManager.default.createDirectory(atPath: kBackgroundImageFolder!, withIntermediateDirectories: false) } if (FileManager.default.fileExists(atPath: kBackgroundPlistPath!)) { let dataDict = NSDictionary(contentsOfFile: kBackgroundPlistPath!) if (dataDict == nil) { return } let 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 = parseDictionaryToModel(dict: backgroundDict) model.backgroundID = key if (model.type == .image) { self.datas.append(model) } else { self.datas.append(model) } } if (deleteKeys.count > 0) { let newDict: NSMutableDictionary = NSMutableDictionary(dictionary: dataDict!) for key in deleteKeys { newDict.removeObject(forKey: key) } newDict.write(toFile: kBackgroundPlistPath!, atomically: true) } } defaultModel.name = fetchAvailableBackgroundName() } //MARK: - 增删改查 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.parseModelToDict(model: model) if (backgroundDict.isEmpty) { let alert = NSAlert() alert.alertStyle = .critical alert.messageText = NSLocalizedString("文件\(model.imagePath?.lastPathComponent)已损坏", comment: "") alert.runModal() return false } let tag = model.backgroundID newDict.addEntries(from: [tag : backgroundDict]) 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) } model.updatePreviewImage() } 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 == .image) { 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() } KMDataManager.ud_set(nil, forKey: Self.kRemovedKey) 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 == .image) { 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.parseModelToDict(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) { if let index = self.datas.firstIndex(of: flagModel) { self.datas[index] = model } model.updatePreviewImage() } return result } func updateModel(_ model: KMBackgroundModel, withDict dict: NSDictionary) { model.type = CPDFBackgroundType(rawValue: dict.object(forKey: "type") as! Int)! if (model.type == .image) { model.imagePath = (dict.object(forKey: "imagePath") as! String) } else { if let value = dict.object(forKey: "color") { model.color = NSColor.km_init(hex: value as! String) } } model.scale = dict.object(forKey: "scale") as! CGFloat model.rotation = CGFloat(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.backgroundID = dict.object(forKey: "backgroundID") as! String if let value = dict.object(forKey: "name") { model.name = value as! String } } func updateBackground(_ background: CPDFBackground, withModel model: KMBackgroundModel) { background.type = model.type background.color = model.color background.setImage(model.image()) background.rotation = model.rotation background.opacity = model.opacity background.scale = model.scale background.verticalAlignment = UInt(model.verticalMode) background.yOffset = model.verticalSpace background.horizontalAlignment = UInt(model.horizontalMode) background.xOffset = model.horizontalSpace } //MARK: - parse func parseModelToDict(model: KMBackgroundModel) -> Dictionary { var dict: [String : Any] = [:] if (model.type == .color) { dict["color"] = model.color?.colorToHexString() } else { dict["imagePath"] = model.imagePath } 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["backgroundID"] = model.backgroundID dict["name"] = model.name return dict } private func parseDictionaryToModel(dict: NSDictionary) -> KMBackgroundModel { let model = KMBackgroundModel() model.type = CPDFBackgroundType(rawValue: dict.object(forKey: "type") as! Int)! if (model.type == .image) { if let value = dict.object(forKey: "imagePath") { model.imagePath = value as? String } } else { if let value = dict.object(forKey: "color") { model.color = NSColor.km_init(hex: value as! String) } } model.scale = dict.object(forKey: "scale") as! CGFloat model.rotation = CGFloat(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) if let value = dict.object(forKey: "backgroundID") { model.backgroundID = value as! String } if let value = dict.object(forKey: "name") { model.name = value as! String } return model } //MARK: - Compare class func compareIsChangedModel(_ model: KMBackgroundModel, withDict dict: NSDictionary) -> Bool { if let value = dict["type"] { if model.type != CPDFBackgroundType(rawValue: value as! Int)! { return true } } if let value = dict["color"] { if model.color?.colorToHexString() != (value as! String) { return true } } if let value = dict["rotation"] { if model.rotation != (value as! CGFloat) { return true } } if let value = dict["opacity"] { if model.opacity != (value as! CGFloat) { return true } } if let value = dict["scale"] { if model.scale != (value as! CGFloat) { return true } } if let value = dict["verticalMode"] { if model.verticalMode != (value as! Int) { return true } } if let value = dict["verticalSpace"] { if model.verticalSpace != (value as! CGFloat) { return true } } if let value = dict["horizontalMode"] { if model.horizontalMode != (value as! Int) { return true } } if let value = dict["horizontalSpace"] { if model.horizontalSpace != (value as! CGFloat) { return true } } return false } //MARK: - Get func fetchAvailableBackgroundName() -> String { var availableIndex = 0 for item in datas { if item.name.hasPrefix("Background") { if let index = Int(item.name.dropFirst("Background".count)), index >= availableIndex { availableIndex = index + 1 } } } return "Background\(availableIndex)" } }