123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597 |
- //
- // 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, NSCoding {
- 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<KMBackgroundModel> = []
-
- var backgroundObjects: [KMBackgroundObject] = []
-
- static let defaultManager = KMBackgroundManager()
-
- static let kRemovedKey = "KMBackgroundRemovedKey"
-
- override init() {
- super.init()
-
- // 查找原数据
- if let storedData = UserDefaults.standard.value(forKey: "kBackgroundInfoSaveKey") as? Data {
- NSKeyedUnarchiver.setClass(KMBackgroundObject.self, forClassName: "KMBackgroundObject")
- NSKeyedUnarchiver.setClass(KMBackgroundManager.self, forClassName: "KMBackgroundManager")
- if let man = NSKeyedUnarchiver.unarchiveObject(with: storedData) as? KMBackgroundManager {
- for object in man.backgroundObjects {
- self.backgroundObjects.append(object)
- }
- }
- }
- // 原数据转换
- let removedKeys = KMDataManager.ud_array(forKey: Self.kRemovedKey) as? [String] ?? []
- for obj in self.backgroundObjects {
- let id = obj.backgroundID ?? ""
- if removedKeys.contains(id) {
- continue
- }
-
- let model = self.parseObject(object: obj)
- self.datas.append(model)
- }
-
- if (FileManager.default.fileExists(atPath: kBackgroundPlistPath!)) {
- let dataDict = NSDictionary(contentsOfFile: kBackgroundPlistPath!)
- if (dataDict == nil) {
- return
- }
- var deleteKeys: Array<String> = []
- 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) {
- let newDict: NSMutableDictionary = NSMutableDictionary(dictionary: dataDict!)
- for key in deleteKeys {
- newDict.removeObject(forKey: key)
- }
- newDict.write(toFile: kBackgroundPlistPath!, atomically: true)
- }
- }
- }
-
- required init?(coder: NSCoder) {
- if let data = coder.decodeObject(forKey: "backgroundObjects") {
- self.backgroundObjects = data as? [KMBackgroundObject] ?? []
- }
- }
-
- func encode(with coder: NSCoder) {
- // coder.encode(self.backgroundObjects, forKey: "backgroundObjects")
- }
-
- 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()
- }
-
- model.modificationDate = Date().timeIntervalSince1970
- 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 = fetchAvailableName()//tagString()
- newDict.addEntries(from: [tag : backgroundDict])
- if model.backgroundID.count == 0 {
- 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.isMigrate && model.isUpdated == false { // 原数据删除
- // if (self._addRemovedTemplate(model: model)) {
- var removedKeys = KMDataManager.ud_array(forKey: Self.kRemovedKey) ?? []
- removedKeys.append(model.backgroundID)
- KMDataManager.ud_set(removedKeys, forKey: Self.kRemovedKey)
- if (self.datas.contains(model)) { // 数据源删除
- self.datas.removeObject(model)
- }
- // }
- return true
- }
- 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()
- }
-
- KMDataManager.ud_set(nil, forKey: Self.kRemovedKey)
- self._clearStored()
-
- 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<KMBackgroundModel> = []
- 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)
- }
- }
-
- self._clearStored()
-
- 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<KMBackgroundModel> = []
- 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)
- }
- }
-
- self._clearStored()
-
- return result
- }
-
- func updateTemplate(model: KMBackgroundModel) -> Bool {
- if model.isMigrate && model.isUpdated == false { // 原数据
- // 移除旧数据
- _ = self.deleteTemplate(model: model)
- // 新增新数据
- model.isUpdated = true
- model.modificationDate = Date().timeIntervalSince1970
- return self.addTemplate(model: model)
- }
- 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()
- }
- model.isUpdated = true
- model.modificationDate = Date().timeIntervalSince1970
- 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 _addRemovedTemplate(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()
- }
-
- model.isRemoved = true
- model.modificationDate = Date().timeIntervalSince1970
- 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 = model.backgroundID
- newDict.addEntries(from: [tag : backgroundDict])
- model.backgroundID = tag
- let result = newDict.write(toFile: kBackgroundPlistPath!, atomically: true)
-
- return result
- }
-
- private func parseModel(model: KMBackgroundModel) -> Dictionary<String, Any> {
- 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.rawValue
- dict["pagesString"] = model.pagesString
-
- dict["isMigrate"] = model.isMigrate
- dict["isUpdated"] = model.isUpdated
- if let data = model.modificationDate {
- dict["modificationDate"] = data
- }
- dict["isRemoved"] = model.isRemoved
-
- 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 = 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.pageRangeType = KMWatermarkeModelPageRangeType.init(rawValue: (dict.object(forKey: "pageRangeType") as! Int))!
- model.pagesString = (dict.object(forKey: "pagesString") as! String)
- model.isMigrate = (dict.object(forKey: "isMigrate") as? Bool) ?? false
- model.isUpdated = (dict.object(forKey: "isUpdated") as? Bool) ?? false
- model.modificationDate = (dict.object(forKey: "modificationDate") as? TimeInterval)
- model.isRemoved = (dict.object(forKey: "isRemoved") as? Bool) ?? false
-
- return model
- }
-
- private func parseObject(object: KMBackgroundObject) -> KMBackgroundModel {
- let model = KMBackgroundModel()
-
- model.type = object.type
- if (model.type == .file) {
- model.image = object.image
- model.imagePath = object.imagePath ?? ""
- } else {
- model.color = object.color
- }
-
- model.scale = object.scale
- model.rotation = object.rotation.cgFloat
- model.opacity = object.opacity
- model.verticalMode = object.verticalMode
- model.verticalSpace = object.verticalSpace.cgFloat
- model.horizontalMode = object.horizontalMode
- model.horizontalSpace = object.horizontalSpace.cgFloat
- model.pageRangeType = KMWatermarkeModelPageRangeType.init(rawValue: object.pageRangeType.rawValue) ?? .all
- model.pagesString = object.pagesString
- model.backgroundID = object.backgroundID ?? "background0"
- model.isMigrate = true
-
- return model
- }
-
- private func parseModeForObject(_ mode: KMBackgroundModel) -> KMBackgroundObject {
- let obj = KMBackgroundObject()
-
- obj.type = mode.type
- if (obj.type == .file) {
- obj.image = mode.image
- obj.imagePath = mode.imagePath
- } else {
- obj.color = mode.color ?? .red
- }
-
- obj.scale = mode.scale
- obj.rotation = Int(mode.rotation)
- obj.opacity = mode.opacity
- obj.verticalMode = mode.verticalMode
- obj.verticalSpace = Int(mode.verticalSpace)
- obj.horizontalMode = mode.horizontalMode
- obj.horizontalSpace = Int(mode.horizontalSpace)
- obj.pageRangeType = KMBatchOperatePageChoice.init(rawValue: mode.pageRangeType.rawValue) ?? .All
- obj.pagesString = mode.pagesString
- obj.backgroundID = mode.backgroundID
-
- return obj
- }
-
- private func _addBackground(_ obj: KMBackgroundObject) {
- // self.backgroundObjects.insert(obj, at: 0)
- // self._store()
- }
-
- private func _removeBackground(_ obj: KMBackgroundObject) {
- // self.backgroundObjects.removeObject(obj)
- // self._store()
- }
-
- private func _store() {
- // let encodedObject = NSKeyedArchiver.archivedData(withRootObject: self)
- // let defaults = UserDefaults.standard
- // defaults.set(encodedObject, forKey: "kBackgroundInfoSaveKey")
- // defaults.synchronize()
- }
-
- private func _clearStored() {
- let defaults = UserDefaults.standard
- defaults.set(nil, forKey: "kBackgroundInfoSaveKey")
- defaults.synchronize()
- }
-
- 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
- }
-
- func fetchAvailableName() -> String {
- var availableIndex = 0
-
- for item in datas {
- if item.backgroundID.hasPrefix("Background") {
- if let index = Int(item.backgroundID.dropFirst("Background".count)), index >= availableIndex {
- availableIndex = index + 1
- }
- }
- }
-
- return "Background\(availableIndex)"
- }
- }
|