// // KMBatchOperateWindowController.swift // PDF Reader Pro // // Created by kdanmobile on 2023/10/24. // import Cocoa import PDFKit let kBatchOperateToolbarIdentifier = "kBatchOperateToolbarIdentifier" let kBatchOperateToolbar_ConvertIdentifier = "kBatchOperateToolbar_ConvertIdentifier" let kBatchOperateToolbar_MergeIdentifier = "kBatchOperateToolbar_MergeIdentifier" let kBatchOperateToolbar_CompressIdentifier = "kBatchOperateToolbar_CompressIdentifier" let kBatchOperateToolbar_OCRIdentifier = "kBatchOperateToolbar_OCRIdentifier" let kBatchOperateToolbar_SecurityIdentifier = "kBatchOperateToolbar_SecurityIdentifier" let kBatchOperateToolbar_WatermarkIdentifier = "kBatchOperateToolbar_WatermarkIdentifier" let kBatchOperateToolbar_BackgroundIdentifier = "kBatchOperateToolbar_BackgroundIdentifier" let kBatchOperateToolbar_HeadFooterIdentifier = "kBatchOperateToolbar_HeadFooterIdentifier" let kBatchOperateToolbar_BatesIdentifier = "kBatchOperateToolbar_BatesIdentifier" @objcMembers final class KMBatchOperateWindowController: KMBatchOperateBaseWindowController, NSWindowDelegate, KMCustomButtonViewPopDelegate, KMCustomButtonViewPopDataSource, NSToolbarDelegate{ func numberOfLine(in button: KMCustomViewButton) -> Int { return 2 } func string(for button: KMCustomViewButton, index: Int) -> String? { if button.isEqual(self.convertToolbarItemView) { if index == 0 { return NSLocalizedString("Create PDF", comment: "") } else { return NSLocalizedString("Export to other format", comment: "") } } else if button.isEqual(self.securityToolbarItemView) { if index == 0 { return NSLocalizedString("Set Passwords", comment: "") } else { return NSLocalizedString("Remove Security", comment: "") } } else if button.isEqual(self.watermarkToolbarItemView) { if index == 0 { return NSLocalizedString("Add Watermark", comment: "") } else { return NSLocalizedString("Remove Watermark", comment: "") } } else if button.isEqual(self.backgroundToolbarItemView) { if index == 0 { return NSLocalizedString("Add Background", comment: "") } else { return NSLocalizedString("Remove Background", comment: "") } } else if button.isEqual(self.headerfooterToolbarItemView) { if index == 0 { return NSLocalizedString("Add Header & Footer", comment: "") } else { return NSLocalizedString("Remove Header & Footer", comment: "") } } else if button.isEqual(self.batesToolbarItemView) { if index == 0 { return NSLocalizedString("Add Bates Numbers", comment: "") } else { return NSLocalizedString("Remove Bates Numbers", comment: "") } } return "" } func needInsertSeperateLine(_ button: KMCustomViewButton, index: Int) -> Bool { return false } func needHightLightLine(_ button: KMCustomViewButton, index: Int) -> Bool { if button.isEqual(self.convertToolbarItemView) { if index == 0 { if self.operateType == .CreatePDF { return true } } else if index == 1 { if self.operateType == .Convert { return true } } } else if button.isEqual(self.securityToolbarItemView) { if index == 0 { if self.operateType == .AddPassword { return true } } else if index == 1 { if self.operateType == .RemovePassword { return true } } } else if button.isEqual(self.watermarkToolbarItemView) { if index == 0 { if self.operateType == .AddWatermark { return true } } else if index == 1 { if self.operateType == .RemoveWatermark { return true } } } else if button.isEqual(self.backgroundToolbarItemView) { if index == 0 { if self.operateType == .AddBackground { return true } } else if index == 1 { if self.operateType == .RemoveBackground { return true } } } else if button.isEqual(self.headerfooterToolbarItemView) { if index == 0 { if self.operateType == .AddHeaderFooter { return true } } else if index == 1 { if self.operateType == .RemoveHeaderFooter { return true } } } else if button.isEqual(self.batesToolbarItemView) { if index == 0 { if self.operateType == .AddBates { return true } } else if index == 1 { if self.operateType == .RemoveBates { return true } } } return false } func customViewButton(_ button: KMCustomViewButton, didSelectIndex index: Int) { if button.isEqual(self.convertToolbarItemView) { if index == 0 { self.createPDF(sender: "") } else if index == 1 { self.convertPDFToOtherFormat(sender: "") } } else if button.isEqual(self.securityToolbarItemView) { if index == 0 { self.setPDFPassword(sender: "") } else if index == 1 { self.removePDFPassword(sender: "") } } else if button.isEqual(self.watermarkToolbarItemView) { if index == 0 { self.addWatermark(sender: "") } else if index == 1 { self.removeWatermark(sender: "") } } else if button.isEqual(self.backgroundToolbarItemView) { if index == 0 { self.addBackgroud(sender: "") } else if index == 1 { self.removeBackground(sender: "") } } else if button.isEqual(self.headerfooterToolbarItemView) { if index == 0 { self.addHeaderFooter(sender: "") } else if index == 1 { self.removeHeaderFooter(sender: "") } } else if button.isEqual(self.batesToolbarItemView) { if index == 0 { self.addBates(sender: "") } else if index == 1 { self.removeBates(sender: "") } } } lazy var convertToolbarItemView: KMCustomViewButton = { let item = KMCustomViewButton.init(frontImage: NSImage(named: "KMImageNameUXIconBatchConvert"), backImage: nil, title: NSLocalizedString("Convert", comment: ""), type: .batchToolbar) item.addTarget(self, action: #selector(convertPDFToOtherFormat(sender:))) self.window?.contentView?.addSubview(item) return item }() lazy var mergeToolbarItemView: KMCustomViewButton = { let item = KMCustomViewButton.init(frontImage: NSImage(named: "KMImageNameUXIconBatchMerge"), backImage: nil, title: NSLocalizedString("Merge", comment: ""), type: .batchToolbar) item.addTarget(self, action: #selector(merge(sender:))) self.window?.contentView?.addSubview(item) return item }() lazy var compressToolbarItemView: KMCustomViewButton = { let item = KMCustomViewButton.init(frontImage: NSImage(named: "KMImageNameUXIconBatchOptimize"), backImage: nil, title: NSLocalizedString("Compress", comment: ""), type: .batchToolbar) item.addTarget(self, action: #selector(compress(sender:))) self.window?.contentView?.addSubview(item) return item }() lazy var ocrToolbarItemView: KMCustomViewButton = { let item = KMCustomViewButton.init(frontImage: NSImage(named: "KMImageNameUXIconBatchConvertOCR"), backImage: nil, title: NSLocalizedString("OCR", comment: ""), type: .batchToolbar) item.addTarget(self, action: #selector(ocr(sender:))) self.window?.contentView?.addSubview(item) return item }() lazy var securityToolbarItemView: KMCustomViewButton = { let item = KMCustomViewButton.init(frontImage: NSImage(named: "KMImageNameUXIconBatchSafe"), backImage: NSImage(named: "KMImageNameUXIconBtnTriDownNor"), title: NSLocalizedString("Security", comment: ""), type: .batchToolbar) item.delegate = self item.dataSource = self self.window?.contentView?.addSubview(item) item.mas_makeConstraints { make in make?.center.equalTo()(self.window?.contentView) } return item }() lazy var watermarkToolbarItemView: KMCustomViewButton = { let item = KMCustomViewButton.init(frontImage: NSImage(named: "KMImageNameUXIconBatchWatermark"), backImage: NSImage(named: "KMImageNameUXIconBtnTriDownNor"), title: NSLocalizedString("Watermark", comment: ""), type: .batchToolbar) item.delegate = self item.dataSource = self self.window?.contentView?.addSubview(item) item.mas_makeConstraints { make in make?.center.equalTo()(self.window?.contentView) } return item }() lazy var backgroundToolbarItemView: KMCustomViewButton = { let item = KMCustomViewButton.init(frontImage: NSImage(named: "KMImageNameUXIconBatchBackground"), backImage: NSImage(named: "KMImageNameUXIconBtnTriDownNor"), title: NSLocalizedString("Background", comment: ""), type: .batchToolbar) item.delegate = self item.dataSource = self self.window?.contentView?.addSubview(item) item.mas_makeConstraints { make in make?.center.equalTo()(self.window?.contentView) } return item }() lazy var headerfooterToolbarItemView: KMCustomViewButton = { let item = KMCustomViewButton.init(frontImage: NSImage(named: "KMImageNameUXIconBatchHeaderandfooter"), backImage: NSImage(named: "KMImageNameUXIconBtnTriDownNor"), title: NSLocalizedString("Header & Footer", comment: ""), type: .batchToolbar) item.delegate = self item.dataSource = self self.window?.contentView?.addSubview(item) item.mas_makeConstraints { make in make?.center.equalTo()(self.window?.contentView) } return item }() lazy var batesToolbarItemView: KMCustomViewButton = { let item = KMCustomViewButton.init(frontImage: NSImage(named: "KMImageNameUXIconBatchBates"), backImage: NSImage(named: "KMImageNameUXIconBtnTriDownNor"), title: NSLocalizedString("Bates Numbers", comment: ""), type: .batchToolbar) item.delegate = self item.dataSource = self self.window?.contentView?.addSubview(item) item.mas_makeConstraints { make in make?.center.equalTo()(self.window?.contentView) } return item }() lazy var toolbarItemViews: NSMutableArray = { let arr = [self.convertToolbarItemView, self.mergeToolbarItemView, self.compressToolbarItemView, self.ocrToolbarItemView, self.securityToolbarItemView, self.watermarkToolbarItemView, self.backgroundToolbarItemView, self.headerfooterToolbarItemView, self.batesToolbarItemView ] return NSMutableArray(array: arr) }() override var operateType: KMBatchOperationType?{ willSet{ } didSet { if operateType == oldValue{ return }else{ super.operateType = operateType } for i in 0.. Bool { if self.operateType == .Compress { let vc: KMBatchOperateRightViewController = (self.contentViewController as! KMBatchOperateSplitViewController).rightPropertiesViewController! let compress = vc.compressViewController var begin = false for info in compress!.files! { if info.status == KMBatchOperateStatus.processing { begin = true break } } if begin { let alert = NSAlert() alert.alertStyle = .critical alert.messageText = NSLocalizedString("Do you want to cancel compressing?", comment: "") alert.informativeText = NSLocalizedString("Documents which have been compressed will still be retained.", comment: "") alert.addButton(withTitle: NSLocalizedString("Cancel Compressing", comment: "")) alert.addButton(withTitle: NSLocalizedString("Continue compressing", comment: "")) alert.beginSheetModal(for: self.window!, completionHandler: { (response) in if response == .alertFirstButtonReturn { compress!.cancelBatchOperation() self.close() } else if response == .alertSecondButtonReturn { compress!.beginBatchOperation() } }) return false } } return true } override func windowDidLoad() { super.windowDidLoad() if #available(macOS 11.0, *) { self.window?.toolbarStyle = NSWindow.ToolbarStyle.expanded } self.updateViewColor() self.window?.titlebarAppearsTransparent = true // self.toolbarItemViews DispatchQueue.main.async { self.configuToolbar() } // NotificationCenter.default.addObserver(self, selector: #selector(themeChanged(notification:)), name: NSNotification.Name("AppleInterfaceThemeChangedNotification"), object: nil) DistributedNotificationCenter.default().addObserver(self, selector: #selector(themeChanged(notification:)), name: NSNotification.Name("AppleInterfaceThemeChangedNotification"), object: nil) } @objc func themeChanged(notification: NSNotification) { DispatchQueue.main.asyncAfter(deadline: .now() + 0.3) { self.updateViewColor() } } func configuToolbar() { let toolbar = NSToolbar(identifier: kBatchOperateToolbarIdentifier) toolbar.delegate = self self.window?.toolbar = toolbar toolbar.allowsUserCustomization = false toolbar.displayMode = .iconOnly } @objc func convertPDFToOtherFormat(sender: Any) { self.operateType = .Convert } @objc func createPDF(sender: Any) { self.operateType = .CreatePDF } @objc func merge(sender: Any) { self.operateType = .Merge } @objc func compress(sender: Any) { self.operateType = .Compress } @objc func ocr(sender: Any) { self.operateType = .OCR } @objc func setPDFPassword(sender: Any) { self.operateType = .AddPassword } @objc func removePDFPassword(sender: Any) { self.operateType = .RemovePassword } @objc func addWatermark(sender: Any) { self.operateType = .AddWatermark } @objc func removeWatermark(sender: Any) { self.operateType = .RemoveWatermark } @objc func addBackgroud(sender: Any) { self.operateType = .AddBackground } @objc func removeBackground(sender: Any) { self.operateType = .RemoveBackground } @objc func addHeaderFooter(sender: Any) { self.operateType = .AddHeaderFooter } @objc func removeHeaderFooter(sender: Any) { self.operateType = .RemoveHeaderFooter } @objc func addBates(sender: Any) { self.operateType = .AddBates } @objc func removeBates(sender: Any) { self.operateType = .RemoveBates } func toolbarAllowedItemIdentifiers(_ toolbar: NSToolbar) -> [NSToolbarItem.Identifier] { let arr = [NSToolbarItem.Identifier.flexibleSpace, NSToolbarItem.Identifier(rawValue: kBatchOperateToolbar_ConvertIdentifier), NSToolbarItem.Identifier.flexibleSpace, NSToolbarItem.Identifier(rawValue: kBatchOperateToolbar_CompressIdentifier), NSToolbarItem.Identifier.flexibleSpace, NSToolbarItem.Identifier(rawValue: kBatchOperateToolbar_SecurityIdentifier), NSToolbarItem.Identifier.flexibleSpace, NSToolbarItem.Identifier(rawValue: kBatchOperateToolbar_WatermarkIdentifier), NSToolbarItem.Identifier.flexibleSpace, NSToolbarItem.Identifier(rawValue: kBatchOperateToolbar_BackgroundIdentifier), NSToolbarItem.Identifier.flexibleSpace, NSToolbarItem.Identifier(rawValue: kBatchOperateToolbar_HeadFooterIdentifier), NSToolbarItem.Identifier.flexibleSpace, NSToolbarItem.Identifier(rawValue: kBatchOperateToolbar_BatesIdentifier), NSToolbarItem.Identifier.flexibleSpace ] return arr } func toolbarDefaultItemIdentifiers(_ toolbar: NSToolbar) -> [NSToolbarItem.Identifier] { let arr = [ NSToolbarItem.Identifier(rawValue: kBatchOperateToolbar_ConvertIdentifier), NSToolbarItem.Identifier(rawValue: kBatchOperateToolbar_CompressIdentifier), NSToolbarItem.Identifier(rawValue: kBatchOperateToolbar_SecurityIdentifier), NSToolbarItem.Identifier(rawValue: kBatchOperateToolbar_WatermarkIdentifier), NSToolbarItem.Identifier(rawValue: kBatchOperateToolbar_BackgroundIdentifier), NSToolbarItem.Identifier(rawValue: kBatchOperateToolbar_HeadFooterIdentifier), NSToolbarItem.Identifier(rawValue: kBatchOperateToolbar_BatesIdentifier) ] return arr } func toolbar(_ toolbar: NSToolbar, itemForItemIdentifier itemIdentifier: NSToolbarItem.Identifier, willBeInsertedIntoToolbar flag: Bool) -> NSToolbarItem? { let item = NSToolbarItem(itemIdentifier: itemIdentifier) if itemIdentifier.rawValue == kBatchOperateToolbar_ConvertIdentifier { item.view = self.convertToolbarItemView item.toolTip = NSLocalizedString("Convert", comment: "") let menuItem = NSMenuItem(title: NSLocalizedString("Convert", comment: ""), action: #selector(convertPDFToOtherFormat(sender:)), keyEquivalent: "") menuItem.target = self item.menuFormRepresentation = menuItem } else if itemIdentifier.rawValue == kBatchOperateToolbar_MergeIdentifier { item.view = self.mergeToolbarItemView item.toolTip = NSLocalizedString("Merge", comment: "") let menuItem = NSMenuItem(title: NSLocalizedString("Merge", comment: ""), action: #selector(merge(sender:)), keyEquivalent: "") menuItem.target = self item.menuFormRepresentation = menuItem } else if itemIdentifier.rawValue == kBatchOperateToolbar_CompressIdentifier { item.view = self.compressToolbarItemView item.toolTip = NSLocalizedString("Compress", comment: "") let menuItem = NSMenuItem(title: NSLocalizedString("Compress", comment: ""), action: #selector(compress(sender:)), keyEquivalent: "") menuItem.target = self item.menuFormRepresentation = menuItem } else if itemIdentifier.rawValue == kBatchOperateToolbar_OCRIdentifier { item.view = self.ocrToolbarItemView item.toolTip = NSLocalizedString("OCR", comment: "") let menuItem = NSMenuItem(title: NSLocalizedString("OCR", comment: ""), action: #selector(ocr(sender:)), keyEquivalent: "") menuItem.target = self item.menuFormRepresentation = menuItem } else if itemIdentifier.rawValue == kBatchOperateToolbar_SecurityIdentifier { item.view = self.securityToolbarItemView let menuItem = NSMenuItem(title: NSLocalizedString("Security", comment: ""), action: nil, keyEquivalent: "") let menu = NSMenu() menu.addItem(withTitle: NSLocalizedString("Set Passwords", comment: ""), action: #selector(setPDFPassword(sender:)), keyEquivalent: "") menu.addItem(withTitle: NSLocalizedString("Remove Security", comment: ""), action: #selector(removePDFPassword(sender:)), keyEquivalent: "") menuItem.submenu = menu menuItem.target = self item.menuFormRepresentation = menuItem } else if itemIdentifier.rawValue == kBatchOperateToolbar_WatermarkIdentifier { item.view = self.watermarkToolbarItemView let menuItem = NSMenuItem(title: NSLocalizedString("Watermark", comment: ""), action: nil, keyEquivalent: "") let menu = NSMenu() menu.addItem(withTitle: NSLocalizedString("Add Watermark", comment: ""), action: #selector(addWatermark(sender:)), keyEquivalent: "") menu.addItem(withTitle: NSLocalizedString("Remove Watermark", comment: ""), action: #selector(removeWatermark(sender:)), keyEquivalent: "") menuItem.submenu = menu menuItem.target = self item.menuFormRepresentation = menuItem } else if itemIdentifier.rawValue == kBatchOperateToolbar_BackgroundIdentifier { item.view = self.backgroundToolbarItemView let menuItem = NSMenuItem(title: NSLocalizedString("Background", comment: ""), action: nil, keyEquivalent: "") let menu = NSMenu() menu.addItem(withTitle: NSLocalizedString("Add Background", comment: ""), action: #selector(addBackgroud(sender:)), keyEquivalent: "") menu.addItem(withTitle: NSLocalizedString("Remove Background", comment: ""), action: #selector(removeBackground(sender:)), keyEquivalent: "") menuItem.submenu = menu menuItem.target = self item.menuFormRepresentation = menuItem } else if itemIdentifier.rawValue == kBatchOperateToolbar_HeadFooterIdentifier { item.view = self.headerfooterToolbarItemView let menuItem = NSMenuItem(title: NSLocalizedString("Header & Footer", comment: ""), action: nil, keyEquivalent: "") let menu = NSMenu() menu.addItem(withTitle: NSLocalizedString("Add Header & Footer", comment: ""), action: #selector(addHeaderFooter(sender:)), keyEquivalent: "") menu.addItem(withTitle: NSLocalizedString("Remove Header & Footer", comment: ""), action: #selector(removeHeaderFooter(sender:)), keyEquivalent: "") menuItem.submenu = menu menuItem.target = self item.menuFormRepresentation = menuItem } else if itemIdentifier.rawValue == kBatchOperateToolbar_BatesIdentifier { item.view = self.batesToolbarItemView let menuItem = NSMenuItem(title: NSLocalizedString("Bates Numbers", comment: ""), action: nil, keyEquivalent: "") let menu = NSMenu() menu.addItem(withTitle: NSLocalizedString("Add Bates Numbers", comment: ""), action: #selector(addBates(sender:)), keyEquivalent: "") menu.addItem(withTitle: NSLocalizedString("Remove Bates Numbers", comment: ""), action: #selector(removeBates(sender:)), keyEquivalent: "") menuItem.submenu = menu menuItem.target = self item.menuFormRepresentation = menuItem } return item } func showIsConvertingHint() { let texHintWindowController = KMTextHintWindowController(windowNibName: "KMTextHintWindowController") self.window?.beginSheet(texHintWindowController.window!) } func windowDidBecomeKey(_ notification: Notification) { for i in 0..