// // KMOutlineEditViewController.swift // PDF Reader Pro // // Created by lxy on 2022/11/9. // import Cocoa import KMComponentLibrary class KMOutlineEditViewController: KMNBaseViewController { @IBOutlet var outlineNameTextView: NSTextView! @IBOutlet weak var outlineNameLabel: NSTextField! @IBOutlet weak var outlineTargetPageIndexTextField: NSTextField! @IBOutlet weak var pageButton: NSButton! @IBOutlet weak var totalPageCountLabel: NSTextField! @IBOutlet weak var outlineURLTextField: NSTextField! @IBOutlet weak var urlButton: NSButton! @IBOutlet weak var mailAddressTextField: NSTextField! @IBOutlet weak var mailButton: NSButton! @IBOutlet weak var inputScrollView: NSScrollView! @IBOutlet weak var pageBox: NSBox! @IBOutlet weak var webBox: NSBox! @IBOutlet weak var emailBox: NSBox! @IBOutlet weak var bottomBox: NSBox! @IBOutlet weak var leftButtonBox: NSBox! @IBOutlet weak var rightButtonBox: NSBox! weak var outline : CPDFOutline? weak var pdfView : CPDFView? var originalURLString : String = "" weak var originalDestination : CPDFDestination? var originalPageIndex = -1 var originalLabel : String = "" var currentPageIndex : Int = 0 var pageCount = 0 var itemClick: KMCommonClickBlock? private lazy var inputView_: ComponentTextarea = { let view = ComponentTextarea() view.properties = ComponentTextareaProperty(size: .m, state: .pressed, isError: false, placeholderString: "", totalCount: -1, text: "", isDisabled: false) return view }() private lazy var pageRadio_: ComponentRadio = { let view = ComponentRadio() view.properties = ComponentCheckBoxProperty(size: .s, state: .normal, isDisabled: false, showhelp: false, text: KMLocalizedString("Page:", comment: ""), checkboxType: .normal) return view }() private lazy var pageInput_: ComponentInput = { let view = ComponentInput() let inputWithAddonProperty = ComponentInputProperty(size: .s, state: .normal, isError: false, showPrefix: false, showSuffix: false, showClear: false, isDisabled: true, placeholder: "", text: "", creatable: true) view.properties = inputWithAddonProperty return view }() private lazy var pageLabel: NSTextField = { let view = NSTextField(labelWithString: "") return view }() private lazy var webRadio_: ComponentRadio = { let view = ComponentRadio() view.properties = ComponentCheckBoxProperty(size: .s, state: .normal, isDisabled: false, showhelp: false, text: KMLocalizedString("Webside:", comment: ""), checkboxType: .normal) return view }() private lazy var webInput_: ComponentInput = { let view = ComponentInput() view.properties = ComponentInputProperty(size: .s, placeholder: KMLocalizedString("http://www.pdfreaderpro.com"), text: "") return view }() private lazy var emailRadio_: ComponentRadio = { let view = ComponentRadio() view.properties = ComponentCheckBoxProperty(size: .s, state: .normal, isDisabled: false, showhelp: false, text: KMLocalizedString("Email:", comment: ""), checkboxType: .normal) return view }() private lazy var emailInput_: ComponentInput = { let view = ComponentInput() view.properties = ComponentInputProperty(size: .s, placeholder: KMLocalizedString("support@pdfreaderpro.com"), text: "") return view }() private lazy var cancelButton_: ComponentButton = { let view = ComponentButton() view.properties = ComponentButtonProperty(type: .default_tertiary, size: .s, state: .normal, isDisable: false, onlyIcon: false, buttonText: KMLocalizedString("Cancel"), keepPressState: false) return view }() private lazy var okButton_: ComponentButton = { let view = ComponentButton() view.properties = ComponentButtonProperty(type: .primary, size: .s, state: .normal, isDisable: false, onlyIcon: false, buttonText: KMLocalizedString("Apply"), keepPressState: false) return view }() var pageRadio: ComponentRadio { get { return pageRadio_ } } var pageInput: ComponentInput { get { return pageInput_ } } var webRaido: ComponentRadio { get { return webRadio_ } } var webInput: ComponentInput { get { return webInput_ } } var emailRadio: ComponentRadio { get { return emailRadio_ } } var emailInput: ComponentInput { get { return emailInput_ } } convenience init(outline: CPDFOutline?, document: CPDFView?) { self.init() self.outline = outline self.pdfView = document } override func loadView() { super.loadView() // 382-48=334 64 inputView_.frame = inputScrollView.contentView.bounds inputView_.autoresizingMask = [.width, .height] inputScrollView.documentView = inputView_ inputView_.properties.text = outline?.label ?? "" inputView_.reloadData() pageButton.isHidden = true totalPageCountLabel.isHidden = true pageBox.borderWidth = 0 pageBox.contentView?.addSubview(pageRadio_) pageBox.contentView?.addSubview(pageInput_) pageBox.contentView?.addSubview(pageLabel) pageRadio_.km_add_centerY_constraint() pageRadio_.km_add_leading_constraint() pageRadio_.km_add_width_constraint(constant: pageRadio_.properties.propertyInfo.viewWidth+8) pageRadio_.km_add_height_constraint(constant: 20) pageInput_.km_add_leading_constraint(equalTo: pageRadio_, attribute: .trailing, constant: 0) pageInput_.km_add_centerY_constraint() pageInput_.km_add_height_constraint(constant: 32) pageInput_.km_add_width_constraint(constant: 80) pageLabel.km_add_leading_constraint(equalTo: pageInput_, attribute: .trailing, constant: 8) pageLabel.km_add_centerY_constraint() pageLabel.stringValue = "/\(pageCount)" pageInput_.properties.text = "11" pageInput_.reloadData() pageRadio_.setTarget(self, action: #selector(buttonClicked_GotoAction)) urlButton.isHidden = true outlineURLTextField.isHidden = true webBox.borderWidth = 0 webBox.contentView?.addSubview(webRadio_) webBox.contentView?.addSubview(webInput_) webRadio_.km_add_centerY_constraint() webRadio_.km_add_leading_constraint() webRadio_.km_add_width_constraint(constant: webRadio_.properties.propertyInfo.viewWidth+8) webRadio_.km_add_height_constraint(constant: 20) webInput_.km_add_leading_constraint(equalTo: webRadio_, attribute: .trailing, constant: 0) webInput_.km_add_centerY_constraint() webInput_.km_add_height_constraint(constant: 32) webInput_.km_add_trailing_constraint() webRadio_.setTarget(self, action: #selector(buttonClicked_URLAction)) mailButton.isHidden = true mailAddressTextField.isHidden = true emailBox.borderWidth = 0 emailBox.contentView?.addSubview(emailRadio_) emailBox.contentView?.addSubview(emailInput_) emailRadio_.km_add_centerY_constraint() emailRadio_.km_add_leading_constraint() emailRadio_.km_add_width_constraint(constant: emailRadio_.properties.propertyInfo.viewWidth+8) emailRadio_.km_add_height_constraint(constant: 20) emailInput_.km_add_leading_constraint(equalTo: emailRadio_, attribute: .trailing, constant: 0) emailInput_.km_add_centerY_constraint() emailInput_.km_add_height_constraint(constant: 32) emailInput_.km_add_trailing_constraint() emailRadio_.setTarget(self, action: #selector(buttonClicked_MailAction)) bottomBox.borderWidth = 0 leftButtonBox.borderWidth = 0 leftButtonBox.contentView = cancelButton_ rightButtonBox.borderWidth = 0 rightButtonBox.contentView = okButton_ cancelButton_.setTarget(self, action: #selector(_cancelAction)) okButton_.setTarget(self, action: #selector(_okAction)) outlineNameLabel.font = ComponentLibrary.shared.getFontFromKey("mac/body-m-medium") pageLabel.font = ComponentLibrary.shared.getFontFromKey("mac/body-s-regular") setONButton(button: pageRadio_) enableTextField(textField: pageInput_) setDelegateAndFormatter() if let action = outline?.action { adjustUIWithAction(action: action) } } override func updateUILanguage() { super.updateUILanguage() KMMainThreadExecute { self.outlineNameLabel.stringValue = KMLocalizedString("Rename") } } override func updateUIThemeColor() { super.updateUIThemeColor() view.wantsLayer = true KMMainThreadExecute { self.view.layer?.backgroundColor = KMNColorTools.colorBg_popup().cgColor self.outlineNameLabel.textColor = KMNColorTools.colorText_1() self.pageLabel.textColor = KMNColorTools.compField_colorTextFilledNor() } } //MARK: - Private Methods private func adjustUIWithAction(action:CPDFAction!) { guard let doc = self.pdfView?.document else { return } if action == nil { pageLabel.stringValue = " \(doc.pageCount)" pageInput_.properties.text = " \(currentPageIndex + 1)" pageInput_.reloadData() } else { guard let outL = outline else { return } if action.isKind(of: CPDFURLAction.self) { var newAction : CPDFURLAction = outline?.action as! CPDFURLAction var urlString = newAction.url() ?? "" originalURLString = urlString if urlString.hasPrefix("mailto:") { setONButton(button: emailRadio_) enableTextField(textField: emailInput_) urlString = String(urlString.suffix(from: "mailto:".endIndex)) emailInput_.properties.text = urlString emailInput_.reloadData() } else { setONButton(button: webRadio_) enableTextField(textField: webInput_) webInput_.properties.text = urlString webInput_.reloadData() } currentPageIndex = Int(doc.index(for: doc.page(at: UInt(pdfView?.currentPageIndex ?? 0)))) } else { setONButton(button: pageRadio_) enableTextField(textField: pageInput_) currentPageIndex = Int(doc.index(for: doc.page(at: UInt(outL.destination.pageIndex)))) originalDestination = outL.destination originalPageIndex = originalDestination?.pageIndex ?? -1 } originalLabel = outL.label ?? "" pageLabel.stringValue = " /\(doc.pageCount)" pageInput_.properties.text = "\(self.currentPageIndex + 1)" pageInput_.reloadData() } } private func setDelegateAndFormatter () { self.outlineTargetPageIndexTextField.delegate = self self.outlineNameTextView.delegate = self var formatter = NumberFormatter() formatter.numberStyle = .none formatter.maximum = NSNumber(value: self.pdfView?.document?.pageCount ?? 0) formatter.minimum = NSNumber(value: 1) self.outlineTargetPageIndexTextField.formatter = formatter } private func setONButton(button sender: ComponentRadio) { for radio in [pageRadio_, webRadio_, emailRadio_] { if radio.isEqual(to: sender) { radio.properties.checkboxType = .selected } else { radio.properties.checkboxType = .normal } radio.reloadData() } } private func enableTextField(textField sender: ComponentInput) { for input in [pageInput_, webInput_, emailInput_] { if sender.isEqual(to: input) { input.properties.isDisabled = false input.properties.creatable = true } else { input.properties.isDisabled = true input.properties.creatable = false } input.reloadData() } } //MARK: Button Action @IBAction func buttonClicked_GotoAction(_ sender: Any) { self.setONButton(button: pageRadio_) self.enableTextField(textField: pageInput_) // self.view.window?.makeFirstResponder(self.outlineTargetPageIndexTextField) } @IBAction func buttonClicked_URLAction(_ sender: Any) { self.setONButton(button: self.webRadio_) self.enableTextField(textField: webInput_) // self.view.window?.makeFirstResponder(self.outlineURLTextField) if (self.outlineTargetPageIndexTextField.stringValue == "0" || self.outlineTargetPageIndexTextField.stringValue.lengthOfBytes(using: String.Encoding(rawValue: String.Encoding.utf16.rawValue)) < 1){ self.outlineTargetPageIndexTextField.stringValue = "\(self.currentPageIndex + 1)" } } @IBAction func buttonClicked_MailAction(_ sender: Any) { self.setONButton(button: self.emailRadio_) self.enableTextField(textField: emailInput_) // self.view.window?.makeFirstResponder(self.mailAddressTextField) if (self.outlineTargetPageIndexTextField.stringValue == "0" || self.outlineTargetPageIndexTextField.stringValue.lengthOfBytes(using: String.Encoding(rawValue: String.Encoding.utf16.rawValue)) < 1){ self.outlineTargetPageIndexTextField.stringValue = "\(self.currentPageIndex + 1)" } } @objc private func _cancelAction() { itemClick?(1) } @objc private func _okAction() { itemClick?(2, self) } } extension KMOutlineEditViewController : NSTextFieldDelegate,NSTextViewDelegate { func controlTextDidChange(_ obj: Notification) { if self.outlineTargetPageIndexTextField.isEqual(obj.object) { let number = NSNumber(value: Int(self.outlineTargetPageIndexTextField.stringValue) ?? 0) let string = self.outlineTargetPageIndexTextField.formatter?.string(for: number) let s = Int(string ?? "") if s != 0 { self.currentPageIndex = (s ?? 0) - 1 } self.outlineTargetPageIndexTextField.stringValue = string ?? "" } } }