//
//  KMMainViewController.swift
//  PDF Reader Pro
//
//  Created by wanjun on 2022/12/15.
//

import Cocoa
import KMComponentLibrary

let MIN_SIDE_PANE_WIDTH: NSNumber = 264 // 最小值
let CPDFViewIsReadModeKey = "kKMPDFViewIsReadMode"
let CPDFViewLeftSidePaneWidthKey = "CPDFOfficeLeftSidePaneWidthKey"

struct KMNMWCFlags {
    var settingUpWindow: Bool = true
}

@objcMembers class KMMainViewController: KMNBaseViewController, NSTextFieldDelegate {
    
    @IBOutlet var contendBox: NSBox!
    
    @IBOutlet var toolbarBox: NSBox! //工具栏Box
    
    @IBOutlet var bottomContendBox: NSBox! //
    
    @IBOutlet var sidebarBox: NSBox! //左侧边栏Box
    
    @IBOutlet var infoContendSplitView: NSSplitView!
    @IBOutlet var infoSplitLeftView: NSView!
    @IBOutlet var infoSplitRightView: NSView!
    @IBOutlet var infoSplitCenterView: NSView!
    
    @IBOutlet var pdfSplitView: NSSplitView!
    @IBOutlet var pdfSplitTopView: NSView!
    @IBOutlet var pdfSplitBottomView: NSView!
    
    @IBOutlet var toolbarBoxHeightConst: NSLayoutConstraint!
    @IBOutlet var infoSplitViewLeftConst: NSLayoutConstraint!
    @IBOutlet var infoSplitViewRightConst: NSLayoutConstraint!
    
    var viewManager: KMPDFViewManager = KMPDFViewManager.init()
    var toolbarManager: KMPDFToolbarManager = KMPDFToolbarManager.init()
    
    var listView: CPDFListView = CPDFListView.init()
    var document: CPDFDocument?
    var myDocument: NSDocument?
    
    var isFirstOpen: Bool = true
    
    var insertDocuments: Set<CPDFDocument> = [] //插入新文档时,SDK会出现崩溃,临时记录
    
    //工具栏
    private var pdfToolbarController: KMPDFToolbarController?
    
    //BOTA SideBar
    private var sideBarController: KMPDFSideBarController?
    
    //页面编辑
    private var pageEditViewController: KMNPageEditViewController?
    
    //DisplaySetting
    private var displaySettingController: KMNDisplayViewController?
    
    //SPlitPDF分屏视图
    private var splitPDFController: KMSplitPDFViewController?
    
    private var pageNumberToolbar: KMPageNumberPromptView?
    
    //PPT操作界面
    var presentationTopViewController: KMPresentationTopViewController?
    
    //Edit
    var editToolbarView: KMEditToolbarView?
    //水印
    var watermarkViewController: KMWatermarkController?
    //背景
    var backgroundViewController: KMBackgroundController?
    //Header&Footer
    var headerFooterViewController: KMHeaderFooterController?
    //Bates
    var batesViewController: KMBatesController?
    //Crop
    var cropController: KMCropController?
    
    //左边
    var botaViewController: KMNLeftSideViewController?
    
    //右边
    var rightSideController: KMRightSideController?
    
    let alertTipViewController: KMNAlertTipViewController = KMNAlertTipViewController(nibName: "KMNAlertTipViewController", bundle: nil)
    
    //合并
    var mergeWindowController: KMMergeWindowController?
    
    //春季活动
    var recommondPopWindowVC: KMRecommondPopWindow?
    
    //数字签名状态
    var signaturestateVC: CDSignatureCertificateStateViewController = CDSignatureCertificateStateViewController.init()

    //MARK: - 旧代码,有需要用到的拿出来,写好备注
    
    @IBOutlet weak var leftView: NSView!
    
    var model = KMMainModel()
    
    //自动滚动
    var autoFlowOptionsSheetController: KMAutoFlowOptionsSheetController?
    
    //Search
    var searchIndex: Int = 0
    
    //Secure
    var secureAlertView: KMSecureAlertView?
    
    //对比
    var isCompareModel: Bool = false {
        didSet {
        }
    }
    
    //密码弹窗
    var passwordWindow: KMPasswordInputWindow?
    //对比
    var compressWindowController: KMCompressWindowController?
    //
    var securityWindowController: KMSecurityWindowController?
    
    //引导
    var guideInfoWindowController: KMGuideInfoWindowController?
    
    
    var removeAllAnnotationsStore = KMPDFViewRemoveAllAnnotationsStore()
    
    private var _needSave = false
    var needSave: Bool {
        set {
            _needSave = newValue
            
            if (_needSave == false) {
                self.clearIsPDFDocumentEdited()
            }
        }
        get {
            return _needSave
        }
    }
    
    var isPDFDocumentEdited: Bool {
        get {
            return self.model.isPDFDocumentEdited
        }
    }
    var newMwcFlags = KMNMWCFlags(settingUpWindow: true)
    
    var searchResults: [KMSearchMode] = []
    var mwcFlags: MwcFlags = MwcFlags()
    
    weak var browserWindowController: KMBrowserWindowController? //慎直接使用这个方法
    
    var currentWindowController: NSWindowController!
    var savedNormalSetup: NSMutableDictionary = NSMutableDictionary()
        
    var redactController: KMPDFRedactViewController!
    
    let CPDFOfficeLeftSidePaneWidthKey = "CPDFOfficeLeftSidePaneWidthKey"
    let CPDFOfficeRightSidePaneWidthKey = "CPDFOfficeRightSidePaneWidthKey"
    
    var extract: KMExtractImageWindowController?
    
    var functionWidth: Double {
        get {
            if self.viewManager.isPDFReadMode {
                if !self.model.isShowBOTA {
                    return 0
                }
            }
            return 48-4
        }
    }
    
    var pageNumber: UInt?
    
    var pdfEditController: KMPDFEditViewController? {
        get {
            return self.getPDFEditController()
        }
    }
    
    var autoSaveTimer: Timer?
    private var _documentFirstLoad: Bool = true
    
    var eventMonitor: Any?
    var keyEventMonitor: Any?
    var mouseRightMenuEvent: NSEvent?
    
    lazy private var homeVC: KMNHomeViewController? = {
        let vc = KMNHomeViewController()
        return vc
    }()
    
    fileprivate var _secureOptions: [CPDFDocumentWriteOption : Any]?
    var secureOptions: [CPDFDocumentWriteOption : Any]? {
        get {
            return self._secureOptions
        }
    }
    var documentAttribute: [CPDFDocumentAttribute : Any]?
    
    fileprivate var _removeSecureFlag = false
    var removeSecureFlag: Bool {
        get {
            return self._removeSecureFlag
        }
    }
    fileprivate var _saveWatermarkFlag = false
    var saveWatermarkFlag: Bool {
        get {
            return self._saveWatermarkFlag
        }
    }
    
    private var mainWindow_: NSWindow?
    var mainWindow: NSWindow? {
        get {
            return self.mainWindow_
        }
        set {
            self.mainWindow_ = newValue
        }
    }
    
    var setDocument: CPDFDocument? {
        get {
            return document
        }
        set {
            if document != newValue {
                document = newValue
            }
            listView.document = document
            botaViewController?.changeDocument(document: document)
        }
    }
    
    var setPageNumber: UInt {
        get {
            return pageNumber!
        }
        set {
            let pageCount = listView.document?.pageCount ?? 0
            var value = newValue
            if value > pageCount {
                value = pageCount
            }
            if value > 0 && listView.currentPage().pageIndex() != value-1 {
                listView.go(to: listView.document?.page(at: value-1))
            }
            if pageNumber != value {
                pageNumber = value
            }
        }
    }
    
    
    var distanceMeasureInfoWindowController: CDistanceMeasureInfoWindowController?
    var perimeterMeasureInfoWindowController: CPerimeterMeasureInfoWindowController?
    var areaMeasureInfoWindowController: CAreaMeasureInfoWindowController?
    
    //MARK: - func
    deinit {
        NotificationCenter.default.removeObserver(self)
        
        self.listView.delegate = nil
        self.listView.document?.delegate = nil
        
        self.removeEventMonitor()
        self.removeKeyEventMonitor()
    }
    
