KMHeaderFooterManager.swift 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403
  1. //
  2. // KMHeaderFooterManager.swift
  3. // PDF Master
  4. //
  5. // Created by tangchao on 2022/12/27.
  6. //
  7. import Cocoa
  8. let kHeaderFooterInfoSaveKey = "kHeaderFooterInfoSaveKey"
  9. class KMHeaderFooterManager: NSObject, NSCoding{
  10. let kFolderPath = NSSearchPathForDirectoriesInDomains(FileManager.SearchPathDirectory.applicationSupportDirectory, FileManager.SearchPathDomainMask.userDomainMask, true).last?.stringByAppendingPathComponent(Bundle.main.bundleIdentifier!).stringByAppendingPathComponent("headerfooter")
  11. let kPlistPath = NSSearchPathForDirectoriesInDomains(FileManager.SearchPathDirectory.applicationSupportDirectory, FileManager.SearchPathDomainMask.userDomainMask, true).last?.stringByAppendingPathComponent(Bundle.main.bundleIdentifier!).stringByAppendingPathComponent("headerfooter").stringByAppendingPathComponent("headerfooter.plist")
  12. static let defaultManager: KMHeaderFooterManager = {
  13. var manager = KMHeaderFooterManager()
  14. if let storedData = UserDefaults.standard.value(forKey: kHeaderFooterInfoSaveKey) as? Data {
  15. manager = NSKeyedUnarchiver.unarchiveObject(with: storedData) as! KMHeaderFooterManager
  16. } else {
  17. manager = KMHeaderFooterManager()
  18. if manager.headFooterObjects == nil {
  19. manager.headFooterObjects = []
  20. }
  21. }
  22. return manager
  23. }()
  24. func encode(with coder: NSCoder) {
  25. coder.encode(self.headFooterObjects, forKey: "headFooterObjects")
  26. }
  27. required init?(coder: NSCoder) {
  28. self.headFooterObjects = coder.decodeObject(forKey: "headFooterObjects") as? [KMHeaderFooterModel]
  29. }
  30. var datas: Array<KMHeaderFooterModel> = []
  31. var headFooterObjects: [KMHeaderFooterModel]?
  32. lazy var dateFormatArray: Array = {
  33. let arr = [
  34. "m/d",
  35. "m/d/yy",
  36. "m/d/yyyy",
  37. "mm/dd/yy",
  38. "mm/dd/yyyy",
  39. "d/m/yy",
  40. "d/m/yyyy",
  41. "dd/mm/yy",
  42. "dd/mm/yyyy",
  43. "mm/yy",
  44. "mm/yyyy",
  45. "m.d.yy",
  46. "m.d.yyyy",
  47. "mm.dd.yy",
  48. "mm.dd.yyyy",
  49. "mm.yy",
  50. "mm.yyyy",
  51. "d.m.yy",
  52. "d.m.yyyy",
  53. "dd.mm.yy",
  54. "dd.mm.yyyy",
  55. "yy-mm-dd",
  56. "yyyy-mm-dd"
  57. ]
  58. return arr
  59. }()
  60. lazy var onlyBatesObjects: [KMHeaderFooterModel] = {
  61. var arr: [KMHeaderFooterModel] = Array<KMHeaderFooterModel>()
  62. for i in 0..<(headFooterObjects?.count ?? 0) {
  63. let obj = headFooterObjects?[i]
  64. if KMDataVersionManager.updateBatesData() {
  65. KMDataVersionManager.refrshBatesData(bates: obj)
  66. store()
  67. }
  68. if obj!.isBates {
  69. arr.append(obj!)
  70. }
  71. }
  72. return arr
  73. }()
  74. lazy var onlyHeaderFooterObjects: [KMHeaderFooterModel] = {
  75. var arr: [KMHeaderFooterModel] = Array<KMHeaderFooterModel>()
  76. for i in 0..<(headFooterObjects?.count ?? 0) {
  77. let obj = headFooterObjects?[i]
  78. if !obj!.isBates {
  79. arr.append(obj!)
  80. }
  81. }
  82. return arr
  83. }()
  84. override init() {
  85. super.init()
  86. if (FileManager.default.fileExists(atPath: kPlistPath!)) {
  87. let dataDict = NSDictionary(contentsOfFile: kPlistPath!)
  88. if (dataDict == nil) {
  89. return
  90. }
  91. for keyIndex in 0 ..< (dataDict?.allKeys.count)! {
  92. let key: String = dataDict?.allKeys[keyIndex] as! String
  93. let backgroundDict: NSDictionary = dataDict?.object(forKey: key) as! NSDictionary
  94. let model = parseDictionary(dict: backgroundDict)
  95. /// 赋值id
  96. model.id = key
  97. self.datas.append(model)
  98. }
  99. /// 根据id进行排序(升序)
  100. self.datas.sort(){$0.id > $1.id}
  101. }
  102. }
  103. func store() {
  104. let encodedObject = NSKeyedArchiver.archivedData(withRootObject: self)
  105. let defaults = UserDefaults.standard
  106. defaults.set(encodedObject, forKey: kHeaderFooterInfoSaveKey)
  107. defaults.synchronize()
  108. }
  109. func fetchBatesAvailableName() -> String {
  110. var availableIndex = 0
  111. let nameArray = converArrType(arr: onlyBatesObjects, keyString: "id")
  112. for i in 0..<nameArray.count {
  113. let string = nameArray[i]
  114. if string.hasPrefix("Bates") {
  115. let index = Int(string.substring(from: "Bates".endIndex))!
  116. if index >= availableIndex {
  117. availableIndex = index + 1
  118. }
  119. }
  120. }
  121. return String(format: "Bates%ld", availableIndex)
  122. }
  123. func fetchHeaderFooterAvailableName() -> String {
  124. var availableIndex = 0
  125. let nameArray = converArrType(arr: onlyHeaderFooterObjects, keyString: "id")
  126. for i in 0..<nameArray.count {
  127. let string = nameArray[i]
  128. if string.hasPrefix("HeaderFooter") {
  129. let index = Int(string.substring(from: "HeaderFooter".endIndex))!
  130. if index >= availableIndex {
  131. availableIndex = index + 1
  132. }
  133. }
  134. }
  135. return String(format: "HeaderFooter%ld", availableIndex)
  136. }
  137. func converArrType(arr: Array<KMHeaderFooterModel>, keyString: String) -> [String] {
  138. let newArr = NSMutableArray()
  139. for item in arr {
  140. newArr.add(item.id)
  141. }
  142. return newArr as! [String]
  143. }
  144. func addTemplate(_ model: KMHeaderFooterModel) -> Bool {
  145. if (!FileManager.default.fileExists(atPath: kFolderPath!)) {
  146. let create: ()? = try?FileManager.default.createDirectory(atPath: kFolderPath!, withIntermediateDirectories: false)
  147. if (create == nil) {
  148. return false
  149. }
  150. }
  151. if (!FileManager.default.fileExists(atPath: kPlistPath!)) {
  152. let create = try?FileManager.default.createFile(atPath: kPlistPath!, contents: nil)
  153. if (create == nil) {
  154. return false
  155. }
  156. }
  157. let dict = NSDictionary(contentsOfFile: kPlistPath!)
  158. var newDict:NSMutableDictionary!
  159. if (dict != nil) {
  160. newDict = NSMutableDictionary(dictionary: dict!)
  161. } else {
  162. newDict = NSMutableDictionary()
  163. }
  164. let modelDict = self.parseModel(model: model)
  165. let tag = tagString()
  166. newDict.addEntries(from: [tag : modelDict])
  167. model.id = tag
  168. let result = newDict.write(toFile: kPlistPath!, atomically: true)
  169. if (result) {
  170. if (self.datas.count < 1) {
  171. self.datas.append(model)
  172. } else {
  173. self.datas.insert(model, at: 0)
  174. }
  175. }
  176. return result
  177. }
  178. func deleteTemplate(_ model: KMHeaderFooterModel) -> Bool {
  179. if (model.id.isEmpty) {
  180. return false
  181. }
  182. if (!FileManager.default.fileExists(atPath: kPlistPath!)) {
  183. return false
  184. }
  185. let key: String = model.id
  186. let dictionary = NSDictionary(contentsOfFile: kPlistPath!)
  187. var newDictionary: NSMutableDictionary!
  188. if (dictionary != nil) {
  189. newDictionary = NSMutableDictionary(dictionary: dictionary!)
  190. } else {
  191. newDictionary = NSMutableDictionary()
  192. }
  193. newDictionary.removeObject(forKey: key)
  194. let result = newDictionary.write(toFile: kPlistPath!, atomically: true)
  195. if (result) {
  196. if (self.datas.contains(model)) {
  197. self.datas.removeObject(model)
  198. }
  199. }
  200. return result
  201. }
  202. func deleteAllTemplate() -> Bool {
  203. if (!FileManager.default.fileExists(atPath: kPlistPath!)) {
  204. return false
  205. }
  206. let dictionary = NSDictionary(contentsOfFile: kPlistPath!)
  207. var newDictionary: NSMutableDictionary!
  208. if (dictionary != nil) {
  209. newDictionary = NSMutableDictionary(dictionary: dictionary!)
  210. } else {
  211. newDictionary = NSMutableDictionary()
  212. }
  213. newDictionary.removeAllObjects()
  214. let result = newDictionary.write(toFile: kPlistPath!, atomically: true)
  215. if (result) {
  216. self.datas.removeAll()
  217. }
  218. return result
  219. }
  220. func updateTemplate(_ model: KMHeaderFooterModel) -> Bool {
  221. if (!FileManager.default.fileExists(atPath: kFolderPath!)) {
  222. let create = try?FileManager.default.createDirectory(atPath: kFolderPath!, withIntermediateDirectories: false)
  223. if (create == nil) {
  224. return false
  225. }
  226. }
  227. if (!FileManager.default.fileExists(atPath: kPlistPath!)) {
  228. let create = try?FileManager.default.createFile(atPath: kPlistPath!, contents: nil)
  229. if (create == nil) {
  230. return false
  231. }
  232. }
  233. var flagModel: KMHeaderFooterModel!
  234. for model_ in self.datas {
  235. if (model_.id == model.id) {
  236. flagModel = model_
  237. break
  238. }
  239. }
  240. if (flagModel == nil) {
  241. return false
  242. }
  243. let dict = NSDictionary(contentsOfFile: kPlistPath!)
  244. var newDict:NSMutableDictionary!
  245. if (dict != nil) {
  246. newDict = NSMutableDictionary(dictionary: dict!)
  247. } else {
  248. newDict = NSMutableDictionary()
  249. }
  250. let modelDict = self.parseModel(model: model)
  251. newDict.setObject(modelDict, forKey: flagModel.id as NSCopying)
  252. let result = newDict.write(toFile: kPlistPath!, atomically: true)
  253. if (result) {
  254. let index = self.datas.index(of: flagModel)
  255. self.datas[index!] = model
  256. }
  257. return result
  258. }
  259. func removeHeaderFooter(_ obj: KMHeaderFooterModel) {
  260. self.headFooterObjects?.removeObject(obj)
  261. self.store()
  262. }
  263. /**
  264. `Private Methods`
  265. */
  266. private func parseModel(model: KMHeaderFooterModel) -> Dictionary<String, Any> {
  267. var dict: [String : Any] = [:]
  268. /// 字体相关
  269. switch model.textFont {
  270. case .font(name: var name, size: var size):
  271. dict["fontName"] = name
  272. dict["fontSize"] = size
  273. default: break
  274. }
  275. switch model.textColor {
  276. case .color(red: var red, green: var green, blue: var blue, alpha: var alpha):
  277. dict["red"] = red
  278. dict["green"] = green
  279. dict["blue"] = blue
  280. dict["alpha"] = alpha
  281. default: break
  282. }
  283. /// 页边距
  284. dict["leftMargin"] = model.leftMargin
  285. dict["rightMargin"] = model.rightMargin
  286. dict["bottomMargin"] = model.bottomMargin
  287. dict["topMargin"] = model.topMargin
  288. /// 内容
  289. dict["topLeftString"] = model.topLeftString
  290. dict["topCenterString"] = model.topCenterString
  291. dict["topRightString"] = model.topRightString
  292. dict["bottomLeftString"] = model.bottomLeftString
  293. dict["bottomCenterString"] = model.bottomCenterString
  294. dict["bottomRightString"] = model.bottomRightString
  295. /// 日期
  296. dict["dateFormatString"] = model.dateFormatString
  297. /// 页面
  298. dict["pageRangeString"] = model.pageRangeString
  299. dict["startString"] = model.startString
  300. /// 页面范围
  301. dict["pageRangeType"] = model.pageRangeType.rawValue
  302. dict["pageRangeString"] = model.pageRangeString
  303. return dict
  304. }
  305. private func parseDictionary(dict: NSDictionary) -> KMHeaderFooterModel {
  306. let model = KMHeaderFooterModel()
  307. /// 字体相关
  308. model.textFont = .font(name: dict["fontName"] as! String, size: dict["fontSize"] as! CGFloat)
  309. model.textColor = .color(red: dict["red"] as! CGFloat, green: dict["green"] as! CGFloat, blue: dict["blue"] as! CGFloat, alpha: dict["alpha"] as! CGFloat)
  310. /// 页边距
  311. model.leftMargin = dict["leftMargin"] as! CGFloat
  312. model.rightMargin = dict["rightMargin"] as! CGFloat
  313. model.bottomMargin = dict["bottomMargin"] as! CGFloat
  314. model.topMargin = dict["topMargin"] as! CGFloat
  315. /// 内容
  316. model.topLeftString = dict["topLeftString"] as! String
  317. model.topCenterString = dict["topCenterString"] as! String
  318. model.topRightString = dict["topRightString"] as! String
  319. model.bottomLeftString = dict["bottomLeftString"] as! String
  320. model.bottomCenterString = dict["bottomCenterString"] as! String
  321. model.bottomRightString = dict["bottomRightString"] as! String
  322. /// 日期
  323. model.dateFormatString = dict["dateFormatString"] as! String
  324. /// 页面
  325. model.pageRangeString = dict["pageRangeString"] as! String
  326. model.startString = dict["startString"] as! String
  327. /// 页面范围
  328. model.pageRangeType = KMWatermarkeModelPageRangeType.init(rawValue: dict["pageRangeType"] as! Int)!
  329. model.pageRangeString = dict["pageRangeString"] as! String
  330. return model
  331. }
  332. private func tagString() -> String {
  333. var result: String = ""
  334. let dateFormatter = DateFormatter()
  335. dateFormatter.dateFormat = "yyMMddHHmmss"
  336. result.append(dateFormatter.string(from: Date()))
  337. result = result.appendingFormat("%04d", arc4random()%10000)
  338. return result
  339. }
  340. }