123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462 |
- //
- // KMMergeView.swift
- // PDF Reader Pro
- //
- // Created by lizhe on 2023/11/8.
- //
- import Cocoa
- typealias KMMergeViewCancelAction = (_ view: KMMergeView) -> Void
- typealias KMMergeViewAddFilesAction = (_ view: KMMergeView) -> Void
- typealias KMMergeViewMergeAction = (_ view: KMMergeView, _ files: [KMFileAttribute], _ size: CGSize) -> Void
- typealias KMMergeViewClearAction = (_ view: KMMergeView) -> Void
- enum KMMergeViewType: Int {
- case add = 0
- case merge
- }
- class KMMergeView: KMBaseXibView {
- @IBOutlet weak var tableview: NSTableView!
-
- @IBOutlet weak var clearButton: NSButton!
-
- @IBOutlet weak var cancelButton: NSButton!
- @IBOutlet weak var mergeButton: NSButton!
- @IBOutlet weak var addFilesButton: NSButton!
-
- @IBOutlet weak var progress: NSProgressIndicator!
-
- @IBOutlet weak var pageSizeWidthTextField: NSTextField!
- @IBOutlet weak var pageSizeWidthHeightConnectorTextField: NSTextField!
- @IBOutlet weak var pageSizeHeightTextField: NSTextField!
- @IBOutlet weak var pageSizeUnitLabel: NSTextField!
-
- @IBOutlet weak var originalSizeButton: NSButton!
- @IBOutlet weak var A4SizeButton: NSButton!
- @IBOutlet weak var A3SizeButton: NSButton!
- @IBOutlet weak var USLetterSizeButton: NSButton!
- @IBOutlet weak var USLegalButton: NSButton!
- @IBOutlet weak var customSizeButton: NSButton!
- @IBOutlet weak var box: KMBox!
- @IBOutlet weak var boxLabel: NSTextField!
-
- @IBOutlet weak var blankView: KMMergeBlankView!
-
- var cancelAction: KMMergeViewCancelAction?
- var addFilesAction: KMMergeViewAddFilesAction?
- var mergeAction: KMMergeViewMergeAction?
- var clearAction: KMMergeViewClearAction?
-
-
- let MyTableCellViewDataType = NSPasteboard.PasteboardType(rawValue: "KMLocalForDraggedTypes")
- var type: KMMergeViewType = .add {
- didSet {
- self.updateLanguage()
- }
- }
- var files: [KMFileAttribute] = [] {
- didSet {
- self.reloadData()
- }
- }
- var lockFiles: [KMFileAttribute] = [] {
- didSet {
- self.reloadData()
- }
- }//存在密码文件
- var lockFilesIndex: Int = 0
- var newPageSize: NSSize = .zero
-
- var insertRow: Int = 0
- override func draw(_ dirtyRect: NSRect) {
- super.draw(dirtyRect)
- // Drawing code here.
- }
-
- override func setup() {
- self.box.cornerRadius = 4
-
- pageSizeWidthTextField.isEnabled = false
- pageSizeHeightTextField.isEnabled = false;
-
- tableview.delegate = self
- tableview.dataSource = self
- tableview.allowsMultipleSelection = true
- tableview.registerForDraggedTypes([MyTableCellViewDataType, .fileURL, .string, .pdf])
-
- // tableview.register(NSNib.init(nibNamed: "KMMergeTableViewCell", bundle: nil), forIdentifier: NSUserInterfaceItemIdentifier(rawValue: "KMMergeTableViewCell"))
-
- progress.isHidden = true
-
- boxLabel.textColor = KMAppearance.Layout.h0Color()
-
- blankView.dragAction = { [weak self] filePaths in
- var theFileUrls: [URL] = []
- for fileUrl in filePaths {
- if KMTools.isImageType(fileUrl.pathExtension) {
- self?.addImageFile(fileUrl: fileUrl)
- } else {
- theFileUrls.append(fileUrl)
- }
- }
- self?.addFilePaths(urls: theFileUrls)
- }
-
- blankView.mouseDownAction = { [unowned self] view in
- self.addFilesAction?(self)
- }
- }
-
- override func updateLanguage() {
-
- originalSizeButton.title = NSLocalizedString("Original Size", comment: "")
- A4SizeButton.title = "A4";
- A3SizeButton.title = "A3";
- USLetterSizeButton.title = NSLocalizedString("U.S.Letter", comment: "");
- USLegalButton.title = NSLocalizedString("U.S.Legal", comment: "");
- customSizeButton.title = NSLocalizedString("Custom", comment: "");
- pageSizeWidthTextField.stringValue = "595";
- pageSizeHeightTextField.stringValue = "841";
-
- cancelButton.title = NSLocalizedString("Cancel", comment: "");
- clearButton.title = NSLocalizedString("Clear", comment: "");
- addFilesButton.title = NSLocalizedString("Add Files", comment: "")
- mergeButton.title = self.type == .add ? NSLocalizedString("Append", comment: ""): NSLocalizedString("Merge", comment: "")
-
- boxLabel.stringValue = NSLocalizedString("Page size:", comment: "")
- }
-
- override func reloadData() {
- self.updateButtonState()
- if files.count != 0 {
- self.blankView.isHidden = true
- } else {
- self.blankView.isHidden = false
- }
-
- self.tableview.reloadData()
- }
-
- func updateButtonState() {
- if (files.count >= 1) {
- blankView.isHidden = true
- clearButton.isEnabled = true
- mergeButton.isEnabled = true
- } else {
- blankView.isHidden = false
- clearButton.isEnabled = false
- mergeButton.isEnabled = false
- }
- }
- }
- extension KMMergeView {
- func controlTextDidChange(_ obj: Notification) {
- // NSTextField *textField = (NSTextField*)[obj object];
- // NSInteger index = textField.tag;
- // [[_files objectAtIndex:index] setPagesString:textField.stringValue];
- }
- }
- extension KMMergeView: NSTableViewDataSource {
- func numberOfRows(in tableView: NSTableView) -> Int {
- return files.count
- }
-
- func tableView(_ tableView: NSTableView, viewFor tableColumn: NSTableColumn?, row: Int) -> NSView? {
- var cell = tableView.makeView(withIdentifier: NSUserInterfaceItemIdentifier("KMMergeTableViewCell"), owner: self)
- if cell == nil {
- cell = KMMergeTableViewCell.init(frame: .zero)
- }
- let myCellView: KMMergeTableViewCell = cell! as! KMMergeTableViewCell
- if row < files.count {
- myCellView.fileModel = files[row]
- }
- myCellView.index = row + 1
- // 配置单元格的显示内容
- myCellView.removeAction = { [weak self] view, model in
- self?.files.removeObject(model)
- self?.reloadData()
- }
- return myCellView
-
- }
-
- func tableView(_ tableView: NSTableView, shouldSelect tableColumn: NSTableColumn?) -> Bool {
- return false
- }
-
- func tableView(_ tableView: NSTableView, heightOfRow row: Int) -> CGFloat {
- return 120
- }
- }
- extension KMMergeView: NSTableViewDelegate {
- func tableView(_ tableView: NSTableView, writeRowsWith rowIndexes: IndexSet, to pboard: NSPasteboard) -> Bool {
- let indexSetData = try? NSKeyedArchiver.archivedData(withRootObject: rowIndexes, requiringSecureCoding: true)
- pboard.declareTypes([NSPasteboard.PasteboardType.string], owner: self)
- pboard.setData(indexSetData, forType: MyTableCellViewDataType)
- return true
- }
-
- func tableView(_ tableView: NSTableView, validateDrop info: NSDraggingInfo, proposedRow row: Int, proposedDropOperation dropOperation: NSTableView.DropOperation) -> NSDragOperation {
- if dropOperation == .on {
- return []
- }
- var isCanDrag = false
- var result = NSDragOperation.copy
- let pboard = info.draggingPasteboard
- if pboard.availableType(from: [NSPasteboard.PasteboardType.fileURL]) != nil {
- let filePath = pboard.propertyList(forType: NSPasteboard.PasteboardType.fileURL) as? String
- let url = URL(string: filePath!)
-
- if url!.path.lowercased().hasSuffix("pdf") {
- isCanDrag = true
- } else {
- if KMTools.isImageType(url?.pathExtension ?? "") {
- isCanDrag = true
- } else {
- isCanDrag = false
- }
- }
- } else if (pboard.availableType(from: [MyTableCellViewDataType]) != nil) {
- result = .every
- }
- if isCanDrag {
- result = .copy
- }
- return result
- }
-
- func tableView(_ tableView: NSTableView, acceptDrop info: NSDraggingInfo, row: Int, dropOperation: NSTableView.DropOperation) -> Bool {
- var result = false
- let pboard = info.draggingPasteboard
- insertRow = row
- // NSPasteboard.PasteboardType.fileURL
- if pboard.availableType(from: [NSPasteboard.PasteboardType.fileURL]) != nil {
- let filePath = pboard.propertyList(forType: NSPasteboard.PasteboardType.fileURL) as? String
- let url = URL(string: filePath!)
- var array = [URL]()
- array.append(url!)
- var theFileUrls: [URL] = []
- for fileUrl in array {
- if KMTools.isImageType(fileUrl.pathExtension) {
- self.addImageFile(fileUrl: fileUrl)
- } else {
- theFileUrls.append(fileUrl)
- }
- }
- addFilePaths(urls: theFileUrls)
- result = true
- } else if pboard.availableType(from: [MyTableCellViewDataType]) != nil {
- guard let data = info.draggingPasteboard.data(forType: MyTableCellViewDataType),
- let rowIndexes = try? NSKeyedUnarchiver.unarchiveTopLevelObjectWithData(data) as? IndexSet else {
- return false
- }
-
- // 移动数据
- var draggedItems: [KMFileAttribute] = []
- for index in rowIndexes {
- draggedItems.append(files[index])
- }
-
- for index in rowIndexes.reversed() {
- files.remove(at: index)
- }
-
- let insertionIndex = row > rowIndexes.first! ? row - rowIndexes.count : row
-
- for (index, item) in draggedItems.enumerated() {
- files.insert(item, at: insertionIndex + index)
- }
-
- tableView.reloadData()
- return true
-
- } else {
- result = false
- }
- return result
- }
- }
- extension KMMergeView {
- @IBAction func clearButtonAction(_ sender: Any) {
- self.files.removeAll()
- self.reloadData()
-
- guard let callBack = clearAction else { return }
-
- callBack(self)
- }
-
- @IBAction func cancelButtonAction(_ sender: Any) {
- guard let callBack = cancelAction else { return }
-
- callBack(self)
- }
-
- @IBAction func mergeButtonAction(_ sender: Any) {
- guard let callBack = mergeAction else { return }
- self.reloadData()
- callBack(self, self.files, self.newPageSize)
- }
-
- @IBAction func addFilesButtonAction(_ sender: Any) {
- guard let callBack = addFilesAction else { return }
-
- callBack(self)
- }
-
- @IBAction func sizeButtonAction(_ sender: NSButton) {
- originalSizeButton.state = .off
- A3SizeButton.state = .off
- A4SizeButton.state = .off
- USLetterSizeButton.state = .off
- USLegalButton.state = .off
- customSizeButton.state = .off
- sender.state = .on
-
- pageSizeHeightTextField.isEnabled = sender.isEqual(customSizeButton)
- pageSizeWidthTextField.isEnabled = sender.isEqual(customSizeButton)
-
- var size: NSSize = .zero
- switch sender.tag {
- case 0:
- break
- case 1:
- size = NSMakeSize(595, 841);
- break;
- case 2:
- size = NSMakeSize(841, 1190);
- break;
- case 3:
- size = NSMakeSize(612, 792);
- break;
- case 4:
- size = NSMakeSize(612, 1108);
- break;
- case 5:
- size = NSMakeSize(595, 841);
- pageSizeWidthTextField.stringValue = size.width.description
- pageSizeHeightTextField.stringValue = size.height.description
- break;
- default:
- break
- }
- self.newPageSize = size
- }
- }
- //MARK: public
- extension KMMergeView {
- func addFilePaths(urls: [URL]) {
- lockFiles.removeAll()
- // files.removeAll()
-
- for url in urls {
- let file = KMFileAttribute()
- file.filePath = url.path
-
- if file.isLocked {
- lockFiles.append(file)
- } else {
- var isExist = false
- for item in files {
- if item.filePath == file.filePath {
- isExist = true
- break
- }
- }
- if !isExist {
- files.append(file)
- }
- }
- }
-
- lockFilesIndex = 0
- self.openPasswordFile { [weak self] success, resultPassword in
- self?.reloadData()
- }
- }
-
- func addImageFile(fileUrl: URL) {
- if let image = NSImage(contentsOf: fileUrl) {
- if let page = PDFPage(image: image) {
- let document = PDFDocument()
- document.insert(page, at: 0)
-
- var path = self._saveImagePath() + "/" + fileUrl.deletingPathExtension().lastPathComponent + ".pdf"
- path = KMTools.getUniqueFilePath(filePath: path)
- let result = document.write(toFile: path)
- if result {
- let file = KMFileAttribute()
- file.filePath = path
- file.oriFilePath = fileUrl.path
- file.myPDFDocument = document
-
- self.files.append(file)
- }
- }
- } else {
- Task {
- _ = await KMAlertTool.runModel(message: NSLocalizedString("An error occurred while opening this document. The file is damaged and could not be repaired.", comment: ""))
- }
- }
- }
-
- func openPasswordFile(completion: @escaping ((_ success: Bool, _ resultPassword: String) -> Void)) {
- if lockFiles.count != 0 {
- let file = lockFiles[lockFilesIndex]
- KMBaseWindowController.checkPassword(url: URL(fileURLWithPath: file.filePath), type: .owner) { [unowned self] success, resultPassword in
- if success {
- file.password = resultPassword
- lockFilesIndex = lockFilesIndex + 1
- files.append(file)
- completion(true, "")
- if lockFiles.count > lockFilesIndex {
- self.openPasswordFile(completion: completion)
- }
- } else {
- completion(false, "")
- }
- }
- } else {
- completion(true, "")
- }
- }
- }
- //MARK: private
- extension KMMergeView {
- private func openFilePath(url: URL) {
- NSWorkspace.shared.activateFileViewerSelecting([url])
- }
-
- private func isExistAtFilePath(filePath: String) -> Bool{
- for file in self.files {
- if file.filePath == filePath {
- return true
- }
- }
-
- return false
- }
-
- private func _saveImagePath() -> String {
- let rootPath = KMDataManager.fetchAppSupportOfBundleIdentifierDirectory()
- let path = rootPath.appendingPathComponent("Merge").path
- if FileManager.default.fileExists(atPath: path) == false {
- try?FileManager.default.createDirectory(atPath: path, withIntermediateDirectories: false)
- }
- return path
- }
- }
|