123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547 |
- //
- // KMEditImagePropertyViewController.swift
- // PDF Master
- //
- // Created by lxy on 2022/12/28.
- //
- import Cocoa
- class KMEditImagePropertyViewController: NSViewController {
- @IBOutlet weak var titleLabel: NSTextField!
- @IBOutlet weak var editImageView: NSImageView!
- @IBOutlet weak var opacityTitleLabel: NSTextField!
- @IBOutlet weak var opacitySlider: NSSlider!
- @IBOutlet weak var opacityPopUpButton: KMComboBox!
- @IBOutlet weak var alignTitleLabel: NSTextField!
- @IBOutlet weak var cutButton: NSButton!
- @IBOutlet weak var replaceButton: NSButton!
- @IBOutlet weak var exportButton: NSButton!
- @IBOutlet weak var headerBox: NSBox!
- @IBOutlet weak var cancelCutButton: NSButton!
- @IBOutlet weak var cutRightConstraint: NSLayoutConstraint!
- @IBOutlet weak var headerBoxHeight: NSLayoutConstraint!
- @IBOutlet weak var imageBox: NSBox!
- @IBOutlet weak var imageBoxHeight: NSLayoutConstraint!
- @IBOutlet weak var opacityBoxHeight: NSLayoutConstraint!
- @IBOutlet weak var opacityBox: NSBox!
- @IBOutlet weak var buttonBoxHeight: NSLayoutConstraint!
- @IBOutlet weak var buttonBox: NSBox!
-
- @IBOutlet weak var areasLeftButton: NSButton!
- @IBOutlet weak var areasVerticalCenterButton: NSButton!
- @IBOutlet weak var areasHorzontalButton: NSButton!
- @IBOutlet weak var areasVerticalButton: NSButton!
- @IBOutlet weak var areasBotoomButton: NSButton!
- @IBOutlet weak var areasHorizontalCenterButton: NSButton!
- @IBOutlet weak var areasTopButton: NSButton!
- @IBOutlet weak var areasRightButton: NSButton!
- let items = ["10","20","50","80","100"]
- var imagesAreas : [CPDFEditImageArea] = []
- var listView : CPDFListView!
-
- override func viewDidLoad() {
- super.viewDidLoad()
- self.updateButtonState(hidden: true)
- self.editImageView.wantsLayer = true
- self.editImageView.layer?.backgroundColor = NSColor.white.cgColor
- self.opacityPopUpButton.removeAllItems()
- for i in 0 ... items.count-1 {
- self.opacityPopUpButton.addItem(withObjectValue: "\(items[i])%")
- }
- self.opacityPopUpButton.selectItem(at:items.count-1)
-
- self.titleLabel.stringValue = NSLocalizedString("Image", comment: "")
- self.opacityTitleLabel.stringValue = NSLocalizedString("Opacity", comment: "")
- self.cutButton.title = NSLocalizedString("Crop", comment: "")
- self.cancelCutButton.title = NSLocalizedString("Cancel", comment: "")
- self.replaceButton.title = NSLocalizedString("Replace", comment: "")
- self.exportButton.title = NSLocalizedString("Extract", comment: "")
- self.alignTitleLabel.stringValue = NSLocalizedString("Align", comment: "")
-
- self.updateButtonState(hidden: true)
- self.reloadData()
- }
-
- func reloadData() {
- self.formAearsAlignIcon()
- imagesAreas = []
- if self.listView.editingAreas()?.count ?? 0 < 1 {
- return
- }
- let areas = self.listView.editingAreas()
- for i in 0 ... areas!.count-1 {
- if areas![i] is CPDFEditImageArea {
- imagesAreas.append(areas![i] as! CPDFEditImageArea)
- }
- }
- if imagesAreas.count == 1 && imagesAreas.count == areas!.count{ //单个图片
- self.listView.selectImageAreas = imagesAreas.first
- self.headerBox.isHidden = false
- self.headerBoxHeight.constant = 170
- self.imageBox.isHidden = false
- self.imageBoxHeight.constant = 90
- self.opacityBox.isHidden = false
- self.opacityBoxHeight.constant = 48
- self.buttonBox.isHidden = false
- self.cutButton.isHidden = false
- self.cancelCutButton.isHidden = false
- self.replaceButton.isHidden = false
- self.buttonBoxHeight.constant = 100
- self.editImageView.image = self.listView.selectImageAreas.thumbnailImage
- self.opacitySlider.objectValue = self.listView.opacity(for: imagesAreas.first)
- self.opacityPopUpButton.stringValue = "\(Int(self.listView.opacity(for: imagesAreas.first)*100))%"
- } else if imagesAreas.count > 1 && imagesAreas.count == areas!.count { //多选图片
- self.headerBox.isHidden = false
- self.headerBoxHeight.constant = 80
- self.imageBox.isHidden = true
- self.imageBoxHeight.constant = 0
- self.opacityBox.isHidden = false
- self.opacityBoxHeight.constant = 48
- self.buttonBox.isHidden = false
- self.cutButton.isHidden = true
- self.cancelCutButton.isHidden = true
- self.replaceButton.isHidden = true
- self.buttonBoxHeight.constant = 52
- var opacity = self.listView.opacity(for: imagesAreas.first)
- for area in imagesAreas {
- let newOpacity = self.listView.opacity(for: area)
- if (opacity < newOpacity) {
- opacity = newOpacity
- }
- }
- self.opacitySlider.objectValue = opacity
- self.opacityPopUpButton.stringValue = "\(Int(opacity)*100))%"
- } else if imagesAreas.count > 0 && imagesAreas.count != areas!.count { //多选图片跟文字
- self.headerBox.isHidden = true
- self.headerBoxHeight.constant = 0
- self.imageBox.isHidden = true
- self.imageBoxHeight.constant = 0
- self.opacityBox.isHidden = true
- self.opacityBoxHeight.constant = 0
- self.buttonBox.isHidden = true
- self.buttonBoxHeight.constant = 0
- }
- }
-
- //MARK: action
-
- @IBAction func selectOpacityAction(_ sender: KMComboBox) {
- let value = sender.indexOfItem(withObjectValue: sender.stringValue)
- if self.listView.editingAreas()?.count ?? 0 < 1 {
- return
- }
- self.updateImageAreasOpacity(opacity: Float("\(items[value])")!/100.0)
- self.opacitySlider.objectValue = Float("\(items[value])")!/100.0
- }
-
- @IBAction func updateopacitySlider(_ sender: NSSlider) {
- let value = sender.floatValue
- if self.listView.editingAreas()?.count ?? 0 < 1 {
- return
- }
- self.updateImageAreasOpacity(opacity:value)
- self.opacityPopUpButton.stringValue = "\(Int(value*100))%"
- }
-
-
- @IBAction func rightRotationImageAction(_ sender: Any) {
- if self.listView.editingAreas()?.count ?? 0 < 1 {
- return
- }
- let areas = self.listView.editingAreas()
- if areas!.count == 1 && (areas!.first is CPDFEditImageArea) {
- let imageArea = areas!.first as! CPDFEditImageArea
- self.listView.rotate(with: imageArea, rotate: 90)
- self.listView.selectImageAreas = imageArea
- self.editImageView.image = self.listView.selectImageAreas.thumbnailImage
- } else if areas!.count > 1 {
- for imagesArea in imagesAreas {
- self.listView.rotate(with: imagesArea, rotate: 90)
- }
- }
- }
-
- @IBAction func leftRotationImageAction(_ sender: Any) {
- if self.listView.editingAreas()?.count ?? 0 < 1 {
- return
- }
- let areas = self.listView.editingAreas()
- if areas!.count == 1 && (areas!.first is CPDFEditImageArea) {
- self.listView.rotate(with: self.listView.selectImageAreas, rotate: -90)
- if self.listView.editingAreas()!.count == 1 && (self.listView.editingAreas()!.first is CPDFEditImageArea) {
- self.listView.selectImageAreas = self.listView.editingAreas()!.first as! CPDFEditImageArea
- }
- self.editImageView.image = self.listView.selectImageAreas.thumbnailImage
- } else {
- for imagesArea in imagesAreas {
- self.listView.rotate(with: imagesArea, rotate: -90)
- }
- }
- }
-
- @IBAction func cutImageAction(_ sender: Any) {
- if self.listView.selectImageAreas == nil {
- return
- }
- if self.listView.cropAreas != nil && self.listView.selectImageAreas != nil{
- self.listView.cropEditImageArea(self.listView.selectImageAreas, withBounds: self.listView.cropAreas.cropRect)
- } else if self.listView.selectImageAreas != nil {
- self.listView.isEditImage = true
- self.listView.enterCrop(with: self.listView.selectImageAreas)
- self.updateButtonState(hidden: false)
- }
- }
-
- @IBAction func cancelCutImageAction(_ sender: Any) {
- if self.listView.selectImageAreas == nil {
- return
- }
- self.listView.exitCrop(with: self.listView.selectImageAreas)
- self.listView.cropAreas = nil
- self.listView.isEditImage = false
- self.updateButtonState(hidden: true)
- }
-
- @IBAction func replaceImageAction(_ sender: NSButton) {
- if self.listView.selectImageAreas == nil {
- return
- }
- let panel = NSOpenPanel()
- panel.allowsMultipleSelection = false
- panel.allowedFileTypes = ["png","jpg"]
- panel.beginSheetModal(for: NSApp.mainWindow!) { response in
- if response == .OK {
- let openPath = panel.url?.path
- // let s = self.listView.extractImage(with: self.selectImageAreas, toImagePath: openPath!)
- let s = self.listView.replace(self.listView.selectImageAreas, imagePath: openPath!)
- if s {
-
- }
- }
- }
- }
-
- @available(macOS 13.0, *)
- @IBAction func exportImageAction(_ sender: Any) {
- if self.listView.selectImageAreas == nil {
- return
- }
- if imagesAreas.count == 1 {
- let panel = NSSavePanel()
- panel.nameFieldStringValue = "\(NSLocalizedString("Untitled", comment: "")).png"
- let button = NSButton.init(checkboxWithTitle: NSLocalizedString("Open the document after saving", comment: ""), target: nil, action: nil)
- button.state = .on
- panel.accessoryView = button
- panel.isExtensionHidden = true
- let response = panel.runModal()
- if response == .OK {
- let url = panel.url
- let result = self.listView.extractImage(with: self.listView.selectImageAreas, toImagePath: url!.path)
- if result {
- if button.state == .on { /// 开启文档
- NSWorkspace.shared.openFile(url!.path)
- } else {
-
- }
- }
- }
- } else if imagesAreas.count > 1 {
- let panel = NSOpenPanel()
- panel.canChooseFiles = false
- panel.canChooseDirectories = true
- panel.canCreateDirectories = true
- panel.allowsMultipleSelection = false
- panel.beginSheetModal(for: NSApp.mainWindow!) { response in
- if response == .OK {
- let outputURL = panel.url
- let s = self.listView.document.documentURL.lastPathComponent
- let folderPath = self.listView.document.documentURL.deletingPathExtension().lastPathComponent + "_extract"
- var filePath = outputURL?.path.stringByAppendingPathComponent(folderPath)
-
- var i = 1
- let testFilePath = filePath
- while FileManager.default.fileExists(atPath: filePath!) {
- filePath = testFilePath! + "\(i)"
- i = i + 1
- }
- try? FileManager.default.createDirectory(atPath: filePath!, withIntermediateDirectories: false, attributes: nil)
- var saveURLs : [URL] = []
- for j in 0 ... self.imagesAreas.count-1 {
- let documentFileName = self.listView.document.documentURL.deletingPathExtension().lastPathComponent
- var outPath = filePath!
- outPath = outPath.stringByAppendingPathComponent(documentFileName)
- outPath = outPath + "page \(j+1)"
- outPath = outPath.stringByAppendingPathExtension("png")
- let result = self.listView.extractImage(with: self.imagesAreas[j], toImagePath: outPath)
- if result {
- saveURLs.append(URL(fileURLWithPath: outPath))
- }
- }
- NSWorkspace.shared.activateFileViewerSelecting(saveURLs)
- }
- }
- }
-
- }
- override func mouseDown(with event: NSEvent) {
-
- }
-
- //MARK: 对齐
- @IBAction func areasAlignStyleAction(_ sender: NSButton) {
- self.formAearsAlignMangent(stype: CPDFActiveAreasAlignType.init(rawValue: sender.tag) ?? .Left)
- }
-
- func updateButtonState(hidden:Bool) {
- if hidden {
- self.cancelCutButton.isHidden = true
- self.cutRightConstraint.constant = 10
- self.cutButton.title = NSLocalizedString("cut", comment: "")
- self.replaceButton.isEnabled = true
- self.exportButton.isEnabled = true
- } else {
- self.cancelCutButton.isHidden = false
- self.cutRightConstraint.constant = 80
- self.cutButton.title = NSLocalizedString("sure cut", comment: "")
- self.replaceButton.isEnabled = false
- self.exportButton.isEnabled = false
- }
- }
-
- func updateImageAreasOpacity (opacity:Float) {
- for area in imagesAreas {
- self.listView.setOpacityEditArea(area, opacity: CGFloat(opacity))
- }
- if self.listView.editingAreas()!.count == 1 && (self.listView.editingAreas()!.first is CPDFEditImageArea) {
- self.listView.selectImageAreas = self.listView.editingAreas()!.first as! CPDFEditImageArea
- self.editImageView.image = self.listView.selectImageAreas.thumbnailImage
- self.opacitySlider.objectValue = self.listView.opacity(for: self.listView.selectImageAreas)
- }
- }
-
- func formAearsAlignIcon() {
- let norIcons : [String] = ["KMImageNameEditPDFImage20","KMImageNameEditPDFImage21","KMImageNameEditPDFImage45","KMImageNameEditPDFImage46",
- "KMImageNameEditPDFImage47","KMImageNameEditPDFImage48","KMImageNameEditPDFImage49","KMImageNameEditPDFImage50"]
- let selectIcons : [String] = ["KMImageNameEditPDFImage20_1","KMImageNameEditPDFImage21_1","KMImageNameEditPDFImage45_1","KMImageNameEditPDFImage46_1",
- "KMImageNameEditPDFImage47_1","KMImageNameEditPDFImage48_1","KMImageNameEditPDFImage49_1","KMImageNameEditPDFImage50_1"]
- let areasButtons : [NSButton] = [self.areasVerticalButton,self.areasHorzontalButton,self.areasLeftButton,self.areasVerticalCenterButton,
- self.areasRightButton,self.areasTopButton,self.areasHorizontalCenterButton,self.areasBotoomButton]
- if self.listView.editingAreas()?.count ?? 0 < 2 {
- for i in 0 ... areasButtons.count-1 {
- areasButtons[i].image = NSImage(named: norIcons[i])
- }
- } else if self.listView.editingAreas()?.count ?? 0 == 2 {
- for i in 0 ... areasButtons.count-1 {
- if i == 0 || i == 1 {
- areasButtons[i].image = NSImage(named: norIcons[i])
- } else {
- areasButtons[i].image = NSImage(named: selectIcons[i])
- }
- }
- } else if self.listView.editingAreas()?.count ?? 0 > 2 {
- for i in 0 ... areasButtons.count-1 {
- areasButtons[i].image = NSImage(named: selectIcons[i])
- }
- }
- }
-
- private func formAearsAlignMangent(stype:CPDFActiveAreasAlignType) {
- if self.listView.editingAreas().count < 2 {
- return
- }
-
- var zeroRect = NSRect.null
- var highestRect = NSZeroRect
- var widthestRect = NSZeroRect
-
- let fristArea : CPDFEditArea = self.listView.editingAreas().first as! CPDFEditArea
- var leftestRect = fristArea.bounds
- var rightestRect = fristArea.bounds
- var topestRect = fristArea.bounds
- var bottomestRect = fristArea.bounds
-
- var leftestArea : CPDFEditArea = fristArea
- var rightestArea : CPDFEditArea = fristArea
- var topestArea : CPDFEditArea = fristArea
- var bottomestArea : CPDFEditArea = fristArea
-
- var totalWidth = 0.0
- var totalHeight = 0.0
-
- for i in 0 ... self.listView.editingAreas().count-1 {
- let area : CPDFEditArea = self.listView.editingAreas()[i] as! CPDFEditArea
- zeroRect = zeroRect.union(area.bounds)
- totalWidth = totalWidth + area.bounds.width
- totalHeight = totalHeight + area.bounds.height
-
- if area.bounds.height > highestRect.height {
- highestRect = area.bounds
- }
-
- if area.bounds.width > widthestRect.width {
- widthestRect = area.bounds
- }
-
- if leftestRect.minX > area.bounds.minX {
- leftestRect = area.bounds
- leftestArea = area
- }
-
- if area.bounds.maxX > rightestRect.maxX {
- rightestRect = area.bounds
- rightestArea = area
- }
-
- if area.bounds.maxY > topestRect.maxY {
- topestRect = area.bounds
- topestArea = area
- }
-
- if bottomestRect.minY > area.bounds.minY {
- bottomestRect = area.bounds
- bottomestArea = area
- }
- }
-
- if stype == .Left {
- var newBoundsArray : [String] = []
- for i in 0 ... self.listView.editingAreas().count-1 {
- let areas = self.listView.editingAreas()[i] as! CPDFEditArea
- var bounds = areas.bounds
- bounds.origin.x = zeroRect.origin.x
- newBoundsArray.append(NSStringFromRect(bounds))
- }
- self.changeAreasAlign(areas: self.listView.editingAreas(), newBounds: newBoundsArray)
- } else if stype == .Right {
- var newBounds : [String] = []
- for i in 0 ... self.listView.editingAreas().count-1 {
- let areas = self.listView.editingAreas()[i] as! CPDFEditArea
- var bounds = areas.bounds
- bounds.origin.x = zeroRect.maxX - bounds.size.width
- newBounds.append(NSStringFromRect(bounds))
- }
- self.changeAreasAlign(areas: self.listView.editingAreas(), newBounds: newBounds)
- } else if stype == .Top {
- var newBounds : [String] = []
- for i in 0 ... self.listView.editingAreas().count-1 {
- let areas = self.listView.editingAreas()[i] as! CPDFEditArea
- var bounds = areas.bounds
- bounds.origin.y = zeroRect.maxY - bounds.size.height
- newBounds.append(NSStringFromRect(bounds))
- }
- self.changeAreasAlign(areas: self.listView.editingAreas(), newBounds: newBounds)
- } else if stype == .Bottom {
- var newBounds : [String] = []
- for i in 0 ... self.listView.editingAreas().count-1 {
- let areas = self.listView.editingAreas()[i] as! CPDFEditArea
- var bounds = areas.bounds
- bounds.origin.y = zeroRect.minY
- newBounds.append(NSStringFromRect(bounds))
- }
- self.changeAreasAlign(areas: self.listView.editingAreas(), newBounds: newBounds)
- } else if stype == .Horizontally {
- var newBounds : [String] = []
- for i in 0 ... self.listView.editingAreas().count-1 {
- let areas = self.listView.editingAreas()[i] as! CPDFEditArea
- var bounds = areas.bounds
- bounds.origin.y = highestRect.midY - bounds.height/2
- newBounds.append(NSStringFromRect(bounds))
- }
- self.changeAreasAlign(areas: self.listView.editingAreas(), newBounds: newBounds)
- } else if stype == .Vertical {
- var newBounds : [String] = []
- for i in 0 ... self.listView.editingAreas().count-1 {
- let areas = self.listView.editingAreas()[i] as! CPDFEditArea
- var bounds = areas.bounds
- bounds.origin.x = widthestRect.midX - bounds.width/2
- newBounds.append(NSStringFromRect(bounds))
- }
- self.changeAreasAlign(areas: self.listView.editingAreas(), newBounds: newBounds)
- } else if stype == .DisHorizontally {
- let middleGap = zeroRect.width - leftestRect.width - rightestRect.width
- let otherAreasTotalWidth = totalWidth - leftestRect.width - rightestRect.width
-
- let gap = (middleGap - otherAreasTotalWidth)/CGFloat(self.listView.editingAreas().count - 1)
- var areasCopyArray : [CPDFEditArea] = self.listView.editingAreas() as! [CPDFEditArea]
- areasCopyArray.sorted(by: { obj1, obj2 in
- let area1 = obj1
- let area2 = obj2
- if area1.bounds.origin.x < area2.bounds.origin.x {
- return true
- } else {
- return false
- }
- })
- if let index = areasCopyArray.firstIndex(of: leftestArea) {
- areasCopyArray.remove(at: index)
- }
-
- if let index = areasCopyArray.firstIndex(of: rightestArea) {
- areasCopyArray.remove(at: index)
- }
-
- var newBounds : [String] = []
-
- var leftStartX = leftestRect.maxX + gap
- for i in 0 ... areasCopyArray.count-1 {
- let areas = areasCopyArray[i]
- var bounds = areas.bounds
- bounds.origin.x = leftStartX
- newBounds.append(NSStringFromRect(bounds))
- leftStartX = leftStartX + bounds.width + gap
- }
- self.changeAreasAlign(areas: areasCopyArray, newBounds: newBounds)
- } else if stype == .DisVertical {
- let middleGap = zeroRect.height - topestRect.height - bottomestRect.height
- let otherAreasTotalHeight = totalHeight - topestRect.height - bottomestRect.height
-
- let gap = (middleGap - otherAreasTotalHeight)/CGFloat(self.listView.editingAreas().count - 1)
- var areasCopyArray : [CPDFEditArea] = self.listView.editingAreas() as! [CPDFEditArea]
- areasCopyArray.sorted(by: { obj1, obj2 in
- let area1 = obj1
- let area2 = obj2
- if area1.bounds.origin.x < area2.bounds.origin.x {
- return true
- } else {
- return false
- }
- })
- if let index = areasCopyArray.firstIndex(of: topestArea) {
- areasCopyArray.remove(at: index)
- }
-
- if let index = areasCopyArray.firstIndex(of: bottomestArea) {
- areasCopyArray.remove(at: index)
- }
-
- var newBounds : [String] = []
-
- var bottomStartY = bottomestRect.maxY + gap
- for i in 0 ... areasCopyArray.count-1 {
- let areas = areasCopyArray[i]
- var bounds = areas.bounds
- bounds.origin.y = bottomStartY
- newBounds.append(NSStringFromRect(bounds))
- bottomStartY = bottomStartY + bounds.height + gap
- }
- self.changeAreasAlign(areas: areasCopyArray, newBounds: newBounds)
- }
- }
-
- private func changeAreasAlign(areas:[Any],newBounds:[String]) {
- var oldBounds : [String] = []
- for i in 0 ... areas.count-1 {
- let area : CPDFEditArea = areas[i] as! CPDFEditArea
- oldBounds.append(NSStringFromRect(area.bounds))
- self.listView.setBoundsEditArea(area, withBounds: NSRectFromString(newBounds[i]))
- }
- self.listView.setNeedsDisplayForVisiblePages()
- }
-
-
- }
|