123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613 |
- //
- // KMHeaderFooterManager.swift
- // PDF Master
- //
- // Created by tangchao on 2022/12/27.
- //
- import Cocoa
- let kHeaderFooterInfoSaveKey = "kHeaderFooterInfoSaveKey"
- class KMHeaderFooterObject: NSObject, NSCopying, NSCoding{
- var type: KMBatchHeaderFooterType = .HeaderFooter
- var leftMargin: Int = 30
- var rightMargin: Int = 30
- var bottomMargin: Int = 30
- var topMargin: Int = 30
- var topLeftString: String = ""
- var topCenterString: String = ""
- var topRightString: String = ""
- var bottomLeftString: String = ""
- var bottomCenterString: String = ""
- var bottomRightString: String = ""
- var startString: String = "1"
- var fontSize: CGFloat = 16.0
- var textColor: NSColor = .black
- var pagesString: String = ""
- var isBates: Bool = false
- var batesPrefixString: String = ""
- var batesSuffixString: String = ""
- var batesDigits: Int = 0
- var hasHeader: Bool = false
- var hasFooter: Bool = false
- var cellHeight: CGFloat = 0.0{
- willSet{
-
- }
- didSet {
- if cellHeight < 0.1 {
- var baseHeight: CGFloat = 33.0 + 24.0
- if self.topLeftString.count > 0 {
- baseHeight += 20.0
- }
-
- if topCenterString.count > 0 {
- baseHeight += 20.0
- }
-
- if topRightString.count > 0 {
- baseHeight += 20.0
- }
-
- if bottomLeftString.count > 0 {
- baseHeight += 20.0
- }
-
- if bottomCenterString.count > 0 {
- baseHeight += 20.0
- }
-
- if bottomRightString.count > 0 {
- baseHeight += 20.0
- }
-
- baseHeight -= 4.0
- cellHeight = baseHeight
- }
- }
- }
- var headerFooterID: String = ""
- var pageChoice: KMBatchOperatePageChoice = .All
- var dateFormatString: String = "m/d"
- var pageFormatString: String = "1"
-
- override init() {
- super.init()
- self.topLeftString = ""
- self.topCenterString = ""
- self.topRightString = ""
- self.bottomLeftString = ""
- self.bottomCenterString = ""
- self.bottomRightString = ""
- self.startString = ""
- self.pagesString = ""
- self.batesPrefixString = ""
- self.batesSuffixString = ""
- self.headerFooterID = ""
- self.fontSize = 16.0
- self.dateFormatString = "m/d"
- self.startString = "1"
- self.pageFormatString = "1"
- self.textColor = .black
- self.leftMargin = 30
- self.rightMargin = 30
- self.topMargin = 30
- self.bottomMargin = 30
- }
-
- func copy(with zone: NSZone? = nil) -> Any {
- var obj: KMHeaderFooterObject = KMHeaderFooterObject()
- obj.type = self.type
- obj.leftMargin = self.leftMargin
- obj.rightMargin = self.rightMargin
- obj.bottomMargin = self.bottomMargin
- obj.topMargin = self.topMargin
- obj.topLeftString = self.topLeftString
- obj.topCenterString = self.topCenterString
- obj.topRightString = self.topRightString
- obj.bottomLeftString = self.bottomLeftString
- obj.bottomCenterString = self.bottomCenterString
- obj.bottomRightString = self.bottomRightString
- obj.startString = self.startString
- obj.fontSize = self.fontSize
- obj.textColor = self.textColor
- obj.pagesString = self.pagesString
- obj.isBates = self.isBates
- obj.batesPrefixString = self.batesPrefixString
- obj.batesSuffixString = self.batesSuffixString
- obj.batesDigits = self.batesDigits
- obj.headerFooterID = self.headerFooterID
- obj.hasHeader = self.hasHeader
- obj.hasFooter = self.hasFooter
- obj.pageChoice = self.pageChoice
- obj.pageFormatString = self.pageFormatString
- obj.dateFormatString = self.dateFormatString
- return obj;
- }
-
- func encode(with coder: NSCoder) {
- coder.encode(self.type.rawValue, forKey: "type")
- coder.encode(self.leftMargin, forKey: "leftMargin")
- coder.encode(self.rightMargin, forKey: "rightMargin")
- coder.encode(self.bottomMargin, forKey: "bottomMargin")
- coder.encode(self.topMargin, forKey: "topMargin")
-
- coder.encode(self.topLeftString, forKey: "topLeftString")
-
- coder.encode(self.topCenterString, forKey: "topCenterString")
- coder.encode(self.topRightString, forKey: "topRightString")
- coder.encode(self.bottomLeftString, forKey: "bottomLeftString")
- coder.encode(self.bottomCenterString, forKey: "bottomCenterString")
- coder.encode(self.bottomRightString, forKey: "bottomRightString")
- coder.encode(self.startString, forKey: "startString")
- coder.encode(self.fontSize, forKey: "fontSize")
- coder.encode(self.textColor, forKey: "textColor")
-
- coder.encode(self.pagesString, forKey: "pagesString")
- coder.encode(self.isBates, forKey: "isBates")
- coder.encode(self.batesPrefixString, forKey: "batesPrefixString")
- coder.encode(self.batesSuffixString, forKey: "batesSuffixString")
- coder.encode(self.batesDigits, forKey: "batesDigits")
- coder.encode(self.hasHeader, forKey: "hasHeader")
- coder.encode(self.hasFooter, forKey: "hasFooter")
- coder.encode(self.cellHeight, forKey: "cellHeight")
- coder.encode(self.headerFooterID, forKey: "headerFooterID")
- coder.encode(self.pageChoice, forKey: "pageChoice")
- coder.encode(self.dateFormatString, forKey: "dateFormatString")
- coder.encode(self.pageFormatString, forKey: "pageFormatString")
- }
-
- required init?(coder: NSCoder) {
- type = KMBatchHeaderFooterType(rawValue: coder.decodeInteger(forKey: "type")) ?? .HeaderFooter
- leftMargin = coder.decodeInteger(forKey: "leftMargin")
- rightMargin = coder.decodeInteger(forKey: "rightMargin")
- bottomMargin = coder.decodeInteger(forKey: "bottomMargin")
- topMargin = coder.decodeInteger(forKey: "topMargin")
- topLeftString = coder.decodeObject(forKey: "topLeftString") as! String
- topCenterString = coder.decodeObject(forKey: "topCenterString") as! String
- topRightString = coder.decodeObject(forKey: "topRightString") as! String
-
- bottomLeftString = coder.decodeObject(forKey: "bottomLeftString") as! String
- bottomCenterString = coder.decodeObject(forKey: "bottomCenterString") as! String
- bottomRightString = coder.decodeObject(forKey: "bottomCenterString") as! String
- startString = coder.decodeObject(forKey: "startString") as! String
- fontSize = CGFloat(coder.decodeFloat(forKey: "fontSize"))
- textColor = coder.decodeObject(forKey: "textColor") as! NSColor
- pagesString = coder.decodeObject(forKey: "pagesString") as! String
- isBates = coder.decodeBool(forKey: "isBates")
- batesPrefixString = coder.decodeObject(forKey: "batesPrefixString") as! String
- batesSuffixString = coder.decodeObject(forKey: "batesSuffixString") as! String
- batesDigits = coder.decodeInteger(forKey: "batesDigits")
- hasHeader = coder.decodeBool(forKey: "hasHeader")
- hasFooter = coder.decodeBool(forKey: "hasFooter")
- cellHeight = CGFloat(coder.decodeFloat(forKey: "cellHeight"))
- headerFooterID = coder.decodeObject(forKey: "headerFooterID") as! String
- pageChoice = KMBatchOperatePageChoice(rawValue: coder.decodeInteger(forKey: "pageChoice")) ?? .All
- dateFormatString = coder.decodeObject(forKey: "dateFormatString") as! String
- pageFormatString = coder.decodeObject(forKey: "pageFormatString") as! String
- }
-
- func copyData(dataObj: KMHeaderFooterObject) {
- type = dataObj.type
- leftMargin = dataObj.leftMargin
- rightMargin = dataObj.rightMargin
- bottomMargin = dataObj.bottomMargin
- topMargin = dataObj.topMargin
- topLeftString = dataObj.topLeftString
- topCenterString = dataObj.topCenterString
- topRightString = dataObj.topRightString
- bottomLeftString = dataObj.bottomLeftString
- bottomCenterString = dataObj.bottomCenterString
- bottomRightString = dataObj.bottomRightString
- startString = dataObj.startString
- fontSize = dataObj.fontSize
- textColor = dataObj.textColor
- pagesString = dataObj.pagesString
- isBates = dataObj.isBates
- batesPrefixString = dataObj.batesPrefixString
- batesSuffixString = dataObj.batesSuffixString
- batesDigits = dataObj.batesDigits
- hasHeader = dataObj.hasHeader
- hasFooter = dataObj.hasFooter
- cellHeight = dataObj.cellHeight
- headerFooterID = dataObj.headerFooterID
- pageChoice = dataObj.pageChoice
- dateFormatString = dataObj.dateFormatString
- pageFormatString = dataObj.pageFormatString
- }
- }
- class KMHeaderFooterManager: NSObject, NSCoding{
-
-
- let kFolderPath = NSSearchPathForDirectoriesInDomains(FileManager.SearchPathDirectory.applicationSupportDirectory, FileManager.SearchPathDomainMask.userDomainMask, true).last?.stringByAppendingPathComponent(Bundle.main.bundleIdentifier!).stringByAppendingPathComponent("headerfooter")
- let kPlistPath = NSSearchPathForDirectoriesInDomains(FileManager.SearchPathDirectory.applicationSupportDirectory, FileManager.SearchPathDomainMask.userDomainMask, true).last?.stringByAppendingPathComponent(Bundle.main.bundleIdentifier!).stringByAppendingPathComponent("headerfooter").stringByAppendingPathComponent("headerfooter.plist")
-
- static let defaultManager: KMHeaderFooterManager = {
- var manager = KMHeaderFooterManager()
- if let storedData = UserDefaults.standard.value(forKey: kHeaderFooterInfoSaveKey) as? Data {
- manager = NSKeyedUnarchiver.unarchiveObject(with: storedData) as! KMHeaderFooterManager
- } else {
- manager = KMHeaderFooterManager()
- if manager.headFooterObjects == nil {
- manager.headFooterObjects = []
- }
- }
- return manager
- }()
-
- func encode(with coder: NSCoder) {
- coder.encode(self.headFooterObjects, forKey: "headFooterObjects")
- }
-
- required init?(coder: NSCoder) {
- self.headFooterObjects = coder.decodeObject(forKey: "headFooterObjects") as? [KMHeaderFooterObject]
- }
-
- var datas: Array<KMHeaderFooterModel> = []
-
- var headFooterObjects: [KMHeaderFooterObject]?
-
- lazy var dateFormatArray: Array = {
- let arr = [
- "m/d",
- "m/d/yy",
- "m/d/yyyy",
- "mm/dd/yy",
- "mm/dd/yyyy",
- "d/m/yy",
- "d/m/yyyy",
- "dd/mm/yy",
- "dd/mm/yyyy",
- "mm/yy",
- "mm/yyyy",
- "m.d.yy",
- "m.d.yyyy",
- "mm.dd.yy",
- "mm.dd.yyyy",
- "mm.yy",
- "mm.yyyy",
- "d.m.yy",
- "d.m.yyyy",
- "dd.mm.yy",
- "dd.mm.yyyy",
- "yy-mm-dd",
- "yyyy-mm-dd"
- ]
- return arr
- }()
-
- lazy var onlyBatesObjects: [KMHeaderFooterObject] = {
- var arr: [KMHeaderFooterObject] = Array<KMHeaderFooterObject>()
- for i in 0..<(headFooterObjects?.count ?? 0) {
- let obj = headFooterObjects?[i]
- if KMDataVersionManager.updateBatesData() {
- KMDataVersionManager.refrshBatesData(bates: obj)
- store()
- }
-
- if obj!.isBates {
- arr.append(obj!)
- }
- }
- return arr
- }()
- lazy var onlyHeaderFooterObjects: [KMHeaderFooterObject] = {
- var arr: [KMHeaderFooterObject] = Array<KMHeaderFooterObject>()
- for i in 0..<(headFooterObjects?.count ?? 0) {
- let obj = headFooterObjects?[i]
-
- if !obj!.isBates {
- arr.append(obj!)
- }
- }
- return arr
- }()
- override init() {
- super.init()
- if (FileManager.default.fileExists(atPath: kPlistPath!)) {
- let dataDict = NSDictionary(contentsOfFile: kPlistPath!)
- if (dataDict == nil) {
- return
- }
-
- 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.id = key
- self.datas.append(model)
- }
-
- /// 根据id进行排序(升序)
- self.datas.sort(){$0.id > $1.id}
- }
- }
-
- func store() {
- let encodedObject = NSKeyedArchiver.archivedData(withRootObject: self)
- let defaults = UserDefaults.standard
- defaults.set(encodedObject, forKey: kHeaderFooterInfoSaveKey)
- defaults.synchronize()
- }
-
- func fetchBatesAvailableName() -> String {
- var availableIndex = 0
- let nameArray = converArrType(arr: onlyBatesObjects, keyString: "headerFooterID")
- for i in 0..<nameArray.count {
- let string = nameArray[i]
- if string.hasPrefix("Bates") {
- let index = Int(string.substring(from: "Bates".endIndex))!
- if index >= availableIndex {
- availableIndex = index + 1
- }
- }
- }
- return String(format: "Bates%ld", availableIndex)
- }
-
- func fetchHeaderFooterAvailableName() -> String {
- var availableIndex = 0
- let nameArray = converArrType(arr: onlyHeaderFooterObjects, keyString: "headerFooterID")
- for i in 0..<nameArray.count {
- let string = nameArray[i]
- if string.hasPrefix("HeaderFooter") {
- let index = Int(string.substring(from: "HeaderFooter".endIndex))!
- if index >= availableIndex {
- availableIndex = index + 1
- }
- }
- }
- return String(format: "HeaderFooter%ld", availableIndex)
- }
-
- func converArrType(arr: Array<KMHeaderFooterObject>, keyString: String) -> [String] {
- var newArr = NSMutableArray()
- for item in arr {
- newArr.add(item.headerFooterID)
- }
- return newArr as! [String]
- }
-
- func addTemplate(_ model: KMHeaderFooterModel) -> Bool {
- if (!FileManager.default.fileExists(atPath: kFolderPath!)) {
- let create: ()? = try?FileManager.default.createDirectory(atPath: kFolderPath!, withIntermediateDirectories: false)
- if (create == nil) {
- return false
- }
- }
-
- if (!FileManager.default.fileExists(atPath: kPlistPath!)) {
- let create = try?FileManager.default.createFile(atPath: kPlistPath!, contents: nil)
- if (create == nil) {
- return false
- }
- }
-
- let dict = NSDictionary(contentsOfFile: kPlistPath!)
- var newDict:NSMutableDictionary!
- if (dict != nil) {
- newDict = NSMutableDictionary(dictionary: dict!)
- } else {
- newDict = NSMutableDictionary()
- }
-
- let modelDict = self.parseModel(model: model)
-
- let tag = tagString()
- newDict.addEntries(from: [tag : modelDict])
- model.id = tag
- let result = newDict.write(toFile: kPlistPath!, 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: KMHeaderFooterModel) -> Bool {
- if (model.id.isEmpty) {
- return false
- }
-
- if (!FileManager.default.fileExists(atPath: kPlistPath!)) {
- return false
- }
-
- let key: String = model.id
-
- let dictionary = NSDictionary(contentsOfFile: kPlistPath!)
- var newDictionary: NSMutableDictionary!
- if (dictionary != nil) {
- newDictionary = NSMutableDictionary(dictionary: dictionary!)
- } else {
- newDictionary = NSMutableDictionary()
- }
- newDictionary.removeObject(forKey: key)
-
- let result = newDictionary.write(toFile: kPlistPath!, atomically: true)
- if (result) {
- if (self.datas.contains(model)) {
- self.datas.removeObject(model)
- }
- }
- return result
- }
-
- func deleteAllTemplate() -> Bool {
- if (!FileManager.default.fileExists(atPath: kPlistPath!)) {
- return false
- }
-
- let dictionary = NSDictionary(contentsOfFile: kPlistPath!)
- var newDictionary: NSMutableDictionary!
- if (dictionary != nil) {
- newDictionary = NSMutableDictionary(dictionary: dictionary!)
- } else {
- newDictionary = NSMutableDictionary()
- }
-
- newDictionary.removeAllObjects()
-
- let result = newDictionary.write(toFile: kPlistPath!, atomically: true)
- if (result) {
- self.datas.removeAll()
- }
-
- return result
- }
-
- func updateTemplate(_ model: KMHeaderFooterModel) -> Bool {
- if (!FileManager.default.fileExists(atPath: kFolderPath!)) {
- let create = try?FileManager.default.createDirectory(atPath: kFolderPath!, withIntermediateDirectories: false)
- if (create == nil) {
- return false
- }
- }
-
- if (!FileManager.default.fileExists(atPath: kPlistPath!)) {
- let create = try?FileManager.default.createFile(atPath: kPlistPath!, contents: nil)
- if (create == nil) {
- return false
- }
- }
-
- var flagModel: KMHeaderFooterModel!
- for model_ in self.datas {
- if (model_.id == model.id) {
- flagModel = model_
- break
- }
- }
-
- if (flagModel == nil) {
- return false
- }
-
- let dict = NSDictionary(contentsOfFile: kPlistPath!)
- var newDict:NSMutableDictionary!
- if (dict != nil) {
- newDict = NSMutableDictionary(dictionary: dict!)
- } else {
- newDict = NSMutableDictionary()
- }
-
- let modelDict = self.parseModel(model: model)
- newDict.setObject(modelDict, forKey: flagModel.id as NSCopying)
- let result = newDict.write(toFile: kPlistPath!, atomically: true)
- if (result) {
- let index = self.datas.index(of: flagModel)
- self.datas[index!] = model
- }
-
- return result
- }
- func removeHeaderFooter(_ obj: KMHeaderFooterObject) {
- self.headFooterObjects?.removeObject(obj)
- self.store()
- }
-
- /**
- `Private Methods`
- */
- private func parseModel(model: KMHeaderFooterModel) -> Dictionary<String, Any> {
- var dict: [String : Any] = [:]
- /// 字体相关
- switch model.textFont {
- case .font(name: var name, size: var size):
- dict["fontName"] = name
- dict["fontSize"] = size
- default: break
- }
-
- switch model.textColor {
- case .color(red: var red, green: var green, blue: var blue, alpha: var alpha):
- dict["red"] = red
- dict["green"] = green
- dict["blue"] = blue
- dict["alpha"] = alpha
- default: break
- }
-
- /// 页边距
- dict["leftMargin"] = model.leftMargin
- dict["rightMargin"] = model.rightMargin
- dict["bottomMargin"] = model.bottomMargin
- dict["topMargin"] = model.topMargin
-
- /// 内容
- dict["topLeftString"] = model.topLeftString
- dict["topCenterString"] = model.topCenterString
- dict["topRightString"] = model.topRightString
- dict["bottomLeftString"] = model.bottomLeftString
- dict["bottomCenterString"] = model.bottomCenterString
- dict["bottomRightString"] = model.bottomRightString
-
- /// 日期
- dict["dateFormatString"] = model.dateFormatString
-
- /// 页面
- dict["pageRangeString"] = model.pageRangeString
- dict["startString"] = model.startString
-
- /// 页面范围
- dict["pageRangeType"] = model.pageRangeType
- dict["pageRangeString"] = model.pageRangeString
-
- return dict
- }
-
- private func parseDictionary(dict: NSDictionary) -> KMHeaderFooterModel {
- let model = KMHeaderFooterModel()
-
- /// 字体相关
- model.textFont = .font(name: dict["fontName"] as! String, size: dict["fontSize"] as! CGFloat)
- model.textColor = .color(red: dict["red"] as! CGFloat, green: dict["green"] as! CGFloat, blue: dict["blue"] as! CGFloat, alpha: dict["alpha"] as! CGFloat)
- /// 页边距
- model.leftMargin = dict["leftMargin"] as! CGFloat
- model.rightMargin = dict["rightMargin"] as! CGFloat
- model.bottomMargin = dict["bottomMargin"] as! CGFloat
- model.topMargin = dict["topMargin"] as! CGFloat
-
- /// 内容
- model.topLeftString = dict["topLeftString"] as! String
- model.topCenterString = dict["topCenterString"] as! String
- model.topRightString = dict["topRightString"] as! String
- model.bottomLeftString = dict["bottomLeftString"] as! String
- model.bottomCenterString = dict["bottomCenterString"] as! String
- model.bottomRightString = dict["bottomRightString"] as! String
-
- /// 日期
- model.dateFormatString = dict["dateFormatString"] as! String
-
- /// 页面
- model.pageRangeString = dict["pageRangeString"] as! String
- model.startString = dict["startString"] as! String
-
- /// 页面范围
- model.pageRangeType = dict["pageRangeType"] as! Int
- model.pageRangeString = dict["pageRangeString"] 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
- }
- }
|