Browse Source

【2025】【BOTA】搜索列表替换窗口整理代码

tangchao 3 months ago
parent
commit
21931e590d

+ 0 - 816
PDF Office/PDF Master/Class/Tools/Search/Window/KMSearchReplaceWindowController.swift

@@ -1,816 +0,0 @@
-//
-//  KMSearchReplaceWindowController.swift
-//  PDF Reader Pro
-//
-//  Created by User-Tangchao on 2024/8/7.
-//
-
-import Cocoa
-import KMComponentLibrary
-
-class KMSearchReplaceWindowController_Window: NSWindow {
-    override var canBecomeMain: Bool {
-        return true
-    }
-    
-    override var canBecomeKey: Bool {
-        return true
-    }
-}
-
-@objc enum KMSearchReplaceType: Int {
-    case none = 0
-    case search = 1
-    case replace = 2
-}
-
-class KMNSearchReplaceTitleBarView: NSView {
-    private lazy var closeButton_: ComponentButton = {
-        let view = ComponentButton()
-        let prop = ComponentButtonProperty()
-        prop.type = .text_gray
-        prop.size = .xxs
-        prop.onlyIcon = true
-        prop.icon = NSImage(named: "KMImageNameSearchReplaceClose")
-        view.properties = prop
-        view.setTarget(self, action: #selector(closeAction))
-        return view
-    }()
-    
-    private lazy var switchButton_: ComponentButton = {
-        let view = ComponentButton()
-        let prop = ComponentButtonProperty()
-        prop.type = .text_gray
-        prop.size = .xxs
-        prop.onlyIcon = true
-        prop.icon = NSImage(named: "KMImageNameSearchReplaceSwitch")
-        view.properties = prop
-        view.setTarget(self, action: #selector(switchAction))
-        return view
-    }()
-    
-    private lazy var titleLabel_: NSTextField = {
-        let view = NSTextField(labelWithString: "")
-        return view
-    }()
-    
-    var titleLabel: NSTextField {
-        get {
-            return titleLabel_
-        }
-    }
-    
-    var itemClick: KMCommonClickBlock?
-    
-    convenience init() {
-        self.init(frame: .init(x: 0, y: 0, width: 300, height: 44))
-    }
-    
-    override func awakeFromNib() {
-        super.awakeFromNib()
-        
-        initSubviews()
-    }
-    
-    override init(frame frameRect: NSRect) {
-        super.init(frame: frameRect)
-        
-        initSubviews()
-    }
-    
-    required init?(coder: NSCoder) {
-        super.init(coder: coder)
-        
-        initSubviews()
-    }
-    
-    func initSubviews() {
-        addSubview(closeButton_)
-        addSubview(switchButton_)
-        addSubview(titleLabel_)
-        
-        closeButton_.km_add_size_constraint(size: .init(width: 24, height: 24))
-        closeButton_.km_add_top_constraint(constant: 8)
-        closeButton_.km_add_trailing_constraint(constant: -8)
-        
-        switchButton_.km_add_size_constraint(size: .init(width: 24, height: 24))
-        switchButton_.km_add_top_constraint(constant: 8)
-        switchButton_.km_add_trailing_constraint(equalTo: closeButton_, attribute: .leading, constant: -8)
-        
-        titleLabel_.km_add_leading_constraint(constant: 24)
-        titleLabel_.km_add_top_constraint(constant: 24)
-    }
-    
-    @objc func closeAction() {
-        itemClick?(1)
-    }
-    
-    @objc func switchAction() {
-        itemClick?(2)
-    }
-}
-
-class KMNSearchReplaceSearchItemView: NSView {
-    private lazy var previousButton_: ComponentButton = {
-        let view = ComponentButton()
-        view.properties = ComponentButtonProperty(type: .gray, size: .s, state: .normal, onlyIcon: true, icon: NSImage(named: "KMImageNameBotaSearchPreviousDisable"))
-//        view.setTarget(self, action: #selector(previousAction))
-        return view
-    }()
-    
-    private lazy var nextButton_: ComponentButton = {
-        let view = ComponentButton()
-        view.properties = ComponentButtonProperty(type: .gray, size: .s, state: .normal, onlyIcon: true, icon: NSImage(named: "KMImageNameBotaSearchNext"))
-//        view.setTarget(self, action: #selector(nextActon))
-        return view
-    }()
-    
-    private lazy var input_: ComponentInput = {
-        let view = ComponentInput()
-        let prop = ComponentInputProperty()
-        prop.size = .s
-        prop.showPrefix = true
-        prop.showSuffix = true
-        view.properties = prop
-        return view
-    }()
-    
-    convenience init() {
-        self.init(frame: .init(x: 0, y: 0, width: 300, height: 44))
-    }
-    
-    override func awakeFromNib() {
-        super.awakeFromNib()
-        
-        initSubviews()
-    }
-    
-    override init(frame frameRect: NSRect) {
-        super.init(frame: frameRect)
-        
-        initSubviews()
-    }
-    
-    required init?(coder: NSCoder) {
-        super.init(coder: coder)
-        
-        initSubviews()
-    }
-    
-    func initSubviews() {
-        addSubview(nextButton_)
-        addSubview(previousButton_)
-        addSubview(input_)
-        
-        nextButton_.km_add_size_constraint(size: .init(width: 32, height: 32))
-        nextButton_.km_add_top_constraint(constant: 0)
-        nextButton_.km_add_trailing_constraint(constant: -24)
-        
-        previousButton_.km_add_size_constraint(size: .init(width: 32, height: 32))
-        previousButton_.km_add_top_constraint(constant: 0)
-        previousButton_.km_add_trailing_constraint(equalTo: nextButton_, attribute: .leading, constant: -8)
-        
-        input_.km_add_top_constraint(constant: 0)
-        input_.km_add_leading_constraint(constant: 24)
-        input_.km_add_height_constraint(constant: 32)
-        input_.km_add_trailing_constraint(equalTo: previousButton_, attribute: .leading, constant: -8)
-    }
-}
-
-class KMSearchReplaceWindowController: KMNBaseWindowController {
-    @IBOutlet weak var titleBarBox: NSBox!
-    @IBOutlet weak var closeButton: NSButton!
-    
-    @IBOutlet weak var tabBox: NSBox!
-    @IBOutlet weak var searchTabButton: NSButton!
-    @IBOutlet weak var replaceTabButton: NSButton!
-    @IBOutlet weak var tabBottomLine: NSBox!
-    @IBOutlet weak var tabSelectedLine: NSBox!
-    @IBOutlet weak var tabSelectedLineLeftConst: NSLayoutConstraint!
-    
-    @IBOutlet weak var searchBox: NSBox!
-    @IBOutlet weak var searchTitleLabel: NSTextField!
-    @IBOutlet weak var searchInputBox: NSBox!
-    @IBOutlet weak var searchInputView: NSTextField!
-    @IBOutlet weak var matchWholeCheck: NSButton!
-    @IBOutlet weak var caseSensitiveCheck: NSButton!
-    @IBOutlet weak var previousButton: NSButton!
-    @IBOutlet weak var nextButton: NSButton!
-    
-    @IBOutlet weak var replaceBox: NSBox!
-    @IBOutlet weak var replaceTitleLabel: NSTextField!
-    @IBOutlet weak var replaceInputBox: NSBox!
-    @IBOutlet weak var replaceInputView: NSTextField!
-    
-    @IBOutlet weak var bottomBarBox: NSBox!
-    @IBOutlet weak var replaceButton: NSButton!
-    @IBOutlet weak var replaceAllButton: NSButton!
-    
-    var replaceCallback: (() -> Void)?
-    var itemClick: KMCommonClickBlock?
-    
-    private var _modalSession: NSApplication.ModalSession?
-    
-    private var handdler: KMSearchReplaceHanddler = KMSearchReplaceHanddler()
-    private var type_: KMSearchReplaceType = .search
-    
-    private var currentSel: CPDFSelection?
-    
-    private var finding_ = false
-    
-    private lazy var titleBarView_: KMNSearchReplaceTitleBarView = {
-        let view = KMNSearchReplaceTitleBarView()
-        return view
-    }()
-    
-    private lazy var searchItemView_: KMNSearchReplaceSearchItemView = {
-        let view = KMNSearchReplaceSearchItemView()
-        return view
-    }()
-    
-    private lazy var replaceItemView_: KMNSearchReplacePopItemView = {
-        let view = KMNSearchReplacePopItemView()
-        return view
-    }()
-    
-    deinit {
-        KMPrint("KMSearchReplaceWindowController deinit.")
-        
-        DistributedNotificationCenter.default().removeObserver(self)
-    }
-    
-    convenience init(with pdfView: CPDFView?, type: KMSearchReplaceType) {
-        self.init(windowNibName: "KMSearchReplaceWindowController")
-        
-        self.handdler.pdfView = pdfView
-        self.type_ = type
-    }
-
-    override func windowDidLoad() {
-        super.windowDidLoad()
-
-        self.initDefaultValue()
-        self.switchType(self.type_)
-        self.updateViewColor()
-        DistributedNotificationCenter.default().addObserver(self, selector: #selector(themeChanged), name: NSApplication.interfaceThemeChangedNotification, object: nil)
-    }
-    
-    func initDefaultValue() {
-        self.window?.isMovableByWindowBackground = true
-        
-        self.window?.contentView?.wantsLayer = true
-        self.window?.contentView?.layer?.cornerRadius = 4
-        self.window?.contentView?.layer?.masksToBounds = true
-        
-        self.window?.backgroundColor = .clear
-        
-        self.titleBarBox.boxType = .custom
-        self.titleBarBox.borderWidth = 0
-        self.closeButton.imagePosition = .imageOnly
-        self.closeButton.image = NSImage(named: "KMImageNameUXIconBtnCloseNor")
-        self.closeButton.target = self
-        self.closeButton.action = #selector(_closeAction)
-        self.titleBarBox.contentView = titleBarView_
-        titleBarView_.titleLabel.font = .SFProTextRegularFont(14)
-        titleBarView_.itemClick = { [unowned self] idx, _ in
-            if idx == 1 {
-                self._closeAction(NSButton())
-            } else if idx == 2 {
-                self._closeAction(NSButton())
-                
-                self.itemClick?(1)
-            }
-        }
-        
-        self.searchTabButton.target = self
-        self.searchTabButton.action = #selector(_searchTabAction)
-        self.searchTabButton.title = "  \(NSLocalizedString("Search", comment: ""))"
-        self.searchTabButton.image = NSImage(named: "KMImageNameSearchIcon")
-        self.searchTabButton.imagePosition = .imageLeft
-//        self.searchTabButton.imageHugsTitle = true
-        
-        searchBox.contentView = searchItemView_
-        
-        self.replaceTabButton.target = self
-        self.replaceTabButton.action = #selector(_replaceTabAction)
-        self.replaceTabButton.title = "  \(NSLocalizedString("Replace", comment: ""))"
-        self.replaceTabButton.image = NSImage(named: "KMImageNameReplaceIcon")
-        self.replaceTabButton.imagePosition = .imageLeft
-        self.tabSelectedLine.borderWidth = 0
-        self.tabSelectedLine.fillColor = NSColor(hex: "#4982E6")
-        
-        self.searchBox.borderWidth = 0
-        // #0E1114
-        self.searchTitleLabel.stringValue = NSLocalizedString("Search", comment: "")
-        self.searchTitleLabel.font = NSFont.SFProTextBoldFont(14)
-        self.searchInputBox.cornerRadius = 0
-        self.searchInputView.drawsBackground = false
-        self.searchInputView.isBordered = false
-        self.searchInputView.delegate = self
-        
-        self.matchWholeCheck.title = NSLocalizedString("Whole Words Only", comment: "")
-        self.matchWholeCheck.target = self
-        self.matchWholeCheck.action = #selector(_checkAction)
-        self.matchWholeCheck.state = .off
-        self.caseSensitiveCheck.title = NSLocalizedString("Ignore Case", comment: "")
-        self.caseSensitiveCheck.target = self
-        self.caseSensitiveCheck.action = #selector(_checkAction)
-        self.caseSensitiveCheck.state = .off
-        self.previousButton.title = NSLocalizedString("Next", comment: "")
-        self.previousButton.target = self
-        self.previousButton.action = #selector(_nextAction)
-        self.nextButton.title = NSLocalizedString("Previous", comment: "")
-        self.nextButton.target = self
-        self.nextButton.action = #selector(_previousAction)
-        
-        self.replaceBox.borderWidth = 0
-        self.replaceTitleLabel.stringValue = NSLocalizedString("Replace with", comment: "")
-        self.replaceTitleLabel.font = NSFont.SFProTextBoldFont(14)
-        self.replaceInputBox.cornerRadius = 0
-        self.replaceInputView.drawsBackground = false
-        self.replaceInputView.isBordered = false
-        self.replaceInputView.delegate = self
-        
-        replaceBox.contentView = replaceItemView_
-        
-        self.bottomBarBox.borderWidth = 0
-        self.replaceButton.title = NSLocalizedString("Replace", comment: "")
-        self.replaceButton.target = self
-        self.replaceButton.action = #selector(_replaceAction)
-        self.replaceAllButton.title = NSLocalizedString("Replace All", comment: "")
-        self.replaceAllButton.target = self
-        self.replaceAllButton.action = #selector(_replaceAllAction)
-        
-        if self.searchInputView.stringValue.isEmpty {
-            self.previousButton.isEnabled = false
-            self.nextButton.isEnabled = false
-            self.replaceButton.isEnabled = false
-            self.replaceAllButton.isEnabled = false
-        } else {
-            self.previousButton.isEnabled = true
-            self.nextButton.isEnabled = true
-            self.replaceButton.isEnabled = true
-            self.replaceAllButton.isEnabled = true
-            
-            self.currentSel = nil
-        }
-    }
-    
-    override func updateUILanguage() {
-        super.updateUILanguage()
-        
-        KMMainThreadExecute {
-            self.titleBarView_.titleLabel.stringValue = KMLocalizedString("Search")
-        }
-    }
-    
-    override func updateUIThemeColor() {
-        super.updateUIThemeColor()
-        
-        KMMainThreadExecute {
-            self.titleBarView_.titleLabel.textColor = KMNColorTools.colorText_1()
-        }
-    }
-    
-    // MARK: - Actions
-    
-    @objc private func _closeAction(_ sender: NSButton) {
-        self.endModal(sender)
-        
-        self.handdler.clearData()
-    }
-    
-    @objc private func _previousAction(_ sender: NSButton) {
-        let isEditing = self.handdler.pdfView?.isEditing() ?? false
-        if isEditing == false {
-            guard let model = self.handdler.searchResults.safe_element(for: self.handdler.showIdx-1) as? KMSearchMode else {
-                return
-            }
-            self.handdler.showIdx -= 1
-            self.handdler.showSelection(model.selection)
-        } else {
-            if let _ = self.currentSel {
-                self.currentSel = self.handdler.pdfView?.document.findForwardEditText()
-                if let sel = self.currentSel {
-                    self.handdler.showSelection(sel)
-                } else {
-                    let alert = NSAlert()
-                    alert.messageText = NSLocalizedString("No related content found, please change keyword.", comment: "")
-                    alert.addButton(withTitle: NSLocalizedString("OK", comment: ""))
-//                    alert.runModal()
-                    alert.beginSheetModal(for: (self.window)!)
-                }
-            } else {
-                if self.finding_ {
-                    return
-                }
-                self.finding_ = true
-                let searchS = self.searchInputView.stringValue
-                let opt = self.fetchSearchOptions()
-                self._beginLoading()
-                DispatchQueue.global().async {
-                    let datas = self.handdler.pdfView?.document.startFindEditText(from: nil, with: searchS, options: opt)
-                    DispatchQueue.main.async {
-                        self._endLoading()
-                        self.finding_ = false
-                        let sel = datas?.first?.first
-                        if sel == nil {
-                            let alert = NSAlert()
-                            alert.messageText = NSLocalizedString("No related content found, please change keyword.", comment: "")
-                            alert.addButton(withTitle: NSLocalizedString("OK", comment: ""))
-//                            alert.runModal()
-                            alert.beginSheetModal(for: (self.window)!)
-                            return
-                        }
-                        self.currentSel = sel
-                        self.handdler.showSelection(sel)
-                    }
-                }
-            }
-        }
-    }
-    
-    @objc private func _nextAction(_ sender: NSButton) {
-        let isEditing = self.handdler.pdfView?.isEditing() ?? false
-        if isEditing == false {
-            guard let model = self.handdler.searchResults.safe_element(for: self.handdler.showIdx+1) as? KMSearchMode else {
-                return
-            }
-            self.handdler.showIdx += 1
-            self.handdler.showSelection(model.selection)
-        } else {
-            if let _ = self.currentSel {
-                self.currentSel = self.handdler.pdfView?.document.findBackwordEditText()
-                if let sel = self.currentSel {
-                    self.handdler.showSelection(sel)
-                } else {
-                    let alert = NSAlert()
-                    alert.messageText = NSLocalizedString("No related content found, please change keyword.", comment: "")
-                    alert.addButton(withTitle: NSLocalizedString("OK", comment: ""))
-//                    alert.runModal()
-                    alert.beginSheetModal(for: (self.window)!)
-                }
-            } else {
-                if self.finding_ {
-                    return
-                }
-                self.finding_ = true
-                let searchS = self.searchInputView.stringValue
-                let opt = self.fetchSearchOptions()
-                self._beginLoading()
-                DispatchQueue.global().async {
-                
-                    let datas = self.handdler.pdfView?.document.startFindEditText(from: nil, with: searchS, options: opt)
-                    DispatchQueue.main.async {
-                        self._endLoading()
-                        self.finding_ = false
-                        let sel = datas?.first?.first
-                        if sel == nil {
-                            let alert = NSAlert()
-                            alert.messageText = NSLocalizedString("No related content found, please change keyword.", comment: "")
-                            alert.addButton(withTitle: NSLocalizedString("OK", comment: ""))
-//                            alert.runModal()
-                            alert.beginSheetModal(for: (self.window)!)
-                            return
-                        }
-                        self.currentSel = sel
-                        self.handdler.showSelection(sel)
-                    }
-                }
-            }
-        }
-    }
-    
-    @objc private func _checkAction(_ sender: NSButton) {
-        self.currentSel = nil
-    }
-    
-    @objc private func _searchTabAction(_ sender: NSButton) {
-        self.switchType(.search, animate: true)
-    }
-    
-    @objc private func _replaceTabAction(_ sender: NSButton) {
-        self.switchType(.replace, animate: true)
-    }
-    
-    @objc private func _replaceAction(_ sender: NSButton) {
-        let isEditing =  self.handdler.pdfView?.isEditing() ?? false
-        if isEditing == false {
-            NSSound.beep()
-            return
-        }
-        if let sel = self.currentSel {
-            let searchS = self.searchInputView.stringValue
-            let replaceS = self.replaceInputView.stringValue
-            let success = self.handdler.replace(searchS: searchS, replaceS: replaceS, sel: sel) { [weak self] newSel in
-                self?.handdler.showSelection(newSel)
-            }
-            if success {
-//                self.handdler.showSelection(sel)
-            }
-        } else { // 先查找
-            if self.finding_ {
-                return
-            }
-            self.finding_ = true
-            let searchS = self.searchInputView.stringValue
-            let opt = self.fetchSearchOptions()
-            self._beginLoading()
-            DispatchQueue.global().async {
-                let datas = self.handdler.pdfView?.document.startFindEditText(from: nil, with: searchS, options: opt)
-                DispatchQueue.main.async {
-                    self._endLoading()
-                    self.finding_ = false
-                    let sel = datas?.first?.first
-                    if sel == nil {
-                        let alert = NSAlert()
-                        alert.messageText = NSLocalizedString("No related content found, please change keyword.", comment: "")
-                        alert.addButton(withTitle: NSLocalizedString("OK", comment: ""))
-//                        alert.runModal()
-                        alert.beginSheetModal(for: (self.window)!)
-                        return
-                    }
-                    self.currentSel = sel
-                    self.handdler.showSelection(sel)
-                }
-            }
-        }
-    }
-    
-    @objc private func _replaceAllAction(_ sender: NSButton) {
-        let isEditing =  self.handdler.pdfView?.isEditing() ?? false
-        if isEditing == false {
-            NSSound.beep()
-            return
-        }
-        
-        let datas = self.handdler.pdfView?.document.findEditSelections() ?? []
-        if datas.isEmpty {
-            let alert = NSAlert()
-            alert.informativeText = NSLocalizedString("No related content found, please change keyword.", comment: "")
-            alert.addButton(withTitle: NSLocalizedString("OK", comment: ""))
-//            alert.beginSheetModal(for: NSApp.mainWindow!)
-//            alert.runModal()
-            alert.beginSheetModal(for: (self.window)!)
-            return
-        }
-        
-        if self.finding_ {
-            return
-        }
-        self.finding_ = true
-        let searchS = self.searchInputView.stringValue
-        let replaceS = self.replaceInputView.stringValue
-        self._beginLoading()
-        DispatchQueue.global().async {
-            self.handdler.pdfView?.document.replaceAllEditText(with: searchS, toReplace: replaceS)
-            self.currentSel = nil
-            
-            DispatchQueue.main.async {
-                self._endLoading()
-                self.finding_ = false
-                self.handdler.pdfView?.setHighlightedSelection(nil, animated: false)
-                self.handdler.pdfView?.setNeedsDisplayForVisiblePages()
-            }
-        }
-    }
-    
-    private func fetchSearchOptions() -> CPDFSearchOptions {
-        var opt = CPDFSearchOptions()
-        let isCase = self.caseSensitiveCheck.state == .off
-        if isCase {
-            opt.insert(.caseSensitive)
-        }
-        let isWholeWord = self.matchWholeCheck.state == .on
-        if isWholeWord {
-            opt.insert(.matchWholeWord)
-        }
-        return opt
-    }
-    
-    private func updateViewColor() {
-        let isDark = KMAppearance.isDarkMode()
-        if isDark {
-//            self.window?.backgroundColor = NSColor(hex: "#393C3E")
-            self.window?.contentView?.wantsLayer = true
-            self.window?.contentView?.layer?.backgroundColor = NSColor(hex: "#393C3E").cgColor
-            
-            self.searchInputBox.borderColor = NSColor(hex: "#56585A")
-            self.replaceInputBox.borderColor = NSColor(hex: "#56585A")
-        } else {
-//            self.window?.backgroundColor = .white
-            self.window?.contentView?.wantsLayer = true
-            self.window?.contentView?.layer?.backgroundColor = .white
-            
-            self.searchInputBox.borderColor = NSColor(hex: "#DADBDE")
-            self.replaceInputBox.borderColor = NSColor(hex: "#DADBDE")
-        }
-        
-        self.switchType(self.type_)
-    }
-    
-    func switchType(_ type: KMSearchReplaceType, animate: Bool = false) {
-        if type == .replace {
-            if IAPProductsManager.default().isAvailableAllFunction() == false {
-//                KMPurchaseCompareWindowController.sharedInstance().showWindow(nil)
-                let winC = KMPurchaseCompareWindowController.sharedInstance()
-                winC?.showWindow(nil)
-                guard let win = winC?.window else {
-                    return
-                }
-                self.window?.addChildWindow(win, ordered: .above)
-                return
-            }
-        }
-        
-        self.type_ = type
-        let isDark = KMAppearance.isDarkMode()
-        var selectedColor = NSColor(hex: "0E1114")
-        var unSelectedColor = NSColor(hex: "757780")
-        if isDark {
-            selectedColor = .white
-            unSelectedColor = NSColor(hex: "#7E7F85")
-        }
-        
-        if type == .search { // 248 112
-            self.tabSelectedLineLeftConst.animator().constant = 24
-            
-            self.searchTabButton.setTitleColor(selectedColor)
-            self.searchTabButton.image = NSImage(named: "KMImageNameSearchIcon")
-            self.replaceTabButton.setTitleColor(unSelectedColor)
-            self.replaceTabButton.image = NSImage(named: "KMImageNameReplaceUnselectedIcon")
-            
-//            DispatchQueue.main.async {
-                self.replaceBox.isHidden = true
-                self.bottomBarBox.isHidden = true
-//            }
-            
-            var frame = self.window?.frame ?? .zero
-//            let height: CGFloat = 248+20
-            let height: CGFloat = 112
-            let heightOffset = frame.size.height - height
-            frame.origin.y += heightOffset
-            frame.size.height = height
-            self.window?.setFrame(frame, display: true, animate: animate)
-            self.window?.minSize = frame.size
-            self.window?.maxSize = frame.size
-        } else if type == .replace { // 388 208
-            self.tabSelectedLineLeftConst.animator().constant = 140
-            
-            self.searchTabButton.setTitleColor(unSelectedColor)
-            self.searchTabButton.image = NSImage(named: "KMImageNameSearchUnselectedIcon")
-            self.replaceTabButton.setTitleColor(selectedColor)
-            self.replaceTabButton.image = NSImage(named: "KMImageNameReplaceIcon")
-            
-            DispatchQueue.main.async {
-                self.replaceBox.isHidden = false
-                self.bottomBarBox.isHidden = false
-            }
-            
-            var frame = self.window?.frame ?? .zero
-            let height:CGFloat = 208
-            let heightOffset = frame.size.height-height
-            frame.origin.y += heightOffset
-            frame.size.height = height
-            self.window?.setFrame(frame, display: true, animate: animate)
-            self.window?.minSize = frame.size
-            self.window?.maxSize = frame.size
-            
-            // 将事件回调出去
-            self.replaceCallback?()
-        }
-    }
-    
-    private func _beginLoading() {
-        self.window?.contentView?.beginLoading()
-    }
-    
-    private func _endLoading() {
-        self.window?.contentView?.endLoading()
-    }
-    
-    func startModal(_ sender: AnyObject?) {
-        NSApp.stopModal()
-        
-        var modalCode: NSApplication.ModalResponse?
-        if let _win = self.window {
-            self._modalSession = NSApp.beginModalSession(for: _win)
-            repeat {
-                modalCode = NSApp.runModalSession(self._modalSession!)
-            } while (modalCode == .continue)
-        }
-    }
-    
-    func endModal(_ sender: AnyObject?) {
-        if let session = self._modalSession {
-            NSApp.stopModal()
-            NSApp.endModalSession(session)
-            self.window?.orderOut(self)
-        }
-        if let winC = self.window?.kmCurrentWindowC, winC.isEqual(to: self) {
-            self.window?.kmCurrentWindowC = nil
-        }
-    }
-    
-    // MARK: - Noti Methods
-    
-    @objc func themeChanged(_ notification: Notification) {
-        DispatchQueue.main.asyncAfter(deadline: .now() + 0.3) {
-            self.updateViewColor()
-        }
-    }
-}
-
-extension KMSearchReplaceWindowController: NSTextFieldDelegate {
-    func controlTextDidEndEditing(_ obj: Notification) {
-        
-    }
-    
-    func controlTextDidChange(_ obj: Notification) {
-        if self.searchInputView.isEqual(to: obj.object) { // 搜索输入框
-            if self.searchInputView.stringValue.isEmpty {
-                self.previousButton.isEnabled = false
-                self.nextButton.isEnabled = false
-                self.replaceButton.isEnabled = false
-                self.replaceAllButton.isEnabled = false
-            } else {
-                self.previousButton.isEnabled = true
-                self.nextButton.isEnabled = true
-                self.replaceButton.isEnabled = true
-                self.replaceAllButton.isEnabled = true
-                
-                self.currentSel = nil
-            }
-        }
-    }
-    
-    func control(_ control: NSControl, textView: NSTextView, doCommandBy commandSelector: Selector) -> Bool {
-        switch commandSelector {
-        case #selector(NSResponder.insertNewline(_:)):
-            if let inputView = control as? NSTextField {
-//                //当当前TextField按下enter
-                if inputView == self.searchInputView {
-                    let isCase = self.caseSensitiveCheck.state == .off
-                    let isWholeWord = self.matchWholeCheck.state == .on
-                    let isEditing = self.handdler.pdfView?.isEditing() ?? false
-                    if isEditing == false {
-                        if self.finding_ {
-                            return false
-                        }
-                        self.finding_ = true
-                        self._beginLoading()
-                        self.handdler.search(keyword: self.searchInputView.stringValue, isCase: isCase, isWholeWord: isWholeWord, callback: { [weak self] datas in
-                            self?.finding_ = false
-                            self?._endLoading()
-
-                            guard let sels = datas, sels.isEmpty == false else {
-                                let alert = NSAlert()
-                                alert.informativeText = NSLocalizedString("No related content found, please change keyword.", comment: "")
-                                alert.addButton(withTitle: NSLocalizedString("OK", comment: ""))
-//                                alert.runModal()
-                                alert.beginSheetModal(for: (self?.window)!)
-                                return
-                            }
-                            if let sel = datas?.first?.selection {
-                                self?.handdler.showIdx = 0
-                                self?.handdler.showSelection(sel)
-                            }
-                        })
-                    } else {
-                        if self.finding_ {
-                            return false
-                        }
-                        self.finding_ = true
-                        let searchS = self.searchInputView.stringValue
-                        let opt = self.fetchSearchOptions()
-                        self._beginLoading()
-                        DispatchQueue.global().async {
-                            let datas = self.handdler.pdfView?.document.findEditAllPageString(searchS, with: opt) ?? []
-                            DispatchQueue.main.async {
-                                self.finding_ = false
-                                self._endLoading()
-                                if datas.isEmpty {
-                                    let alert = NSAlert()
-                                    alert.informativeText = NSLocalizedString("No related content found, please change keyword.", comment: "")
-                                    alert.addButton(withTitle: NSLocalizedString("OK", comment: ""))
-//                                    alert.beginSheetModal(for: NSApp.mainWindow!)
-//                                    alert.runModal()
-                                    alert.beginSheetModal(for: (self.window)!)
-                                    return
-                                }
-                                self.currentSel = datas.first?.first
-                                if let sel = self.currentSel {
-                                    self.handdler.showSelection(sel)
-                                }
-                            }
-                            
-                        }
-                    }
-                }
-            }
-            return true
-        default:
-            return false
-        }
-    }
-}

+ 0 - 358
PDF Office/PDF Master/Class/Tools/Search/Window/KMSearchReplaceWindowController.xib

@@ -1,358 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<document type="com.apple.InterfaceBuilder3.Cocoa.XIB" version="3.0" toolsVersion="21507" targetRuntime="MacOSX.Cocoa" propertyAccessControl="none" useAutolayout="YES" customObjectInstantitationMethod="direct">
-    <dependencies>
-        <deployment identifier="macosx"/>
-        <plugIn identifier="com.apple.InterfaceBuilder.CocoaPlugin" version="21507"/>
-        <capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
-    </dependencies>
-    <objects>
-        <customObject id="-2" userLabel="File's Owner" customClass="KMSearchReplaceWindowController" customModule="PDF_Reader_Pro" customModuleProvider="target">
-            <connections>
-                <outlet property="bottomBarBox" destination="aX3-LQ-PXi" id="pTa-Jj-51B"/>
-                <outlet property="caseSensitiveCheck" destination="X98-Hr-uLG" id="m9g-IW-cLu"/>
-                <outlet property="closeButton" destination="883-OE-nPf" id="do0-4i-9Wi"/>
-                <outlet property="matchWholeCheck" destination="tox-LJ-GtX" id="oMU-xm-hmP"/>
-                <outlet property="nextButton" destination="qxA-YM-xIq" id="V1I-bs-Gsy"/>
-                <outlet property="previousButton" destination="FCV-r1-BiZ" id="fP2-ZK-Ff3"/>
-                <outlet property="replaceAllButton" destination="fxe-UM-ZCK" id="UgL-wl-Ytq"/>
-                <outlet property="replaceBox" destination="4kx-6q-nJ8" id="fTS-By-eXX"/>
-                <outlet property="replaceButton" destination="3l4-91-BR7" id="7ao-WQ-KzS"/>
-                <outlet property="replaceInputBox" destination="LkR-Op-2Jo" id="QRf-mq-z6Y"/>
-                <outlet property="replaceInputView" destination="7BJ-XF-ZVY" id="4hW-bO-JeZ"/>
-                <outlet property="replaceTabButton" destination="glm-Go-gH2" id="Wg5-Jc-yco"/>
-                <outlet property="replaceTitleLabel" destination="Y3N-ik-Fnb" id="581-K4-k8r"/>
-                <outlet property="searchBox" destination="cdc-3d-gh5" id="9Se-Lu-XEN"/>
-                <outlet property="searchInputBox" destination="Ej6-th-OuJ" id="2SX-y1-k6p"/>
-                <outlet property="searchInputView" destination="xLT-x3-sTt" id="XDG-eW-Z14"/>
-                <outlet property="searchTabButton" destination="1cp-Kv-Xgy" id="ErO-ct-H2f"/>
-                <outlet property="searchTitleLabel" destination="kXL-bh-JQK" id="FDZ-6m-m7N"/>
-                <outlet property="tabBottomLine" destination="Wap-a3-1zt" id="Od9-va-tNP"/>
-                <outlet property="tabBox" destination="TYX-fO-lan" id="k0D-nW-DRi"/>
-                <outlet property="tabSelectedLine" destination="lKS-tK-sLu" id="gJs-LM-97f"/>
-                <outlet property="tabSelectedLineLeftConst" destination="Kux-3H-btA" id="il6-6v-P26"/>
-                <outlet property="titleBarBox" destination="h69-NL-IH7" id="CIc-G8-vOa"/>
-                <outlet property="window" destination="F0z-JX-Cv5" id="gIp-Ho-8D9"/>
-            </connections>
-        </customObject>
-        <customObject id="-1" userLabel="First Responder" customClass="FirstResponder"/>
-        <customObject id="-3" userLabel="Application" customClass="NSObject"/>
-        <window title="Window" allowsToolTipsWhenApplicationIsInactive="NO" autorecalculatesKeyViewLoop="NO" releasedWhenClosed="NO" animationBehavior="default" id="F0z-JX-Cv5" customClass="KMSearchReplaceWindowController_Window" customModule="PDF_Reader_Pro" customModuleProvider="target">
-            <windowStyleMask key="styleMask" closable="YES" miniaturizable="YES" resizable="YES"/>
-            <windowPositionMask key="initialPositionMask" leftStrut="YES" rightStrut="YES" topStrut="YES" bottomStrut="YES"/>
-            <rect key="contentRect" x="196" y="240" width="280" height="388"/>
-            <rect key="screenRect" x="0.0" y="0.0" width="1440" height="875"/>
-            <value key="minSize" type="size" width="280" height="388"/>
-            <value key="maxSize" type="size" width="280" height="388"/>
-            <value key="minFullScreenContentSize" type="size" width="280" height="388"/>
-            <value key="maxFullScreenContentSize" type="size" width="280" height="388"/>
-            <view key="contentView" id="se5-gp-TjO">
-                <rect key="frame" x="0.0" y="0.0" width="280" height="388"/>
-                <autoresizingMask key="autoresizingMask"/>
-                <subviews>
-                    <box boxType="custom" cornerRadius="4" title="Box" translatesAutoresizingMaskIntoConstraints="NO" id="h69-NL-IH7">
-                        <rect key="frame" x="0.0" y="332" width="280" height="56"/>
-                        <view key="contentView" id="Zea-eJ-KkO">
-                            <rect key="frame" x="1" y="1" width="278" height="54"/>
-                            <autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
-                            <subviews>
-                                <button verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="883-OE-nPf">
-                                    <rect key="frame" x="217" y="22" width="45" height="16"/>
-                                    <buttonCell key="cell" type="bevel" title="Button" bezelStyle="rounded" alignment="center" imageScaling="proportionallyDown" inset="2" id="Xc1-vH-gHT">
-                                        <behavior key="behavior" pushIn="YES" lightByBackground="YES" lightByGray="YES"/>
-                                        <font key="font" metaFont="system"/>
-                                    </buttonCell>
-                                </button>
-                            </subviews>
-                            <constraints>
-                                <constraint firstItem="883-OE-nPf" firstAttribute="top" secondItem="Zea-eJ-KkO" secondAttribute="top" constant="16" id="ggj-JC-6oK"/>
-                                <constraint firstAttribute="trailing" secondItem="883-OE-nPf" secondAttribute="trailing" constant="16" id="stY-bX-Fcc"/>
-                            </constraints>
-                        </view>
-                        <constraints>
-                            <constraint firstAttribute="height" constant="56" id="QCO-3b-P69"/>
-                        </constraints>
-                    </box>
-                    <box boxType="custom" borderWidth="0.0" cornerRadius="4" title="Box" translatesAutoresizingMaskIntoConstraints="NO" id="TYX-fO-lan">
-                        <rect key="frame" x="0.0" y="332" width="280" height="0.0"/>
-                        <view key="contentView" id="kB0-PA-LMT">
-                            <rect key="frame" x="0.0" y="0.0" width="280" height="0.0"/>
-                            <autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
-                            <subviews>
-                                <box boxType="custom" borderWidth="0.0" cornerRadius="4" title="Box" translatesAutoresizingMaskIntoConstraints="NO" id="s0x-OF-qoP">
-                                    <rect key="frame" x="16" y="0.0" width="124" height="0.0"/>
-                                    <view key="contentView" id="Yce-JC-LZV">
-                                        <rect key="frame" x="0.0" y="0.0" width="124" height="0.0"/>
-                                        <autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
-                                        <subviews>
-                                            <button verticalHuggingPriority="750" misplaced="YES" translatesAutoresizingMaskIntoConstraints="NO" id="1cp-Kv-Xgy">
-                                                <rect key="frame" x="31" y="-29" width="61" height="20"/>
-                                                <buttonCell key="cell" type="bevel" title="Button" bezelStyle="rounded" alignment="center" imageScaling="proportionallyDown" inset="2" id="OvP-aq-dIx">
-                                                    <behavior key="behavior" pushIn="YES" lightByBackground="YES" lightByGray="YES"/>
-                                                    <font key="font" metaFont="system"/>
-                                                </buttonCell>
-                                            </button>
-                                        </subviews>
-                                        <constraints>
-                                            <constraint firstItem="1cp-Kv-Xgy" firstAttribute="centerX" secondItem="Yce-JC-LZV" secondAttribute="centerX" id="Bi3-Uq-HFt"/>
-                                            <constraint firstItem="1cp-Kv-Xgy" firstAttribute="centerY" secondItem="Yce-JC-LZV" secondAttribute="centerY" id="gLr-TR-LUR"/>
-                                        </constraints>
-                                    </view>
-                                    <constraints>
-                                        <constraint firstAttribute="width" constant="124" id="jqg-aJ-xBg"/>
-                                    </constraints>
-                                </box>
-                                <box boxType="custom" borderWidth="0.0" cornerRadius="4" title="Box" translatesAutoresizingMaskIntoConstraints="NO" id="1Fg-ni-eIe">
-                                    <rect key="frame" x="140" y="0.0" width="124" height="0.0"/>
-                                    <view key="contentView" id="96H-Ea-IeV">
-                                        <rect key="frame" x="0.0" y="0.0" width="124" height="0.0"/>
-                                        <autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
-                                        <subviews>
-                                            <button verticalHuggingPriority="750" misplaced="YES" translatesAutoresizingMaskIntoConstraints="NO" id="glm-Go-gH2">
-                                                <rect key="frame" x="31" y="-29" width="61" height="20"/>
-                                                <buttonCell key="cell" type="bevel" title="Button" bezelStyle="rounded" alignment="center" imageScaling="proportionallyDown" inset="2" id="vZr-jX-B2q">
-                                                    <behavior key="behavior" pushIn="YES" lightByBackground="YES" lightByGray="YES"/>
-                                                    <font key="font" metaFont="system"/>
-                                                </buttonCell>
-                                            </button>
-                                        </subviews>
-                                        <constraints>
-                                            <constraint firstItem="glm-Go-gH2" firstAttribute="centerY" secondItem="96H-Ea-IeV" secondAttribute="centerY" id="7lN-qV-XtE"/>
-                                            <constraint firstItem="glm-Go-gH2" firstAttribute="centerX" secondItem="96H-Ea-IeV" secondAttribute="centerX" id="gB4-g4-tkg"/>
-                                        </constraints>
-                                    </view>
-                                    <constraints>
-                                        <constraint firstAttribute="width" relation="greaterThanOrEqual" constant="124" id="JIi-PH-kJY"/>
-                                        <constraint firstAttribute="width" constant="124" id="PBE-Dw-5nl"/>
-                                    </constraints>
-                                </box>
-                                <box verticalHuggingPriority="750" boxType="separator" translatesAutoresizingMaskIntoConstraints="NO" id="Wap-a3-1zt">
-                                    <rect key="frame" x="16" y="-2" width="248" height="5"/>
-                                </box>
-                                <box boxType="custom" cornerRadius="4" title="Box" translatesAutoresizingMaskIntoConstraints="NO" id="lKS-tK-sLu">
-                                    <rect key="frame" x="24" y="1" width="116" height="2"/>
-                                    <view key="contentView" id="BuK-6J-cGL">
-                                        <rect key="frame" x="1" y="1" width="114" height="0.0"/>
-                                        <autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
-                                    </view>
-                                    <constraints>
-                                        <constraint firstAttribute="width" constant="116" id="ktu-xh-18e"/>
-                                        <constraint firstAttribute="height" constant="2" id="oyg-Z3-Hdd"/>
-                                    </constraints>
-                                </box>
-                            </subviews>
-                            <constraints>
-                                <constraint firstItem="s0x-OF-qoP" firstAttribute="leading" secondItem="kB0-PA-LMT" secondAttribute="leading" constant="16" id="6gG-BF-RMr"/>
-                                <constraint firstAttribute="trailing" secondItem="Wap-a3-1zt" secondAttribute="trailing" constant="16" id="CNc-d5-Pj5"/>
-                                <constraint firstAttribute="bottom" secondItem="1Fg-ni-eIe" secondAttribute="bottom" id="GIS-iT-Wgm"/>
-                                <constraint firstItem="s0x-OF-qoP" firstAttribute="top" secondItem="kB0-PA-LMT" secondAttribute="top" id="JnH-Np-WHH"/>
-                                <constraint firstItem="lKS-tK-sLu" firstAttribute="leading" secondItem="kB0-PA-LMT" secondAttribute="leading" constant="24" id="Kux-3H-btA"/>
-                                <constraint firstAttribute="trailing" secondItem="1Fg-ni-eIe" secondAttribute="trailing" constant="16" id="MFW-cJ-Mrb"/>
-                                <constraint firstAttribute="bottom" secondItem="Wap-a3-1zt" secondAttribute="bottom" id="SjT-EL-rpj"/>
-                                <constraint firstItem="1Fg-ni-eIe" firstAttribute="top" secondItem="kB0-PA-LMT" secondAttribute="top" id="adE-jm-BOz"/>
-                                <constraint firstItem="Wap-a3-1zt" firstAttribute="leading" secondItem="kB0-PA-LMT" secondAttribute="leading" constant="16" id="mrg-sJ-e9N"/>
-                                <constraint firstAttribute="bottom" secondItem="lKS-tK-sLu" secondAttribute="bottom" constant="0.5" id="of3-un-7lz"/>
-                                <constraint firstAttribute="bottom" secondItem="s0x-OF-qoP" secondAttribute="bottom" id="z6d-FL-xhz"/>
-                            </constraints>
-                        </view>
-                        <constraints>
-                            <constraint firstAttribute="height" id="D6x-KS-trS"/>
-                        </constraints>
-                    </box>
-                    <box boxType="custom" cornerRadius="4" title="Box" translatesAutoresizingMaskIntoConstraints="NO" id="cdc-3d-gh5">
-                        <rect key="frame" x="0.0" y="276" width="280" height="56"/>
-                        <view key="contentView" id="Vzf-SG-CWc">
-                            <rect key="frame" x="1" y="1" width="278" height="54"/>
-                            <autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
-                            <subviews>
-                                <textField horizontalHuggingPriority="251" verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="kXL-bh-JQK">
-                                    <rect key="frame" x="14" y="22" width="37" height="16"/>
-                                    <textFieldCell key="cell" lineBreakMode="clipping" title="Label" id="7B6-BJ-taz">
-                                        <font key="font" usesAppearanceFont="YES"/>
-                                        <color key="textColor" name="labelColor" catalog="System" colorSpace="catalog"/>
-                                        <color key="backgroundColor" name="textBackgroundColor" catalog="System" colorSpace="catalog"/>
-                                    </textFieldCell>
-                                </textField>
-                                <box boxType="custom" cornerRadius="4" title="Box" translatesAutoresizingMaskIntoConstraints="NO" id="Ej6-th-OuJ">
-                                    <rect key="frame" x="16" y="-22" width="246" height="28"/>
-                                    <view key="contentView" id="dDd-h4-ZBa">
-                                        <rect key="frame" x="1" y="1" width="244" height="26"/>
-                                        <autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
-                                        <subviews>
-                                            <textField verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="xLT-x3-sTt">
-                                                <rect key="frame" x="10" y="3" width="224" height="21"/>
-                                                <textFieldCell key="cell" scrollable="YES" lineBreakMode="clipping" selectable="YES" editable="YES" sendsActionOnEndEditing="YES" borderStyle="bezel" drawsBackground="YES" id="FSm-lM-7Vp">
-                                                    <font key="font" usesAppearanceFont="YES"/>
-                                                    <color key="textColor" name="controlTextColor" catalog="System" colorSpace="catalog"/>
-                                                    <color key="backgroundColor" name="textBackgroundColor" catalog="System" colorSpace="catalog"/>
-                                                </textFieldCell>
-                                            </textField>
-                                        </subviews>
-                                        <constraints>
-                                            <constraint firstItem="xLT-x3-sTt" firstAttribute="centerY" secondItem="dDd-h4-ZBa" secondAttribute="centerY" id="403-Zw-5QF"/>
-                                            <constraint firstItem="xLT-x3-sTt" firstAttribute="leading" secondItem="dDd-h4-ZBa" secondAttribute="leading" constant="10" id="XWP-B2-C1Y"/>
-                                            <constraint firstAttribute="trailing" secondItem="xLT-x3-sTt" secondAttribute="trailing" constant="10" id="t1z-gK-KkH"/>
-                                        </constraints>
-                                    </view>
-                                    <constraints>
-                                        <constraint firstAttribute="height" constant="28" id="iyf-90-muH"/>
-                                    </constraints>
-                                </box>
-                                <button verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="tox-LJ-GtX">
-                                    <rect key="frame" x="14" y="-55" width="65" height="18"/>
-                                    <buttonCell key="cell" type="check" title="Check" bezelStyle="regularSquare" imagePosition="left" state="on" inset="2" id="REg-su-rhq">
-                                        <behavior key="behavior" changeContents="YES" doesNotDimImage="YES" lightByContents="YES"/>
-                                        <font key="font" metaFont="system"/>
-                                    </buttonCell>
-                                </button>
-                                <button verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="X98-Hr-uLG">
-                                    <rect key="frame" x="14" y="-87" width="65" height="18"/>
-                                    <buttonCell key="cell" type="check" title="Check" bezelStyle="regularSquare" imagePosition="left" state="on" inset="2" id="Q01-7e-7FJ">
-                                        <behavior key="behavior" changeContents="YES" doesNotDimImage="YES" lightByContents="YES"/>
-                                        <font key="font" metaFont="system"/>
-                                    </buttonCell>
-                                </button>
-                                <button verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="FCV-r1-BiZ">
-                                    <rect key="frame" x="194" y="-1" width="75" height="32"/>
-                                    <buttonCell key="cell" type="push" title="Button" bezelStyle="rounded" alignment="center" borderStyle="border" imageScaling="proportionallyDown" inset="2" id="dQv-AB-jAA">
-                                        <behavior key="behavior" pushIn="YES" lightByBackground="YES" lightByGray="YES"/>
-                                        <font key="font" metaFont="system"/>
-                                    </buttonCell>
-                                </button>
-                                <button verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="qxA-YM-xIq">
-                                    <rect key="frame" x="123" y="-1" width="75" height="32"/>
-                                    <buttonCell key="cell" type="push" title="Button" bezelStyle="rounded" alignment="center" borderStyle="border" imageScaling="proportionallyDown" inset="2" id="xRU-tm-8hM">
-                                        <behavior key="behavior" pushIn="YES" lightByBackground="YES" lightByGray="YES"/>
-                                        <font key="font" metaFont="system"/>
-                                    </buttonCell>
-                                </button>
-                            </subviews>
-                            <constraints>
-                                <constraint firstItem="Ej6-th-OuJ" firstAttribute="top" secondItem="kXL-bh-JQK" secondAttribute="bottom" constant="16" id="8bI-gj-X4I"/>
-                                <constraint firstAttribute="trailing" secondItem="Ej6-th-OuJ" secondAttribute="trailing" constant="16" id="9WP-kr-chZ"/>
-                                <constraint firstItem="kXL-bh-JQK" firstAttribute="leading" secondItem="Vzf-SG-CWc" secondAttribute="leading" constant="16" id="9sj-Vd-1tH"/>
-                                <constraint firstAttribute="bottom" secondItem="FCV-r1-BiZ" secondAttribute="bottom" constant="6" id="CGb-Je-HhI"/>
-                                <constraint firstItem="tox-LJ-GtX" firstAttribute="leading" secondItem="Vzf-SG-CWc" secondAttribute="leading" constant="16" id="E7U-lZ-LJN"/>
-                                <constraint firstItem="kXL-bh-JQK" firstAttribute="top" secondItem="Vzf-SG-CWc" secondAttribute="top" constant="16" id="Mnw-10-rKE"/>
-                                <constraint firstItem="Ej6-th-OuJ" firstAttribute="leading" secondItem="Vzf-SG-CWc" secondAttribute="leading" constant="16" id="Nmj-9n-m2E"/>
-                                <constraint firstItem="X98-Hr-uLG" firstAttribute="top" secondItem="tox-LJ-GtX" secondAttribute="bottom" constant="16" id="bUM-4P-TDa"/>
-                                <constraint firstAttribute="bottom" secondItem="qxA-YM-xIq" secondAttribute="bottom" constant="6" id="iuU-LI-HPQ"/>
-                                <constraint firstItem="X98-Hr-uLG" firstAttribute="leading" secondItem="Vzf-SG-CWc" secondAttribute="leading" constant="16" id="mdo-ib-fQk"/>
-                                <constraint firstItem="tox-LJ-GtX" firstAttribute="top" secondItem="Ej6-th-OuJ" secondAttribute="bottom" constant="16" id="ohP-Eh-4hD"/>
-                                <constraint firstAttribute="trailing" secondItem="FCV-r1-BiZ" secondAttribute="trailing" constant="16" id="roz-Ak-WYB"/>
-                                <constraint firstItem="FCV-r1-BiZ" firstAttribute="leading" secondItem="qxA-YM-xIq" secondAttribute="trailing" constant="10" id="xYi-mQ-Mwy"/>
-                            </constraints>
-                        </view>
-                        <constraints>
-                            <constraint firstAttribute="height" constant="56" id="VG5-11-3Gh"/>
-                        </constraints>
-                    </box>
-                    <box boxType="custom" cornerRadius="4" title="Box" translatesAutoresizingMaskIntoConstraints="NO" id="4kx-6q-nJ8">
-                        <rect key="frame" x="12" y="196" width="256" height="88"/>
-                        <view key="contentView" id="ghJ-Ir-m60">
-                            <rect key="frame" x="1" y="1" width="254" height="86"/>
-                            <autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
-                            <subviews>
-                                <textField horizontalHuggingPriority="251" verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="Y3N-ik-Fnb">
-                                    <rect key="frame" x="14" y="54" width="37" height="16"/>
-                                    <textFieldCell key="cell" lineBreakMode="clipping" title="Label" id="HiA-Gn-RRu">
-                                        <font key="font" usesAppearanceFont="YES"/>
-                                        <color key="textColor" name="labelColor" catalog="System" colorSpace="catalog"/>
-                                        <color key="backgroundColor" name="textBackgroundColor" catalog="System" colorSpace="catalog"/>
-                                    </textFieldCell>
-                                </textField>
-                                <box boxType="custom" cornerRadius="4" title="Box" translatesAutoresizingMaskIntoConstraints="NO" id="LkR-Op-2Jo">
-                                    <rect key="frame" x="16" y="0.0" width="222" height="28"/>
-                                    <view key="contentView" id="op8-Z1-sL4">
-                                        <rect key="frame" x="1" y="1" width="220" height="26"/>
-                                        <autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
-                                        <subviews>
-                                            <textField verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="7BJ-XF-ZVY">
-                                                <rect key="frame" x="10" y="3" width="200" height="21"/>
-                                                <textFieldCell key="cell" scrollable="YES" lineBreakMode="clipping" selectable="YES" editable="YES" sendsActionOnEndEditing="YES" borderStyle="bezel" drawsBackground="YES" id="hZn-NQ-muC">
-                                                    <font key="font" usesAppearanceFont="YES"/>
-                                                    <color key="textColor" name="controlTextColor" catalog="System" colorSpace="catalog"/>
-                                                    <color key="backgroundColor" name="textBackgroundColor" catalog="System" colorSpace="catalog"/>
-                                                </textFieldCell>
-                                            </textField>
-                                        </subviews>
-                                        <constraints>
-                                            <constraint firstItem="7BJ-XF-ZVY" firstAttribute="leading" secondItem="op8-Z1-sL4" secondAttribute="leading" constant="10" id="P7g-Zd-3HH"/>
-                                            <constraint firstAttribute="trailing" secondItem="7BJ-XF-ZVY" secondAttribute="trailing" constant="10" id="k9I-1p-gST"/>
-                                            <constraint firstItem="7BJ-XF-ZVY" firstAttribute="centerY" secondItem="op8-Z1-sL4" secondAttribute="centerY" id="umO-JG-ZLp"/>
-                                        </constraints>
-                                    </view>
-                                    <constraints>
-                                        <constraint firstAttribute="height" constant="28" id="heN-CK-NtC"/>
-                                    </constraints>
-                                </box>
-                            </subviews>
-                            <constraints>
-                                <constraint firstAttribute="bottom" secondItem="LkR-Op-2Jo" secondAttribute="bottom" id="8jk-KG-3vv"/>
-                                <constraint firstItem="LkR-Op-2Jo" firstAttribute="leading" secondItem="ghJ-Ir-m60" secondAttribute="leading" constant="16" id="IYD-mQ-9Cf"/>
-                                <constraint firstAttribute="trailing" secondItem="LkR-Op-2Jo" secondAttribute="trailing" constant="16" id="JrJ-wR-jnQ"/>
-                                <constraint firstItem="Y3N-ik-Fnb" firstAttribute="leading" secondItem="ghJ-Ir-m60" secondAttribute="leading" constant="16" id="V2h-bT-qsV"/>
-                                <constraint firstItem="Y3N-ik-Fnb" firstAttribute="top" secondItem="ghJ-Ir-m60" secondAttribute="top" constant="16" id="dqF-Bi-4G2"/>
-                            </constraints>
-                        </view>
-                        <constraints>
-                            <constraint firstAttribute="height" constant="88" id="qQI-0G-n5r"/>
-                        </constraints>
-                    </box>
-                    <box hidden="YES" boxType="custom" cornerRadius="4" title="Box" translatesAutoresizingMaskIntoConstraints="NO" id="aX3-LQ-PXi">
-                        <rect key="frame" x="0.0" y="0.0" width="280" height="52"/>
-                        <view key="contentView" id="FTe-Pe-5Wd">
-                            <rect key="frame" x="1" y="1" width="278" height="50"/>
-                            <autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
-                            <subviews>
-                                <button hidden="YES" verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="fxe-UM-ZCK">
-                                    <rect key="frame" x="194" y="17" width="75" height="32"/>
-                                    <buttonCell key="cell" type="push" title="Button" bezelStyle="rounded" alignment="center" borderStyle="border" imageScaling="proportionallyDown" inset="2" id="LQk-fe-7It">
-                                        <behavior key="behavior" pushIn="YES" lightByBackground="YES" lightByGray="YES"/>
-                                        <font key="font" metaFont="system"/>
-                                    </buttonCell>
-                                </button>
-                                <button hidden="YES" verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="3l4-91-BR7">
-                                    <rect key="frame" x="123" y="17" width="75" height="32"/>
-                                    <buttonCell key="cell" type="push" title="Button" bezelStyle="rounded" alignment="center" borderStyle="border" imageScaling="proportionallyDown" inset="2" id="Ub2-Qi-UVE">
-                                        <behavior key="behavior" pushIn="YES" lightByBackground="YES" lightByGray="YES"/>
-                                        <font key="font" metaFont="system"/>
-                                    </buttonCell>
-                                </button>
-                            </subviews>
-                            <constraints>
-                                <constraint firstItem="fxe-UM-ZCK" firstAttribute="leading" secondItem="3l4-91-BR7" secondAttribute="trailing" constant="10" id="0Uj-Be-luV"/>
-                                <constraint firstItem="fxe-UM-ZCK" firstAttribute="top" secondItem="FTe-Pe-5Wd" secondAttribute="top" constant="6" id="IkM-7X-gBB"/>
-                                <constraint firstAttribute="trailing" secondItem="fxe-UM-ZCK" secondAttribute="trailing" constant="16" id="SZ7-5x-DZf"/>
-                                <constraint firstItem="3l4-91-BR7" firstAttribute="top" secondItem="FTe-Pe-5Wd" secondAttribute="top" constant="6" id="ru8-zJ-SeL"/>
-                            </constraints>
-                        </view>
-                        <constraints>
-                            <constraint firstAttribute="height" constant="52" id="dW2-x8-dcV"/>
-                        </constraints>
-                    </box>
-                </subviews>
-                <constraints>
-                    <constraint firstItem="cdc-3d-gh5" firstAttribute="top" secondItem="TYX-fO-lan" secondAttribute="bottom" id="0Cv-jO-ixc"/>
-                    <constraint firstAttribute="trailing" secondItem="TYX-fO-lan" secondAttribute="trailing" id="5zp-6K-zSy"/>
-                    <constraint firstItem="TYX-fO-lan" firstAttribute="leading" secondItem="se5-gp-TjO" secondAttribute="leading" id="961-QQ-EKQ"/>
-                    <constraint firstItem="h69-NL-IH7" firstAttribute="top" secondItem="se5-gp-TjO" secondAttribute="top" id="CTM-Ty-KCN"/>
-                    <constraint firstItem="cdc-3d-gh5" firstAttribute="leading" secondItem="se5-gp-TjO" secondAttribute="leading" id="FBd-tQ-1Md"/>
-                    <constraint firstAttribute="trailing" secondItem="cdc-3d-gh5" secondAttribute="trailing" id="I0Z-uh-PdE"/>
-                    <constraint firstItem="TYX-fO-lan" firstAttribute="top" secondItem="h69-NL-IH7" secondAttribute="bottom" id="NFe-Vw-raH"/>
-                    <constraint firstAttribute="trailing" secondItem="h69-NL-IH7" secondAttribute="trailing" id="XLD-vC-gfq"/>
-                    <constraint firstAttribute="trailing" secondItem="4kx-6q-nJ8" secondAttribute="trailing" constant="12" id="Zwi-0o-uvZ"/>
-                    <constraint firstItem="aX3-LQ-PXi" firstAttribute="leading" secondItem="se5-gp-TjO" secondAttribute="leading" id="e7W-rd-KkH"/>
-                    <constraint firstItem="4kx-6q-nJ8" firstAttribute="leading" secondItem="se5-gp-TjO" secondAttribute="leading" constant="12" id="hfv-r4-LBp"/>
-                    <constraint firstAttribute="bottom" secondItem="aX3-LQ-PXi" secondAttribute="bottom" id="u5o-Tk-SGA"/>
-                    <constraint firstItem="h69-NL-IH7" firstAttribute="leading" secondItem="se5-gp-TjO" secondAttribute="leading" id="vO3-NH-iBM"/>
-                    <constraint firstItem="4kx-6q-nJ8" firstAttribute="top" secondItem="cdc-3d-gh5" secondAttribute="bottom" constant="-8" id="xsV-yh-NkH"/>
-                    <constraint firstAttribute="trailing" secondItem="aX3-LQ-PXi" secondAttribute="trailing" id="zOc-g6-tpE"/>
-                </constraints>
-            </view>
-            <connections>
-                <outlet property="delegate" destination="-2" id="0bl-1N-AYu"/>
-            </connections>
-            <point key="canvasLocation" x="52" y="132"/>
-        </window>
-    </objects>
-</document>

PDF Office/PDF Master/Class/Tools/Search/Tools/KMSearchReplaceHanddler.swift → PDF Office/PDF Master/KMClass/Left/Search/Tools/KMSearchReplaceHanddler.swift


+ 9 - 0
PDF Office/PDF Master/KMClass/Left/Search/View/KMNSearchReplaceItemView.swift

@@ -81,6 +81,15 @@ class KMNSearchReplaceItemView: NSView {
         }
     }
     
+    var inputValue: String {
+        get {
+            return input.properties.text
+        }
+        set {
+            input.properties.text = newValue
+            input.reloadData()
+        }
+    }
     
     convenience init() {
         self.init(frame: .init(x: 0, y: 0, width: 300, height: 60))

+ 121 - 0
PDF Office/PDF Master/KMClass/Left/Search/View/KMNSearchReplaceSearchItemView.swift

@@ -0,0 +1,121 @@
+//
+//  KMNSearchReplaceSearchItemView.swift
+//  PDF Reader Pro
+//
+//  Created by User-Tangchao on 2024/12/3.
+//
+
+import Cocoa
+import KMComponentLibrary
+
+class KMNSearchReplaceSearchItemView: NSView {
+    private lazy var previousButton_: ComponentButton = {
+        let view = ComponentButton()
+        view.properties = ComponentButtonProperty(type: .gray, size: .s, state: .normal, onlyIcon: true, icon: NSImage(named: "KMImageNameBotaSearchPreviousDisable"))
+        view.setTarget(self, action: #selector(previousAction))
+        return view
+    }()
+    
+    private lazy var nextButton_: ComponentButton = {
+        let view = ComponentButton()
+        view.properties = ComponentButtonProperty(type: .gray, size: .s, state: .normal, onlyIcon: true, icon: NSImage(named: "KMImageNameBotaSearchNext"))
+        view.setTarget(self, action: #selector(nextActon))
+        return view
+    }()
+    
+    private lazy var input_: ComponentInput = {
+        let view = ComponentInput()
+        let prop = ComponentInputProperty()
+        prop.size = .s
+        prop.showPrefix = true
+        prop.showSuffix = true
+        view.properties = prop
+        view.delegate = self
+        return view
+    }()
+    
+    var inputValue: String {
+        set {
+            input_.properties.text = newValue
+            input_.reloadData()
+        }
+        get {
+            return input_.properties.text
+        }
+    }
+    
+    var previousButton: ComponentButton {
+        get {
+            return previousButton_
+        }
+    }
+    
+    var nextButton: ComponentButton {
+        get {
+            return nextButton_
+        }
+    }
+    
+    var itemClick: KMCommonClickBlock?
+    var valueDidChange: KMValueDidChangeBlock?
+    var inputDidEditBlock: KMEmptyBlock?
+    
+    convenience init() {
+        self.init(frame: .init(x: 0, y: 0, width: 300, height: 44))
+    }
+    
+    override func awakeFromNib() {
+        super.awakeFromNib()
+        
+        initSubviews()
+    }
+    
+    override init(frame frameRect: NSRect) {
+        super.init(frame: frameRect)
+        
+        initSubviews()
+    }
+    
+    required init?(coder: NSCoder) {
+        super.init(coder: coder)
+        
+        initSubviews()
+    }
+    
+    func initSubviews() {
+        addSubview(nextButton_)
+        addSubview(previousButton_)
+        addSubview(input_)
+        
+        nextButton_.km_add_size_constraint(size: .init(width: 32, height: 32))
+        nextButton_.km_add_top_constraint(constant: 0)
+        nextButton_.km_add_trailing_constraint(constant: -24)
+        
+        previousButton_.km_add_size_constraint(size: .init(width: 32, height: 32))
+        previousButton_.km_add_top_constraint(constant: 0)
+        previousButton_.km_add_trailing_constraint(equalTo: nextButton_, attribute: .leading, constant: -8)
+        
+        input_.km_add_top_constraint(constant: 0)
+        input_.km_add_leading_constraint(constant: 24)
+        input_.km_add_height_constraint(constant: 32)
+        input_.km_add_trailing_constraint(equalTo: previousButton_, attribute: .leading, constant: -8)
+    }
+    
+    @objc func previousAction() {
+        itemClick?(1)
+    }
+    
+    @objc func nextActon() {
+        itemClick?(2)
+    }
+}
+
+extension KMNSearchReplaceSearchItemView: ComponentInputDelegate {
+    func componentInputDidChanged(inputView: ComponentInput) {
+        valueDidChange?(inputView.properties.text, nil)
+    }
+    
+    func componentInputDidEndEditing(inputView: ComponentInput) {
+        inputDidEditBlock?()
+    }
+}

+ 95 - 0
PDF Office/PDF Master/KMClass/Left/Search/View/KMNSearchReplaceTitleBarView.swift

@@ -0,0 +1,95 @@
+//
+//  KMNSearchReplaceTitleBarView.swift
+//  PDF Reader Pro
+//
+//  Created by User-Tangchao on 2024/12/3.
+//
+
+import Cocoa
+import KMComponentLibrary
+
+class KMNSearchReplaceTitleBarView: NSView {
+    private lazy var closeButton_: ComponentButton = {
+        let view = ComponentButton()
+        let prop = ComponentButtonProperty()
+        prop.type = .text_gray
+        prop.size = .xxs
+        prop.onlyIcon = true
+        prop.icon = NSImage(named: "KMImageNameSearchReplaceClose")
+        view.properties = prop
+        view.setTarget(self, action: #selector(closeAction))
+        return view
+    }()
+    
+    private lazy var switchButton_: ComponentButton = {
+        let view = ComponentButton()
+        let prop = ComponentButtonProperty()
+        prop.type = .text_gray
+        prop.size = .xxs
+        prop.onlyIcon = true
+        prop.icon = NSImage(named: "KMImageNameSearchReplaceSwitch")
+        view.properties = prop
+        view.setTarget(self, action: #selector(switchAction))
+        return view
+    }()
+    
+    private lazy var titleLabel_: NSTextField = {
+        let view = NSTextField(labelWithString: "")
+        return view
+    }()
+    
+    var titleLabel: NSTextField {
+        get {
+            return titleLabel_
+        }
+    }
+    
+    var itemClick: KMCommonClickBlock?
+    
+    convenience init() {
+        self.init(frame: .init(x: 0, y: 0, width: 300, height: 44))
+    }
+    
+    override func awakeFromNib() {
+        super.awakeFromNib()
+        
+        initSubviews()
+    }
+    
+    override init(frame frameRect: NSRect) {
+        super.init(frame: frameRect)
+        
+        initSubviews()
+    }
+    
+    required init?(coder: NSCoder) {
+        super.init(coder: coder)
+        
+        initSubviews()
+    }
+    
+    func initSubviews() {
+        addSubview(closeButton_)
+        addSubview(switchButton_)
+        addSubview(titleLabel_)
+        
+        closeButton_.km_add_size_constraint(size: .init(width: 24, height: 24))
+        closeButton_.km_add_top_constraint(constant: 8)
+        closeButton_.km_add_trailing_constraint(constant: -8)
+        
+        switchButton_.km_add_size_constraint(size: .init(width: 24, height: 24))
+        switchButton_.km_add_top_constraint(constant: 8)
+        switchButton_.km_add_trailing_constraint(equalTo: closeButton_, attribute: .leading, constant: -8)
+        
+        titleLabel_.km_add_leading_constraint(constant: 24)
+        titleLabel_.km_add_top_constraint(constant: 24)
+    }
+    
+    @objc func closeAction() {
+        itemClick?(1)
+    }
+    
+    @objc func switchAction() {
+        itemClick?(2)
+    }
+}

+ 571 - 0
PDF Office/PDF Master/KMClass/Left/Search/Window/KMSearchReplaceWindowController.swift

@@ -0,0 +1,571 @@
+//
+//  KMSearchReplaceWindowController.swift
+//  PDF Reader Pro
+//
+//  Created by User-Tangchao on 2024/8/7.
+//
+
+import Cocoa
+import KMComponentLibrary
+
+class KMSearchReplaceWindowController_Window: NSWindow {
+    override var canBecomeMain: Bool {
+        return true
+    }
+    
+    override var canBecomeKey: Bool {
+        return true
+    }
+}
+
+@objc enum KMSearchReplaceType: Int {
+    case none = 0
+    case search = 1
+    case replace = 2
+}
+
+class KMSearchReplaceWindowController: KMNBaseWindowController {
+    @IBOutlet weak var titleBarBox: NSBox!
+    
+    @IBOutlet weak var tabBox: NSBox!
+    
+    @IBOutlet weak var searchBox: NSBox!
+    
+    @IBOutlet weak var replaceBox: NSBox!
+    
+    var replaceCallback: (() -> Void)?
+    var itemClick: KMCommonClickBlock?
+    
+    private var _modalSession: NSApplication.ModalSession?
+    
+    private var handdler: KMSearchReplaceHanddler = KMSearchReplaceHanddler()
+    private var type_: KMSearchReplaceType = .search
+    
+    private var currentSel: CPDFSelection?
+    
+    private var finding_ = false
+    
+    private lazy var titleBarView_: KMNSearchReplaceTitleBarView = {
+        let view = KMNSearchReplaceTitleBarView()
+        return view
+    }()
+    
+    private lazy var searchItemView_: KMNSearchReplaceSearchItemView = {
+        let view = KMNSearchReplaceSearchItemView()
+        return view
+    }()
+    
+    private lazy var replaceItemView_: KMNSearchReplacePopItemView = {
+        let view = KMNSearchReplacePopItemView()
+        return view
+    }()
+    
+    var previousButton: ComponentButton {
+        get {
+            return searchItemView_.previousButton
+        }
+    }
+    
+    var nextButton: ComponentButton {
+        get {
+            return searchItemView_.nextButton
+        }
+    }
+    
+    var replaceAllButton: ComponentButton {
+        get {
+            return replaceItemView_.replaceAllButton
+        }
+    }
+    
+    var replaceButton: ComponentButton {
+        get {
+            return replaceItemView_.replaceButton
+        }
+    }
+    
+    convenience init(with pdfView: CPDFView?, type: KMSearchReplaceType) {
+        self.init(windowNibName: "KMSearchReplaceWindowController")
+        
+        self.handdler.pdfView = pdfView
+        self.type_ = type
+    }
+
+    override func windowDidLoad() {
+        super.windowDidLoad()
+
+        self.initDefaultValue()
+        self.switchType(self.type_)
+    }
+    
+    func initDefaultValue() {
+        window?.isMovableByWindowBackground = true
+        
+        window?.contentView?.wantsLayer = true
+        window?.contentView?.layer?.cornerRadius = ComponentLibrary.shared.getComponentValueFromKey("radius/m") as? CGFloat ?? 8
+        window?.contentView?.layer?.masksToBounds = true
+        window?.backgroundColor = .clear
+        
+        titleBarBox.boxType = .custom
+        titleBarBox.borderWidth = 0
+        titleBarBox.contentView = titleBarView_
+        titleBarView_.titleLabel.font = .SFProTextRegularFont(14)
+        titleBarView_.itemClick = { [unowned self] idx, _ in
+            if idx == 1 {
+                _closeAction(NSButton())
+            } else if idx == 2 {
+                _closeAction(NSButton())
+                
+                itemClick?(1)
+            }
+        }
+        
+        searchBox.borderWidth = 0
+        searchBox.contentView = searchItemView_
+        searchItemView_.itemClick = { [unowned self] idx, _ in
+            if idx == 1 { // Previous
+                _previousAction(NSButton())
+            } else if idx == 2 { // next
+                _nextAction(NSButton())
+            }
+        }
+        searchItemView_.valueDidChange = { [unowned self] value, _ in
+            if let data = value as? String {
+                search(keyboard: data)
+            }
+        }
+        searchItemView_.inputDidEditBlock = { [unowned self] in
+            updateButtonStatus()
+            let value = searchItemView_.inputValue
+            if value.isEmpty {
+            } else {
+                currentSel = nil
+            }
+        }
+        
+        replaceBox.borderWidth = 0
+        replaceBox.contentView = replaceItemView_
+        
+        updateButtonStatus()
+        if searchItemView_.inputValue.isEmpty {
+        } else {
+            self.currentSel = nil
+        }
+    }
+    
+    override func updateUILanguage() {
+        super.updateUILanguage()
+        
+        KMMainThreadExecute {
+            self.titleBarView_.titleLabel.stringValue = KMLocalizedString("Search")
+        }
+    }
+    
+    override func updateUIThemeColor() {
+        super.updateUIThemeColor()
+        
+        KMMainThreadExecute {
+            self.titleBarView_.titleLabel.textColor = KMNColorTools.colorText_1()
+            
+            self.updateViewColor()
+        }
+    }
+    
+    func updateButtonStatus() {
+        let value = searchItemView_.inputValue
+        if value.isEmpty {
+            previousButton.properties.isDisabled = true
+            previousButton.reloadData()
+            nextButton.properties.isDisabled = true
+            nextButton.reloadData()
+            replaceButton.properties.isDisabled = true
+            replaceButton.reloadData()
+            replaceAllButton.properties.isDisabled = true
+            replaceAllButton.reloadData()
+        } else {
+            previousButton.properties.isDisabled = false
+            previousButton.reloadData()
+            nextButton.properties.isDisabled = false
+            nextButton.reloadData()
+            replaceButton.properties.isDisabled = false
+            replaceButton.reloadData()
+            replaceAllButton.properties.isDisabled = false
+            replaceAllButton.reloadData()
+        }
+    }
+    
+    // MARK: - Actions
+    
+    @objc private func _closeAction(_ sender: NSButton) {
+        self.endModal(sender)
+        
+        self.handdler.clearData()
+    }
+    
+    @objc private func _previousAction(_ sender: NSButton) {
+        let isEditing = self.handdler.pdfView?.isEditing() ?? false
+        if isEditing == false {
+            guard let model = self.handdler.searchResults.safe_element(for: self.handdler.showIdx-1) as? KMSearchMode else {
+                return
+            }
+            self.handdler.showIdx -= 1
+            self.handdler.showSelection(model.selection)
+        } else {
+            if let _ = self.currentSel {
+                self.currentSel = self.handdler.pdfView?.document.findForwardEditText()
+                if let sel = self.currentSel {
+                    self.handdler.showSelection(sel)
+                } else {
+                    let alert = NSAlert()
+                    alert.messageText = NSLocalizedString("No related content found, please change keyword.", comment: "")
+                    alert.addButton(withTitle: NSLocalizedString("OK", comment: ""))
+//                    alert.runModal()
+                    alert.beginSheetModal(for: (self.window)!)
+                }
+            } else {
+                if self.finding_ {
+                    return
+                }
+                self.finding_ = true
+                let searchS = self.searchItemView_.inputValue
+                let opt = self.fetchSearchOptions()
+                self._beginLoading()
+                DispatchQueue.global().async {
+                    let datas = self.handdler.pdfView?.document.startFindEditText(from: nil, with: searchS, options: opt)
+                    DispatchQueue.main.async {
+                        self._endLoading()
+                        self.finding_ = false
+                        let sel = datas?.first?.first
+                        if sel == nil {
+                            let alert = NSAlert()
+                            alert.messageText = NSLocalizedString("No related content found, please change keyword.", comment: "")
+                            alert.addButton(withTitle: NSLocalizedString("OK", comment: ""))
+//                            alert.runModal()
+                            alert.beginSheetModal(for: (self.window)!)
+                            return
+                        }
+                        self.currentSel = sel
+                        self.handdler.showSelection(sel)
+                    }
+                }
+            }
+        }
+    }
+    
+    @objc private func _nextAction(_ sender: NSButton) {
+        let isEditing = self.handdler.pdfView?.isEditing() ?? false
+        if isEditing == false {
+            guard let model = self.handdler.searchResults.safe_element(for: self.handdler.showIdx+1) as? KMSearchMode else {
+                return
+            }
+            self.handdler.showIdx += 1
+            self.handdler.showSelection(model.selection)
+        } else {
+            if let _ = self.currentSel {
+                self.currentSel = self.handdler.pdfView?.document.findBackwordEditText()
+                if let sel = self.currentSel {
+                    self.handdler.showSelection(sel)
+                } else {
+                    let alert = NSAlert()
+                    alert.messageText = NSLocalizedString("No related content found, please change keyword.", comment: "")
+                    alert.addButton(withTitle: NSLocalizedString("OK", comment: ""))
+//                    alert.runModal()
+                    alert.beginSheetModal(for: (self.window)!)
+                }
+            } else {
+                if self.finding_ {
+                    return
+                }
+                self.finding_ = true
+                let searchS = self.searchItemView_.inputValue
+                let opt = self.fetchSearchOptions()
+                self._beginLoading()
+                DispatchQueue.global().async {
+                
+                    let datas = self.handdler.pdfView?.document.startFindEditText(from: nil, with: searchS, options: opt)
+                    DispatchQueue.main.async {
+                        self._endLoading()
+                        self.finding_ = false
+                        let sel = datas?.first?.first
+                        if sel == nil {
+                            let alert = NSAlert()
+                            alert.messageText = NSLocalizedString("No related content found, please change keyword.", comment: "")
+                            alert.addButton(withTitle: NSLocalizedString("OK", comment: ""))
+//                            alert.runModal()
+                            alert.beginSheetModal(for: (self.window)!)
+                            return
+                        }
+                        self.currentSel = sel
+                        self.handdler.showSelection(sel)
+                    }
+                }
+            }
+        }
+    }
+    
+    @objc private func _checkAction(_ sender: NSButton) {
+        self.currentSel = nil
+    }
+    
+    @objc private func _searchTabAction(_ sender: NSButton) {
+        self.switchType(.search, animate: true)
+    }
+    
+    @objc private func _replaceTabAction(_ sender: NSButton) {
+        self.switchType(.replace, animate: true)
+    }
+    
+    @objc private func _replaceAction(_ sender: NSButton) {
+        let isEditing =  self.handdler.pdfView?.isEditing() ?? false
+        if isEditing == false {
+            NSSound.beep()
+            return
+        }
+        if let sel = self.currentSel {
+            let searchS = self.searchItemView_.inputValue
+            let replaceS = self.replaceItemView_.inputValue
+            let success = self.handdler.replace(searchS: searchS, replaceS: replaceS, sel: sel) { [weak self] newSel in
+                self?.handdler.showSelection(newSel)
+            }
+            if success {
+//                self.handdler.showSelection(sel)
+            }
+        } else { // 先查找
+            if self.finding_ {
+                return
+            }
+            self.finding_ = true
+            let searchS = self.searchItemView_.inputValue
+            let opt = self.fetchSearchOptions()
+            self._beginLoading()
+            DispatchQueue.global().async {
+                let datas = self.handdler.pdfView?.document.startFindEditText(from: nil, with: searchS, options: opt)
+                DispatchQueue.main.async {
+                    self._endLoading()
+                    self.finding_ = false
+                    let sel = datas?.first?.first
+                    if sel == nil {
+                        let alert = NSAlert()
+                        alert.messageText = NSLocalizedString("No related content found, please change keyword.", comment: "")
+                        alert.addButton(withTitle: NSLocalizedString("OK", comment: ""))
+//                        alert.runModal()
+                        alert.beginSheetModal(for: (self.window)!)
+                        return
+                    }
+                    self.currentSel = sel
+                    self.handdler.showSelection(sel)
+                }
+            }
+        }
+    }
+    
+    @objc private func _replaceAllAction(_ sender: NSButton) {
+        let isEditing =  self.handdler.pdfView?.isEditing() ?? false
+        if isEditing == false {
+            NSSound.beep()
+            return
+        }
+        
+        let datas = self.handdler.pdfView?.document.findEditSelections() ?? []
+        if datas.isEmpty {
+            let alert = NSAlert()
+            alert.informativeText = NSLocalizedString("No related content found, please change keyword.", comment: "")
+            alert.addButton(withTitle: NSLocalizedString("OK", comment: ""))
+//            alert.beginSheetModal(for: NSApp.mainWindow!)
+//            alert.runModal()
+            alert.beginSheetModal(for: (self.window)!)
+            return
+        }
+        
+        if self.finding_ {
+            return
+        }
+        self.finding_ = true
+        let searchS = self.searchItemView_.inputValue
+        let replaceS = self.replaceItemView_.inputValue
+        self._beginLoading()
+        DispatchQueue.global().async {
+            self.handdler.pdfView?.document.replaceAllEditText(with: searchS, toReplace: replaceS)
+            self.currentSel = nil
+            
+            DispatchQueue.main.async {
+                self._endLoading()
+                self.finding_ = false
+                self.handdler.pdfView?.setHighlightedSelection(nil, animated: false)
+                self.handdler.pdfView?.setNeedsDisplayForVisiblePages()
+            }
+        }
+    }
+    
+    private func fetchSearchOptions() -> CPDFSearchOptions {
+        var opt = CPDFSearchOptions()
+        let isCase = KMDataManager.ud_bool(forKey: KMNSearchKey.caseSensitive.botaSearch)
+        let isWholeWord = KMDataManager.ud_bool(forKey: KMNSearchKey.wholeWords.botaSearch)
+        if isCase {
+            opt.insert(.caseSensitive)
+        }
+        if isWholeWord {
+            opt.insert(.matchWholeWord)
+        }
+        return opt
+    }
+    
+    private func updateViewColor() {
+        let isDark = KMAppearance.isDarkMode()
+        if isDark {
+            self.window?.contentView?.wantsLayer = true
+            self.window?.contentView?.layer?.backgroundColor = NSColor(hex: "#393C3E").cgColor
+        } else {
+            self.window?.contentView?.wantsLayer = true
+            self.window?.contentView?.layer?.backgroundColor = .white
+        }
+        
+        self.switchType(self.type_)
+    }
+    
+    func switchType(_ type: KMSearchReplaceType, animate: Bool = false) {
+        if type == .replace {
+            if IAPProductsManager.default().isAvailableAllFunction() == false {
+//                KMPurchaseCompareWindowController.sharedInstance().showWindow(nil)
+                let winC = KMPurchaseCompareWindowController.sharedInstance()
+                winC?.showWindow(nil)
+                guard let win = winC?.window else {
+                    return
+                }
+                self.window?.addChildWindow(win, ordered: .above)
+                return
+            }
+        }
+        
+        self.type_ = type
+        let isDark = KMAppearance.isDarkMode()
+        var selectedColor = NSColor(hex: "0E1114")
+        var unSelectedColor = NSColor(hex: "757780")
+        if isDark {
+            selectedColor = .white
+            unSelectedColor = NSColor(hex: "#7E7F85")
+        }
+        
+        if type == .search { // 248 112
+//            DispatchQueue.main.async {
+                self.replaceBox.isHidden = true
+//            }
+            
+            var frame = self.window?.frame ?? .zero
+//            let height: CGFloat = 248+20
+            let height: CGFloat = 112
+            let heightOffset = frame.size.height - height
+            frame.origin.y += heightOffset
+            frame.size.height = height
+            self.window?.setFrame(frame, display: true, animate: animate)
+            self.window?.minSize = frame.size
+            self.window?.maxSize = frame.size
+        } else if type == .replace { // 388 208
+            DispatchQueue.main.async {
+                self.replaceBox.isHidden = false
+            }
+            
+            var frame = self.window?.frame ?? .zero
+            let height:CGFloat = 208
+            let heightOffset = frame.size.height-height
+            frame.origin.y += heightOffset
+            frame.size.height = height
+            self.window?.setFrame(frame, display: true, animate: animate)
+            self.window?.minSize = frame.size
+            self.window?.maxSize = frame.size
+            
+            // 将事件回调出去
+            self.replaceCallback?()
+        }
+    }
+    
+    private func _beginLoading() {
+        self.window?.contentView?.beginLoading()
+    }
+    
+    private func _endLoading() {
+        self.window?.contentView?.endLoading()
+    }
+    
+    func startModal(_ sender: AnyObject?) {
+        NSApp.stopModal()
+        
+        var modalCode: NSApplication.ModalResponse?
+        if let _win = self.window {
+            self._modalSession = NSApp.beginModalSession(for: _win)
+            repeat {
+                modalCode = NSApp.runModalSession(self._modalSession!)
+            } while (modalCode == .continue)
+        }
+    }
+    
+    func endModal(_ sender: AnyObject?) {
+        if let session = self._modalSession {
+            NSApp.stopModal()
+            NSApp.endModalSession(session)
+            self.window?.orderOut(self)
+        }
+        if let winC = self.window?.kmCurrentWindowC, winC.isEqual(to: self) {
+            self.window?.kmCurrentWindowC = nil
+        }
+    }
+    
+    func search(keyboard: String) {
+        let isCase = KMDataManager.ud_bool(forKey: KMNSearchKey.caseSensitive.botaSearch)
+        let isWholeWord = KMDataManager.ud_bool(forKey: KMNSearchKey.wholeWords.botaSearch)
+        let isEditing = self.handdler.pdfView?.isEditing() ?? false
+        if isEditing == false {
+            if self.finding_ {
+                return
+            }
+            self.finding_ = true
+            self._beginLoading()
+            self.handdler.search(keyword: keyboard, isCase: isCase, isWholeWord: isWholeWord, callback: { [weak self] datas in
+                self?.finding_ = false
+                self?._endLoading()
+                
+                guard let sels = datas, sels.isEmpty == false else {
+                    let alert = NSAlert()
+                    alert.informativeText = NSLocalizedString("No related content found, please change keyword.", comment: "")
+                    alert.addButton(withTitle: NSLocalizedString("OK", comment: ""))
+                    //                                alert.runModal()
+                    alert.beginSheetModal(for: (self?.window)!)
+                    return
+                }
+                if let sel = datas?.first?.selection {
+                    self?.handdler.showIdx = 0
+                    self?.handdler.showSelection(sel)
+                }
+            })
+        } else {
+            if self.finding_ {
+                return
+            }
+            self.finding_ = true
+            let searchS = keyboard
+            let opt = self.fetchSearchOptions()
+            self._beginLoading()
+            DispatchQueue.global().async {
+                let datas = self.handdler.pdfView?.document.findEditAllPageString(searchS, with: opt) ?? []
+                DispatchQueue.main.async {
+                    self.finding_ = false
+                    self._endLoading()
+                    if datas.isEmpty {
+                        let alert = NSAlert()
+                        alert.informativeText = NSLocalizedString("No related content found, please change keyword.", comment: "")
+                        alert.addButton(withTitle: NSLocalizedString("OK", comment: ""))
+                        //                                    alert.beginSheetModal(for: NSApp.mainWindow!)
+                        //                                    alert.runModal()
+                        alert.beginSheetModal(for: (self.window)!)
+                        return
+                    }
+                    self.currentSel = datas.first?.first
+                    if let sel = self.currentSel {
+                        self.handdler.showSelection(sel)
+                    }
+                }
+                
+            }
+        }
+    }
+}

+ 95 - 0
PDF Office/PDF Master/KMClass/Left/Search/Window/KMSearchReplaceWindowController.xib

@@ -0,0 +1,95 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<document type="com.apple.InterfaceBuilder3.Cocoa.XIB" version="3.0" toolsVersion="21507" targetRuntime="MacOSX.Cocoa" propertyAccessControl="none" useAutolayout="YES" customObjectInstantitationMethod="direct">
+    <dependencies>
+        <deployment identifier="macosx"/>
+        <plugIn identifier="com.apple.InterfaceBuilder.CocoaPlugin" version="21507"/>
+        <capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
+    </dependencies>
+    <objects>
+        <customObject id="-2" userLabel="File's Owner" customClass="KMSearchReplaceWindowController" customModule="PDF_Reader_Pro" customModuleProvider="target">
+            <connections>
+                <outlet property="replaceBox" destination="4kx-6q-nJ8" id="fTS-By-eXX"/>
+                <outlet property="searchBox" destination="cdc-3d-gh5" id="9Se-Lu-XEN"/>
+                <outlet property="tabBox" destination="TYX-fO-lan" id="k0D-nW-DRi"/>
+                <outlet property="titleBarBox" destination="h69-NL-IH7" id="CIc-G8-vOa"/>
+                <outlet property="window" destination="F0z-JX-Cv5" id="gIp-Ho-8D9"/>
+            </connections>
+        </customObject>
+        <customObject id="-1" userLabel="First Responder" customClass="FirstResponder"/>
+        <customObject id="-3" userLabel="Application" customClass="NSObject"/>
+        <window title="Window" allowsToolTipsWhenApplicationIsInactive="NO" autorecalculatesKeyViewLoop="NO" releasedWhenClosed="NO" animationBehavior="default" id="F0z-JX-Cv5" customClass="KMSearchReplaceWindowController_Window" customModule="PDF_Reader_Pro" customModuleProvider="target">
+            <windowStyleMask key="styleMask" closable="YES" miniaturizable="YES" resizable="YES"/>
+            <windowPositionMask key="initialPositionMask" leftStrut="YES" rightStrut="YES" topStrut="YES" bottomStrut="YES"/>
+            <rect key="contentRect" x="196" y="240" width="280" height="388"/>
+            <rect key="screenRect" x="0.0" y="0.0" width="1440" height="875"/>
+            <value key="minSize" type="size" width="280" height="388"/>
+            <value key="maxSize" type="size" width="280" height="388"/>
+            <value key="minFullScreenContentSize" type="size" width="280" height="388"/>
+            <value key="maxFullScreenContentSize" type="size" width="280" height="388"/>
+            <view key="contentView" id="se5-gp-TjO">
+                <rect key="frame" x="0.0" y="0.0" width="280" height="388"/>
+                <autoresizingMask key="autoresizingMask"/>
+                <subviews>
+                    <box boxType="custom" cornerRadius="4" title="Box" translatesAutoresizingMaskIntoConstraints="NO" id="h69-NL-IH7">
+                        <rect key="frame" x="0.0" y="332" width="280" height="56"/>
+                        <view key="contentView" id="Zea-eJ-KkO">
+                            <rect key="frame" x="1" y="1" width="278" height="54"/>
+                            <autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
+                        </view>
+                        <constraints>
+                            <constraint firstAttribute="height" constant="56" id="QCO-3b-P69"/>
+                        </constraints>
+                    </box>
+                    <box boxType="custom" borderWidth="0.0" cornerRadius="4" title="Box" translatesAutoresizingMaskIntoConstraints="NO" id="TYX-fO-lan">
+                        <rect key="frame" x="0.0" y="332" width="280" height="0.0"/>
+                        <view key="contentView" id="kB0-PA-LMT">
+                            <rect key="frame" x="0.0" y="0.0" width="280" height="0.0"/>
+                            <autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
+                        </view>
+                        <constraints>
+                            <constraint firstAttribute="height" id="D6x-KS-trS"/>
+                        </constraints>
+                    </box>
+                    <box boxType="custom" cornerRadius="4" title="Box" translatesAutoresizingMaskIntoConstraints="NO" id="cdc-3d-gh5">
+                        <rect key="frame" x="0.0" y="276" width="280" height="56"/>
+                        <view key="contentView" id="Vzf-SG-CWc">
+                            <rect key="frame" x="1" y="1" width="278" height="54"/>
+                            <autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
+                        </view>
+                        <constraints>
+                            <constraint firstAttribute="height" constant="56" id="VG5-11-3Gh"/>
+                        </constraints>
+                    </box>
+                    <box boxType="custom" cornerRadius="4" title="Box" translatesAutoresizingMaskIntoConstraints="NO" id="4kx-6q-nJ8">
+                        <rect key="frame" x="12" y="196" width="256" height="88"/>
+                        <view key="contentView" id="ghJ-Ir-m60">
+                            <rect key="frame" x="1" y="1" width="254" height="86"/>
+                            <autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
+                        </view>
+                        <constraints>
+                            <constraint firstAttribute="height" constant="88" id="qQI-0G-n5r"/>
+                        </constraints>
+                    </box>
+                </subviews>
+                <constraints>
+                    <constraint firstItem="cdc-3d-gh5" firstAttribute="top" secondItem="TYX-fO-lan" secondAttribute="bottom" id="0Cv-jO-ixc"/>
+                    <constraint firstAttribute="trailing" secondItem="TYX-fO-lan" secondAttribute="trailing" id="5zp-6K-zSy"/>
+                    <constraint firstItem="TYX-fO-lan" firstAttribute="leading" secondItem="se5-gp-TjO" secondAttribute="leading" id="961-QQ-EKQ"/>
+                    <constraint firstItem="h69-NL-IH7" firstAttribute="top" secondItem="se5-gp-TjO" secondAttribute="top" id="CTM-Ty-KCN"/>
+                    <constraint firstItem="cdc-3d-gh5" firstAttribute="leading" secondItem="se5-gp-TjO" secondAttribute="leading" id="FBd-tQ-1Md"/>
+                    <constraint firstAttribute="trailing" secondItem="cdc-3d-gh5" secondAttribute="trailing" id="I0Z-uh-PdE"/>
+                    <constraint firstItem="TYX-fO-lan" firstAttribute="top" secondItem="h69-NL-IH7" secondAttribute="bottom" id="NFe-Vw-raH"/>
+                    <constraint firstAttribute="trailing" secondItem="h69-NL-IH7" secondAttribute="trailing" id="XLD-vC-gfq"/>
+                    <constraint firstAttribute="trailing" secondItem="4kx-6q-nJ8" secondAttribute="trailing" constant="12" id="Zwi-0o-uvZ"/>
+                    <constraint firstItem="4kx-6q-nJ8" firstAttribute="leading" secondItem="se5-gp-TjO" secondAttribute="leading" constant="12" id="hfv-r4-LBp"/>
+                    <constraint firstItem="h69-NL-IH7" firstAttribute="leading" secondItem="se5-gp-TjO" secondAttribute="leading" id="vO3-NH-iBM"/>
+                    <constraint firstItem="4kx-6q-nJ8" firstAttribute="top" secondItem="cdc-3d-gh5" secondAttribute="bottom" constant="-8" id="xsV-yh-NkH"/>
+                </constraints>
+            </view>
+            <connections>
+                <outlet property="delegate" destination="-2" id="0bl-1N-AYu"/>
+            </connections>
+            <point key="canvasLocation" x="52" y="132"/>
+        </window>
+    </objects>
+</document>

+ 48 - 48
PDF Office/PDF Reader Pro.xcodeproj/project.pbxproj

@@ -92,15 +92,6 @@
 		65202DFC2CE4827900A204B5 /* KMNBotaHeaderSearchView.xib in Resources */ = {isa = PBXBuildFile; fileRef = 65202DFB2CE4827900A204B5 /* KMNBotaHeaderSearchView.xib */; };
 		65202DFD2CE4827900A204B5 /* KMNBotaHeaderSearchView.xib in Resources */ = {isa = PBXBuildFile; fileRef = 65202DFB2CE4827900A204B5 /* KMNBotaHeaderSearchView.xib */; };
 		65202DFE2CE4827900A204B5 /* KMNBotaHeaderSearchView.xib in Resources */ = {isa = PBXBuildFile; fileRef = 65202DFB2CE4827900A204B5 /* KMNBotaHeaderSearchView.xib */; };
-		65341C742C63CCFE00FE30F9 /* KMSearchReplaceWindowController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 65341C722C63CCFE00FE30F9 /* KMSearchReplaceWindowController.swift */; };
-		65341C752C63CCFE00FE30F9 /* KMSearchReplaceWindowController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 65341C722C63CCFE00FE30F9 /* KMSearchReplaceWindowController.swift */; };
-		65341C762C63CCFE00FE30F9 /* KMSearchReplaceWindowController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 65341C722C63CCFE00FE30F9 /* KMSearchReplaceWindowController.swift */; };
-		65341C772C63CCFE00FE30F9 /* KMSearchReplaceWindowController.xib in Resources */ = {isa = PBXBuildFile; fileRef = 65341C732C63CCFE00FE30F9 /* KMSearchReplaceWindowController.xib */; };
-		65341C782C63CCFE00FE30F9 /* KMSearchReplaceWindowController.xib in Resources */ = {isa = PBXBuildFile; fileRef = 65341C732C63CCFE00FE30F9 /* KMSearchReplaceWindowController.xib */; };
-		65341C792C63CCFE00FE30F9 /* KMSearchReplaceWindowController.xib in Resources */ = {isa = PBXBuildFile; fileRef = 65341C732C63CCFE00FE30F9 /* KMSearchReplaceWindowController.xib */; };
-		65341C7C2C646C6400FE30F9 /* KMSearchReplaceHanddler.swift in Sources */ = {isa = PBXBuildFile; fileRef = 65341C7B2C646C6400FE30F9 /* KMSearchReplaceHanddler.swift */; };
-		65341C7D2C646C6400FE30F9 /* KMSearchReplaceHanddler.swift in Sources */ = {isa = PBXBuildFile; fileRef = 65341C7B2C646C6400FE30F9 /* KMSearchReplaceHanddler.swift */; };
-		65341C7E2C646C6400FE30F9 /* KMSearchReplaceHanddler.swift in Sources */ = {isa = PBXBuildFile; fileRef = 65341C7B2C646C6400FE30F9 /* KMSearchReplaceHanddler.swift */; };
 		653647702CDC8C3700CDB13E /* KMNTableHeaderCellView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6536476F2CDC8C3700CDB13E /* KMNTableHeaderCellView.swift */; };
 		653647712CDC8C3700CDB13E /* KMNTableHeaderCellView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6536476F2CDC8C3700CDB13E /* KMNTableHeaderCellView.swift */; };
 		653647722CDC8C3700CDB13E /* KMNTableHeaderCellView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6536476F2CDC8C3700CDB13E /* KMNTableHeaderCellView.swift */; };
@@ -248,6 +239,21 @@
 		657851682CFEA3C40023D640 /* KMSearchMode.swift in Sources */ = {isa = PBXBuildFile; fileRef = 657851612CFEA3C40023D640 /* KMSearchMode.swift */; };
 		657851692CFEA3C40023D640 /* KMSearchMode.swift in Sources */ = {isa = PBXBuildFile; fileRef = 657851612CFEA3C40023D640 /* KMSearchMode.swift */; };
 		6578516A2CFEA3C40023D640 /* KMSearchMode.swift in Sources */ = {isa = PBXBuildFile; fileRef = 657851612CFEA3C40023D640 /* KMSearchMode.swift */; };
+		6578516E2CFEE38E0023D640 /* KMSearchReplaceWindowController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6578516C2CFEE38E0023D640 /* KMSearchReplaceWindowController.swift */; };
+		6578516F2CFEE38E0023D640 /* KMSearchReplaceWindowController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6578516C2CFEE38E0023D640 /* KMSearchReplaceWindowController.swift */; };
+		657851702CFEE38E0023D640 /* KMSearchReplaceWindowController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6578516C2CFEE38E0023D640 /* KMSearchReplaceWindowController.swift */; };
+		657851712CFEE38E0023D640 /* KMSearchReplaceWindowController.xib in Resources */ = {isa = PBXBuildFile; fileRef = 6578516D2CFEE38E0023D640 /* KMSearchReplaceWindowController.xib */; };
+		657851722CFEE38E0023D640 /* KMSearchReplaceWindowController.xib in Resources */ = {isa = PBXBuildFile; fileRef = 6578516D2CFEE38E0023D640 /* KMSearchReplaceWindowController.xib */; };
+		657851732CFEE38E0023D640 /* KMSearchReplaceWindowController.xib in Resources */ = {isa = PBXBuildFile; fileRef = 6578516D2CFEE38E0023D640 /* KMSearchReplaceWindowController.xib */; };
+		657851752CFEE3A10023D640 /* KMSearchReplaceHanddler.swift in Sources */ = {isa = PBXBuildFile; fileRef = 657851742CFEE3A10023D640 /* KMSearchReplaceHanddler.swift */; };
+		657851762CFEE3A10023D640 /* KMSearchReplaceHanddler.swift in Sources */ = {isa = PBXBuildFile; fileRef = 657851742CFEE3A10023D640 /* KMSearchReplaceHanddler.swift */; };
+		657851772CFEE3A10023D640 /* KMSearchReplaceHanddler.swift in Sources */ = {isa = PBXBuildFile; fileRef = 657851742CFEE3A10023D640 /* KMSearchReplaceHanddler.swift */; };
+		657851792CFEE4580023D640 /* KMNSearchReplaceTitleBarView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 657851782CFEE4580023D640 /* KMNSearchReplaceTitleBarView.swift */; };
+		6578517A2CFEE4580023D640 /* KMNSearchReplaceTitleBarView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 657851782CFEE4580023D640 /* KMNSearchReplaceTitleBarView.swift */; };
+		6578517B2CFEE4580023D640 /* KMNSearchReplaceTitleBarView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 657851782CFEE4580023D640 /* KMNSearchReplaceTitleBarView.swift */; };
+		6578517D2CFEE4850023D640 /* KMNSearchReplaceSearchItemView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6578517C2CFEE4850023D640 /* KMNSearchReplaceSearchItemView.swift */; };
+		6578517E2CFEE4850023D640 /* KMNSearchReplaceSearchItemView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6578517C2CFEE4850023D640 /* KMNSearchReplaceSearchItemView.swift */; };
+		6578517F2CFEE4850023D640 /* KMNSearchReplaceSearchItemView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6578517C2CFEE4850023D640 /* KMNSearchReplaceSearchItemView.swift */; };
 		657865F32CE1E7DD00AFE2DB /* KMNBookmarkHanddler.swift in Sources */ = {isa = PBXBuildFile; fileRef = 657865EA2CE1E7DD00AFE2DB /* KMNBookmarkHanddler.swift */; };
 		657865F42CE1E7DD00AFE2DB /* KMNBookmarkHanddler.swift in Sources */ = {isa = PBXBuildFile; fileRef = 657865EA2CE1E7DD00AFE2DB /* KMNBookmarkHanddler.swift */; };
 		657865F52CE1E7DD00AFE2DB /* KMNBookmarkHanddler.swift in Sources */ = {isa = PBXBuildFile; fileRef = 657865EA2CE1E7DD00AFE2DB /* KMNBookmarkHanddler.swift */; };