    override func viewDidLoad() {
        super.viewDidLoad()
        // Do view setup here.
        
        setupData()
        
        setupUI()
        
        NotificationCenter.default.addObserver(self, selector: #selector(pdfViewScrollViewDidScroll), name: NSScrollView.didLiveScrollNotification, object: listView.documentView())
        NotificationCenter.default.addObserver(self, selector: #selector(pageCountChangedNotification), name: NSNotification.Name.CPDFDocumentPageCountChanged, object: listView.document)
        
        loadUserDefaultsData()
    }
    
    override func viewDidAppear() {
        super.viewDidAppear()
        
        reloadPopUIWindow()
    }
    
    override func viewDidDisappear() {
        super.viewDidDisappear()
        
        toggleClosePopUIWindow()
    }
    
    override func initContentView() {
        super.initContentView()
    }
    
    override func updateUIThemeColor() {
        super.updateUIThemeColor()
    }
    
    override func updateUILanguage() {
        super.updateUILanguage()
    }
    
    //MARK: - private
    func setupUI() {
        
        initPDFView()
        
        initToolbar()
        
        initSideBar()
        
        setUpSplitView()
    }
    
    func setupData() {
        toolbarManager.pdfViewManager = viewManager
        
        if (UserDefaults.standard.object(forKey: CPDFViewLeftSidePaneWidthKey) != nil) {
            UserDefaults.standard.set(MIN_SIDE_PANE_WIDTH, forKey: CPDFViewLeftSidePaneWidthKey)
            UserDefaults.standard.synchronize()
        }
        
        newMwcFlags.settingUpWindow = true
    }
    
    //MARK: - document load成功
    private func documentLoadComplete() {
        loadUserDefaultsData()
        
        initLeftSideController()
        
        addNotificationCenter()
        
        activityLoadMethod()
        
        let readModel = UserDefaults.standard.bool(forKey: CPDFViewIsReadModeKey)
        if readModel == true {
            self.openPDFReadMode()
        }
        
        toggleCloseLeftSide() //根据偏好设置显示左边栏状态
        
        reloadDigitalSigns()
        
        alertTipViewController.showInView(listView)
        alertTipViewController.formFieldHighlightCallback = { [weak self] in
            let highlightFormFiled = CPDFKitConfig.sharedInstance().enableFormFieldHighlight()
            CPDFKitConfig.sharedInstance().setEnableFormFieldHighlight(!highlightFormFiled)
            self?.listView.setNeedsDisplayForVisiblePages()
        }
        
        alertTipViewController.enterPasswordCallback = { [weak self] in
            self?.removeOwnerPassword()
        }
        
        alertTipViewController.digitalDetailsCallback = { [weak self] in
        }
        
        alertTipViewController.redactApplyCallback = { [weak self] in
            let returnCode = KMAlertTool.runModelForMainThread_r(message: "", informative: KMLocalizedString("This will permanently remove the redacted information from this document. Once you save this document, you won’t be able to retrieve the redacted information."), buttons: [KMLocalizedString("Apply"), KMLocalizedString("Cancel")])
            if returnCode == .alertFirstButtonReturn {
                DispatchQueue.main.async {
                    self?.saveAsPath()
                }
            }
        }
                
        newMwcFlags.settingUpWindow = false
    }
    
   private func saveAsPath() {
        let saveAccessCtr = KMSavePanelAccessoryController()
        var fileName = listView.document.documentURL.deletingPathExtension().lastPathComponent
        fileName = String(format: "%@_%@.pdf", fileName, "Redact")
        let outputSavePanel = NSSavePanel()
        outputSavePanel.allowedFileTypes = ["pdf"]
        outputSavePanel.nameFieldStringValue = fileName
        outputSavePanel.accessoryView = saveAccessCtr.view
        outputSavePanel.beginSheetModal(for: NSApp.mainWindow!) { result in
            if result == .OK {
                self.listView.document.applyRedactions()
                self.showProgressWindow(message: KMLocalizedString("Save") + "PDF")
                self.progressC?.maxValue = 3.0
                self.progressC?.increment(by: 1.0)
                let savePDFPath = outputSavePanel.url!.path
                // 执行进度 [假进度]
                self.progressC?.increment(by: 1.0)
                self.progressC?.increment(by: 1.0)
                let isSuccess = self.listView.document.write(toFile: savePDFPath)
                if (isSuccess) {
                    if (saveAccessCtr.openAutomaticButton.state == .on) {
                        NSDocumentController.shared.km_safe_openDocument(withContentsOf: outputSavePanel.url!, display: true) { _, _, _ in
                        }
                    } else {
                        let url = URL(fileURLWithPath: savePDFPath)
                        NSWorkspace.shared.activateFileViewerSelecting([url])
                    }
                }
                
                self.hiddenProgressWindow()
            }
         }
     }
    
    private func reloadDigitalSigns() {
        let signatures = listView.document.signatures()
        
        for i in 0 ..< (signatures?.count ?? 0) {
            let signature:CPDFSignature = signatures?[i] ?? CPDFSignature()
            if signature.signers.count > 0 {
                signature.verifySignature(with: listView.document)//耗时,注意
            }
        }
        
        listView.signatures = signatures
    }
    
    //MARK: - 活动加载相关
    private func activityLoadMethod() {
        
    }
    
    private func addNotificationCenter() {
        NotificationCenter.default.addObserver(self, selector: #selector(annotationsAttributeHasChange), name: NSNotification.Name.CPDFListViewAnnotationsAttributeHasChange, object:nil)
        
        NotificationCenter.default.addObserver(self, selector: #selector(signatureStateChangeNoti), name: NSNotification.Name(rawValue: "CSignatureTrustCerDidChangeNotification"), object: nil)
        
    }
    
    private func loadUserDefaultsData() {
        applyLeftSideWidth(0, rightSideWidth: 0) //初始打开左边栏
    }
    
    func applyLeftSideWidth(_ leftSideWidth: CGFloat, rightSideWidth: CGFloat) -> Void {
        infoContendSplitView.setPosition(infoContendSplitView.maxPossiblePositionOfDivider(at: 1) - infoContendSplitView.dividerThickness - rightSideWidth, ofDividerAt: 1)
        infoContendSplitView.setPosition(leftSideWidth, ofDividerAt: 0)
    }
    
    //MARK: - PDFView
    func initPDFView() {
        listView.autoresizingMask = [.width, .height]
        listView.autoScales = true
        listView.delegate = self
        listView.pdfListViewDelegate = self
        listView.document = self.document
        listView.pageBreakMargins = NSEdgeInsetsMake(10, 0, 10, 10)
        reloadPDFSplitInfo()
    }
    
    func updatePDFViewAnnotationMode() {
        let toolbarMode = viewManager.toolMode
        let subToolMode = viewManager.subToolMode
         
        listView.isHidden = false
         
        if toolbarMode == .None {
            listView.annotationType = .unkown
            
        } else if toolbarMode == .Markup {
            if subToolMode == .None  {
                listView.toolMode = .CTextToolMode
            } else {
                listView.toolMode = .CNoteToolMode
            }
            //MARK: -Markup
            
            if subToolMode == .None {
                listView.annotationType = .unkown
            } else if subToolMode == .Highlight {
                listView.annotationType = .highlight
            } else if subToolMode == .Underline {
                listView.annotationType = .underline
            } else if subToolMode == .Waveline {
                listView.annotationType = .squiggly
            } else if subToolMode == .Strikethrough {
                listView.annotationType = .strikeOut
            } else if subToolMode == .Text {
                listView.annotationType = .freeText
            } else if subToolMode == .Note {
                listView.annotationType = .anchored
            } else if subToolMode == .Pen {
                listView.annotationType = .ink
            } else if subToolMode == .Eraser {
                listView.annotationType = .eraser
            } else if subToolMode == .Rectangle {
                listView.annotationType = .square
            } else if subToolMode == .Circle {
                listView.annotationType = .circle
            } else if subToolMode == .Arrow {
                listView.annotationType = .arrow
            } else if subToolMode == .Line {
                listView.annotationType = .line
            } else if subToolMode == .Measure {
                listView.annotationType = .measureLine
            } else if subToolMode == .Stamp {
                listView.annotationType = .stamp
            } else if subToolMode == .Sign {
                listView.annotationType = .signSignature
            }
        } else if toolbarMode == .Edit {
            //MARK: -编辑
            if subToolMode == .None {
                if listView.toolMode != .CEditPDFToolMode {
                    listView.toolMode = .CEditPDFToolMode
                    listView.configPDFEditingInfo()
                }
                listView.setShouAddEdit([])
                listView.change([.text, .image])
                
            } else if subToolMode == .Edit_text {
                if listView.toolMode != .CEditPDFToolMode {
                    listView.toolMode = .CEditPDFToolMode
                    listView.configPDFEditingInfo()
                }
                listView.setShouAddEdit([.text])
                listView.change(.text)
                
            } else if subToolMode == .Edit_Image {
                if listView.toolMode != .CEditPDFToolMode {
                    listView.toolMode = .CEditPDFToolMode
                    listView.configPDFEditingInfo()
                }
                listView.setShouAddEdit([.image])
                listView.change(.image)
                
            } else if subToolMode == .Edit_Link {
                listView.toolMode = .CEditLinkToolMode
                
                listView.annotationType = .link
                
            } else if subToolMode == .Edit_Crop {
                listView.isHidden = true
                listView.toolMode = .CCropToolMode
            }
            
            if viewManager.editType == .watermark ||
                viewManager.editType == .background ||
                viewManager.editType == .header_Footer ||
                viewManager.editType == .bates {
                listView.isHidden = true
                listView.toolMode = .CTextToolMode

            }
            
            if subToolMode != .Edit_Crop {
                removeCropController()
            }
            
        } else if toolbarMode == .Form {
            //MARK: -Form表单
            listView.toolMode = .CFormToolMode
            if subToolMode == .None {
                listView.annotationType = .unkown
            } else if subToolMode == .Form_text {
                listView.annotationType = .textField
            } else if subToolMode == .Form_checkbox {
                listView.annotationType = .checkBox
            } else if subToolMode == .Form_radio {
                listView.annotationType = .radioButton
            } else if subToolMode == .Form_list {
                listView.annotationType = .listMenu
            } else if subToolMode == .Form_dropdown {
                listView.annotationType = .comboBox
            } else if subToolMode == .Form_OK {
                listView.annotationType = .actionButton
            } else if subToolMode == .Form_digitalSign {
                listView.annotationType = .signature
            }
            
        } else if toolbarMode == .Fill {
            //MARK: -填充
            if subToolMode == .None  {
                listView.toolMode = .CTextToolMode
            } else {
                listView.toolMode = .CNoteToolMode
            }
            if subToolMode == .None {
                
            } else if subToolMode == .Fill_tick {
                listView.annotationType = .signTure
                
            } else if subToolMode == .fill_fork {
                listView.annotationType = .signFalse
                
            } else if subToolMode == .fill_rectangle {
                listView.annotationType = .signCircle
                
            } else if subToolMode == .fill_line {
                listView.annotationType = .signLine
                
            } else if subToolMode == .fill_dot {
                listView.annotationType = .signDot
                
            } else if subToolMode == .fill_date {
                listView.annotationType = .signDate
                
            } else if subToolMode == .fill_sign {
                listView.annotationType = .signSignature
            }
            
        } else if toolbarMode == .Convert {
            //MARK: -转档
            listView.toolMode = .CTextToolMode
            
        } else if toolbarMode == .Protect {
            //MARK: -Protect
            listView.toolMode = .CTextToolMode
            
            /*
             let properties = KMRedactPropertiesWindowController()
             self.km_beginSheet(windowC: properties)
             */

            if subToolMode == .Redact {
                 //密文
                listView.annotationType = .redact
                listView.toolMode = .CRedactToolMode
            } else if subToolMode == .Digital_Sign {
                //数字签名
                listView.annotationType = .digitalSign
                listView.toolMode = .CDigitalSignToolMode
            }

            
            
        } else if toolbarMode == .Tools {
            //MARK: -工具
            if subToolMode == .Tool_OCR {
                listView.toolMode = .COCRToolMode
            } else {
                listView.toolMode = .CTextToolMode
            }
            
        }
    }
    
    func showOrHideNotes() {
        self.listView.hideNotes = !self.listView.hideNotes
        if self.listView.hideNotes {
            listView.annotationType = .unkown
        }
        for note in self.listView.notes as? [CPDFAnnotation] ?? [] {
            if note.isForm() {
                note.setAnnotationShouldDisplay(true)
                note.setHidden(false)
            }
        }
        self.listView.setNeedsDisplayAnnotationViewForVisiblePages()
    }
    
    //MARK: - SplitView
    func setUpSplitView() {
        infoContendSplitView.wantsLayer = true
        infoContendSplitView.layer?.backgroundColor = NSColor.clear.cgColor
        infoContendSplitView.delegate = self
        infoContendSplitView.layer?.masksToBounds = true
    }
    
    func setupSplitPDFController() {
        if splitPDFController == nil {
            splitPDFController = KMSplitPDFViewController.init()
        }
        splitPDFController?.view.frame = pdfSplitBottomView.bounds
        splitPDFController?.view.autoresizingMask = [.height, .width]
        splitPDFController?.viewManager = self.viewManager
        splitPDFController?.delegate = self
        splitPDFController?.reloadData()
        
        pdfSplitBottomView.addSubview(splitPDFController!.view)
    }
    
    //MARK: - 工具栏
    func initToolbar() {
        toolbarBox.borderWidth = 0
        
        if pdfToolbarController == nil {
            pdfToolbarController = KMPDFToolbarController.init()
        }
        pdfToolbarController?.view.frame = toolbarBox.bounds
        pdfToolbarController?.view.autoresizingMask = [.width, .height]
        pdfToolbarController?.delegate = self
        toolbarBox.contentView = pdfToolbarController?.view
        
        pdfToolbarController?.viewManager = viewManager
        pdfToolbarController?.toolbarManager = toolbarManager
        pdfToolbarController?.pdfView = listView
        pdfToolbarController?.setUpData()
        
        refreshToolbarViewHeightInfo()
        
        if listView.showFormFieldName {
            toolbarManager.form_ShowName_Property.righticon = NSImage(named: "tick_Green")
        } else {
            toolbarManager.form_ShowName_Property.righticon = nil
        }
        
        DispatchQueue.main.asyncAfter(deadline: DispatchTime.now() + 0.15) {
            self.pdfToolbarController?.clickWithIdentify(KMPDFToolbar_Markup_Identifier)
        }
        
    }
    
    func refreshToolbarViewHeightInfo() {
        let _viewManager = viewManager
        
        if viewManager.isPageEditMode {
            toolbarBoxHeightConst.constant = 80
            
        } else if viewManager.editType == .watermark ||
                    viewManager.editType == .background ||
                    viewManager.editType == .header_Footer ||
                    viewManager.editType == .bates {
            
            toolbarBoxHeightConst.constant = 40
        } else if _viewManager.toolMode == .Markup ||
                    _viewManager.toolMode == .Edit ||
                    _viewManager.toolMode == .Form ||
                    _viewManager.toolMode == .Fill ||
                    _viewManager.toolMode == .Convert ||
                    _viewManager.toolMode == .Protect ||
                    _viewManager.toolMode == .Tools {
            
            toolbarBoxHeightConst.constant = 80
            if _viewManager.subToolMode == .Redact {
                toolbarBoxHeightConst.constant = 40
            }
        } else {
            toolbarBoxHeightConst.constant = 40
        }
        
    }
    
    func toolbarViewModeChanged() {
        updatePDFViewAnnotationMode()
        
        if viewManager.showRightSide == true {
            toggleOpenRightSide()
        } else {
            toggleCloseRightSide()
        }
        
        
        if viewManager.toolMode != .Edit && viewManager.subToolMode != .Edit_Crop {
            removeCropController()
        }
    }
    
    //MARK: - 侧边工具栏
    func initSideBar() {
        sidebarBox.borderWidth = 0
        
        if sideBarController == nil {
            sideBarController = KMPDFSideBarController.init()
        }
        sideBarController?.view.frame = sidebarBox.bounds
        sideBarController?.view.autoresizingMask = [.width, .height]
        sidebarBox.contentView = sideBarController?.view
        
        sideBarController?.pdfView = listView
        sideBarController?.delegate = self
        sideBarController?.pdfViewManager = viewManager
        
        sideBarController?.reloadData()
    }
    
    //MARK: - 左边侧边栏
    func initLeftSideController() {
        if botaViewController == nil {
            botaViewController = KMNLeftSideViewController(listView.document)
        }
        botaViewController?.leftSideViewDelegate = self
        botaViewController?.view.frame = infoSplitLeftView.bounds
        botaViewController?.view.autoresizingMask = [.width, .height]
        if botaViewController != nil {
            infoSplitLeftView?.addSubview(botaViewController!.view)
        }
    }
    
    private func leftSidePaneIsOpen() -> Bool {
        return !infoContendSplitView.isSubviewCollapsed(infoSplitLeftView) //第一次点击时存在问题,待解决
    }
    
    private func toggleOpenLeftSide(pdfSideBarType: KMPDFSidebarType) {
        if(leftSidePaneIsOpen() == false) {
            let leftWidthNumber = UserDefaults.standard.object(forKey: CPDFViewLeftSidePaneWidthKey) as? NSNumber ?? MIN_SIDE_PANE_WIDTH
            infoContendSplitView.setPosition(MIN_SIDE_PANE_WIDTH.doubleValue, ofDividerAt: 0) //暂时无法记录上一次打开的宽度
        }
        if pdfSideBarType == .search {
            botaViewController?.searchViewC.handdler.pdfView = listView
            botaViewController?.leftsideType = .search
        } else if pdfSideBarType == .thumbnail {
            botaViewController?.leftsideType = pdfSideBarType
            botaViewController?.thumnailViewController?.reloadDatas()
            botaViewController?.currentPageDidChangedAction(listView: listView)
        } else if pdfSideBarType == .outline {
            botaViewController?.outlineViewC.handdler.pdfView = listView
            botaViewController?.leftsideType = pdfSideBarType
        } else if pdfSideBarType == .bookmark {
            botaViewController?.bookmarkViewC.handdler.pdfView = listView
            botaViewController?.leftsideType = pdfSideBarType
        } else if pdfSideBarType == .annotation {
            //            botaViewController?.annoController.handdler.pdfView = listView
            //            botaViewController?.leftsideType = .annotation
        }
    }
    
    private func toggleCloseLeftSide() {
        if(leftSidePaneIsOpen() == true) {
            infoContendSplitView.setPosition(0, ofDividerAt: 0)
        }
    }
    
    //MARK: - 右侧属性栏
    func initRightSideController() {
        if rightSideController == nil {
            rightSideController = KMRightSideController.init()
            rightSideController?.delegate = self
        }
        rightSideController?.view.frame = CGRectMake(0, 0, MIN_SIDE_PANE_WIDTH.doubleValue, 680)
        rightSideController?.view.autoresizingMask = [.height, .maxXMargin]
    }
    
    func removeRightSideController() {
        rightSideController?.view.removeFromSuperview()
        rightSideController = nil
    }
    
    @objc func toggleOpenRightSide() -> Void {
        if rightSideController != nil {
            return
        }
        initRightSideController()
        
        rightSideController?.view.frame = infoSplitRightView.bounds
        rightSideController?.view.autoresizingMask = [.width, .height]
        infoSplitRightView.addSubview(rightSideController!.view)
        infoContendSplitView.setPosition(CGRectGetWidth(view.frame)-MIN_SIDE_PANE_WIDTH.doubleValue, ofDividerAt: 1)
        
        rightSideController?.viewManager = self.viewManager
        
        rightSideController?.reloadDataWithPDFView(pdfView: listView)
    }
    
    @objc func toggleCloseRightSide() -> Void {
        removeRightSideController()
        
        infoContendSplitView.setPosition(CGRectGetWidth(view.frame), ofDividerAt: 1)
    }
    
    func refreshRightSide() -> Void {
        if let rightVC = rightSideController, let _ = rightSideController?.view.superview {
            rightVC.reloadDataWithPDFView(pdfView: listView)
        }
    }
    
    //MARK: - PDFDisplayView
    func updatePDFDisplaySettingView() {
        
        if viewManager.showDisplayView {
            infoSplitViewLeftConst.constant = MIN_SIDE_PANE_WIDTH.doubleValue
        } else {
            infoSplitViewLeftConst.constant = 44
        }
        
        if viewManager.showDisplayView {
            if displaySettingController == nil {
                displaySettingController = KMNDisplayViewController.init()
            }
            displaySettingController?.view.frame = CGRectMake(0, 0, MIN_SIDE_PANE_WIDTH.doubleValue, CGRectGetHeight(bottomContendBox.frame))
            displaySettingController?.view.autoresizingMask = [.height, .maxXMargin]
            bottomContendBox.addSubview(displaySettingController!.view)
            displaySettingController?.pdfView = self.listView
            displaySettingController?.viewManager = self.viewManager
            displaySettingController?.delegate = self
            
            displaySettingController?.reloadData()
            
        } else {
            displaySettingController?.view.removeFromSuperview()
            displaySettingController = nil
        }
    }
    
    //MARK: - 页面编辑
    func enterPageEditMode() {
        pageEditViewController = KMNPageEditViewController(self.document)
        if(pageEditViewController != nil) {
            bottomContendBox.addSubview(pageEditViewController!.view)
            pageEditViewController?.view.frame = bottomContendBox.bounds
            pageEditViewController?.thumbnailBaseViewDelegate = self
            pageEditViewController?.selectionIndexPaths = [IndexPath(item: listView.currentPageIndex, section: 0)]
            pageEditViewController?.view.autoresizingMask = [.width,.height]
            pageEditViewController?.currentUndoManager = listView.undoManager
            toolbarManager.page_pageInfo_Property.text = String(listView.currentPageIndex + 1)
            pdfToolbarController?.refreshSecondToolbarItemsState()
            
            listView.isHidden = true
        }
    }
    
    func exitPageEditMode() {
        if pageEditViewController != nil {
            pageEditViewController?.view.removeFromSuperview()
            pageEditViewController = nil
        }
        
        listView.isHidden = false
        
        if listView.document?.isModified() == true {
            listView.layoutDocumentView()
            botaViewController?.thumnailViewController?.reloadDatas()
        }
    }
    
    //MARK: - 阅读模式
    func openPDFReadMode() {
        if viewManager.showDisplayView {
            viewManager.showDisplayView = false
            pdfToolbarController?.reloadLeftIconView()
            
            updatePDFDisplaySettingView()
        }
        infoSplitViewLeftConst.constant = 0
        toolbarBoxHeightConst.constant = 0
        
        view.window?.makeFirstResponder(listView)
        
        let readModeMessage: ComponentMessage = ComponentMessage()
        readModeMessage.properties = ComponentMessageProperty(messageType: .normal_custom, title: KMLocalizedString("Read Mode On"))
        readModeMessage.frame = CGRectMake((CGRectGetWidth(self.view.frame) - readModeMessage.properties.propertyInfo.viewWidth)/2,
                                           CGRectGetHeight(self.view.frame) - readModeMessage.properties.propertyInfo.viewHeight - 8,
                                           readModeMessage.properties.propertyInfo.viewWidth,
                                           readModeMessage.properties.propertyInfo.viewHeight)
        readModeMessage.reloadData()
        readModeMessage.show(inView: self.view, autoHideSeconde: 2)
        
        setUpPDFPageNumberToolbar()
        
    }
    
    func exitPDFReadMode() {
        viewManager.isPDFReadMode = false
        if viewManager.showDisplayView == false {
            viewManager.showDisplayView = true
            pdfToolbarController?.reloadLeftIconView()
            
        }
        
        updatePDFDisplaySettingView()
        
        refreshToolbarViewHeightInfo()
        
        reloadPDFPageNumberToolbar()
        
        let readModeMessage: ComponentMessage = ComponentMessage()
        readModeMessage.properties = ComponentMessageProperty(messageType: .normal_custom, title: KMLocalizedString("Read Mode Off"))
        readModeMessage.frame = CGRectMake((CGRectGetWidth(self.view.frame) - readModeMessage.properties.propertyInfo.viewWidth)/2,
                                           CGRectGetHeight(self.view.frame) - readModeMessage.properties.propertyInfo.viewHeight - 8,
                                           readModeMessage.properties.propertyInfo.viewWidth,
                                           readModeMessage.properties.propertyInfo.viewHeight)
        readModeMessage.reloadData()
        readModeMessage.show(inView: self.view, autoHideSeconde: 2)
    }
    
    //MARK: - PPT
    func togglePresentation(_ sender: Any?) {
        if self.canExitPresentation() {
            exitFullScreen()
        } else if self.canEnterPresentation() {
            NotificationCenter.default.addObserver(self, selector: #selector(willEnterInteractionModeNotification), name: NSWindow.willEnterInteractionModeNotification, object: nil)
            NotificationCenter.default.addObserver(self, selector: #selector(didEnterInteractionModeNotification), name: NSWindow.didEnterInteractionModeNotification, object: nil)
            NotificationCenter.default.addObserver(self, selector: #selector(willShowFullScreenNotification), name: NSWindow.willShowFullScreenNotification, object: nil)
            NotificationCenter.default.addObserver(self, selector: #selector(didShowFullScreenNotification), name: NSWindow.didShowFullScreenNotification, object: nil)
            
            view.window?.enterPresentation(provider: self)
        }
    }
    
    func enterPresentationMode() {
        let scrollView = listView.documentView().enclosingScrollView
        savedNormalSetup.setValue(scrollView?.hasHorizontalScroller, forKey: KMMainModel.Key.kHasHorizontalScroller)
        savedNormalSetup.setValue(scrollView?.hasVerticalScroller, forKey: KMMainModel.Key.kHasVerticalsCroller)
        savedNormalSetup.setValue(scrollView?.autohidesScrollers, forKey: KMMainModel.Key.kAutoHidesScrollers)
        
        listView.backgroundColor = NSColor.clear
        listView.setDisplay(.singlePage)
        listView.autoScales = true
        listView.displayBox = .cropBox
        listView.displaysPageBreaks = false
        scrollView?.autohidesScrollers = true
        scrollView?.hasHorizontalScroller = false
        scrollView?.hasVerticalScroller = false
        
        listView.setCurrentSelection(nil, animate: true)
    }
    
    func exitPresentationMode() {
        
        NotificationCenter.default.removeObserver(self, name: NSWindow.willEnterInteractionModeNotification, object: nil)
        NotificationCenter.default.removeObserver(self, name: NSWindow.didEnterInteractionModeNotification, object: nil)
        NotificationCenter.default.removeObserver(self, name: NSWindow.willShowFullScreenNotification, object: nil)
        NotificationCenter.default.removeObserver(self, name: NSWindow.willShowFullScreenNotification, object: nil)
        
    }
    
    func exitFullScreen() {
        if self.canExitPresentation() == true {
            let mainDocument = self.myDocument as? KMMainDocument
            let browserWindowController = mainDocument?.browser?.windowController as? KMBrowserWindowController
            browserWindowController?.exitFullscreen()
            
        }
    }
    
    func exitFullscreenMode() {
        if self.interactionMode == .presentation {
            self.exitPresentationMode()
        }
        
        self.applyPDFSettings(self.savedNormalSetup)
        self.savedNormalSetup.removeAllObjects()
        
        listView.layoutDocumentView()
        listView.requiresDisplay()
        
        if let backgroundColor = UserDefaults.standard.color(forKey: KMBackgroundColorKey) {
            listView.backgroundColor = backgroundColor
        }
    }
    
    func applyPDFSettings(_ setup: NSDictionary) {
        if let data = setup.object(forKey: KMMainModel.Key.kAutoScales) as? NSNumber {
            self.listView.autoScales = data.boolValue
        }
        if self.listView.autoScales == false {
            if let data = setup.object(forKey: KMMainModel.Key.kScaleFactor) as? NSNumber {
                self.listView.scaleFactor = data.floatValue.cgFloat
            }
        }
        
        if let data = setup.object(forKey: KMMainModel.Key.kDisplayMode) as? NSNumber {
            self.listView.setDisplay(CPDFDisplayViewMode(rawValue: data.intValue) ?? .singlePage)
        }
        
        if let data = setup.object(forKey: KMMainModel.Key.kDisplaysAsBook) as? NSNumber {
            self.listView.displaysAsBook = data.boolValue
        }
        
        if let data = setup.object(forKey: KMMainModel.Key.kDisplaysPageBreaks) as? NSNumber {
            self.listView.displaysPageBreaks = data.boolValue
        }
        
        if let data = setup.object(forKey: KMMainModel.Key.kDisplayBox) as? NSNumber {
            
        }
        
        self.listView.layoutDocumentView()
    }
    
    func currentPDFSettings() -> NSDictionary {
        let setup = NSMutableDictionary()
        setup[KMMainModel.Key.kDisplaysPageBreaks] = NSNumber(value: listView.displaysPageBreaks)
        setup[KMMainModel.Key.kDisplaysAsBook] = NSNumber(value: listView.displaysAsBook)
        setup[KMMainModel.Key.kDisplayBox] = NSNumber(value: listView.displayBox.rawValue)
        setup[KMMainModel.Key.kScaleFactor] = NSNumber(value: listView.scaleFactor)
        setup[KMMainModel.Key.kAutoScales] = NSNumber(value: listView.autoScales)
        setup[KMMainModel.Key.kDisplayMode] = NSNumber(value: listView.fetchDisplayViewMode().rawValue)
        
        return setup
    }
    
    func canEnterFullscreen() -> Bool {
        if (mwcFlags.isSwitchingFullScreen != 0) {
            return false
        }
        if useNativeFullScreen() {
            return interactionMode == .normal || interactionMode == .presentation
        } else {
            return !self.listView.document.isLocked && (interactionMode == .normal || interactionMode == .presentation) && self.view.window?.tabbedWindows?.count ?? 0 < 2
        }
    }
    
    override func canEnterPresentation() -> Bool {
        let can = super.canEnterPresentation()
        if can == false {
            return false
        }
        guard let doc = self.listView.document, doc.isLocked == false else {
            return false
        }
        return can
    }
    
    func fadeOutFullScreenWindow() {
        guard let fullScreenWindow = self.view.window as? KMFullScreenWindow else {
            NSSound.beep()
            return
        }
        
        let mainWindow = fullScreenWindow.interactionParent
        let collectionBehavior = mainWindow?.collectionBehavior
        
        mainWindow?.alphaValue = 0
        if let data = mainWindow?.responds(to: NSSelectorFromString("setAnimationBehavior:")), data {
            mainWindow?.animationBehavior = .none
        }
        // trick to make sure the main window shows up in the same space as the fullscreen window
        fullScreenWindow.addChildWindow(mainWindow!, ordered: .below)
        fullScreenWindow.removeChildWindow(mainWindow!)
        fullScreenWindow.level = .popUpMenu
        // these can change due to the child window trick
        mainWindow?.level = .normal
        mainWindow?.alphaValue = 1.0
        mainWindow?.collectionBehavior = collectionBehavior!
        mainWindow?.display()
        mainWindow?.makeFirstResponder(self.listView)
        mainWindow?.recalculateKeyViewLoop()
        //        mainWindow?.delegate = self
        mainWindow?.makeKey()
        
        if let data = mainWindow?.responds(to: NSSelectorFromString("setAnimationBehavior:")), data {
            mainWindow?.animationBehavior = .default
        }
        NSApp.removeWindowsItem(fullScreenWindow)
        fullScreenWindow.fadeOut()
    }
    
    //MARK: - PDF分屏视图
    func reloadPDFSplitInfo() {
        if listView.viewSplitMode == .disable {
            pdfSplitView.isHidden = true
            listView.frame = infoSplitCenterView.bounds
            infoSplitCenterView.addSubview(listView)
            
            if splitPDFController != nil {
                splitPDFController = nil
            }
        } else {
            pdfSplitView.isHidden = false
            listView.frame = pdfSplitTopView.bounds
            pdfSplitTopView.addSubview(listView)
            
            setUpPDFPageNumberToolbar()
            
            setupSplitPDFController()
            
            if listView.viewSplitMode == .horizontal {
                pdfSplitView.isVertical = false
            } else if listView.viewSplitMode == .vertical {
                pdfSplitView.isVertical = true
            }
        }
    }
    
    func setUpPDFPageNumberToolbar() {
        if pageNumberToolbar != nil {
            pageNumberToolbar?.removeFromSuperview()
            pageNumberToolbar = nil
        }
        if pageNumberToolbar == nil {
            pageNumberToolbar = KMPageNumberPromptView.init()
        }
        pageNumberToolbar?.frame = CGRectMake(CGRectGetWidth(listView.frame)/2-144, 20, 288, 40)
        pageNumberToolbar?.autoresizingMask = [.minXMargin, .maxXMargin, .maxYMargin]
        pageNumberToolbar?.pdfView = self.listView
        pageNumberToolbar?.reloadData()
        pageNumberToolbar?.isHidden = true
        
        listView.addSubview(pageNumberToolbar!)
        
        reloadPDFPageNumberToolbar()
    }
    
    func reloadPDFPageNumberToolbar() {
        if viewManager.isPDFReadMode == true ||
            (viewManager.splitShowBottomBar && listView.viewSplitMode != .disable) {
            
            pageNumberToolbar?.isHidden = false
            pageNumberToolbar?.reloadData()
        } else {
            pageNumberToolbar?.isHidden = true
            
        }
    }
    //MARK: - Edit模式
    func showEditToolbarView() {
        if editToolbarView == nil {
            editToolbarView = KMEditToolbarView()
        }
        editToolbarView?.frame = toolbarBox.bounds
        editToolbarView?.delegate = self
        editToolbarView?.autoresizingMask = [.width, .height]
        toolbarBox.contentView = editToolbarView
    }
    
    func exitEditToolbarView() {
        viewManager.editType = .none
        viewManager.subToolMode = .None
        
        editToolbarView?.removeFromSuperview()
        editToolbarView = nil
        
        watermarkViewController?.view.removeFromSuperview()
        watermarkViewController = nil
        
        backgroundViewController?.view.removeFromSuperview()
        backgroundViewController = nil
        
        headerFooterViewController?.view.removeFromSuperview()
        headerFooterViewController = nil
        
        batesViewController?.view.removeFromSuperview()
        batesViewController = nil
        
        refreshToolbarViewHeightInfo()
        toolbarBox.contentView = pdfToolbarController?.view
        
        updatePDFViewAnnotationMode()
    }
    
    func updateEditModeDocumentWhenPageChanged() {
        if viewManager.editType == .watermark {
            updateWatermarkDocument()
        } else if viewManager.editType == .background {
            updateBackgroundDocument()
        } else if viewManager.editType == .header_Footer {
            updateHeaderFooterDocument()
        } else if viewManager.editType == .bates {
            updateBatesDocument()
        } else if viewManager.subToolMode == .Edit_Crop {
            updateCropDocument()
        }
    }
    
    //MARK: - 数字签名
    func writeSignatureToWidget(_ widget: CPDFSignatureWidgetAnnotation, _ path: String, _ password: String, _ config: CPDFSignatureConfig, _ isLock: Bool) ->() {
        
        let fileName = listView.document.documentURL?.lastPathComponent
        let fileNameWithoutExtension = URL(fileURLWithPath: fileName!).deletingPathExtension().lastPathComponent

        let outputSavePanel = NSSavePanel()
        outputSavePanel.directoryURL = listView.document.documentURL.deletingLastPathComponent()
        outputSavePanel.title = NSLocalizedString("", comment: "Save as PDF")
        outputSavePanel.allowedFileTypes = ["pdf"]
        outputSavePanel.nameFieldStringValue = fileNameWithoutExtension + "_" + NSLocalizedString("Signed", comment: "")
        let result = outputSavePanel.runModal()
        if result == .OK {
            let contentArr = NSMutableArray()
            var locationStr = ""
            var reasonStr = NSLocalizedString("none", comment: "")
            for item in config.contents {
                if item.key == NSLocalizedString("Reason", comment: "") {
                    if item.value == NSLocalizedString("<your signing reason here>", comment: "") {
                        item.value = " " + NSLocalizedString("none", comment: "")
                    }
                    reasonStr = item.value
                } else if item.key == NSLocalizedString("Location", comment: "") {
                    if item.value == NSLocalizedString("<your signing location here>", comment: "") {
                        item.value = " "
                    }
                    locationStr = item.value
                }
                contentArr.add(item)
            }
            config.contents = contentArr as? [CPDFSignatureConfigItem]
            widget.signAppearanceConfig(config)
            
            let success = listView.document.writeSignature(to: outputSavePanel.url, withWidget: widget, pkcs12Cert: path, password: password, location: locationStr, reason: reasonStr, permissions: .forbidChange)
            widget.removeSignature()
            if success {
                DispatchQueue.main.asyncAfter(deadline: DispatchTime.now() + 0.3) {
                    NSDocumentController.shared.openDocument(withContentsOf: outputSavePanel.url!, display: true) { document, documentWasAlreadyOpen, error in
                        if error != nil {
                            NSApp.presentError(error!)
                            return
                        }
                    }
                }
            } else {
                let alert = NSAlert.init()
                alert.messageText = NSLocalizedString("Save failed!", comment: "")
                alert.addButton(withTitle: NSLocalizedString("OK", comment: ""))
                alert.runModal()
            }
            widget.page.removeAnnotation(widget)
            listView.setNeedsDisplayAnnotationViewFor(widget.page)
        } else {
            widget.page.removeAnnotation(widget)
            listView.setNeedsDisplayAnnotationViewFor(widget.page)
        }
    }
    
    func popUpSignatureWidgetState(_ signature: CPDFSignature, _ pdfListView: CPDFListView) ->(){
        signaturestateVC.signature = signature
        signaturestateVC.pdfListView = pdfListView
        signaturestateVC.actionBlock = { [weak self, weak signaturestateVC] stateVCSelf, actionType in
            guard let weakSelf = self, let stateVC = signaturestateVC else { return }
            if actionType == .cancel {
                stateVC.dismiss(stateVCSelf)
            } else if actionType == .confirm {
                if let signer = signature.signers.first, let data = signer.certificates {
                    let signatureDetail = DSignatureDetailsViewController.init()
                    signatureDetail.certificates = data
                    signatureDetail.signature = signature
                    signatureDetail.pdfListView = pdfListView
                    stateVCSelf.presentAsSheet(signatureDetail)
                } else {
                    NSSound.beep()
                }
            }
        }
        self.presentAsSheet(signaturestateVC)
        signaturestateVC.reloadData()
    }

    
    // MARK: - 显示合并窗口
    public func showMergeWindow(url: URL? = nil, _ password: String?) {
        DispatchQueue.main.async {
            var documentURL = url
            if documentURL == nil {
                documentURL = self.listView.document?.documentURL
            }
            
            guard let _url = documentURL else { return }
            guard let document = PDFDocument(url: _url) else { return }
            
            self.mergeWindowController = KMMergeWindowController(document: document, password: password ?? "")
            self.mergeWindowController!.oriDucumentUrl = self.listView.document?.documentURL
            self.mergeWindowController!.pageIndex = self.listView.currentPageIndex
            
            self.mergeWindowController!.cancelAction = { [unowned self] controller in
                self.view.window?.endSheet(mergeWindowController!.window!)
            }
            
            self.mergeWindowController!.mergeAction = { [unowned self] controller, filePath in
                self.view.window?.endSheet(mergeWindowController!.window!)
            }
            
            self.view.window?.beginSheet(self.mergeWindowController!.window!)
        }
    }
    
    //MARK: - Crop裁剪
    func showCropController() {
        if cropController == nil {
            cropController = KMCropController.init()
            
            cropController?.view.frame = infoSplitCenterView.bounds
            cropController?.view.autoresizingMask = [.width, .height]
            cropController?.delegate = self
            infoSplitCenterView.addSubview(cropController!.view)
            
            updateCropDocument()
            
            if viewManager.showRightSide == false {
                viewManager.showRightSide = true
                pdfToolbarController?.reloadRightToolsView()
                
                toggleOpenRightSide()
            }
        }
    }
    
    func updateCropDocument() {
        
        guard let controller = cropController else { return }
        
        controller.pdfDocument = nil
        
        let page = listView.document.page(at: UInt(listView.currentPageIndex))
        
        let editDocument = CPDFDocument.init()
        editDocument?.insertPageObject(page, at: 0)
        if let editPage = editDocument?.page(at: 0) {
            editPage.setBounds(CGRectMake(0, 0, editPage.bounds(for: .mediaBox).size.width, editPage.bounds(for: .mediaBox).size.height), for: .cropBox)
            controller.selectionRect = page?.bounds(for: .cropBox) ?? .zero
        }
        controller.pdfDocument = editDocument
        controller.reloadData()
        
    }
    
    func removeCropController() {
        if cropController != nil {
            cropController?.view.removeFromSuperview()
            cropController = nil
            
            toolbarManager.edit_crop_Property.state = .normal
        }
        
    }
    
    //MARK: - Watermark水印
    func showWatermarkController() {
        viewManager.editType = .watermark
        
        showEditToolbarView()
        editToolbarView?.editType = .watermark
        if KMWatermarkManager.defaultManager.watermarks.count == 0 {
            editToolbarView?.editSubType = .add
        } else {
            editToolbarView?.editSubType = .template
        }
        editToolbarView?.reloadData()
        
        if watermarkViewController == nil {
            watermarkViewController = KMWatermarkController.init()
        }
        watermarkViewController?.view.frame = CGRectMake(44, 0, CGRectGetWidth(bottomContendBox.frame)-44, CGRectGetHeight(bottomContendBox.frame))
        watermarkViewController?.view.autoresizingMask = [.maxXMargin, .width, .height]
        watermarkViewController?.delegate = self
        bottomContendBox.contentView?.addSubview(watermarkViewController!.view)
        
        watermarkViewController?.editSubType = editToolbarView?.editSubType ?? .template
        
        updateWatermarkDocument()
    }
    
    func updateWatermarkDocument() {
        
        guard let controller = watermarkViewController else { return }
        
        var editDocument = CPDFDocument.init()
        if let vcDoc = controller.pdfDocument {
            editDocument = vcDoc
        }
        
        let page = listView.document.page(at: UInt(listView.currentPageIndex))
        editDocument?.insertPageObject(page, at: 0)
        if editDocument?.pageCount == 2 {
            let theIndex = IndexSet(integer: 1)
            editDocument?.removePage(at: theIndex)
        }
        if watermarkViewController?.pdfDocument == nil {
            watermarkViewController?.pdfDocument = editDocument
        }
        watermarkViewController?.resetUI()
        watermarkViewController?.reloadData()
        
    }
    
    //移除文档水印
    func removePDFWatermark() {
        let watermarks = self.listView.document.watermarks()
        if (watermarks == nil || watermarks!.count <= 0) {
            let alert = NSAlert()
            alert.alertStyle = .warning
            alert.messageText = NSLocalizedString("Could not find a removable watermark in this document. If you see a watermark, it was not added with PDF Reader Pro and therefore cannot be detected.", comment: "")
            alert.addButton(withTitle: NSLocalizedString("Confirm", comment: ""))
            alert.runModal()
            return
        }
        
        let alert = NSAlert()
        alert.alertStyle = .warning
        alert.messageText = NSLocalizedString("Are you sure you want to remove the watermark?", comment: "")
        alert.addButton(withTitle: NSLocalizedString("Delete", comment: ""))
        alert.addButton(withTitle: NSLocalizedString("Cancel", comment: ""))
        let result = alert.runModal()
        if (result == .alertFirstButtonReturn) {
            for watermark in watermarks! {
                listView.document.removeWatermark(watermark)
            }
            listView.layoutDocumentView()
            
            _ = KMNCustomAlertView.alertView(message: KMLocalizedString("Watermark removed"),
                                             type: .success,
                                             fromView: bottomContendBox,
                                             point:CGPointMake(CGRectGetWidth(bottomContendBox.frame)/2, CGRectGetHeight(bottomContendBox.frame)-28))
            
        }
    }
    
    func batchAddWatermark() {
        
    }
    
    func batchRemoveWatermark() {
        
    }
    
    //MARK: - PopUI
    func reloadPopUIWindow() {
        if listView.toolMode == .CSelectToolMode {
            let pageRect = listView.currentSelectionRect()
            let page:CPDFPage? = listView.currentSelectionPage()
            
            if listView.selectionRect != CGRectZero  && page != nil {
                let positioningRect = listView.convert(pageRect, from: page)
                if (CGRectIntersectsRect(positioningRect, listView.frame)) {
                    reloadPopUIOperation()
                    return
                }
            }
            toggleClosePopUIWindow()
        } else if(listView.isEditing() == false) {
            let activeAnnotations:[CPDFAnnotation] = listView.activeAnnotations as! [CPDFAnnotation]
            if(activeAnnotations.count > 0) {
                if let page = activeAnnotations.first?.page {
                    let pageRect = listView.selectionMultipleBounds(with: activeAnnotations)
                    let positioningRect = listView.convert(pageRect, from: page)
                    if (CGRectIntersectsRect(positioningRect, listView.frame)) {
                        reloadPopUIActiveAnnotations(activeAnnotations: activeAnnotations)
                        return
                    }
                }
            }
            toggleClosePopUIWindow()
        } else {
            let editAreas:[CPDFEditArea] = listView.km_EditingAreas()
            if(editAreas.count > 0) {
                if let page = editAreas.first?.page {
                    let pageRect = listView.selectionMultipleBounds(withEditArea: editAreas)
                    let positioningRect = listView.convert(pageRect, from: page)
                    if (CGRectIntersectsRect(positioningRect, listView.frame)) {
                        reloadPopUIContentEdits(editAreas: editAreas)
                        return
                    }
                }
            }
            toggleClosePopUIWindow()
        }
    }
    
    func toggleClosePopUIWindow() {
        let popWindow = KMNPopAnnotationWindowController.shared
        if popWindow.window?.isVisible  == true {
            closeAnnotationPopWindow()
        }
        let editPopWindow = KMNPopContentEditWindowController.shared
        if editPopWindow.window?.isVisible  == true {
            closePopContentEditWindow()
        }
        
        let operationWindow = KMNPopOperationWindowController.shared
        if operationWindow.window?.isVisible  == true {
            closePopOperationWindow()
        }
    }
    
    func closeAnnotationPopWindow() {
        KMNPopAnnotationWindowController.shared.closeWindow(listView: listView)
    }
    
    func closePopContentEditWindow() {
        KMNPopContentEditWindowController.shared.closeWindow(listView: listView)
    }
    
    func closePopOperationWindow() {
        KMNPopOperationWindowController.shared.closeWindow(listView: listView)
    }
    
    func reloadPopUIOperation() {
        if listView.selectionRect != CGRectZero {
            let popWindow = KMNPopOperationWindowController.shared

            if popWindow.window?.isVisible == false {
                listView.window?.addChildWindow(popWindow.window ?? NSWindow(), ordered: .above)
            }
            popWindow.listView = listView
            if listView.toolMode == .CSelectToolMode {
                popWindow.popType = .crop
            } else if listView.toolMode == .COCRToolMode {
                popWindow.popType = .ocr
            }
            updatePopOperationPopWinodwFrame()
            popWindow.updatePDFViewCallback = {[weak self] in
                self?.closePopOperationWindow()
                self?.listView.setNeedsDisplayForVisiblePages()
            }
            
            popWindow.cropCurrentCallback = {[weak self] in
                let rect = self?.listView.currentSelectionRect() ?? CGRect.zero
                let orgPage : CPDFPage = self?.listView.currentSelectionPage() ?? CPDFPage()
                self?.cropPages(atIndexs: [orgPage.pageIndex()], to: [rect])
                self?.closePopOperationWindow()
            }
        } else {
            closePopOperationWindow()
        }
    }
    
    func reloadPopUIActiveAnnotations(activeAnnotations:[CPDFAnnotation]) {
        let annotationMode = KMNAnnotationPopMode(pdfAnnotations: activeAnnotations )
        let popWindow = KMNPopAnnotationWindowController.shared
        if annotationMode.popType == .popTypeNone {
            closeAnnotationPopWindow()
        } else {
            if popWindow.window?.isVisible == false {
                listView.window?.addChildWindow(popWindow.window ?? NSWindow(), ordered: .above)
            }
            popWindow.listView = listView
            popWindow.annotationPopMode = annotationMode
            popWindow.isOpenPane = viewManager.showRightSide
            updateAnnotationsPopWinodwFrame()
            
            popWindow.updatePDFViewCallback = {[weak self] in
                self?.rightSideController?.reloadDataWithPDFView(pdfView: self?.listView ?? CPDFListView())
                self?.listView.setNeedsDisplayMultiAnnotations(annotationMode.annotations)
            }
            
            popWindow.paneCallback = {[weak self] isOpen in
                if isOpen == true && self?.viewManager.showRightSide == false {
                    self?.toggleCloseRightSide()
                } else {
                    self?.toggleOpenRightSide()
                }
            }
        }
    }
    
    func reloadPopUIContentEdits(editAreas:[CPDFEditArea]) {
        let editingAreas = listView.km_EditingAreas()
        let editMode = KMNEditContentPopMode(currentEditAreas: editingAreas)
        let popWindow = KMNPopContentEditWindowController.shared
        if editMode.popType == .editNone {
            closePopContentEditWindow()
        } else {
            listView.window?.addChildWindow(popWindow.window ?? NSWindow(), ordered: .above)
            
            popWindow.listView = listView
            popWindow.editContentPopMode = editMode
            popWindow.isOpenPane = viewManager.showRightSide
            updateContentEditPopWinodwFrame()
            
            popWindow.paneCallback = {[weak self] isOpen in
                if isOpen == true && self?.viewManager.showRightSide == false {
                    self?.toggleCloseRightSide()
                } else {
                    self?.toggleOpenRightSide()
                }
            }
        }
    }
    
    func updateAnnotationsPopWinodwFrame() {
        let popWindow = KMNPopAnnotationWindowController.shared
        if popWindow.window?.isVisible == true {
            popWindow.updateFrame(listView: listView)
        }
    }
    
    func updateContentEditPopWinodwFrame() {
        let popWindow = KMNPopContentEditWindowController.shared
        if popWindow.window?.isVisible == true {
            popWindow.updateFrame(listView: listView)
        }
    }
    
    func updatePopOperationPopWinodwFrame() {
        let popWindow = KMNPopOperationWindowController.shared
        if popWindow.window?.isVisible == true {
            popWindow.updateFrame(listView: listView,page: listView.currentSelectionPage())
        }
    }
    
    //MARK: - 安全
    func removeOwnerPassword() {
        guard let doc = listView.document else {
            NSSound.beep()
            return
        }
        if doc.permissionsStatus != .user {
            NSSound.beep()
            return
        }
        _ = KMPasswordInputWindow.openWindow(window: self.view.window!, type: .owner, url: doc.documentURL) { [weak self] result, password in
            if result == .cancel { /// 关闭
                return
            }
            self?.listView.document?.unlock(withPassword: password)
            
            if doc.permissionsStatus == .owner {
                self?.alertTipViewController.reloadSecureAlertUI()
                self?.alertTipViewController.reloadAlertUIFrame()
            }
        }
    }

    //MARK: - Background背景
    func showBackgroundController() {
        
        viewManager.editType = .background
        
        showEditToolbarView()
        editToolbarView?.editType = .background
        if KMBackgroundManager.defaultManager.datas.count == 0 {
            editToolbarView?.editSubType = .add
        } else {
            editToolbarView?.editSubType = .template
        }
        editToolbarView?.reloadData()
        
        if backgroundViewController == nil {
            backgroundViewController = KMBackgroundController.init()
        }
        backgroundViewController?.view.frame = CGRectMake(44, 0, CGRectGetWidth(bottomContendBox.frame)-44, CGRectGetHeight(bottomContendBox.frame))
        backgroundViewController?.view.autoresizingMask = [.maxXMargin, .width, .height]
        backgroundViewController?.delegate = self
        bottomContendBox.contentView?.addSubview(backgroundViewController!.view)
        backgroundViewController?.editSubType = editToolbarView?.editSubType ?? .template
        backgroundViewController?.resetUI()
        
        updateBackgroundDocument()
    }
    
    func updateBackgroundDocument() {
        guard let controller = backgroundViewController else { return }
        
        controller.pdfDocument = nil
        
        let editDocument = CPDFDocument.init()
        
        let page = listView.document.page(at: UInt(listView.currentPageIndex))
        editDocument?.insertPageObject(page, at: 0)
        
        backgroundViewController?.pdfDocument = editDocument
        backgroundViewController?.reloadData()
        
    }
    
    func removePDFBackground() {
        let alert = NSAlert()
        alert.alertStyle = .warning
        alert.messageText = NSLocalizedString("Are you sure you want to remove the background?", comment: "")
        alert.addButton(withTitle: NSLocalizedString("Delete", comment: ""))
        alert.addButton(withTitle: NSLocalizedString("Cancel", comment: ""))
        let result = alert.runModal()
        if (result == .alertFirstButtonReturn) {
            let background = listView.document.background()
            background?.clear()
            
            listView.document?.refreshPageData()
            listView.layoutDocumentView()
            
            _ = KMNCustomAlertView.alertView(message: KMLocalizedString("Background removed"),
                                             type: .success,
                                             fromView: bottomContendBox,
                                             point:CGPointMake(CGRectGetWidth(bottomContendBox.frame)/2, CGRectGetHeight(bottomContendBox.frame)-28))
            
        }
    }
    
    func batchAddBackground() {
        
    }
    
    func batchRemoveBackground() {
        
    }
    
    //MARK: - header&footer
    func showHeaderFooterController() {
        
        viewManager.editType = .header_Footer
        
        showEditToolbarView()
        editToolbarView?.editType = .header_Footer
        if KMHeaderFooterManager.defaultManager.headFooterObjects.count == 0 {
            editToolbarView?.editSubType = .add
        } else {
            editToolbarView?.editSubType = .template
        }
        editToolbarView?.reloadData()
        
        if headerFooterViewController == nil {
            headerFooterViewController = KMHeaderFooterController.init()
        }
        headerFooterViewController?.view.frame = CGRectMake(44, 0, CGRectGetWidth(bottomContendBox.frame)-44, CGRectGetHeight(bottomContendBox.frame))
        headerFooterViewController?.view.autoresizingMask = [.maxXMargin, .width, .height]
        headerFooterViewController?.totalPDFCount = Int(listView.document.pageCount)
        headerFooterViewController?.delegate = self
        bottomContendBox.contentView?.addSubview(headerFooterViewController!.view)
        headerFooterViewController?.editSubType = editToolbarView?.editSubType ?? .template
        
        updateHeaderFooterDocument()
    }
    
    func updateHeaderFooterDocument() {
        guard let controller = headerFooterViewController else { return }
        controller.pdfDocument = nil
        
        let editDocument = CPDFDocument.init()
        let page = listView.document.page(at: UInt(listView.currentPageIndex))
        editDocument?.insertPageObject(page, at: 0)
        
        headerFooterViewController?.totalPDFCount = Int(listView.document.pageCount)
        headerFooterViewController?.pdfDocument = editDocument
        headerFooterViewController?.resetUI()
        headerFooterViewController?.reloadData()
        
    }
    
    func removeHeaderFooter() {
        
        let alert = NSAlert()
        alert.alertStyle = .warning
        alert.messageText = NSLocalizedString("Are you sure you want to remove the Header & Footer?", comment: "")
        alert.addButton(withTitle: NSLocalizedString("Delete", comment: ""))
        alert.addButton(withTitle: NSLocalizedString("Cancel", comment: ""))
        let result = alert.runModal()
        if (result == .alertFirstButtonReturn) {
            let headerFooter = listView.document.headerFooter()
            headerFooter?.clear()
            
            listView.document?.refreshPageData()
            listView.layoutDocumentView()
            
            _ = KMNCustomAlertView.alertView(message: KMLocalizedString("Header & Footer removed"),
                                             type: .success,
                                             fromView: bottomContendBox,
                                             point:CGPointMake(CGRectGetWidth(bottomContendBox.frame)/2, CGRectGetHeight(bottomContendBox.frame)-28))
            
        }
        
    }
    
    func batchAddHeaderFooter() {
        
    }
    
    func batchRemoveHeaderFooter() {
        
    }
    
    //MARK: - Bates
    func showBatesController() {
        
        viewManager.editType = .bates
        
        showEditToolbarView()
        editToolbarView?.editType = viewManager.editType
        if KMBatesManager.defaultManager.datas.count == 0 {
            editToolbarView?.editSubType = .add
        } else {
            editToolbarView?.editSubType = .template
        }
        editToolbarView?.reloadData()
        
        if batesViewController == nil {
            batesViewController = KMBatesController.init()
        }
        batesViewController?.view.frame = CGRectMake(44, 0, CGRectGetWidth(bottomContendBox.frame)-44, CGRectGetHeight(bottomContendBox.frame))
        batesViewController?.view.autoresizingMask = [.maxXMargin, .width, .height]
        batesViewController?.delegate = self
        batesViewController?.totalPDFCount = Int(listView.document.pageCount)
        bottomContendBox.contentView?.addSubview(batesViewController!.view)
        batesViewController?.editSubType = editToolbarView?.editSubType ?? .template
        
        updateBatesDocument()
        
        batesViewController?.resetUI()
    }
    
    func updateBatesDocument() {
        guard let controller = batesViewController else { return }
        
        controller.pdfDocument = nil
        
        let editDocument = CPDFDocument.init()
        
        let page = listView.document.page(at: UInt(listView.currentPageIndex))
        editDocument?.insertPageObject(page, at: 0)
        
        batesViewController?.pdfDocument = editDocument
        batesViewController?.reloadData()
        
    }
    
    func removePDFBates() {
        let alert = NSAlert()
        alert.alertStyle = .warning
        alert.messageText = NSLocalizedString("Are you sure you want to remove the Bates?", comment: "")
        alert.addButton(withTitle: NSLocalizedString("Delete", comment: ""))
        alert.addButton(withTitle: NSLocalizedString("Cancel", comment: ""))
        let result = alert.runModal()
        if (result == .alertFirstButtonReturn) {
            let bates = listView.document.bates()
            bates?.clear()
            
            listView.document?.refreshPageData()
            listView.layoutDocumentView()
            
            _ = KMNCustomAlertView.alertView(message: KMLocalizedString("Bates removed"),
                                             type: .success,
                                             fromView: bottomContendBox,
                                             point:CGPointMake(CGRectGetWidth(bottomContendBox.frame)/2, CGRectGetHeight(bottomContendBox.frame)-28))
            
        }
        
    }
    
    func batchAddBates() {
        
    }
    
    func batchRemoveBates() {
        
    }
    
    //MARK: - Crop Action
    
    // 白边距,统一大小
    @objc func auto_cropPagesWhiteMargin(_ pageIndexs: [UInt]) {
        var size = NSZeroSize
        for i in pageIndexs {
            let page = self.listView.document.page(at: i)
            let rect = KMCropTools.getPageForegroundBox(page!)
            size.width = fmax(size.width, NSWidth(rect))
            size.height = fmax(size.height, NSHeight(rect))
        }
        
        var rectArray: Array<NSRect> = []
        for i in pageIndexs {
            progressC?.increment(by: Double(i))
            progressC?.doubleValue = Double(i)
            let page = self.listView.document.page(at: i)
            var rect = KMCropTools.getPageForegroundBox(page!)
            let bounds: NSRect = (page?.bounds(for: .mediaBox))!
            if (rect.minX - bounds.minX > bounds.maxX-rect.maxX) {
                rect.origin.x = rect.maxX-size.width
            }
            
            rect.origin.y = rect.maxY-size.height
            rect.size = size
            
            if (NSWidth(rect) > NSWidth(bounds)) {
                rect.size.width = NSWidth(bounds)
            }
            if (NSHeight(rect) > NSHeight(bounds)) {
                rect.size.height = NSHeight(bounds)
            }
            
            if (NSMinX(rect) < NSMinX(bounds)) {
                rect.origin.x = NSMinX(bounds)
            } else if (NSMaxX(rect) > NSMaxX(bounds)) {
                rect.origin.x = NSMaxX(bounds) - NSWidth(rect)
            }
            
            if (NSMinY(rect) < NSMinY(bounds)) {
                rect.origin.y = NSMinY(bounds)
            } else if (NSMaxY(rect) > NSMaxY(bounds)) {
                rect.origin.y = NSMaxY(bounds) - NSHeight(rect)
            }
            
            rectArray.append(rect)
        }
        self.cropPages(atIndexs: pageIndexs, to: rectArray)
        
    }
    
    func cropPages(atIndexs pageIndexs: [UInt], to rects: Array<NSRect>) {
        let currentPage = self.listView.currentPage()
        let visibleRect: NSRect = self.listView.convert(self.listView.convert(self.listView.documentView().visibleRect, from: self.listView.documentView()), to: self.listView.currentPage())
        
        var oldRectArray: Array<NSRect> = []
        let rectCount = rects.count
        for i in pageIndexs {
            if let page = self.listView.document.page(at: i) {
                let rect = NSIntersectionRect(rects[Int(i) % rectCount], (page.bounds(for: .mediaBox)))
                let oldRect = page.bounds(for: .cropBox)
                oldRectArray.append(oldRect)
                
                page.setBounds(rect, for: .cropBox)
            }
        }
        
        let undoManager = self.listView.undoManager
        (undoManager?.prepare(withInvocationTarget: self) as AnyObject).cropPages(atIndexs: pageIndexs, to: oldRectArray)
        
        /// 刷新预览视图
        self.listView.layoutDocumentView()
        
        self.listView.displayBox = .cropBox
        
        self.listView.go(to: currentPage)
        self.listView.go(to: visibleRect, on: currentPage)
        
    }
    
    //MARK: - TTS
    @IBAction func startSpeaking(_ sender: Any) {
        self.showTTSWindow()
        let ttsView = KMTTSWindowController.share
        ttsView.buttonItemClick_Play(ttsView.playButton)
    }
    
    @IBAction func stopSpeaking(_ sender: Any) {
        let ttsWindowC = KMTTSWindowController.share
        if ttsWindowC.pdfView?.document?.documentURL.path == self.listView.document?.documentURL.path {
            if let data = ttsWindowC.window?.isVisible, data {
                ttsWindowC.stopSpeaking()
                ttsWindowC.close()
            }
        }
    }
    
    func showTTSWindow() {
        var lastPDFView: CPDFView?
        let ttsView = KMTTSWindowController.share
        if (ttsView.window?.isVisible ?? false) {
            lastPDFView = ttsView.pdfView
            if lastPDFView?.document?.documentURL?.path == self.listView.document?.documentURL?.path {
                lastPDFView = nil
                ttsView.window?.orderOut(nil)
            } else {
                ttsView.pdfView = self.listView
                ttsView.showWindow(nil)
            }
        } else {
            ttsView.pdfView = self.listView
            ttsView.showWindow(nil)
        }
        ttsView.closeWindowCallback = { (isCloseWindow: Bool) in
            if isCloseWindow {
                
            }
        }
        
        if let currentSelection = self.listView.currentSelection {
            if let data = currentSelection.selectionsByLine, data.isEmpty == false {
                ttsView.startSpeakingPDFSelection(currentSelection)
            }
        }
        if let lastPDFView = lastPDFView {
            lastPDFView.setHighlightedSelections([])
            ttsView.stopSpeaking()
        }
    }
    
    //MARK: 导出图片
    func extractImageAction(num: Int) {
        if !IAPProductsManager.default().isAvailableAllFunction(){
            let winC = KMPurchaseCompareWindowController.sharedInstance()
            winC?.kEventName = "Reading_ExtractImage_BuyNow"
            winC?.showWindow(nil)
            return
        }
        
        if !(self.listView.document.allowsPrinting || self.listView.document.allowsCopying) {
            let alert = NSAlert()
            alert.alertStyle = .critical
            alert.messageText = NSLocalizedString("This is a secured document. Editing is not permitted.", comment: "")
            alert.runModal()
            return
        }
        
        let document = self.listView.document
        var fileURL = document?.documentURL
        
        if num == 1 {
            let pageCount = document?.pageCount ?? 0
            let indeSet = NSMutableIndexSet()
            
            indeSet.add(in: NSRange(location: 0, length: Int(pageCount)))
            if indeSet.count == 0 {
                return
            }
            let lastPathName = fileURL?.deletingPathExtension().lastPathComponent ?? ""
            let tFileName = (String(format: "%@_Extract Images", lastPathName))
            let outputSavePanel = NSSavePanel()
            outputSavePanel.title = NSLocalizedString("Save as PDF", comment: "")
            outputSavePanel.allowsOtherFileTypes = true
            outputSavePanel.isExtensionHidden = true
            outputSavePanel.canCreateDirectories = true
            outputSavePanel.nameFieldStringValue = tFileName
            outputSavePanel.beginSheetModal(for: self.view.window!, completionHandler: { (result) in
                if result == NSApplication.ModalResponse.OK {
                    DispatchQueue.main.async {
                        self.beginProgressSheet(withMessage: NSLocalizedString("Extracting all pictures...", comment: "") + "...", maxValue: 0)
                        let tDestFile = outputSavePanel.url!.path
                        let uniquePath = KMExtractImageWindowController.createDestFolder(path: tDestFile, isUnique: false)
                        let pdfconverter = PDFConvertObject()
                        pdfconverter.extractResourcesFromPDF(at: fileURL?.path ?? "", pdfPassword: document?.password, selectIndexSet: indeSet as IndexSet, destDocPath: uniquePath, moreOptions: nil)
                        self.dismissProgressSheet()
                        let fileManager = FileManager.default
                        if fileManager.fileExists(atPath: tDestFile) {
                            let workspace = NSWorkspace.shared
                            let url = URL(fileURLWithPath: tDestFile)
                            workspace.activateFileViewerSelecting([url])
                        }
                    }
                }
            })
            return
        }
        
        if fileURL != nil {
            self.myDocument?.save(nil)
        } else {
            let myDocument = self.myDocument
            let str = String(format: "%@.pdf", myDocument?.displayName ?? "")
            let writeSuccess = document!.write(to: URL(fileURLWithPath: (kTempSavePath?.stringByAppendingPathComponent(str))!))
            if writeSuccess {
                var documentTemp = CPDFDocument(url: URL(fileURLWithPath: (kTempSavePath?.stringByAppendingPathComponent(str))!))
                fileURL = document?.documentURL
            } else {
                NSSound.beep()
                return
            }
        }
        extract = KMExtractImageWindowController(windowNibName: "KMExtractImageWindowController")
        extract?.docPath = fileURL?.path ?? ""
        extract?.password = document?.password ?? ""
        extract?.currentPage = self.listView.currentPageIndex
        self.km_beginSheet(windowC: extract!)
        extract?.selectCurrentPageBtn()
    }
    
    func beginProgressSheet(withMessage message: String, maxValue: UInt) {
        
        let progress = SKProgressController()
        progress.window?.backgroundColor = NSColor.km_init(hex: "#36383B")
        progress.window?.contentView?.wantsLayer = true
        progress.window?.contentView?.layer?.backgroundColor = NSColor.km_init(hex: "#36383B").cgColor
        progress.progressField.textColor = NSColor.white
        progress.message = NSLocalizedString("Converting...", comment: "")
        progressC = progress
        progressC?.message = message
        if maxValue > 0 {
            progressC?.indeterminate = false
            progressC?.maxValue = Double(maxValue)
            progressC?.progressBar.doubleValue = 0.3
        } else {
            progressC?.indeterminate = true
        }
        self.view.km_beginSheet(windowC: progressC!)
    }
    
    func dismissProgressSheet() {
        progressC?.stopAnimation()
        self.view.km_endSheet()
        progressC = nil
    }
    
    func converFilesToPath(files: Array<KMBatchOperateFile>) -> [String] {
        let newArr = NSMutableArray()
        for item in files {
            newArr.add(item.filePath)
        }
        return newArr as! [String]
    }
    
    internal func showPrintWindow(pageRange: KMPrintPageRange = KMPrintPageRange(type: .allPage, selectPages: [])) {
        self.saveDocument()
        if (self.listView.document != nil && !self.listView.document.allowsPrinting) { // 有打印限制
            KMPasswordInputWindow.openWindow(window: self.view.window!, type: .owner,  url: self.listView.document.documentURL) { [weak self] result ,password in
                if (result == .cancel) {
                    return
                }
                // 解除权限
                self?.listView.document.unlock(withPassword: password)
                // 隐藏提示
                self?.hiddenSecureLimitTip()
                // 去打印
                KMPrintWindowController.openDocument(inputDocument: self?.listView.document, inputPageRange: pageRange)
            }
            return
        }
        KMPrintWindowController.openDocument(inputDocument: self.listView.document, inputPageRange: pageRange)
    }
    //MARK: - Share Action
    @objc private func shareDocument(sender: NSView) {
        let document = self.listView.document ?? CPDFDocument()
        if  document?.documentURL == nil {
            return
        }
        var doucumentURL : URL = self.listView.document.documentURL
        if doucumentURL.path.count > 0 {
            let docDir = NSTemporaryDirectory()
            let documentName : String = doucumentURL.path.lastPathComponent
            let path = docDir.stringByAppendingPathComponent(documentName)
            let writeSuccess = self.listView.document.write(to: URL(fileURLWithPath: path))
            if writeSuccess == false {
                __NSBeep()
                return;
            }
            doucumentURL = URL(fileURLWithPath: path)
        }
        let array = [doucumentURL]
        let picker = NSSharingServicePicker.init(items: array)
        if sender.window != nil {
            picker.show(relativeTo: sender.bounds, of: sender, preferredEdge: NSRectEdge.minY)
        } else {
            picker.show(relativeTo: NSRect(x: (self.view.window?.contentView?.frame.size.width)!, y: (self.view.window?.contentView?.frame.size.height ?? 0)-8, width: 0, height: 0), of: self.view.window?.contentView ?? NSView(), preferredEdge: NSRectEdge.minY)
        }
    }
    
    @objc private func shareFlatten(sender: NSView) {
        let document = self.listView.document ?? CPDFDocument()
        var path: String?
        if  document?.documentURL != nil {
            path = document?.documentURL.path ?? ""
        }
        if path?.count ?? 0 > 0 {
            let docDir = NSTemporaryDirectory()
            let documentName : String = path?.lastPathComponent ?? ""
            path = docDir.stringByAppendingPathComponent(documentName)
        }
        let pathFolder = path?.fileURL.deletingLastPathComponent().path
        var tfileName = path?.deletingPathExtension.lastPathComponent
        let tStdFileSuffix = "_flatten"
        tfileName = (tfileName ?? "") + tStdFileSuffix + ".pdf"
        path = (pathFolder ?? "") + "/" + (tfileName ?? "")
        let success : Bool = document?.writeFlatten(to: URL(fileURLWithPath: path ?? "")) ?? false
        if success {
            let url = URL(fileURLWithPath: path ?? "")
            let picker = NSSharingServicePicker.init(items: [url])
            if sender.window != nil {
                picker.show(relativeTo: sender.bounds, of: sender, preferredEdge: NSRectEdge.minY)
            } else {
                picker.show(relativeTo: NSRect(x: (self.view.window?.contentView?.frame.size.width)!, y: (self.view.window?.contentView?.frame.size.height ?? 0)-8, width: 0, height: 0), of: self.view.window?.contentView ?? NSView(), preferredEdge: NSRectEdge.minY)
            }
        }
    }
    
    @objc private func shareOriginalPDF(sender: NSView) {
        guard let pdfDoc = self.listView.document else {
            NSSound.beep()
            return
        }
        if !pdfDoc.allowsCopying || !pdfDoc.allowsPrinting {
            let alert = NSAlert()
            alert.alertStyle = .critical
            alert.messageText = NSLocalizedString("This is a secured document. Editing is not permitted.", comment: "")
            alert.runModal()
            return
        }
        
        let document = self.listView.document ?? CPDFDocument()
        var path: String?
        if  document?.documentURL != nil {
            path = document?.documentURL.path ?? ""
        }
        if path?.count ?? 0 > 0 {
            let docDir = NSTemporaryDirectory()
            let documentName : String = path?.lastPathComponent ?? ""
            path = docDir.stringByAppendingPathComponent(documentName)
        }
        var writeSuccess = document?.write(to: URL(fileURLWithPath: path ?? ""))
        if writeSuccess == false {
            __NSBeep()
            return;
        }
        let newDocument = CPDFDocument(url: URL(fileURLWithPath: path ?? ""))
        
        let cnt = newDocument?.pageCount ?? 0
        for i in 0 ..< cnt {
            let page = newDocument!.page(at: i)
            var annotations : [CPDFAnnotation] = []
            for annotation in page!.annotations {
                annotations.append(annotation)
            }
            for annotation in annotations {
                annotation.page.removeAnnotation(annotation)
            }
        }
        writeSuccess = newDocument?.write(to:URL(fileURLWithPath: path ?? ""))
        if writeSuccess ?? false {
            let url = URL(fileURLWithPath: path ?? "")
            let picker = NSSharingServicePicker.init(items: [url])
            if sender.window != nil {
                picker.show(relativeTo: sender.bounds, of: sender, preferredEdge: NSRectEdge.minY)
            } else {
                picker.show(relativeTo: NSRect(x: (self.view.window?.contentView?.frame.size.width)!, y: (self.view.window?.contentView?.frame.size.height ?? 0)-8, width: 0, height: 0), of: self.view.window?.contentView ?? NSView(), preferredEdge: NSRectEdge.minY)
            }
        }
    }
    
    @objc func shareFromService(sender: NSMenuItem) {
        if ((NSApp.mainWindow?.windowController is KMBrowserWindowController) == false) {
            return
        }
        
        var string = ""
        if let freeTextAnnotation = listView.activeAnnotation as? CPDFFreeTextAnnotation {
            string = freeTextAnnotation.contents ?? ""
        } else if let markupAnnotation = listView.activeAnnotation as? CPDFMarkupAnnotation {
            if let page = markupAnnotation.page {
                if let selection = page.selection(for: markupAnnotation.bounds) {
                    string = selection.string() ?? ""
                }
            }
        } else {
            string = listView.currentSelection?.string() ?? ""
        }
        
        let windowControler = NSApp.mainWindow?.windowController as! KMBrowserWindowController
        let model = windowControler.browser?.tabStripModel
        if let cnt = model?.count(), cnt <= 0 {
            return
        }
        
        if let data = model?.activeTabContents().isHome, data {
            return
        }
        
        let document: KMMainDocument = model?.activeTabContents() as! KMMainDocument
        if string.count > 0 {
            let represent : NSSharingService = sender.representedObject as! NSSharingService
            represent.perform(withItems: [string])
            return
        }
        
        let represent = sender.representedObject as? NSSharingService
        represent?.perform(withItems: [string])
    }
    
    // 搜索 & 替换
    
    func showSearchPopWindow(type: KMNBotaSearchType, keyborad: String?, replaceText: String?, results: [KMSearchMode]) {
        let toolMode = self.listView.toolMode
        let isEditing = self.listView.isEditing()
        
        var winH: CGFloat = 112
        if type == .replace {
            if IAPProductsManager.default().isAvailableAllFunction() == false {
                let winC = KMPurchaseCompareWindowController.sharedInstance()
                winC?.kEventName = "Reading_ReplaceText_BuyNow"
                winC?.showWindow(nil)
                return
            }
            
            if toolMode == .CEditPDFToolMode && isEditing {
                
            } else { // 进入内容编辑模式
                viewManager.toolMode = .Edit
                updatePDFViewAnnotationMode()
            }
            winH = 208
        }
        
        self.view.window?.makeFirstResponder(nil)
        let winC = KMSearchReplaceWindowController(with: listView, type: type)
        self.currentWindowController = winC
        
        winC.replaceCallback = { [weak self] in
            let toolMode = self?.listView.toolMode ?? .none
            let isEditing = self?.listView.isEditing() ?? false
            if toolMode == .CEditPDFToolMode &&  isEditing {
                
            } else { // 进入内容编辑模式
                self?.viewManager.toolMode = .Edit
                self?.updatePDFViewAnnotationMode()
            }
        }
        winC.itemClick = { [weak self] idx, params in
            if idx == 1 {
                self?.toggleOpenLeftSide(pdfSideBarType: .search)
                
                guard let handdler = params.first as? KMNSearchHanddler else {
                    return
                }
                let viewC = self?.botaViewController?.searchViewC
                viewC?.update(keyborad: handdler.searchKey, replaceKey: handdler.replaceKey, results: handdler.searchSectionResults)
            }
        }
        let targetView = self.pdfToolbarController?.leftViewButton
        let point = targetView?.convert(targetView?.frame.origin ?? .zero, to: nil) ?? .zero
        // 200 248
        let x = point.x + (self.view.window?.frame.origin.x ?? 0) - 32
        let y = point.y + (self.view.window?.frame.origin.y ?? 0) - winH - 32
        
        let winFramePoint = NSPoint(x: x, y: y)
        winC.window?.setFrameOrigin(winFramePoint)
        
        winC.update(keyborad: keyborad, replaceKey: replaceText, results: results)
        self.view.window?.addChildWindow(winC.window!, ordered: .above)
    }
    
}

//MARK: Compress
extension KMMainViewController {
    func showCompressController(_ url: URL) {
        self.compressWindowController = KMCompressWindowController(windowNibName: "KMCompressWindowController")
        self.compressWindowController?.password = self.listView.document?.password ?? ""
        self.compressWindowController?.documentURL = url
        self.view.window?.beginSheet(self.compressWindowController!.window!)
        
        self.compressWindowController?.itemClick = { [unowned self] in
            self.view.window?.endSheet((self.compressWindowController?.window)!)
            
        }
        
        self.compressWindowController?.batchAction = { [unowned self] view, filePaths in
            self.view.window?.endSheet((self.compressWindowController?.window)!)
            self.showBatchCompressController(filePaths)
        }
        
        self.compressWindowController?.resultCallback = { [unowned self] result, openDocument, fileURL, error in
            self.view.window?.endSheet((self.compressWindowController?.window)!)
            if (result) {
                
                if (openDocument) {
                    NSDocumentController.shared.openDocument(withContentsOf: fileURL, display: true) { document, result, error in }
                } else {
                    NSWorkspace.shared.activateFileViewerSelecting([fileURL])
                }
            } else {
                let alert = NSAlert()
                alert.messageText = NSLocalizedString("Compress Faild", comment: "")
                alert.runModal()
            }
        }
    }
    
    func showBatchCompressController(_ filePaths: [URL]) {
        let batchWindowController = KMBatchOperateWindowController.sharedWindowController
        let batchOperateFile = KMBatchOperateFile(filePath: filePaths.first!.path, type: .Compress)
        batchWindowController.switchToOperateType(KMBatchOperationType.Compress, files: [batchOperateFile])
        batchWindowController.window?.makeKeyAndOrderFront("")
    }
}

//MARK: - NSSplitViewDelegate
extension KMMainViewController: NSSplitViewDelegate {
    
    func splitView(_ splitView: NSSplitView, canCollapseSubview subview: NSView) -> Bool {
        if splitView == infoContendSplitView {
            return subview.isEqual(to: infoSplitCenterView) == false
        }
        return false
    }
    
    func splitView(_ splitView: NSSplitView, shouldCollapseSubview subview: NSView, forDoubleClickOnDividerAt dividerIndex: Int) -> Bool {
        if splitView == infoContendSplitView {
            if(subview.isEqual(to: infoSplitLeftView)) {
                
            } else if(subview.isEqual(to: infoSplitRightView)) {
                
            }
        }
        return false
    }
    
    func splitView(_ splitView: NSSplitView, shouldHideDividerAt dividerIndex: Int) -> Bool {
        if splitView == infoContendSplitView {
            return splitView == infoContendSplitView
        } else if splitView == pdfSplitView {
            return splitView == pdfSplitView
        }
        return false
    }
    
    func splitView(_ splitView: NSSplitView, constrainMaxCoordinate proposedMaximumPosition: CGFloat, ofSubviewAt dividerIndex: Int) -> CGFloat {
        if(splitView == infoContendSplitView && dividerIndex == 1) {
            return proposedMaximumPosition - MIN_SIDE_PANE_WIDTH.doubleValue
        }
        return proposedMaximumPosition
    }
    
    func splitView(_ splitView: NSSplitView, constrainMinCoordinate proposedMinimumPosition: CGFloat, ofSubviewAt dividerIndex: Int) -> CGFloat {
        if(splitView == infoContendSplitView && dividerIndex == 0) {
            return proposedMinimumPosition + MIN_SIDE_PANE_WIDTH.doubleValue
        }
        return proposedMinimumPosition
    }
    
    func splitViewDidResizeSubviews(_ notification: Notification) {
        let splitView = notification.object as? NSSplitView
        if(splitView == infoContendSplitView) {
            leftSplitViewResizeFinish()
            
            if(newMwcFlags.settingUpWindow == false && self.view.window?.frameAutosaveName != nil) {
                let leftWidth = infoContendSplitView.isSubviewCollapsed(infoSplitLeftView) ? 0.0 : infoSplitLeftView.frame.width
                UserDefaults.standard.set(leftWidth, forKey: CPDFViewLeftSidePaneWidthKey)
                UserDefaults.standard.synchronize()
            }
            if listView.isEditing() == false {
                updateAnnotationsPopWinodwFrame()
            } else {
                updateContentEditPopWinodwFrame()
            }
        }
        
        NSObject.cancelPreviousPerformRequests(withTarget: self, selector: #selector(splitViewResizeFinish), object: nil)
        self.perform(#selector(splitViewResizeFinish), with: nil, afterDelay: 0.15)
    }
    
    @objc func leftSplitViewResizeFinish() {
        botaViewController?.changeLeftSideBounds()
    }
    
    @objc func splitViewResizeFinish() {
        if infoContendSplitView.isSubviewCollapsed(infoSplitLeftView) {
            if viewManager.pdfSideBarType != .none {
                viewManager.pdfSideBarType = .none
                
                sideBarController?.reloadBOTAData()
            }
        }
    }
    
}

//MARK: - KMPDFSideBarControllerDelegate 左侧Sidebar代理
extension KMMainViewController: KMPDFSideBarControllerDelegate {
    func kmPDFSideBarControllerDidSidebarTypeUpdated(_ view: KMPDFSideBarController) {
        if viewManager.pdfSideBarType == .none {
            toggleCloseLeftSide()
        } else {
            toggleOpenLeftSide(pdfSideBarType: viewManager.pdfSideBarType)
        }
    }
    
    func kmPDFSideBarControllerDidGotoPage(_ view: KMPDFSideBarController, _ pageIndex: Int) {
        listView.go(toPageIndex: pageIndex, animated: true)
        
    }
    
}

//MARK: - KMPDFToolbarControllerDelegate 工具栏代理
extension KMMainViewController: KMPDFToolbarControllerDelegate {
    
    //MARK: -ViewTools发生变化时调用
    func kmPDFToolbarControllerDidViewToolsChanged(_ controller: KMPDFToolbarController) {
        let viewToolsType = viewManager.viewToolsType
        
        if viewToolsType == .Select {
            listView.toolMode = .CNoteToolMode
        } else if viewToolsType == .Scroll {
            listView.toolMode = .CMoveToolMode
        } else if viewToolsType == .Content_Selection {
            listView.toolMode = .CSelectToolMode
        } else if viewToolsType == .Magnify {
            listView.toolMode = .CMagnifyToolMode
        } else if viewToolsType == .AreaZoom {
            listView.toolMode = .CSelectZoomToolMode
        }
        
        refreshToolbarViewHeightInfo()
        
    }
    
    //MARK: -一级工具栏状态发生变化时调用
    func kmPDFToolbarControllerDidToolModeChanged(_ controller: KMPDFToolbarController) {
        refreshToolbarViewHeightInfo()
        
        toolbarViewModeChanged()
    }
    
    //MARK: -点击工具栏按钮
    func kmPDFToolbarControllerDidToolbarItemClicked(_ controller: KMPDFToolbarController, _ itemIdentifier: String) {
        
        print("toolbar点击", itemIdentifier)
       
        if toolbarManager.getSubToolItemIdentifys(KMPDFToolbar_PageEdit_Identifier).contains(itemIdentifier) {
            //MARK: -页面编辑
            if itemIdentifier == KMPDFToolbar_PageEdit_InsertFile_Identifier {
                pageEditViewController?.insertFromPDFAction()
            } else if itemIdentifier == KMPDFToolbar_PageEdit_InsertBlank_Identifier {
                pageEditViewController?.insertFromBlankAction()
            } else if itemIdentifier == KMPDFToolbar_PageEdit_InsertClip_Identifier {
                pageEditViewController?.insertFromClipboardAction()
            } else if itemIdentifier == KMPDFToolbar_PageEdit_InsertScanner_Identifier {
                pageEditViewController?.insertFromScannerAction()
            } else if itemIdentifier == KMPDFToolbar_PageEdit_Extract_Identifier {
                pageEditViewController?.extractPDFAction()
            } else if itemIdentifier == KMPDFToolbar_PageEdit_Replace_Identifier {
                pageEditViewController?.replacePDFAction()
            } else if itemIdentifier == KMPDFToolbar_PageEdit_Split_Identifier {
                pageEditViewController?.splitPDFAction()
            } else if itemIdentifier == KMPDFToolbar_PageEdit_Reverse_Identifier {
                pageEditViewController?.reversePDFAction()
            } else if itemIdentifier == KMPDFToolbar_PageEdit_LeftRotate_Identifier {
                pageEditViewController?.rotatePageLeftAction()
            } else if itemIdentifier == KMPDFToolbar_PageEdit_RightRotate_Identifier{
                pageEditViewController?.rotatePageRightAction()
            } else if itemIdentifier == KMPDFToolbar_PageEdit_Delete_Identifier {
                pageEditViewController?.deletePageAction()
            } else if itemIdentifier == KMPDFToolbar_PageEdit_Reduce_Identifier {
                pageEditViewController?.zoomOutPageAction()
                if(pageEditViewController?.canZoomInPageSize() == false) {
                    toolbarManager.page_Increase_Property.isDisabled = true
                } else {
                    toolbarManager.page_Increase_Property.isDisabled = false
                }
                if(pageEditViewController?.canZoomOutPageSize() == false) {
                    toolbarManager.page_Reduce_Property.isDisabled = true
                } else {
                    toolbarManager.page_Reduce_Property.isDisabled = false
                }
                controller.refreshSecondToolbarItemsState()
            } else if itemIdentifier == KMPDFToolbar_PageEdit_Increase_Identifier {
                pageEditViewController?.zoomInPageAction()
                
                if(pageEditViewController?.canZoomInPageSize() == false) {
                    toolbarManager.page_Increase_Property.isDisabled = true
                } else {
                    toolbarManager.page_Increase_Property.isDisabled = false
                }
                if(pageEditViewController?.canZoomOutPageSize() == false) {
                    toolbarManager.page_Reduce_Property.isDisabled = true
                } else {
                    toolbarManager.page_Reduce_Property.isDisabled = false
                }
                controller.refreshSecondToolbarItemsState()
            } else if itemIdentifier == KMPDFToolbar_PageEdit_page_oddPage_Identifier {
                pageEditViewController?.thumbnailChoosePageStyle = .odd
                if(toolbarManager.page_pageInfo_Property.creatable == true) {
                    toolbarManager.page_pageInfo_Property.creatable = false
                    controller.refreshSecondToolbarItemsState()
                }
            } else if itemIdentifier == KMPDFToolbar_PageEdit_page_EvenPage_Identifier {
                pageEditViewController?.thumbnailChoosePageStyle = .even
                if(toolbarManager.page_pageInfo_Property.creatable == true) {
                    toolbarManager.page_pageInfo_Property.creatable = false
                    controller.refreshSecondToolbarItemsState()
                }
            } else if itemIdentifier == KMPDFToolbar_PageEdit_page_PortraitPage_Identifier {
                pageEditViewController?.thumbnailChoosePageStyle = .horizontal
                if(toolbarManager.page_pageInfo_Property.creatable == true) {
                    toolbarManager.page_pageInfo_Property.creatable = false
                    controller.refreshSecondToolbarItemsState()
                }
            } else if itemIdentifier == KMPDFToolbar_PageEdit_page_LandscapePage_Identifier {
                pageEditViewController?.thumbnailChoosePageStyle = .vertical
                if(toolbarManager.page_pageInfo_Property.creatable == true) {
                    toolbarManager.page_pageInfo_Property.creatable = false
                    controller.refreshSecondToolbarItemsState()
                }
            } else if itemIdentifier == KMPDFToolbar_PageEdit_page_AllPage_Identifier {
                pageEditViewController?.thumbnailChoosePageStyle = .allPage
                if(toolbarManager.page_pageInfo_Property.creatable == true) {
                    toolbarManager.page_pageInfo_Property.creatable = false
                    controller.refreshSecondToolbarItemsState()
                }
            } else if itemIdentifier == KMPDFToolbar_PageEdit_page_CustomPage_Identifier {
                pageEditViewController?.thumbnailChoosePageStyle = .custom
                toolbarManager.page_pageInfo_Property.text = nil
                if(toolbarManager.page_pageInfo_Property.creatable == false) {
                    toolbarManager.page_pageInfo_Property.creatable = true
                }
                controller.refreshSecondToolbarItemsState()
            }
        } else if toolbarManager.getSubToolItemIdentifys(KMPDFToolbar_Markup_Identifier).contains(itemIdentifier) {
            //MARK: -Markup
            if itemIdentifier == KMPDFToolbar_eye_Identifier {
                self.showOrHideNotes()
            }
            
            if viewManager.subToolMode == .None {
                viewManager.showRightSide = false
            } else {
                viewManager.showRightSide = true
            }
        } else if toolbarManager.getSubToolItemIdentifys(KMPDFToolbar_Edit_Identifier).contains(itemIdentifier) {
            //MARK: -编辑
            if itemIdentifier == KMPDFToolbar_edit_addWatermark_Identifier {
                showWatermarkController()
            } else if itemIdentifier == KMPDFToolbar_edit_removeWatermark_Identifier {
                removePDFWatermark()
            } else if itemIdentifier == KMPDFToolbar_edit_batch_AddWatermark_Identifier {
                batchAddWatermark()
            } else if itemIdentifier == KMPDFToolbar_edit_batchRemoveWatermark_Identifier {
                batchRemoveWatermark()
            } else if itemIdentifier == KMPDFToolbar_edit_addBG_Identifier {
                showBackgroundController()
            } else if itemIdentifier == KMPDFToolbar_edit_removeBG_Identifier {
                removePDFBackground()
            } else if itemIdentifier == KMPDFToolbar_edit_batch_AddBG_Identifier {
                batchAddBackground()
            } else if itemIdentifier == KMPDFToolbar_edit_batchRemoveBG_Identifier {
                batchRemoveBackground()
            } else if itemIdentifier == KMPDFToolbar_edit_addHF_Identifier {
                showHeaderFooterController()
            } else if itemIdentifier == KMPDFToolbar_edit_removeHF_Identifier {
                removeHeaderFooter()
            } else if itemIdentifier == KMPDFToolbar_edit_batch_AddHF_Identifier {
                batchAddHeaderFooter()
            } else if itemIdentifier == KMPDFToolbar_edit_batchRemoveHF_Identifier {
                batchRemoveHeaderFooter()
            } else if itemIdentifier == KMPDFToolbar_edit_addBates_Identifier {
                showBatesController()
            } else if itemIdentifier == KMPDFToolbar_edit_removeBates_Identifier {
                removePDFBates()
            } else if itemIdentifier == KMPDFToolbar_edit_batch_AddBates_Identifier {
                batchAddBates()
            } else if itemIdentifier == KMPDFToolbar_edit_batchRemoveBates_Identifier {
                batchRemoveBates()
            } else if itemIdentifier == KMPDFToolbar_edit_crop_Identifier {
                showCropController()
            }
        } else if toolbarManager.getSubToolItemIdentifys(KMPDFToolbar_Form_Identifier).contains(itemIdentifier) {
            //MARK: -Form表单
            if itemIdentifier == KMPDFToolbar_form_HighlightFields_Identifier {
                CPDFWidgetAnnotation.updateHighlightFormFiled(listView)
            } else if itemIdentifier == KMPDFToolbar_form_ShowName_Identifier {
                listView.showFormFieldName = !listView.showFormFieldName
                if listView.showFormFieldName {
                    toolbarManager.form_ShowName_Property.righticon = NSImage(named: "tick_Green")
                } else {
                    toolbarManager.form_ShowName_Property.righticon = nil
                }
                listView.setNeedsDisplayForVisiblePages()
            } else if itemIdentifier == KMPDFToolbar_form_ClearForm_Identifier {
                listView.resetFormAnnotation()
            }
        } else if toolbarManager.getSubToolItemIdentifys(KMPDFToolbar_Fill_Identifier).contains(itemIdentifier) {
            //MARK: -填充
            
        } else if toolbarManager.getSubToolItemIdentifys(KMPDFToolbar_Convert_Identifier).contains(itemIdentifier) {
            //MARK: -转档
            if itemIdentifier == KMPDFToolbar_convert_word_Identifier {
                let winC = KMConvertWordWindowController()
                let model = KMDocumentModel(url: listView.document.documentURL)
                winC.documentModel = model
                winC.own_beginSheetModal(for: self.view.window, completionHandler: nil)
            } else if itemIdentifier == KMPDFToolbar_convert_ppt_Identifier {
                let winC = KMConvertPPTsWindowController()
                winC.subType = 1
                let model = KMDocumentModel(url: listView.document.documentURL)
                winC.documentModel = model
                winC.own_beginSheetModal(for: self.view.window, completionHandler: nil)
            } else if itemIdentifier == KMPDFToolbar_convert_RTF_Identifier {
                let winC = KMConvertPPTsWindowController()
                winC.subType = 2
                let model = KMDocumentModel(url: listView.document.documentURL)
                winC.documentModel = model
                winC.own_beginSheetModal(for: self.view.window, completionHandler: nil)
            } else if itemIdentifier == KMPDFToolbar_convert_Text_Identifier {
                let winC = KMConvertPPTsWindowController()
                winC.subType = 4
                let model = KMDocumentModel(url: listView.document.documentURL)
                winC.documentModel = model
                winC.own_beginSheetModal(for: self.view.window, completionHandler: nil)
            } else if itemIdentifier == KMPDFToolbar_convert_CSV_Identifier {
                let winC = KMConvertPPTsWindowController()
                winC.subType = 5
                let model = KMDocumentModel(url: listView.document.documentURL)
                winC.documentModel = model
                winC.own_beginSheetModal(for: self.view.window, completionHandler: nil)
            } else if itemIdentifier == KMPDFToolbar_convert_excel_Identifier {
                let winC = KMConvertExcelWindowController()
                let model = KMDocumentModel(url: listView.document.documentURL)
                winC.documentModel = model
                winC.own_beginSheetModal(for: self.view.window, completionHandler: nil)
            } else if itemIdentifier == KMPDFToolbar_convert_HTML_Identifier {
                let winC = KMConvertHtmlWindowController()
                let model = KMDocumentModel(url: listView.document.documentURL)
                winC.documentModel = model
                winC.own_beginSheetModal(for: self.view.window, completionHandler: nil)
            } else if itemIdentifier == KMPDFToolbar_convert_Json_Identifier {
                let winC = KMConvertJsonWindowController()
                let model = KMDocumentModel(url: listView.document.documentURL)
                winC.documentModel = model
                winC.own_beginSheetModal(for: view.window, completionHandler: nil)
            } else if itemIdentifier == KMPDFToolbar_convert_image_Identifier {
                let winC = KMConvertImageWindowController()
                let model = KMDocumentModel(url: listView.document.documentURL)
                winC.documentModel = model
                winC.own_beginSheetModal(for: view.window, completionHandler: nil)
            } else if itemIdentifier == KMPDFToolbar_convert_imageToPDF_Identifier {
                NSApplication.ShowImageToPDFWindow()
            }
        } else if toolbarManager.getSubToolItemIdentifys(KMPDFToolbar_Protect_Identifier).contains(itemIdentifier) {
            //MARK: -Protect
            if itemIdentifier == KMPDFToolbar_protect_redact_Identifier {
               
            } else if itemIdentifier == KMPDFToolbar_protect_security_Identifier {
                
            } else if itemIdentifier == KMPDFToolbar_protect_removeSecurity_Identifier {
                
            } else if itemIdentifier == KMPDFToolbar_protect_digitalSign_Identifier {
                
            }
        } else if toolbarManager.getSubToolItemIdentifys(KMPDFToolbar_Tools_Identifier).contains(itemIdentifier) {
            //MARK: -工具
            if itemIdentifier == KMPDFToolbar_tools_compress_Identifier {
                self.showCompressController(self.listView.document.documentURL)
            } else if itemIdentifier == KMPDFToolbar_tools_batch_compress_Identifier {
                self.showBatchCompressController([self.listView.document.documentURL])
            } else if itemIdentifier == KMPDFToolbar_tools_OCR_Identifier {
                viewManager.showRightSide = !viewManager.showRightSide
            } else if itemIdentifier == KMPDFToolbar_tools_merge_Identifier {
                self.showMergeWindow(self.listView.document.password)
            } else if itemIdentifier == KMPDFToolbar_tools_TTS_Identifier {
                self.showTTSWindow()
            } else if itemIdentifier == KMPDFToolbar_tools_extractImage_Identifier {
                self.extractImageAction(num: 2)
            } else if itemIdentifier == KMPDFToolbar_tools_AITools_Identifier {
                self.viewManager.pdfSideBarType = .aiTools
                self.sideBarController?.reloadData()
                if let sideVC = self.sideBarController {
                    self.kmPDFSideBarControllerDidSidebarTypeUpdated(sideVC)
                }
            }
        } else if itemIdentifier == KMPDFToolbar_ViewDisplay_Identifier {
            //MARK: -Display
            updatePDFDisplaySettingView()
        } else if itemIdentifier == KMPDFToolbar_rightView_Identifier {
            //MARK: -属性栏
            
        } else if itemIdentifier == KMPDFToolbar_PageEdit_Identifier {
            //MARK: -页面编辑
            if viewManager.isPageEditMode == true {
                enterPageEditMode()
            } else {
                exitPageEditMode()
            }
        } else if(itemIdentifier == KMPDFToolbar_undo_Identifier) {
            //MARK: -Undo
            listView.undoManager?.undo()
        } else if(itemIdentifier == KMPDFToolbar_redo_Identifier) {
            //MARK: -Redo
            listView.undoManager?.redo()
        } else if(itemIdentifier == KMPDFToolbar_share_PDF_Identifier ||
                  itemIdentifier == KMPDFToolbar_share_Flattened_Identifier ||
                  itemIdentifier == KMPDFToolbar_share_Original_Identifier) {
            //MARK: -Share
            if(itemIdentifier == KMPDFToolbar_share_PDF_Identifier) {
                if let view = controller.findViewWith(KMPDFToolbar_share_Identifier) {
                    shareDocument(sender: view)
                }
            } else if(itemIdentifier == KMPDFToolbar_share_Flattened_Identifier) {
                if let view = controller.findViewWith(KMPDFToolbar_share_Identifier) {
                    shareFlatten(sender: view)
                }
            } else if(itemIdentifier == KMPDFToolbar_share_Original_Identifier) {
                if let view = controller.findViewWith(KMPDFToolbar_share_Identifier) {
                    shareOriginalPDF(sender: view)
                }
            }
        } else {
            print("click else")
        }
        
        refreshToolbarViewHeightInfo()
        
        toolbarViewModeChanged()
        
        refreshRightSide()
        
    }
    
    func kmPDFToolbarControllerDidSelectTextDidBeginEditing(_ controller: KMPDFToolbarController, _ view: ComponentSelect) {
        
    }
    
    func kmPDFToolbarControllerDidSelectTextDidChange(_ controller: KMPDFToolbarController, _ view: ComponentSelect) {
        
    }
    
    func kmPDFToolbarControllerDidSelectTextDidEndEditing(_ controller: KMPDFToolbarController, _ view: ComponentSelect) {
        if view.properties == toolbarManager.page_pageInfo_Property {
            if viewManager.isPageEditMode == true {
                let fileAttribute = KMNFileAttribute()
                fileAttribute.password = listView.document?.password ?? ""
                fileAttribute.pdfDocument = listView.document
                fileAttribute.filePath =  listView.document?.documentURL.path ?? ""
                fileAttribute.bAllPage = false
                fileAttribute.pagesType = .PagesString
                fileAttribute.pagesString = view.properties.text ?? ""
                
                let fetchSelectPages = fileAttribute.fetchSelectPages()
                if (fetchSelectPages.isEmpty) {
                    let alert = NSAlert()
                    alert.alertStyle = .critical
                    alert.messageText = String(format: "%@ %@", fileAttribute.filePath.lastPathComponent, KMLocalizedString("Invalid page range or the page number is out of range. Please try again."))
                    alert.runModal()
                    toolbarManager.page_pageInfo_Property.text = ""
                    controller.refreshSecondToolbarItemsState()
                } else {
                    var tIndexPaths: Set<IndexPath> = []
                    for i in 0 ..< fetchSelectPages.count {
                        tIndexPaths.insert(IndexPath(item: (fetchSelectPages[i] - 1), section: 0))
                    }
                    pageEditViewController?.selectionIndexPaths = tIndexPaths
                    
                }
                
            }
        }
    }
    
    func kmPDFToolbarControllerDidExitPageEditMode(_ controller: KMPDFToolbarController) {
        exitPageEditMode()
    }
}

//MARK: - KMRightSideControllerDelegate右边属性栏代理
extension KMMainViewController: KMRightSideControllerDelegate {
    func kmRightSideControllerDidContendVCUpdated(_ controller: KMRightSideController) {
        //MARK: -Crop
        if (controller.contentViewController is KMCropPropertyController) {
            if let cropVC = rightSideController?.edit_cropController {
                cropVC.pdfView = controller.pdfView
                if cropVC.delegate == nil {
                    cropVC.delegate = cropController
                }
                cropVC.reloadData()
            }
        }
    }
}

//MARK: - KMNDisplayViewControllerDelegate代理
extension KMMainViewController: KMNDisplayViewControllerDelegate {
    //Display Mode
    func displayViewControllerDidDisplayModeChanged(_ controller: KMNDisplayViewController) {
        listView.layoutDocumentView()
        
    }
    
    //阅读模式
    func displayViewControllerDidReadModeUpdated(_ controller: KMNDisplayViewController) {
        if viewManager.isPDFReadMode {
            openPDFReadMode()
        } else {
            exitPDFReadMode()
        }
    }
    
    //PPT
    func displayViewControllerDidGotoSlideShow(_ controller: KMNDisplayViewController) {
        togglePresentation(nil)
    }
    
    //SplitView
    func displayViewControllerDidSplitModeChanged(_ controller: KMNDisplayViewController) {
        reloadPDFSplitInfo()
        
    }
    
    func displayViewControllerDidSplitFileChanged(_ controller: KMNDisplayViewController) {
        splitPDFController?.reloadData()
        
    }
    
    func displayViewControllerDidToolbarStateChanged(_ controller: KMNDisplayViewController) {
        splitPDFController?.refreshToolbarState()
        
        reloadPDFPageNumberToolbar()
    }
}

//MARK: - PPT
extension KMMainViewController: KMInteractionProviderProtocol {
    func providerContentView(fullScreenWindow: NSWindow, inset: CGFloat) -> NSView? {
        if(interactionMode == .presentation) {
            if listView.presentationDrawView == nil {
                listView.createPresentationDraw()
            }
            
            presentationTopViewController = KMPresentationTopViewController.init(nibName: "KMPresentationTopViewController", bundle: nil)
            presentationTopViewController?.pdfView = listView
            presentationTopViewController?.delegate = self
            presentationTopViewController?.isSelectionPre = true
            listView.isPresentationMode = true
            presentationTopViewController?.view.frame = CGRect(x: 0, y: (fullScreenWindow.contentView?.bounds.height ?? 0) - 42, width: fullScreenWindow.contentView?.bounds.width ?? 0, height: 42)
            if((presentationTopViewController) != nil) {
                fullScreenWindow.contentView?.addSubview(presentationTopViewController!.view)
            }
        } else {
            listView.frame = NSInsetRect(fullScreenWindow.contentView?.bounds ?? .zero, 0, 0)
        }
        
        fullScreenWindow.contentView?.addSubview(listView)
        if(interactionMode == .presentation) {
            let frame = fullScreenWindow.frame
            listView.frame = CGRectMake(0, 0, frame.size.width, frame.size.height-42)
            listView.autoresizingMask = [.width, .maxYMargin]
        }
        return view
    }
    
    @objc func willEnterInteractionModeNotification(_ sender: Notification) {
        guard let win = sender.object as? NSWindow, win.isEqual(to: self.view.window) else {
            return
        }
        let interactionMode = sender.userInfo?[NSWindow.UserInfo.interactionModeKey] as? KMInteractionMode
        if interactionMode == .presentation {
            let backgroundColor = NSColor.black
            let level = UserDefaults.standard.bool(forKey: "SKUseNormalLevelForPresentationKey") ? NSWindow.Level.normal : NSWindow.Level.popUpMenu
            
            let wasInteractionMode = self.interactionMode
            if wasInteractionMode == .normal {
                self.savedNormalSetup.setDictionary(self.currentPDFSettings() as! [AnyHashable : Any])
            }
            
            if wasInteractionMode == .legacyFullScreen {
                self.enterPresentationMode()
                
                self.listView.frame = (self.view.window?.contentView?.bounds)!
                self.view.window?.contentView?.addSubview(listView)
                
                //                self.view.window?.backgroundColor = backgroundColor
                self.view.window?.level = level
                self.listView.layoutDocumentView()
                self.listView.requiresDisplay()
                
                self.forceSubwindowsOnTop(false)
                
            }
        } else {
            KMPrint("2")
        }
    }
    
    @objc func didEnterInteractionModeNotification(_ sender: Notification) {
        guard let win = sender.object as? NSWindow, win.isEqual(to: self.view.window) else {
            return
        }
        if self.interactionMode == .presentation {
            
            self.listView.layoutDocumentView()
            self.listView.requiresDisplay()
        }
    }
    
    @objc func willShowFullScreenNotification(_ sender: Notification) {
        guard let win = sender.object as? NSWindow, win.isEqual(to: self.view.window) else {
            return
        }
        if self.interactionMode == .presentation {
            let view = self.view.window?.firstResponder as? NSView
            if let data = view?.isDescendant(of: self.pdfSplitView), data {
                self.view.window?.makeFirstResponder(nil)
            }
        }
    }
    
    @objc func didShowFullScreenNotification(_ sender: Notification) {
        guard let win = sender.object as? NSWindow, win.isEqual(to: self.view.window) else {
            return
        }
        if self.interactionMode == .presentation {
            self.enterPresentationMode()
        }
    }
}

// MARK: -KMPresentationTopViewControllerDelegate (幻灯片)
extension KMMainViewController: KMPresentationTopViewControllerDelegate {
    func presentationTopViewExit(_ presentationTopViewController: KMPresentationTopViewController, withButton: NSButton) {
        self.exitFullScreen()
    }
    
    func presentationTopViewClear(_ presentationTopViewController: KMPresentationTopViewController, withButton: NSButton) {
        listView.presentationDrawView?.clear()
    }
    
    func presentationTopViewUndo(_ presentationTopViewController: KMPresentationTopViewController, withButton: NSButton) {
        let presentationDrawView = listView.presentationDrawView
        if presentationDrawView?.canUndo() == true {
            presentationDrawView?.undo()
        }
    }
    
    func presentationTopViewType(_ presentationTopViewController: KMPresentationTopViewController, withButton: NSButton, isSeletion: Bool) {
        listView.isPresentationMode = isSeletion
        if listView.isEnterPresentationDrawMode() == true {
            listView.exitPresentationDrawMode()
        }
    }
    
    func presentationTopViewDrawColor(_ presentationTopViewController: KMPresentationTopViewController, withView: NSView,color:NSColor?) {
        if color == nil{
            listView.exitPresentationDrawMode()
        } else {
            if listView.isEnterPresentationDrawMode() == false {
                listView.enterPresentationDrawMode()
            }
            listView.changePresentationDrawModelColor(color)
        }
    }
}

//MARK: - KMSplitPDFViewControllerDelegate SplitPDFView分屏视图
extension KMMainViewController: KMSplitPDFViewControllerDelegate {
    func splitPDFViewControllerDidUpdateFilePath(_ controller: KMSplitPDFViewController) {
        displaySettingController?.reloadData()
        
    }
    
    func splitPDFViewControllerDidUpdatePDFScale(_ controller: KMSplitPDFViewController) {
        if let scaleFactor = controller.pdfView?.scaleFactor {
            listView.scaleFactor = scaleFactor
        }
    }
    
    func splitPDFViewControllerDidUpdatePDFPageIndex(_ controller: KMSplitPDFViewController) {
        if let pageIndex = controller.pdfView?.currentPageIndex {
            listView.go(toPageIndex: pageIndex, animated: false)
        }
        
    }
}

//MARK: - Edit编辑相关代理
extension KMMainViewController: KMEditToolbarViewDelegate {
    func kmEditToolbarViewDidUpdateMode(_ view: KMEditToolbarView) {
        if view.editType == .watermark {
            watermarkViewController?.editSubType = editToolbarView?.editSubType ?? .template
            watermarkViewController?.resetUI()
            watermarkViewController?.reloadData()
        } else if view.editType == .background {
            backgroundViewController?.editSubType = editToolbarView?.editSubType ?? .template
            backgroundViewController?.resetUI()
            backgroundViewController?.reloadData()
        } else if view.editType == .header_Footer {
            headerFooterViewController?.editSubType = editToolbarView?.editSubType ?? .template
            headerFooterViewController?.resetUI()
            headerFooterViewController?.reloadData()
        } else if view.editType == .bates {
            batesViewController?.editSubType = editToolbarView?.editSubType ?? .template
            batesViewController?.resetUI()
            batesViewController?.reloadData()
        }
    }
    
    func kmEditToolbarViewDidChooseBatch(_ view: KMEditToolbarView) {
        
    }
    
    func kmEditToolbarViewDidChooseApply(_ view: KMEditToolbarView) {
//        let pageIndex = view.getSelectedPageIndex(listView.document)
//        if pageIndex.isEmpty {
//            let alert = NSAlert()
//            alert.alertStyle = .critical
//            alert.messageText = KMLocalizedString("Invalid page range or the page number is out of range. Please try again.")
//            alert.runModal()
//            return
//        }
//        let pageString = view.getSelectedPageString(listView.document, pageIndex)
//        
//        if view.editType == .watermark {
//            if let model = watermarkViewController?.currentWatermarkData {
//                let watermark = KMPDFWatermarkData.returnWaterMarkWith(model, listView.document)
//                watermark.pageString = pageString
//                listView.document.addWatermark(watermark)
//                listView.layoutDocumentView()
//            }
//            exitEditToolbarView()
//        } else if view.editType == .background {
//            if let model = backgroundViewController?.backgroundModel {
//                if let background = listView.document.background() {
//                    KMBackgroundManager.defaultManager.updateBackground(background, withModel: model)
//                    background.pageString = pageString
//                    background.update()
//                    
//                    listView.document?.refreshPageData()
//                    listView.layoutDocumentView()
//                }
//            }
//            exitEditToolbarView()
//            
//        } else if view.editType == .header_Footer {
//            if let model = headerFooterViewController?.headerFooterModel {
//                if let headerFooter = listView.document.headerFooter() {
//                    KMHeaderFooterManager.defaultManager.updateCPDFHeaderFooter(headerFooter, withModel: model, Int(listView.document.pageCount))
//                    headerFooter.pageString = pageString
//                    headerFooter.update()
//                    
//                    listView.document?.refreshPageData()
//                    listView.layoutDocumentView()
//                }
//            }
//            
//            exitEditToolbarView()
//            
//        } else if view.editType == .bates {
//            exitEditToolbarView()
//            
//        }
        
    }
    
    func kmEditToolbarViewDidChooseExit(_ view: KMEditToolbarView) {
        if view.applyEnable {
            let alert = NSAlert()
            if view.editType == .watermark {
                alert.messageText = NSLocalizedString("There are unapplied Watermark settings, do you want to apply them?", comment: "")
            } else if view.editType == .background {
                alert.messageText = NSLocalizedString("There are unapplied Background settings, do you want to apply them?", comment: "")
            } else if view.editType == .header_Footer {
                alert.messageText = NSLocalizedString("There are unapplied Header & Footer settings, do you want to apply them?", comment: "")
            } else if view.editType == .bates {
                alert.messageText = NSLocalizedString("There are unapplied Bates settings, do you want to apply them?", comment: "")
            }
            alert.informativeText = NSLocalizedString("If not, the changes will be lost.", comment: "")
            alert.addButton(withTitle: NSLocalizedString("Apply", comment: ""))
            alert.addButton(withTitle: NSLocalizedString("Don't Apply", comment: ""))
            alert.addButton(withTitle: NSLocalizedString("Cancel", comment: ""))
            let result = alert.runModal()
            if (result == .alertFirstButtonReturn) {
                self.kmEditToolbarViewDidChooseApply(view)
            } else if (result == .alertSecondButtonReturn) {
                //"Don't Apply"
                exitEditToolbarView()
            } else if (result == .alertThirdButtonReturn) {
                //Cancel
                
            }
        } else {
            exitEditToolbarView()
        }
    }
}

//MARK: - KMCropControllerDelegate 裁剪相关代理
extension KMMainViewController: KMCropControllerDelegate {
    func kmCropControllerDidCrop(_ controller: KMCropController, _ cropRect: CGRect, _ view: KMPageRangeSelectView) {
        let rangeSelectResult = view.getSelectedPageIndex(listView.document)
        let indexs = rangeSelectResult.0
        let isCurrentPage = rangeSelectResult.1
        var uIndexs: [UInt] = []
        for index in indexs {
            if index > 0 {
                uIndexs.append(UInt(index-1))
            }
        }
        if isCurrentPage {
            uIndexs = [UInt(listView.currentPageIndex)]
        }
        cropPages(atIndexs: uIndexs, to: [cropRect])
        removeCropController()
        
        viewManager.subToolMode = .None
        if let toolbarVC = self.pdfToolbarController {
            toolbarVC.refreshSecondToolbarItemsState()
            self.kmPDFToolbarControllerDidToolbarItemClicked(toolbarVC, KMPDFToolbar_edit_crop_Identifier)
        }
    }
    
    func kmCropControllerDidCropSeparate(_ controller: KMCropController, _ view: KMPageRangeSelectView) {
        let rangeSelectResult = view.getSelectedPageIndex(listView.document)
        let indexs = rangeSelectResult.0
        let isCurrentPage = rangeSelectResult.1
        var rectArray: Array<NSRect> = []
        var uIndexs: [UInt] = []
        for index in indexs {
            if index > 0 {
                uIndexs.append(UInt(index-1))
                
                let page = self.listView.document.page(at: UInt(index-1))
                let rect = KMCropTools.getPageForegroundBox(page!)
                rectArray.append(rect)
            }
        }
        if isCurrentPage {
            uIndexs = [UInt(listView.currentPageIndex)]
        }
        cropPages(atIndexs: uIndexs, to: rectArray)
        removeCropController()
        
        viewManager.subToolMode = .None
        if let toolbarVC = self.pdfToolbarController {
            toolbarVC.refreshSecondToolbarItemsState()
            self.kmPDFToolbarControllerDidToolbarItemClicked(toolbarVC, KMPDFToolbar_edit_crop_Identifier)
        }
    }
    
    func kmCropControllerDidCropAuto(_ controller: KMCropController, _ view: KMPageRangeSelectView) {
        let rangeSelectResult = view.getSelectedPageIndex(listView.document)
        let indexs = rangeSelectResult.0
        let isCurrentPage = rangeSelectResult.1
        var uIndexs: [UInt] = []
        for index in indexs {
            if index > 0 {
                uIndexs.append(UInt(index-1))
            }
        }
        if isCurrentPage {
            uIndexs = [UInt(listView.currentPageIndex)]
        }
        auto_cropPagesWhiteMargin(uIndexs)
        removeCropController()
        
        viewManager.subToolMode = .None
        if let toolbarVC = self.pdfToolbarController {
            toolbarVC.refreshSecondToolbarItemsState()
            self.kmPDFToolbarControllerDidToolbarItemClicked(toolbarVC, KMPDFToolbar_edit_crop_Identifier)
        }
    }
    
    func kmCropControllerDidChangedSelectionOrMagnification(_ controller: KMCropController) {
        if let cropVC = rightSideController?.edit_cropController {
            if cropVC.pdfView != controller.pdfView {
                cropVC.pdfView = controller.pdfView
            }
            cropVC.cropSeparateOn = false
            cropVC.cropAutoOn = false
            cropVC.reloadData()
        }
    }
    
}

//MARK: - KMWatermarkControllerDelegate 水印相关代理
extension KMMainViewController: KMWatermarkControllerDelegate {
    func kmWatermarkControllerDidUpdateMode(_ view: KMWatermarkController) {
        editToolbarView?.editSubType = view.editSubType
        editToolbarView?.reloadData()
        
    }
    
    func kmWatermarkControllerDidWatermarkUpdated(_ view: KMWatermarkController) {
        var applyEnable = true
        if let model = view.currentWatermarkData {
            if model.watermarkType == .text {
                if model.text == nil || model.text?.count == 0 {
                    applyEnable = false
                }
            } else if model.watermarkType == .image {
                if model.imagePath == nil {
                    applyEnable = false
                }
            }
        } else {
            applyEnable = false
        }
        editToolbarView?.applyEnable = applyEnable
        
        editToolbarView?.reloadData()
        
    }
}

//MARK: - KMBackgroundControllerDelegate 背景代理
extension KMMainViewController: KMBackgroundControllerDelegate {
    func kmBackgroundControllerDidUpdateMode(_ view: KMBackgroundController) {
        editToolbarView?.editSubType = view.editSubType
        
    }
    
    func kmBackgroundControllerDidWatermarkUpdated(_ view: KMBackgroundController) {
        var applyEnable = true
        if let model = view.backgroundModel {
            if model.type == .image {
                if model.imagePath == nil {
                    applyEnable = false
                }
            }
        } else {
            applyEnable = false
        }
        editToolbarView?.applyEnable = applyEnable
        
        editToolbarView?.reloadData()
    }
}

//MARK: - KMHeaderFooterControllerDelegate 页眉页脚代理
extension KMMainViewController: KMHeaderFooterControllerDelegate {
    func kmHeaderFooterControllerDidUpdateModeType(_ view: KMHeaderFooterController) {
        editToolbarView?.editSubType = view.editSubType
        
    }
    
    func kmHeaderFooterControllerDidModelDataUpdated(_ view: KMHeaderFooterController) {
        var applyEnable = true
        if let model = view.headerFooterModel {
            if model.topLeftString.count == 0 && model.topCenterString.count == 0 && model.topRightString.count == 0 &&
                model.bottomLeftString.count == 0 && model.bottomCenterString.count == 0 && model.bottomRightString.count == 0 {
                applyEnable = false
            }
        } else {
            applyEnable = false
        }
        editToolbarView?.applyEnable = applyEnable
        
        editToolbarView?.reloadData()
    }
}

//MARK: - KMBatesControllerDelegate Bates贝茨码代理
extension KMMainViewController: KMBatesControllerDelegate {
    func kmBatesControllerDidUpdateMode(_ view: KMBatesController) {
        editToolbarView?.editSubType = view.editSubType
        editToolbarView?.reloadData()
        
    }
    
    func kmBatesControllerDidModelDataUpdated(_ view: KMBatesController) {
        var applyEnable = true
        if let model = view.batesModel {
            if model.topLeftString.count == 0 && model.topCenterString.count == 0 && model.topRightString.count == 0 &&
                model.bottomLeftString.count == 0 && model.bottomCenterString.count == 0 && model.bottomRightString.count == 0 {
                applyEnable = false
            }
        } else {
            applyEnable = false
        }
        editToolbarView?.applyEnable = applyEnable
        
        editToolbarView?.reloadData()
    }
    
}

//MARK: - CPDFViewDelegate PDFView代理

extension KMMainViewController: CPDFViewDelegate,CPDFListViewDelegate {
    func pdfViewDocumentDidLoaded(_ pdfView: CPDFView!) {
        sideBarController?.reloadPageTurnerData()
        
        documentLoadComplete()
    }
    
    func pdfViewCurrentPageDidChanged(_ pdfView: CPDFView!) {
        
        sideBarController?.reloadPageTurnerData()
        
        botaViewController?.currentPageDidChangedAction(listView: listView)
        
        //分屏视图
        reloadPDFPageNumberToolbar()
        
        if viewManager.splitSyncScroll {
            if splitPDFController?.inPDFFirst == false && splitPDFController?.outPDFFirst == false {
                splitPDFController?.outPDFFirst = true
                
                if let splitPDFView = splitPDFController?.pdfView, let document = splitPDFView.document {
                    var index = pdfView.currentPageIndex
                    if index > document.pageCount {
                        index = Int(splitPDFView.document.pageCount - 1)
                    }
                    splitPDFView.go(toPageIndex: index, animated: false)
                }
                NSObject.cancelPreviousPerformRequests(withTarget: self, selector: #selector(pdfUpdatedFinish), object: nil)
                self.perform(#selector(pdfUpdatedFinish), with: nil, afterDelay: 0.35)
            } else if splitPDFController?.outPDFFirst == true {
                if let splitPDFView = splitPDFController?.pdfView, let document = splitPDFView.document {
                    var index = pdfView.currentPageIndex
                    if index > document.pageCount {
                        index = Int(splitPDFView.document.pageCount - 1)
                    }
                    splitPDFView.go(toPageIndex: index, animated: false)
                }
                
                NSObject.cancelPreviousPerformRequests(withTarget: self, selector: #selector(pdfUpdatedFinish), object: nil)
                self.perform(#selector(pdfUpdatedFinish), with: nil, afterDelay: 0.35)
            }
        }
        
        //水印
        updateEditModeDocumentWhenPageChanged()
        
        //
    }
    
    func pdfViewScaleDidChanged(_ pdfView: CPDFView!) {
        
        pdfToolbarController?.reloadSelectZoomView()
        
        reloadPDFPageNumberToolbar()
        
        reloadPopUIWindow()
        
        //分屏视图
        if viewManager.splitSyncScroll {
            if splitPDFController?.inPDFFirst == false && splitPDFController?.outPDFFirst == false {
                splitPDFController?.outPDFFirst = true
                
                NSObject.cancelPreviousPerformRequests(withTarget: self, selector: #selector(pdfUpdatedFinish), object: nil)
                self.perform(#selector(pdfUpdatedFinish), with: nil, afterDelay: 0.35)
            } else if splitPDFController?.outPDFFirst == true {
                if let splitPDFView = splitPDFController?.pdfView {
                    splitPDFView.scaleFactor = pdfView.scaleFactor
                }
                NSObject.cancelPreviousPerformRequests(withTarget: self, selector: #selector(pdfUpdatedFinish), object: nil)
                self.perform(#selector(pdfUpdatedFinish), with: nil, afterDelay: 0.35)
            }
        }
    }
    
    func pdfViewDidClick(onLink pdfView: CPDFView!, withURL url: String!) {
        if let urlString = url, urlString == kKMPurchaseProductURLString {
            //跳转订阅比较表
            return
        }
        
        if url.hasPrefix("smb://") {
            NSWorkspace.shared.openFile(url)
        } else {
            KMTools.openURL(urlString: url)
        }
    }
    
    func pdfViewPerformURL(_ pdfView: CPDFView!, withContent content: String!) {
        KMPrint("pdfViewPerformURL")
        if content != nil {
            NSWorkspace.shared.open(URL(string: content)!)
        } else {
            let alert = NSAlert()
            alert.alertStyle = .critical
            alert.informativeText = NSLocalizedString("The hyperlink is invalid.", comment: "")
            alert.messageText = ""
            alert.addButton(withTitle: NSLocalizedString("OK", comment: ""))
            alert.runModal()
            return
        }
    }
    
    func pdfViewPerformPrint(_ pdfView: CPDFView!) {
        KMPrint("pdfViewPerformPrint")
        self.showPrintWindow()
    }
    
    func pdfViewPerformGo(toPage pdfView: CPDFView!) {
        KMPrint("pdfViewPerformGo")
    }
    
    func pdfViewOpenPDF(_ pdfView: CPDFView!, forRemoteGoTo action: CPDFAction!) {
        KMPrint("pdfViewOpenPDF")
    }
    
    func pdfViewPerformReset(_ pdfView: CPDFView!) {
        KMPrint("pdfViewPerformReset")
        pdfView.document?.resetForm()
    }
    
    func pdfViewEditingBlockDidChanged(_ pdfView: CPDFView!) {
        KMPrint("pdfViewEditingBlockDidChanged")
    }
    
    func pdfViewAsBookBookmark() -> NSImage! {
        return NSImage(named: "KMImageNameBookmarkIcon")!
    }
    
    //MARK: -编辑模块
    func pdfViewEditingSelectionDidChanged(_ pdfView: CPDFView!) {
        // 文本区块 选中文本已经变化
        reloadPopUIWindow()
    }
    
    func pdfViewPDFSelectionAttributeDidChanged(_ pdfView: CPDFView!) {
        reloadPopUIWindow()
    }
    
    func pdfViewEditingAreaDidChanged(_ pdfView: CPDFView!) {
        //编辑模块变化
        rightSideController?.reloadDataWithPDFView(pdfView: (pdfView as! CPDFListView))
        
        if pdfView is CPDFListView {
            (pdfView as! CPDFListView).isEditImage = false
        }
        
        reloadPopUIWindow()
    }
    
    func pdfViewEditingCropBoundsDidChanged(_ pdfView: CPDFView!, editing editArea: CPDFEditArea!) {
        if editArea != nil && (editArea is CPDFEditImageArea){
            self.listView.cropAreas = editArea as? CPDFEditImageArea
        }
        reloadPopUIWindow()
    }
    
    //编辑PDF 创建图片区域回调
    func pdfViewEditingAddImageArea(_ pdfView: CPDFView!, add page: CPDFPage!, add rect: CGRect) {
        if (pdfView as! CPDFListView).isEditImage {
            
            return
        }
        
        if rect.size.width < 5 && rect.size.height < 5 {
            pdfView.updateEditing([])
            
            return
        }
        
        let panel = NSOpenPanel()
        panel.allowsMultipleSelection = false
        panel.allowedFileTypes = ["png","jpg"]
        panel.beginSheetModal(for: NSApp.mainWindow!) { response in
            if response == .OK {
                var filePath = panel.url?.path
                let image = NSImage.init(contentsOf: panel.url!)
                //图片自适应范围
                if image != nil {
                    var imageRect = rect
                    let imageSize = image!.size
                    var previewSize = rect.size
                    var isChangeSize = false
                    if previewSize.width == 0 && previewSize.height == 0 {
                        previewSize = CGSize(width: 500, height: 500)
                        isChangeSize = true
                    }
                    
                    var scale = min(previewSize.width / imageSize.width, previewSize.height / imageSize.height)
                    if scale < 1 { // 大于 500
                        
                    } else {
                        let wh = max(imageSize.width, imageSize.height)
                        if wh >= 72 {
                            scale = min(scale, 1)
                        } else {
                            scale = min(72 / imageSize.width, 72 / imageSize.height)
                        }
                    }
                    
                    let newSize = CGSize(width: imageSize.width * scale, height: imageSize.height * scale)
                    
                    if isChangeSize {
                        imageRect.origin.x = imageRect.origin.x - newSize.width / 2
                        imageRect.origin.y = imageRect.origin.y - newSize.height / 2
                    } else {
                        imageRect.origin.x = imageRect.origin.x + imageRect.width / 2 - newSize.width / 2
                        imageRect.origin.y = imageRect.origin.y + imageRect.height / 2 - newSize.height / 2
                    }
                    
                    imageRect.size = newSize
                    let limitWidth = 1920.0
                    if imageSize.width > limitWidth || imageSize.height > limitWidth {
                        filePath = KMImageOptimization.needCompressImageLosslessly(image: image!,
                                                                                   targetSize: CGSize(width: limitWidth, height: limitWidth),
                                                                                   maxSizeInBytes: 1024 * 1024 * 5,
                                                                                   targetCompression: 1.0)
                    }
                    
                    //自适应page
                    let pageRect = self.listView.currentPage().bounds ?? .zero
                    if imageRect.width > pageRect.width ||
                        imageRect.height > pageRect.height {
                        let pageScale = min(pageRect.width / imageSize.width, pageRect.height / imageSize.height)
                        imageRect = CGRect(x: imageRect.origin.x,
                                           y: imageRect.origin.y,
                                           width: imageRect.width * pageScale,
                                           height: imageRect.height * pageScale)
                    }
                    
                    if imageRect.origin.x < 0 {
                        imageRect.origin.x = 5
                    }
                    
                    if imageRect.origin.y < 0 {
                        imageRect.origin.y = 5
                    }
                    
                    if imageRect.origin.x + imageRect.width > pageRect.width ||
                        imageRect.origin.y + imageRect.height > pageRect.height {
                        let offsetX = imageRect.origin.x + imageRect.width - pageRect.width
                        let offsetY = imageRect.origin.y + imageRect.height - pageRect.height
                        
                        imageRect.origin.x = imageRect.origin.x - offsetX - 5
                        imageRect.origin.y = imageRect.origin.y - offsetY - 5
                    }
                    DispatchQueue.main.async {
                        self.listView.createImagePath(filePath, rect: imageRect, page: pdfView.currentPage())
                    }
                }
            }
        }
    }
    
    func pdfViewEditingAddTextArea(_ pdfView: CPDFView!, add page: CPDFPage!, add rect: CGRect) {
        
        if rect.size.width < 5 && rect.size.height < 5 {
            let areas = self.listView.km_EditingAreas()
            if let area = areas.last {
                if let data = area as? CPDFEditTextArea {
                    if let str = data.editTextAreaString(), str.isEmpty {
                        self.listView.remove(with: area)
                    } else {
                        self.listView.updateEditing([])
                    }
                }
            }
            return
        }
        
        var newRect = rect
        if rect.size.equalTo(.zero) {
            newRect = CGRect(x: rect.origin.x, y: rect.origin.y - 12, width: 20, height: 12)
        } else {
            newRect = CGRect(x: rect.origin.x, y: rect.origin.y + rect.size.height - 12, width: rect.size.width, height: 12)
        }
        
        let model = KMEditPDFTextManager.manager.fetchUserDefaultData(type: .commonly)
        let fontSize = model.fontSize
        let fontColor = model.color
        let fontAlign = model.alignment
        NSColorPanel.shared.color = fontColor
         
        let attri = CEditAttributes()
        attri.cFont = CPDFFont(familyName: model.fontName, fontStyle: model.fontStyle)
        attri.fontColor = fontColor
        attri.alignment = fontAlign
        attri.isBold = model.bold
        attri.isItalic = model.italic
        
        self.listView.createStringBounds(newRect, with: attri, page: page)
        
    }
    
    func pdfViewMobileEditingBegan(_ point: CGPoint, for pdfView: CPDFView!, forEditing editingAreas: [CPDFEditArea]!) {
        rightSideController?.reloadEditingAreas()
        
        toggleClosePopUIWindow()
    }
    
    func pdfViewMobileEditingMove(_ point: CGPoint, for pdfView: CPDFView!, forEditing editingAreas: [CPDFEditArea]!) {
        rightSideController?.reloadEditingAreas()
        
        toggleClosePopUIWindow()
    }
    
    func pdfViewMobileEditingEnd(_ point: CGPoint, for pdfView: CPDFView!, forEditing editingAreas: [CPDFEditArea]!) {
        rightSideController?.reloadEditingAreas()
        
        reloadPopUIWindow()
    }
    
    func pdfViewEditingSelectCharDidChanged(_ pdfView: CPDFView!) {
        rightSideController?.reloadEditingAreas()
        reloadPopUIWindow()
    }
    
    func pdfViewEditingExitCropMode(_ pdfView: CPDFView!, forEditing editingArea: CPDFEditImageArea!) {
        rightSideController?.reloadEditingAreas()
        
        toggleClosePopUIWindow()
    }
    
    func pdfViewEditingOperationDidChanged(_ pdfView: CPDFView!) {
        let areas = self.listView.km_editingImageAreas()
        if areas.count == 1 {
            if let data = areas.first as? CPDFEditImageArea {
                let updating = self.listView.editAreaBoundUpdating
                if updating {
                    self.listView.editAreaBoundUpdating = false
                }
            }
        }
        
    }
    
    func pdfViewEditingDoubleClick(_ pdfView: CPDFView!, imageArea editArea: CPDFEditArea!) {
        
    }
    
    func pdfListViewKeyDownIsContinue(_ pdfListView: CPDFListView!, theEvent: NSEvent!) -> Bool {
        let command = theEvent.modifierFlags.contains(.command)
        let control = theEvent.modifierFlags.contains(.control)
        
        KMPrint(theEvent.keyCode)
        if self.listView.isEditing() == true {
            if control && theEvent.keyCode == 11 { // ctr + b
                self.listView.setEditingTextarea_Bold()
                rightSideController?.reloadEditingAreas()
                
                return false
            } else if control && theEvent.keyCode == 34 { // ctr +i
                self.listView.setEditingTextarea_Italic()
                rightSideController?.reloadEditingAreas()
                
                return false
            } else if theEvent.keyCode == 36 { // enter
                if self.listView.isCropMode {
                    self.listView.cropComfirmAction()
                    rightSideController?.reloadEditingAreas()
                    
                    return false
                }
            } else if theEvent.keyCode == 53 { // Cancel
                if self.listView.isCropMode {
                    self.listView.cropCancelAction()
                    rightSideController?.reloadEditingAreas()
                    
                    return false
                }
            }
        }
        
        if (theEvent.keyCode == 11 && command) { // command + B [添加书签]
            self.menuItemBookMarkClick_add(sender: NSMenuItem())
            return false
        } else if (command && control && theEvent.keyCode == 14) { // command + control + E [注释 橡皮擦]
            return false
        } else if (theEvent.keyCode == 123) { // 向左
            if(self.listView.isEditing() && !self.listView.isSelecteditAreaNotEdit()) {
                return false
            } else {
                if (self.pdfViewCanHorizontalScroll() == false && self.listView.canGoToPreviousPage()) {
                    self.listView.goToPreviousPage(nil)
                    return false
                }
            }
        } else if (theEvent.keyCode == 126) { // 向上
            if(self.listView.isEditing() && !self.listView.isSelecteditAreaNotEdit()) {
                return false
            } else {
                if (self.listView.isContinousScroll()) {
                    return true
                }
                if (self.pdfViewCanVerticalScroll() == false && self.listView.canGoToPreviousPage()) {
                    self.listView.goToPreviousPage(nil)
                    return false
                }
            }
        } else if (theEvent.keyCode == 124) { // 向右
            if(self.listView.isEditing() && !self.listView.isSelecteditAreaNotEdit()) {
                return false
            } else {
                if (self.pdfViewCanHorizontalScroll() == false && self.listView.canGoToNextPage()) {
                    self.listView.goToNextPage(nil)
                    return false
                }
            }
        } else if (theEvent.keyCode == 125) { // 向下
            if(self.listView.isEditing() && !self.listView.isSelecteditAreaNotEdit()) {
                return false
            } else {
                if (self.listView.isContinousScroll()) {
                    return true
                }
                if (self.pdfViewCanVerticalScroll() == false && self.listView.canGoToNextPage()) {
                    self.listView.goToNextPage(nil)
                    return false
                }
            }
        } else if (theEvent.keyCode == 36) {
            if self.listView.shouAddEditAreaType() == .image || self.listView.shouAddEditAreaType() == .text {
                if self.listView.isEditImage {
                    self.menuItemEditingClick_CropImage(sender: NSMenuItem())
                }
            }
        }
        
        if theEvent.keyCode == 53 {
            //ESC
            self.exitFullScreen()
            
            if viewManager.isPDFReadMode {
                self.exitPDFReadMode()
            }
            
            self.leftSideViewCancelSelect()
            
        }
        return true
    }
    
    func pdfListViewMenuValidate(_ pdfListView: CPDFListView!, menuItem: NSMenuItem!, isTakesEffect: UnsafeMutablePointer<ObjCBool>!) -> Bool {
        guard let action = menuItem.action else {
            isTakesEffect.pointee = false
            return false
        }
        
        if (KMSystemMenu.isEditSelector(sel: action)) {
            if (KMSystemMenu.Edit.deleteSelector == action) {
                isTakesEffect.pointee = true
                return self.listView.activeAnnotations.count > 0
            } else if (KMSystemMenu.Edit.copySelector == action) {
                isTakesEffect.pointee = true
                return true//self.listView.canCopy()
            } else if (KMSystemMenu.Edit.cutSelector == action) {
                isTakesEffect.pointee = true
                return self.listView.canCopy()
            } else if (KMSystemMenu.Edit.pasteSelector == action) {
                isTakesEffect.pointee = true
                return self.listView.canPaste()
            }
        }
        
        isTakesEffect.pointee = false
        return false
    }
    
    //MARK: - CPDFListViewDelegate
    
    func pdfListViewChangedToolMode(_ pdfListView: CPDFListView!, for toolMode: CToolMode) {
        reloadPopUIWindow()
    }
    
    func pdfListViewChangeatioActiveAnnotations(_ pdfListView: CPDFListView!, forActiveAnnotations annotations: [CPDFAnnotation]!, isRightMenu: Bool) {
        self.view.window?.makeFirstResponder(self.listView)
        
        reloadPopUIWindow()
        
        if isRightMenu {
            
        } else if annotations.count > 0 {
            if annotations.count > 1 {
                var isMultiAnnotations = pdfListView.isMultiAnnotation(annotations)
                if isMultiAnnotations == true {
                    self.toggleCloseRightSide()
                } else {
                    self.toggleOpenRightSide()
                }
                self.rightSideController?.reloadDataWithPDFView(pdfView: pdfListView)
            } else {
                let fristAnnotation  = annotations.first
                let className = NSStringFromClass(fristAnnotation!.classForCoder)
                if self.viewManager.isPDFReadMode {
                    toggleCloseRightSide()
                } else {
                    self.toggleOpenRightSide()
                    self.rightSideController?.reloadDataWithPDFView(pdfView: pdfListView)
                }
            }
            
            //测量相关
            if (listView.activeAnnotation.isKind(of: CPDFLineAnnotation.self)) {
                if (!(listView.activeAnnotation as! CPDFLineAnnotation).isMeasure) {
                    cancelMeasureType()
                } else {
                    if distanceMeasureInfoWindowController == nil {
                        let measureInfo = CPDFDistanceMeasureInfo()
                        distanceMeasureInfoWindowController = CDistanceMeasureInfoWindowController()
                        distanceMeasureInfoWindowController?.measureInfo = measureInfo
                        distanceMeasureInfoWindowController?.delegate = self
                    }
                }
            } else if (!listView.activeAnnotation.isKind(of: CPDFPolygonAnnotation.self) && !listView.activeAnnotation.isKind(of: CPDFPolylineAnnotation.self)) {
                cancelMeasureType()
            } else if (listView.activeAnnotation.isKind(of: CPDFPolygonAnnotation.self) || listView.activeAnnotation.isKind(of: CPDFPolylineAnnotation.self)) {
                if perimeterMeasureInfoWindowController == nil {
                    let measureInfo = CPDFPerimeterMeasureInfo()
                    perimeterMeasureInfoWindowController = CPerimeterMeasureInfoWindowController()
                    perimeterMeasureInfoWindowController?.measureInfo = measureInfo
                    perimeterMeasureInfoWindowController?.delegate = self
                }
                if areaMeasureInfoWindowController == nil {
                    let measureInfo = CPDFAreaMeasureInfo()
                    areaMeasureInfoWindowController = CAreaMeasureInfoWindowController()
                    areaMeasureInfoWindowController?.measureInfo = measureInfo
                    areaMeasureInfoWindowController?.delegate = self
                }
            }
        } else if (annotations.count == 0){
            if pdfListView.annotationType == .unkown {
                toggleCloseRightSide()
            } else {
                if self.viewManager.isPDFReadMode {
                    toggleCloseRightSide()
                } else {
                    toggleOpenRightSide()
                }
            }
            rightSideController?.reloadDataWithPDFView(pdfView: pdfListView)
        }
    }
    
    func pdfListViewMobileAnnotationBegan(_ point: CGPoint, for pdfListView: CPDFListView!, forActiveAnnotations annotations: [CPDFAnnotation]!) {
        toggleClosePopUIWindow()
    }
    
    func pdfListViewMobileAnnotationMove(_ point: CGPoint, for pdfListView: CPDFListView!, forActiveAnnotations annotations: [CPDFAnnotation]!) {
        toggleClosePopUIWindow()
    }
    
    func pdfListViewMobileAnnotationEnd(_ point: CGPoint, for pdfListView: CPDFListView!, forActiveAnnotations annotations: [CPDFAnnotation]!) {
        reloadPopUIWindow()
    }
    
    func pdfListViewChangedAnnotationType(_ pdfListView: CPDFListView!, for annotationType: CAnnotationType) {
        if(annotationType == .unkown) {
            toggleCloseRightSide()
        }
    }
    
    func pdfListViewMenuItemsEditing(at point: CGPoint, for page: CPDFPage!, menuItems: [NSMenuItem]!) -> [NSMenuItem]! {
        return menuItems
    }
    
    func pdfListViewAddAnnotations(_ pdfListView: CPDFListView!, forAdd annotations: [CPDFAnnotation]!, in pdfPage: CPDFPage!) {
        
        var pageIndexes = IndexSet()
        pageIndexes.insert(Int(pdfPage.pageIndex()))
        botaViewController?.thumnailViewController?.reloadDataWithIndexs(pageIndexs: pageIndexes)
    }
    
    func pdfListViewRemoveAnnotations(_ pdfListView: CPDFListView!, forRemove annotations: [CPDFAnnotation]!, in pdfPage: CPDFPage!) {
        var pageIndexes = IndexSet()
        pageIndexes.insert(Int(pdfPage.pageIndex()))
        botaViewController?.thumnailViewController?.reloadDataWithIndexs(pageIndexs: pageIndexes)
    }
    
    func pdfListViewEditAnnotation(_ pdfListView: CPDFListView!, for anotation: CPDFAnnotation!) {
        if anotation.isKind(of: CPDFSignatureWidgetAnnotation.self) {
            if let signatureWidgetAnnotation = anotation as? CPDFSignatureWidgetAnnotation {
                let signature = signatureWidgetAnnotation.signature()
                if ((signature) != nil) {
                    popUpSignatureWidgetState(signature!, listView)
                } else {
                    let widget = CPDFSignatureWidgetAnnotation.init(PDFListViewNoteWith: listView.document)
                    widget.bounds = NSMakeRect(-1000, -1000, 545, 178);
                    anotation.page.addAnnotation(widget)
                    
                    let configWindowVC = DSignatureConfigWindowController.init(windowNibName: "DSignatureConfigWindowController")
                    configWindowVC.viewType = .fileList;
                    configWindowVC.appearanceWidget = widget;
                    configWindowVC.isCreatDS = false
                    configWindowVC.complentionHandle = {[weak self] isSign, dic, config, isLock in
                        widget.page.removeAnnotation(widget)
                        if isSign {
                            if (dic.object(forKey: SAVEFILEPATH_KEY) != nil) {
                                let p12Path = dic.object(forKey: SAVEFILEPATH_KEY) as! String
                                let password = dic.object(forKey: PASSWORD_KEY)
                                if p12Path.count > 0 {
                                    self?.writeSignatureToWidget(signatureWidgetAnnotation, p12Path, password as! String, config, isLock)
                                }
                            }
                        } else {
                            if signatureWidgetAnnotation.isSignSignatureAdd() == true {
                                self?.listView.remove(anotation)
                            }
                        }
                    }
                    configWindowVC.actionBlock = {[weak self] controller, type in
                        if (type == .cancel) {
                            NSApplication.shared.stopModal()
                            controller.window?.orderOut(nil)
                            controller.window?.close()
                            widget.page.removeAnnotation(widget)
                            
                            if signatureWidgetAnnotation.isSignSignatureAdd() == true {
                                self?.listView.remove(anotation)
                            } else {
                                self?.listView.setNeedsDisplayAnnotationViewFor(anotation.page)
                            }
                        } else if (type == .confirm) {
                            NSApplication.shared.stopModal()
                            controller.window?.orderOut(nil)
                            controller.window?.close()
                        }
                    }
                    configWindowVC.window?.center()
                    NSApplication.shared.runModal(for: configWindowVC.window!)
                }
            }
                
        } else if anotation.isKind(of: CPDFRedactAnnotation.self) {
            if let redactAnnotation = anotation as? CPDFRedactAnnotation {
                let properties = KMRedactPropertiesWindowController()
                properties.readactAnnotation = redactAnnotation
                self.km_beginSheet(windowC: properties)
                properties.callback = { [weak self] annotation in
                    if let page = annotation?.page {
                        self?.listView.setNeedsDisplayAnnotationViewFor(page)
                    }
                }

            }
        }
    }
    
    //MARK: -Crop
    func pdfListViewChangedSelectionOrMagnification(_ pdfListView: CPDFListView!) {
        reloadPopUIWindow()
    }
    
    func pdfListViewDidSelectionEnd(_ pdfListView: CPDFListView!) {
        if (!self.listView.isEqual(to: pdfListView)) {
            return
        }
        if (self.listView.toolMode != .CSelectToolMode) {
            return
        }
        reloadPopUIWindow()
    }
    
    func pdfListViewEventMarkupColor(with annotation: CPDFAnnotation!) -> [NSColor]! {
        if (annotation.isKind(of: CPDFMarkupAnnotation.self)) {
            if (annotation as! CPDFMarkupAnnotation).markupType() == .highlight {
                return KMAnnotationPropertiesColorManager.manager.markHighlightColors
            } else {
                return KMAnnotationPropertiesColorManager.manager.markOtherColors
            }
        } else {
            return KMAnnotationPropertiesColorManager.manager.markOtherColors
        }
    }
    
    func pdfListViewHaveDocumentAttribute() -> Bool {
        if(!self.listView.document.allowsCopying) {
            self.removeOwnerPassword()
            return false
        }
        return true
    }
    
    func pdfListViewAnnotationMeasureInfoChange(_ pdfListView: CPDFListView!, with annotation: CPDFAnnotation!) {
        guard let data = annotation else {
            if distanceMeasureInfoWindowController?.window?.isVisible == true {
                distanceMeasureInfoWindowController?.clearData()
            }
            return
        }
        if let lineAnnotation = annotation as? CPDFLineAnnotation {
            handleLineAnnotation(lineAnnotation)
        } else if let polylineAnnotation = annotation as? CPDFPolylineAnnotation {
            handlePolylineAnnotation(polylineAnnotation)
        } else if let polygonAnnotation = annotation as? CPDFPolygonAnnotation {
            handlePolygonAnnotation(polygonAnnotation)
        }
    }
    
    func pdfListViewMeasureCancel(_ pdfListView: CPDFListView!) {
        cancelMeasureType()
    }
    
    private func handleLineAnnotation(_ annotation: CPDFLineAnnotation) {
        if perimeterMeasureInfoWindowController?.window?.isVisible == true {
            perimeterMeasureInfoWindowController?.hideFloatingWindow()
            distanceMeasureInfoWindowController?.showWindow(self)
        } else if areaMeasureInfoWindowController?.window?.isVisible == true {
            areaMeasureInfoWindowController?.hideFloatingWindow()
            distanceMeasureInfoWindowController?.showWindow(self)
        } else if distanceMeasureInfoWindowController?.window?.isVisible == false {
            distanceMeasureInfoWindowController?.showWindow(self)
        }
        
        let measureInfo = annotation.measureInfo
        let startPoint = annotation.startPoint
        let endPoint = annotation.endPoint
        let angle = atan2(endPoint.y - startPoint.y, endPoint.x - startPoint.x) * (180.0 / .pi)
        
        distanceMeasureInfoWindowController?.angleLabel.stringValue = String(format: "%.2f°", abs(angle))
        distanceMeasureInfoWindowController?.xLabel.stringValue = String(format: "%.0f", abs(endPoint.x - startPoint.x))
        distanceMeasureInfoWindowController?.yLabel.stringValue = String(format: "%.0f", abs(endPoint.y - startPoint.y))
        distanceMeasureInfoWindowController?.reloadData(with: measureInfo!)
    }
    
    private func handlePolylineAnnotation(_ annotation: CPDFPolylineAnnotation) {
        if distanceMeasureInfoWindowController?.window?.isVisible == true {
            distanceMeasureInfoWindowController?.hideFloatingWindow()
            perimeterMeasureInfoWindowController?.showWindow(self)
        } else if areaMeasureInfoWindowController?.window?.isVisible == true {
            areaMeasureInfoWindowController?.hideFloatingWindow()
            perimeterMeasureInfoWindowController?.showWindow(self)
        } else if perimeterMeasureInfoWindowController?.window?.isVisible == false {
            perimeterMeasureInfoWindowController?.showWindow(self)
        }
        
        let measureInfo = annotation.measureInfo
        let savePoints = annotation.savePoints()
        var angle: CGFloat = 0
        if savePoints.count >= 3 {
            let count = savePoints.count
            let startPoint = savePoints[count - 3].pointValue
            let midPoint = savePoints[count - 2].pointValue
            let endPoint = savePoints.last!.pointValue
            
            angle = angleBetweenPoints(startPoint, midPoint, endPoint)
        }
        angle = 180 - angle
        perimeterMeasureInfoWindowController?.angleLabel.stringValue = String(format: "%.2f°", abs(angle))
        perimeterMeasureInfoWindowController?.reloadData(with: measureInfo!)
    }
    
    private func handlePolygonAnnotation(_ annotation: CPDFPolygonAnnotation) {
        if distanceMeasureInfoWindowController?.window?.isVisible == true {
            distanceMeasureInfoWindowController?.hideFloatingWindow()
            areaMeasureInfoWindowController?.showWindow(self)
        } else if perimeterMeasureInfoWindowController?.window?.isVisible == true {
            perimeterMeasureInfoWindowController?.hideFloatingWindow()
            areaMeasureInfoWindowController?.showWindow(self)
        } else if areaMeasureInfoWindowController?.window?.isVisible == false {
            areaMeasureInfoWindowController?.showWindow(self)
        }
        
        let measureInfo = annotation.measureInfo
        let savePoints = annotation.savePoints
        var angle: CGFloat = 0
        if savePoints.count >= 3 {
            let count = savePoints.count
            let startPoint = (savePoints[count - 3] as AnyObject).pointValue
            let midPoint = (savePoints[count - 2] as AnyObject).pointValue
            let endPoint = (savePoints.lastObject as AnyObject).pointValue
            
            angle = angleBetweenPoints(startPoint!, midPoint!, endPoint!)
        }
        angle = 180 - angle
        areaMeasureInfoWindowController?.angleLabel.stringValue = String(format: "%.2f°", abs(angle))
        areaMeasureInfoWindowController?.reloadData(measureInfo!)
    }
    
    private func angleBetweenPoints(_ startPoint: CGPoint, _ midPoint: CGPoint, _ endPoint: CGPoint) -> CGFloat {
        let vector1 = CGPoint(x: midPoint.x - startPoint.x, y: midPoint.y - startPoint.y)
        let vector2 = CGPoint(x: endPoint.x - midPoint.x, y: endPoint.y - midPoint.y)
        let dotProduct = vector1.x * vector2.x + vector1.y * vector2.y
        let magnitude1 = sqrt(vector1.x * vector1.x + vector1.y * vector1.y)
        let magnitude2 = sqrt(vector2.x * vector2.x + vector2.y * vector2.y)
        
        return acos(dotProduct / (magnitude1 * magnitude2)) * (180.0 / .pi)
    }
    
    
    @objc func pdfUpdatedFinish() {
        splitPDFController?.inPDFFirst = false
        splitPDFController?.outPDFFirst = false
        
    }
    
    //MARK: - Notification
    
    @objc private func pdfViewScrollViewDidScroll(_ noti: Notification) {
        reloadPopUIWindow()
    }
    
    func pageCountChangedNotification(_ sender: Notification) {
          guard let document = sender.object as? CPDFDocument else {
            return
        }
        botaViewController?.pageCountChangedAction(document: document)
    }
    
    func annotationsAttributeHasChange(_ sender: Notification) {
        guard let dict = sender.object as? [String : Any] else {
            return
        }
        
        if let anno = dict["object"] as? CPDFAnnotation {
            let value = dict["keyPath"] as? String ?? ""
            let didEnd = dict["didEnd"] as? Bool ?? false
            if didEnd {
                if value == CPDFAnnotationBoundsKey {
                    if anno is CPDFSquareAnnotation || anno is CPDFCircleAnnotation {
                        anno.contents = anno.page?.string(for: anno.bounds) ?? ""
                    }
                }
                if anno.km_isMeasure() && anno.contents == nil {
                    anno.contents = anno.string() ?? ""
                }
                var pageIndexes = IndexSet()
                pageIndexes.insert(Int(anno.page.pageIndex()))
                botaViewController?.thumnailViewController?.reloadDataWithIndexs(pageIndexs: pageIndexes)
                
                reloadPopUIWindow()
            } else {
                if value != CPDFAnnotationBoundsKey && value != CPDFAnnotationStartPointKey && value != CPDFAnnotationEndPointKey && value != CPDFAnnotationPathsKey { // 改变bounds(箭头、直线注释 开始点和结束点, 手绘注释的paths)的操作会卡顿,比如移动
                    var pageIndexes = IndexSet()
                    pageIndexes.insert(Int(anno.page.pageIndex()))
                    botaViewController?.thumnailViewController?.reloadDataWithIndexs(pageIndexs: pageIndexes)
                    
                    reloadPopUIWindow()
                }
            }
        }
    }
    
    @objc fileprivate func signatureStateChangeNoti(_ sender: Notification) {
        guard let objecListView = sender.object as? CPDFListView else {
            return
        }
        if listView == objecListView  {
            reloadDigitalSigns()
            
            alertTipViewController.reloadDigitalAlertUI()
            alertTipViewController.reloadAlertUIFrame()
            
            let signatureWidget = listView.editAnnotation
            if let signatureWidgetAnnotation = signatureWidget as? CPDFSignatureWidgetAnnotation {
                let signature = signatureWidgetAnnotation.signature()
                if signature == nil {
                    return
                }
                signaturestateVC.signature = signature
                signaturestateVC.reloadData()
            }
        }
    }
}


//MARK: - KMNThumbnailBaseViewDelegate
extension KMMainViewController: KMNThumbnailBaseViewDelegate {
    func clickThumbnailViewControlle(pageEditVC:KMNThumbnailBaseViewController?,currentIndex:Int)  {
        exitPageEditMode()
        if listView.currentPageIndex != currentIndex {
            listView.go(toPageIndex: currentIndex, animated: true)
        }
        viewManager.isPageEditMode = false
        pdfToolbarController?.clickWithIdentify(KMPDFToolbar_PageEdit_Identifier)
    }
    
    func insertPDFThumbnailViewControlle(pageEditVC: KMNThumbnailBaseViewController?, pdfDocment: CPDFDocument?) {
        if(pdfDocment != nil) {
            insertDocuments.insert(pdfDocment!)
        }
    }
    
    func changeIndexPathsThumbnailViewControlle(pageEditVC: KMNThumbnailBaseViewController?, selectionIndexPaths: Set<IndexPath>, selectionStrings: String) {
        toolbarManager.page_pageInfo_Property.text = selectionStrings
        
        if(toolbarManager.page_pageInfo_Property.creatable == false) {
            toolbarManager.page_pageInfo_Property.creatable = true
        }
        pdfToolbarController?.refreshSecondToolbarItemsState()
    }
    
}

//MARK: - KMNLeftSideViewControllerDelegate
extension KMMainViewController: KMNLeftSideViewControllerDelegate {
    func enterPageEditLeftSideViewController(leftSideViewController: KMNLeftSideViewController) {
        if viewManager.isPageEditMode == false {
            viewManager.isPageEditMode = true
            if(pdfToolbarController != nil) {
                kmPDFToolbarControllerDidToolbarItemClicked(pdfToolbarController!, KMPDFToolbar_PageEdit_Identifier)
                pdfToolbarController?.reloadSecondToolbar()
            }
        }
    }
    
    func changeSelectePageLeftSideViewController(leftSideViewController: KMNLeftSideViewController, pageIndex: Int) {
        if(listView.currentPageIndex != pageIndex) {
            listView.go(toPageIndex: pageIndex, animated: true)
        }
    }
    
    func addBookmarkForLeftC(controller: KMNLeftSideViewController, bookmark: CPDFBookmark?, info: [String : Any]?) {
        if let result = info?["result"] as? Bool {
            if result == false {
                if let targetV = listView.superview {
                    _ = KMNCustomAlertView.alertView(message: KMLocalizedString("This page has been bookmarked"), type: .normal_custom, fromView: targetV, point:CGPointMake(targetV.frame.size.width/2, targetV.bounds.size.height-24))
                }
            }
        }
    }
    
    func switchSearchPopWindow(controller: KMNLeftSideViewController) {
        closeLeftPane()
        
        let handdler = controller.searchViewC.handdler
        showSearchPopWindow(type: handdler.type, keyborad: handdler.searchKey, replaceText: handdler.replaceKey, results: handdler.searchResults)
    }
    
    func searchTypeDidChange(controller: KMNLeftSideViewController) {
        let handdler = controller.searchViewC.handdler
        if handdler.type == .replace {
            viewManager.toolMode = .Edit
            updatePDFViewAnnotationMode()
        }
    }
}


//MARK: -
//MARK: -
//MARK: -
//MARK: - 旧代码,需要用到的内容需要拖出来,写好注释

extension KMMainViewController {
     
    internal func removeNotifications() {
        NotificationCenter.default.removeObserver(self)
        
    }
     
    func removeAllAnnotations() {
        let alert = NSAlert()
        alert.messageText = NSLocalizedString("This will permanently remove all annotations. Are you sure to continue?", comment: "")
        alert.addButton(withTitle: NSLocalizedString("Yes", comment:""))
        alert.addButton(withTitle: NSLocalizedString("No", comment:""))
        if (alert.runModal() != .alertFirstButtonReturn) {
            return
        }
        
        DispatchQueue.main.async {
            self.removeAllAnnotationsStore.store(t: self.listView)
        }
    }
    
    @objc func cancelMeasureType() {
        self.hideMeasureFloatingWindows()
        
    }
    
    func hideMeasureFloatingWindows() {
        if distanceMeasureInfoWindowController?.window?.isVisible == true {
            distanceMeasureInfoWindowController?.hideFloatingWindow()
        } else if perimeterMeasureInfoWindowController?.window?.isVisible == true {
            perimeterMeasureInfoWindowController?.hideFloatingWindow()
        } else if areaMeasureInfoWindowController?.window?.isVisible == true {
            areaMeasureInfoWindowController?.hideFloatingWindow()
        }
    }
    
    func showMeasureFloatingWindowsIfNeed() {
        let toolMode = self.listView.toolMode
        if toolMode != .CNoteToolMode {
            return
        }
        let type = self.listView.annotationType
        if type == .measureLine {
            self.distanceMeasureInfoWindowController?.window?.orderFront(nil)
        } else if type == .measurePolyLine {
            self.perimeterMeasureInfoWindowController?.window?.orderFront(nil)
        } else if type == .measurePolyGon {
            self.areaMeasureInfoWindowController?.window?.orderFront(nil)
        } else if type == .measureSquare {
            self.areaMeasureInfoWindowController?.window?.orderFront(nil)
        }
    }
    
    
    // MARK: - 标记密文
    
    func enterRedact() {
        if !IAPProductsManager.default().isAvailableAllFunction(){
            let winC = KMPurchaseCompareWindowController.sharedInstance()
            winC?.kEventName = "Reading_Redact_BuyNow"
            winC?.showWindow(nil)
            return
        }
        
        if self.listView.document?.allowsPrinting == false || self.listView.document?.allowsCopying == false {
            Task {
                _ = await KMAlertTool.runModel(message: KMLocalizedString("This is a secured document. Editing is not permitted."))
            }
            return
        }
        
        if self.hasEnterRedact() {
            self.exitRedact()
            return
        }
        
        
        let ttsWindowC = KMTTSWindowController.share
        if ttsWindowC.pdfView?.document?.documentURL.path == self.listView.document?.documentURL.path {
            if let data = ttsWindowC.window?.isVisible, data {
                ttsWindowC.stopSpeaking()
                ttsWindowC.close()
            }
        }
        NSColorPanel.shared.showsAlpha = false
        
        redactController = KMPDFRedactViewController(url: self.listView.document!.documentURL, password: self.listView.document?.password)
        self.addChild(redactController)
        redactController.view.autoresizingMask = [.width, .height]
        self.listView.isHidden = true
        
        redactController.scaleFactor = self.listView.scaleFactor
        redactController.titleBack = { [weak self] title in
            self?.view.window?.title = title
        }
        redactController.callback = { [weak self] result, currentPageIndex, saveResult, saveUrl in
            self?.listView.go(toPageIndex: self!.redactController.redactPdfView.currentPageIndex, animated: false)
            
            if result == false { // 退出
                self?.exitRedact()
                return
            }
            let controller = self?._getPDFRedactController()
            controller?.redactPdfView.newAddAnnotation.removeAll()
            self?.exitRedact()
            if saveResult {
                let newDocument = CPDFDocument(url: saveUrl)
                if let data = newDocument?.isLocked, data {
                    newDocument?.unlock(withPassword: self?.listView.document?.password ?? "")
                }
                self?.document = newDocument
                self?.listView.document = newDocument
                self?.listView.layoutDocumentView()
            }
        }
        redactController.setCurrentPageIndex(self.listView.currentPageIndex)
    }
    
    func exitRedact() {
    
        
        let controller = self._getPDFRedactController()
        if let data = controller {
            if data.redactPdfView.newAddAnnotation.count > 0 {
                KMAlertTool.runModel(message: "", informative: KMLocalizedString("There are unapplied redactions in this file. Exit will not save redaction."), buttons: [KMLocalizedString("Exit"), KMLocalizedString("Cancel")]) { response in
                    if response == .alertFirstButtonReturn {
                        controller?.redactPdfView.newAddAnnotation.removeAll()
                        self.exitRedact()
                    }
                }
                return
            }
        }
        NSColorPanel.shared.showsAlpha = true
        controller?.redactPdfView.resignMonitor()
        
        controller?.view.removeFromSuperview()
        controller?.removeFromParent()
        
        self.listView.isHidden = false
        self.listView.annotationType = .unkown
    }
    
    func hasEnterRedact() -> Bool {
        return self._getPDFRedactController() != nil
    }
    
    //MARK: - AI
    
    func showAITypeChooseView(aiConfigType: AIConfigType) -> Void {
        
        if (self.document != nil) {
            AIChatInfoManager.defaultManager.currentFilePath = (self.document?.documentURL.path)!
        } else {
            AIChatInfoManager.defaultManager.currentFilePath = ""
        }
        
        let windowVC: AINewConfigWindowController = AINewConfigWindowController.currentWC()
        windowVC.chooseCurFileHandle = {[unowned self] windowVC in
            if AIChatInfoManager.defaultManager.currentFilePath.isEmpty == false {
                let documentArray = NSDocumentController.shared.documents
                var didFileEdit: Bool = false
                var curDoc: KMMainDocument!
                for document in documentArray {
                    if document.fileURL?.path == AIChatInfoManager.defaultManager.currentFilePath {
                        didFileEdit = document.isDocumentEdited
                        curDoc = document as! KMMainDocument
                        break
                    }
                }
                if didFileEdit {
                    let tempFileURL = FileManager.default.temporaryDirectory.appendingPathComponent(AIChatInfoManager.defaultManager.currentFilePath.lastPathComponent)
                    if FileManager.default.fileExists(atPath: tempFileURL.path) {
                        do {
                            try FileManager.default.removeItem(at: tempFileURL)
                            
                        } catch {
                            
                        }
                    }
                    if curDoc != nil {
                        curDoc.mainViewController?.SaveTempPDFDocumentToURLPath(tempPath: tempFileURL.path)
                    }
                }
                windowVC.window?.becomeMain()
            }
        }
        if windowVC.window?.isVisible == true && windowVC.didSetOriginFrame == true {
            
        } else {
            var windowRect = windowVC.window?.frame
            windowRect!.origin.x = NSMaxX(self.view.window!.frame) - (windowRect?.size.width)!
            windowRect!.origin.y = NSMaxY(self.view.window!.frame) - (windowRect?.size.height)! - 64
            windowVC.window?.setFrame(windowRect!, display: true)
            
            windowVC.didSetOriginFrame = true
        }
        windowVC.eventLabel = "AITools_Tbr"
        windowVC.showWindow(nil)
        if (aiConfigType != .none) {
            windowVC.eventLabel = "AITools_Start"
            if self.listView.currentSelection?.string()?.isEmpty == false {
                windowVC.setCurrentPDFSelection(self.listView.currentSelection.string())
            }
            windowVC.chooseAIFunctionWithType(aiConfigType)
        }
    }
    
    @objc func aiTipIconViewShowStateChangeNoti() {
        
    }
    
    //MARK: - 引导
    
    func loadFunctionGuide() -> Void {
        DispatchQueue.main.asyncAfter(deadline: DispatchTime.now() + 1) {
            if self.view.window != nil {
                self.loadOpenFileFunctionGuide(.openFileNormal)
            }
        }
    }
    
    
    func loadOpenFileFunctionGuide(_ showType: KMGuideInfoType) -> Void {
        if showType == .openFileNormal && KMGuideInfoWindowController.availableShow(.openFileNormal) {
            
            self.guideInfoWindowController = KMGuideInfoWindowController.currentWC()
            guard let guideWC = self.guideInfoWindowController else { return }
            
            guideWC.type = .openFileNormal
            //            guideWC.openPanelRect = (self.view.window?.contentView?.convert(leftPanelItem.frame, from: leftPanelItem.superview)) ?? .zero
            guideWC.window?.collectionBehavior = [.canJoinAllSpaces]
            guideWC.normalGuideFinishHandle = { [weak self] windowVC in
                
                
            }
            guideWC.finishHandle = { [weak self] windowVC, type in
                if type == .windowNewFinish ||
                    type == . windowDigitalFinish {
                    self?.checkFirstTrialController()
                }
            }
            guideWC.openFileToggleHandle = { [weak self] windowVC, type in
                self?.checkFirstTrialController()
            }
            var rect = self.view.window!.frame
            rect.size.height -= 20
            guideWC.window?.setFrame(rect, display: false)
            guideWC.window?.minSize = rect.size
            guideWC.window?.maxSize = rect.size
            self.view.window?.addChildWindow(guideWC.window!, ordered: .above)
            guideWC.show()
        } else if showType == .digitalSignGuide && KMGuideInfoWindowController.availableShow(.digitalSignGuide) {
            self.guideInfoWindowController = KMGuideInfoWindowController.currentWC()
            guard let guideWC = self.guideInfoWindowController else { return }
            
            guideWC.type = .digitalSignGuide
            
            guideWC.window?.collectionBehavior = [.canJoinAllSpaces]
            guideWC.finishHandle = { [weak self] windowVC, type in
                self?.checkFirstTrialController()
            }
            var rect = self.view.window!.frame
            rect.size.height -= 20
            guideWC.window?.setFrame(rect, display: false)
            guideWC.window?.minSize = rect.size
            guideWC.window?.maxSize = rect.size
            self.view.window?.addChildWindow(guideWC.window!, ordered: .above)
            guideWC.show()
            
        } else if showType == .pdfCompareGuide && KMGuideInfoWindowController.availableShow(.pdfCompareGuide) {
            DispatchQueue.main.asyncAfter(deadline: DispatchTime.now() + 0.2) {
                self.guideInfoWindowController = KMGuideInfoWindowController.currentWC()
                guard let guideWC = self.guideInfoWindowController else { return }
                
                guideWC.type = .pdfCompareGuide
                
                
                guard let win = self.view.window else {
                    return
                }
                
                guideWC.finishHandle = { [weak self] winC, type in
                    if type == .windowNewFinish {
                        DispatchQueue.main.async {
                            self?.loadOpenFileFunctionGuide(.measureGuide)
                        }
                        return
                    }
                }
                
                guideWC.window?.collectionBehavior = [.canJoinAllSpaces]
                var rect = self.view.window!.frame
                rect.size.height -= 20
                guideWC.window?.setFrame(rect, display: false)
                guideWC.window?.minSize = rect.size
                guideWC.window?.maxSize = rect.size
                self.view.window?.addChildWindow(guideWC.window!, ordered: .above)
                guideWC.show()
            }
        } else if showType == .measureGuide && KMGuideInfoWindowController.availableShow(.measureGuide) {
            DispatchQueue.main.asyncAfter(deadline: DispatchTime.now() + 0.2) {
                self.guideInfoWindowController = KMGuideInfoWindowController.currentWC()
                guard let guideWC = self.guideInfoWindowController else { return }
                guard let _ = self.view.window else {
                    return
                }
                
                guideWC.type = .measureGuide
                
                guideWC.window?.collectionBehavior = [.canJoinAllSpaces]
                var rect = self.view.window?.frame ?? .zero
                rect.size.height -= 20
                guideWC.window?.setFrame(rect, display: false)
                guideWC.window?.minSize = rect.size
                guideWC.window?.maxSize = rect.size
                self.view.window?.addChildWindow(guideWC.window!, ordered: .above)
                guideWC.show()
            }
        } else if showType == .convertGuide && KMGuideInfoWindowController.availableShow(.convertGuide) {
            DispatchQueue.main.asyncAfter(deadline: DispatchTime.now() + 1) {
                self.guideInfoWindowController = KMGuideInfoWindowController.currentWC()
                guard let guideWC = self.guideInfoWindowController else { return }
                
                guideWC.type = .convertGuide
                guard let win = self.view.window else {
                    return
                }
                guideWC.purchaseHandle = { [weak self] windowVC in
#if VERSION_DMG
                    if IAPProductsManager.default().isAvailableAllFunction() {
                        if IAPProductsManager.default().isAvailableAdvancedPDFToOffice() {
                            //Convert:
                            self?.showAllConvertWindow(convertT: .Word)
                        } else {
                            let limitWC = KMPurchaseLimitWindowController.currentLimitWC()
                            limitWC.continueBlock = { windowController in
                                
                            }
                            limitWC.window?.center()
                            limitWC.showWindow(nil)
                        }
                    } else {
                        KMPurchaseCompareWindowController.sharedInstance().showWindow(nil)
                    }
#else
                    if IAPProductsManager.default().isAvailableAllFunction() {
                        if IAPProductsManager.default().isAvailableAdvancedPDFToOffice() {
                            //Convert:
                        } else {
                            var vc = KMToolCompareWindowController(toolType: .Convert, selectNum: 1)
                            vc.showWindow(nil)
                        }
                    } else {
                        KMPurchaseCompareWindowController.sharedInstance().showWindow(nil)
                    }
#endif
                }
                
                guideWC.window?.collectionBehavior = [.canJoinAllSpaces]
                var rect = self.view.window?.frame ?? .zero
                rect.size.height -= 20
                guideWC.window?.setFrame(rect, display: false)
                guideWC.window?.minSize = rect.size
                guideWC.window?.maxSize = rect.size
                self.view.window?.addChildWindow(guideWC.window!, ordered: .above)
                guideWC.show()
            }
        } else {
            
        }
    }
    
    func checkFirstTrialController() -> Void {
#if VERSION_DMG
        //打开文档后引导相关
        if VerificationManager.default().status == .none {
            let appVersion = Bundle.main.infoDictionary?["CFBundleShortVersionString"] as? String ?? ""
            let lastVersion = UserDefaults.standard.object(forKey: "SKLastTrialVersionMainDocumentLaunchedKey") as? String ?? ""
            if lastVersion.isEmpty || lastVersion != appVersion {
                UserDefaults.standard.setValue(appVersion, forKey: "SKLastTrialVersionMainDocumentLaunchedKey")
                UserDefaults.standard.synchronize()
                KMPurchaseCompareWindowController.sharedInstance().showWindow(nil)
            }
        }
#endif
    }
    
    // MARK: - 页面编辑
    
    open func enterPageEdit(_ pages: [Int] = []) {
        if let doc = self.listView.document {
            if doc.allowsCopying == false || doc.allowsPrinting == false {
                KMBaseWindowController.checkPassword(url: doc.documentURL, type: .owner) { result, pwd in
                    if result && pwd.isEmpty == false {
                        self.listView.document?.unlock(withPassword: pwd)
                        
                        Task { @MainActor in
                            self.enterPageEdit(pages)
                        }
                    } else {
                        self.exitPageEdit()
                    }
                }
                return
            }
        }
        //选中page
        var tPages = pages
        if tPages.count == 0 {
            
        }
        
        if (hasEnterPageEdit()) {
            exitPageEdit()
            return
        }
        
        
        
        
        let controller = KMPDFEditViewController(self.listView.document)
        
        controller.selectedPages = tPages
        controller.listView = self.listView
        self.addChild(controller)
        
        controller.view.autoresizingMask = [.width,.height]
        self.listView.isHidden = true
        
        controller.itemClick = { [weak self] index, params in
            if (index == 1) { /// 双击退出
               
                DispatchQueue.main.async {
                    let pageIndex: Int = params.first as! Int
                    self?.listView.go(toPageIndex: pageIndex, animated: true)
                }
            } else if (index == 2) { // 打印
                self?.showPrintWindow(pageRange: KMPrintPageRange(type: .custom, selectPages: params.first as! [Int]))
            }
        }
        controller.documentEditedCallback = { [weak self] params in
            self?.recordIsPDFDocumentEdited()
        }
        
        controller.selectionDidChange = { selectedIndexs in
            var indexSet = IndexSet()
            for indexPath in selectedIndexs {
                indexSet.insert(indexPath.item)
            }
            if indexSet.count != 0 {
            }
        }
    }
    
    open func exitPageEdit() {
        
        let editController = getPDFEditController()
        if (editController == nil) {
            return
        }
        self.listView.annotationType = .highlight
        
        // FIXME: - sdk修复插入特定文档crash后,这行代码可以去掉
 
        editController?.view.removeFromSuperview()
        editController?.removeFromParent()
        
        self.listView.isHidden = false
        self.listView.layoutDocumentView()
        self.view.window?.makeFirstResponder(self.listView)
        
        self.listView.annotationType = .unkown
        
        self.listView.go(toPageIndex: editController!.listViewCurrentIndex, animated: false)
        
         
    }
    
    open func hasEnterPageEdit() -> Bool {
        return self.getPDFEditController() != nil
    }
     
    // MARK: - Private Methods
    
    private func getPDFEditController() -> KMPDFEditViewController? {
        var editController: KMPDFEditViewController?
        for controller in self.children {
            if (controller.isKind(of: KMPDFEditViewController.self)) {
                editController = (controller as! KMPDFEditViewController)
                break
            }
        }
        return editController
    }
    
    private func _getPDFRedactController() -> KMPDFRedactViewController? {
        var controller: KMPDFRedactViewController?
        for childC in self.children {
            if (childC.isKind(of: KMPDFRedactViewController.self)) {
                controller = (childC as! KMPDFRedactViewController)
                break
            }
        }
        return controller
    }
    
    private func addBackgroundMaskView() {
       
        
    }
    
    private func removeBackgroundMaskView() {
        
    }
    
    private func _goToFirstPageForFristAppear() {
        DispatchQueue.main.asyncAfter(wallDeadline: .now()+0.1) {
            self.listView.go(toPageIndex: 0, animated: false)
        }
    }
    
    func isPDFPageCountExceedsLimit(filePath: String) -> Bool {
        let url = URL(fileURLWithPath: filePath)
        guard let document = PDFDocument(url: url) else {
            return false
        }
        
        let pageCount = document.pageCount
        return pageCount > 30
    }
    
    // MARK: - Redact 【标记密文】
    
    func exeRedactConfirm(_ type: KMRedactConfirmType, callback: @escaping () -> ()?) {
        let windowController = KMRedactConfirmWindowController(type)
        self.currentWindowController = windowController
        self.view.window?.beginSheet(windowController.window!)
        windowController.itemClick = { [weak self] index in
            if (index == 2) { /// 取消
                self?.view.window?.endSheet((self?.currentWindowController.window)!)
                self?.currentWindowController = nil
                callback()
                return
            }
            
            self?.view.window?.endSheet((self?.currentWindowController.window)!)
            self?.currentWindowController = nil
            
            let panel = NSSavePanel()
            panel.nameFieldStringValue = "[新文件]"+((self?.listView.document?.documentURL.lastPathComponent) ?? "")
            let button = NSButton.init(checkboxWithTitle: "保存后打开文档", target: nil, action: nil)
            button.state = .on
            panel.accessoryView = button
            panel.isExtensionHidden = true
            panel.beginSheetModal(for: (self?.view.window!)!) { response in
                if response != .OK {
                    callback()
                    return
                }
                
                if (type == .redactOne) {
                    let anno = self!.listView.activeAnnotation
                    if (anno == nil || (anno?.isKind(of: CPDFRedactAnnotation.self)) == false) {
                        callback()
                        return
                    }
                    
                    (anno as! CPDFRedactAnnotation).applyRedaction()
                } else if (type == .redactAll) {
                    self?.listView.document?.applyRedactions()
                } else if (type == .eraserOne) {
                    let anno = self!.listView.activeAnnotation
                    if (anno == nil || (anno?.isKind(of: CPDFRedactAnnotation.self)) == false) {
                        callback()
                        return
                    }
                    
                    anno?.page.erasureRedact(from: anno!.bounds)
                } else if (type == .eraserAll) {
                    KMRedactTools.eraserDocument((self?.listView.document)!) { result, errorAnno in
                        if (result == false) {
                            callback()
                            return
                        }
                    }
                }
                
                self!.listView.document?.write(to: panel.url)
                if (button.state == .on) {
                    NSDocumentController.shared.openDocument(withContentsOf: panel.url!, display: true) { document, alreadyOpen, error in
                        
                    }
                } else {
                    NSWorkspace.shared.activateFileViewerSelecting([panel.url!])
                }
                callback()
            }
        }
    }
    
    // MARK: - Secure 【安全】
     
    
    public func hiddenSecureLimitTip() {
        self.secureAlertView?.removeFromSuperview()
        self.secureAlertView = nil
    }
     
    override func mouseMoved(with event: NSEvent) {
        self.view.window?.mouseMoved(with: event)
    }
    
    func savePageNumberIfNeed() {
        if (KMPreferenceManager.shared.openLastUnlockedDocumentWhenAppStart) {
            let scaleFactor = self.listView.scaleFactor ?? 0
            if scaleFactor <= 0 {
                return
            }
            if self.listView.document != nil {
                KMPreferenceManager.shared.setPageNumber(self.listView.currentPageIndex, forKey: self.listView.document.documentURL.path)
                KMPreferenceManager.shared.setPageScale(Float(self.listView.scaleFactor), forKey: self.listView.document.documentURL.path)
            }
        }
    }
    
    
    // MARK: - 显示加密弹窗
    
    public func showSecureWindow(_ url: URL) {
        self.securityWindowController = KMSecurityWindowController(windowNibName: "KMSecurityWindowController")
        guard let securityWindowController = securityWindowController else { return }
        
        securityWindowController.documentURL = self.listView.document?.documentURL
        securityWindowController.batchAction = { [unowned self] controller, files in
            self.view.window?.endSheet((securityWindowController.window)!)
            
            
            let batchWindowController = KMBatchOperateWindowController.sharedWindowController
            let batchOperateFile = KMBatchOperateFile(filePath: self.document?.documentURL.path ?? "", type: .AddPassword)
            batchWindowController.switchToOperateType(.AddPassword, files: [batchOperateFile])
            batchWindowController.window?.makeKeyAndOrderFront("")
        }
        
        securityWindowController.doneAction = { [unowned self] controller, options, attribute in
            let openPanel = NSOpenPanel()
            openPanel.canChooseFiles = false
            openPanel.canChooseDirectories = true
            openPanel.canCreateDirectories = true
            openPanel.beginSheetModal(for: NSWindow.currentWindow()) { (result) in
                if result == NSApplication.ModalResponse.OK {
                    for fileURL in openPanel.urls {
                        let document = CPDFDocument(url: self.document?.documentURL)
                        if document != nil {
                            document!.setDocumentAttributes(attribute)
                            
                            let path = fileURL.path.stringByAppendingPathComponent(url.deletingPathExtension().lastPathComponent) + "_SetPassword" + "." + url.pathExtension
                            let success = document!.write(to: NSURL(fileURLWithPath: path) as URL, withOptions: options)
                            if success {
                                self.view.window?.endSheet((securityWindowController.window)!)
                                
                                NSWorkspace.shared.activateFileViewerSelecting([URL(fileURLWithPath: path)])
                            }
                        }
                    }
                }
            }
        }
        
        securityWindowController.cancelAction = { [unowned self] controller in
            self.view.window?.endSheet((securityWindowController.window)!)
        }
        NSWindow.currentWindow().beginSheet(securityWindowController.window!)
    }
    
    // MARK: - 保存文档
    
    internal func needSaveDocument() -> Bool {
        if (self.isPDFDocumentEdited) {
            return self.isPDFDocumentEdited
        }
        if (self.needSave) {
            return self.needSave
        }
        
        let document: KMMainDocument? = self.myDocument as? KMMainDocument
        if (document?.isDocumentEdited == nil || document?.isDocumentEdited == false) {
            return false
        }
        return true
    }
    
    internal func saveDocument(overlookDocumentIfEdited overlook: Bool = false) {
        let document: KMMainDocument? = self.myDocument as? KMMainDocument
        if (overlook) {
            document?.save(nil)
            return
        }
        if (self.isPDFDocumentEdited) {
            self.clearIsPDFDocumentEdited()
            self.needSave = false
            document?.save(nil)
            return
        }
        if (document?.isDocumentEdited == nil || document?.isDocumentEdited == false) {
            return
        }
        
        document?.save(nil)
    }
    
    internal func asyncSaveDocument(overlookDocumentIfEdited overlook: Bool = false, callback:@escaping KMCommonBlock) {
        let document: KMMainDocument? = self.myDocument as? KMMainDocument
        if (overlook) {
            DispatchQueue.main.async {
                document?.save(nil)
                callback()
            }
            return
        }
        if (self.isPDFDocumentEdited) {
            self.clearIsPDFDocumentEdited()
            self.needSave = false
            DispatchQueue.main.async {
                document?.save(nil)
                callback()
            }
            return
        }
        if (document?.isDocumentEdited == nil || document?.isDocumentEdited == false) {
            callback()
            return
        }
        
        DispatchQueue.main.async {
            document?.save(nil)
            callback()
        }
    }
    
    internal func saveDocumentWithProgressAlert(callback:@escaping KMCommonBlock) {
        // 显示进度
        AutoSaveManager.manager.isSaving = true
        self.showProgressWindow(message: NSLocalizedString("Save", comment: "") + "PDF")
        self.progressC?.maxValue = 3.0
        self.progressC?.increment(by: 1.0)
        // 保存文档
        self.asyncSaveDocument { [weak self] params in
            // 执行进度 [假进度]
            self?.progressC?.increment(by: 1.0)
            self?.progressC?.increment(by: 1.0)
            
            DispatchQueue.main.asyncAfter(deadline: .now()+0.1) {
                // 隐藏进度
                self?.hiddenProgressWindow()
                DispatchQueue.main.asyncAfter(deadline: .now()+1) {
                    AutoSaveManager.manager.isSaving = false
                }
                // 回调
                callback()
            }
        }
    }
    func SaveTempPDFDocumentToURLPath(tempPath: String) {
        self.document?.write(toFile: tempPath)
    }
    
    // MARK: - 定时保存
    
    func addAutoSaveEvent() {
        if (self.autoSaveTimer != nil) {
            self.autoSaveTimer?.invalidate()
            self.autoSaveTimer = nil
        }
        
        if self.document != nil {
            self.autoSaveTimer = Timer.scheduledTimer(withTimeInterval: AutoSaveManager.manager.timeInterval * 60, repeats: true, block: { [weak self] timer in
                self?.autoSaveTimerAction(timer)
            })
        }
        self.checkAutoSaveInfo()
    }
    
    func checkAutoSaveInfo() {
        guard let cnt = AutoSaveManager.manager.autoSavePaths?.count, cnt > 0 else {
            return
        }
        if AutoSaveManager.manager.autoSaveAlertShow {
            return
        }
        
        AutoSaveManager.manager.autoSaveDidEndAction = false
        AutoSaveManager.manager.autoSaveAlertShow = true
        
        let blockSaveWindow = AutoSavePopController()
        blockSaveWindow.cancelHandle = { [weak self] windowController in
            AutoSaveManager.manager.autoSaveDidEndAction = true
            AutoSaveManager.manager.clearCache()
            self?.km_quick_endSheet()
        }
        
        blockSaveWindow.confirmHandle = { [weak self] windowController in
            self?.km_quick_endSheet()
            self?.saveAutoSaveInfo()
        }
        self.km_beginSheet(windowC: blockSaveWindow)
    }
    
    func saveAutoSaveInfo() {
        let openPanel = NSOpenPanel()
        openPanel.canChooseDirectories = true
        openPanel.canChooseFiles = false
        openPanel.allowsMultipleSelection = false
        let win = NSApp.keyWindow != nil ? NSApp.keyWindow : self.view.window
        openPanel.beginSheetModal(for: win!) { result in
            if (result == .OK)  {
                let folderPath = openPanel.url?.path ?? openPanel.url?.absoluteString
                for path in AutoSaveManager.manager.opendPaths ?? [] {
                    let _path = path as? String
                    var newPath = "\(folderPath ?? "")/\(_path?.lastPathComponent ?? "")"
                    newPath = self.getValidFilePath(newPath)
                    do {
                        try FileManager.default.moveItem(atPath: _path ?? "", toPath: newPath)
                    } catch {
                        NSWorkspace.shared.activateFileViewerSelecting([URL(fileURLWithPath: newPath)])
                    }
                }
                AutoSaveManager.manager.clearCache()
            }
            AutoSaveManager.manager.autoSaveDidEndAction = true
        }
    }
    
    func autoSaveTimerAction(_ timer: Timer) {
        if (self.document == nil || self.listView.document?.documentURL.path == nil) {
            return
        }
        if AutoSaveManager.manager.autoSaveDidEndAction == false {
            //防止提示弹窗出现后,未进行任何操作又进入自动保存的机制
            return
        }
        
        if let data = self.document?.isLocked, data {
            return
        }
        
        if AutoSaveManager.manager.autoSaveEnabled == false {
            return
        }
        
        let documentArray = NSDocumentController.shared.documents
        var didFileEdit = false
        for doc in documentArray {
            if doc.fileURL?.path == self.document?.documentURL.path {
                didFileEdit = doc.isDocumentEdited
                break
            }
        }
        if (didFileEdit == false) {
            return
        }
        
        AutoSaveManager.manager.isSaving = true
        let savePath = AutoSaveManager.manager.autoSaveWithPath(self.listView.document?.documentURL.path ?? "")
        if (!self.document!.isLocked) {
            self.document?.write(to: URL(fileURLWithPath: savePath))
        }
        DispatchQueue.main.asyncAfter(deadline: .now() + 1.5) {
            AutoSaveManager.manager.isSaving = false
        }
    }
    
    func removeAutoSaveInfo() {
        if self.autoSaveTimer != nil {
            self.autoSaveTimer?.invalidate()
            self.autoSaveTimer = nil
        }
        
        if AutoSaveManager.manager.autoSaveDidEndAction == false {
            //防止提示弹窗出现后,未进行任何操作又进入自动保存的机制
            return
        }
        if AutoSaveManager.manager.autoSaveEnabled == false {
            return
        }
        
        if self.document == nil || self.listView.document?.documentURL.path == nil {
            return
        }
        AutoSaveManager.manager.removeAutoSavePath(self.listView.document?.documentURL.path ?? "")
    }
    
    // MARK: - 选择 PDFDisplay 模式
    public func setPDFDisplay(pdfViewMode: CPDFDisplayViewMode) {
        listView.setDisplay(pdfViewMode)
        
    }
    
    // MARK: - 选择缩放模式
    
    @objc public func selectZoom(_ type: KMPDFZoomType) {
        switch type {
        case .width:
            self.listView.autoScales = true
            break
        case .fit:
            if let pageHeight = self.listView.currentPage()?.size.height, pageHeight > 0 {
                let pdfviewHeight = self.listView.bounds.size.height
                self.listView.scaleFactor = pdfviewHeight/pageHeight
                self.listView.autoScales = false
            }
            
            break
        case .actualSize:
            if self.listView.scaleFactor != 1.0 {
                self.listView.scaleFactor = 1.0
                self.listView.autoScales = false
            }
            break
        }
    }
    
    internal func createPdf(index:Int) {
        
    }
    
    // MARK - Event 监听
    
    private func addEventMonitor() {
        if (self.eventMonitor != nil) {
            self.removeEventMonitor()
        }
        
        self.eventMonitor = NSEvent.addLocalMonitorForEvents(matching: [.scrollWheel, .leftMouseDown, .leftMouseUp]) { [weak self] event in
            if (event.type == .scrollWheel && event.modifierFlags.contains(.option)) { // Alt + 鼠标滚轮
                self?.listView.magnifyWheel(event)
                return nil
            } else if event.type == .leftMouseDown {
                let point = event.locationInView(self?.listView ?? NSView())
                let presentationDrawView = self?.listView.presentationDrawView
                if let data = self?.interactionMode, data == .presentation,CGRectContainsPoint(self?.listView.frame ?? .zero, point),presentationDrawView?.isHidden == true { // 幻灯片模式下
                    if point.x >= (self?.listView.frame.maxX ?? 0) / 2 {
                        let can = self?.listView.canGoToNextPage() ?? false
                        if can {
                            self?.listView.goToNextPage(nil)
                        }
                    } else {
                        let can = self?.listView.canGoToPreviousPage() ?? false
                        if can {
                            self?.listView.goToPreviousPage(nil)
                        }
                    }
                    
                    return nil
                }
            }
            return event
        }
    }
    
    func addKeyEventMonitor() {
        if (self.keyEventMonitor != nil) {
            self.removeKeyEventMonitor()
        }
        keyEventMonitor = NSEvent.addLocalMonitorForEvents(matching: .keyDown) { [weak self] event in
            if event.keyCode == 53 {
                if let data = self?.interactionMode, data == .presentation { // 幻灯片模式下
                    self?.exitFullScreen()
                    return event
                }
                if self?.listView.toolMode == .CEditPDFToolMode {
                    if self != nil {
                        //使用editingSelectionString获取内容文字
                        if self!.listView.editingAreas() != nil {
                            if self!.listView.editingAreas().count > 0 && self!.listView.isEditable() {
                                self!.listView.clearEditingSelectCharItem()
                            } else if self!.listView.editingAreas().count > 0 {
                                if self?.listView.shouAddEditAreaType() == .image ||
                                    self?.listView.shouAddEditAreaType() == .text {
                                }
                                self?.listView.endEditIsRemoveBlock(with: self!.listView.editingAreas().first as? CPDFEditArea)
                                self?.listView.updateEditing([])
                                self?.listView.isEditImage = false
                                self?.listView.setNeedsDisplayPageViewFor(self!.listView.currentPage())
                                if self?.listView.shouAddEditAreaType() == .image {
                                    self?.listView.change([.text, .image])
                                }
                                self?.toggleCloseRightSide()
                            } else if(self?.listView.shouAddEditAreaType() == .image || self!.listView.shouAddEditAreaType() == .text) {
                                if self?.listView.shouAddEditAreaType() == .image ||
                                    self?.listView.shouAddEditAreaType() == .text {
                                }
                                self?.listView.setShouAddEdit([])
                                self?.listView.change([.text, .image])
                                self?.toggleCloseRightSide()
                            }
                            
                        } else {
                            if self?.listView.shouAddEditAreaType() == .image ||
                                self?.listView.shouAddEditAreaType() == .text {
                            }
                        }
                    }
                }
            } else {
                if let data = self?.interactionMode, data == .presentation { // 幻灯片模式下
                    self?.listView.keyDown(with: event)
                    return event
                } else {
                    let cmd = event.modifierFlags.contains(.command)
                    let shift = event.modifierFlags.contains(.shift)
                    if event.keyCode == 6 { // z
                        let editPDFIng = self?.listView.isEditing() ?? false
                        if cmd && shift { // 恢复
                            let can = self?.listView.canEditTextRedo() ?? false
                            if can == false {
                                return event
                            }
                            if editPDFIng {
                                _ = CustomAlertView.alertView(message: NSLocalizedString("Redo", comment: ""), fromView: self!.view, withStyle: .black)
                                
                            }
                        } else if cmd { // 撤回
                            let can = self?.listView.canEditTextUndo() ?? false
                            if can == false {
                                return event
                            }
                            if editPDFIng {
                                _ = CustomAlertView.alertView(message: NSLocalizedString("Undo", comment: ""), fromView: self!.view, withStyle: .black)
                                
                            }
                        }
                    }
                }
            }
            return event
        }
    }
    
    func removeKeyEventMonitor() {
        if (self.keyEventMonitor != nil) {
            KMPrint("removeKeyEventMonitor 已移除事件监听")
            
            NSEvent.removeMonitor(self.keyEventMonitor as Any)
            self.keyEventMonitor = nil
        }
    }
    
    private func removeEventMonitor() {
        if (self.eventMonitor != nil) {
            KMPrint("已移除事件监听")
            
            NSEvent.removeMonitor(self.eventMonitor as Any)
            self.eventMonitor = nil
        }
    }
    
    // MARK: - Tools
    
    func pdfViewCanHorizontalScroll() -> Bool {
        let scroll = self.listView.scroll()
        if (scroll == nil) {
            return false
        }
        
        return scroll?.horizontalScroller?.isHidden == nil ? false : !(scroll!.horizontalScroller!.isHidden)
    }
    
    func pdfViewCanVerticalScroll() -> Bool {
        let scroll = self.listView.scroll()
        if (scroll == nil) {
            return false
        }
        
        return scroll?.verticalScroller?.isHidden == nil ? false : !(scroll!.verticalScroller!.isHidden)
    }
    
    // MARK: - Public Methods
    // 清理数据 [eg. 通知]
    public func clearData() {
        KMThumbnailCache.shared.clearCache()
        
        self.removeNotifications()
        if (self.listView.spellingTag() > 0) {
            NSSpellChecker.shared.closeSpellDocument(withTag: self.listView.spellingTag())
        }
        self.removeAutoSaveInfo()
        
        self.myDocument = nil
        
    }
    
    public func clearSecureOptions() {
        self._secureOptions = nil
        self.documentAttribute = nil
    }
     
    public func clearRemoveSecureFlag() {
        self._removeSecureFlag = false
    }
    
    public func recordIsPDFDocumentEdited(type: KMSubscribeWaterMarkType = .none) {
        km_synchronized(self) {
            self.model.isPDFDocumentEdited = true
            
            if type == .editText || type == .editImage {
              
            }
            
            if let _document = self.myDocument {
                KMTools.setDocumentEditedState(document: _document)
            }
        }
    }
    
    public func clearIsPDFDocumentEdited() {
        km_synchronized(self) {
            self.model.isPDFDocumentEdited = false
        }
    }
    
    func showSnapshots(setups: NSArray?) {
        if self.listView.document != nil {
            for setup in setups ?? [] {
                let swc = KMSnapshotWindowController()
                swc.delegate = self
                swc.setPdfDocument(self.listView.document, setup: setup as? NSDictionary)
                swc.setForceOnTop(self.interactionMode != .normal)
                self.myDocument?.addWindowController(swc)
            }
        }
    }
      
    // MARK: - Noti Actions
    
    internal func documentDidUnlockNotification(_ sender: Notification) {
        if (self.listView.document != nil && self.listView.document.isEqual(to: sender.object)) {
            
            if (self.myDocument == nil) {
                return
            }
            if (self.listView.document.allowsPrinting && self.listView.document.allowsCopying) {
                self.hiddenSecureLimitTip()
            }
            
            let isUnlockFromKeychain = (self.myDocument as? KMMainDocument)?.isUnlockFromKeychain ?? false
            if (isUnlockFromKeychain || self.model.isSaveKeyChain == false) {
                return
            }
            
            let type = KMPreferenceManager.shared.savePasswordType
            if (type == .never) {
                return
            }
            if (type == .always) {
                self.myDocument?.savePasswordInKeychain(self.listView.document.password, self.listView.document)
                return
            }
            
            // 保存到钥匙串
            let alert = NSAlert()
            alert.messageText = NSLocalizedString("Remember Password?", comment: "")
            alert.informativeText = NSLocalizedString("Do you want to save this password in your Keychain?", comment: "")
            alert.addButton(withTitle: NSLocalizedString("Yes", comment: ""))
            alert.addButton(withTitle: NSLocalizedString("No", comment: ""))
            if (alert.runModal() == .alertFirstButtonReturn) { // 保存密码
                self.myDocument?.savePasswordInKeychain(self.listView.document.password, self.listView.document)
                return
            }
        }
    }
    
    internal func applicationWillTerminateNotification(_ sender: Notification) {
        self.savePageNumberIfNeed()
        self.saveDocument()
    }
    
    func CEditPDFToolModeChangeStateUnkownNotification(_ sender: Notification) {
        var editSelectd = false
        if (self.listView.shouAddEditAreaType() == .text || self.listView.shouAddEditAreaType() == .image) && self.listView.toolMode == .CEditPDFToolMode {
            editSelectd = true
        }
        if self.listView.toolMode == .CEditPDFToolMode {
            if editSelectd {
            }
        }
    }
    
    @objc func handlePageChangedNotification(_ sender: Notification) {
        if self.mwcFlags.isSwitchingFullScreen > 0 {
            return
        }
        let page = self.listView.currentPage()
        let pageIndex = page?.pageIndex() ?? 0
      
        
    }
    
    @objc func handleDisplayBoxChangedNotification(_ sender: Notification) {
     
        
    }
    
    
    
}