KMGeneralAnnotationViewController.swift 107 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786178717881789179017911792179317941795179617971798179918001801180218031804180518061807180818091810181118121813181418151816181718181819182018211822182318241825182618271828182918301831183218331834183518361837183818391840184118421843184418451846184718481849185018511852185318541855185618571858185918601861186218631864186518661867186818691870187118721873187418751876187718781879188018811882188318841885188618871888188918901891189218931894189518961897189818991900190119021903190419051906190719081909191019111912191319141915191619171918191919201921192219231924192519261927192819291930193119321933193419351936193719381939194019411942194319441945194619471948194919501951195219531954195519561957195819591960196119621963196419651966196719681969197019711972197319741975197619771978197919801981198219831984198519861987198819891990199119921993199419951996199719981999200020012002200320042005200620072008200920102011201220132014201520162017201820192020202120222023202420252026202720282029203020312032203320342035203620372038203920402041204220432044204520462047204820492050205120522053205420552056205720582059206020612062206320642065206620672068206920702071207220732074207520762077207820792080208120822083208420852086208720882089209020912092209320942095209620972098209921002101210221032104210521062107210821092110211121122113211421152116211721182119212021212122212321242125212621272128212921302131213221332134213521362137213821392140214121422143214421452146214721482149215021512152215321542155215621572158215921602161216221632164216521662167216821692170217121722173217421752176217721782179218021812182218321842185218621872188218921902191219221932194219521962197219821992200220122022203220422052206220722082209221022112212221322142215221622172218221922202221222222232224222522262227222822292230223122322233223422352236223722382239224022412242224322442245224622472248224922502251225222532254225522562257225822592260226122622263226422652266226722682269227022712272227322742275227622772278227922802281228222832284228522862287228822892290
  1. //
  2. // KMGeneralAnnotationViewController.swift
  3. // PDF Reader Pro
  4. //
  5. // Created by wanjun on 2023/12/1.
  6. //
  7. import Cocoa
  8. /**
  9. NSString *SKNFreeTextString = @"FreeText";
  10. NSString *SKNTextString = @"Text";
  11. NSString *SKNNoteString = @"Note";
  12. NSString *SKNCircleString = @"Circle";
  13. NSString *SKNSquareString = @"Square";
  14. NSString *SKNMarkUpString = @"MarkUp";
  15. NSString *SKNHighlightString = @"Highlight";
  16. NSString *SKNUnderlineString = @"Underline";
  17. NSString *SKNStrikeOutString = @"StrikeOut";
  18. NSString *SKNLineString = @"Line";
  19. NSString *SKNInkString = @"Ink";
  20. NSString *SKNPDFAnnotationTypeKey = @"type";
  21. NSString *SKNPDFAnnotationBoundsKey = @"bounds";
  22. NSString *SKNPDFAnnotationPageKey = @"page";
  23. NSString *SKNPDFAnnotationPageIndexKey = @"pageIndex";
  24. NSString *SKNPDFAnnotationContentsKey = @"contents";
  25. NSString *SKNPDFAnnotationStringKey = @"string";
  26. NSString *SKNPDFAnnotationColorKey = @"color";
  27. NSString *SKNPDFAnnotationBorderKey = @"border";
  28. NSString *SKNPDFAnnotationLineWidthKey = @"lineWidth";
  29. NSString *SKNPDFAnnotationBorderStyleKey = @"borderStyle";
  30. NSString *SKNPDFAnnotationDashPatternKey = @"dashPattern";
  31. NSString *SKNPDFAnnotationModificationDateKey = @"modificationDate";
  32. NSString *SKNPDFAnnotationUserNameKey = @"userName";
  33. NSString *SKNPDFAnnotationInteriorColorKey = @"interiorColor";
  34. NSString *SKNPDFAnnotationStartLineStyleKey = @"startLineStyle";
  35. NSString *SKNPDFAnnotationEndLineStyleKey = @"endLineStyle";
  36. NSString *SKNPDFAnnotationStartPointKey = @"startPoint";
  37. NSString *SKNPDFAnnotationEndPointKey = @"endPoint";
  38. NSString *SKNPDFAnnotationFontKey = @"font";
  39. NSString *SKNPDFAnnotationFontColorKey = @"fontColor";
  40. NSString *SKNPDFAnnotationFontNameKey = @"fontName";
  41. NSString *SKNPDFAnnotationFontSizeKey = @"fontSize";
  42. NSString *SKNPDFAnnotationAlignmentKey = @"alignment";
  43. NSString *SKNPDFAnnotationRotationKey = @"rotation";
  44. NSString *SKNPDFAnnotationQuadrilateralPointsKey = @"quadrilateralPoints";
  45. NSString *SKNPDFAnnotationIconTypeKey = @"iconType";
  46. NSString *SKNPDFAnnotationPointListsKey = @"pointLists";
  47. */
  48. enum KMActiveAnnotationType: UInt {
  49. case highlight = 0
  50. case strikeOut
  51. case underline
  52. case inkAndLine
  53. case text
  54. case squareAndCircle
  55. case freeText
  56. case selfSignFreeText
  57. }
  58. enum KMFreeTextAnnotationAlignmentType: UInt {
  59. case left = 0
  60. case center
  61. case right
  62. }
  63. let KMColorPickerViewHeight: CGFloat = 64
  64. @objcMembers class KMGeneralAnnotationViewController: NSViewController, NSTextViewDelegate {
  65. var _annotations: [CPDFAnnotation]?
  66. var subType: KMSelfSignAnnotationFreeTextSubType = .none
  67. var _activeAnnotationType: KMActiveAnnotationType = .highlight
  68. var pdfView: CPDFListView?
  69. var annotationModel: CPDFAnnotationModel?
  70. // var annotationCallback: ((CPDFAnnotation) -> Void)?
  71. @IBOutlet private weak var imageBox: NSBox!
  72. @IBOutlet private weak var imageBoxLayoutConstraint: NSLayoutConstraint!
  73. @IBOutlet private weak var textImageBoxView: NSView!
  74. @IBOutlet private weak var textImageBox: KMBox!
  75. @IBOutlet private weak var textAnnotationImageView: NSImageView!
  76. @IBOutlet private weak var textImageBoxButton: NSButton!
  77. @IBOutlet private weak var textImageUpDateButton: NSButton!
  78. @IBOutlet private weak var generalImageBoxView: NSView!
  79. @IBOutlet private weak var generalImageView: NSImageView!
  80. @IBOutlet private weak var fontView: NSView! // 字体
  81. @IBOutlet private weak var fontLabel: NSTextField!
  82. @IBOutlet private weak var fontButton: NSButton!
  83. @IBOutlet private weak var fontPopUpButton: KMPopUpButton!
  84. @IBOutlet private weak var fontSizeComboBox: KMComboBox!
  85. @IBOutlet private weak var fontStylePopUpButton: KMPopUpButton!
  86. @IBOutlet private weak var leftAlignButton: NSButton!
  87. @IBOutlet private weak var centerAlignButton: NSButton!
  88. @IBOutlet private weak var rightAlignButton: NSButton!
  89. @IBOutlet private weak var fontViewTopConstant: NSLayoutConstraint!
  90. @IBOutlet private weak var fontViewCorloPV: KMColorPickerView!
  91. @IBOutlet private weak var fontViewColorPVConstraint: NSLayoutConstraint!
  92. @IBOutlet private weak var rotateView: NSView! // 旋转
  93. @IBOutlet private weak var rotateLabel: NSTextField!
  94. @IBOutlet private weak var leftRotateBox: KMBox!
  95. @IBOutlet private weak var leftRotateButton: NSButton!
  96. @IBOutlet private weak var rightRotateBox: KMBox!
  97. @IBOutlet private weak var rightRotateButton: NSButton!
  98. @IBOutlet private weak var rotateViewTopConstant: NSLayoutConstraint!
  99. @IBOutlet private weak var typeView: NSView! // 类型
  100. @IBOutlet private weak var typeLabel: NSTextField!
  101. @IBOutlet private weak var tureTypeButton: NSButton!
  102. @IBOutlet private weak var falseTypeButton: NSButton!
  103. @IBOutlet private weak var circletypeButton: NSButton!
  104. @IBOutlet private weak var lineTypeButton: NSButton!
  105. @IBOutlet private weak var dotTypeButton: NSButton!
  106. @IBOutlet private weak var typeViewTopConstant: NSLayoutConstraint!
  107. @IBOutlet private weak var dateView: NSView! // 日期
  108. @IBOutlet private weak var dateLabel: NSTextField!
  109. @IBOutlet private weak var datePopUpButton: KMPopUpButton!
  110. @IBOutlet private weak var dateCheckButton: NSButton!
  111. @IBOutlet private weak var dateViewTopConstant: NSLayoutConstraint!
  112. @IBOutlet private weak var iconView: NSView! // 图标
  113. @IBOutlet private weak var iconLabel: NSTextField!
  114. @IBOutlet private weak var commentBox: NSBox!
  115. @IBOutlet private weak var commentButton: NSButton!
  116. @IBOutlet private weak var noteBox: NSBox!
  117. @IBOutlet private weak var noteButton: NSButton!
  118. @IBOutlet private weak var keyBox: NSBox!
  119. @IBOutlet private weak var keyButton: NSButton!
  120. @IBOutlet private weak var helpBox: NSBox!
  121. @IBOutlet private weak var helpButton: NSButton!
  122. @IBOutlet private weak var paragraphBox: NSBox!
  123. @IBOutlet private weak var paragraphButton: NSButton!
  124. @IBOutlet private weak var insertBox: NSBox!
  125. @IBOutlet private weak var insertButton: NSButton!
  126. @IBOutlet private weak var addParagraphBox: NSBox!
  127. @IBOutlet private weak var addParagraphButton: NSButton!
  128. @IBOutlet private weak var iconViewTopConstant: NSLayoutConstraint!
  129. @IBOutlet private weak var iconButtonHeightConstant: NSLayoutConstraint!
  130. @IBOutlet private weak var borderAndLineView: NSView! // 边框
  131. @IBOutlet private weak var borderLabel: NSTextField!
  132. @IBOutlet private weak var borderButton: NSButton!
  133. @IBOutlet private weak var lineWidthComboBox: KMComboBox!
  134. @IBOutlet private weak var lineWidthSlider: NSSlider!
  135. @IBOutlet private weak var lineTypeLabel: NSTextField!
  136. @IBOutlet private weak var lineStyleButton: KMButton!
  137. @IBOutlet private weak var dottedLineStyleButton: KMButton!
  138. @IBOutlet private weak var rightArrowStyleButton: KMButton!
  139. @IBOutlet private weak var lineStyleBox: NSBox!
  140. @IBOutlet private weak var dottedLineStyleBox: NSBox!
  141. @IBOutlet private weak var rightArrowStyleBox: NSBox!
  142. @IBOutlet private weak var borderViewTopConstant: NSLayoutConstraint!
  143. @IBOutlet private weak var fillColorView: NSView!
  144. @IBOutlet private weak var fillColorLabel: NSTextField!
  145. @IBOutlet private weak var fillColorPickerView: KMColorPickerView!
  146. @IBOutlet private weak var fillColorViewTopConstraint: NSLayoutConstraint!
  147. @IBOutlet private weak var opacityView: NSView! // 透明度
  148. @IBOutlet private weak var opacityLabel: NSTextField!
  149. @IBOutlet private weak var opacitySlider: NSSlider!
  150. @IBOutlet private weak var opacityComboBox: KMComboBox!
  151. @IBOutlet private weak var opacityViewTopConstant: NSLayoutConstraint!
  152. @IBOutlet private weak var noteView: NSView! // 笔记
  153. @IBOutlet private weak var noteViewLabel: NSTextField!
  154. @IBOutlet private var noteTextView: NSTextView!
  155. @IBOutlet private weak var noteViewTopConstant: NSLayoutConstraint!
  156. @IBOutlet private weak var colorView: NSView! // 颜色
  157. @IBOutlet private weak var colorTitleLabel: NSTextField!
  158. @IBOutlet private weak var textColorBox: NSBox!
  159. @IBOutlet private weak var textColorBoxConstraint: NSLayoutConstraint!
  160. @IBOutlet private weak var textColorPickerView: KMColorPickerView!
  161. @IBOutlet private weak var borderColorBox: NSBox!
  162. @IBOutlet private weak var borderColorPickerView: KMColorPickerView!
  163. @IBOutlet private weak var borderColorBoxConstraint: NSLayoutConstraint!
  164. @IBOutlet private weak var lineWidthBox: NSBox!
  165. @IBOutlet private weak var widthLabel: NSTextField!
  166. @IBOutlet private weak var widthComboBox: KMComboBox!
  167. @IBOutlet private weak var widthSlider: NSSlider!
  168. @IBOutlet private weak var ColorViewTopConstant: NSLayoutConstraint!
  169. @IBOutlet private weak var textColorPickerViewConstant: NSLayoutConstraint!
  170. var isannotationMode: Bool = false
  171. var selectedAlignmentButtonLayer: CALayer?
  172. var iconButtonArray: [NSBox] = []
  173. var lineStyleCount: Int = 0
  174. var isTextEdit: Bool = false
  175. var fonts: [[String : [String]]]!
  176. var noteIcons: [NSImage?] = [nil, nil, nil, nil, nil, nil, nil]
  177. private func makeNoteIcons() {
  178. if noteIcons[0] != nil { return }
  179. let bounds = CGRect(origin: .zero, size: NSMakeSize(16, 16))
  180. let annotation = CPDFTextAnnotation()
  181. annotation.bounds = bounds
  182. annotation.color = NSColor.clear
  183. let page = CPDFPage()
  184. page.setBounds(bounds, for: .mediaBox)
  185. page.addAnnotation(annotation)
  186. for i in 0..<7 {
  187. annotation.setIconType(CPDFTextAnnotationIconType(rawValue: i) ?? .comment)
  188. noteIcons[i] = NSImage.bitmapImage(with: NSMakeSize(16, 16), drawingHandler: { rect in
  189. page.draw(with: .mediaBox, to: (NSGraphicsContext.current?.cgContext))
  190. })
  191. }
  192. }
  193. deinit {
  194. NotificationCenter.default.removeObserver(self)
  195. if ((annotationModel?.annotation) != nil) && annotationModel?.annotations.count == 1 {
  196. let keys = ["contents", "markupText"]
  197. for key in keys {
  198. annotationModel?.annotation.removeObserver(self, forKeyPath: key)
  199. }
  200. }
  201. textColorPickerView.target = nil
  202. textColorPickerView.action = nil
  203. borderColorPickerView.target = nil
  204. borderColorPickerView.action = nil
  205. fillColorPickerView.target = nil
  206. fillColorPickerView.action = nil
  207. NSColorPanel.shared.setTarget(nil)
  208. NSColorPanel.shared.setAction(nil)
  209. }
  210. // MARK: View Methods
  211. override func loadView() {
  212. super.loadView()
  213. DispatchQueue.main.async {
  214. if NSColorPanel.shared.isVisible {
  215. NSColorPanel.shared.close()
  216. }
  217. }
  218. isannotationMode = true
  219. fonts = (CPDFAnnotationModel.supportFonts() as! [[String : [String]]])
  220. imageBox.borderColor = KMAppearance.Interactive.s0Color()
  221. imageBox.borderWidth = 1.0
  222. imageBox.fillColor = KMAppearance.Layout.l1Color()
  223. textImageBox.fillColor = KMAppearance.Layout.l1Color()
  224. fontLabel.stringValue = NSLocalizedString("Fonts", comment: "")
  225. fontLabel.textColor = KMAppearance.Layout.h0Color()
  226. colorTitleLabel.stringValue = NSLocalizedString("Color", comment: "")
  227. colorTitleLabel.textColor = KMAppearance.Layout.h0Color()
  228. opacityLabel.stringValue = NSLocalizedString("Opacity", comment: "")
  229. opacityLabel.textColor = KMAppearance.Layout.h1Color()
  230. noteViewLabel.stringValue = NSLocalizedString("Note", comment: "")
  231. noteViewLabel.textColor = KMAppearance.Layout.h0Color()
  232. rotateLabel.stringValue = NSLocalizedString("Rotate", comment: "")
  233. rotateLabel.textColor = KMAppearance.Layout.h0Color()
  234. typeLabel.stringValue = NSLocalizedString("Type", comment: "")
  235. typeLabel.textColor = KMAppearance.Layout.h0Color()
  236. dateLabel.stringValue = NSLocalizedString("Date", comment: "")
  237. dateLabel.textColor = KMAppearance.Layout.h0Color()
  238. iconLabel.stringValue = NSLocalizedString("Icon", comment: "")
  239. iconLabel.textColor = KMAppearance.Layout.h0Color()
  240. borderLabel.stringValue = NSLocalizedString("Line and Border Style", comment: "")
  241. borderLabel.textColor = KMAppearance.Layout.h0Color()
  242. fillColorLabel.stringValue = NSLocalizedString("Fill", comment: "")
  243. fillColorLabel.textColor = KMAppearance.Layout.h0Color()
  244. lineStyleCount = 0
  245. if annotationType == .highlight {
  246. activeAnnotationType = .highlight
  247. } else if annotationType == .strikeOut {
  248. activeAnnotationType = .strikeOut
  249. } else if annotationType == .underline {
  250. activeAnnotationType = .underline
  251. } else if annotationType == .ink || annotationType == .line || annotationType == .arrow {
  252. activeAnnotationType = .inkAndLine
  253. } else if annotationType == .anchored {
  254. activeAnnotationType = .text
  255. } else if annotationType == .circle || annotationType == .square {
  256. borderColorPickerView.isCallColorPanelAction = isannotationMode
  257. textColorPickerView.isCallColorPanelAction = isannotationMode
  258. activeAnnotationType = .squareAndCircle
  259. } else if annotationType == .freeText {
  260. if subType == .date {
  261. colorTitleLabel.stringValue = NSLocalizedString("Fill Color", comment: "")
  262. activeAnnotationType = .selfSignFreeText
  263. } else {
  264. activeAnnotationType = .freeText
  265. }
  266. fontViewCorloPV.isCallColorPanelAction = isannotationMode
  267. var alignmentType: KMFreeTextAnnotationAlignmentType = .left
  268. if annotationModel?.alignment() == .left {
  269. alignmentType = .left
  270. } else if annotationModel?.alignment() == .center {
  271. alignmentType = .center
  272. } else if annotationModel?.alignment() == .right {
  273. alignmentType = .right
  274. }
  275. alignmentTypeSelected(alignmentType)
  276. }
  277. textColorPickerView.isCallColorPanelAction = isannotationMode
  278. borderColorPickerView.isCallColorPanelAction = isannotationMode
  279. if annotationType == .freeText {
  280. fontViewCorloPV.isFreeText = true
  281. } else {
  282. fontViewCorloPV.isFreeText = false
  283. }
  284. if annotationType == .ink || annotationType == .line || annotationType == .arrow || annotationType == .square || annotationType == .circle {
  285. let lineType = annotationModel?.style()
  286. if lineType == .dashed {
  287. let lineType = annotationModel?.dashPattern()
  288. // if lineType.count == 0 {
  289. // let number = NSNumber(value: Float(4))
  290. // annotation.setDashPattern([number])
  291. //
  292. // let userDefaults = UserDefaults.standard
  293. // if annotationType == .ink {
  294. // userDefaults.set(annotationModel?.dashPattern(), forKey: SKInkNoteDashPatternKey)
  295. // } else if annotationType == .line {
  296. // userDefaults.set(annotationModel?.dashPattern(), forKey: SKLineNoteDashPatternKey)
  297. // } else if annotationType == .square {
  298. // userDefaults.set(annotationModel?.dashPattern(), forKey: SKSquareNoteDashPatternKey)
  299. // } else if annotationType == .circle {
  300. // userDefaults.set(annotationModel?.dashPattern(), forKey: SKCircleNoteDashPatternKey)
  301. // } else if annotationType == .freeText {
  302. // userDefaults.set(annotationModel?.dashPattern(), forKey: CFreeTextNoteDashPatternKey)
  303. // }
  304. // }
  305. }
  306. }
  307. opacityComboBox.type = .none
  308. opacityComboBox.comboxRect = opacityComboBox.bounds
  309. lineWidthComboBox.type = .none
  310. lineWidthComboBox.comboxRect = lineWidthComboBox.bounds
  311. widthComboBox.type = .none
  312. widthComboBox.comboxRect = widthComboBox.bounds
  313. fontPopUpButton.type = .arrowDown
  314. fontSizeComboBox.type = .none
  315. fontSizeComboBox.comboxRect = fontSizeComboBox.bounds
  316. fontStylePopUpButton.type = .arrowUpDown
  317. datePopUpButton.type = .arrowUpDown
  318. noteTextView.backgroundColor = KMAppearance.Layout.l1Color()
  319. let views: [NSView] = [fontPopUpButton, fontSizeComboBox, fontStylePopUpButton, lineWidthComboBox, opacityComboBox, widthComboBox, datePopUpButton, noteTextView]
  320. for view in views {
  321. view.wantsLayer = true
  322. view.layer?.borderWidth = 1.0
  323. view.layer?.cornerRadius = 1.0
  324. }
  325. refreshLineTypeUI()
  326. rightArrowStyleButton.isHidden = true
  327. rightArrowStyleBox.isHidden = true
  328. annotationFontReload()
  329. reloadData()
  330. updateViewColor()
  331. if ((annotationModel?.annotation) != nil) && annotationModel?.annotations.count == 1 {
  332. let annotation = annotationModel?.annotation
  333. let keys = ["contents", "markupText"]
  334. for key in keys {
  335. annotation?.addObserver(self, forKeyPath: key, options: [.new, .old], context: nil)
  336. }
  337. }
  338. // NotificationCenter.default.addObserver(self, selector: #selector(alignmentTypeNotification(_:)), name: "KMAnnotationAlignmentTypeNotification1", object: nil)
  339. // NotificationCenter.default.addObserver(self, selector: #selector(loadingUIAndLocalization(_:)), name: "KMPreferenceDidChangeNotificationName", object: nil)
  340. // NotificationCenter.default.addObserver(self, selector: #selector(annotationChangeNotification(_:)), name: CPDFListViewAnnotationsAttributeHasChangeNotification, object: nil)
  341. }
  342. override func viewDidLoad() {
  343. super.viewDidLoad()
  344. // Do view setup here.
  345. }
  346. override func viewDidAppear() {
  347. super.viewDidAppear()
  348. let showConvertDetails = KMPropertiesViewPopController.showChangeColorDetails()
  349. let fileURL = (self.view.window?.windowController?.document as? NSDocument)?.fileURL
  350. if showConvertDetails && (fileURL != nil) {
  351. KMPropertiesViewPopController.defaultManager.showChangeColorDetailsView(self.textColorPickerView.firstButton)
  352. }
  353. }
  354. func reloadData() {
  355. var annotationColor = annotationModel?.color()
  356. if annotationType == .signFalse ||
  357. annotationType == .signTure ||
  358. annotationType == .signDot ||
  359. annotationType == .signCircle ||
  360. annotationType == .signLine {
  361. annotationColor = annotationModel?.color()
  362. } else if annotationType == .square ||
  363. annotationType == .circle {
  364. annotationColor = annotationModel?.color()
  365. } else if annotationType == .freeText || annotationType == .signDate || annotationType == .signText {
  366. annotationColor = annotationModel?.interiorColor()
  367. } else {
  368. annotationColor = annotationModel?.color()
  369. }
  370. guard let color = annotationColor else { return }
  371. var opacity: CGFloat = 1.0
  372. color.usingColorSpaceName(.calibratedRGB)?.getRed(nil, green: nil, blue: nil, alpha: &opacity)
  373. if annotationType == .signFalse ||
  374. annotationType == .signTure ||
  375. annotationType == .signDot ||
  376. annotationType == .signCircle ||
  377. annotationType == .signLine {
  378. opacity = (annotationModel?.opacity())!
  379. } else if annotationType == .square ||
  380. annotationType == .circle {
  381. opacity = (annotationModel?.opacity())!
  382. } else if annotationType == .freeText || annotationType == .signDate || annotationType == .signText {
  383. opacity = (annotationModel?.interiorOpacity())!
  384. } else {
  385. opacity = (annotationModel?.opacity())!
  386. }
  387. opacitySlider.floatValue = Float(opacity)
  388. opacitySlider.toolTip = "\(Int(opacity * 100))%"
  389. opacityComboBox.stringValue = "\(Int(opacity * 100))%"
  390. if annotationModel?.annotations != nil {
  391. let contextString = annotation.string() ?? ""
  392. noteTextView.string = contextString
  393. noteTextView.textColor = NSColor.labelColor
  394. noteTextView.delegate = self
  395. }
  396. if annotationType == .freeText {
  397. imageBox.contentView = textImageBoxView
  398. textAnnotationImageView.image = annotationModel?.annotationImage
  399. } else if annotationType == .signText || annotationType == .signDate {
  400. imageBox.contentView = generalImageBoxView
  401. generalImageView.image = annotationModel?.annotationImage
  402. } else {
  403. imageBox.contentView = generalImageBoxView
  404. generalImageView.image = annotationModel?.annotationImage
  405. }
  406. if annotationType == .square || annotationType == .circle || annotationType == .line || annotationType == .arrow || annotationType == .ink {
  407. if annotationType == .ink {
  408. textColorPickerView.setColor(color)
  409. } else if annotationType == .square || annotationType == .circle {
  410. var red: CGFloat = 0.0, green: CGFloat = 0.0, blue: CGFloat = 0.0, opacity: CGFloat = 0.0
  411. let modelColor = annotationModel?.interiorColor() ?? .black
  412. modelColor.usingColorSpaceName(.calibratedRGB)?.getRed(&red, green: &green, blue: &blue, alpha: &opacity)
  413. let interiorColor = NSColor(red: red, green: green, blue: blue, alpha: (annotationModel?.interiorOpacity())!)
  414. textColorPickerView.setColor(interiorColor)
  415. textColorPickerView.isFillColor = true
  416. borderColorPickerView.setColor(color)
  417. } else if annotationType == .line || annotationType == .arrow {
  418. var red: CGFloat = 0.0, green: CGFloat = 0.0, blue: CGFloat = 0.0, opacity: CGFloat = 0.0
  419. let modelColor = annotationModel?.interiorColor() ?? .black
  420. modelColor.usingColorSpaceName(.calibratedRGB)?.getRed(&red, green: &green, blue: &blue, alpha: &opacity)
  421. let interiorColor = NSColor(red: red, green: green, blue: blue, alpha: (annotationModel?.interiorOpacity())!)
  422. textColorPickerView.setColor(interiorColor)
  423. textColorPickerView.isFillColor = true
  424. borderColorPickerView.setColor(color)
  425. }
  426. lineWidthSlider.floatValue = Float(annotationModel?.lineWidth() ?? 1.0)
  427. lineWidthSlider.toolTip = "\(annotationModel?.lineWidth() ?? 1.0) pt"
  428. lineWidthComboBox.stringValue = String(format: "%0.1f pt", (annotationModel?.lineWidth())!)
  429. } else if annotationType == .freeText || annotationType == .signText || annotationType == .signDate {
  430. if annotationType == .signText || annotationType == .signDate {
  431. if subType == .date {
  432. dateView.isHidden = false
  433. datePopUpButton.removeAllItems()
  434. let freeText = annotation as! KMSelfSignAnnotationFreeText
  435. // self.datePopUpButton.addItems(withTitles: KMSelfSignAnnotationFreeText.fetchAllDateString(includeTime: <#T##Bool#>))
  436. if freeText.dateFormatIndex >= 0, freeText.dateFormatIndex < datePopUpButton.numberOfItems {
  437. datePopUpButton.selectItem(at: freeText.dateFormatIndex)
  438. } else {
  439. datePopUpButton.selectItem(at: 0)
  440. }
  441. dateCheckButton.state = freeText.includeTime ? NSControl.StateValue.on : NSControl.StateValue.off
  442. textColorPickerView.setColor(annotation.color)
  443. }
  444. } else {
  445. lineWidthSlider.minValue = 0.0
  446. lineWidthSlider.floatValue = Float((annotationModel?.lineWidth())!)
  447. lineWidthSlider.toolTip = String(format: "%0.1f pt", (annotationModel?.lineWidth())!)
  448. lineWidthComboBox.stringValue = String(format: "%0.1f pt", (annotationModel?.lineWidth())!)
  449. var alignmentType: KMFreeTextAnnotationAlignmentType = .left
  450. if annotationModel?.alignment() == .left {
  451. alignmentType = .left
  452. } else if annotationModel?.alignment() == .center {
  453. alignmentType = .center
  454. } else if annotationModel?.alignment() == .right {
  455. alignmentType = .right
  456. }
  457. alignmentTypeSelected(alignmentType)
  458. annotationFontReload()
  459. fillColorPickerView.color = annotationModel?.color()
  460. }
  461. fontViewCorloPV.color = annotationModel?.fontColor()
  462. fontSizeComboBox.stringValue = String(format: "%0.1f pt", (annotationModel?.fontSize())!)
  463. } else if annotationType == .highlight || annotationType == .strikeOut || annotationType == .underline || annotationType == .anchored {
  464. textColorPickerView.setColor(color)
  465. }
  466. noteView.isHidden = isannotationMode
  467. if annotationType == .signText || annotationType == .signDate {
  468. if subType == .date {
  469. noteView.isHidden = true
  470. } else {
  471. noteView.isHidden = false
  472. }
  473. }
  474. if annotationModel?.annotations != nil {
  475. noteView.isHidden = annotationModel?.annotation==nil
  476. } else {
  477. if annotationType == .stamp ||
  478. annotationType == .ink ||
  479. annotationType == .square ||
  480. annotationType == .circle ||
  481. annotationType == .arrow ||
  482. annotationType == .line ||
  483. annotationType == .highlight ||
  484. annotationType == .strikeOut ||
  485. annotationType == .underline ||
  486. annotationType == .freeText {
  487. noteView.isHidden = true
  488. } else {
  489. noteView.isHidden = annotationModel?.annotation==nil
  490. }
  491. }
  492. }
  493. // MARK: Set & Get
  494. var annotations: [CPDFAnnotation] {
  495. get {
  496. return annotationModel?.annotations as! [CPDFAnnotation]
  497. }
  498. }
  499. var annotation: CPDFAnnotation {
  500. get {
  501. return (annotationModel?.annotation)!
  502. }
  503. }
  504. var annotationType: CAnnotationType {
  505. get {
  506. return (annotationModel?.annotationType as? CAnnotationType)!
  507. }
  508. }
  509. func updateannotationMode() {
  510. let defaults = UserDefaults.standard
  511. if annotationType == .freeText {
  512. // if ([annotation isKindOfClass:[SKNPDFAnnotationNote class]]) {
  513. // [sud setColor:self.annotation.color forKey:SKNPDFAnnotationColorKey];
  514. // [sud setInteger:self.annotation.iconType forKey:SKAnchoredNoteIconTypeKey];
  515. // }
  516. if annotation.isKind(of: CPDFFreeTextAnnotation.self) {
  517. defaults.safe_setColor(annotation.color, forKey: CFreeTextNoteColorKey)
  518. defaults.safe_setColor((annotation as! CPDFFreeTextAnnotation).fontColor, forKey: CFreeTextNoteFontColorKey)
  519. defaults.set((annotation as! CPDFFreeTextAnnotation).alignment.rawValue, forKey: CFreeTextNoteAlignmentKey)
  520. defaults.set((annotation as! CPDFFreeTextAnnotation).fontName(), forKey: CFreeTextNoteFontNameKey)
  521. defaults.set((annotation as! CPDFFreeTextAnnotation).fontSize(), forKey: CFreeTextNoteFontSizeKey)
  522. defaults.set(annotation.lineWidth(), forKey: CFreeTextNoteLineWidthKey)
  523. defaults.set(annotation.borderStyle().rawValue, forKey: CFreeTextNoteLineStyleKey)
  524. defaults.set(annotation.dashPattern(), forKey: CFreeTextNoteDashPatternKey)
  525. }
  526. } else if annotationType == .circle {
  527. defaults.safe_setColor(annotation.color, forKey: CCircleNoteColorKey)
  528. defaults.safe_setColor((annotation as! CPDFCircleAnnotation).interiorColor, forKey: CCircleNoteInteriorColorKey)
  529. defaults.set(annotation.lineWidth(), forKey: CCircleNoteLineWidthKey)
  530. defaults.set((annotation as! CPDFCircleAnnotation).borderStyle().rawValue, forKey: CCircleNoteLineStyleKey)
  531. defaults.set((annotation as! CPDFCircleAnnotation).dashPattern(), forKey: CCircleNoteDashPatternKey)
  532. } else if annotationType == .square {
  533. defaults.safe_setColor(annotation.color, forKey: CSquareNoteColorKey)
  534. defaults.safe_setColor((annotation as! CPDFSquareAnnotation).interiorColor, forKey: CSquareNoteInteriorColorKey)
  535. defaults.set(annotation.lineWidth(), forKey: CSquareNoteLineWidthKey)
  536. defaults.set((annotation as! CPDFSquareAnnotation).borderStyle().rawValue, forKey: CSquareNoteLineStyleKey)
  537. defaults.set((annotation as! CPDFSquareAnnotation).dashPattern(), forKey: CSquareNoteDashPatternKey)
  538. } else if annotationType == .highlight {
  539. defaults.safe_setColor(annotation.color, forKey: CHighlightNoteColorKey)
  540. } else if annotationType == .underline {
  541. defaults.safe_setColor(annotation.color, forKey: CUnderlineNoteColorKey)
  542. } else if annotationType == .strikeOut {
  543. defaults.safe_setColor(annotation.color, forKey: CStrikeOutNoteColorKey)
  544. } else if annotationType == .line || annotationType == .arrow {
  545. defaults.safe_setColor(annotation.color, forKey: CLineNoteColorKey)
  546. defaults.set(annotation.lineWidth(), forKey: CLineNoteLineWidthKey)
  547. defaults.set(annotation.borderStyle().rawValue, forKey: CLineNoteLineStyleKey)
  548. defaults.set(annotation.dashPattern(), forKey: CLineNoteDashPatternKey)
  549. defaults.safe_setColor((annotation as! CPDFLineAnnotation).interiorColor, forKey: CLineNoteInteriorColorKey)
  550. defaults.set((annotation as! CPDFLineAnnotation).startLineStyle.rawValue, forKey: CLineNoteStartLineStyleKey)
  551. defaults.set((annotation as! CPDFLineAnnotation).endLineStyle.rawValue, forKey: CLineNoteEndLineStyleKey)
  552. } else if annotationType == .ink {
  553. defaults.safe_setColor(annotation.color, forKey: CInkNoteColorKey)
  554. defaults.set(annotation.lineWidth(), forKey: CInkNoteLineWidthKey)
  555. defaults.set(annotation.borderStyle().rawValue, forKey: CInkNoteLineStyleKey)
  556. defaults.set(annotation.dashPattern(), forKey: CInkNoteDashPatternKey)
  557. } else if annotationType == .anchored {
  558. // [sud setColor:self.annotation.color forKey:SKNPDFAnnotationColorKey];
  559. // [sud setInteger:self.annotation.iconType forKey:SKAnchoredNoteIconTypeKey];
  560. }
  561. }
  562. var activeAnnotationType: KMActiveAnnotationType {
  563. set {
  564. _activeAnnotationType = newValue
  565. switch self.activeAnnotationType {
  566. case .highlight, .strikeOut, .underline:
  567. self.fontView.isHidden = true
  568. self.borderAndLineView.isHidden = true
  569. self.fillColorView.isHidden = true
  570. self.rotateView.isHidden = true
  571. self.typeView.isHidden = true
  572. self.dateView.isHidden = true
  573. self.iconView.isHidden = true
  574. self.createMarkupProperties()
  575. case .inkAndLine:
  576. self.fontView.isHidden = true
  577. self.fillColorView.isHidden = true
  578. self.rotateView.isHidden = true
  579. self.typeView.isHidden = true
  580. self.dateView.isHidden = true
  581. self.iconView.isHidden = true
  582. self.createInkAndLineProperties()
  583. case .text:
  584. self.fontView.isHidden = true
  585. self.borderAndLineView.isHidden = true
  586. self.fillColorView.isHidden = true
  587. self.rotateView.isHidden = true
  588. self.typeView.isHidden = true
  589. self.dateView.isHidden = true
  590. self.createTextProperties()
  591. case .squareAndCircle:
  592. self.fontView.isHidden = true
  593. self.rotateView.isHidden = true
  594. self.typeView.isHidden = true
  595. self.dateView.isHidden = true
  596. self.iconView.isHidden = true
  597. self.fillColorView.isHidden = true
  598. self.createSquareAndCircleProperties()
  599. case .freeText:
  600. self.colorView.isHidden = true
  601. self.rotateView.isHidden = true
  602. self.typeView.isHidden = true
  603. self.dateView.isHidden = true
  604. self.iconView.isHidden = true
  605. self.createFreeTextProperties()
  606. case .selfSignFreeText:
  607. self.rotateView.isHidden = true
  608. self.borderAndLineView.isHidden = true
  609. self.fillColorView.isHidden = true
  610. self.typeView.isHidden = true
  611. self.iconView.isHidden = true
  612. self.createSelfSignFreeTextProperties()
  613. default:
  614. break
  615. }
  616. }
  617. get {
  618. return _activeAnnotationType
  619. }
  620. }
  621. // MARK: private
  622. func updateViewColor() {
  623. if KMAppearance.isDarkMode() {
  624. let darkColor = NSColor(red: 57/255.0, green: 60/255.0, blue: 62/255.0, alpha: 1.0).cgColor
  625. let borderColor = NSColor(red: 86/255.0, green: 88/255.0, blue: 90/255.0, alpha: 1.0).cgColor
  626. setViewColor(fontPopUpButton, darkColor, borderColor)
  627. setViewColor(fontSizeComboBox, darkColor, borderColor)
  628. setViewColor(fontStylePopUpButton, darkColor, borderColor)
  629. setViewColor(lineWidthComboBox, darkColor, borderColor)
  630. setViewColor(opacityComboBox, darkColor, borderColor)
  631. setViewColor(datePopUpButton, darkColor, borderColor)
  632. setViewColor(widthComboBox, darkColor, borderColor)
  633. setViewColor(noteTextView, darkColor, borderColor)
  634. } else {
  635. let lightColor = NSColor.white.cgColor
  636. let borderColor = NSColor(red: 218/255.0, green: 219/255.0, blue: 222/255.0, alpha: 1.0).cgColor
  637. setViewColor(fontPopUpButton, lightColor, borderColor)
  638. setViewColor(fontSizeComboBox, lightColor, borderColor)
  639. setViewColor(fontStylePopUpButton, lightColor, borderColor)
  640. setViewColor(lineWidthComboBox, lightColor, borderColor)
  641. setViewColor(opacityComboBox, lightColor, borderColor)
  642. setViewColor(datePopUpButton, lightColor, borderColor)
  643. setViewColor(widthComboBox, lightColor, borderColor)
  644. setViewColor(noteTextView, lightColor, borderColor)
  645. }
  646. }
  647. func setViewColor(_ view: NSView, _ backgroundColor: CGColor, _ borderColor: CGColor) {
  648. view.layer?.backgroundColor = backgroundColor
  649. view.layer?.borderColor = borderColor
  650. }
  651. func refreshLineTypeUI() {
  652. lineStyleBox.borderColor = KMAppearance.Interactive.s0Color()
  653. dottedLineStyleBox.borderColor = KMAppearance.Interactive.s0Color()
  654. rightArrowStyleBox.borderColor = KMAppearance.Interactive.s0Color()
  655. lineStyleBox.fillColor = KMAppearance.Layout.l1Color()
  656. dottedLineStyleBox.fillColor = KMAppearance.Layout.l1Color()
  657. rightArrowStyleBox.fillColor = KMAppearance.Layout.l1Color()
  658. lineStyleBox.borderWidth = 1
  659. dottedLineStyleBox.borderWidth = 1
  660. rightArrowStyleBox.borderWidth = 1
  661. if lineStyleCount == 0 {
  662. lineStyleBox.fillColor = KMAppearance.Status.selColor()
  663. lineStyleBox.borderWidth = 0.0
  664. } else if lineStyleCount == 1 {
  665. dottedLineStyleBox.fillColor = KMAppearance.Status.selColor()
  666. dottedLineStyleBox.borderWidth = 0
  667. } else if lineStyleCount == 2 {
  668. rightArrowStyleBox.fillColor = KMAppearance.Status.selColor()
  669. rightArrowStyleBox.borderWidth = 0
  670. }
  671. }
  672. func hiddenSubviews() {
  673. fontViewTopConstant.constant = fontView.isHidden ? -(fontView.bounds.size.height) - 20 : 10
  674. ColorViewTopConstant.constant = colorView.isHidden ? -(colorView.bounds.size.height) : 10
  675. borderViewTopConstant.constant = borderAndLineView.isHidden ? -(borderAndLineView.bounds.size.height) : 20
  676. opacityViewTopConstant.constant = opacityView.isHidden ? -opacityView.bounds.size.height : 20
  677. rotateViewTopConstant.constant = rotateView.isHidden ? -(rotateView.bounds.size.height) : 20
  678. typeViewTopConstant.constant = typeView.isHidden ? -(typeView.bounds.size.height) : 20
  679. dateViewTopConstant.constant = dateView.isHidden ? -(dateView.bounds.size.height) : 20
  680. iconViewTopConstant.constant = iconView.isHidden ? -(iconView.bounds.size.height) : 20
  681. noteViewTopConstant.constant = noteView.isHidden ? -(noteView.bounds.size.height) : 20
  682. fillColorViewTopConstraint.constant = fillColorView.isHidden ? -fillColorView.bounds.size.height : 20
  683. fontViewColorPVConstraint.constant = fontViewCorloPV.isHidden ? -fontViewCorloPV.bounds.size.height : 10
  684. }
  685. func setActiveAnnotationType(_ activeAnnotationType: KMActiveAnnotationType) {
  686. self.activeAnnotationType = activeAnnotationType
  687. switch activeAnnotationType {
  688. case .highlight, .strikeOut, .underline:
  689. fontView.isHidden = true
  690. borderAndLineView.isHidden = true
  691. fillColorView.isHidden = true
  692. rotateView.isHidden = true
  693. typeView.isHidden = true
  694. dateView.isHidden = true
  695. iconView.isHidden = true
  696. createMarkupProperties()
  697. case .inkAndLine:
  698. fontView.isHidden = true
  699. fillColorView.isHidden = true
  700. rotateView.isHidden = true
  701. typeView.isHidden = true
  702. dateView.isHidden = true
  703. iconView.isHidden = true
  704. createInkAndLineProperties()
  705. case .text:
  706. fontView.isHidden = true
  707. borderAndLineView.isHidden = true
  708. fillColorView.isHidden = true
  709. rotateView.isHidden = true
  710. typeView.isHidden = true
  711. dateView.isHidden = true
  712. createTextProperties()
  713. case .squareAndCircle:
  714. fontView.isHidden = true
  715. rotateView.isHidden = true
  716. typeView.isHidden = true
  717. dateView.isHidden = true
  718. iconView.isHidden = true
  719. fillColorView.isHidden = true
  720. createSquareAndCircleProperties()
  721. case .freeText:
  722. colorView.isHidden = true
  723. rotateView.isHidden = true
  724. typeView.isHidden = true
  725. dateView.isHidden = true
  726. iconView.isHidden = true
  727. createFreeTextProperties()
  728. case .selfSignFreeText:
  729. rotateView.isHidden = true
  730. borderAndLineView.isHidden = true
  731. fillColorView.isHidden = true
  732. typeView.isHidden = true
  733. iconView.isHidden = true
  734. createSelfSignFreeTextProperties()
  735. default:
  736. break
  737. }
  738. }
  739. func createMarkupProperties() {
  740. let colorViewHeight = colorTitleLabel.frame.height + KMColorPickerViewHeight + 30
  741. colorView.frame = CGRect(x: 0, y: 0, width: view.frame.size.width, height: colorViewHeight)
  742. textColorBoxConstraint.constant = 10
  743. borderColorBoxConstraint.constant = 0
  744. textColorBox.isHidden = true
  745. lineWidthBox.isHidden = true
  746. imageBoxLayoutConstraint.constant = generalImageBoxView.frame.height
  747. hiddenSubviews()
  748. textColorPickerView.noContentString = true
  749. if activeAnnotationType == .highlight {
  750. textColorPickerView.annotationTypeString = NSLocalizedString("Highlight", comment: "Description for export")
  751. } else if activeAnnotationType == .strikeOut {
  752. textColorPickerView.annotationTypeString = NSLocalizedString("Strikethrough", comment: "Description for export")
  753. } else if activeAnnotationType == .underline {
  754. textColorPickerView.annotationTypeString = NSLocalizedString("Underline", comment: "Description for export")
  755. }
  756. textColorPickerView.annotationType = (activeAnnotationType == .highlight) ? .markupHighlightColors : .markupOtherColors
  757. }
  758. func openFreeTextStylesViewController() {
  759. // let vc = KMFreeTextStylesViewController()
  760. // vc.annotations = self.annotations
  761. // vc.view.frame = CGRect(x: 0, y: 0, width: 280, height: CGRectGetHeight(self.view.window?.frame ?? CGRect.zero) - 300)
  762. //
  763. // let createFilePopover = NSPopover()
  764. // createFilePopover.contentViewController = vc
  765. // createFilePopover.animates = true
  766. // createFilePopover.behavior = .transient
  767. // createFilePopover.show(relativeTo: CGRect(x: _textImageBox.bounds.origin.x, y: 10, width: _textImageBox.bounds.size.width, height: _textImageBox.bounds.size.height), of: _textImageBox, preferredEdge: .minY)
  768. //
  769. // // Assuming _textImageBox is an NSView instance
  770. // createFilePopover.show(relativeTo: _textImageBox.bounds, of: _textImageBox, preferredEdge: .minY)
  771. // Release is not needed in Swift due to automatic reference counting (ARC)
  772. }
  773. func changeStoredFontInfo(_ sender: Any) {
  774. // if let senderFont = sender as? NSFont {
  775. // for tAnnotation in self.annotations {
  776. // tAnnotation.removeAllAppearanceStreams()
  777. // let font = senderFont.convert(tAnnotation.font)
  778. // if let validFont = font {
  779. // tAnnotation.font = validFont
  780. // }
  781. // }
  782. // }
  783. }
  784. private func updateAnnotation() {
  785. if annotationModel?.annotation != nil {
  786. if annotation is CPDFFreeTextAnnotation {
  787. let textNote = (annotation as! CPDFFreeTextAnnotation)
  788. if let isEdit = pdfView?.isEdit(withCurrentFreeText: textNote), isEdit {
  789. pdfView?.commitEditAnnotationFreeText(textNote)
  790. }
  791. pdfView?.setNeedsDisplay(pdfView?.activeAnnotation)
  792. }
  793. for tAnnotation in annotations {
  794. if tAnnotation is CPDFStampAnnotation {
  795. (tAnnotation as? KMSelfSignAnnotation)?.updateAppearanceStream()
  796. }
  797. if tAnnotation is CPDFMarkupAnnotation {
  798. pdfView?.setNeedsDisplayFor(tAnnotation.page)
  799. } else {
  800. pdfView?.setNeedsDisplayAnnotationViewFor(tAnnotation.page)
  801. }
  802. }
  803. }
  804. if annotationType == .freeText {
  805. textAnnotationImageView.image = annotationModel?.annotationImage
  806. } else {
  807. generalImageView.image = annotationModel?.annotationImage
  808. }
  809. }
  810. override func observeValue(forKeyPath keyPath: String?, of object: Any?, change: [NSKeyValueChangeKey : Any]?, context: UnsafeMutableRawPointer?) {
  811. if self.annotation.isEqual(to: object) == false {
  812. return
  813. }
  814. let newValue = change?[NSKeyValueChangeKey.newKey] as? NSObject
  815. let oldValue = change?[NSKeyValueChangeKey.oldKey]
  816. if let data = newValue?.isEqual(to: oldValue), data {
  817. return
  818. }
  819. if keyPath == "string" {
  820. if newValue == nil || newValue is NSNull {
  821. return
  822. }
  823. //处理编辑时光标后移
  824. if self.isTextEdit == false {
  825. self.noteTextView.string = newValue as? String ?? ""
  826. }
  827. self.isTextEdit = false
  828. } else {
  829. self.reloadData()
  830. if self.isannotationMode {
  831. self.updateannotationMode()
  832. }
  833. }
  834. }
  835. // MARK: Line Note
  836. func createInkAndLineProperties() {
  837. if annotationType == .ink {
  838. let colorViewHeight = CGRectGetHeight(colorTitleLabel.frame) + KMColorPickerViewHeight + 30
  839. colorView.frame = CGRect(x: 0, y: 0, width: self.view.frame.size.width, height: colorViewHeight)
  840. textColorBoxConstraint.constant = 10
  841. borderColorBoxConstraint.constant = 0
  842. textColorBox.isHidden = true
  843. lineWidthBox.isHidden = true
  844. imageBoxLayoutConstraint.constant = CGRectGetHeight(generalImageBoxView.frame)
  845. hiddenSubviews()
  846. textColorPickerView.noContentString = true
  847. textColorPickerView.annotationTypeString = NSLocalizedString("Line Color", comment: "")
  848. textColorPickerView.annotationType = .inkColors
  849. } else if annotationType == .line || annotationType == .arrow {
  850. let colorViewHeight = CGRectGetHeight(colorTitleLabel.frame) + KMColorPickerViewHeight * 2 + 40
  851. colorView.frame = CGRect(x: 0, y: 0, width: self.view.frame.size.width, height: colorViewHeight)
  852. textColorBoxConstraint.constant = KMColorPickerViewHeight + 20
  853. borderColorBoxConstraint.constant = 0
  854. lineWidthBox.isHidden = true
  855. textColorPickerViewConstant.constant = 57
  856. imageBoxLayoutConstraint.constant = CGRectGetHeight(generalImageBoxView.frame)
  857. hiddenSubviews()
  858. borderColorPickerView.annotationTypeString = NSLocalizedString("Line Color", comment: "")
  859. textColorPickerView.annotationTypeString = NSLocalizedString("Fill Color", comment: "")
  860. borderColorPickerView.annotationType = .lineColors
  861. textColorPickerView.annotationType = .lineFillColors
  862. borderColorPickerView.annotationTypeString = NSLocalizedString("Line Color", comment: "")
  863. borderColorPickerView.annotationType = .lineColors
  864. }
  865. lineTypeLabel.stringValue = NSLocalizedString("Line and Border Style", comment: "")
  866. lineTypeLabel.textColor = KMAppearance.Layout.h0Color()
  867. lineWidthSlider.floatValue = Float((annotationModel?.lineWidth())!)
  868. lineWidthComboBox.stringValue = String(format: "%0.1f pt", (annotationModel?.lineWidth())!)
  869. lineStyleButton.wantsLayer = true
  870. dottedLineStyleButton.wantsLayer = true
  871. rightArrowStyleButton.wantsLayer = true
  872. lineStyleButton.image = borderStyleSolid(false)
  873. dottedLineStyleButton.image = borderStyleDashed(false)
  874. rightArrowStyleButton.image = lineStyleRightArrow(false)
  875. if annotationModel?.style() == .solid {
  876. lineStyleCount = 0
  877. lineStyleButton.image = borderStyleSolid(true)
  878. lineStyleBox.borderWidth = 0
  879. lineStyleBox.fillColor = KMAppearance.Status.selColor()
  880. } else if annotationModel?.style() == .dashed {
  881. lineStyleCount = 1
  882. dottedLineStyleButton.image = borderStyleDashed(true)
  883. dottedLineStyleBox.borderWidth = 0
  884. dottedLineStyleBox.fillColor = KMAppearance.Status.selColor()
  885. }
  886. if (annotationType == .line || annotationType == .arrow) && annotationModel?.endLineStyle() == .closedArrow {
  887. lineStyleCount = 2
  888. rightArrowStyleButton.image = lineStyleRightArrow(true)
  889. rightArrowStyleBox.borderWidth = 0
  890. rightArrowStyleBox.fillColor = KMAppearance.Status.selColor()
  891. }
  892. }
  893. func createTextProperties() {
  894. makeNoteIcons()
  895. let colorViewHeight = colorTitleLabel.frame.height + KMColorPickerViewHeight + 30
  896. colorView.frame = CGRect(x: 0, y: 0, width: self.view.frame.size.width, height: colorViewHeight)
  897. textColorBoxConstraint.constant = 10
  898. borderColorBoxConstraint.constant = 0
  899. textColorBox.isHidden = true
  900. lineWidthBox.isHidden = true
  901. imageBoxLayoutConstraint.constant = generalImageBoxView.frame.height
  902. hiddenSubviews()
  903. textColorPickerView.annotationTypeString = NSLocalizedString("Anchored Note", comment: "Description for export")
  904. commentButton.title = NSLocalizedString("Comment", comment: "")
  905. commentButton.toolTip = NSLocalizedString("Comment", comment: "")
  906. commentButton.setTitleColor(KMAppearance.Layout.h0Color())
  907. paragraphButton.title = NSLocalizedString("Paragraph", comment: "")
  908. paragraphButton.toolTip = NSLocalizedString("Paragraph", comment: "")
  909. paragraphButton.setTitleColor(KMAppearance.Layout.h0Color())
  910. insertButton.title = NSLocalizedString("Insert", comment: "")
  911. insertButton.toolTip = NSLocalizedString("Insert", comment: "")
  912. insertButton.setTitleColor(KMAppearance.Layout.h0Color())
  913. addParagraphButton.title = NSLocalizedString("New Paragraph", comment: "")
  914. addParagraphButton.toolTip = NSLocalizedString("New Paragraph", comment: "")
  915. addParagraphButton.setTitleColor(KMAppearance.Layout.h0Color())
  916. keyButton.title = NSLocalizedString("Key", comment: "")
  917. keyButton.toolTip = NSLocalizedString("Key", comment: "")
  918. keyButton.setTitleColor(KMAppearance.Layout.h0Color())
  919. noteButton.title = NSLocalizedString("Note", comment: "")
  920. noteButton.toolTip = NSLocalizedString("Note", comment: "")
  921. noteButton.setTitleColor(KMAppearance.Layout.h0Color())
  922. helpButton.title = NSLocalizedString("Help", comment: "")
  923. helpButton.toolTip = NSLocalizedString("Help", comment: "")
  924. helpButton.setTitleColor(KMAppearance.Layout.h0Color())
  925. let languages = NSLocale.preferredLanguages
  926. var currentLocaleLanguageCode = "en"
  927. if let firstLanguage = languages.first {
  928. currentLocaleLanguageCode = firstLanguage
  929. if currentLocaleLanguageCode.hasPrefix("zh") {
  930. currentLocaleLanguageCode = "zh"
  931. }
  932. }
  933. let buttonArray: [NSButton] = [commentButton, keyButton, noteButton, helpButton, addParagraphButton, paragraphButton, insertButton]
  934. for button in buttonArray {
  935. button.wantsLayer = true
  936. button.layer?.cornerRadius = 6.0
  937. if currentLocaleLanguageCode == "zh" {
  938. iconButtonHeightConstant.constant = 56.0
  939. button.imagePosition = .imageAbove
  940. } else {
  941. iconButtonHeightConstant.constant = 50.0
  942. button.imagePosition = .imageOnly
  943. }
  944. }
  945. iconButtonArray = [commentBox, keyBox, noteBox, helpBox, addParagraphBox, paragraphBox, insertBox]
  946. // let iconType = annotation.iconType
  947. // clickAnnotationTextIconButtonAction(iconType: iconType, boxArr: iconButtonArray)
  948. textColorPickerView.annotationType = .anchoredNoteColors
  949. textColorPickerView.isCallColorPanelAction = true
  950. }
  951. func clickAnnotationTextIconButtonAction(iconType: UInt, boxArr buttonArr: [NSBox]) {
  952. for i in 0..<buttonArr.count {
  953. if iconType == 0 {
  954. commentButton.layer?.backgroundColor = KMAppearance.Status.selColor().cgColor
  955. commentButton.image = NSImage(named: KMImageNameUXIconPropertybarNoteAnnotationSel)
  956. } else {
  957. commentButton.layer?.backgroundColor = NSColor.clear.cgColor
  958. commentButton.image = NSImage(named: KMImageNameUXIconPropertybarNoteAnnotationNor)
  959. }
  960. if iconType == 1 {
  961. keyButton.layer?.backgroundColor = KMAppearance.Status.selColor().cgColor
  962. keyButton.image = NSImage(named: KMImageNameUXIconPropertybarNoteKeywordSel)
  963. } else {
  964. keyButton.layer?.backgroundColor = NSColor.clear.cgColor
  965. keyButton.image = NSImage(named: KMImageNameUXIconPropertybarNoteKeywordNor)
  966. }
  967. if iconType == 2 {
  968. noteButton.layer?.backgroundColor = KMAppearance.Status.selColor().cgColor
  969. noteButton.image = NSImage(named: KMImageNameUXIconPropertybarNoteNotesSel)
  970. } else {
  971. noteButton.layer?.backgroundColor = NSColor.clear.cgColor
  972. noteButton.image = NSImage(named: KMImageNameUXIconPropertybarNoteNotesNor)
  973. }
  974. if iconType == 3 {
  975. helpButton.layer?.backgroundColor = KMAppearance.Status.selColor().cgColor
  976. helpButton.image = NSImage(named: KMImageNameUXIconPropertybarNoteHelpSel)
  977. } else {
  978. helpButton.layer?.backgroundColor = NSColor.clear.cgColor
  979. helpButton.image = NSImage(named: KMImageNameUXIconPropertybarNoteHelpNor)
  980. }
  981. if iconType == 4 {
  982. addParagraphButton.layer?.backgroundColor = KMAppearance.Status.selColor().cgColor
  983. addParagraphButton.image = NSImage(named: KMImageNameUXIconPropertybarNoteNewparagraphSel)
  984. } else {
  985. addParagraphButton.layer?.backgroundColor = NSColor.clear.cgColor
  986. addParagraphButton.image = NSImage(named: KMImageNameUXIconPropertybarNoteNewparagraphNor)
  987. }
  988. if iconType == 5 {
  989. paragraphButton.layer?.backgroundColor = KMAppearance.Status.selColor().cgColor
  990. paragraphButton.image = NSImage(named: KMImageNameUXIconPropertybarNoteParagraphSel)
  991. } else {
  992. paragraphButton.layer?.backgroundColor = NSColor.clear.cgColor
  993. paragraphButton.image = NSImage(named: KMImageNameUXIconPropertybarNoteParagraphNor)
  994. }
  995. if iconType == 6 {
  996. insertButton.layer?.backgroundColor = KMAppearance.Status.selColor().cgColor
  997. insertButton.image = NSImage(named: KMImageNameUXIconPropertybarNoteInsertSel)
  998. } else {
  999. insertButton.layer?.backgroundColor = NSColor.clear.cgColor
  1000. insertButton.image = NSImage(named: KMImageNameUXIconPropertybarNoteInsertNor)
  1001. }
  1002. }
  1003. }
  1004. func borderStyleSolid(_ isSelect: Bool) -> NSImage {
  1005. let size = NSSize(width: 49.0, height: 12.0)
  1006. let image = NSImage(size: size, flipped: false, drawingHandler: { rect in
  1007. let path = NSBezierPath(rect: NSRect(x: 15.0, y: 5.0, width: 20.0, height: 1.0))
  1008. path.lineWidth = 2.0
  1009. isSelect ? KMAppearance.Layout.m_1Color().setStroke() : KMAppearance.Layout.m_1Color().setStroke()
  1010. path.stroke()
  1011. return true
  1012. })
  1013. return image
  1014. }
  1015. func borderStyleDashed(_ isSelect: Bool) -> NSImage {
  1016. let size = NSSize(width: 49.0, height: 12.0)
  1017. let image = NSImage(size: size, flipped: false, drawingHandler: { rect in
  1018. let path = NSBezierPath()
  1019. path.move(to: NSPoint(x: 15.0, y: 5.0))
  1020. path.line(to: NSPoint(x: 19.0, y: 5.0))
  1021. path.move(to: NSPoint(x: 23.0, y: 5.0))
  1022. path.line(to: NSPoint(x: 27.0, y: 5.0))
  1023. path.move(to: NSPoint(x: 31.0, y: 5.0))
  1024. path.line(to: NSPoint(x: 35.0, y: 5.0))
  1025. path.lineWidth = 2.0
  1026. isSelect ? KMAppearance.Layout.m_1Color().setStroke() : KMAppearance.Layout.m_1Color().setStroke()
  1027. path.stroke()
  1028. return true
  1029. })
  1030. return image
  1031. }
  1032. func lineStyleRightArrow(_ isSelect: Bool) -> NSImage {
  1033. let size = NSSize(width: 49.0, height: 12.0)
  1034. let image = NSImage(size: size, flipped: false, drawingHandler: { rect in
  1035. let path = NSBezierPath()
  1036. path.move(to: NSPoint(x: 6.0, y: 6.0))
  1037. path.line(to: NSPoint(x: 43.0, y: 6.0))
  1038. path.move(to: NSPoint(x: 32.0, y: 3.0))
  1039. path.line(to: NSPoint(x: 43.0, y: 6.0))
  1040. path.line(to: NSPoint(x: 32.0, y: 9.0))
  1041. path.close()
  1042. path.lineWidth = 2.0
  1043. if isSelect {
  1044. KMAppearance.Layout.l0Color().setStroke()
  1045. } else {
  1046. KMAppearance.Interactive.s0Color().setStroke()
  1047. }
  1048. path.stroke()
  1049. return true
  1050. })
  1051. return image
  1052. }
  1053. // MARK: SKSquareNote、SKCircleNote、SKArrowNote Properties
  1054. func createSquareAndCircleProperties() {
  1055. let colorViewHeight = CGRectGetHeight(colorTitleLabel.frame) + KMColorPickerViewHeight * 2 + 40
  1056. colorView.frame = CGRect(x: 0, y: 0, width: view.frame.size.width, height: colorViewHeight)
  1057. textColorBoxConstraint.constant = KMColorPickerViewHeight + 20
  1058. borderColorBoxConstraint.constant = 0
  1059. lineWidthBox.isHidden = true
  1060. textColorPickerViewConstant.constant = 57
  1061. imageBoxLayoutConstraint.constant = CGRectGetHeight(generalImageBoxView.frame)
  1062. hiddenSubviews()
  1063. lineTypeLabel.stringValue = NSLocalizedString("Line and Border Style", comment: "")
  1064. lineTypeLabel.textColor = KMAppearance.Layout.h0Color()
  1065. lineWidthSlider.floatValue = Float((annotationModel?.lineWidth())!)
  1066. lineWidthComboBox.stringValue = String(format: "%0.1f pt", (annotationModel?.lineWidth())!)
  1067. textColorPickerView.annotationTypeString = NSLocalizedString("Fill Color", comment: "")
  1068. borderColorPickerView.annotationTypeString = NSLocalizedString("Line Color", comment: "")
  1069. textColorPickerView.annotationType = .lineFillColors
  1070. borderColorPickerView.annotationType = .lineColors
  1071. lineStyleButton.wantsLayer = true
  1072. dottedLineStyleButton.wantsLayer = true
  1073. rightArrowStyleButton.wantsLayer = true
  1074. lineStyleButton.image = borderStyleSolid(false)
  1075. dottedLineStyleButton.image = borderStyleDashed(false)
  1076. if annotationModel?.annotation != nil {
  1077. if annotationModel?.annotation.borderStyle() == .solid {
  1078. lineStyleCount = 0
  1079. lineStyleButton.image = borderStyleSolid(true)
  1080. lineStyleBox.borderWidth = 0
  1081. lineStyleBox.fillColor = KMAppearance.Status.selColor()
  1082. } else if annotationModel?.annotation.borderStyle() == .dashed {
  1083. lineStyleCount = 1
  1084. dottedLineStyleButton.image = borderStyleDashed(true)
  1085. dottedLineStyleBox.borderWidth = 1
  1086. dottedLineStyleBox.fillColor = KMAppearance.Status.selColor()
  1087. }
  1088. } else {
  1089. if annotationModel?.style() == .solid {
  1090. lineStyleCount = 0
  1091. lineStyleButton.image = borderStyleSolid(true)
  1092. lineStyleBox.borderWidth = 0
  1093. lineStyleBox.fillColor = KMAppearance.Status.selColor()
  1094. } else if annotationModel?.style() == .dashed {
  1095. lineStyleCount = 1
  1096. dottedLineStyleButton.image = borderStyleDashed(true)
  1097. dottedLineStyleBox.borderWidth = 1
  1098. dottedLineStyleBox.fillColor = KMAppearance.Status.selColor()
  1099. }
  1100. }
  1101. }
  1102. // MARK: SKFreeTextNote、PDFAnnotationFreeText Properties
  1103. func createFreeTextProperties() {
  1104. imageBox.fillColor = KMAppearance.Layout.w0Color()
  1105. textColorBox.isHidden = true
  1106. lineWidthBox.isHidden = true
  1107. imageBoxLayoutConstraint.constant = CGRectGetHeight(textImageBoxView.frame)
  1108. textImageBox.downCallback = { [weak self] downEntered, mouseBox, event in
  1109. if downEntered {
  1110. self?.openFreeTextStylesViewController()
  1111. }
  1112. }
  1113. textImageUpDateButton.wantsLayer = true
  1114. textImageBoxButton.image = NSImage(named: KMImageNameUXIconBtnTriDownNor)
  1115. textImageBoxButton.isEnabled = true
  1116. textImageUpDateButton.title = NSLocalizedString("Click to refresh", comment: "")
  1117. textImageUpDateButton.setTitleColor(KMAppearance.Layout.w0Color())
  1118. textImageUpDateButton.layer?.cornerRadius = 1.0
  1119. textImageUpDateButton.layer?.backgroundColor = KMAppearance.Interactive.m0Color().cgColor
  1120. textImageUpDateButton.isHidden = true
  1121. hiddenSubviews()
  1122. fontViewCorloPV.noContentString = true
  1123. fontViewCorloPV.annotationTypeString = NSLocalizedString("Color", comment: "")
  1124. fillColorPickerView.noContentString = true
  1125. fillColorPickerView.annotationTypeString = NSLocalizedString("Color", comment: "")
  1126. lineTypeLabel.stringValue = NSLocalizedString("Line and Border Style", comment: "")
  1127. lineTypeLabel.textColor = KMAppearance.Layout.h0Color()
  1128. leftAlignButton.toolTip = NSLocalizedString("Left Alignment", comment: "")
  1129. centerAlignButton.toolTip = NSLocalizedString("Center", comment: "")
  1130. rightAlignButton.toolTip = NSLocalizedString("Right Alignment", comment: "")
  1131. lineWidthSlider.floatValue = Float((annotationModel?.lineWidth())!)
  1132. lineWidthComboBox.stringValue = String(format: "%0.1f pt", Float((annotationModel?.lineWidth())!))
  1133. leftRotateBox.borderColor = KMAppearance.Interactive.s0Color()
  1134. leftRotateBox.borderWidth = 0.5
  1135. leftRotateButton.image = NSImage(named: KMImageNameUXIconPropertybarRotateCounterclockwiseNor)
  1136. leftRotateBox.downCallback = { [weak self] downEntered, mouseBox, event in
  1137. if downEntered {
  1138. self?.leftRotateBox.fillColor = KMAppearance.Status.selColor()
  1139. self?.leftRotateButton.image = NSImage(named: KMImageNameUXIconPropertybarRotateCounterclockwisePre)
  1140. } else {
  1141. self?.leftRotateBox.fillColor = KMAppearance.Layout.w0Color()
  1142. self?.leftRotateButton.image = NSImage(named: KMImageNameUXIconPropertybarRotateCounterclockwiseNor)
  1143. }
  1144. }
  1145. rightRotateBox.borderColor = KMAppearance.Interactive.s0Color()
  1146. rightRotateBox.borderWidth = 0.5
  1147. rightRotateButton.image = NSImage(named: KMImageNameUXIconPropertybarRotateClockwiseNor)
  1148. rightRotateBox.downCallback = { [weak self] downEntered, mouseBox, event in
  1149. if downEntered {
  1150. self?.rightRotateBox.fillColor = KMAppearance.Status.selColor()
  1151. self?.rightRotateButton.image = NSImage(named: KMImageNameUXIconPropertybarRotateClockwisePre)
  1152. } else {
  1153. self?.rightRotateBox.fillColor = KMAppearance.Layout.w0Color()
  1154. self?.rightRotateButton.image = NSImage(named: KMImageNameUXIconPropertybarRotateClockwiseNor)
  1155. }
  1156. }
  1157. lineStyleButton.wantsLayer = true
  1158. dottedLineStyleButton.wantsLayer = true
  1159. rightArrowStyleButton.wantsLayer = true
  1160. lineStyleButton.image = borderStyleSolid(false)
  1161. dottedLineStyleButton.image = borderStyleDashed(false)
  1162. if annotationModel?.style() == .solid {
  1163. lineStyleCount = 0
  1164. lineStyleButton.image = borderStyleSolid(true)
  1165. lineStyleBox.borderWidth = 0
  1166. lineStyleBox.fillColor = KMAppearance.Status.selColor()
  1167. lineStyleBox.borderWidth = 0
  1168. } else if annotationModel?.style() == .dashed {
  1169. lineStyleCount = 1
  1170. dottedLineStyleButton.image = borderStyleDashed(true)
  1171. dottedLineStyleBox.fillColor = KMAppearance.Status.selColor()
  1172. dottedLineStyleBox.borderWidth = 0
  1173. } else {
  1174. lineStyleCount = 0
  1175. lineStyleButton.image = borderStyleSolid(true)
  1176. lineStyleBox.borderWidth = 0
  1177. lineStyleBox.fillColor = KMAppearance.Status.selColor()
  1178. lineStyleBox.borderWidth = 0
  1179. }
  1180. fontViewCorloPV.annotationType = .freeTextColors
  1181. fillColorPickerView.annotationType = .freeTextFillColors
  1182. }
  1183. func alignmentTypeSelected(_ type: KMFreeTextAnnotationAlignmentType) {
  1184. selectedAlignmentButtonLayer?.removeFromSuperlayer()
  1185. selectedAlignmentButtonLayer = CALayer()
  1186. selectedAlignmentButtonLayer?.cornerRadius = 6.0
  1187. leftAlignButton.wantsLayer = true
  1188. centerAlignButton.wantsLayer = true
  1189. rightAlignButton.wantsLayer = true
  1190. selectedAlignmentButtonLayer?.bounds = leftAlignButton.layer?.bounds ?? CGRect.zero
  1191. selectedAlignmentButtonLayer?.anchorPoint = CGPoint(x: 0, y: 0)
  1192. var color = NSColor(red: 71/255.0, green: 126/255.0, blue: 222/255.0, alpha: 0.16)
  1193. if #available(macOS 10.14, *) {
  1194. let appearanceName = NSApp.effectiveAppearance.bestMatch(from: [.aqua, .darkAqua])
  1195. if appearanceName == .darkAqua {
  1196. color = NSColor(red: 34/255.0, green: 122/255.0, blue: 255/255.0, alpha: 0.3)
  1197. }
  1198. }
  1199. selectedAlignmentButtonLayer?.backgroundColor = color.cgColor
  1200. leftAlignButton.image = NSImage(named: KMImageNameUXIconPropertybarTextalignLeftNor)
  1201. centerAlignButton.image = NSImage(named: KMImageNameUXIconPropertybarTextalignCenterNor)
  1202. rightAlignButton.image = NSImage(named: KMImageNameUXIconPropertybarTextalignRightNor)
  1203. if type == .left {
  1204. leftAlignButton.image = NSImage(named: KMImageNameUXIconPropertybarTextalignLeftSel)
  1205. } else if type == .center {
  1206. centerAlignButton.image = NSImage(named: KMImageNameUXIconPropertybarTextalignCenterSel)
  1207. } else if type == .right {
  1208. rightAlignButton.image = NSImage(named: KMImageNameUXIconPropertybarTextalignRightSel)
  1209. }
  1210. DispatchQueue.main.asyncAfter(deadline: .now() + 0.01) { [weak self] in
  1211. guard let self = self else { return }
  1212. if type == .left {
  1213. self.leftAlignButton.layer?.insertSublayer(self.selectedAlignmentButtonLayer!, at: 0)
  1214. } else if type == .center {
  1215. self.centerAlignButton.layer?.insertSublayer(self.selectedAlignmentButtonLayer!, at: 0)
  1216. } else if type == .right {
  1217. self.rightAlignButton.layer?.insertSublayer(self.selectedAlignmentButtonLayer!, at: 0)
  1218. }
  1219. }
  1220. }
  1221. // MARK: SKFreeTextNote、KMSelfSignAnnotationFreeText Properties
  1222. func createSelfSignFreeTextProperties() {
  1223. let colorViewHeight = CGRectGetHeight(colorTitleLabel.frame) + KMColorPickerViewHeight + 30
  1224. colorView.frame = CGRect(x: 0, y: 0, width: view.frame.size.width, height: colorViewHeight)
  1225. textColorBoxConstraint.constant = 10
  1226. borderColorBoxConstraint.constant = 0
  1227. textColorBox.isHidden = true
  1228. lineWidthBox.isHidden = true
  1229. imageBoxLayoutConstraint.constant = CGRectGetHeight(generalImageBoxView.frame)
  1230. hiddenSubviews()
  1231. fontViewTopConstant.constant = colorView.frame.size.height + opacityView.frame.size.height - 10 + 10
  1232. ColorViewTopConstant.constant = -(fontView.frame.size.height + fontViewTopConstant.constant)
  1233. dateViewTopConstant.constant = fontView.frame.size.height + 30
  1234. fontViewCorloPV.noContentString = true
  1235. fontViewCorloPV.annotationTypeString = ""
  1236. textColorPickerView.annotationTypeString = NSLocalizedString("Background", comment: "")
  1237. dateCheckButton.title = NSLocalizedString("Time", comment: "")
  1238. if let attrTitle = dateCheckButton.attributedTitle.mutableCopy() as? NSMutableAttributedString {
  1239. let len = attrTitle.length
  1240. let range = NSRange(location: 0, length: len)
  1241. attrTitle.addAttribute(.foregroundColor, value: KMAppearance.Layout.h1Color(), range: range)
  1242. attrTitle.fixAttributes(in: range)
  1243. dateCheckButton.attributedTitle = attrTitle
  1244. }
  1245. if activeAnnotationType == .selfSignFreeText { // 添加日期 字体默认颜色不要透明色
  1246. textColorPickerView.annotationType = .freeTextFillColors
  1247. fontViewCorloPV.annotationType = .freeTextColors
  1248. } else {
  1249. textColorPickerView.annotationType = .freeTextColors
  1250. fontViewCorloPV.annotationType = .freeTextFillColors
  1251. }
  1252. }
  1253. func setFontStyle(fontName: String, currentStyle style: String?) -> UInt {
  1254. var selectIndex: UInt = 0
  1255. let menu = NSMenu()
  1256. if let fontFamily = NSFontManager.shared.availableMembers(ofFontFamily: fontName) {
  1257. for i in 0..<fontFamily.count {
  1258. let array = fontFamily[i]
  1259. if let styleName = array[1] as? String {
  1260. if style == styleName {
  1261. selectIndex = UInt(i)
  1262. }
  1263. let attributeFontDescriptor = NSFontDescriptor(fontAttributes: [NSFontDescriptor.AttributeName.family: fontName, NSFontDescriptor.AttributeName.face: styleName])
  1264. let font = NSFont(descriptor: attributeFontDescriptor, size: 12.0)
  1265. let attrited = [NSAttributedString.Key.font: font]
  1266. let string = NSAttributedString(string: styleName, attributes: attrited)
  1267. let item = NSMenuItem()
  1268. item.attributedTitle = string
  1269. menu.addItem(item)
  1270. }
  1271. }
  1272. }
  1273. if style == nil {
  1274. selectIndex = 0
  1275. }
  1276. fontStylePopUpButton.menu = menu
  1277. return selectIndex
  1278. }
  1279. // MARK: UI Action
  1280. @IBAction func colorPickerViewAction(_ sender: Any) {
  1281. var fillColor: NSColor = NSColor.clear
  1282. var red: CGFloat = 0.0, green: CGFloat = 0.0, blue: CGFloat = 0.0, opacity: CGFloat = 0.0
  1283. if let textColor = textColorPickerView.color {
  1284. textColor.usingColorSpaceName(.calibratedRGB)?.getRed(&red, green: &green, blue: &blue, alpha: &opacity)
  1285. if fabs(opacity - 0) < 0.001 {
  1286. if annotationType == .square || annotationType == .circle || annotationType == .line || annotationType == .arrow {
  1287. annotationModel?.setInteriorOpacity(0)
  1288. annotationModel?.setInteriorColor(.black)
  1289. } else if annotationType == .freeText || annotationType == .signText || annotationType == .signDate {
  1290. annotationModel?.setOpacity(0)
  1291. annotationModel?.setFontColor(.black)
  1292. } else {
  1293. annotationModel?.setOpacity(0)
  1294. annotationModel?.setFontColor(.black)
  1295. }
  1296. } else {
  1297. if annotationType == .square || annotationType == .circle || annotationType == .line || annotationType == .arrow {
  1298. annotationModel?.setInteriorOpacity(opacity)
  1299. annotationModel?.setInteriorColor(textColor)
  1300. } else if annotationType == .freeText || annotationType == .signText || annotationType == .signDate {
  1301. annotationModel?.setOpacity(opacity)
  1302. annotationModel?.setFontColor(textColor)
  1303. } else {
  1304. annotationModel?.setOpacity(opacity)
  1305. annotationModel?.setColor(textColor)
  1306. }
  1307. }
  1308. opacitySlider.floatValue = Float(opacity)
  1309. let color = NSColor(calibratedRed: red, green: green, blue: blue, alpha: opacity)
  1310. fillColor = color
  1311. if annotationModel?.annotations != nil {
  1312. if annotationModel?.annotation is CPDFFreeTextAnnotation {
  1313. let textNote = (annotationModel?.annotation as! CPDFFreeTextAnnotation)
  1314. if let isEdit = pdfView?.isEdit(withCurrentFreeText: textNote), isEdit {
  1315. pdfView?.setEditAnnotationFreeTextColor(textColor, freeText: textNote)
  1316. } else {
  1317. updateAnnotation()
  1318. }
  1319. } else {
  1320. updateAnnotation()
  1321. }
  1322. generalImageView.image = annotationModel?.annotationImage
  1323. } else {
  1324. updateAnnotation()
  1325. }
  1326. }
  1327. }
  1328. @IBAction func fillColorPickerViewAction(_ sender: Any) {
  1329. var fillColor = NSColor.clear
  1330. var red: CGFloat = 0.0, green: CGFloat = 0.0, blue: CGFloat = 0.0, opacity: CGFloat = 0.0
  1331. if let borderColor = borderColorPickerView.color {
  1332. borderColor.usingColorSpaceName(.calibratedRGB)?.getRed(&red, green: &green, blue: &blue, alpha: &opacity)
  1333. opacitySlider.floatValue = Float(opacity)
  1334. let color = NSColor(calibratedRed: red, green: green, blue: blue, alpha: opacity)
  1335. fillColor = color
  1336. }
  1337. if annotationType == .freeText {
  1338. if let fillColorPickerColor = fillColorPickerView.color {
  1339. fillColorPickerColor.usingColorSpaceName(.calibratedRGB)?.getRed(&red, green: &green, blue: &blue, alpha: &opacity)
  1340. opacitySlider.floatValue = Float(opacity)
  1341. let color = NSColor(calibratedRed: red, green: green, blue: blue, alpha: opacity)
  1342. annotationModel?.setColor(color)
  1343. annotationModel?.setOpacity(opacity)
  1344. }
  1345. } else {
  1346. annotationModel?.setColor(fillColor)
  1347. annotationModel?.setOpacity(opacity)
  1348. }
  1349. updateAnnotation()
  1350. }
  1351. @IBAction func fontViewCorloPVAction(_ sender: Any) {
  1352. // var fillColor: NSColor = NSColor.clear
  1353. // var red: CGFloat = 0.0, green: CGFloat = 0.0, blue: CGFloat = 0.0, opacity: CGFloat = 0.0
  1354. //
  1355. // if let textColor = fontViewCorloPV.color {
  1356. // textColor.usingColorSpaceName(.calibratedRGB)?.getRed(&red, green: &green, blue: &blue, alpha: &opacity)
  1357. // if fabs(opacity - 0) < 0.001 {
  1358. // if annotationType == .freeText || annotationType == .signText || annotationType == .signDate {
  1359. // annotationModel?.setOpacity(0)
  1360. // annotationModel?.setFontColor(.black)
  1361. // } else {
  1362. // annotationModel?.setOpacity(0)
  1363. // annotationModel?.setFontColor(.black)
  1364. // }
  1365. // } else {
  1366. // if annotationType == .freeText || annotationType == .signText || annotationType == .signDate {
  1367. // annotationModel?.setOpacity(opacity)
  1368. // annotationModel?.setFontColor(textColor)
  1369. // } else {
  1370. // annotationModel?.setOpacity(opacity)
  1371. // annotationModel?.setColor(textColor)
  1372. // }
  1373. // }
  1374. //
  1375. // opacitySlider.floatValue = Float(opacity)
  1376. //
  1377. // if annotationModel?.annotation != nil {
  1378. // if annotationModel?.annotation is CPDFFreeTextAnnotation {
  1379. // let textNote = (annotationModel?.annotation as! CPDFFreeTextAnnotation)
  1380. // if let isEdit = pdfView?.isEdit(withCurrentFreeText: textNote), isEdit {
  1381. // pdfView?.setEditAnnotationFreeTextColor(textColor, freeText: textNote)
  1382. // } else {
  1383. // updateAnnotation()
  1384. // }
  1385. // } else {
  1386. // updateAnnotation()
  1387. // }
  1388. // generalImageView.image = annotationModel?.annotationImage
  1389. // } else {
  1390. // updateAnnotation()
  1391. // }
  1392. // }
  1393. if annotationType == .freeText {
  1394. annotationModel?.setFontColor(fontViewCorloPV.color)
  1395. } else {
  1396. annotationModel?.setColor(fontViewCorloPV.color)
  1397. }
  1398. updateAnnotation()
  1399. }
  1400. @IBAction func opacitySliderAction(_ sender: Any) {
  1401. var opcity = CGFloat(opacitySlider.floatValue)
  1402. if opcity == 0 {
  1403. opcity = 0.0001
  1404. }
  1405. if annotationType == .signFalse ||
  1406. annotationType == .signTure ||
  1407. annotationType == .signDot ||
  1408. annotationType == .signCircle ||
  1409. annotationType == .signLine {
  1410. annotationModel?.setOpacity(opcity)
  1411. } else if annotationType == .square ||
  1412. annotationType == .circle {
  1413. if opcity != 0 {
  1414. annotationModel?.setOpacity(opcity)
  1415. annotationModel?.setInteriorOpacity(opcity)
  1416. } else {
  1417. annotationModel?.setColor(nil)
  1418. annotationModel?.setInteriorColor(nil)
  1419. }
  1420. } else if annotationType == .freeText || annotationType == .signDate || annotationType == .signText {
  1421. annotationModel?.setOpacity(opcity)
  1422. var color = annotationModel?.fontColor()
  1423. if annotationModel?.opacity() != 0 {
  1424. var red: CGFloat = 0.0
  1425. var green: CGFloat = 0.0
  1426. var blue: CGFloat = 0.0
  1427. var opacity: CGFloat = 0.0
  1428. color?.usingColorSpaceName(.calibratedRGB)?.getRed(&red, green: &green, blue: &blue, alpha: &opacity)
  1429. color = NSColor(red: red, green: green, blue: blue, alpha: (annotationModel?.opacity())!)
  1430. } else {
  1431. color = .clear
  1432. }
  1433. } else {
  1434. annotationModel?.setOpacity(opcity)
  1435. }
  1436. opacityComboBox.stringValue = "\(Int(opcity * 100))%"
  1437. updateAnnotation()
  1438. }
  1439. @IBAction func opacityComboBoxAction(_ sender: Any) {
  1440. opacitySlider.floatValue = Float(opacityComboBox.floatValue / 100)
  1441. var opcity = CGFloat(opacitySlider.floatValue)
  1442. if opcity == 0 {
  1443. opcity = 0.0001
  1444. }
  1445. if annotationType == .signFalse ||
  1446. annotationType == .signTure ||
  1447. annotationType == .signDot ||
  1448. annotationType == .signCircle ||
  1449. annotationType == .signLine {
  1450. annotationModel?.setOpacity(opcity)
  1451. } else if annotationType == .square ||
  1452. annotationType == .circle {
  1453. if opcity != 0 {
  1454. annotationModel?.setOpacity(opcity)
  1455. annotationModel?.setInteriorOpacity(opcity)
  1456. } else {
  1457. annotationModel?.setColor(nil)
  1458. annotationModel?.setInteriorColor(nil)
  1459. }
  1460. } else if annotationType == .freeText || annotationType == .signDate || annotationType == .signText {
  1461. annotationModel?.setInteriorOpacity(opcity)
  1462. } else {
  1463. annotationModel?.setOpacity(opcity)
  1464. }
  1465. opacitySlider.floatValue = Float(opcity)
  1466. opacitySlider.toolTip = "\(Int(opcity * 100))%"
  1467. updateAnnotation()
  1468. }
  1469. @IBAction func lineWidthSliderAction(_ sender: Any) {
  1470. annotationModel?.setLineWidth(CGFloat(lineWidthSlider.floatValue))
  1471. lineWidthComboBox.stringValue = String(format: "%0.1f pt", (annotationModel?.lineWidth())!)
  1472. updateAnnotation()
  1473. }
  1474. @IBAction func lineWidthComboBoxAction(_ sender: Any) {
  1475. var lineWidth = lineWidthComboBox.floatValue
  1476. if lineWidth > 18 {
  1477. lineWidth = 18
  1478. } else if lineWidth < 0.5 {
  1479. lineWidth = 0.5
  1480. }
  1481. annotationModel?.setLineWidth(CGFloat(lineWidth))
  1482. lineWidthSlider.floatValue = Float((annotationModel?.lineWidth())!)
  1483. updateAnnotation()
  1484. }
  1485. @IBAction func alignButtonAction(_ sender: NSButton) {
  1486. var alignmentType: KMFreeTextAnnotationAlignmentType = .left
  1487. if annotationModel?.annotations != nil {
  1488. for tAnnotation in self.annotations {
  1489. switch sender.tag {
  1490. case 0:
  1491. if tAnnotation is CPDFFreeTextAnnotation {
  1492. (tAnnotation as! CPDFFreeTextAnnotation).alignment = .left
  1493. }
  1494. alignmentType = .left
  1495. case 1:
  1496. if tAnnotation is CPDFFreeTextAnnotation {
  1497. (tAnnotation as! CPDFFreeTextAnnotation).alignment = .center
  1498. }
  1499. alignmentType = .center
  1500. case 2:
  1501. if tAnnotation is CPDFFreeTextAnnotation {
  1502. (tAnnotation as! CPDFFreeTextAnnotation).alignment = .right
  1503. }
  1504. alignmentType = .right
  1505. default:
  1506. break
  1507. }
  1508. }
  1509. } else {
  1510. switch sender.tag {
  1511. case 0:
  1512. annotationModel?.setAlignment(.left)
  1513. alignmentType = .left
  1514. case 1:
  1515. annotationModel?.setAlignment(.center)
  1516. alignmentType = .center
  1517. case 2:
  1518. annotationModel?.setAlignment(.right)
  1519. alignmentType = .right
  1520. default:
  1521. break
  1522. }
  1523. }
  1524. alignmentTypeSelected(alignmentType)
  1525. updateAnnotation()
  1526. NotificationCenter.default.post(name: NSNotification.Name("KMAnnotationAlignmentTypeNotification"),
  1527. object: "\(alignmentType.rawValue)")
  1528. }
  1529. @IBAction func currentFontColorButtonAction(_ sender: NSButton) {
  1530. // if ([_annotation isKindOfClass:[PDFAnnotationFreeText class]]) {
  1531. // KMFontColorViewController *vc = [[[KMFontColorViewController alloc] initWithNibName:@"KMFontColorViewController" bundle:[NSBundle mainBundle]] autorelease];
  1532. // vc.annotationFontColor = _annotation.fontColor;
  1533. // __block typeof(self) blockSelf = self;
  1534. // vc.fontColorChangeCallback = ^(NSColor *fontColor) {
  1535. // for (PDFAnnotation *tAnnotation in blockSelf.annotations) {
  1536. // tAnnotation.fontColor = fontColor;
  1537. // }
  1538. // };
  1539. // NSPopover *popover = [[NSPopover alloc] init];
  1540. // popover.delegate = self;
  1541. // popover.contentViewController = vc;
  1542. // popover.animates = YES;
  1543. // popover.behavior = NSPopoverBehaviorTransient;
  1544. // [popover showRelativeToRect:CGRectMake([sender bounds].origin.x, 0, [sender bounds].size.width, [sender bounds].size.height) ofView:sender preferredEdge:CGRectMaxYEdge];
  1545. // [popover release];
  1546. // }
  1547. }
  1548. @IBAction func borderButtonAction(_ sender: NSButton) {
  1549. let fontWindowController = KMAnnotationLineWindowController.sharedAnnotationLine
  1550. guard let window = fontWindowController.window else { return }
  1551. fontWindowController.annotations = annotations
  1552. fontWindowController.annotationLineChangeBlock = { [weak self] lineNote in
  1553. if lineNote.borderStyle() == .solid {
  1554. self!.lineTypeButtonAction(self!.lineStyleButton)
  1555. } else if lineNote.borderStyle() == .dashed {
  1556. self!.lineTypeButtonAction(self!.dottedLineStyleButton)
  1557. for tAnnotation in self!.annotations {
  1558. tAnnotation.setDashPattern(lineNote.dashPattern())
  1559. }
  1560. }
  1561. }
  1562. window.orderFront(sender)
  1563. }
  1564. func lineTypePopAction() {
  1565. annotationModel?.setStyle(CPDFBorderStyle(rawValue: lineStyleCount) ?? .solid)
  1566. updateAnnotation()
  1567. }
  1568. @IBAction func lineTypeButtonAction(_ sender: NSButton) {
  1569. let tag = sender.tag
  1570. switch tag {
  1571. case 0:
  1572. lineStyleCount = 0
  1573. refreshLineTypeUI()
  1574. lineStyleButton.image = borderStyleSolid(true)
  1575. dottedLineStyleButton.image = borderStyleDashed(false)
  1576. rightArrowStyleButton.image = lineStyleRightArrow(false)
  1577. lineTypePopAction()
  1578. case 1:
  1579. lineStyleCount = 1
  1580. refreshLineTypeUI()
  1581. lineStyleButton.image = borderStyleSolid(false)
  1582. dottedLineStyleButton.image = borderStyleDashed(true)
  1583. rightArrowStyleButton.image = lineStyleRightArrow(false)
  1584. lineTypePopAction()
  1585. case 2:
  1586. lineStyleCount = 2
  1587. refreshLineTypeUI()
  1588. lineStyleButton.image = borderStyleSolid(false)
  1589. dottedLineStyleButton.image = borderStyleDashed(false)
  1590. rightArrowStyleButton.image = lineStyleRightArrow(true)
  1591. for tAnnotation in annotations {
  1592. if tAnnotation is CPDFLineAnnotation {
  1593. (tAnnotation as! CPDFLineAnnotation).endLineStyle = .closedArrow
  1594. }
  1595. }
  1596. default:
  1597. break
  1598. }
  1599. }
  1600. @IBAction func iconButtonAction(_ sender: NSButton) {
  1601. var type: CPDFTextAnnotationIconType = .comment
  1602. switch sender.tag {
  1603. case 0:
  1604. type = .comment
  1605. case 1:
  1606. type = .key
  1607. case 2:
  1608. type = .note
  1609. case 3:
  1610. type = .help
  1611. case 4:
  1612. type = .newParagraph
  1613. case 5:
  1614. type = .paragraph
  1615. case 6, _:
  1616. type = .insert
  1617. }
  1618. if annotationModel?.annotations != nil {
  1619. for tAnnotation in self.annotations {
  1620. if tAnnotation is CPDFTextAnnotation {
  1621. (tAnnotation as! CPDFTextAnnotation).setIconType(type)
  1622. }
  1623. }
  1624. } else {
  1625. annotationModel?.setAnchoredIconType(type)
  1626. }
  1627. generalImageView.image = annotationModel?.annotationImage
  1628. updateannotationMode()
  1629. clickAnnotationTextIconButtonAction(iconType: UInt(sender.tag), boxArr: iconButtonArray)
  1630. }
  1631. @IBAction func textImageBoxButtonAction(_ sender: Any) {
  1632. openFreeTextStylesViewController()
  1633. }
  1634. // MARK: Font、FontSize Action
  1635. @IBAction func fontButtonAction(_ sender: NSButton) {
  1636. let fontWindowController = KMAnnotationFontWindowController.sharedAnnotationFont
  1637. let window = fontWindowController.window
  1638. fontWindowController.annotations = annotations
  1639. fontWindowController.annotationAlignCallback = { [weak self] selectedCount in
  1640. var alignmentType: KMFreeTextAnnotationAlignmentType = .left
  1641. if selectedCount == NSTextAlignment.left.rawValue {
  1642. alignmentType = .left
  1643. } else if selectedCount == NSTextAlignment.center.rawValue {
  1644. alignmentType = .center
  1645. } else if selectedCount == NSTextAlignment.right.rawValue {
  1646. alignmentType = .right
  1647. }
  1648. self!.alignmentTypeSelected(alignmentType)
  1649. }
  1650. fontWindowController.annotationCallback = { [weak self] annotation in
  1651. if annotation is CPDFFreeTextAnnotation {
  1652. if let family = (annotation as! CPDFFreeTextAnnotation).font?.fontDescriptor.object(forKey: NSFontDescriptor.AttributeName.family) as? String,
  1653. let style = (annotation as! CPDFFreeTextAnnotation).font?.fontDescriptor.object(forKey: NSFontDescriptor.AttributeName.face) as? String {
  1654. DispatchQueue.main.async {
  1655. let selectedStyleIndex = self!.setFontStyle(fontName: family, currentStyle: style)
  1656. self!.fontStylePopUpButton.selectItem(at: Int(selectedStyleIndex))
  1657. }
  1658. DispatchQueue.global(qos: .default).async {
  1659. let fonts = NSFontManager.shared.availableFontFamilies
  1660. let menu = NSMenu()
  1661. var selectedIndex = 0
  1662. for (index, fontName) in fonts.enumerated() {
  1663. if let font = NSFont(name: fontName, size: 12.0) {
  1664. let attributedString = NSAttributedString(string: fontName, attributes: [.font: font])
  1665. let item = NSMenuItem()
  1666. item.attributedTitle = attributedString
  1667. menu.addItem(item)
  1668. if (annotation as! CPDFFreeTextAnnotation).font?.fontName == font.fontName {
  1669. selectedIndex = index
  1670. }
  1671. }
  1672. }
  1673. DispatchQueue.main.async {
  1674. self!.fontPopUpButton.menu = menu
  1675. self!.fontPopUpButton.selectItem(at: selectedIndex)
  1676. }
  1677. }
  1678. }
  1679. }
  1680. }
  1681. window?.orderFront(sender)
  1682. }
  1683. @IBAction func fontPopUpButtonAction(_ sender: NSPopUpButton) {
  1684. guard let selectedItem = fontPopUpButton.selectedItem else { return }
  1685. let resultAtt = NSMutableAttributedString(attributedString: selectedItem.attributedTitle!)
  1686. let familyString = resultAtt.string
  1687. let selectIndex = setFontStyle(fontName: familyString, currentStyle: nil)
  1688. guard let styleString = fontStylePopUpButton.selectedItem?.title else { return }
  1689. fontStylePopUpButton.selectItem(at: Int(selectIndex))
  1690. if annotationModel?.annotations != nil {
  1691. for tAnnotation in annotations {
  1692. if tAnnotation is CPDFFreeTextAnnotation {
  1693. let newAnnotation = (tAnnotation as! CPDFFreeTextAnnotation)
  1694. if let font = newAnnotation.font {
  1695. if let fontSize = font.fontDescriptor.object(forKey: NSFontDescriptor.AttributeName.size) as? String {
  1696. let attributeFontDescriptor = NSFontDescriptor(fontAttributes: [NSFontDescriptor.AttributeName.family: familyString, NSFontDescriptor.AttributeName.face: styleString])
  1697. if let newFont = NSFont(descriptor: attributeFontDescriptor, size: fontSize.stringToCGFloat()) {
  1698. newAnnotation.font = newFont
  1699. }
  1700. }
  1701. if let tFont = newAnnotation.font {
  1702. if let family = tFont.fontDescriptor.object(forKey: NSFontDescriptor.AttributeName.family) as? String,
  1703. let style = tFont.fontDescriptor.object(forKey: NSFontDescriptor.AttributeName.face) as? String {
  1704. DispatchQueue.main.async {
  1705. let selectedStyleIndex = self.setFontStyle(fontName: family, currentStyle: style)
  1706. self.fontStylePopUpButton.selectItem(at: Int(selectedStyleIndex))
  1707. }
  1708. }
  1709. }
  1710. }
  1711. } else if tAnnotation is KMSelfSignAnnotationFreeText {
  1712. let newAnnotation = (tAnnotation as! KMSelfSignAnnotationFreeText)
  1713. if let font = newAnnotation.font {
  1714. if let fontSize = font.fontDescriptor.object(forKey: NSFontDescriptor.AttributeName.size) as? String {
  1715. let attributeFontDescriptor = NSFontDescriptor(fontAttributes: [NSFontDescriptor.AttributeName.family: familyString, NSFontDescriptor.AttributeName.face: styleString])
  1716. if let newFont = NSFont(descriptor: attributeFontDescriptor, size: fontSize.stringToCGFloat()) {
  1717. newAnnotation.font = newFont
  1718. }
  1719. }
  1720. newAnnotation.updateBounds()
  1721. if let tFont = newAnnotation.font {
  1722. if let family = tFont.fontDescriptor.object(forKey: NSFontDescriptor.AttributeName.family) as? String,
  1723. let style = tFont.fontDescriptor.object(forKey: NSFontDescriptor.AttributeName.face) as? String {
  1724. DispatchQueue.main.async {
  1725. let selectedStyleIndex = self.setFontStyle(fontName: family, currentStyle: style)
  1726. self.fontStylePopUpButton.selectItem(at: Int(selectedStyleIndex))
  1727. }
  1728. }
  1729. }
  1730. }
  1731. }
  1732. }
  1733. } else {
  1734. if annotationType == .freeText || annotationType == .signText || annotationType == .signDate {
  1735. let font = NSFont(name: (annotationModel?.fontName())!, size: (annotationModel?.fontSize())!) ?? NSFont.systemFont(ofSize: 16)
  1736. if let fontSize = font.fontDescriptor.object(forKey: NSFontDescriptor.AttributeName.size) as? String {
  1737. let attributeFontDescriptor = NSFontDescriptor(fontAttributes: [NSFontDescriptor.AttributeName.family: familyString, NSFontDescriptor.AttributeName.face: styleString])
  1738. if let newFont = NSFont(descriptor: attributeFontDescriptor, size: fontSize.stringToCGFloat()) {
  1739. annotationModel?.setFontName(newFont.fontName)
  1740. annotationModel?.setFontSize(newFont.pointSize)
  1741. }
  1742. }
  1743. let tFont = NSFont(name: (annotationModel?.fontName())!, size: (annotationModel?.fontSize())!) ?? NSFont.systemFont(ofSize: 16)
  1744. if let family = tFont.fontDescriptor.object(forKey: NSFontDescriptor.AttributeName.family) as? String,
  1745. let style = tFont.fontDescriptor.object(forKey: NSFontDescriptor.AttributeName.face) as? String {
  1746. DispatchQueue.main.async {
  1747. let selectedStyleIndex = self.setFontStyle(fontName: family, currentStyle: style)
  1748. self.fontStylePopUpButton.selectItem(at: Int(selectedStyleIndex))
  1749. }
  1750. }
  1751. }
  1752. }
  1753. updateAnnotation()
  1754. }
  1755. @IBAction func fontSizeComboBoxAction(_ sender: NSComboBox) {
  1756. if annotationModel?.annotations != nil {
  1757. for tAnnotation in annotations {
  1758. if tAnnotation is CPDFFreeTextAnnotation {
  1759. let newAnnotation = (tAnnotation as! CPDFFreeTextAnnotation)
  1760. if let font = newAnnotation.font {
  1761. let newFont = NSFont(name: font.fontName, size: CGFloat(fontSizeComboBox.floatValue))
  1762. if let newFont = newFont {
  1763. newAnnotation.font = newFont
  1764. }
  1765. }
  1766. } else if tAnnotation is KMSelfSignAnnotationFreeText {
  1767. let newAnnotation = (tAnnotation as! KMSelfSignAnnotationFreeText)
  1768. if let font = newAnnotation.font {
  1769. let newFont = NSFont(name: font.fontName, size: CGFloat(fontSizeComboBox.floatValue))
  1770. if let newFont = newFont {
  1771. newAnnotation.font = newFont
  1772. }
  1773. }
  1774. newAnnotation.updateBounds()
  1775. }
  1776. }
  1777. } else {
  1778. if annotationType == .freeText || annotationType == .signText || annotationType == .signDate {
  1779. let font = NSFont(name: (annotationModel?.fontName()!)!, size: (annotationModel?.fontSize())!) ?? NSFont.systemFont(ofSize: 16)
  1780. let newFont = NSFont(name: font.fontName, size: CGFloat(fontSizeComboBox.floatValue))
  1781. if let newFont = newFont {
  1782. annotationModel?.setFontName(newFont.fontName)
  1783. annotationModel?.setFontSize(newFont.pointSize)
  1784. }
  1785. }
  1786. }
  1787. updateAnnotation()
  1788. NotificationCenter.default.post(name: NSNotification.Name("KMAnnotationFontTypeNotification"),
  1789. object: pdfView)
  1790. adjustFreeText()
  1791. }
  1792. //字重 NSFontWeight
  1793. @IBAction func fontStylePopUpButtonAction(_ sender: NSPopUpButton) {
  1794. if let styleString = self.fontStylePopUpButton.selectedItem?.title {
  1795. if annotationModel?.annotations != nil {
  1796. for tAnnotation in self.annotations {
  1797. if tAnnotation is CPDFFreeTextAnnotation {
  1798. let newAnnotation = (tAnnotation as! CPDFFreeTextAnnotation)
  1799. if let font = newAnnotation.font {
  1800. if let fontSize = font.fontDescriptor.object(forKey: NSFontDescriptor.AttributeName.size) as? String,
  1801. let familyString = font.fontDescriptor.object(forKey: NSFontDescriptor.AttributeName.family) as? String {
  1802. let attributeFontDescriptor = NSFontDescriptor(fontAttributes: [NSFontDescriptor.AttributeName.family: familyString, NSFontDescriptor.AttributeName.face: styleString])
  1803. if let newFont = NSFont(descriptor: attributeFontDescriptor, size: fontSize.stringToCGFloat()) {
  1804. newAnnotation.font = newFont
  1805. }
  1806. }
  1807. }
  1808. } else if tAnnotation is KMSelfSignAnnotationFreeText {
  1809. let newAnnotation = (tAnnotation as! KMSelfSignAnnotationFreeText)
  1810. if let font = newAnnotation.font {
  1811. if let fontSize = font.fontDescriptor.object(forKey: NSFontDescriptor.AttributeName.size) as? String,
  1812. let familyString = font.fontDescriptor.object(forKey: NSFontDescriptor.AttributeName.family) as? String {
  1813. let attributeFontDescriptor = NSFontDescriptor(fontAttributes: [NSFontDescriptor.AttributeName.family: familyString, NSFontDescriptor.AttributeName.face: styleString])
  1814. if let newFont = NSFont(descriptor: attributeFontDescriptor, size: fontSize.stringToCGFloat()) {
  1815. newAnnotation.font = newFont
  1816. }
  1817. newAnnotation.updateBounds()
  1818. }
  1819. }
  1820. }
  1821. }
  1822. } else {
  1823. if annotationType == .freeText || annotationType == .signText || annotationType == .signDate {
  1824. let font = NSFont(name: (annotationModel?.fontName())!, size: (annotationModel?.fontSize())!) ?? NSFont.systemFont(ofSize: 16)
  1825. if let fontSize = font.fontDescriptor.object(forKey: NSFontDescriptor.AttributeName.size) as? String,
  1826. let familyString = font.fontDescriptor.object(forKey: NSFontDescriptor.AttributeName.family) as? String {
  1827. let attributeFontDescriptor = NSFontDescriptor(fontAttributes: [NSFontDescriptor.AttributeName.family: familyString, NSFontDescriptor.AttributeName.face: styleString])
  1828. if let newFont = NSFont(descriptor: attributeFontDescriptor, size: fontSize.stringToCGFloat()) {
  1829. annotationModel?.setFontName(newFont.fontName)
  1830. annotationModel?.setFontSize(newFont.pointSize)
  1831. }
  1832. }
  1833. }
  1834. }
  1835. }
  1836. updateAnnotation()
  1837. }
  1838. @IBAction func buttonClicked_SwitchIncludeTime(_ sender: NSButton) {
  1839. for case let tAnnotation as KMSelfSignAnnotationFreeText in annotations {
  1840. tAnnotation.includeTime = sender.state == .on ? true : false
  1841. let index = datePopUpButton.indexOfSelectedItem
  1842. datePopUpButton.removeAllItems()
  1843. datePopUpButton.addItems(withTitles: KMSelfSignAnnotationFreeText.fetchAllDateString(includeTime: false))
  1844. datePopUpButton.selectItem(at: index)
  1845. if self.subType == .date && isannotationMode {
  1846. UserDefaults.standard.set(sender.state == .on ? true : false, forKey: SKAnnotationSelfSignDateFormatterIncludeTimeKey)
  1847. }
  1848. }
  1849. reloadData()
  1850. }
  1851. @IBAction func dateCheckButtonAction(_ sender: NSPopUpButton) {
  1852. for case let tAnnotation as KMSelfSignAnnotationFreeText in annotations {
  1853. if subType == .date && isannotationMode {
  1854. let fetchArray = KMSelfSignAnnotationFreeText.fetchAllDateString(includeTime: false)
  1855. if sender.indexOfSelectedItem >= 0 && sender.indexOfSelectedItem <= fetchArray.count - 1 {
  1856. UserDefaults.standard.set(sender.indexOfSelectedItem, forKey: SKAnnotationSelfSignDateFormatterKey)
  1857. }
  1858. }
  1859. tAnnotation.dateFormatIndex = sender.indexOfSelectedItem
  1860. }
  1861. reloadData()
  1862. }
  1863. func annotationFontReload() {
  1864. DispatchQueue.global(qos: .default).async { [self] in
  1865. let fonts = NSFontManager.shared.availableFontFamilies
  1866. let menu = NSMenu()
  1867. var selectedIndex = 0
  1868. for (index, fontName) in fonts.enumerated() {
  1869. if let font = NSFont(name: fontName, size: 12.0) {
  1870. let attributedString = NSAttributedString(string: fontName, attributes: [NSAttributedString.Key.font: font])
  1871. let item = NSMenuItem()
  1872. item.attributedTitle = attributedString
  1873. menu.addItem(item)
  1874. if annotationType == .freeText {
  1875. if annotationModel?.fontName() == font.fontName {
  1876. selectedIndex = index
  1877. }
  1878. }
  1879. }
  1880. }
  1881. if annotationType == .freeText {
  1882. let freetextFont = NSFont(name: (annotationModel?.fontName() as? String)!, size: 16) ?? NSFont.systemFont(ofSize: 16)
  1883. if let family = freetextFont.fontDescriptor.object(forKey: NSFontDescriptor.AttributeName.family) as? String,
  1884. let style = freetextFont.fontDescriptor.object(forKey: NSFontDescriptor.AttributeName.face) as? String {
  1885. DispatchQueue.main.async { [self] in
  1886. fontPopUpButton.menu = menu
  1887. fontPopUpButton.selectItem(at: selectedIndex)
  1888. let selectedStyleIndex = setFontStyle(fontName: family, currentStyle: style)
  1889. fontStylePopUpButton.selectItem(at: Int(selectedStyleIndex))
  1890. }
  1891. }
  1892. }
  1893. }
  1894. }
  1895. func adjustFreeText() {
  1896. if annotationModel?.annotations != nil {
  1897. if annotationType == .freeText || annotationType == .signText || annotationType == .signDate {
  1898. for an in (annotationModel?.annotations)! {
  1899. if let freeTextAn = an as? CPDFFreeTextAnnotation {
  1900. let font = freeTextAn.font
  1901. var attributes: [NSAttributedString.Key: Any] = [NSAttributedString.Key.font: font as Any]
  1902. let style = NSMutableParagraphStyle()
  1903. style.alignment = freeTextAn.alignment
  1904. attributes[NSAttributedString.Key.paragraphStyle] = style
  1905. let contents = freeTextAn.contents ?? ""
  1906. let textViewSize = contents.boundingRect(with: CGSize(width: freeTextAn.bounds.size.width, height: CGFloat(MAXFLOAT)),
  1907. options: .usesLineFragmentOrigin,
  1908. attributes: attributes).size
  1909. var rect = freeTextAn.bounds
  1910. if textViewSize.height != freeTextAn.bounds.size.height {
  1911. rect.origin.y -= (textViewSize.height - rect.size.height)
  1912. rect.size.height = textViewSize.height
  1913. }
  1914. if textViewSize.width < freeTextAn.bounds.size.width {
  1915. rect.size.width = textViewSize.width
  1916. }
  1917. freeTextAn.bounds = rect
  1918. }
  1919. }
  1920. }
  1921. }
  1922. }
  1923. // MARK: NSNotification
  1924. @objc func textDidChange(_ notification: Notification) {
  1925. self.isTextEdit = true
  1926. if self.subType == KMSelfSignAnnotationFreeTextSubType.freeText && isannotationMode {
  1927. if let obj = notification.object as? NSObject {
  1928. for tAnnotation in annotations {
  1929. tAnnotation.setString(noteTextView.string)
  1930. }
  1931. if obj.isEqual(to: noteTextView) {
  1932. UserDefaults.standard.set(noteTextView.string, forKey: SKAnnotationSelfSignPlaceHolderStringKey)
  1933. }
  1934. if annotation.isKind(of: CPDFFreeTextAnnotation.self) {
  1935. textAnnotationImageView.image = annotationModel?.annotationImage
  1936. } else {
  1937. generalImageView.image = annotationModel?.annotationImage
  1938. }
  1939. }
  1940. } else {
  1941. if let obj = notification.object as? NSObject, obj.isEqual(to: noteTextView) {
  1942. for tAnnotation in self.annotations {
  1943. tAnnotation.setString(noteTextView.string)
  1944. }
  1945. }
  1946. }
  1947. }
  1948. @objc func themeChanged(_ notification: Notification) {
  1949. DispatchQueue.main.asyncAfter(deadline: .now() + 0.3) { [self] in
  1950. updateViewColor()
  1951. }
  1952. }
  1953. }
  1954. class KMGeneralAnnotationColorButton: NSButton {
  1955. var _circleColor: NSColor = .clear
  1956. var _buttonBorderColor: NSColor = .clear
  1957. // MARK: Get & Set
  1958. var circleColor: NSColor {
  1959. set {
  1960. _circleColor = newValue
  1961. needsDisplay = true
  1962. }
  1963. get {
  1964. return _circleColor
  1965. }
  1966. }
  1967. var buttonBorderColor: NSColor {
  1968. set {
  1969. _buttonBorderColor = newValue
  1970. needsDisplay = true
  1971. }
  1972. get {
  1973. return _buttonBorderColor
  1974. }
  1975. }
  1976. // MARK: Init
  1977. required init?(coder: NSCoder) {
  1978. super.init(coder: coder)
  1979. wantsLayer = true
  1980. layer?.cornerRadius = 12.0
  1981. layer?.masksToBounds = true
  1982. layer?.borderColor = NSColor.clear.cgColor
  1983. }
  1984. override func draw(_ dirtyRect: NSRect) {
  1985. super.draw(dirtyRect)
  1986. let path3 = NSBezierPath(ovalIn: NSMakeRect(3, 3, dirtyRect.size.width - 6, dirtyRect.size.height - 6))
  1987. }
  1988. }
  1989. class KMNoteIconButtonCell: NSButtonCell {
  1990. override func drawImage(_ image: NSImage, withFrame frame: NSRect, in controlView: NSView) {
  1991. let titleSize = self.attributedTitle.size()
  1992. let imageSize = self.image!.size
  1993. var rect = NSZeroRect
  1994. let leftGap = (controlView.bounds.size.width - image.size.width) / 2.0
  1995. rect.origin.x = leftGap
  1996. if self.imagePosition == .imageAbove {
  1997. rect.origin.y = 6
  1998. } else {
  1999. rect.origin.y = (controlView.frame.size.height - image.size.height) / 2.0
  2000. }
  2001. rect.size = imageSize
  2002. super.drawImage(self.image!, withFrame: rect, in: controlView)
  2003. }
  2004. override func drawTitle(_ title: NSAttributedString, withFrame frame: NSRect, in controlView: NSView) -> NSRect {
  2005. let titleSize = self.attributedTitle.size()
  2006. let imageSize = self.image!.size
  2007. let totalHeight = titleSize.height + imageSize.height + 1
  2008. var rect = NSZeroRect
  2009. rect.origin.x = (controlView.bounds.size.width - titleSize.width) / 2.0
  2010. rect.origin.y = (controlView.bounds.size.height - totalHeight) / 2.0 + imageSize.height + 1
  2011. rect.size = titleSize
  2012. return super.drawTitle(title, withFrame: rect, in: controlView)
  2013. }
  2014. }