KMNPopContentEditWindowController.swift 41 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921
  1. //
  2. // KMNPopContentEditWindowController.swift
  3. // PDF Reader Pro
  4. //
  5. // Created by 丁林圭 on 2024/12/2.
  6. //
  7. import Cocoa
  8. import KMComponentLibrary
  9. class KMNPopContentEditWindowController: KMNBaseWindowController {
  10. public var editType:EditContentPopType = .editNone {
  11. didSet {
  12. rightOffsetConstraint.constant = 45.0
  13. paneBox.isHidden = false
  14. switch editType {
  15. case .signTextEdit :
  16. textPopView.layoutSubtreeIfNeeded()
  17. operationWidthConstraint.constant = textPopView.bounds.width
  18. self.window?.display() //需刷新约束才会有值,不然会变化
  19. operationBox.contentView = textPopView
  20. congfigFontPopUI()
  21. fontAlightButton.properties.icon = NSImage(named: "KMNImageNameListViewPopAlightLeft")
  22. fontAlightButton.reloadData()
  23. break
  24. case .signImageEdit:
  25. imagePopView.layoutSubtreeIfNeeded()
  26. congfigSignImageUI()
  27. operationWidthConstraint.constant = imagePopView.bounds.width
  28. self.window?.display() //需刷新约束才会有值,不然会变化
  29. operationBox.contentView = imagePopView
  30. break
  31. case .multpleTextEdit:
  32. textPopView.layoutSubtreeIfNeeded()
  33. operationWidthConstraint.constant = textPopView.bounds.width
  34. self.window?.display() //需刷新约束才会有值,不然会变化
  35. operationBox.contentView = textPopView
  36. congfigFontPopUI()
  37. fontAlightButton.properties.icon = NSImage(named: "KMNImageNameListViewPopAlightLeft")
  38. fontAlightButton.reloadData()
  39. break
  40. case .multpleImageEdit:
  41. imagePopView.layoutSubtreeIfNeeded()
  42. congfigMultpleImageUI()
  43. operationWidthConstraint.constant = imagePopView.bounds.width
  44. self.window?.display() //需刷新约束才会有值,不然会变化
  45. operationBox.contentView = imagePopView
  46. break
  47. case .multpleImageAndText:
  48. alightView.layoutSubtreeIfNeeded()
  49. operationWidthConstraint.constant = alightView.bounds.width
  50. self.window?.display() //需刷新约束才会有值,不然会变化
  51. operationBox.contentView = alightView
  52. break
  53. case .cropImage:
  54. cropPopView.layoutSubtreeIfNeeded()
  55. rightOffsetConstraint.constant = 0
  56. paneBox.isHidden = true
  57. operationWidthConstraint.constant = cropPopView.bounds.width
  58. self.window?.display() //需刷新约束才会有值,不然会变化
  59. operationBox.contentView = cropPopView
  60. break
  61. case .editNone:
  62. break
  63. }
  64. }
  65. }
  66. public var isOpenPane = false {
  67. didSet {
  68. if isOpenPane == true {
  69. paneSelectorItem.properties.state = .pressed
  70. } else {
  71. paneSelectorItem.properties.state = .normal
  72. }
  73. paneSelectorItem.reloadData()
  74. }
  75. }
  76. public var editContentPopMode:KMNEditContentPopMode = KMNEditContentPopMode(currentEditAreas: []) {
  77. didSet {
  78. let editPopType = editContentPopMode.popType
  79. editType = editPopType
  80. if(editType == .signTextEdit || editType == .multpleTextEdit) {
  81. let textEditAreas = listView?.km_editingTextAreas()
  82. let oldColor:NSColor? = fontColor
  83. let firstTextEditArea = textEditAreas?.first
  84. let firstColor = listView?.editingSelectionFontColor(with: firstTextEditArea)
  85. var newColor:NSColor? = firstColor
  86. for textEditArea in textEditAreas ?? [] {
  87. if firstTextEditArea != textEditArea {
  88. let color = listView?.editingSelectionFontColor(with: firstTextEditArea)
  89. if CPDFListView.isTheSameColor(color, anotherColor: firstColor) == false{
  90. newColor = nil
  91. break
  92. }
  93. }
  94. }
  95. if !CPDFListView.isTheSameColor(newColor, anotherColor: oldColor) {
  96. fontColor = newColor
  97. }
  98. let oldBold:Bool = isBold
  99. let newBolds:[Bool] = listView?.km_editTextAreasFontBolds(textEditAreas ?? []) ?? []
  100. var newBold = true
  101. for i in 0 ..< newBolds.count {
  102. let boldV = newBolds[i]
  103. if boldV == false {
  104. newBold = false
  105. break
  106. }
  107. }
  108. if oldBold != newBold {
  109. isBold = newBold
  110. }
  111. let oldItalic:Bool = isItalic
  112. let newItalics:[Bool] = listView?.km_editTextAreasFontItalics(textEditAreas ?? []) ?? []
  113. var newItalic = true
  114. for i in 0 ..< newItalics.count {
  115. let boldV = newItalics[i]
  116. if boldV == false {
  117. newItalic = false
  118. break
  119. }
  120. }
  121. if oldItalic != newItalic {
  122. isItalic = newItalic
  123. }
  124. let oldStrikeoutLine:Bool = isStrikeoutLine
  125. let newStrikeoutLines:[Bool] = listView?.km_editTextAreasFontStrikeout(textEditAreas ?? []) ?? []
  126. var newStrikeoutLine = true
  127. for i in 0 ..< newStrikeoutLines.count {
  128. let boldV = newStrikeoutLines[i]
  129. if boldV == false {
  130. newStrikeoutLine = false
  131. break
  132. }
  133. }
  134. if oldStrikeoutLine != newStrikeoutLine {
  135. isStrikeoutLine = newStrikeoutLine
  136. }
  137. let oldUnderLine:Bool = isUnderLine
  138. let newUnderLines:[Bool] = listView?.km_editTextAreasFontUnder(textEditAreas ?? []) ?? []
  139. var newUnderLine = true
  140. for i in 0 ..< newStrikeoutLines.count {
  141. let boldV = newUnderLines[i]
  142. if boldV == false {
  143. newUnderLine = false
  144. break
  145. }
  146. }
  147. if oldUnderLine != newUnderLine {
  148. isUnderLine = newUnderLine
  149. }
  150. let alights = listView?.km_editTextAreasTextAlignments(textEditAreas ?? []) ?? []
  151. var newAlignment = alights.first ?? .left
  152. let oldAlignment :NSTextAlignment = fontAlight
  153. for i in 0 ..< alights.count {
  154. let alignmentV = alights[i]
  155. if oldAlignment != alignmentV {
  156. newAlignment = .left
  157. break
  158. }
  159. }
  160. if oldAlignment != newAlignment {
  161. fontAlight = newAlignment
  162. }
  163. let fonts = listView?.km_editTextAreasComPDFFonts(textEditAreas ?? []) ?? []
  164. var newFont:CPDFFont? = fonts.first
  165. for i in 0 ..< fonts.count {
  166. let fontV = fonts[i]
  167. if i != 0 && (fontV.familyName != compdfFont?.familyName || fontV.styleName != compdfFont?.styleName) {
  168. newFont = nil
  169. break
  170. }
  171. }
  172. compdfFont = newFont
  173. }
  174. }
  175. }
  176. private var fontColor:NSColor? {
  177. didSet {
  178. fontColorItem.properties?.color = fontColor
  179. fontColorItem.reloadData()
  180. }
  181. }
  182. private var compdfFont:CPDFFont?{
  183. didSet {
  184. if(compdfFont != nil) {
  185. let styleName = compdfFont!.styleName
  186. if(styleName?.isEmpty == true) {
  187. fontNameSelect.properties.text = compdfFont!.familyName
  188. } else {
  189. fontNameSelect.properties.text = compdfFont!.familyName + "-" + (compdfFont!.styleName ?? "")
  190. }
  191. } else {
  192. fontNameSelect.properties.text = "-"
  193. }
  194. fontNameSelect.reloadData()
  195. }
  196. }
  197. private var fontAlight:NSTextAlignment = .left {
  198. didSet {
  199. if fontAlight == .center {
  200. fontAlightButton.properties.icon = NSImage(named: "KMNImageNameListViewPopAlightCenter")
  201. } else if fontAlight == .right {
  202. fontAlightButton.properties.icon = NSImage(named: "KMNImageNameListViewPopAlightRight")
  203. } else if fontAlight == .justified {
  204. fontAlightButton.properties.icon = NSImage(named: "KMNImageNameListViewPopAlightJus")
  205. } else {
  206. fontAlightButton.properties.icon = NSImage(named: "KMNImageNameListViewPopAlightLeft")
  207. }
  208. fontAlightButton.reloadData()
  209. }
  210. }
  211. private var objectAlign:ObjectAlignType = .alightLeft {
  212. didSet {
  213. switch objectAlign {
  214. case .alightLeft :
  215. listView?.changeEditingAreas(.left)
  216. alightButton.properties.icon = NSImage(named: "KMNImageNameObjectPopAlightLeft")
  217. break
  218. case .alightRight:
  219. listView?.changeEditingAreas(.right)
  220. alightButton.properties.icon = NSImage(named: "KMNImageNameObjectPopAlightRight")
  221. break
  222. case .alightTop:
  223. listView?.changeEditingAreas(.top)
  224. alightButton.properties.icon = NSImage(named: "KMNImageNameObjectPopAlightTop")
  225. break
  226. case .alightVer:
  227. listView?.changeEditingAreas(.vertical)
  228. alightButton.properties.icon = NSImage(named: "KMNImageNameObjectPopAlightVer")
  229. break
  230. case .alightHor:
  231. listView?.changeEditingAreas(.horizontally)
  232. alightButton.properties.icon = NSImage(named: "KMNImageNameObjectPopAlightHor")
  233. break
  234. case .alightBottom:
  235. listView?.changeEditingAreas(.bottom)
  236. alightButton.properties.icon = NSImage(named: "KMNImageNameObjectPopAlightBottom")
  237. break
  238. case .averageVer:
  239. listView?.changeEditingAreas(.disVertical)
  240. alightButton.properties.icon = NSImage(named: "KMNImageNameObjecAlignAverageVer")
  241. break
  242. case .averageHor:
  243. listView?.changeEditingAreas(.disHorizontally)
  244. alightButton.properties.icon = NSImage(named: "KMNImageNameObjecAlignAverageHor")
  245. break
  246. }
  247. alightButton.reloadData()
  248. }
  249. }
  250. private var isBold:Bool = false {
  251. didSet {
  252. fontBoldSelectorItem.properties.state = isBold ? .pressed : .normal
  253. fontBoldSelectorItem.reloadData()
  254. }
  255. }
  256. private var isItalic:Bool = false {
  257. didSet {
  258. fontItalicSelectorItem.properties.state = isItalic ? .pressed : .normal
  259. fontItalicSelectorItem.reloadData()
  260. }
  261. }
  262. private var isStrikeoutLine:Bool = false {
  263. didSet {
  264. fontStrikeoutLineSelectorItem.properties.state = isStrikeoutLine ? .pressed : .normal
  265. fontStrikeoutLineSelectorItem.reloadData()
  266. }
  267. }
  268. private var isUnderLine:Bool = false {
  269. didSet {
  270. fontUnderLineSelectorItem.properties.state = isUnderLine ? .pressed : .normal
  271. fontUnderLineSelectorItem.reloadData()
  272. }
  273. }
  274. static let shared: KMNPopContentEditWindowController = {
  275. let windowC = KMNPopContentEditWindowController(windowNibName: "KMNPopContentEditWindowController")
  276. return windowC
  277. }()
  278. var paneCallback: PaneCallback?
  279. var updatePDFViewCallback: UpdatePDFViewCallback?
  280. @IBOutlet weak var contentBox: NSBox!
  281. @IBOutlet weak var operationBox: NSBox!
  282. @IBOutlet weak var paneBox: NSBox!
  283. @IBOutlet weak var lineBox: NSBox!
  284. @IBOutlet var paneSelectorItem: ComponentCSelectorItem!
  285. @IBOutlet weak var operationWidthConstraint: NSLayoutConstraint!
  286. @IBOutlet weak var rightOffsetConstraint: NSLayoutConstraint!
  287. @IBOutlet var textPopView: NSView!
  288. @IBOutlet var fontColorItem: ComponentCColorItem!
  289. @IBOutlet var fontNameSelect: ComponentSelect!
  290. @IBOutlet var fontBoldSelectorItem: ComponentCSelector!
  291. @IBOutlet var fontItalicSelectorItem: ComponentCSelector!
  292. @IBOutlet var fontStrikeoutLineSelectorItem: ComponentCSelector!
  293. @IBOutlet var fontUnderLineSelectorItem: ComponentCSelector!
  294. @IBOutlet var fontSizeZoomOutButton: ComponentButton!
  295. @IBOutlet var fontSizeZoomInButton: ComponentButton!
  296. @IBOutlet var fontAlightButton: ComponentButton!
  297. @IBOutlet var imagePopView: NSView!
  298. @IBOutlet var rotaLeftButton: ComponentButton!
  299. @IBOutlet var rotaRightButton: ComponentButton!
  300. @IBOutlet var horizontalMirrorButton: ComponentButton!
  301. @IBOutlet var verticalMirrorButton: ComponentButton!
  302. @IBOutlet var cropButton: ComponentButton!
  303. @IBOutlet var replaceButton: ComponentButton!
  304. @IBOutlet var extractButton: ComponentButton!
  305. @IBOutlet weak var rightConstraint: NSLayoutConstraint!
  306. @IBOutlet var alightView: NSView!
  307. @IBOutlet var alightButton: ComponentButton!
  308. @IBOutlet var cropPopView: NSView!
  309. @IBOutlet var cropSureButton: ComponentButton!
  310. @IBOutlet var cropRestButton: ComponentButton!
  311. private var extractGroupView: ComponentGroup?
  312. weak var listView: CPDFListView?
  313. private var fontPopover:NSPopover?
  314. private var ObjectPopover:NSPopover?
  315. override func windowDidLoad() {
  316. super.windowDidLoad()
  317. }
  318. override func initContentView() {
  319. super.initContentView()
  320. paneSelectorItem.properties = ComponentCSelectorProperty(iconImage:NSImage(named: "KMNImageNameListViewPopPane"))
  321. paneSelectorItem.setTarget(self, action: #selector(paneButtonClicked(_ :)))
  322. fontBoldSelectorItem.properties = ComponentCSelectorProperty(
  323. iconImage:NSImage(named: "KMNImageNameContentBold"))
  324. fontBoldSelectorItem.setTarget(self, action: #selector(fontBoldButtonClicked(_ :)))
  325. fontItalicSelectorItem.properties = ComponentCSelectorProperty(
  326. iconImage:NSImage(named: "KMNImageNameContentItalic"))
  327. fontItalicSelectorItem.setTarget(self, action: #selector(fontItalicButtonClicked(_ :)))
  328. fontStrikeoutLineSelectorItem.properties = ComponentCSelectorProperty(
  329. iconImage:NSImage(named: "KMNImageNameContentStrikeoutLine"))
  330. fontStrikeoutLineSelectorItem.setTarget(self, action: #selector(fontStrikeoutLineButtonClicked(_ :)))
  331. fontUnderLineSelectorItem.properties = ComponentCSelectorProperty(iconImage:NSImage(named: "KMNImageNameContentUnderLine"))
  332. fontUnderLineSelectorItem.setTarget(self, action: #selector(fontUnderLineButtonClicked(_ :)))
  333. fontSizeZoomOutButton.properties = ComponentButtonProperty(type: .text_gray,
  334. size: .s,
  335. state: .normal,
  336. onlyIcon: true,
  337. icon:NSImage(named: "KMNImageNameListViewPopFontSizeZoomOut"),
  338. keepPressState: false)
  339. fontSizeZoomOutButton.setTarget(self, action: #selector(fontSizeZoomOutButtonClicked(_ :)))
  340. fontSizeZoomInButton.properties = ComponentButtonProperty(type: .text_gray,
  341. size: .s,
  342. state: .normal,
  343. onlyIcon: true,
  344. icon:NSImage(named: "KMNImageNameListViewPopFontSizeZoomIn"),
  345. keepPressState: false)
  346. fontSizeZoomInButton.setTarget(self, action: #selector(fontSizeZoomInButtonClicked(_ :)))
  347. fontColorItem.properties = ComponentCColorProperty(colorType: .color, state: .normal, isCustom: false, color: .clear)
  348. fontColorItem.delegate = self
  349. fontAlightButton.properties = ComponentButtonProperty(type: .text_gray,
  350. size: .s,
  351. state: .normal,
  352. onlyIcon: true,
  353. icon:NSImage(named: "KMNImageNameListViewPopAlightLeft"),
  354. keepPressState: false)
  355. fontAlightButton.setTarget(self, action: #selector(fontAlightButtonClicked(_ :)))
  356. rotaLeftButton.properties = ComponentButtonProperty(type: .text_gray,
  357. size: .s,
  358. state: .normal,
  359. onlyIcon: true,
  360. icon:NSImage(named: "KMNImageNameContentRotateLeft"),
  361. keepPressState: false)
  362. rotaLeftButton.setTarget(self, action: #selector(rotateLeftButtonClicked(_ :)))
  363. rotaRightButton.properties = ComponentButtonProperty(type: .text_gray,
  364. size: .s,
  365. state: .normal,
  366. onlyIcon: true,
  367. icon:NSImage(named: "KMNImageNameContentRotateRight"),
  368. keepPressState: false)
  369. rotaRightButton.setTarget(self, action: #selector(rotateRightButtonClicked(_ :)))
  370. horizontalMirrorButton.properties = ComponentButtonProperty(type: .text_gray,
  371. size: .s,
  372. state: .normal,
  373. onlyIcon: true,
  374. icon:NSImage(named: "KMNImageNameContentHorMirr"),
  375. keepPressState: false)
  376. horizontalMirrorButton.setTarget(self, action: #selector(horizontalMirrorButtonClicked(_ :)))
  377. verticalMirrorButton.properties = ComponentButtonProperty(type: .text_gray,
  378. size: .s,
  379. state: .normal,
  380. onlyIcon: true,
  381. icon:NSImage(named: "KMNImageNameContentVerMirr"),
  382. keepPressState: false)
  383. verticalMirrorButton.setTarget(self, action: #selector(verticalMirrorButtonClicked(_ :)))
  384. alightButton.properties = ComponentButtonProperty(type: .text_gray,
  385. size: .s,
  386. state: .normal,
  387. onlyIcon: true,
  388. icon:NSImage(named: "KMNImageNameObjectPopAlightLeft"))
  389. alightButton.setTarget(self, action: #selector(alightButtonClicked(_ :)))
  390. cropRestButton.properties = ComponentButtonProperty(type: .text_gray,
  391. size: .s,
  392. state: .normal,
  393. onlyIcon: true,
  394. icon:NSImage(named: "KMNImageNameContentCropRest"),keepPressState: false)
  395. cropRestButton.setTarget(self, action: #selector(cropRestClicked(_ :)))
  396. cropSureButton.properties = ComponentButtonProperty(type: .text_gray,
  397. size: .s,
  398. state: .normal,
  399. onlyIcon: true,
  400. icon:NSImage(named: "KMNImageNameContentCropSure"),keepPressState: false)
  401. cropSureButton.setTarget(self, action: #selector(cropSureClicked(_ :)))
  402. }
  403. override func updateUIThemeColor() {
  404. super.updateUIThemeColor()
  405. lineBox.fillColor = ComponentLibrary.shared.getComponentColorFromKey("colorBorder/divider")
  406. contentBox.fillColor = ComponentLibrary.shared.getComponentColorFromKey("colorBg/popup")
  407. contentBox.borderColor = ComponentLibrary.shared.getComponentColorFromKey("colorBorder/3-default")
  408. }
  409. override func updateUILanguage() {
  410. super.updateUILanguage()
  411. }
  412. //MARK: - Public
  413. public func updateFrame(listView:CPDFListView) {
  414. let editingAreas = listView.km_EditingAreas()
  415. let page = editingAreas.first?.page
  416. let windowFram = listView.window?.frame ?? CGRectZero
  417. if(page != nil) {
  418. let pageRect = listView.selectionMultipleBounds(withEditArea: editingAreas)
  419. let positioningRect = listView.convert(pageRect, from: page!)
  420. let view: NSView? = nil
  421. let position = listView.convert(positioningRect, to: view)
  422. var positionNew = position.origin
  423. positionNew.x += windowFram.origin.x + position.width/2
  424. positionNew.y += windowFram.origin.y + position.height
  425. var positionRect = self.window?.frame ?? CGRectZero
  426. positionRect.origin.x = positionNew.x - positionRect.width/2
  427. positionRect.origin.y = positionNew.y + popOffSet + CGFloat(truncating: listView.editingConfig().editAreaMargin)
  428. var listViewWindRect = listView.convert(listView.frame, to: view)
  429. listViewWindRect.origin.x += windowFram.origin.x
  430. listViewWindRect.origin.y += windowFram.origin.y
  431. if CGRectGetMaxY(positionRect) > CGRectGetMaxY(listViewWindRect) {
  432. positionRect.origin.y = positionNew.y - popOffSet - position.height - positionRect.size.height
  433. }
  434. if CGRectGetMinX(positionRect) < CGRectGetMinX(listViewWindRect) {
  435. positionRect.origin.x = CGRectGetMinX(listViewWindRect)
  436. }
  437. if CGRectGetMaxX(positionRect) > CGRectGetMaxX(listViewWindRect) {
  438. positionRect.origin.x = CGRectGetMaxX(listViewWindRect) - positionRect.width
  439. }
  440. self.window?.setFrame(positionRect, display: true)
  441. updateUILanguage()
  442. }
  443. }
  444. public func closeWindow(listView:CPDFListView?) {
  445. if self.window?.isVisible == true {
  446. listView?.window?.removeChildWindow(self.window ?? NSWindow())
  447. self.window?.close()
  448. }
  449. if ObjectPopover?.isShown == true {
  450. ObjectPopover?.close()
  451. }
  452. if fontPopover?.isShown == true {
  453. fontPopover?.close()
  454. }
  455. }
  456. //MARK: - private
  457. private func congfigFontPopUI() {
  458. fontNameSelect.properties = ComponentSelectProperties(size: .s,
  459. state: .normal,
  460. isDisabled: false,
  461. isError: false,
  462. leftIcon: false,
  463. placeholder: nil,
  464. errorText: nil,
  465. creatable: false,
  466. text: NSLocalizedString("", comment: ""))
  467. fontNameSelect.delegate = self
  468. var menuItemArr: [ComponentMenuitemProperty] = []
  469. for familyName in CPDFFont.familyNames {
  470. let fontNames = CPDFFont.fontNames(forFamilyName: familyName)
  471. let itemProperty: ComponentMenuitemProperty = ComponentMenuitemProperty(multipleSelect: false,
  472. itemSelected: false,
  473. isDisabled: false,
  474. keyEquivalent: nil,
  475. text: familyName,
  476. identifier: "1")
  477. var subMenuItemArr: [ComponentMenuitemProperty] = []
  478. for fontName in fontNames {
  479. let subItemProperty: ComponentMenuitemProperty = ComponentMenuitemProperty(multipleSelect: false,
  480. itemSelected: false,
  481. isDisabled: false,
  482. keyEquivalent: nil,
  483. text: fontName,identifier: "2")
  484. subMenuItemArr.append(subItemProperty)
  485. }
  486. itemProperty.subPropertys = subMenuItemArr
  487. menuItemArr.append(itemProperty)
  488. }
  489. fontNameSelect.updateMenuItemsArr(menuItemArr)
  490. }
  491. private func congfigSignImageUI() {
  492. rightConstraint.constant = 36
  493. imagePopView.display()
  494. cropButton.properties = ComponentButtonProperty(type: .text_gray,
  495. size: .s,
  496. state: .normal,
  497. onlyIcon: true,
  498. icon:NSImage(named: "KMNImageNameContentCrop"),
  499. keepPressState: false)
  500. cropButton.setTarget(self, action: #selector(cropImageButtonClicked(_ :)))
  501. replaceButton.properties = ComponentButtonProperty(type: .text_gray,
  502. size: .s,
  503. state: .normal,
  504. onlyIcon: true,
  505. icon:NSImage(named: "KMNImageNameContentReplace"),
  506. keepPressState: false)
  507. replaceButton.setTarget(self, action: #selector(replaceImageButtonClicked(_ :)))
  508. extractButton.properties = ComponentButtonProperty(type: .text_gray,
  509. size: .s,
  510. state: .normal,
  511. onlyIcon: true,
  512. icon:NSImage(named: "KMNImageNameContentExtract"),
  513. keepPressState: false)
  514. extractButton.setTarget(self, action: #selector(extractImageButtonClicked(_ :)))
  515. extractButton.isHidden = false
  516. }
  517. private func congfigMultpleImageUI() {
  518. rightConstraint.constant = 0
  519. imagePopView.display()
  520. cropButton.properties = ComponentButtonProperty(type: .text_gray,
  521. size: .s,
  522. state: .normal,
  523. onlyIcon: true,
  524. icon:NSImage(named: "KMNImageNameContentExtract"),
  525. keepPressState: false)
  526. cropButton.setTarget(self, action: #selector(extractImageButtonClicked(_ :)))
  527. replaceButton.properties = ComponentButtonProperty(type: .text_gray,
  528. size: .s,
  529. state: .normal,
  530. onlyIcon: true,
  531. icon:NSImage(named: "KMNImageNameContentReplace"),
  532. keepPressState: false)
  533. replaceButton.setTarget(self, action: #selector(alightButtonClicked(_ :)))
  534. extractButton.isHidden = true
  535. }
  536. func removeGroupView() {
  537. if extractGroupView != nil {
  538. extractGroupView?.removeFromSuperview()
  539. }
  540. extractButton.properties.state = .normal
  541. extractButton.reloadData()
  542. }
  543. //MARK: - Action
  544. @objc func paneButtonClicked(_ sender: NSView) {
  545. isOpenPane = !isOpenPane
  546. paneCallback?(isOpenPane)
  547. }
  548. @objc func fontBoldButtonClicked(_ sender: NSView) {
  549. listView?.setEditingTextarea_Bold()
  550. updatePDFViewCallback?()
  551. let textEditAreas = listView?.km_editingTextAreas()
  552. let newBolds:[Bool] = listView?.km_editTextAreasFontBolds(textEditAreas ?? []) ?? []
  553. if newBolds.first == false {
  554. fontBoldSelectorItem.properties.state = .normal
  555. fontBoldSelectorItem.reloadData()
  556. }
  557. }
  558. @objc func fontItalicButtonClicked(_ sender: NSView) {
  559. listView?.setEditingTextarea_Italic()
  560. updatePDFViewCallback?()
  561. let textEditAreas = listView?.km_editingTextAreas()
  562. let newItalics:[Bool] = listView?.km_editTextAreasFontItalics(textEditAreas ?? []) ?? []
  563. if newItalics.first == false {
  564. fontItalicSelectorItem.properties.state = .normal
  565. fontItalicSelectorItem.reloadData()
  566. }
  567. }
  568. @objc func fontUnderLineButtonClicked(_ sender: NSView) {
  569. listView?.setEditingTextarea_Under()
  570. updatePDFViewCallback?()
  571. let textEditAreas = listView?.km_editingTextAreas()
  572. let newUnders:[Bool] = listView?.km_editTextAreasFontUnder(textEditAreas ?? []) ?? []
  573. if newUnders.first == false {
  574. fontUnderLineSelectorItem.properties.state = .normal
  575. fontUnderLineSelectorItem.reloadData()
  576. }
  577. }
  578. @objc func fontStrikeoutLineButtonClicked(_ sender: NSView) {
  579. listView?.setEditingTextarea_Strikeout()
  580. updatePDFViewCallback?()
  581. let textEditAreas = listView?.km_editingTextAreas()
  582. let newStrikeouts:[Bool] = listView?.km_editTextAreasFontStrikeout(textEditAreas ?? []) ?? []
  583. if newStrikeouts.first == false {
  584. fontStrikeoutLineSelectorItem.properties.state = .normal
  585. fontStrikeoutLineSelectorItem.reloadData()
  586. }
  587. }
  588. @objc func fontSizeZoomOutButtonClicked(_ sender: NSView) {
  589. listView?.zoomOutEditTextFontSize()
  590. updatePDFViewCallback?()
  591. }
  592. @objc func fontSizeZoomInButtonClicked(_ sender: NSView) {
  593. listView?.zoomInEditTextFontSize()
  594. updatePDFViewCallback?()
  595. }
  596. @objc func alightButtonClicked(_ sender: NSView) {
  597. if ObjectPopover?.isShown == true {
  598. ObjectPopover?.close()
  599. } else {
  600. let vc = KMNPopDetailsViewController(nibName: "KMNPopDetailsViewController", bundle: nil)
  601. let createFilePopover: NSPopover = NSPopover.init()
  602. createFilePopover.contentViewController = vc
  603. createFilePopover.delegate = self
  604. createFilePopover.animates = true
  605. createFilePopover.behavior = .semitransient
  606. createFilePopover.setValue(true, forKey: "shouldHideAnchor")
  607. createFilePopover.show(relativeTo: CGRect(x: sender.bounds.origin.x, y: 20, width: sender.bounds.size.width, height: sender.bounds.size.height), of: sender, preferredEdge: .maxY)
  608. if (editContentPopMode.editAreas.count == 2) {
  609. vc.detailPopType = .doubleObjectAlight
  610. } else if (editContentPopMode.editAreas.count > 2) {
  611. vc.detailPopType = .multpleObjectAlight
  612. }
  613. vc.objectChangeAlighCallback = { [weak self] alight in
  614. self?.objectAlign = alight
  615. self?.updatePDFViewCallback?()
  616. }
  617. ObjectPopover = createFilePopover
  618. vc.objectAlignType = objectAlign
  619. }
  620. }
  621. @objc func fontAlightButtonClicked(_ sender: NSView) {
  622. if fontPopover?.isShown == true {
  623. fontPopover?.close()
  624. } else {
  625. let vc = KMNPopDetailsViewController(nibName: "KMNPopDetailsViewController", bundle: nil)
  626. let createFilePopover: NSPopover = NSPopover.init()
  627. createFilePopover.contentViewController = vc
  628. createFilePopover.delegate = self
  629. createFilePopover.animates = true
  630. createFilePopover.behavior = .semitransient
  631. createFilePopover.setValue(true, forKey: "shouldHideAnchor")
  632. createFilePopover.show(relativeTo: CGRect(x: sender.bounds.origin.x, y: 20, width: sender.bounds.size.width, height: sender.bounds.size.height), of: sender, preferredEdge: .maxY)
  633. vc.detailPopType = .contentEditAlight
  634. vc.fontChangeAlighCallback = { [weak self] alight in
  635. self?.listView?.setEditingTextarea_Alignment(align: .right)
  636. self?.fontAlight = alight
  637. self?.updatePDFViewCallback?()
  638. }
  639. fontPopover = createFilePopover
  640. vc.fontAlight = fontAlight
  641. }
  642. }
  643. @objc func rotateLeftButtonClicked(_ sender: NSView) {
  644. listView?.rightRotateAction()
  645. updatePDFViewCallback?()
  646. }
  647. @objc func rotateRightButtonClicked(_ sender: NSView) {
  648. listView?.leftRotateAction()
  649. updatePDFViewCallback?()
  650. }
  651. @objc func horizontalMirrorButtonClicked(_ sender: NSView) {
  652. listView?.reverseYAction()
  653. updatePDFViewCallback?()
  654. }
  655. @objc func verticalMirrorButtonClicked(_ sender: NSView) {
  656. listView?.reverseXAction()
  657. updatePDFViewCallback?()
  658. }
  659. @objc func cropImageButtonClicked(_ sender: NSView) {
  660. listView?.cropAction()
  661. }
  662. @objc func replaceImageButtonClicked(_ sender: NSView) {
  663. listView?.replaceImageEdit()
  664. updatePDFViewCallback?()
  665. }
  666. @objc func extractImageButtonClicked(_ sender: NSView) {
  667. if extractGroupView?.superview != nil {
  668. removeGroupView()
  669. } else {
  670. var viewHeight: CGFloat = 8
  671. var menuItemArr: [ComponentMenuitemProperty] = []
  672. for i in ["jpg", "png", "pdf"] {
  673. let properties_Menuitem: ComponentMenuitemProperty = ComponentMenuitemProperty(multipleSelect: false,
  674. itemSelected: false,
  675. isDisabled: false,
  676. keyEquivalent: nil,
  677. text: KMLocalizedString(i))
  678. menuItemArr.append(properties_Menuitem)
  679. viewHeight += 36
  680. }
  681. if extractGroupView == nil {
  682. extractGroupView = ComponentGroup.createFromNib(in: ComponentLibrary.shared.componentBundle())
  683. }
  684. extractGroupView?.groupDelegate = self
  685. extractGroupView?.frame = CGRectMake(310, 0, 72, viewHeight)
  686. extractGroupView?.updateGroupInfo(menuItemArr)
  687. var point = CGPoint(x: sender.frame.origin.x + sender.frame.size.width/2, y: CGRectGetMaxY(sender.frame))
  688. extractGroupView?.showWithPoint(point, relativeTo: self.window?.contentView)
  689. extractButton.properties.state = .pressed
  690. extractButton.reloadData()
  691. }
  692. }
  693. @objc func cropRestClicked(_ sender: NSView) {
  694. listView?.cropRestAction()
  695. }
  696. @objc func cropSureClicked(_ sender: NSView) {
  697. listView?.cropComfirmAction()
  698. }
  699. @objc func fontColorChange(_ sender: Any) {
  700. if let color = (sender as? NSColorPanel)?.color {
  701. listView?.changeEditingTextarea_Color(color: color)
  702. updatePDFViewCallback?()
  703. }
  704. }
  705. }
  706. //MARK: - ComponentCColorDelegate
  707. extension KMNPopContentEditWindowController: ComponentCColorDelegate {
  708. func componentCColorDidChooseColor(_ view: NSView, _ color: NSColor?) {
  709. if (view == fontColorItem) {
  710. fontColorItem.properties?.state = .normal
  711. fontColorItem.reloadData()
  712. let colorPanel = NSColorPanel.shared
  713. colorPanel.setTarget(self)
  714. colorPanel.showsAlpha = false
  715. colorPanel.setAction(#selector(self.fontColorChange(_:)))
  716. colorPanel.orderFront(nil)
  717. }
  718. }
  719. }
  720. //MARK: - ComponentSelectDelegate
  721. extension KMNPopContentEditWindowController: ComponentSelectDelegate {
  722. func componentSelectDidSelect(view: ComponentSelect?, menuItemProperty: ComponentMenuitemProperty?) {
  723. if(view == fontNameSelect) {
  724. if menuItemProperty?.identifier == "1" {
  725. let familyName = fontNameSelect.properties.text ?? "Helvetica"
  726. let styles = CPDFFont.fontNames(forFamilyName: familyName)
  727. compdfFont = CPDFFont(familyName: familyName, fontStyle: styles.first ?? "")
  728. listView?.setEditingTextarea_font(font: compdfFont ?? CPDFFont(familyName: "Helvetica", fontStyle: ""))
  729. } else if menuItemProperty?.identifier == "2" { //字体样式
  730. compdfFont = CPDFFont(familyName: compdfFont?.familyName ?? "Helvetica", fontStyle: menuItemProperty?.text ?? "")
  731. listView?.setEditingTextarea_font(font: compdfFont ?? CPDFFont(familyName: "Helvetica", fontStyle: ""))
  732. }
  733. }
  734. }
  735. }
  736. //MARK: - ComponentSelectDelegate
  737. extension KMNPopContentEditWindowController: NSPopoverDelegate {
  738. func popoverWillClose(_ notification: Notification) {
  739. if fontPopover == (notification.object as? NSPopover) {
  740. if(fontAlightButton.properties.state == .pressed) {
  741. fontAlightButton.properties.state = .normal
  742. fontAlightButton.reloadData()
  743. }
  744. } else if ObjectPopover == (notification.object as? NSPopover) {
  745. if(alightButton.properties.state == .pressed) {
  746. alightButton.properties.state = .normal
  747. alightButton.reloadData()
  748. }
  749. }
  750. }
  751. }
  752. extension KMNPopContentEditWindowController: ComponentGroupDelegate {
  753. func componentGroupDidDismiss(group: ComponentGroup?) {
  754. removeGroupView()
  755. extractButton.properties.state = .normal
  756. extractButton.reloadData()
  757. }
  758. func componentGroupDidSelect(group: ComponentGroup?, menuItemProperty: ComponentMenuitemProperty?) {
  759. if group == extractGroupView {
  760. if let selItem = menuItemProperty {
  761. let index = group?.menuItemArr.firstIndex(of: selItem)
  762. if index == 0 {
  763. listView?.exportEditingImageAreasAction(format: "jpg")
  764. } else if index == 1 {
  765. listView?.exportEditingImageAreasAction(format: "png")
  766. } else if index == 2 {
  767. listView?.exportEditingImageAreasAction(format: "pdf")
  768. }
  769. }
  770. }
  771. }
  772. }