@@ -5584,9 +5590,6 @@
 		65202DF02CE46DA700A204B5 /* KMNColorTools.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = KMNColorTools.swift; sourceTree = "<group>"; };
 		65202DF62CE4803500A204B5 /* KMNBotaHeaderSearchView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = KMNBotaHeaderSearchView.swift; sourceTree = "<group>"; };
 		65202DFB2CE4827900A204B5 /* KMNBotaHeaderSearchView.xib */ = {isa = PBXFileReference; lastKnownFileType = file.xib; path = KMNBotaHeaderSearchView.xib; sourceTree = "<group>"; };
-		65341C722C63CCFE00FE30F9 /* KMSearchReplaceWindowController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = KMSearchReplaceWindowController.swift; sourceTree = "<group>"; };
-		65341C732C63CCFE00FE30F9 /* KMSearchReplaceWindowController.xib */ = {isa = PBXFileReference; lastKnownFileType = file.xib; path = KMSearchReplaceWindowController.xib; sourceTree = "<group>"; };
-		65341C7B2C646C6400FE30F9 /* KMSearchReplaceHanddler.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = KMSearchReplaceHanddler.swift; sourceTree = "<group>"; };
 		6536476F2CDC8C3700CDB13E /* KMNTableHeaderCellView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = KMNTableHeaderCellView.swift; sourceTree = "<group>"; };
 		653647752CDCA47300CDB13E /* KMBatchOperateImageToPDFViewController.xib */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.xib; path = KMBatchOperateImageToPDFViewController.xib; sourceTree = "<group>"; };
 		653647762CDCA47300CDB13E /* KMBatchOperateImageToPDFViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = KMBatchOperateImageToPDFViewController.swift; sourceTree = "<group>"; };
@@ -5637,6 +5640,11 @@
 		6578515E2CFEA3C40023D640 /* KMBotaSearchViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = KMBotaSearchViewController.swift; sourceTree = "<group>"; };
 		6578515F2CFEA3C40023D640 /* KMBotaSearchViewController.xib */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.xib; path = KMBotaSearchViewController.xib; sourceTree = "<group>"; };
 		657851612CFEA3C40023D640 /* KMSearchMode.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = KMSearchMode.swift; sourceTree = "<group>"; };
+		6578516C2CFEE38E0023D640 /* KMSearchReplaceWindowController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = KMSearchReplaceWindowController.swift; sourceTree = "<group>"; };
+		6578516D2CFEE38E0023D640 /* KMSearchReplaceWindowController.xib */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.xib; path = KMSearchReplaceWindowController.xib; sourceTree = "<group>"; };
+		657851742CFEE3A10023D640 /* KMSearchReplaceHanddler.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = KMSearchReplaceHanddler.swift; sourceTree = "<group>"; };
+		657851782CFEE4580023D640 /* KMNSearchReplaceTitleBarView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = KMNSearchReplaceTitleBarView.swift; sourceTree = "<group>"; };
+		6578517C2CFEE4850023D640 /* KMNSearchReplaceSearchItemView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = KMNSearchReplaceSearchItemView.swift; sourceTree = "<group>"; };
 		657865EA2CE1E7DD00AFE2DB /* KMNBookmarkHanddler.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = KMNBookmarkHanddler.swift; sourceTree = "<group>"; };
 		657865EB2CE1E7DD00AFE2DB /* KMBookMarkViewController.xib */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.xib; path = KMBookMarkViewController.xib; sourceTree = "<group>"; };
 		657865EC2CE1E7DD00AFE2DB /* KMBookMarkViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = KMBookMarkViewController.swift; sourceTree = "<group>"; };
@@ -7993,32 +8001,6 @@
 			path = Model;
 			sourceTree = "<group>";
 		};
-		65341C702C63CC2500FE30F9 /* Search */ = {
-			isa = PBXGroup;
-			children = (
-				65341C7A2C646C4C00FE30F9 /* Tools */,
-				65341C712C63CC4C00FE30F9 /* Window */,
-			);
-			path = Search;
-			sourceTree = "<group>";
-		};
-		65341C712C63CC4C00FE30F9 /* Window */ = {
-			isa = PBXGroup;
-			children = (
-				65341C722C63CCFE00FE30F9 /* KMSearchReplaceWindowController.swift */,
-				65341C732C63CCFE00FE30F9 /* KMSearchReplaceWindowController.xib */,
-			);
-			path = Window;
-			sourceTree = "<group>";
-		};
-		65341C7A2C646C4C00FE30F9 /* Tools */ = {
-			isa = PBXGroup;
-			children = (
-				65341C7B2C646C6400FE30F9 /* KMSearchReplaceHanddler.swift */,
-			);
-			path = Tools;
-			sourceTree = "<group>";
-		};
 		6536476A2CDC8B0900CDB13E /* ImageToPDF */ = {
 			isa = PBXGroup;
 			children = (
@@ -8130,6 +8112,15 @@
 			path = Model;
 			sourceTree = "<group>";
 		};
+		6578516B2CFEE38E0023D640 /* Window */ = {
+			isa = PBXGroup;
+			children = (
+				6578516C2CFEE38E0023D640 /* KMSearchReplaceWindowController.swift */,
+				6578516D2CFEE38E0023D640 /* KMSearchReplaceWindowController.xib */,
+			);
+			path = Window;
+			sourceTree = "<group>";
+		};
 		657865E82CE1E7DD00AFE2DB /* Bookmark */ = {
 			isa = PBXGroup;
 			children = (
@@ -8236,6 +8227,7 @@
 		65F9F4822CFC162B00F187A8 /* Search */ = {
 			isa = PBXGroup;
 			children = (
+				6578516B2CFEE38E0023D640 /* Window */,
 				6578515D2CFEA3C40023D640 /* Controller */,
 				657851602CFEA3C40023D640 /* Model */,
 				65F9F4882CFCAA1300F187A8 /* View */,
@@ -8247,6 +8239,7 @@
 		65F9F4832CFC162B00F187A8 /* Tools */ = {
 			isa = PBXGroup;
 			children = (
+				657851742CFEE3A10023D640 /* KMSearchReplaceHanddler.swift */,
 				65F9F4842CFC16A100F187A8 /* KMNSearchHanddler.swift */,
 			);
 			path = Tools;
@@ -8260,6 +8253,8 @@
 				65F9F48D2CFCABE700F187A8 /* KMNBotaSearchTopView.xib */,
 				65C404302CFDA62500B32BDC /* KMNSearchReplaceItemView.swift */,
 				65C404352CFDE1E600B32BDC /* KMNBotaSearchCellView.swift */,
+				657851782CFEE4580023D640 /* KMNSearchReplaceTitleBarView.swift */,
+				6578517C2CFEE4850023D640 /* KMNSearchReplaceSearchItemView.swift */,
 			);
 			path = View;
 			sourceTree = "<group>";
@@ -10983,7 +10978,6 @@
 		BB031B3D2C47BB070099F7AD /* Tools */ = {
 			isa = PBXGroup;
 			children = (
-				65341C702C63CC2500FE30F9 /* Search */,
 				BB031B3E2C47BB070099F7AD /* UserFeekback */,
 			);
 			path = Tools;
@@ -15059,7 +15053,6 @@
 				BBD9223D2B50D6D600DB9585 /* rate_pic_star.pdf in Resources */,
 				BBDF18182CD4853C00ACDB15 /* KMNWatermarkPropertyController.xib in Resources */,
 				BB1B0B042B4FC6E900889528 /* KMCustomColorGuideView.xib in Resources */,
-				65341C772C63CCFE00FE30F9 /* KMSearchReplaceWindowController.xib in Resources */,
 				BB6AAF562C2175A3009C4CB1 /* KMEditPDFPopToolBarController.xib in Resources */,
 				ADE86A8D2B02269400414DFA /* KMRemovePasswordWindowController.xib in Resources */,
 				8942F7FB2926089200389627 /* KMSignatureViewController.xib in Resources */,
@@ -15124,6 +15117,7 @@
 				89D2D2FE294C806000BFF5FE /* KMPDFThumbnailItem.xib in Resources */,
 				BBD14F5A2CDA02640077D52E /* KMEditToolbarView.xib in Resources */,
 				BB52F5782CC236B6007418DB /* KMLinkWebView.xib in Resources */,
+				657851712CFEE38E0023D640 /* KMSearchReplaceWindowController.xib in Resources */,
 				AD055E282B70B3C10035F824 /* KMBookmarkController.xib in Resources */,
 				BBF62C6C2B033B5B007B7E86 /* KMPDFEditExtractWindow.xib in Resources */,
 				BB88106A2B4F771D00AFA63E /* KMVerificationInfoViewController.xib in Resources */,
@@ -15407,7 +15401,6 @@
 				658FDBAE2C9D4B9600EFA72E /* KMNoteReplyCellView.xib in Resources */,
 				9F72D20C2994BDAF00DCACF1 /* KMNotificationVC.xib in Resources */,
 				65C9CB022CA16B36009794E5 /* DocumentAI.bundle in Resources */,
-				65341C782C63CCFE00FE30F9 /* KMSearchReplaceWindowController.xib in Resources */,
 				ADFCEB492B4FBA440001EBAF /* RemoteConfigDefaults.plist in Resources */,
 				9F3D819729A33A290087B5AD /* KMDesignDropdown.xib in Resources */,
 				BB52F5932CC245B3007418DB /* KMLinkPopupEmailView.xib in Resources */,
@@ -15765,6 +15758,7 @@
 				BB3D076D2CD08FDB00EB94DF /* KMSplitPDFViewController.xib in Resources */,
 				AD5374962C65A426002DE248 /* default.metallib in Resources */,
 				9F080B18298CFDB300FC27DA /* KMTextImageButtonVC.xib in Resources */,
+				657851722CFEE38E0023D640 /* KMSearchReplaceWindowController.xib in Resources */,
 				ADE86A8E2B02269400414DFA /* KMRemovePasswordWindowController.xib in Resources */,
 				BBFE6E832930EBD400142C01 /* KMCompressWindowController.xib in Resources */,
 				AD7D5CC72B9566E9006562CD /* KMBookmarkOutlineView.xib in Resources */,
@@ -16163,7 +16157,6 @@
 				BBE7888C2CBD2463008086E2 /* SidebarDemoVC.xib in Resources */,
 				BB52F5832CC2448C007418DB /* KMLinkPopupBaseView.xib in Resources */,
 				9F1F82DF292F84D60092C4B4 /* KMHomeInsertActionViewController.xib in Resources */,
-				65341C792C63CCFE00FE30F9 /* KMSearchReplaceWindowController.xib in Resources */,
 				BB183DE82B4EC0AF00F99C7E /* KMRepeatVerifyExpireController.xib in Resources */,
 				BB6347CA2AF24F6C00F5438E /* KMBatchoperateConvertCollectionViewItem.xib in Resources */,
 				BB6AAF582C2175A3009C4CB1 /* KMEditPDFPopToolBarController.xib in Resources */,
@@ -16334,6 +16327,7 @@
 				ADFCEB4A2B4FBA440001EBAF /* RemoteConfigDefaults.plist in Resources */,
 				F337CC412CC78B9400D46AF4 /* KMNThumbnailImage.xcassets in Resources */,
 				ADFA8F0F2B579957002595A4 /* KMSearchFindView.xib in Resources */,
+				657851732CFEE38E0023D640 /* KMSearchReplaceWindowController.xib in Resources */,
 				BB51074429A61B4100978662 /* ProgressSheet.xib in Resources */,
 				BBFA1CD32B609EC50053AD4A /* KMScreenShotMaskWindowController.xib in Resources */,
 				89316857296E45CA0073EA59 /* KMImageAccessoryController.xib in Resources */,
@@ -16777,6 +16771,7 @@
 				BBF811E02B07178F0074874F /* KMExtractImageWindowController.swift in Sources */,
 				BB96A0B82AFCE45800559E24 /* WaitingView.swift in Sources */,
 				F3EF179C2CD5FF8D0007D364 /* KMNThumnailHeaderViewController.swift in Sources */,
+				6578516E2CFEE38E0023D640 /* KMSearchReplaceWindowController.swift in Sources */,
 				BB5A9D522CB6521400F64C1F /* SettingsWindowController.swift in Sources */,
 				65FABB312C9AFB0C00AA92E5 /* KMSectionCellView.swift in Sources */,
 				9FCFECA02AD17B8A00EAD2CB /* SKProgressController.swift in Sources */,
@@ -16817,7 +16812,6 @@
 				BBA5429C29F13A140041BAD0 /* KMMemorandumPattern.swift in Sources */,
 				BB276A582B038D1100AB5578 /* KMOCRPDFWindowController.swift in Sources */,
 				BB46CF4C2AFBB34900281EDF /* AutoSaveManager.swift in Sources */,
-				65341C742C63CCFE00FE30F9 /* KMSearchReplaceWindowController.swift in Sources */,
 				BBDF18152CD4853C00ACDB15 /* KMNWatermarkPropertyController.swift in Sources */,
 				9F221ED729A9EC0900978A59 /* KMFillSignTextPanel.swift in Sources */,
 				BBF8A4032AE8E10100788BAC /* KMBatchConvertParameter.swift in Sources */,
@@ -16882,6 +16876,7 @@
 				BBB789AB2BE8BF2400F7E09C /* AIChatDefaultTIpItem.swift in Sources */,
 				BB30D4822B90249D00702541 /* KMStatusBar.m in Sources */,
 				BB146FB1299DC0D100784A6A /* GTLRErrorObject.m in Sources */,
+				657851792CFEE4580023D640 /* KMNSearchReplaceTitleBarView.swift in Sources */,
 				ADAFDA482AEA7F1300F084BC /* KMAdvertisementShowView.swift in Sources */,
 				65B143A72CF06B97001B5A69 /* Array+KMExtensions.swift in Sources */,
 				BB03D6942B021124008C9976 /* NSSegmentedControl+KMExtension.swift in Sources */,
@@ -16905,7 +16900,6 @@
 				65D88ED22C85826A00DD06E0 /* KMRSAUtils.swift in Sources */,
 				BB67EE202B54FFEF00573BF0 /* ASIDataDecompressor.m in Sources */,
 				BBD14F562CDA02570077D52E /* KMEditToolbarView.swift in Sources */,
-				65341C7C2C646C6400FE30F9 /* KMSearchReplaceHanddler.swift in Sources */,
 				BB00301D298CB799002DD1A0 /* KMPreferenceManager.swift in Sources */,
 				BBF729A32B19624500576AC5 /* KMAddBackgroundOperationQueue.swift in Sources */,
 				BB09477E2C1A9E50005C4DEE /* KMPDFThumbBaseModel.swift in Sources */,
@@ -17127,6 +17121,7 @@
 				BB716D602CDDB710009787ED /* KMHFTemplateController.swift in Sources */,
 				89D2D2DE294C451400BFF5FE /* KMThumbnailViewController.swift in Sources */,
 				BB2C84692BAE716600AF6142 /* KMSegmentedControl.swift in Sources */,
+				6578517D2CFEE4850023D640 /* KMNSearchReplaceSearchItemView.swift in Sources */,
 				ADB2D6ED2947415E0029D2B3 /* KMPrintPaperSetView.swift in Sources */,
 				BB1B0A9D2B4FB88100889528 /* IAPProductsManager.m in Sources */,
 				65B143A42CF06B97001B5A69 /* NSImage+QuickLook.swift in Sources */,
@@ -17494,6 +17489,7 @@
 				AD9527C6295295110039D2BC /* KMPrintPrinterModel.swift in Sources */,
 				AD4C71712B9ADFE0003A6286 /* NSError_Extensions.swift in Sources */,
 				BB146FE4299DC0D100784A6A /* GTLRURITemplate.m in Sources */,
+				657851752CFEE3A10023D640 /* KMSearchReplaceHanddler.swift in Sources */,
 				BBE788F62CBD2464008086E2 /* SliderVC.swift in Sources */,
 				9F1FE50D29407B2B00E952CA /* KMUploadFilePanel.swift in Sources */,
 				BBE0688A2CDDF116000512BC /* KMBatesController.swift in Sources */,
@@ -18248,7 +18244,6 @@
 				BB234F082BA3D798008B3754 /* KMAIIconGuideView.swift in Sources */,
 				ADAFDA492AEA7F1300F084BC /* KMAdvertisementShowView.swift in Sources */,
 				9FE0BBF12B0F2FB000CD1CAC /* KMAnnotationLineWindowController.swift in Sources */,
-				65341C752C63CCFE00FE30F9 /* KMSearchReplaceWindowController.swift in Sources */,
 				AD8F06182999DB5900D93CBC /* KMPrintDrawPage.swift in Sources */,
 				BB147030299DC0D200784A6A /* OIDTokenUtilities.m in Sources */,
 				BB52F5752CC236B1007418DB /* KMLinkWebView.swift in Sources */,
@@ -18259,6 +18254,7 @@
 				9FAAA33A290F72CC0046FFCE /* KMHistoryFileCollectionView.swift in Sources */,
 				BBCE57192A72723600508EFC /* NSResponder+KMExtension.swift in Sources */,
 				BB146FC1299DC0D100784A6A /* GTMSessionFetcherLogging.m in Sources */,
+				6578516F2CFEE38E0023D640 /* KMSearchReplaceWindowController.swift in Sources */,
 				656C1E412CD0745200295F82 /* KMConvertSettingLimitTipView.swift in Sources */,
 				F3DB86072CCA691B00D0AFDE /* KMNExtractPDFWindowController.swift in Sources */,
 				AD1FE8362BD7C98300AA4A9B /* KMPDFPrintManageWindowController.m in Sources */,
@@ -18273,6 +18269,7 @@
 				BB3D970B2B2FEAC8007094C8 /* KMPDFRedactViewController.swift in Sources */,
 				ADDF83302B391A5C00A81A4E /* NSGeometry+PDFListView.m in Sources */,
 				BB65A06C2AF8D8A1003A27A0 /* KMNotesPreferences.swift in Sources */,
+				6578517E2CFEE4850023D640 /* KMNSearchReplaceSearchItemView.swift in Sources */,
 				BB6EA2982B70AF48000D4490 /* KMConvertCompareViewController.m in Sources */,
 				9F0CB4EA2986559400007028 /* KMDesignToken+PaddingBottom.swift in Sources */,
 				BB96A0B12AFCD56100559E24 /* KMToolCompareWindowController.swift in Sources */,
@@ -18335,6 +18332,7 @@
 				BB5A9D5C2CB6521400F64C1F /* SettingsManager.swift in Sources */,
 				BBFEF7182B3A77E700C28AC0 /* KMSystemFileMenu.swift in Sources */,
 				653647712CDC8C3700CDB13E /* KMNTableHeaderCellView.swift in Sources */,
+				6578517A2CFEE4580023D640 /* KMNSearchReplaceTitleBarView.swift in Sources */,
 				AD58F40F2B1DAAA800299EE0 /* KMPrintDefaultView.swift in Sources */,
 				BB03D68D2B01C782008C9976 /* KMPDFEditInsertBlankPageWindow.swift in Sources */,
 				BB031B612C47BB080099F7AD /* KMUserFeekbackWindowController.swift in Sources */,
@@ -18435,8 +18433,8 @@
 				9F0CB53A2986570600007028 /* KMDesignToken+BoxShadow.swift in Sources */,
 				9F02017A2A1B5C0300C9B673 /* KMAIServerConfig.swift in Sources */,
 				9F0CB4B62977BC1000007028 /* KMPropertiesPanelPreviewSubVC.swift in Sources */,
-				65341C7D2C646C6400FE30F9 /* KMSearchReplaceHanddler.swift in Sources */,
 				BB88109B2B4F7CD100AFA63E /* KMVerificationTrialViewController.m in Sources */,
+				657851762CFEE3A10023D640 /* KMSearchReplaceHanddler.swift in Sources */,
 				F3EF179D2CD5FF8D0007D364 /* KMNThumnailHeaderViewController.swift in Sources */,
 				9F1FE4E229406E4700E952CA /* GTMNSAnimation+Duration.m in Sources */,
 				BB2C846D2BAE716600AF6142 /* KMBotaTableRowView.swift in Sources */,
@@ -19092,6 +19090,7 @@
 				BBB7B4932A03AD2A00B58A5A /* KMPDFEditToolbar.swift in Sources */,
 				BB1B0AF72B4FC6E900889528 /* KMConvertGuideView.swift in Sources */,
 				BB86C1EF28F544F4005AD968 /* CPDFListView+Event.m in Sources */,
+				657851702CFEE38E0023D640 /* KMSearchReplaceWindowController.swift in Sources */,
 				BB6710662BC672260018CE54 /* KMSignatureWindowController.m in Sources */,
 				BBE788BC2CBD2463008086E2 /* AlertControllerVC.swift in Sources */,
 				ADBC2D39299F0A5A006280C8 /* KMPrintHelpViewController.swift in Sources */,
@@ -19273,7 +19272,6 @@
 				BB2EDF7B296ECE17003BCF58 /* KMPageEditThumbnailItem.swift in Sources */,
 				9FD0FA4D29D43D6800F2AB0D /* KMDeviceBrowserWindowController.swift in Sources */,
 				BB146FC2299DC0D100784A6A /* GTMSessionFetcherLogging.m in Sources */,
-				65341C762C63CCFE00FE30F9 /* KMSearchReplaceWindowController.swift in Sources */,
 				ADDF83792B391A5D00A81A4E /* CDSignatureCertificateCustomViewController.swift in Sources */,
 				BB9599C52B31647B0062D346 /* KMRedactPropertiesWindowController.swift in Sources */,
 				BB451A9C2CF59F4C003E1565 /* KMPenController.swift in Sources */,
@@ -19347,7 +19345,6 @@
 				89D2D30A295A83B500BFF5FE /* KMEditPDFTextPropertyViewController.swift in Sources */,
 				651675CC2CE3312000019A20 /* KMTocTableCellView.swift in Sources */,
 				ADBC2CFC299CA6B9006280C8 /* KMPrintDuplexPrintingSetView.swift in Sources */,
-				65341C7E2C646C6400FE30F9 /* KMSearchReplaceHanddler.swift in Sources */,
 				BBC4F9EC2AEB58290098A1A8 /* KMAlertWindowController.swift in Sources */,
 				BB24FFE82B2863EF00A59054 /* KMTTSManager.swift in Sources */,
 				657865F52CE1E7DD00AFE2DB /* KMNBookmarkHanddler.swift in Sources */,
@@ -19403,6 +19400,8 @@
 				F35242902CCB768B0000A901 /* KMNFileAttribute.swift in Sources */,
 				BBBB6CD82AD150D20035AA66 /* CPDFCircleAnnotation+PDFListView.swift in Sources */,
 				BB19A7692CB7D0F4008204DC /* KMHomeFilesEmptyHeaderView.swift in Sources */,
+				657851772CFEE3A10023D640 /* KMSearchReplaceHanddler.swift in Sources */,
+				6578517F2CFEE4850023D640 /* KMNSearchReplaceSearchItemView.swift in Sources */,
 				BBCB9EA82CCDF65000563AC8 /* KMNDisplayViewController.swift in Sources */,
 				BB3D076B2CD08FDB00EB94DF /* KMSplitPDFViewController.swift in Sources */,
 				ADDEEA882AD7805200EF675D /* KMGeneralButton.swift in Sources */,
@@ -19657,6 +19656,7 @@
 				BBB9B31E299A5D6D004F3235 /* KMCloudOperation.m in Sources */,
 				F3EF17992CD5FE330007D364 /* KMNThumnailViewController.swift in Sources */,
 				ADDF839D2B391A5D00A81A4E /* PDFCertExportAccessoryView.swift in Sources */,
+				6578517B2CFEE4580023D640 /* KMNSearchReplaceTitleBarView.swift in Sources */,
 				89D2D2BF29486D2400BFF5FE /* KMSignatureCellView.swift in Sources */,
 				BBBE68162CC7C02800358B31 /* KMPDFViewManager.swift in Sources */,
 				BB2EDF56296E815E003BCF58 /* KMPageEditBaseItemView.swift in Sources */,