KMNPopContentEditWindowController.swift 40 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902
  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 = 49.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. }
  265. }
  266. private var isUnderLine:Bool = false {
  267. didSet {
  268. }
  269. }
  270. static let shared: KMNPopContentEditWindowController = {
  271. let windowC = KMNPopContentEditWindowController(windowNibName: "KMNPopContentEditWindowController")
  272. return windowC
  273. }()
  274. var paneCallback: PaneCallback?
  275. var updatePDFViewCallback: UpdatePDFViewCallback?
  276. @IBOutlet weak var contentBox: NSBox!
  277. @IBOutlet weak var operationBox: NSBox!
  278. @IBOutlet weak var paneBox: NSBox!
  279. @IBOutlet weak var lineBox: NSBox!
  280. @IBOutlet var paneSelectorItem: ComponentCSelectorItem!
  281. @IBOutlet weak var operationWidthConstraint: NSLayoutConstraint!
  282. @IBOutlet weak var rightOffsetConstraint: NSLayoutConstraint!
  283. @IBOutlet var textPopView: NSView!
  284. @IBOutlet var fontColorItem: ComponentCColorItem!
  285. @IBOutlet var fontNameSelect: ComponentSelect!
  286. @IBOutlet var fontBoldSelectorItem: ComponentCSelector!
  287. @IBOutlet var fontItalicSelectorItem: ComponentCSelector!
  288. @IBOutlet var fontSizeZoomOutButton: ComponentButton!
  289. @IBOutlet var fontSizeZoomInButton: ComponentButton!
  290. @IBOutlet var fontAlightButton: ComponentButton!
  291. @IBOutlet var imagePopView: NSView!
  292. @IBOutlet var rotaLeftButton: ComponentButton!
  293. @IBOutlet var rotaRightButton: ComponentButton!
  294. @IBOutlet var horizontalMirrorButton: ComponentButton!
  295. @IBOutlet var verticalMirrorButton: ComponentButton!
  296. @IBOutlet var cropButton: ComponentButton!
  297. @IBOutlet var replaceButton: ComponentButton!
  298. @IBOutlet var extractButton: ComponentButton!
  299. @IBOutlet weak var rightConstraint: NSLayoutConstraint!
  300. @IBOutlet var alightView: NSView!
  301. @IBOutlet var alightButton: ComponentButton!
  302. @IBOutlet var cropPopView: NSView!
  303. @IBOutlet var cropSureButton: ComponentButton!
  304. @IBOutlet var cropRestButton: ComponentButton!
  305. private var extractGroupView: ComponentGroup?
  306. weak var listView: CPDFListView?
  307. private var fontPopover:NSPopover?
  308. private var ObjectPopover:NSPopover?
  309. override func windowDidLoad() {
  310. super.windowDidLoad()
  311. }
  312. override func initContentView() {
  313. super.initContentView()
  314. paneSelectorItem.properties = ComponentCSelectorProperty(iconImage:NSImage(named: "KMNImageNameListViewPopPane"))
  315. paneSelectorItem.setTarget(self, action: #selector(paneButtonClicked(_ :)))
  316. fontBoldSelectorItem.properties = ComponentCSelectorProperty(
  317. iconImage:NSImage(named: "KMNImageNameContentBold"))
  318. fontBoldSelectorItem.setTarget(self, action: #selector(fontBoldButtonClicked(_ :)))
  319. fontItalicSelectorItem.properties = ComponentCSelectorProperty(
  320. iconImage:NSImage(named: "KMNImageNameContentItalic"))
  321. fontItalicSelectorItem.setTarget(self, action: #selector(fontItalicButtonClicked(_ :)))
  322. fontSizeZoomOutButton.properties = ComponentButtonProperty(type: .text_gray,
  323. size: .s,
  324. state: .normal,
  325. onlyIcon: true,
  326. icon:NSImage(named: "KMNImageNameListViewPopFontSizeZoomOut"),
  327. keepPressState: false)
  328. fontSizeZoomOutButton.setTarget(self, action: #selector(fontSizeZoomOutButtonClicked(_ :)))
  329. fontSizeZoomInButton.properties = ComponentButtonProperty(type: .text_gray,
  330. size: .s,
  331. state: .normal,
  332. onlyIcon: true,
  333. icon:NSImage(named: "KMNImageNameListViewPopFontSizeZoomIn"),
  334. keepPressState: false)
  335. fontSizeZoomInButton.setTarget(self, action: #selector(fontSizeZoomInButtonClicked(_ :)))
  336. fontColorItem.properties = ComponentCColorProperty(colorType: .color, state: .normal, isCustom: false, color: .clear)
  337. fontColorItem.delegate = self
  338. fontAlightButton.properties = ComponentButtonProperty(type: .text_gray,
  339. size: .s,
  340. state: .normal,
  341. onlyIcon: true,
  342. icon:NSImage(named: "KMNImageNameListViewPopAlightLeft"),
  343. keepPressState: false)
  344. fontAlightButton.setTarget(self, action: #selector(fontAlightButtonClicked(_ :)))
  345. rotaLeftButton.properties = ComponentButtonProperty(type: .text_gray,
  346. size: .s,
  347. state: .normal,
  348. onlyIcon: true,
  349. icon:NSImage(named: "KMNImageNameContentRotateLeft"),
  350. keepPressState: false)
  351. rotaLeftButton.setTarget(self, action: #selector(rotateLeftButtonClicked(_ :)))
  352. rotaRightButton.properties = ComponentButtonProperty(type: .text_gray,
  353. size: .s,
  354. state: .normal,
  355. onlyIcon: true,
  356. icon:NSImage(named: "KMNImageNameContentRotateRight"),
  357. keepPressState: false)
  358. rotaRightButton.setTarget(self, action: #selector(rotateRightButtonClicked(_ :)))
  359. horizontalMirrorButton.properties = ComponentButtonProperty(type: .text_gray,
  360. size: .s,
  361. state: .normal,
  362. onlyIcon: true,
  363. icon:NSImage(named: "KMNImageNameContentHorMirr"),
  364. keepPressState: false)
  365. horizontalMirrorButton.setTarget(self, action: #selector(horizontalMirrorButtonClicked(_ :)))
  366. verticalMirrorButton.properties = ComponentButtonProperty(type: .text_gray,
  367. size: .s,
  368. state: .normal,
  369. onlyIcon: true,
  370. icon:NSImage(named: "KMNImageNameContentVerMirr"),
  371. keepPressState: false)
  372. verticalMirrorButton.setTarget(self, action: #selector(verticalMirrorButtonClicked(_ :)))
  373. alightButton.properties = ComponentButtonProperty(type: .text_gray,
  374. size: .s,
  375. state: .normal,
  376. onlyIcon: true,
  377. icon:NSImage(named: "KMNImageNameObjectPopAlightLeft"))
  378. alightButton.setTarget(self, action: #selector(alightButtonClicked(_ :)))
  379. cropRestButton.properties = ComponentButtonProperty(type: .text_gray,
  380. size: .s,
  381. state: .normal,
  382. onlyIcon: true,
  383. icon:NSImage(named: "KMNImageNameContentCropRest"),keepPressState: false)
  384. cropRestButton.setTarget(self, action: #selector(cropRestClicked(_ :)))
  385. cropSureButton.properties = ComponentButtonProperty(type: .text_gray,
  386. size: .s,
  387. state: .normal,
  388. onlyIcon: true,
  389. icon:NSImage(named: "KMNImageNameContentCropSure"),keepPressState: false)
  390. cropSureButton.setTarget(self, action: #selector(cropSureClicked(_ :)))
  391. }
  392. override func updateUIThemeColor() {
  393. super.updateUIThemeColor()
  394. lineBox.fillColor = ComponentLibrary.shared.getComponentColorFromKey("colorBorder/divider")
  395. contentBox.fillColor = ComponentLibrary.shared.getComponentColorFromKey("colorBg/popup")
  396. contentBox.borderColor = ComponentLibrary.shared.getComponentColorFromKey("colorBorder/3-default")
  397. }
  398. override func updateUILanguage() {
  399. super.updateUILanguage()
  400. }
  401. //MARK: - Public
  402. public func updateFrame(listView:CPDFListView) {
  403. let editingAreas = listView.km_EditingAreas()
  404. let page = editingAreas.first?.page
  405. let windowFram = listView.window?.frame ?? CGRectZero
  406. if(page != nil) {
  407. let pageRect = listView.selectionMultipleBounds(withEditArea: editingAreas)
  408. let positioningRect = listView.convert(pageRect, from: page!)
  409. let view: NSView? = nil
  410. let position = listView.convert(positioningRect, to: view)
  411. var positionNew = position.origin
  412. positionNew.x += windowFram.origin.x + position.width/2
  413. positionNew.y += windowFram.origin.y + position.height
  414. var positionRect = self.window?.frame ?? CGRectZero
  415. positionRect.origin.x = positionNew.x - positionRect.width/2
  416. positionRect.origin.y = positionNew.y + popOffSet + CGFloat(truncating: listView.editingConfig().editAreaMargin)
  417. var listViewWindRect = listView.convert(listView.frame, to: view)
  418. listViewWindRect.origin.x += windowFram.origin.x
  419. listViewWindRect.origin.y += windowFram.origin.y
  420. if CGRectGetMaxY(positionRect) > CGRectGetMaxY(listViewWindRect) {
  421. positionRect.origin.y = positionNew.y - popOffSet - position.height - positionRect.size.height
  422. }
  423. if CGRectGetMinX(positionRect) < CGRectGetMinX(listViewWindRect) {
  424. positionRect.origin.x = CGRectGetMinX(listViewWindRect)
  425. }
  426. if CGRectGetMaxX(positionRect) > CGRectGetMaxX(listViewWindRect) {
  427. positionRect.origin.x = CGRectGetMaxX(listViewWindRect) - positionRect.width
  428. }
  429. self.window?.setFrame(positionRect, display: true)
  430. updateUILanguage()
  431. }
  432. }
  433. public func closeWindow(listView:CPDFListView?) {
  434. if self.window?.isVisible == true {
  435. listView?.window?.removeChildWindow(self.window ?? NSWindow())
  436. self.window?.close()
  437. }
  438. if ObjectPopover?.isShown == true {
  439. ObjectPopover?.close()
  440. }
  441. if fontPopover?.isShown == true {
  442. fontPopover?.close()
  443. }
  444. }
  445. //MARK: - private
  446. private func congfigFontPopUI() {
  447. fontNameSelect.properties = ComponentSelectProperties(size: .s,
  448. state: .normal,
  449. isDisabled: false,
  450. isError: false,
  451. leftIcon: false,
  452. placeholder: nil,
  453. errorText: nil,
  454. creatable: false,
  455. text: NSLocalizedString("", comment: ""))
  456. fontNameSelect.delegate = self
  457. var menuItemArr: [ComponentMenuitemProperty] = []
  458. for familyName in CPDFFont.familyNames {
  459. let fontNames = CPDFFont.fontNames(forFamilyName: familyName)
  460. let itemProperty: ComponentMenuitemProperty = ComponentMenuitemProperty(multipleSelect: false,
  461. itemSelected: false,
  462. isDisabled: false,
  463. keyEquivalent: nil,
  464. text: familyName,
  465. identifier: "1")
  466. var subMenuItemArr: [ComponentMenuitemProperty] = []
  467. for fontName in fontNames {
  468. let subItemProperty: ComponentMenuitemProperty = ComponentMenuitemProperty(multipleSelect: false,
  469. itemSelected: false,
  470. isDisabled: false,
  471. keyEquivalent: nil,
  472. text: fontName,identifier: "2")
  473. subMenuItemArr.append(subItemProperty)
  474. }
  475. itemProperty.subPropertys = subMenuItemArr
  476. menuItemArr.append(itemProperty)
  477. }
  478. fontNameSelect.updateMenuItemsArr(menuItemArr)
  479. }
  480. private func congfigSignImageUI() {
  481. rightConstraint.constant = 36
  482. imagePopView.display()
  483. cropButton.properties = ComponentButtonProperty(type: .text_gray,
  484. size: .s,
  485. state: .normal,
  486. onlyIcon: true,
  487. icon:NSImage(named: "KMNImageNameContentCrop"),
  488. keepPressState: false)
  489. cropButton.setTarget(self, action: #selector(cropImageButtonClicked(_ :)))
  490. replaceButton.properties = ComponentButtonProperty(type: .text_gray,
  491. size: .s,
  492. state: .normal,
  493. onlyIcon: true,
  494. icon:NSImage(named: "KMNImageNameContentReplace"),
  495. keepPressState: false)
  496. replaceButton.setTarget(self, action: #selector(replaceImageButtonClicked(_ :)))
  497. extractButton.properties = ComponentButtonProperty(type: .text_gray,
  498. size: .s,
  499. state: .normal,
  500. onlyIcon: true,
  501. icon:NSImage(named: "KMNImageNameContentExtract"),
  502. keepPressState: false)
  503. extractButton.setTarget(self, action: #selector(extractImageButtonClicked(_ :)))
  504. extractButton.isHidden = false
  505. }
  506. private func congfigMultpleImageUI() {
  507. rightConstraint.constant = 0
  508. imagePopView.display()
  509. cropButton.properties = ComponentButtonProperty(type: .text_gray,
  510. size: .s,
  511. state: .normal,
  512. onlyIcon: true,
  513. icon:NSImage(named: "KMNImageNameContentExtract"),
  514. keepPressState: false)
  515. cropButton.setTarget(self, action: #selector(extractImageButtonClicked(_ :)))
  516. replaceButton.properties = ComponentButtonProperty(type: .text_gray,
  517. size: .s,
  518. state: .normal,
  519. onlyIcon: true,
  520. icon:NSImage(named: "KMNImageNameContentReplace"),
  521. keepPressState: false)
  522. replaceButton.setTarget(self, action: #selector(alightButtonClicked(_ :)))
  523. extractButton.isHidden = true
  524. }
  525. func removeGroupView() {
  526. if extractGroupView != nil {
  527. extractGroupView?.removeFromSuperview()
  528. }
  529. extractButton.properties.state = .normal
  530. extractButton.reloadData()
  531. }
  532. //MARK: - Action
  533. @objc func paneButtonClicked(_ sender: NSView) {
  534. isOpenPane = !isOpenPane
  535. paneCallback?(isOpenPane)
  536. }
  537. @objc func fontBoldButtonClicked(_ sender: NSView) {
  538. listView?.setEditingTextarea_Bold()
  539. updatePDFViewCallback?()
  540. let textEditAreas = listView?.km_editingTextAreas()
  541. let newBolds:[Bool] = listView?.km_editTextAreasFontBolds(textEditAreas ?? []) ?? []
  542. if newBolds.first == false {
  543. fontBoldSelectorItem.properties.state = .normal
  544. fontBoldSelectorItem.reloadData()
  545. }
  546. }
  547. @objc func fontItalicButtonClicked(_ sender: NSView) {
  548. listView?.setEditingTextarea_Italic()
  549. updatePDFViewCallback?()
  550. let textEditAreas = listView?.km_editingTextAreas()
  551. let newItalics:[Bool] = listView?.km_editTextAreasFontItalics(textEditAreas ?? []) ?? []
  552. if newItalics.first == false {
  553. fontItalicSelectorItem.properties.state = .normal
  554. fontItalicSelectorItem.reloadData()
  555. }
  556. }
  557. @objc func fontUnderLineButtonClicked(_ sender: NSView) {
  558. listView?.setEditingTextarea_Under()
  559. updatePDFViewCallback?()
  560. let textEditAreas = listView?.km_editingTextAreas()
  561. let newUnders:[Bool] = listView?.km_editTextAreasFontUnder(textEditAreas ?? []) ?? []
  562. }
  563. @objc func fontStrikeoutLineButtonClicked(_ sender: NSView) {
  564. listView?.setEditingTextarea_Strikeout()
  565. updatePDFViewCallback?()
  566. let textEditAreas = listView?.km_editingTextAreas()
  567. let newStrikeouts:[Bool] = listView?.km_editTextAreasFontStrikeout(textEditAreas ?? []) ?? []
  568. }
  569. @objc func fontSizeZoomOutButtonClicked(_ sender: NSView) {
  570. listView?.zoomOutEditTextFontSize()
  571. updatePDFViewCallback?()
  572. }
  573. @objc func fontSizeZoomInButtonClicked(_ sender: NSView) {
  574. listView?.zoomInEditTextFontSize()
  575. updatePDFViewCallback?()
  576. }
  577. @objc func alightButtonClicked(_ sender: NSView) {
  578. if ObjectPopover?.isShown == true {
  579. ObjectPopover?.close()
  580. } else {
  581. let vc = KMNPopDetailsViewController(nibName: "KMNPopDetailsViewController", bundle: nil)
  582. let createFilePopover: NSPopover = NSPopover.init()
  583. createFilePopover.contentViewController = vc
  584. createFilePopover.delegate = self
  585. createFilePopover.animates = true
  586. createFilePopover.behavior = .semitransient
  587. createFilePopover.setValue(true, forKey: "shouldHideAnchor")
  588. 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)
  589. if (editContentPopMode.editAreas.count == 2) {
  590. vc.detailPopType = .doubleObjectAlight
  591. } else if (editContentPopMode.editAreas.count > 2) {
  592. vc.detailPopType = .multpleObjectAlight
  593. }
  594. vc.objectChangeAlighCallback = { [weak self] alight in
  595. self?.objectAlign = alight
  596. self?.updatePDFViewCallback?()
  597. }
  598. ObjectPopover = createFilePopover
  599. vc.objectAlignType = objectAlign
  600. }
  601. }
  602. @objc func fontAlightButtonClicked(_ sender: NSView) {
  603. if fontPopover?.isShown == true {
  604. fontPopover?.close()
  605. } else {
  606. let vc = KMNPopDetailsViewController(nibName: "KMNPopDetailsViewController", bundle: nil)
  607. let createFilePopover: NSPopover = NSPopover.init()
  608. createFilePopover.contentViewController = vc
  609. createFilePopover.delegate = self
  610. createFilePopover.animates = true
  611. createFilePopover.behavior = .semitransient
  612. createFilePopover.setValue(true, forKey: "shouldHideAnchor")
  613. 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)
  614. vc.detailPopType = .contentEditAlight
  615. vc.fontChangeAlighCallback = { [weak self] alight in
  616. self?.listView?.setEditingTextarea_Alignment(align: alight)
  617. self?.fontAlight = alight
  618. self?.updatePDFViewCallback?()
  619. }
  620. fontPopover = createFilePopover
  621. vc.fontAlight = fontAlight
  622. }
  623. }
  624. @objc func rotateLeftButtonClicked(_ sender: NSView) {
  625. listView?.leftRotateAction()
  626. updatePDFViewCallback?()
  627. }
  628. @objc func rotateRightButtonClicked(_ sender: NSView) {
  629. listView?.rightRotateAction()
  630. updatePDFViewCallback?()
  631. }
  632. @objc func horizontalMirrorButtonClicked(_ sender: NSView) {
  633. listView?.reverseYAction()
  634. updatePDFViewCallback?()
  635. }
  636. @objc func verticalMirrorButtonClicked(_ sender: NSView) {
  637. listView?.reverseXAction()
  638. updatePDFViewCallback?()
  639. }
  640. @objc func cropImageButtonClicked(_ sender: NSView) {
  641. listView?.cropAction()
  642. }
  643. @objc func replaceImageButtonClicked(_ sender: NSView) {
  644. listView?.replaceImageEdit()
  645. updatePDFViewCallback?()
  646. }
  647. @objc func extractImageButtonClicked(_ sender: NSView) {
  648. if extractGroupView?.superview != nil {
  649. removeGroupView()
  650. } else {
  651. var viewHeight: CGFloat = 8
  652. var menuItemArr: [ComponentMenuitemProperty] = []
  653. for i in ["jpg", "png", "pdf"] {
  654. let properties_Menuitem: ComponentMenuitemProperty = ComponentMenuitemProperty(multipleSelect: false,
  655. itemSelected: false,
  656. isDisabled: false,
  657. keyEquivalent: nil,
  658. text: KMLocalizedString(i))
  659. menuItemArr.append(properties_Menuitem)
  660. viewHeight += 36
  661. }
  662. if extractGroupView == nil {
  663. extractGroupView = ComponentGroup.createFromNib(in: ComponentLibrary.shared.componentBundle())
  664. }
  665. extractGroupView?.groupDelegate = self
  666. extractGroupView?.frame = CGRectMake(310, 0, 72, viewHeight)
  667. extractGroupView?.updateGroupInfo(menuItemArr)
  668. var point = CGPoint(x: sender.frame.origin.x + sender.frame.size.width/2, y: CGRectGetMaxY(sender.frame))
  669. extractGroupView?.showWithPoint(point, relativeTo: self.window?.contentView)
  670. extractButton.properties.state = .pressed
  671. extractButton.reloadData()
  672. }
  673. }
  674. @objc func cropRestClicked(_ sender: NSView) {
  675. listView?.cropRestAction()
  676. }
  677. @objc func cropSureClicked(_ sender: NSView) {
  678. listView?.cropComfirmAction()
  679. }
  680. @objc func fontColorChange(_ sender: Any) {
  681. if let color = (sender as? NSColorPanel)?.color {
  682. listView?.changeEditingTextarea_Color(color: color)
  683. updatePDFViewCallback?()
  684. }
  685. }
  686. }
  687. //MARK: - ComponentCColorDelegate
  688. extension KMNPopContentEditWindowController: ComponentCColorDelegate {
  689. func componentCColorDidChooseColor(_ view: NSView, _ color: NSColor?) {
  690. if (view == fontColorItem) {
  691. fontColorItem.properties?.state = .normal
  692. fontColorItem.reloadData()
  693. let colorPanel = NSColorPanel.shared
  694. colorPanel.setTarget(self)
  695. colorPanel.showsAlpha = false
  696. colorPanel.setAction(#selector(self.fontColorChange(_:)))
  697. colorPanel.orderFront(nil)
  698. }
  699. }
  700. }
  701. //MARK: - ComponentSelectDelegate
  702. extension KMNPopContentEditWindowController: ComponentSelectDelegate {
  703. func componentSelectDidSelect(view: ComponentSelect?, menuItemProperty: ComponentMenuitemProperty?) {
  704. if(view == fontNameSelect) {
  705. if menuItemProperty?.identifier == "1" {
  706. let familyName = fontNameSelect.properties.text ?? "Helvetica"
  707. let styles = CPDFFont.fontNames(forFamilyName: familyName)
  708. compdfFont = CPDFFont(familyName: familyName, fontStyle: styles.first ?? "")
  709. listView?.setEditingTextarea_font(font: compdfFont ?? CPDFFont(familyName: "Helvetica", fontStyle: ""))
  710. } else if menuItemProperty?.identifier == "2" { //字体样式
  711. compdfFont = CPDFFont(familyName: compdfFont?.familyName ?? "Helvetica", fontStyle: menuItemProperty?.text ?? "")
  712. listView?.setEditingTextarea_font(font: compdfFont ?? CPDFFont(familyName: "Helvetica", fontStyle: ""))
  713. }
  714. }
  715. }
  716. }
  717. //MARK: - ComponentSelectDelegate
  718. extension KMNPopContentEditWindowController: NSPopoverDelegate {
  719. func popoverWillClose(_ notification: Notification) {
  720. if fontPopover == (notification.object as? NSPopover) {
  721. if(fontAlightButton.properties.state == .pressed) {
  722. fontAlightButton.properties.state = .normal
  723. fontAlightButton.reloadData()
  724. }
  725. } else if ObjectPopover == (notification.object as? NSPopover) {
  726. if(alightButton.properties.state == .pressed) {
  727. alightButton.properties.state = .normal
  728. alightButton.reloadData()
  729. }
  730. }
  731. }
  732. }
  733. extension KMNPopContentEditWindowController: ComponentGroupDelegate {
  734. func componentGroupDidDismiss(group: ComponentGroup?) {
  735. removeGroupView()
  736. extractButton.properties.state = .normal
  737. extractButton.reloadData()
  738. }
  739. func componentGroupDidSelect(group: ComponentGroup?, menuItemProperty: ComponentMenuitemProperty?) {
  740. if group == extractGroupView {
  741. if let selItem = menuItemProperty {
  742. let index = group?.menuItemArr.firstIndex(of: selItem)
  743. if index == 0 {
  744. listView?.exportEditingImageAreasAction(format: "jpg")
  745. } else if index == 1 {
  746. listView?.exportEditingImageAreasAction(format: "png")
  747. } else if index == 2 {
  748. listView?.exportEditingImageAreasAction(format: "pdf")
  749. }
  750. }
  751. }
  752. }
  753. }