123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453 |
- //
- // KMWatermarkManager.swift
- // PDF Master
- //
- // Created by tangchao on 2022/12/19.
- //
- import Cocoa
- enum KMWatermarkKey: String {
- case text = "text"
- case textFontSize = "textFontSize"
- case textFontName = "textFontName"
- case imagePath = "imagePath"
- case rotate = "rotate"
- case opacity = "opacity"
- case scale = "scale"
- case verticalMode = "verticalMode"
- case verticalSpace = "verticalSpace"
- case horizontalMode = "horizontalMode"
- case horizontalSpace = "horizontalSpace"
- case isFront = "isFront"
- case red = "red"
- case green = "green"
- case blue = "blue"
- case createDate = "createDate"
- case pageRangeType = "pageRangeType"
- case pageRangeString = "pageRangeString"
- case tileVerticalSpace = "tileVerticalSpace"
- case tileHorizontalSpace = "tileHorizontalSpace"
- case isTile = "isTile"
- case lastAddData = "lastAddData"
- case id = "id"
- }
- class KMWatermarkManager: NSObject {
- let watermarkFolderPath = NSSearchPathForDirectoriesInDomains(FileManager.SearchPathDirectory.applicationSupportDirectory, FileManager.SearchPathDomainMask.userDomainMask, true).last?.stringByAppendingPathComponent(Bundle.main.bundleIdentifier!).stringByAppendingPathComponent("watermark")
- let watermarkPlistPath = NSSearchPathForDirectoriesInDomains(FileManager.SearchPathDirectory.applicationSupportDirectory, FileManager.SearchPathDomainMask.userDomainMask, true).last?.stringByAppendingPathComponent(Bundle.main.bundleIdentifier!).stringByAppendingPathComponent("watermark").stringByAppendingPathComponent("watermark.plist")
-
- static let defaultManager = KMWatermarkManager()
-
- var watermarks: Array<KMWatermarkModel> = []
-
- override init() {
- super.init()
- if (FileManager.default.fileExists(atPath: watermarkPlistPath!)) {
- let dataDict = NSDictionary(contentsOfFile: watermarkPlistPath!)
- var deleteKeys: Array<String> = []
- for keyIndex in 0 ..< (dataDict?.allKeys.count)! {
- let key: String = dataDict?.allKeys[keyIndex] as! String
- let watermarkDict: NSDictionary = dataDict?.object(forKey: key) as! NSDictionary
-
- let model = parseDictionary(dict: watermarkDict)
- /// 赋值tag
- model.tag = key
- let isFile: Bool = (watermarkDict.object(forKey: KMWatermarkKey.imagePath.rawValue) != nil)
- if (isFile) {
- if (model.image == nil) {
- deleteKeys.append(key)
- } else {
- self.watermarks.append(model)
- }
- } else {
- self.watermarks.append(model)
- }
- }
-
- /// 根据id进行排序(升序)
- self.watermarks.sort(){$0.watermarkID > $1.watermarkID}
-
- if (deleteKeys.count > 0) {
- var newDict: NSMutableDictionary = NSMutableDictionary(dictionary: dataDict!)
- for key in deleteKeys {
- newDict.removeObject(forKey: key)
- }
- newDict.write(toFile: watermarkPlistPath!, atomically: true)
- }
- }
- }
-
- func addWatermark(watermark: KMWatermarkModel) -> Bool {
- if (!FileManager.default.fileExists(atPath: watermarkFolderPath!)) {
- let create = try?FileManager.default.createDirectory(atPath: watermarkFolderPath!, withIntermediateDirectories: false)
- if (create == nil) {
- return false
- }
- }
-
- if (!FileManager.default.fileExists(atPath: watermarkPlistPath!)) {
- let create = try?FileManager.default.createFile(atPath: watermarkPlistPath!, contents: nil)
- if (create == nil) {
- return false
- }
- }
-
- let dict = NSDictionary(contentsOfFile: watermarkPlistPath!)
- var newDict:NSMutableDictionary!
- if (dict != nil) {
- newDict = NSMutableDictionary(dictionary: dict!)
- } else {
- newDict = NSMutableDictionary()
- }
-
- let watermarkDict = self.parseModel(model: watermark)
- if (watermarkDict.isEmpty) {
- let alert = NSAlert()
- alert.alertStyle = .critical
- alert.messageText = NSLocalizedString("文件\(watermark.imagePath.lastPathComponent)已损坏", comment: "")
- alert.runModal()
- return false
- }
-
- let tag = tagString()
- newDict.addEntries(from: [tag : watermarkDict])
- watermark.tag = tag
- let result = newDict.write(toFile: watermarkPlistPath!, atomically: true)
- if (result) {
- if (self.watermarks.count < 1) {
- self.watermarks.append(watermark)
- } else {
- self.watermarks.insert(watermark, at: 0)
- }
- }
-
- return result
- }
-
- func updateWatermark(watermark: KMWatermarkModel) -> Bool {
- if (!FileManager.default.fileExists(atPath: watermarkFolderPath!)) {
- let create = try?FileManager.default.createDirectory(atPath: watermarkFolderPath!, withIntermediateDirectories: false)
- if (create == nil) {
- return false
- }
- }
-
- if (!FileManager.default.fileExists(atPath: watermarkPlistPath!)) {
- let create = try?FileManager.default.createFile(atPath: watermarkPlistPath!, contents: nil)
- if (create == nil) {
- return false
- }
- }
-
- var flagModel: KMWatermarkModel!
- for model in self.watermarks {
- if (model.tag == watermark.tag) {
- flagModel = model
- break
- }
- }
-
- if (flagModel == nil) {
- return false
- }
-
- let dict = NSDictionary(contentsOfFile: watermarkPlistPath!)
- var newDict:NSMutableDictionary!
- if (dict != nil) {
- newDict = NSMutableDictionary(dictionary: dict!)
- } else {
- newDict = NSMutableDictionary()
- }
-
- let watermarkDict = self.parseModel(model: watermark)
- if (watermarkDict.isEmpty) {
- let alert = NSAlert()
- alert.alertStyle = .critical
- alert.messageText = NSLocalizedString("文件\(watermark.imagePath.lastPathComponent)已损坏", comment: "")
- alert.runModal()
- return false
- }
-
- newDict.setObject(watermarkDict, forKey: flagModel.tag! as NSCopying)
- let result = newDict.write(toFile: watermarkPlistPath!, atomically: true)
- if (result) {
- let index = self.watermarks.index(of: flagModel)
- self.watermarks[index!] = watermark
- }
-
- return result
- }
-
- func removeWatermark(watermark: KMWatermarkModel) -> Bool {
- if (watermark == nil) {
- return false
- }
-
- if (watermark.tag == nil) {
- return false
- }
-
- if (!FileManager.default.fileExists(atPath: watermarkPlistPath!)) {
- return false
- }
-
- let key: String = watermark.tag
-
- let dictionary = NSDictionary(contentsOfFile: watermarkPlistPath!)
- var newDictionary: NSMutableDictionary!
- if (dictionary != nil) {
- newDictionary = NSMutableDictionary(dictionary: dictionary!)
- } else {
- newDictionary = NSMutableDictionary()
- }
- newDictionary.removeObject(forKey: key)
-
- let result = newDictionary.write(toFile: watermarkPlistPath!, atomically: true)
- if (result) {
- if (watermark.text == nil || watermark.text.isEmpty) {
- let filePath: String = watermark.imagePath
- try?FileManager.default.removeItem(atPath: filePath)
- }
-
- if (self.watermarks.contains(watermark)) {
- self.watermarks.removeObject(watermark)
- }
- }
- return result
- }
-
- func removeAllWatermark() -> Bool {
- if (!FileManager.default.fileExists(atPath: watermarkPlistPath!)) {
- return false
- }
-
- let dictionary = NSDictionary(contentsOfFile: watermarkPlistPath!)
- var newDictionary: NSMutableDictionary!
- if (dictionary != nil) {
- newDictionary = NSMutableDictionary(dictionary: dictionary!)
- } else {
- newDictionary = NSMutableDictionary()
- }
-
- newDictionary.removeAllObjects()
-
- let result = newDictionary.write(toFile: watermarkPlistPath!, atomically: true)
- if (result) {
- self.watermarks.removeAll()
- }
-
- return result
- }
-
- func removeAllTextWatermarks() -> Bool {
- if (!FileManager.default.fileExists(atPath: watermarkPlistPath!)) {
- return false
- }
-
- let dictionary = NSDictionary(contentsOfFile: watermarkPlistPath!)
- var newDictionary: NSMutableDictionary!
- if (dictionary != nil) {
- newDictionary = NSMutableDictionary(dictionary: dictionary!)
- } else {
- newDictionary = NSMutableDictionary()
- }
-
- let count = self.watermarks.count-1
- var deleteArray: Array<KMWatermarkModel> = []
- for i in 0 ... count {
- let model = self.watermarks[i]
- if (model.text != nil && !model.text.isEmpty) {
- newDictionary.removeObject(forKey: model.tag as Any)
- deleteArray.append(model)
- }
- }
-
- let result = newDictionary.write(toFile: watermarkPlistPath!, atomically: true)
- if (result) {
- for model in deleteArray {
- self.watermarks.removeObject(model)
- }
- }
-
- return result
- }
-
- func removeAllFileWatermarks() -> Bool {
- if (!FileManager.default.fileExists(atPath: watermarkPlistPath!)) {
- return false
- }
-
- let dictionary = NSDictionary(contentsOfFile: watermarkPlistPath!)
- var newDictionary: NSMutableDictionary!
- if (dictionary != nil) {
- newDictionary = NSMutableDictionary(dictionary: dictionary!)
- } else {
- newDictionary = NSMutableDictionary()
- }
-
- let count = self.watermarks.count-1
- var deleteArray: Array<KMWatermarkModel> = []
- for i in 0 ... count {
- let model = self.watermarks[i]
- if (model.image != nil) {
- newDictionary.removeObject(forKey: model.tag as Any)
- deleteArray.append(model)
- }
- }
-
- let result = newDictionary.write(toFile: watermarkPlistPath!, atomically: true)
- if (result) {
- for model in deleteArray {
- self.watermarks.removeObject(model)
- }
- }
-
- return result
- }
-
- private func parseModel(model: KMWatermarkModel) -> Dictionary<String, Any> {
- let tag = tagString()
- let dateFormatter = DateFormatter()
- dateFormatter.dateFormat = "yy-MM-dd HH:mm:ss"
- let timeString = dateFormatter.string(from: Date())
- model.creatTemplateDate = timeString
-
- var dict: [String : Any] = [:]
- if (!model.text.isEmpty) {
- dict[KMWatermarkKey.text.rawValue] = model.text
- dict[KMWatermarkKey.textFontSize.rawValue] = model.getTextFontSize()
- dict[KMWatermarkKey.textFontName.rawValue] = model.getTextFontName()
- } else {
- if (!FileManager.default.fileExists(atPath: watermarkFolderPath!)) {
- try?FileManager.default.createDirectory(atPath: watermarkFolderPath!, withIntermediateDirectories: false)
- }
-
- let path = watermarkFolderPath?.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[KMWatermarkKey.imagePath.rawValue] = path?.lastPathComponent
- }
- catch {
- KMPrint("Failed to write to disk.")
- return [:]
- }
- }
-
- var red: CGFloat = 0.0
- var green: CGFloat = 0.0
- var blue: CGFloat = 0.0
- model.getTextColor().usingColorSpaceName(NSColorSpaceName.calibratedRGB)?.getRed(&red, green: &green, blue: &blue, alpha: nil)
- dict[KMWatermarkKey.isFront.rawValue] = model.isFront
- dict[KMWatermarkKey.scale.rawValue] = model.scale
- dict[KMWatermarkKey.opacity.rawValue] = model.opacity
- dict[KMWatermarkKey.rotate.rawValue] = model.rotation
- dict[KMWatermarkKey.verticalMode.rawValue] = model.verticalMode
- dict[KMWatermarkKey.verticalSpace.rawValue] = model.verticalSpace
- dict[KMWatermarkKey.horizontalMode.rawValue] = model.horizontalMode
- dict[KMWatermarkKey.horizontalSpace.rawValue] = model.horizontalSpace
- dict[KMWatermarkKey.red.rawValue] = red
- dict[KMWatermarkKey.green.rawValue] = green
- dict[KMWatermarkKey.blue.rawValue] = blue
- dict[KMWatermarkKey.isTile.rawValue] = model.isTilePage
- dict[KMWatermarkKey.tileVerticalSpace.rawValue] = model.tileVerticalSpace
- dict[KMWatermarkKey.tileHorizontalSpace.rawValue] = model.tileHorizontalSpace
- dict[KMWatermarkKey.pageRangeType.rawValue] = model.pageRangeType
- dict[KMWatermarkKey.pageRangeString.rawValue] = model.pagesString
-
- dict[KMWatermarkKey.createDate.rawValue] = model.creatTemplateDate
- dict[KMWatermarkKey.id.rawValue] = model.watermarkID
-
- return dict
- }
-
- private func parseDictionary(dict: NSDictionary) -> KMWatermarkModel {
- let model = KMWatermarkModel()
-
- let isText: Bool = (dict.object(forKey: KMWatermarkKey.text.rawValue) != nil)
- let isFile: Bool = (dict.object(forKey: KMWatermarkKey.imagePath.rawValue) != nil)
- if (isText) {
- model.text = (dict.object(forKey: KMWatermarkKey.text.rawValue) as! String)
- let fontSize: CGFloat = dict.object(forKey: KMWatermarkKey.textFontSize.rawValue) as! CGFloat
- let fontName: String = dict.object(forKey: KMWatermarkKey.textFontName.rawValue) as! String
- model.textFont = .font(name: fontName, size: fontSize)
- } else if (isFile) {
- let path = watermarkFolderPath?.stringByAppendingPathComponent(dict.object(forKey: KMWatermarkKey.imagePath.rawValue) as! String)
- if (FileManager.default.fileExists(atPath: path!)) {
- model.image = NSImage(contentsOfFile: path!)
- model.imagePath = path
- } else {
- model.image = nil
- }
- }
-
- model.scale = (dict.object(forKey: KMWatermarkKey.scale.rawValue) as! CGFloat)
- model.rotation = dict.object(forKey: KMWatermarkKey.rotate.rawValue) as! CGFloat
- model.opacity = (dict.object(forKey: KMWatermarkKey.opacity.rawValue) as! CGFloat)
- model.verticalMode = (dict.object(forKey: KMWatermarkKey.verticalMode.rawValue) as! Int)
- model.verticalSpace = dict.object(forKey: KMWatermarkKey.verticalSpace.rawValue) as! CGFloat
- model.horizontalMode = (dict.object(forKey: KMWatermarkKey.horizontalMode.rawValue) as! Int)
- model.horizontalSpace = dict.object(forKey: KMWatermarkKey.horizontalSpace.rawValue) as! CGFloat
- let red: CGFloat = dict.object(forKey: KMWatermarkKey.red.rawValue) as! CGFloat
- let green: CGFloat = dict.object(forKey: KMWatermarkKey.green.rawValue) as! CGFloat
- let blue: CGFloat = dict.object(forKey: KMWatermarkKey.blue.rawValue) as! CGFloat
- model.textColor = .color(red: red, green: green, blue: blue, alpha: 1.0)
- model.isFront = (dict.object(forKey: KMWatermarkKey.isFront.rawValue) != nil)
- model.pageRangeType = (dict.object(forKey: KMWatermarkKey.pageRangeType.rawValue) as! Int)
- model.pagesString = (dict.object(forKey: KMWatermarkKey.pageRangeString.rawValue) as! String)
- model.isTilePage = (dict.object(forKey: KMWatermarkKey.isTile.rawValue) as! Bool)
- model.tileHorizontalSpace = (dict.object(forKey: KMWatermarkKey.tileHorizontalSpace.rawValue) as! CGFloat)
- model.tileVerticalSpace = (dict.object(forKey: KMWatermarkKey.tileVerticalSpace.rawValue) as! CGFloat)
- model.watermarkID = (dict.object(forKey: KMWatermarkKey.id.rawValue) as! String)
- model.creatTemplateDate = (dict.object(forKey: KMWatermarkKey.createDate.rawValue) as! String)
-
- return model
- }
-
- func fetchAvailableName() -> String {
- var availableIndex: Int = 0
- let watermark = "Watermark"
- for model in self.watermarks {
- let watermarkID = model.watermarkID
- if (((watermarkID?.hasPrefix(watermark))!)) {
- let indexString: String = (watermarkID?.components(separatedBy: watermark).last)!
- let index: Int = Int(indexString)!
- if (index >= availableIndex) {
- availableIndex = index + 1
- }
- }
- }
-
- return "\(watermark)\(availableIndex)"
- }
-
- /**
- Private Methods
- */
-
- 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
- }
- }
|