KMMainViewController.swift 105 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724172517261727172817291730173117321733173417351736173717381739174017411742174317441745174617471748174917501751175217531754175517561757175817591760176117621763176417651766176717681769177017711772177317741775177617771778177917801781178217831784178517861787178817891790179117921793179417951796179717981799180018011802180318041805180618071808180918101811181218131814181518161817181818191820182118221823182418251826182718281829183018311832183318341835183618371838183918401841184218431844184518461847184818491850185118521853185418551856185718581859186018611862186318641865186618671868186918701871187218731874187518761877187818791880188118821883188418851886188718881889189018911892189318941895189618971898189919001901190219031904190519061907190819091910191119121913191419151916191719181919192019211922192319241925192619271928192919301931193219331934193519361937193819391940194119421943194419451946194719481949195019511952195319541955195619571958195919601961196219631964196519661967196819691970197119721973197419751976197719781979198019811982198319841985198619871988198919901991199219931994199519961997199819992000200120022003200420052006200720082009201020112012201320142015201620172018201920202021202220232024202520262027202820292030203120322033203420352036203720382039204020412042204320442045204620472048204920502051205220532054205520562057205820592060206120622063206420652066206720682069207020712072207320742075207620772078207920802081208220832084208520862087208820892090209120922093209420952096209720982099210021012102210321042105210621072108210921102111211221132114211521162117211821192120212121222123212421252126212721282129213021312132213321342135213621372138213921402141214221432144214521462147214821492150215121522153215421552156215721582159216021612162216321642165216621672168216921702171217221732174217521762177217821792180218121822183218421852186218721882189219021912192219321942195219621972198219922002201220222032204220522062207220822092210221122122213221422152216221722182219222022212222222322242225222622272228222922302231223222332234223522362237223822392240224122422243224422452246224722482249225022512252225322542255225622572258225922602261226222632264226522662267226822692270227122722273227422752276227722782279228022812282228322842285228622872288228922902291229222932294229522962297229822992300230123022303230423052306230723082309231023112312231323142315231623172318231923202321232223232324232523262327232823292330233123322333233423352336233723382339234023412342234323442345234623472348234923502351235223532354235523562357235823592360236123622363236423652366236723682369237023712372237323742375237623772378237923802381238223832384238523862387238823892390239123922393239423952396239723982399240024012402240324042405240624072408240924102411241224132414241524162417241824192420242124222423242424252426242724282429243024312432243324342435243624372438243924402441244224432444244524462447244824492450245124522453245424552456245724582459246024612462246324642465246624672468246924702471247224732474247524762477247824792480248124822483248424852486248724882489249024912492249324942495249624972498249925002501250225032504250525062507250825092510251125122513251425152516251725182519252025212522252325242525252625272528252925302531253225332534253525362537253825392540254125422543254425452546
  1. //
  2. // KMMainViewController.swift
  3. // PDF Master
  4. //
  5. // Created by wanjun on 2022/12/15.
  6. //
  7. import Cocoa
  8. @objcMembers class KMMainViewController: NSViewController,CPDFViewDelegate,CPDFListViewDelegate,NSTextFieldDelegate {
  9. @IBOutlet var PDFContendView: NSView!
  10. @IBOutlet var centerContentView: NSView!
  11. @IBOutlet var listView: CPDFListView!
  12. @IBOutlet var secondaryPdfView: CPDFView!
  13. @IBOutlet weak var readContentView: NSView!
  14. @IBOutlet weak var tipCurrentPageBox: KMBox!
  15. @IBOutlet weak var rightView: NSView!
  16. @IBOutlet weak var leftView: NSView!
  17. @IBOutlet weak var mianSplitView: KMSplitView!
  18. @IBOutlet weak var pdfSplitView: KMSplitView!
  19. @IBOutlet weak var pdfContentView: NSView!
  20. @IBOutlet weak var pdfSplitSecondView: NSBox!
  21. @IBOutlet weak var locationPageView: NSView!
  22. @IBOutlet weak var tipLabel: NSTextField!
  23. @IBOutlet weak var toplayoutConstraint: NSLayoutConstraint!
  24. @IBOutlet var childToolbarController: KMToolbarViewController!
  25. @IBOutlet var toolbarController: KMToolbarController!
  26. @IBOutlet weak var toolbarBox: NSBox!
  27. @IBOutlet weak var heightOffset: NSLayoutConstraint!
  28. //阅读模式界面
  29. @IBOutlet weak var readModelView: KMReadModelView!
  30. @IBOutlet weak var bottomAreaView: KMBox!
  31. @IBOutlet weak var readModelViewWidthConstraint: NSLayoutConstraint!
  32. var isReadMode: Bool = false
  33. var readLeftMethodType: BotaType = .None
  34. var readLeftPanelOpen = false
  35. var readLastLeftPanWidth = 0.0
  36. var readLeftViewShowPanel = false
  37. var readRightPanelOpen = false
  38. var readToolbarType: KMToolbarViewType = .None
  39. var readToolbarItemIdentifier: String = ""
  40. var readToolMode: CToolMode = .textToolMode
  41. var readAnnotationType: CAnnotationType = .unkown
  42. var readSubViewType: RightSubViewType = .None
  43. //页码显示器
  44. @IBOutlet weak var pageNumberDisplayView: KMPageNumberDisplayView!
  45. @IBOutlet weak var tipCurrentPageBoxWidthConstraint: NSLayoutConstraint!
  46. private var _needSave = false
  47. var needSave: Bool {
  48. set {
  49. _needSave = newValue
  50. if (_needSave == false) {
  51. self.clearIsPDFDocumentEdited()
  52. self.hiddenSecureSuccessTip()
  53. }
  54. }
  55. get {
  56. return _needSave
  57. }
  58. }
  59. // 标识 pdf 已编辑
  60. fileprivate var _isPDFDocumentEdited = false
  61. // 标识 pdf文字图片已编辑
  62. internal var isPDFTextImageEdited = false
  63. var isPDFDocumentEdited: Bool {
  64. get {
  65. return _isPDFDocumentEdited
  66. }
  67. }
  68. var password: String?
  69. var leftSideViewController: KMLeftSideViewController = KMLeftSideViewController.init(type: KMLeftMethodMode())
  70. var rightSideViewController: KMRightSideViewController!
  71. var searchResults: [KMSearchMode] = []
  72. var mwcFlags: MwcFlags = MwcFlags()
  73. var isShowQuickTour: Bool = false
  74. var document: CPDFDocument?
  75. var myDocument: NSDocument?
  76. var browserWindowController: KMBrowserWindowController?
  77. var cropSettingWindowController: KMCropSettingWindowController!
  78. var currentWindowController: NSWindowController!
  79. //数字签名
  80. var digitalSignController: KMPDFDigitalSignViewController?
  81. let CPDFOfficeLeftSidePaneWidthKey = "CPDFOfficeLeftSidePaneWidthKey"
  82. let CPDFOfficeRightSidePaneWidthKey = "CPDFOfficeRightSidePaneWidthKey"
  83. @IBOutlet weak var topTipBox: NSBox!
  84. @IBOutlet weak var exitFullButton: NSButton!
  85. var hasAddRedact: Bool = false
  86. var functionWidth: Double {
  87. get {
  88. if self.isReadMode {
  89. if !self.isShowBOTA {
  90. return 0
  91. }
  92. }
  93. return 48-4
  94. }
  95. }
  96. var isShowBOTA: Bool = false
  97. let panelWidth = 212.0
  98. let defaultRightWidth = 260.0
  99. var lastLeftPanWidth = 0.0
  100. var lastRightPanWidth = 0.0
  101. var leftPanelOpen: Bool = false
  102. var rightPanelIsOpen = false
  103. var pageNumber: UInt?
  104. var openSecondaryPdfView: KMSecondaryViewController?
  105. var secondaryPdfContentView: NSView?
  106. var lastSplitPDFHeight: Float?
  107. internal var isSaveKeyChain = true
  108. var rightMouseEventing = false
  109. var pdfEditController: KMPDFEditViewController? {
  110. get {
  111. return self.getPDFEditController()
  112. }
  113. }
  114. var autoSaveTimer: Timer?
  115. var progressController: SKProgressController?
  116. private var _documentFirstLoad: Bool = true
  117. var eventMonitor: Any?
  118. var keyEventMonitor: Any?
  119. var mouseRightMenuEvent: NSEvent?
  120. var aiTranslationWindow: KMAITranslationWindowController?
  121. var aiTranslationConfirWC: KMAITranslationConfirmWindowController?
  122. lazy private var homeVC: KMHomeViewController? = {
  123. let vc = KMHomeViewController()
  124. return vc
  125. }()
  126. private var background_mask: NSView?
  127. fileprivate var _secureOptions: [CPDFDocumentWriteOption : Any]?
  128. var secureOptions: [CPDFDocumentWriteOption : Any]? {
  129. get {
  130. return self._secureOptions
  131. }
  132. }
  133. var documentAttribute: [CPDFDocumentAttribute : Any]?
  134. fileprivate var _removeSecureFlag = false
  135. var removeSecureFlag: Bool {
  136. get {
  137. return self._removeSecureFlag
  138. }
  139. }
  140. fileprivate var _saveWatermarkFlag = false
  141. var saveWatermarkFlag: Bool {
  142. get {
  143. return self._saveWatermarkFlag
  144. }
  145. }
  146. deinit {
  147. NotificationCenter.default.removeObserver(self)
  148. self.stopAutoSaveTimer()
  149. self.removeEventMonitor()
  150. self.removeKeyEventMonitor()
  151. }
  152. override func awakeFromNib() {
  153. super.awakeFromNib()
  154. self.addBackgroundMaskView()
  155. // pdfSplitView.frame = NSMakeRect(0, 0, NSWidth(centerContentView.bounds), NSHeight(centerContentView.bounds)-1)
  156. // centerContentView.addSubview(pdfSplitView)
  157. self.PDFContendView.backgroundColor(NSColor.km_init(hex: "FFFFFF"))
  158. listView.delegate = self
  159. listView.pdfListViewDelegate = self
  160. // listView.editingConfig().isSupportMultipleSelectEditingArea = true
  161. if (document != nil) {
  162. // if (self.document!.isLocked) {
  163. //
  164. // } else {
  165. listView.document = document
  166. // }
  167. // listView.document.delegate = self
  168. let autoScale = listView.autoScales
  169. if !autoScale {
  170. listView.scaleFactor = 1.0
  171. }
  172. }
  173. self.initPDFLeftViewVC()
  174. self.initRightSideView()
  175. self.toolbarController.listView = self.listView
  176. }
  177. override func viewDidAppear() {
  178. super.viewDidAppear()
  179. //刷新前一页后一页按钮
  180. self.updateNextAndPreViousButtonState()
  181. KMLightMemberManager.manager.canShowAdvancedView = false
  182. Task { @MainActor in
  183. await KMLightMemberManager.manager.canUseAdvanced(needNetworking: true)
  184. }
  185. // self.addEventMonitor()
  186. self.view.window?.makeFirstResponder(self.listView)
  187. // 更新属性页面的信息
  188. NotificationCenter.default.post(name: KMInfoWindowC.windowDidBecomeMainNotification, object: self.myDocument)
  189. if (self.document == nil) {
  190. return
  191. }
  192. if (self.document!.isLocked == false) {
  193. return
  194. }
  195. if (self.view.window == nil) {
  196. return
  197. }
  198. if (self.password != nil) {
  199. self.isSaveKeyChain = false
  200. self.listView.document.unlock(withPassword: self.password)
  201. return
  202. }
  203. KMPasswordInputWindow.openWindow(window: self.view.window!, url: self.document!.documentURL) { result , password in
  204. if (result == .cancel) {
  205. self.browserWindowController?.browser.closeTab()
  206. return
  207. }
  208. self.isSaveKeyChain = true
  209. self.listView.document = self.document
  210. self.document?.unlock(withPassword: password)
  211. }
  212. }
  213. override func viewWillAppear() {
  214. super.viewWillAppear()
  215. self.reStartAutoSaveTimer()
  216. //是否弹出登录窗口
  217. // self.needShowRegisterView()
  218. }
  219. override func viewWillDisappear() {
  220. super.viewWillDisappear()
  221. // KMPreferenceManager.shared.setPageNumber(self.listView.currentPageIndex, forKey: self.listView.document.documentURL.path)
  222. self.pauseAutoSaveTimer()
  223. self.removeEventMonitor()
  224. }
  225. override func viewWillLayout() {
  226. super.viewWillLayout()
  227. if (KMTools.isFullScreen(self.view.window ?? NSWindow())) { // 全屏
  228. self.exitFullButton.isHidden = false
  229. self.listView.backgroundColor = KMPreferenceManager.shared.displayBackgroundFullScreenColor
  230. } else {
  231. self.exitFullButton.isHidden = true
  232. self.listView.backgroundColor = KMPreferenceManager.shared.displayBackgroundNormalColor
  233. }
  234. }
  235. override func viewDidLoad() {
  236. super.viewDidLoad()
  237. leftSideViewController.mainVC = self
  238. mwcFlags.settingUpWindow = 1
  239. toolbarController.delegate = self
  240. //TODO: 先让项目运行,看后面怎么调整这段逻辑,目前最外层是 KMBrowserWindowController
  241. toolbarBox.contentView = toolbarController.view
  242. // self.childToolbarController.updateType(newType: .Annatiton)
  243. // self.showChildToolbar(showToolbar: true)
  244. // self.toolbarController.editPDFButtonAction(item: NSMenuItem())
  245. if (UserDefaults.standard.object(forKey: CPDFOfficeLeftSidePaneWidthKey) != nil) {
  246. UserDefaults.standard.set(256, forKey: CPDFOfficeLeftSidePaneWidthKey)
  247. UserDefaults.standard.synchronize()
  248. }
  249. if (UserDefaults.standard.object(forKey: CPDFOfficeRightSidePaneWidthKey) != nil) {
  250. UserDefaults.standard.set(256, forKey: CPDFOfficeRightSidePaneWidthKey)
  251. UserDefaults.standard.synchronize()
  252. }
  253. let position = mianSplitView.maxPossiblePositionOfDivider(at: 1)
  254. mianSplitView.setPosition(position, ofDividerAt: 0)
  255. mianSplitView.setPosition(mianSplitView.minPossiblePositionOfDivider(at: 0), ofDividerAt: 0)
  256. pdfSplitView.setPosition(mianSplitView.maxPossiblePositionOfDivider(at: 1), ofDividerAt: 0)
  257. self.locationPageView.wantsLayer = true;
  258. self.locationPageView.layer?.backgroundColor = NSColor(red: 189.0/255.0, green: 223.0/255.0, blue: 253.0/255.0, alpha: 1).cgColor
  259. self.tipLabel.stringValue = NSLocalizedString("Please use the scroll bar, thumbnail tool to locate the target page, click or box the area to select the target range.", comment: "")
  260. if (KMPreferenceManager.shared.openLastUnlockedDocumentWhenAppStart) {
  261. if (self.listView.document != nil) {
  262. let pageNumber = KMPreferenceManager.shared.getPageNumber(forKey: self.listView.document.documentURL.path)
  263. let pageScale = KMPreferenceManager.shared.getPageScale(forKey: self.listView.document.documentURL.path)
  264. if (pageNumber != nil && pageNumber! >= 0 && pageNumber! < self.listView.document.pageCount) {
  265. DispatchQueue.main.asyncAfter(deadline: .now() + 0.5) {
  266. if (pageScale != nil) {
  267. self.listView.scaleFactor = CGFloat(pageScale!)
  268. }
  269. self.listView.go(toPageIndex: pageNumber!, animated: false)
  270. }
  271. } else {
  272. self._goToFirstPageForFristAppear()
  273. }
  274. }
  275. } else {
  276. self._goToFirstPageForFristAppear()
  277. }
  278. //阅读页面
  279. readModelView.delegate = self
  280. pageNumberDisplayView.delegate = self
  281. tipCurrentPageBox.moveCallback = { [unowned self] mouseEntered, mouseBox in
  282. if mouseEntered {
  283. self.pageNumberDisplayView.hover = true
  284. // self.updatePageIndicatoreType()
  285. } else {
  286. self.pageNumberDisplayView.hover = false
  287. // self.updatePageIndicatoreType()
  288. }
  289. }
  290. NotificationCenter.default.addObserver(self, selector: #selector(rename(_:)), name: NSNotification.Name.init(rawValue: "KMTabControllerRename"), object: nil)
  291. NotificationCenter.default.addObserver(self, selector: #selector(closeTab(_:)), name: NSNotification.Name.init(rawValue: "KMTabControllerCloseTabs"), object: nil)
  292. NotificationCenter.default.addObserver(self, selector: #selector(showInFinder(_:)), name: NSNotification.Name.init(rawValue: "KMTabControllerShowInFinder"), object: nil)
  293. NotificationCenter.default.addObserver(self, selector: #selector(preferenceDidChangeNotification), name: KMPreferenceManager.didChangeNotification, object: nil)
  294. NotificationCenter.default.addObserver(self, selector: #selector(documentDidUnlockNotification), name: Notification.Name("CPDFDocumentDidUnlockNotification"), object: nil)
  295. NotificationCenter.default.addObserver(self, selector: #selector(applicationWillTerminateNotification), name: NSApplication.willTerminateNotification, object: nil)
  296. NotificationCenter.default.addObserver(self, selector: #selector(KMPDFViewCurrentPageDidChangedNotification), name: NSNotification.Name.init(rawValue: "KMPDFViewCurrentPageDidChanged"), object: nil)
  297. NotificationCenter.default.addObserver(self, selector: #selector(CPDFDocumentPageCountChangedNotification), name: NSNotification.Name.init(rawValue: "CPDFDocumentPageCountChangedNotification"), object: nil)
  298. NotificationCenter.default.addObserver(self, selector: #selector(CEditPDFToolModeChangeStateUnkownNotification), name: Notification.Name.init("CEditPDFToolModeChangeStateUnkown"), object: nil)
  299. self.autoSaveTimeStartOrStopIfNeed()
  300. self.toolbarController.selectItem(KMDocumentAnnotationToolbarItemIdentifier)
  301. self.closeRightPane()
  302. self.addKeyEventMonitor()
  303. //检测OCR包是否需要更新
  304. #if VERSION_DMG
  305. KMResourceDownloadManager.manager.checkDocumentAIVersion()
  306. #endif
  307. }
  308. //MARK: - KMToolbarViewControllerDelegate
  309. //MARK: - PDFListView
  310. func initPDFLeftViewVC() {
  311. var frame = self.leftView.frame
  312. frame.size.width += 44
  313. self.leftView.frame = frame
  314. leftSideViewController.listView = self.listView ?? CPDFListView()
  315. leftSideViewController.view.frame = CGRect(x: 0, y:0 , width: self.leftView.frame.size.width, height: self.leftView.frame.size.height)
  316. leftSideViewController.view.autoresizingMask = [.height,.width]
  317. leftSideViewController.delegate = self
  318. self.leftView.addSubview(leftSideViewController.view)
  319. }
  320. func initRightSideView() {
  321. self.rightSideViewController = KMRightSideViewController.init()
  322. self.rightSideViewController.view.frame = CGRect(x: 0, y: 0, width: self.rightView.frame.width, height: self.rightView.frame.size.height)
  323. self.rightSideViewController.view.autoresizingMask = [.height,.width]
  324. self.rightSideViewController.listView = self.listView
  325. // self.rightSideViewController.view.isHidden = true
  326. self.rightSideViewController.isHidden = true
  327. self.rightSideViewController.delegate = self
  328. self.rightView.addSubview(self.rightSideViewController.view)
  329. self.rightSideViewController.propertyDidChange = {
  330. [weak self] (model: AnyObject?) in
  331. let topBarView = self?.toolbarController.fetchTopBarView()
  332. if (topBarView == nil || ((topBarView?.isKind(of: KMWatermarkAdjectiveTopBarView.self)) == false)) {
  333. return
  334. }
  335. /// Bates码、页眉页脚、背景、水印
  336. if (model == nil) {
  337. (topBarView as! KMWatermarkAdjectiveTopBarView).isCanApply(can: false)
  338. } else {
  339. if ((model?.isKind(of: KMBatesModel.self))!) {
  340. if ((model as! KMBatesModel).hasVaild) {
  341. (topBarView as! KMWatermarkAdjectiveTopBarView).isCanApply(can: true)
  342. } else {
  343. (topBarView as! KMWatermarkAdjectiveTopBarView).isCanApply(can: false)
  344. }
  345. } else if ((model?.isKind(of: KMHeaderFooterModel.self))!) {
  346. if ((model as! KMHeaderFooterModel).hasVaild) {
  347. (topBarView as! KMWatermarkAdjectiveTopBarView).isCanApply(can: true)
  348. } else {
  349. (topBarView as! KMWatermarkAdjectiveTopBarView).isCanApply(can: false)
  350. }
  351. } else if ((model?.isKind(of: KMBackgroundModel.self))!) {
  352. (topBarView as! KMWatermarkAdjectiveTopBarView).isCanApply(can: true)
  353. } else if ((model?.isKind(of: KMWatermarkModel.self))!) {
  354. (topBarView as! KMWatermarkAdjectiveTopBarView).isCanApply(can: true)
  355. }
  356. }
  357. }
  358. }
  359. // MARK: Private Methods
  360. internal func removeNotifications() {
  361. NotificationCenter.default.removeObserver(self)
  362. self.leftSideViewController.clearAnnotationFilterData()
  363. self.leftSideViewController.clearNotification()
  364. }
  365. func checkShouldAutoOpenLeftVC() {
  366. if (KMPreferenceManager.shared.leftSideNeedCloseWhenOpenFile()) {
  367. return
  368. }
  369. if (KMPreferenceManager.shared.leftSideDisplayType == .showOutlineIfHas) {
  370. let outlineRoot = self.listView.document.outlineRoot()
  371. let hasOutline = (outlineRoot != nil && outlineRoot!.numberOfChildren > 0)
  372. if (hasOutline == false) {
  373. return
  374. }
  375. DispatchQueue.main.asyncAfter(deadline: .now() + 0.15) {
  376. self.leftSideViewController.refreshMethodType(methodType: .Outline)
  377. }
  378. return
  379. }
  380. DispatchQueue.main.asyncAfter(deadline: .now() + 0.15) {
  381. let selectedIndex = UserDefaults.standard.integer(forKey: "KMBOTASelectedIndexKey")
  382. let thumai = KMLeftMethodMode()
  383. if selectedIndex == 0 {
  384. thumai.methodType = .Thumbnail
  385. } else if selectedIndex == 1 {
  386. thumai.methodType = .Outline
  387. } else if selectedIndex == 2 {
  388. thumai.methodType = .BookMark
  389. } else if selectedIndex == 3 {
  390. thumai.methodType = .Annotation
  391. } else if selectedIndex == 4 {
  392. thumai.methodType = .Search
  393. }
  394. self.leftSideViewController.refreshMethodType(methodType: thumai.methodType)
  395. }
  396. }
  397. func applyLeftSideWidth(_ leftSideWidth: CGFloat, rightSideWidth: CGFloat) -> Void {
  398. mianSplitView.setPosition(leftSideWidth, ofDividerAt: 0)
  399. mianSplitView.setPosition(mianSplitView.maxPossiblePositionOfDivider(at: 1) - mianSplitView.dividerThickness - rightSideWidth, ofDividerAt: 1)
  400. lastLeftPanWidth = leftSideWidth
  401. lastRightPanWidth = rightSideWidth
  402. }
  403. //MARK: 动画 暂未接入
  404. func animateSplitView(to position: CGFloat) {
  405. let frame1 = NSRect(x: 0, y: 0, width: position, height: mianSplitView.frame.height)
  406. let frame2 = NSRect(x: position, y: 0, width: mianSplitView.frame.width - position, height: mianSplitView.frame.height)
  407. // 创建一个新的动画上下文
  408. let animationContext = NSAnimationContext.current
  409. animationContext.duration = 0.5
  410. animationContext.timingFunction = CAMediaTimingFunction(name: .easeInEaseOut)
  411. // 启用隐式动画
  412. NSAnimationContext.current.allowsImplicitAnimation = true
  413. // 移动分隔条
  414. mianSplitView.setPosition(position, ofDividerAt: 0)
  415. mianSplitView.subviews[0].frame = frame1
  416. mianSplitView.subviews[1].frame = frame2
  417. }
  418. internal var removeAllAnnotationsStore = KMPDFViewRemoveAllAnnotationsStore()
  419. internal func removeAllAnnotations() {
  420. let alert = NSAlert()
  421. alert.messageText = NSLocalizedString("This will permanently remove all annotations. Are you sure to continue?", comment: "")
  422. alert.addButton(withTitle: NSLocalizedString("Yes", comment:""))
  423. alert.addButton(withTitle: NSLocalizedString("No", comment:""))
  424. if (alert.runModal() != .alertFirstButtonReturn) {
  425. return
  426. }
  427. DispatchQueue.main.async {
  428. self.removeAllAnnotationsStore.store(t: self.listView)
  429. }
  430. }
  431. // MARK: Set Methods
  432. var setDocument: CPDFDocument? {
  433. get {
  434. return document
  435. }
  436. set {
  437. if document != newValue {
  438. document = newValue
  439. }
  440. listView.document = document
  441. // listView.document.delegate = self
  442. self.listView.layoutDocumentView()
  443. }
  444. }
  445. var setPageNumber: UInt {
  446. get {
  447. return pageNumber!
  448. }
  449. set {
  450. let pageCount = listView.document.pageCount
  451. var value = newValue
  452. if value > pageCount {
  453. value = pageCount
  454. }
  455. if value > 0 && listView.currentPage().pageIndex() != value-1 {
  456. listView.go(to: listView.document.page(at: value-1))
  457. }
  458. if pageNumber != value {
  459. pageNumber = value
  460. }
  461. }
  462. }
  463. // MARK: - 标记密文
  464. func enterRedact() {
  465. if self.listView.document.allowsPrinting == false || self.listView.document.allowsCopying == false {
  466. Task {
  467. _ = await KMAlertTool.runModel(message: KMLocalizedString("This is a secured document. Editing is not permitted.", nil))
  468. }
  469. return
  470. }
  471. if self.hasEnterRedact() {
  472. self.exitRedact()
  473. return
  474. }
  475. let ttsWindowC = KMTTSWindowController.share
  476. if ttsWindowC.pdfView?.document?.documentURL.path == self.listView.document.documentURL.path {
  477. if let data = ttsWindowC.window?.isVisible, data {
  478. ttsWindowC.stopSpeaking()
  479. ttsWindowC.close()
  480. }
  481. }
  482. NSColorPanel.shared.showsAlpha = false
  483. let controller = KMPDFRedactViewController(url: self.listView.document!.documentURL, password: self.listView.document.password)
  484. self.addChild(controller)
  485. self.PDFContendView.addSubview(controller.view)
  486. controller.view.frame = self.PDFContendView.bounds
  487. controller.view.autoresizingMask = [.width, .height]
  488. self.listView.isHidden = true
  489. controller.scaleFactor = self.listView.scaleFactor
  490. controller.titleBack = { [weak self] title in
  491. self?.view.window?.title = title
  492. }
  493. controller.callback = { [weak self] result, currentPageIndex, saveResult, saveUrl in
  494. if result == false { // 退出
  495. self?.exitRedact()
  496. return
  497. }
  498. let controller = self?._getPDFRedactController()
  499. controller?.redactPdfView.newAddAnnotation.removeAll()
  500. self?.exitRedact()
  501. if saveResult {
  502. let newDocument = CPDFDocument(url: saveUrl)
  503. if let data = newDocument?.isLocked, data {
  504. newDocument?.unlock(withPassword: self?.listView.document.password ?? "")
  505. }
  506. self?.document = newDocument
  507. self?.listView.document = newDocument
  508. self?.listView.layoutDocumentView()
  509. }
  510. }
  511. }
  512. func exitRedact() {
  513. let controller = self._getPDFRedactController()
  514. if let data = controller {
  515. if data.redactPdfView.newAddAnnotation.count > 0 {
  516. KMAlertTool.runModel(message: "", informative: KMLocalizedString("There are unapplied redactions in this file. Exit will not save redaction.", nil), buttons: [KMLocalizedString("Exit", nil), KMLocalizedString("Cancel", nil)]) { response in
  517. if response == .alertFirstButtonReturn {
  518. data.redactPdfView.newAddAnnotation.removeAll()
  519. self.exitRedact()
  520. }
  521. }
  522. return
  523. }
  524. }
  525. NSColorPanel.shared.showsAlpha = true
  526. self.toolbarController.findItem(KMDocumentRedactToolbarItemIdentifier)?.isSelected = false
  527. // self.toolbarController.toolbarType = .None
  528. // self.listView.toolMode = .moveToolMode
  529. controller?.redactPdfView.resignMonitor()
  530. controller?.view.removeFromSuperview()
  531. controller?.removeFromParent()
  532. self.listView.isHidden = false
  533. // self.listView.layoutDocumentView()
  534. // self.view.window?.makeFirstResponder(self.listView)
  535. self.listView.annotationType = .unkown
  536. }
  537. func hasEnterRedact() -> Bool {
  538. return self._getPDFRedactController() != nil
  539. }
  540. // MARK: - 页面编辑
  541. open func enterPageEdit(_ pages: [Int] = []) {
  542. //选中page
  543. var tPages = pages
  544. if tPages.count == 0 {
  545. tPages = self.leftSideViewController.selectPages ?? [self.listView.currentPageIndex]
  546. }
  547. if (hasEnterPageEdit()) {
  548. exitPageEdit()
  549. return
  550. }
  551. if (self.toolbarController != nil && self.toolbarController.mainToolBarView != nil) {
  552. let toolBarView: KMToolbarViewController = self.toolbarController.mainToolBarView!
  553. for (key, value) in toolBarView.toolbarItems {
  554. if (key == KMRightControlToolbarItemIdentifier || key == KMLeftControlToolbarItemIdentifier) {
  555. (value as! KMToolbarItemView).unEnabled = true
  556. }
  557. }
  558. }
  559. #if VERSION_DMG
  560. let controller = KMPDFEditViewController_dmg(self.listView.document)
  561. #else
  562. let controller = KMPDFEditViewController(self.listView.document)
  563. #endif
  564. controller.selectedPages = tPages
  565. controller.listView = self.listView
  566. self.addChild(controller)
  567. self.PDFContendView.addSubview(controller.view)
  568. controller.view.frame = self.PDFContendView.bounds
  569. controller.view.autoresizingMask = [.width,.height]
  570. self.listView.isHidden = true
  571. controller.itemClick = { [weak self] index, params in
  572. if (index == 1) { /// 双击退出
  573. self?.enterEditMode(self!.leftSideViewController, [])
  574. DispatchQueue.main.async {
  575. let pageIndex: Int = params.first as! Int
  576. self?.listView.go(toPageIndex: pageIndex, animated: true)
  577. }
  578. } else if (index == 2) { // 打印
  579. self?.showPrintWindow(pageRange: KMPrintPageRange(type: .custom, selectPages: params.first as! [Int]))
  580. }
  581. }
  582. controller.documentEditedCallback = { [weak self] params in
  583. self?.recordIsPDFDocumentEdited()
  584. // self?.needSave = true
  585. if let data = params.first as? KMPageEditType {
  586. self?.recordSaveWatermarkFlag(type: data.toSubscribeWaterMarkType())
  587. } else {
  588. self?.recordSaveWatermarkFlag()
  589. }
  590. }
  591. controller.selectionDidChange = { [weak self] selectedIndexs in
  592. var indexSet = IndexSet()
  593. for indexPath in selectedIndexs {
  594. indexSet.insert(indexPath.item)
  595. }
  596. if indexSet.count != 0 {
  597. // self?.leftSideViewController.thumbnailViewController.selectPages(indexs: indexSet, needScroll: true)
  598. // self?.listView.go(toPageIndex: indexSet.first!, animated: false)
  599. }
  600. }
  601. }
  602. open func exitPageEdit() {
  603. if (self.toolbarController != nil && self.toolbarController.mainToolBarView != nil) {
  604. let toolBarView: KMToolbarViewController = self.toolbarController.mainToolBarView!
  605. for (key, value) in toolBarView.toolbarItems {
  606. if (key == KMRightControlToolbarItemIdentifier || key == KMLeftControlToolbarItemIdentifier) {
  607. (value as! KMToolbarItemView).unEnabled = false
  608. }
  609. }
  610. }
  611. let editController = getPDFEditController()
  612. if (editController == nil) {
  613. return
  614. }
  615. self.listView.annotationType = .highlight
  616. editController?.view.removeFromSuperview()
  617. editController?.removeFromParent()
  618. self.listView.isHidden = false
  619. self.listView.layoutDocumentView()
  620. self.view.window?.makeFirstResponder(self.listView)
  621. self.listView.annotationType = .unkown
  622. self.listView.go(toPageIndex: editController!.listViewCurrentIndex, animated: false)
  623. }
  624. open func hasEnterPageEdit() -> Bool {
  625. return self.getPDFEditController() != nil
  626. }
  627. // MARK: - Private Methods
  628. private func getPDFEditController() -> KMPDFEditViewController? {
  629. var editController: KMPDFEditViewController?
  630. for controller in self.children {
  631. if (controller.isKind(of: KMPDFEditViewController.self)) {
  632. editController = (controller as! KMPDFEditViewController)
  633. break
  634. }
  635. }
  636. return editController
  637. }
  638. private func _getPDFRedactController() -> KMPDFRedactViewController? {
  639. var controller: KMPDFRedactViewController?
  640. for childC in self.children {
  641. if (childC.isKind(of: KMPDFRedactViewController.self)) {
  642. controller = (childC as! KMPDFRedactViewController)
  643. break
  644. }
  645. }
  646. return controller
  647. }
  648. private func addBackgroundMaskView() {
  649. self.removeBackgroundMaskView()
  650. if let superview = self.mianSplitView.superview {
  651. let view = NSView()
  652. superview.addSubview(view)
  653. view.frame = superview.bounds
  654. view.autoresizingMask = [.width, .height]
  655. view.wantsLayer = true
  656. view.layer?.backgroundColor = .white
  657. self.background_mask = view
  658. }
  659. }
  660. private func removeBackgroundMaskView() {
  661. self.background_mask?.removeFromSuperview()
  662. self.background_mask = nil
  663. }
  664. private func _goToFirstPageForFristAppear() {
  665. DispatchQueue.main.asyncAfter(wallDeadline: .now()+0.1) {
  666. self.listView.go(toPageIndex: 0, animated: false)
  667. }
  668. }
  669. func isFileGreaterThan10MB(atPath filePath: String) -> Bool {
  670. let fileManager = FileManager.default
  671. do {
  672. let fileAttributes = try fileManager.attributesOfItem(atPath: filePath)
  673. if let fileSize = fileAttributes[.size] as? UInt64 {
  674. let megabyteSize = fileSize / (1024 * 1024)
  675. return megabyteSize >= 10
  676. }
  677. } catch {
  678. KMPrint("Error: \(error)")
  679. }
  680. return false
  681. }
  682. func isPDFPageCountExceedsLimit(filePath: String) -> Bool {
  683. let url = URL(fileURLWithPath: filePath)
  684. guard let document = PDFDocument(url: url) else {
  685. return false
  686. }
  687. let pageCount = document.pageCount
  688. return pageCount > 30
  689. }
  690. // MARK: Redact 【标记密文】
  691. func exeRedactConfirm(_ type: KMRedactConfirmType, callback: @escaping () -> ()?) {
  692. let windowController = KMRedactConfirmWindowController(type)
  693. self.currentWindowController = windowController
  694. self.view.window?.beginSheet(windowController.window!)
  695. windowController.itemClick = { [weak self] index in
  696. if (index == 2) { /// 取消
  697. self?.view.window?.endSheet((self?.currentWindowController.window)!)
  698. self?.currentWindowController = nil
  699. callback()
  700. return
  701. }
  702. self?.view.window?.endSheet((self?.currentWindowController.window)!)
  703. self?.currentWindowController = nil
  704. let panel = NSSavePanel()
  705. panel.nameFieldStringValue = "[新文件]"+(self?.listView.document.documentURL.lastPathComponent)!
  706. let button = NSButton.init(checkboxWithTitle: "保存后打开文档", target: nil, action: nil)
  707. button.state = .on
  708. panel.accessoryView = button
  709. panel.isExtensionHidden = true
  710. panel.beginSheetModal(for: (self?.view.window!)!) { response in
  711. if response != .OK {
  712. callback()
  713. return
  714. }
  715. if (type == .redactOne) {
  716. let anno = self!.listView.activeAnnotation
  717. if (anno == nil || (anno?.isKind(of: CPDFRedactAnnotation.self)) == false) {
  718. callback()
  719. return
  720. }
  721. (anno as! CPDFRedactAnnotation).applyRedaction()
  722. } else if (type == .redactAll) {
  723. self?.listView.document.applyRedactions()
  724. } else if (type == .eraserOne) {
  725. let anno = self!.listView.activeAnnotation
  726. if (anno == nil || (anno?.isKind(of: CPDFRedactAnnotation.self)) == false) {
  727. callback()
  728. return
  729. }
  730. anno?.page.erasureRedact(from: anno!.bounds)
  731. } else if (type == .eraserAll) {
  732. KMRedactTools.eraserDocument((self?.listView.document)!) { result, errorAnno in
  733. if (result == false) {
  734. callback()
  735. return
  736. }
  737. }
  738. }
  739. self!.listView.document.write(to: panel.url)
  740. if (button.state == .on) {
  741. NSDocumentController.shared.openDocument(withContentsOf: panel.url!, display: true) { document, alreadyOpen, error in
  742. }
  743. } else {
  744. NSWorkspace.shared.activateFileViewerSelecting([panel.url!])
  745. }
  746. callback()
  747. }
  748. }
  749. }
  750. // MARK: Secure 【安全】
  751. public func showSecureSuccessTip() {
  752. let view: NSView = self.view
  753. let tip = KMSecureEncryptSuccessTipView()
  754. let size = NSSize(width: 379, height: 176)
  755. tip.frame = NSMakeRect(view.frame.size.width-size.width-16, view.frame.size.height-size.height-88, size.width, size.height)
  756. tip.autoresizingMask = [.minXMargin, .minYMargin]
  757. view.addSubview(tip)
  758. tip.itemClick = { [weak self] in
  759. self!.hiddenSecureSuccessTip()
  760. }
  761. }
  762. public func hiddenSecureSuccessTip() {
  763. let view: NSView = self.view
  764. var tip: KMSecureEncryptSuccessTipView?
  765. for subview in view.subviews {
  766. if (subview.isKind(of: KMSecureEncryptSuccessTipView.self)) {
  767. tip = (subview as! KMSecureEncryptSuccessTipView)
  768. break
  769. }
  770. }
  771. if (tip == nil) {
  772. return
  773. }
  774. tip?.removeFromSuperview()
  775. }
  776. public func showSecureLimitTip() {
  777. self.hiddenSecureLimitTip()
  778. let view: NSView = self.view
  779. let tip = KMSecureLimitAlertView()
  780. let size = NSSize(width: 379, height: 154)
  781. tip.frame = NSMakeRect(view.frame.size.width-size.width-16, view.frame.size.height-size.height-50, size.width, size.height)
  782. tip.autoresizingMask = [.minXMargin, .minYMargin]
  783. view.addSubview(tip)
  784. tip.itemClick = { [unowned self] index in
  785. if (index == 1) {
  786. self.hiddenSecureLimitTip()
  787. return
  788. }
  789. if (self.listView.document.allowsPrinting == false || self.listView.document.allowsCopying == false) {
  790. KMPasswordInputWindow.openWindow(window: self.view.window!, type: .owner, url: self.listView.document.documentURL) { [weak self] result, password in
  791. if result == .cancel { /// 关闭
  792. return
  793. }
  794. /// 解密成功
  795. self?.hiddenSecureLimitTip()
  796. self?.isSaveKeyChain = false
  797. self?.listView.document.unlock(withPassword: password)
  798. }
  799. return
  800. }
  801. }
  802. }
  803. public func hiddenSecureLimitTip() {
  804. let view: NSView = self.view
  805. var tip: KMSecureLimitAlertView?
  806. for subview in view.subviews {
  807. if (subview.isKind(of: KMSecureLimitAlertView.self)) {
  808. tip = (subview as! KMSecureLimitAlertView)
  809. break
  810. }
  811. }
  812. if (tip == nil) {
  813. return
  814. }
  815. tip?.removeFromSuperview()
  816. }
  817. override func mouseMoved(with event: NSEvent) {
  818. }
  819. func savePageNumberIfNeed() {
  820. if (KMPreferenceManager.shared.openLastUnlockedDocumentWhenAppStart) {
  821. if self.listView.document != nil {
  822. KMPreferenceManager.shared.setPageNumber(self.listView.currentPageIndex, forKey: self.listView.document.documentURL.path)
  823. KMPreferenceManager.shared.setPageScale(Float(self.listView.scaleFactor), forKey: self.listView.document.documentURL.path)
  824. }
  825. }
  826. }
  827. // MARK: -
  828. // MARK: 退出全屏
  829. @IBAction func exitFullScreen(_ sender: Any) {
  830. if (self.view.window == nil) {
  831. return
  832. }
  833. if (KMTools.isFullScreen(self.view.window!)) {
  834. self.view.window?.toggleFullScreen(nil)
  835. }
  836. }
  837. // MARK: -
  838. // MARK: 显示合并窗口
  839. public func showMergeWindow(url: URL? = nil, _ password: String?) {
  840. DispatchQueue.main.async {
  841. if let _url = url {
  842. let document = PDFDocument(url: _url)
  843. let windowController = KMMergeWindowController(document: document!, password: password ?? "")
  844. windowController.oriDucumentUrl = self.listView.document.documentURL
  845. self.currentWindowController = windowController
  846. windowController.cancelAction = { [unowned self] controller in
  847. self.view.window?.endSheet((self.currentWindowController.window)!)
  848. self.currentWindowController = nil
  849. }
  850. self.toolbarController.cancelSelected(KMToolbarToolMergeItemIdentifier)
  851. self.view.window?.beginSheet(windowController.window!)
  852. } else {
  853. let document = PDFDocument(url: self.listView.document.documentURL)
  854. let windowController = KMMergeWindowController(document: document!, password: password ?? "")
  855. self.toolbarController.cancelSelected(KMToolbarToolMergeItemIdentifier)
  856. self.view.window!.km_beginSheet(windowC: windowController)
  857. }
  858. }
  859. }
  860. // MARK: -
  861. // MARR: 显示加密弹窗
  862. public func showSecureWindow(_ url: URL) {
  863. // let windowController = KMSecureEncryptWindowController(windowNibName: "KMSecureEncryptWindowController")
  864. // windowController.documentURL = url
  865. // windowController.myDocument = self.listView.document
  866. // self.currentWindowController = windowController
  867. //
  868. // windowController.itemClick = { [weak self] index in
  869. // self?.view.window?.endSheet((self?.currentWindowController.window)!)
  870. // self?.currentWindowController = nil
  871. // }
  872. //
  873. // windowController.resultCallback = { [weak self] result in
  874. // let windowController_secure = self?.currentWindowController as! KMSecureEncryptWindowController
  875. // self?.view.window?.endSheet((self?.currentWindowController.window)!)
  876. // self?.currentWindowController = nil
  877. //
  878. // self?._secureOptions = windowController_secure.options
  879. // self?.needSave = true
  880. // self?.recordIsPDFDocumentEdited(type: .setPassword)
  881. //
  882. // if (result) {
  883. // self?.showSecureSuccessTip()
  884. // self?.recordSaveWatermarkFlag(type: .setPassword)
  885. // } else {
  886. // let alert = NSAlert()
  887. // alert.messageText = NSLocalizedString("Failure", comment: "")
  888. // alert.runModal()
  889. // }
  890. // }
  891. //
  892. // self.view.window?.beginSheet(windowController.window!)
  893. let controller = KMSecurityWindowController(windowNibName: "KMSecurityWindowController")
  894. controller.pdfDocument = self.document
  895. self.currentWindowController = controller
  896. controller.batchAction = { [unowned self] controller, files in
  897. self.view.window?.endSheet((self.currentWindowController.window)!)
  898. self.currentWindowController = nil
  899. self.toolbarController.cancelSelected(KMToolbarToolCompressItemIdentifier)
  900. let batchWindowController = KMBatchOperateWindowController.sharedWindowController
  901. batchWindowController.window?.makeKeyAndOrderFront("")
  902. let batchOperateFile = KMBatchOperateFile(filePath: files.first?.filePath ?? "")
  903. batchWindowController.switchToOperateType(.AddPassword, files: [batchOperateFile])
  904. batchWindowController.window?.makeKeyAndOrderFront("")
  905. }
  906. controller.doneAction = { [unowned self] controller, options, attribute in
  907. // let windowController_secure = self.currentWindowController as! KMSecureEncryptWindowController
  908. self.view.window?.endSheet((self.currentWindowController.window)!)
  909. self.currentWindowController = nil
  910. self._secureOptions = options
  911. self.documentAttribute = attribute
  912. self.needSave = true
  913. self.recordIsPDFDocumentEdited(type: .setPassword)
  914. if (options.count != 0) {
  915. self.showSecureSuccessTip()
  916. self.recordSaveWatermarkFlag(type: .setPassword)
  917. } else {
  918. let alert = NSAlert()
  919. alert.messageText = NSLocalizedString("Failure", comment: "")
  920. alert.runModal()
  921. }
  922. }
  923. controller.cancelAction = { [unowned self] controller in
  924. self.view.window?.endSheet((self.currentWindowController.window)!)
  925. self.currentWindowController = nil
  926. }
  927. NSWindow.currentWindow().beginSheet(controller.window!)
  928. }
  929. // MARK: -
  930. // MARK: 保存文档
  931. internal func needSaveDocument() -> Bool {
  932. if (self.isPDFDocumentEdited) {
  933. return self.isPDFDocumentEdited
  934. }
  935. if (self.needSave) {
  936. return self.needSave
  937. }
  938. let document: KMMainDocument? = self.myDocument as? KMMainDocument
  939. if (document?.isDocumentEdited == nil || document!.isDocumentEdited == false) {
  940. return false
  941. }
  942. return true
  943. }
  944. internal func saveDocument(overlookDocumentIfEdited overlook: Bool = false) {
  945. let document: KMMainDocument? = self.myDocument as? KMMainDocument
  946. if (overlook) {
  947. document?.save(nil)
  948. return
  949. }
  950. if (self.isPDFDocumentEdited) {
  951. self.clearIsPDFDocumentEdited()
  952. self.needSave = false
  953. document?.save(nil)
  954. return
  955. }
  956. if (document?.isDocumentEdited == nil || document!.isDocumentEdited == false) {
  957. return
  958. }
  959. document?.save(nil)
  960. }
  961. internal func asyncSaveDocument(overlookDocumentIfEdited overlook: Bool = false, callback:@escaping KMCommonBlock) {
  962. let document: KMMainDocument? = self.myDocument as? KMMainDocument
  963. if (overlook) {
  964. DispatchQueue.main.async {
  965. document?.save(nil)
  966. callback()
  967. }
  968. return
  969. }
  970. if (self.isPDFDocumentEdited) {
  971. self.clearIsPDFDocumentEdited()
  972. self.needSave = false
  973. DispatchQueue.main.async {
  974. document?.save(nil)
  975. callback()
  976. }
  977. return
  978. }
  979. if (document?.isDocumentEdited == nil || document!.isDocumentEdited == false) {
  980. callback()
  981. return
  982. }
  983. DispatchQueue.main.async {
  984. document?.save(nil)
  985. callback()
  986. }
  987. }
  988. internal func saveDocumentWithProgressAlert(callback:@escaping KMCommonBlock) {
  989. // 显示进度
  990. self.showProgressWindow(message: NSLocalizedString("Save PDF", comment: ""))
  991. self.progressController?.maxValue = 3.0
  992. self.progressController?.increment(by: 1.0)
  993. // 保存文档
  994. self.asyncSaveDocument { [unowned self] params in
  995. // 执行进度 [假进度]
  996. self.progressController?.increment(by: 1.0)
  997. self.progressController?.increment(by: 1.0)
  998. // DispatchQueue.main.async {
  999. DispatchQueue.main.asyncAfter(deadline: .now()+0.1) {
  1000. // 隐藏进度
  1001. self.hiddenProgressWindow()
  1002. // 回调
  1003. callback()
  1004. }
  1005. }
  1006. }
  1007. // MARK: -
  1008. // MARK: 选择 PDFDisplay 模式
  1009. @objc public func selectDisplay(display: KMPDFDisplayType, viewSettingIsReload: Bool = true) {
  1010. let toolModel = self.listView.toolMode
  1011. self.isReadMode = false
  1012. switch display {
  1013. case .singlePage:
  1014. self.listView.setDisplay(.singlePage)
  1015. break
  1016. case .singlePageContinuous:
  1017. self.listView.setDisplay(.singlePageContinuous)
  1018. break
  1019. case .twoUp:
  1020. self.listView.setDisplay(.twoUp)
  1021. break
  1022. case .twoUpContinuous:
  1023. self.listView.setDisplay(.twoUpContinuous)
  1024. break
  1025. case .bookMode:
  1026. self.listView.displaysAsBook = true
  1027. self.listView.displayTwoUp = true
  1028. self.listView.displayDirection = .horizontal
  1029. break
  1030. case .bookContinuous:
  1031. self.listView.displaysAsBook = true
  1032. self.listView.displayTwoUp = true
  1033. self.listView.displayDirection = .vertical
  1034. break
  1035. case .readModel:
  1036. self.openReadModel()
  1037. break
  1038. case .readContinuous:
  1039. self.openReadModel()
  1040. break
  1041. }
  1042. self.listView.layoutDocumentView()
  1043. // if (viewSettingIsReload && self.leftSideViewController.panelSetViewController.isViewLoaded) {
  1044. // self.leftSideViewController.panelSetViewController.reloadListViewModel()
  1045. // }
  1046. if (toolModel == .editPDFToolMode) {
  1047. if self.rightSideViewController.eidtPDFImageProperty != nil {
  1048. self.rightSideViewController.eidtPDFImageProperty?.cancelCutImageAction("")
  1049. self.rightSideViewController.isHidden = true
  1050. self.closeRightPane()
  1051. }
  1052. }
  1053. }
  1054. // Mark: -
  1055. // MARK: - 选择缩放模式
  1056. @objc public func selectZoom(_ type: KMPDFZoomType) {
  1057. switch type {
  1058. case .width:
  1059. self.listView.autoScales = true
  1060. // self.listView.autoScales = false
  1061. break
  1062. case .fit:
  1063. // self.listView.autoScales = !self.listView.autoScales
  1064. if let pageHeight = self.listView.currentPage()?.size.height, pageHeight > 0 {
  1065. let pdfviewHeight = self.listView.bounds.size.height
  1066. self.listView.scaleFactor = pdfviewHeight/pageHeight
  1067. self.listView.autoScales = false
  1068. }
  1069. break
  1070. case .actualSize:
  1071. if self.listView.scaleFactor != 1.0 {
  1072. self.listView.scaleFactor = 1.0
  1073. self.listView.autoScales = false
  1074. }
  1075. break
  1076. }
  1077. }
  1078. // MARK: - 自动保存
  1079. internal func autoSaveTimeStartOrStopIfNeed() {
  1080. if (KMPreferenceManager.shared.autoSave == false) {
  1081. self.stopAutoSaveTimer()
  1082. return
  1083. }
  1084. self.startAutoSaveTimer(KMPreferenceManager.shared.autoSaveTimeInterval)
  1085. if (self.myDocument == nil) {
  1086. self.stopAutoSaveTimer()
  1087. return
  1088. }
  1089. let browser = self.browserWindowController?.browser
  1090. guard let activeDocument = browser?.activeTabContents() else {
  1091. return
  1092. }
  1093. if (self.myDocument!.isEqual(to: activeDocument) == false) {
  1094. self.pauseAutoSaveTimer()
  1095. return
  1096. }
  1097. }
  1098. private func startAutoSaveTimer(_ interval: TimeInterval) {
  1099. if (self.autoSaveTimer != nil) {
  1100. self.autoSaveTimer?.invalidate()
  1101. self.autoSaveTimer = nil
  1102. }
  1103. self.autoSaveTimer = Timer.scheduledTimer(withTimeInterval: interval, repeats: true) { [weak self] timer in
  1104. DispatchQueue.main.async {
  1105. #if DEBUG
  1106. Swift.debugPrint("文档已自动保存")
  1107. if let _document = self?.myDocument {
  1108. Swift.debugPrint(_document.fileURL as Any)
  1109. }
  1110. #endif
  1111. self?.saveDocument()
  1112. }
  1113. }
  1114. RunLoop.current.add(self.autoSaveTimer!, forMode: .common)
  1115. }
  1116. private func pauseAutoSaveTimer() {
  1117. self.autoSaveTimer?.fireDate = Date.distantFuture
  1118. }
  1119. private func reStartAutoSaveTimer() {
  1120. self.autoSaveTimer?.fireDate = Date()+KMPreferenceManager.shared.autoSaveTimeInterval
  1121. }
  1122. private func needShowRegisterView() {
  1123. DispatchQueue.main.asyncAfter(deadline: DispatchTime.now() + 0.1) {
  1124. if KMLightMemberManager.manager.checkPopupRegister() {
  1125. // Login & Logout
  1126. let window = NSApp.mainWindow ?? self.view.window
  1127. if KMLightMemberManager.manager.isLogin() {
  1128. } else if window != nil {
  1129. var email: String = UserDefaults.standard.value(forKey: "kLoginEmail") as? String ?? ""
  1130. if email.count == 0 {
  1131. KMLoginWindowController.show(window: window!, .Batch, .register)
  1132. } else {
  1133. KMLoginWindowController.show(window: window!, .Batch, .login)
  1134. }
  1135. }
  1136. }
  1137. }
  1138. }
  1139. private func stopAutoSaveTimer() {
  1140. self.autoSaveTimer?.invalidate()
  1141. self.autoSaveTimer = nil
  1142. }
  1143. internal func createPdf(index:Int) {
  1144. if index == 1 {
  1145. self.homeVC?.openBlankPage()
  1146. } else if index == 4 {
  1147. self.homeVC?.importFromCamera()
  1148. } else if index == 5 {
  1149. self.homeVC?.importFromScanner()
  1150. } else if index == 3 {
  1151. self.homeVC?.importFromWebPage()
  1152. } else if index == 2 {
  1153. self.homeVC?.newFromImages()
  1154. }
  1155. }
  1156. // MARK: -
  1157. // MARK: Progress
  1158. func showProgressWindow(message: String = "") {
  1159. if (self.progressController != nil) {
  1160. self.hiddenProgressWindow()
  1161. }
  1162. let progress = SKProgressController()
  1163. progress.window?.backgroundColor = NSColor.km_init(hex: "#36383B")
  1164. progress.window?.contentView?.wantsLayer = true
  1165. progress.window?.contentView?.layer?.backgroundColor = NSColor.km_init(hex: "#36383B").cgColor
  1166. progress.progressField.textColor = NSColor.white
  1167. progress.showClose = false
  1168. progress.message = message
  1169. self.progressController = progress
  1170. self.view.window?.beginSheet(progress.window!)
  1171. }
  1172. func hiddenProgressWindow() {
  1173. if (self.progressController != nil) {
  1174. self.view.window?.endSheet((self.progressController?.window)!)
  1175. self.progressController = nil
  1176. }
  1177. }
  1178. // MARK -
  1179. // MARK - Event 监听
  1180. private func addEventMonitor() {
  1181. if (self.eventMonitor != nil) {
  1182. self.removeEventMonitor()
  1183. }
  1184. KMPrint("已添加事件监听")
  1185. self.eventMonitor = NSEvent.addLocalMonitorForEvents(matching: .scrollWheel) { [weak self] event in
  1186. if (event.type == .scrollWheel && event.modifierFlags.contains(.option)) { // Alt + 鼠标滚轮
  1187. self?.listView.magnifyWheel(event)
  1188. return nil
  1189. }
  1190. return event
  1191. }
  1192. }
  1193. func addKeyEventMonitor() {
  1194. if (self.keyEventMonitor != nil) {
  1195. self.removeKeyEventMonitor()
  1196. }
  1197. keyEventMonitor = NSEvent.addLocalMonitorForEvents(matching: .keyDown) { [weak self] event in
  1198. // print(event.keyCode)
  1199. if event.keyCode == 53 {
  1200. if self?.listView.toolMode == .editPDFToolMode {
  1201. if self != nil {
  1202. //使用editingSelectionString获取内容文字
  1203. if self!.listView.editingAreas() != nil {
  1204. if self!.listView.editingAreas().count > 0 && self!.listView.isEditable() {
  1205. self!.listView.clearEditingSelectCharItem()
  1206. } else if self!.listView.editingAreas().count > 0 {
  1207. if self?.listView.annotationType == .addImage ||
  1208. self?.listView.annotationType == .addText {
  1209. let textItem = self?.toolbarController.findItem(KMToolbarAddTextEditPDFItemIdentifier)
  1210. let imageItem = self?.toolbarController.findItem(KMToolbarAddImageEditPDFItemIdentifier)
  1211. textItem?.isSelected = false
  1212. imageItem?.isSelected = false
  1213. }
  1214. self?.rightSideViewController.isHidden = true
  1215. self?.listView.endEditIsRemoveBlock(with: self!.listView.editingAreas().first as? CPDFEditArea)
  1216. self?.listView.updateEditing([])
  1217. self?.listView.isEditImage = false
  1218. self?.listView.setNeedsDisplayPageViewFor(self!.listView.currentPage())
  1219. if self?.listView.annotationType == .addImage {
  1220. self?.listView.change([.text, .image])
  1221. }
  1222. self?.listView.annotationType = .editTextImage
  1223. self?.closeRightPane()
  1224. } else if(self?.listView.annotationType == .addImage || self!.listView.annotationType == .addText) {
  1225. if self?.listView.annotationType == .addImage ||
  1226. self?.listView.annotationType == .addText {
  1227. let textItem = self?.toolbarController.findItem(KMToolbarAddTextEditPDFItemIdentifier)
  1228. let imageItem = self?.toolbarController.findItem(KMToolbarAddImageEditPDFItemIdentifier)
  1229. textItem?.isSelected = false
  1230. imageItem?.isSelected = false
  1231. }
  1232. self?.rightSideViewController.isHidden = true
  1233. self?.listView.setShouAddEdit([])
  1234. self?.listView.change([.text, .image])
  1235. self?.listView.annotationType = .editTextImage
  1236. self?.closeRightPane()
  1237. }
  1238. } else {
  1239. if self?.listView.annotationType == .addImage ||
  1240. self?.listView.annotationType == .addText {
  1241. let textItem = self?.toolbarController.findItem(KMToolbarAddTextEditPDFItemIdentifier)
  1242. let imageItem = self?.toolbarController.findItem(KMToolbarAddImageEditPDFItemIdentifier)
  1243. textItem?.isSelected = false
  1244. imageItem?.isSelected = false
  1245. }
  1246. }
  1247. }
  1248. }
  1249. }
  1250. return event
  1251. }
  1252. }
  1253. func removeKeyEventMonitor() {
  1254. if (self.keyEventMonitor != nil) {
  1255. KMPrint("removeKeyEventMonitor 已移除事件监听")
  1256. NSEvent.removeMonitor(self.keyEventMonitor as Any)
  1257. self.keyEventMonitor = nil
  1258. }
  1259. }
  1260. private func removeEventMonitor() {
  1261. if (self.eventMonitor != nil) {
  1262. KMPrint("已移除事件监听")
  1263. NSEvent.removeMonitor(self.eventMonitor as Any)
  1264. self.eventMonitor = nil
  1265. }
  1266. }
  1267. // MARK: -
  1268. // MARK: Tools
  1269. func pdfViewCanHorizontalScroll() -> Bool {
  1270. let scroll = self.listView.scroll()
  1271. if (scroll == nil) {
  1272. return false
  1273. }
  1274. return scroll?.horizontalScroller?.isHidden == nil ? false : !(scroll!.horizontalScroller!.isHidden)
  1275. }
  1276. func pdfViewCanVerticalScroll() -> Bool {
  1277. let scroll = self.listView.scroll()
  1278. if (scroll == nil) {
  1279. return false
  1280. }
  1281. return scroll?.verticalScroller?.isHidden == nil ? false : !(scroll!.verticalScroller!.isHidden)
  1282. }
  1283. // MARK: - Public Methods
  1284. // 清理数据 [eg. 通知]
  1285. public func clearData() {
  1286. self.removeNotifications()
  1287. if (self.listView.spellingTag() > 0) {
  1288. NSSpellChecker.shared.closeSpellDocument(withTag: self.listView.spellingTag())
  1289. }
  1290. }
  1291. public func clearSecureOptions() {
  1292. self._secureOptions = nil
  1293. self.documentAttribute
  1294. }
  1295. public func recordRemoveSecureFlag() {
  1296. self._removeSecureFlag = true
  1297. self.clearSecureOptions()
  1298. self.recordIsPDFDocumentEdited(type: .removePassword)
  1299. self._needSave = true
  1300. }
  1301. public func clearRemoveSecureFlag() {
  1302. self._removeSecureFlag = false
  1303. }
  1304. public func recordSaveWatermarkFlag(type: KMSubscribeWaterMarkType = .none) {
  1305. km_synchronized(self) {
  1306. self._saveWatermarkFlag = true
  1307. }
  1308. if let _document = self.myDocument as? KMMainDocument {
  1309. _document.recordTrackEvent(type: type)
  1310. }
  1311. }
  1312. public func clearSaveWatermarkFlag() {
  1313. km_synchronized(self) {
  1314. self._saveWatermarkFlag = false
  1315. }
  1316. }
  1317. public func recordIsPDFDocumentEdited(type: KMSubscribeWaterMarkType = .none) {
  1318. km_synchronized(self) {
  1319. self._isPDFDocumentEdited = true
  1320. if let _document = self.myDocument {
  1321. KMTools.setDocumentEditedState(document: _document)
  1322. }
  1323. }
  1324. }
  1325. public func clearIsPDFDocumentEdited() {
  1326. km_synchronized(self) {
  1327. self._isPDFDocumentEdited = false
  1328. }
  1329. }
  1330. // MARK: - Noti Actions
  1331. internal func documentDidUnlockNotification(_ sender: Notification) {
  1332. if (self.listView.document != nil && self.listView.document.isEqual(to: sender.object)) {
  1333. if (self.myDocument == nil) {
  1334. return
  1335. }
  1336. if (self.listView.document.allowsPrinting && self.listView.document.allowsCopying) {
  1337. self.hiddenSecureLimitTip()
  1338. }
  1339. if ((self.myDocument as! KMMainDocument).isUnlockFromKeychain || self.isSaveKeyChain == false) {
  1340. return
  1341. }
  1342. let type = KMPreferenceManager.shared.savePasswordType
  1343. if (type == .never) {
  1344. return
  1345. }
  1346. if (type == .always) {
  1347. self.myDocument?.savePasswordInKeychain(self.listView.document.password, self.listView.document)
  1348. return
  1349. }
  1350. // 保存到钥匙串
  1351. let alert = NSAlert()
  1352. alert.messageText = NSLocalizedString("Remember Password?", comment: "")
  1353. alert.informativeText = NSLocalizedString("Do you want to save this password in your Keychain?", comment: "")
  1354. alert.addButton(withTitle: NSLocalizedString("Yes", comment: ""))
  1355. alert.addButton(withTitle: NSLocalizedString("No", comment: ""))
  1356. if (alert.runModal() == .alertFirstButtonReturn) { // 保存密码
  1357. self.myDocument?.savePasswordInKeychain(self.listView.document.password, self.listView.document)
  1358. return
  1359. }
  1360. }
  1361. }
  1362. internal func applicationWillTerminateNotification(_ sender: Notification) {
  1363. self.savePageNumberIfNeed()
  1364. self.saveDocument()
  1365. }
  1366. func KMPDFViewCurrentPageDidChangedNotification(_ sender: Notification) {
  1367. if self.isReadMode {
  1368. self.readModelView.currentPageIndex = self.listView.currentPageIndex
  1369. }
  1370. //刷新前一页后一页按钮
  1371. self.updateNextAndPreViousButtonState()
  1372. }
  1373. func CPDFDocumentPageCountChangedNotification(_ sender: Notification) {
  1374. if self.isReadMode {
  1375. self.readModelView.totalPagesCount = Int(self.listView.document.pageCount)
  1376. }
  1377. //刷新前一页后一页按钮
  1378. self.updateNextAndPreViousButtonState()
  1379. }
  1380. func CEditPDFToolModeChangeStateUnkownNotification(_ sender: Notification) {
  1381. var editSelectd = false
  1382. if (self.listView.annotationType == .addText || self.listView.annotationType == .addImage) && self.listView.toolMode == .editPDFToolMode {
  1383. editSelectd = true
  1384. }
  1385. if self.listView.toolMode == .editPDFToolMode {
  1386. if editSelectd {
  1387. self.toolbarController.cancelSelected(KMToolbarAddTextEditPDFItemIdentifier)
  1388. }
  1389. }
  1390. }
  1391. //MARK: - PDFListViewDelegate
  1392. func pdfViewDocumentDidLoaded(_ pdfView: CPDFView!) {
  1393. // KMPrint("pdfViewDocumentDidLoaded")
  1394. self.removeBackgroundMaskView()
  1395. if (!self.listView.document!.allowsCopying || !self.listView.document!.allowsPrinting) {
  1396. self.showSecureLimitTip()
  1397. }
  1398. if (self._documentFirstLoad) {
  1399. self.checkShouldAutoOpenLeftVC()
  1400. if (KMPreferenceManager.shared.openLastUnlockedDocumentWhenAppStart) {
  1401. let pageNumber = KMPreferenceManager.shared.getPageNumber(forKey: self.listView.document.documentURL.path)
  1402. let pageScale = KMPreferenceManager.shared.getPageScale(forKey: self.listView.document.documentURL.path)
  1403. if (pageScale != nil) {
  1404. self.listView.scaleFactor = CGFloat(pageScale!)
  1405. }
  1406. if (pageNumber != nil && pageNumber! >= 0 && pageNumber! < self.listView.document.pageCount) {
  1407. self.listView.go(toPageIndex: pageNumber!, animated: false)
  1408. } else {
  1409. self._goToFirstPageForFristAppear()
  1410. }
  1411. } else {
  1412. self._goToFirstPageForFristAppear()
  1413. }
  1414. self._documentFirstLoad = false
  1415. }
  1416. let notification = Notification(name: Notification.Name(rawValue: "pdfViewDocumentDidLoaded"))
  1417. self.preferenceDidChangeNotification(notification:notification)
  1418. let leftWidthNumber = UserDefaults.standard.object(forKey: CPDFOfficeLeftSidePaneWidthKey) as? NSNumber ?? NSNumber(value: panelWidth + functionWidth)
  1419. let rightWidthNumber = UserDefaults.standard.object(forKey: CPDFOfficeRightSidePaneWidthKey) as? NSNumber ?? NSNumber(value: defaultRightWidth)
  1420. applyLeftSideWidth(leftWidthNumber.doubleValue, rightSideWidth: rightWidthNumber.doubleValue)
  1421. self.updatePageIndicatoreType()
  1422. }
  1423. func pdfViewCurrentPageDidChanged(_ pdfView: CPDFView!) {
  1424. self.updatePageIndicatoreType()
  1425. NotificationCenter.default.post(name: NSNotification.Name.init(rawValue: "KMPDFViewCurrentPageDidChanged"), object: self.document)
  1426. // KMPrint("KMPDFViewCurrentPageDidChanged")
  1427. }
  1428. func pdfViewScaleDidChanged(_ pdfView: CPDFView!) {
  1429. self.toolbarController.mainToolBarView?.zoomTextField.stringValue = "\(Int(self.listView.scaleFactor * 100))%"
  1430. self.updateZoomInOutButtonState()
  1431. // KMPrint("pdfViewScaleDidChanged")
  1432. }
  1433. func pdfViewDidClick(onLink pdfView: CPDFView!, withURL url: String!) {
  1434. if let urlString = url, urlString == kKMPurchaseProductURLString {
  1435. //跳转订阅比较表
  1436. let _ = KMComparativeTableViewController.show(window: NSApp.mainWindow ?? NSWindow())
  1437. return
  1438. }
  1439. KMTools.openURL(urlString: url)
  1440. }
  1441. func pdfViewPerformURL(_ pdfView: CPDFView!, withContent content: String!) {
  1442. KMPrint("pdfViewPerformURL")
  1443. }
  1444. func pdfViewPerformPrint(_ pdfView: CPDFView!) {
  1445. KMPrint("pdfViewPerformPrint")
  1446. }
  1447. func pdfViewPerformGo(toPage pdfView: CPDFView!) {
  1448. KMPrint("pdfViewPerformGo")
  1449. }
  1450. func pdfViewOpenPDF(_ pdfView: CPDFView!, forRemoteGoTo action: CPDFAction!) {
  1451. KMPrint("pdfViewOpenPDF")
  1452. }
  1453. func pdfViewPerformReset(_ pdfView: CPDFView!) {
  1454. KMPrint("pdfViewPerformReset")
  1455. }
  1456. func pdfViewEditingBlockDidChanged(_ pdfView: CPDFView!) {
  1457. KMPrint("pdfViewEditingBlockDidChanged")
  1458. }
  1459. func pdfViewAsBookBookmark() -> NSImage! {
  1460. return NSImage(named: "KMImageNameUXIconPDFViewBookMark")!
  1461. }
  1462. func pdfViewEditingSelectionDidChanged(_ pdfView: CPDFView!) {
  1463. self.recordSaveWatermarkFlag()
  1464. if self.rightSideViewController != nil && self.rightSideViewController.subViewType == .EditPDFAddText {
  1465. self.rightSideViewController.eidtPDFTextProperty.reloadData()
  1466. self.rightSideViewController.eidtPDFTextProperty.updateTextTextPresuppositionState()
  1467. }
  1468. }
  1469. func pdfViewEditingAreaDidChanged(_ pdfView: CPDFView!) {
  1470. let areas = self.listView.editingAreas()
  1471. if areas == nil || areas?.count ?? 0 == 0 {
  1472. if self.listView.toolMode == .editPDFToolMode {
  1473. if self.listView.annotationType == .addImage || self.listView.annotationType == .addText {
  1474. if self.listView.isEditImage {
  1475. self.menuItemEditingClick_CropImage(sender: NSMenuItem())
  1476. } else {
  1477. // if self.listView.annotationType == .addImage {
  1478. // self.closeRightPane()
  1479. // }
  1480. if self.listView.annotationType == .addImage {
  1481. if self.rightSideViewController.eidtPDFImageProperty != nil {
  1482. self.rightSideViewController.eidtPDFImageProperty.reloadData()
  1483. }
  1484. }
  1485. // self.openRightPane()
  1486. }
  1487. } else {
  1488. self.closeRightPane()
  1489. }
  1490. } else {
  1491. self.rightSideViewController.isHidden = true
  1492. self.closeRightPane()
  1493. if self.rightSideViewController != nil && self.rightSideViewController.subViewType == .EditPDFAddText && self.listView.annotationType == .addText {
  1494. self.rightSideViewController.eidtPDFTextProperty.initData()
  1495. }
  1496. }
  1497. if self.listView.isEdited() {
  1498. self.recordIsPDFDocumentEdited(type: .editText)
  1499. }
  1500. if self.listView.annotationType != .addText {
  1501. NotificationCenter.default.post(name: NSNotification.Name(rawValue: "kPDFViewEditingAreaDidChanged"), object: self.listView.document)
  1502. }
  1503. return
  1504. }
  1505. self.isPDFTextImageEdited = true
  1506. if (self.listView.annotationType == .addImage) && areas!.count > 0 {
  1507. var isImageArea = false
  1508. for i in 0 ... areas!.count-1 {
  1509. if areas![i] is CPDFEditImageArea {
  1510. isImageArea = true
  1511. }
  1512. }
  1513. if isImageArea {
  1514. // self.rightSideViewController.view.isHidden = false
  1515. self.rightSideViewController.isHidden = false
  1516. if self.rightSideViewController != nil && self.rightSideViewController.subViewType == .EditPDFAddImage {
  1517. self.rightSideViewController.subViewType = .EditPDFAddImage
  1518. self.rightSideViewController.eidtPDFImageProperty.reloadData()
  1519. }
  1520. self.openRightPane()
  1521. } else {
  1522. // self.rightSideViewController.view.isHidden = true
  1523. self.rightSideViewController.isHidden = true
  1524. self.closeRightPane()
  1525. }
  1526. } else if self.rightSideViewController != nil && self.rightSideViewController.subViewType == .EditPDFAddText && self.listView.annotationType == .addText {
  1527. // self.rightSideViewController.view.isHidden = false
  1528. self.rightSideViewController.isHidden = false
  1529. if self.listView.editingSelectionString().count != 0 {
  1530. self.rightSideViewController.eidtPDFTextProperty.reloadData()
  1531. } else {
  1532. self.rightSideViewController.eidtPDFTextProperty.refreshSelectAreaProperty(needDefaultData: true)
  1533. }
  1534. self.openRightPane()
  1535. } else {
  1536. var textsAreas : [CPDFEditTextArea] = []
  1537. var imagesAreas : [CPDFEditImageArea] = []
  1538. if self.listView.editingAreas()?.count ?? 0 < 1 {
  1539. return
  1540. }
  1541. for i in 0 ... areas!.count-1 {
  1542. if areas![i] is CPDFEditTextArea {
  1543. textsAreas.append(areas![i] as! CPDFEditTextArea)
  1544. }
  1545. if areas![i] is CPDFEditImageArea {
  1546. imagesAreas.append(areas![i] as! CPDFEditImageArea)
  1547. }
  1548. }
  1549. if textsAreas.count > 0 && textsAreas.count == areas!.count {
  1550. // self.rightSideViewController.view.isHidden = false
  1551. self.rightSideViewController.isHidden = false
  1552. self.rightSideViewController.subViewType = .EditPDFAddText
  1553. self.rightSideViewController.eidtPDFTextProperty?.reloadData()
  1554. self.openRightPane()
  1555. } else if imagesAreas.count > 0 {
  1556. // self.rightSideViewController.view.isHidden = false
  1557. self.rightSideViewController.isHidden = false
  1558. self.rightSideViewController.subViewType = .EditPDFAddImage
  1559. self.rightSideViewController.eidtPDFImageProperty?.reloadData()
  1560. self.openRightPane()
  1561. }
  1562. }
  1563. if self.listView.isEdited() {
  1564. self.recordIsPDFDocumentEdited(type: .editText)
  1565. if self.listView.annotationType != .addText {
  1566. NotificationCenter.default.post(name: NSNotification.Name(rawValue: "kPDFViewEditingAreaDidChanged"), object: self.listView.document)
  1567. }
  1568. }
  1569. }
  1570. func pdfViewEditingCropBoundsDidChanged(_ pdfView: CPDFView!, editing editArea: CPDFEditArea!) {
  1571. self.recordSaveWatermarkFlag()
  1572. if editArea != nil && (editArea is CPDFEditImageArea){
  1573. self.listView.cropAreas = editArea as? CPDFEditImageArea
  1574. }
  1575. }
  1576. //编辑PDF 创建图片区域回调
  1577. func pdfViewEditingAddImageArea(_ pdfView: CPDFView!, add page: CPDFPage!, add rect: CGRect) {
  1578. self.recordSaveWatermarkFlag(type: .editImage)
  1579. if self.listView.isEditImage {
  1580. self.menuItemEditingClick_CropImage(sender: NSMenuItem())
  1581. } else {
  1582. let panel = NSOpenPanel()
  1583. panel.allowsMultipleSelection = false
  1584. panel.allowedFileTypes = ["png","jpg"]
  1585. panel.beginSheetModal(for: NSApp.mainWindow!) { response in
  1586. if response == .OK {
  1587. var filePath = panel.url?.path
  1588. var image = NSImage.init(contentsOf: panel.url!)
  1589. //图片自适应范围
  1590. if image != nil {
  1591. var imageRect = rect
  1592. let imageSize = image!.size
  1593. var previewSize = rect.size
  1594. var isChangeSize = false
  1595. if previewSize.width == 0 && previewSize.height == 0 {
  1596. previewSize = CGSize(width: 500, height: 500)
  1597. isChangeSize = true
  1598. }
  1599. let scale = min(previewSize.width / imageSize.width, previewSize.height / imageSize.height)
  1600. let newSize = CGSize(width: imageSize.width * scale, height: imageSize.height * scale)
  1601. if isChangeSize {
  1602. imageRect.origin.x = imageRect.origin.x - newSize.width / 2
  1603. imageRect.origin.y = imageRect.origin.y - newSize.height / 2
  1604. } else {
  1605. imageRect.origin.x = imageRect.origin.x + imageRect.width / 2 - newSize.width / 2
  1606. imageRect.origin.y = imageRect.origin.y + imageRect.height / 2 - newSize.height / 2
  1607. }
  1608. imageRect.size = newSize
  1609. let limitWidth = 1920.0
  1610. if imageSize.width > limitWidth || imageSize.height > limitWidth {
  1611. filePath = KMImageOptimization.needCompressImageLosslessly(image: image!,
  1612. targetSize: CGSize(width: limitWidth, height: limitWidth),
  1613. maxSizeInBytes: 1024 * 1024 * 5,
  1614. targetCompression: 1.0)
  1615. }
  1616. //自适应page
  1617. let pageRect = self.listView.currentPage().bounds
  1618. if imageRect.width > pageRect.width ||
  1619. imageRect.height > pageRect.height {
  1620. let pageScale = min(pageRect.width / imageSize.width, pageRect.height / imageSize.height)
  1621. imageRect = CGRect(x: imageRect.origin.x,
  1622. y: imageRect.origin.y,
  1623. width: imageRect.width * pageScale,
  1624. height: imageRect.height * pageScale)
  1625. }
  1626. if imageRect.origin.x < 0 {
  1627. imageRect.origin.x = 5
  1628. }
  1629. if imageRect.origin.y < 0 {
  1630. imageRect.origin.y = 5
  1631. }
  1632. if imageRect.origin.x + imageRect.width > pageRect.width ||
  1633. imageRect.origin.y + imageRect.height > pageRect.height {
  1634. let offsetX = imageRect.origin.x + imageRect.width - pageRect.width
  1635. let offsetY = imageRect.origin.y + imageRect.height - pageRect.height
  1636. imageRect.origin.x = imageRect.origin.x - offsetX - 5
  1637. imageRect.origin.y = imageRect.origin.y - offsetY - 5
  1638. }
  1639. DispatchQueue.main.async {
  1640. self.listView.createImagePath(filePath, rect: imageRect, page: pdfView.currentPage())
  1641. self.isPDFTextImageEdited = true
  1642. self.recordIsPDFDocumentEdited(type: .editImage)
  1643. // self.asyncSaveDocument { params in
  1644. //
  1645. // }
  1646. }
  1647. }
  1648. }
  1649. }
  1650. }
  1651. }
  1652. func pdfViewEditingAddTextArea(_ pdfView: CPDFView!, add page: CPDFPage!, add rect: CGRect) {
  1653. // print(rect)
  1654. var newrect = CGRect(x: rect.origin.x, y: rect.origin.y, width: rect.size.width, height: rect.size.height)
  1655. if __CGSizeEqualToSize(rect.size, CGSize.zero) {
  1656. newrect = CGRect(x: rect.origin.x, y: rect.origin.y - 12, width: 20, height: 12)
  1657. } else {
  1658. newrect = CGRect(x: rect.origin.x, y: rect.origin.y + rect.size.height - 12, width: rect.size.width, height: 12)
  1659. }
  1660. let model = KMEditPDFTextManager.manager.fetchUserDefaultData(type: .commonly)
  1661. let fontName = KMEditPDFTextManager.manager.fetchFontName(fontName: model.fontName)
  1662. let fontSize = model.fontSize
  1663. let fontColor = model.color
  1664. let fontAlign = model.alignment
  1665. let fontStyle = KMEditPDFTextManager.manager.fetchFontStyle(fontName: model.fontName)
  1666. NSColorPanel.shared.color = fontColor
  1667. let font = KMEditPDFTextManager.manager.fetchFont(fontName: fontName, style: fontStyle, size: fontSize)
  1668. let style = NSMutableParagraphStyle()
  1669. style.alignment = fontAlign
  1670. let attributes = [NSAttributedString.Key.font:font, NSAttributedString.Key.foregroundColor:fontColor,NSAttributedString.Key.paragraphStyle:style] as [NSAttributedString.Key : Any]
  1671. self.listView.createEmptyStringBounds(newrect,withAttributes: attributes as [NSAttributedString.Key : Any], page: pdfView.currentPage())
  1672. if self.rightSideViewController != nil && self.rightSideViewController.subViewType == .EditPDFAddText && self.listView.annotationType == .addText {
  1673. self.rightSideViewController.eidtPDFTextProperty.refreshSelectAreaProperty(needDefaultData: true)
  1674. }
  1675. // self.asyncSaveDocument { params in
  1676. //
  1677. // }
  1678. self.recordSaveWatermarkFlag(type: .editText)
  1679. }
  1680. // func pdfViewEditingDoubleClick(_ pdfView: CPDFView!, imageArea editArea: CPDFEditArea!) {
  1681. // debugPrint("pdfViewEditingDoubleClick")
  1682. // }
  1683. func pdfViewEditingOperationDidChanged(_ pdfView: CPDFView!) {
  1684. debugPrint("pdfViewEditingOperationDidChanged")
  1685. if self.listView.isEdited() {
  1686. self.recordSaveWatermarkFlag()
  1687. }
  1688. }
  1689. // func pdfListViewEditAnnotation(_ pdfListView: CPDFListView!, for anotation: CPDFAnnotation!) {
  1690. // debugPrint("pdfListViewEditAnnotation")
  1691. // }
  1692. func pdfListViewKeyDownIsContinue(_ pdfListView: CPDFListView!, theEvent: NSEvent!) -> Bool {
  1693. let command = theEvent.modifierFlags.contains(.command)
  1694. let control = theEvent.modifierFlags.contains(.control)
  1695. KMPrint(theEvent.keyCode)
  1696. if (theEvent.keyCode == 11 && command) { // command + B [添加书签]
  1697. self.menuItemBookMarkClick_add(sender: NSMenuItem())
  1698. return false
  1699. } else if (command && control && theEvent.keyCode == 14) { // command + control + E [注释 橡皮擦]
  1700. return false
  1701. } else if (theEvent.keyCode == 123) { // 向左
  1702. if(self.listView.isEditing() && !self.listView.isSelecteditAreaNotEdit()) {
  1703. return false
  1704. } else {
  1705. if (self.pdfViewCanHorizontalScroll() == false && self.listView.canGoToPreviousPage()) {
  1706. self.listView.goToPreviousPage(nil)
  1707. return false
  1708. }
  1709. }
  1710. } else if (theEvent.keyCode == 126) { // 向上
  1711. if(self.listView.isEditing() && !self.listView.isSelecteditAreaNotEdit()) {
  1712. return false
  1713. } else {
  1714. if (self.listView.isContinousScroll()) {
  1715. return true
  1716. }
  1717. if (self.pdfViewCanVerticalScroll() == false && self.listView.canGoToPreviousPage()) {
  1718. self.listView.goToPreviousPage(nil)
  1719. return false
  1720. }
  1721. }
  1722. } else if (theEvent.keyCode == 124) { // 向右
  1723. if(self.listView.isEditing() && !self.listView.isSelecteditAreaNotEdit()) {
  1724. return false
  1725. } else {
  1726. if (self.pdfViewCanHorizontalScroll() == false && self.listView.canGoToNextPage()) {
  1727. self.listView.goToNextPage(nil)
  1728. return false
  1729. }
  1730. }
  1731. } else if (theEvent.keyCode == 125) { // 向下
  1732. if(self.listView.isEditing() && !self.listView.isSelecteditAreaNotEdit()) {
  1733. return false
  1734. } else {
  1735. if (self.listView.isContinousScroll()) {
  1736. return true
  1737. }
  1738. if (self.pdfViewCanVerticalScroll() == false && self.listView.canGoToNextPage()) {
  1739. self.listView.goToNextPage(nil)
  1740. return false
  1741. }
  1742. }
  1743. } else if (theEvent.keyCode == 36) {
  1744. if self.listView.annotationType == .addImage || self.listView.annotationType == .addText {
  1745. if self.listView.isEditImage {
  1746. self.menuItemEditingClick_CropImage(sender: NSMenuItem())
  1747. }
  1748. }
  1749. }
  1750. if theEvent.keyCode == 53 {
  1751. if self.isReadMode {
  1752. self.closeReadModel()
  1753. }
  1754. self.leftSideViewCancelSelect()
  1755. if (self.toolbarController.toolbarType.isToolMode()) {
  1756. self.toolbarController.selectItem(self.toolbarController.toolbarType.itemIdentifier())
  1757. }
  1758. }
  1759. return true
  1760. }
  1761. func pdfListViewMenuValidate(_ pdfListView: CPDFListView!, menuItem: NSMenuItem!, isTakesEffect: UnsafeMutablePointer<ObjCBool>!) -> Bool {
  1762. guard let action = menuItem.action else {
  1763. isTakesEffect.pointee = false
  1764. return false
  1765. }
  1766. if (KMSystemMenu.isEditSelector(sel: action)) {
  1767. if (KMSystemMenu.Edit.deleteSelector == action) {
  1768. isTakesEffect.pointee = true
  1769. return self.listView.activeAnnotations.count > 0
  1770. } else if (KMSystemMenu.Edit.copySelector == action) {
  1771. isTakesEffect.pointee = true
  1772. return true//self.listView.canCopy()
  1773. } else if (KMSystemMenu.Edit.cutSelector == action) {
  1774. isTakesEffect.pointee = true
  1775. return self.listView.canCopy()
  1776. } else if (KMSystemMenu.Edit.pasteSelector == action) {
  1777. isTakesEffect.pointee = true
  1778. return self.listView.canPaste()
  1779. }
  1780. }
  1781. isTakesEffect.pointee = false
  1782. return false
  1783. }
  1784. //MARK: -CPDFListViewDelegate
  1785. func cPDFListView(_ pdfListView: CPDFListView, didDelete annotation: CPDFAnnotation, in pdfPage: CPDFPage) {
  1786. }
  1787. func pdfListViewChangeatioActiveAnnotations(_ pdfListView: CPDFListView!, forActiveAnnotations annotations: [CPDFAnnotation]!, isRightMenu: Bool) {
  1788. self.view.window?.makeFirstResponder(self.listView)
  1789. if isRightMenu {
  1790. } else if annotations.count > 0 {
  1791. if annotations.count > 1 {
  1792. let fristAnnotation = annotations.first
  1793. var isSameAnnotation = true
  1794. let className = NSStringFromClass(fristAnnotation!.classForCoder)
  1795. for annotation in annotations {
  1796. let cunrrentClassName = NSStringFromClass(annotation.classForCoder)
  1797. if (className == "CPDFSquareAnnotation") ||
  1798. (className == "CPDFCircleAnnotation") ||
  1799. (className == "CPDFLineAnnotation") {
  1800. if (cunrrentClassName != "CPDFSquareAnnotation") &&
  1801. (cunrrentClassName != "CPDFCircleAnnotation") &&
  1802. (cunrrentClassName != "CPDFLineAnnotation") {
  1803. isSameAnnotation = false
  1804. }
  1805. } else {
  1806. if className != cunrrentClassName {
  1807. isSameAnnotation = false
  1808. }
  1809. }
  1810. }
  1811. if isSameAnnotation == false {
  1812. self.rightSideViewController?.reloadDataWithPDFView(pdfView: pdfListView, isShow: false)
  1813. // self.closeRightPane()
  1814. } else {
  1815. self.rightSideViewController?.reloadDataWithPDFView(pdfView: pdfListView, isShow: true)
  1816. self.openRightPane()
  1817. }
  1818. } else {
  1819. let fristAnnotation = annotations.first
  1820. let className = NSStringFromClass(fristAnnotation!.classForCoder)
  1821. if self.isReadMode {
  1822. self.rightSideViewController?.reloadDataWithPDFView(pdfView: pdfListView, isShow: false)
  1823. self.closeRightPane()
  1824. } else {
  1825. self.rightSideViewController?.reloadDataWithPDFView(pdfView: pdfListView, isShow: true)
  1826. if className != "CPDFStampAnnotation" &&
  1827. className != "CPDFSignatureAnnotation" &&
  1828. className != "CPDFListStampAnnotation" {
  1829. self.openRightPane()
  1830. }
  1831. }
  1832. }
  1833. } else if (annotations.count == 0){
  1834. if pdfListView.annotationType == .unkown {
  1835. self.rightSideViewController?.reloadDataWithPDFView(pdfView: pdfListView, isShow: false)
  1836. self.closeRightPane()
  1837. } else {
  1838. if self.isReadMode {
  1839. self.rightSideViewController?.reloadDataWithPDFView(pdfView: pdfListView, isShow: false)
  1840. self.closeRightPane()
  1841. } else {
  1842. self.rightSideViewController?.reloadDataWithPDFView(pdfView: pdfListView, isShow: true)
  1843. self.openRightPane()
  1844. }
  1845. }
  1846. }
  1847. }
  1848. func pdfListViewChangedAnnotationType(_ pdfListView: CPDFListView!, for annotationType: CAnnotationType) {
  1849. if(annotationType == .unkown) {
  1850. // self.rightSideViewController.view.isHidden = true
  1851. self.rightSideViewController.isHidden = true
  1852. self.closeRightPane()
  1853. }
  1854. }
  1855. ///开始定位链接注释
  1856. func pdfListViewLinkDestinationStart(_ pdfListView: CPDFListView!, withActiveAnnotation annotation: CPDFAnnotation!) {
  1857. if self.locationPageView.superview == nil {
  1858. self.locationPageView.frame = CGRect(x: 0, y: pdfListView.frame.maxY-32, width: pdfListView.frame.width, height: 32)
  1859. pdfListView.addSubview(self.locationPageView)
  1860. }
  1861. }
  1862. ///刷新链接注释
  1863. func pdfListViewLinkDestinationEnd(_ pdfListView: CPDFListView!, withActiveAnnotation annotation: CPDFAnnotation!) {
  1864. if self.locationPageView.superview != nil {
  1865. self.locationPageView.removeFromSuperview()
  1866. }
  1867. if self.rightSideViewController.subViewType == .AnnotationProperts && pdfListView.annotationType == .link {
  1868. self.rightSideViewController.reloadDataWithPDFView(pdfView: pdfListView, isShow: true)
  1869. }
  1870. }
  1871. func pdfListViewMenuItemsEditing(at point: CGPoint, for page: CPDFPage!, menuItems: [NSMenuItem]!) -> [NSMenuItem]! {
  1872. if (listView.toolMode != CToolMode.editPDFToolMode) {
  1873. return menuItems
  1874. }
  1875. var tMenuItems = menuItems;
  1876. if(listView.isSelectEditCharRange() ||
  1877. listView.isSelecteditArea(with: point)) {
  1878. tMenuItems?.append(NSMenuItem.separator())
  1879. // tMenuItems?.append(self.fontColorMenuItem())
  1880. // tMenuItems?.append(self.fontSizeMenuItem())
  1881. }
  1882. let areas = self.listView.editingAreas() ?? []
  1883. if areas.count == 1 {
  1884. let fristAreas = areas.first
  1885. if fristAreas is CPDFEditImageArea {
  1886. self.listView.selectImageAreas = fristAreas as? CPDFEditImageArea
  1887. if self.listView.isEditImage {
  1888. tMenuItems?.removeAll()
  1889. tMenuItems?.append(self.corpImageMenuItem())
  1890. tMenuItems?.append(self.cancelCorpImageMenuItem())
  1891. tMenuItems?.append(self.restoreCorpImageMenuItem())
  1892. } else {
  1893. tMenuItems?.append(NSMenuItem.separator())
  1894. tMenuItems?.append(self.cutImageArea())
  1895. tMenuItems?.append(self.replaceImageArea())
  1896. tMenuItems?.append(self.exportImageArea())
  1897. }
  1898. } else {
  1899. tMenuItems?.swapAt(0, 1)
  1900. }
  1901. } else if areas.count == 0 {
  1902. tMenuItems?.append(NSMenuItem.separator())
  1903. tMenuItems?.append(self.addText())
  1904. tMenuItems?.append(self.addImage())
  1905. }
  1906. return tMenuItems
  1907. }
  1908. func pdfListViewMenu(forEvent pdfListView: CPDFListView!, for theEvent: NSEvent!, click menu: AutoreleasingUnsafeMutablePointer<NSMenu?>!) {
  1909. self.mouseRightMenuEvent = theEvent
  1910. let currentMenu : NSMenu = menu.pointee!
  1911. if currentMenu.items.count > 3 {
  1912. currentMenu.insertItem(NSMenuItem.separator(), at: currentMenu.items.count - 3)
  1913. currentMenu.insertItem(self.addReadModelStype(), at: currentMenu.items.count - 3)
  1914. }
  1915. if listView.currentSelection != nil{
  1916. if listView.currentSelection.selectionType() == .text {
  1917. currentMenu.insertItem(NSMenuItem.separator(), at: 3)
  1918. currentMenu.insertItem(self.setSearchBaiduStype(), at: 3)
  1919. currentMenu.insertItem(NSMenuItem.separator(), at: 3)
  1920. currentMenu.insertItem(self.setLookUpStype(), at: 3)
  1921. currentMenu.insertItem(NSMenuItem.separator(), at: 3)
  1922. currentMenu.insertItem(self.addOutlineStype(), at: 3)
  1923. currentMenu.insertItem(NSMenuItem.separator(), at: 3)
  1924. currentMenu.insertItem(self.setAnnotationToolStype(), at: 3)
  1925. currentMenu.insertItem(self.setTTSStype(), at: 3)
  1926. currentMenu.insertItem(NSMenuItem.separator(), at: 3)
  1927. currentMenu.insertItem(self.setShareStype(), at: 3)
  1928. currentMenu.insertItem(NSMenuItem.separator(), at: 3)
  1929. }
  1930. currentMenu.insertItem(self.enterAnnotationStype(), at: 3)
  1931. currentMenu.insertItem(NSMenuItem.separator(), at: 3)
  1932. if listView.currentSelection.selectionType() == .image{
  1933. currentMenu.insertItem(self.setCutStype(), at: 1)
  1934. currentMenu.insertItem(self.setDeleteStype(), at: 4)
  1935. currentMenu.insertItem(NSMenuItem.separator(), at: 6)
  1936. currentMenu.insertItem(self.setEditNoteStype(), at: 6)
  1937. currentMenu.insertItem(self.setRotateStype(), at: 6)
  1938. currentMenu.insertItem(self.setLinesStype(), at: 6)
  1939. currentMenu.insertItem(self.setColorsStype(), at: 6)
  1940. }
  1941. if listView.currentSelection.selectionType() == .text {
  1942. currentMenu.insertItem(NSMenuItem.separator(), at: currentMenu.items.count)
  1943. currentMenu.insertItem(self.setTranslateStype(), at: currentMenu.items.count)
  1944. currentMenu.insertItem(NSMenuItem.separator(), at: currentMenu.items.count)
  1945. currentMenu.insertItem(self.setServicesStype(), at: currentMenu.items.count)
  1946. }
  1947. }
  1948. if listView.activeAnnotation == nil && listView.currentSelection == nil{
  1949. currentMenu.insertItem(NSMenuItem.separator(), at: currentMenu.items.count)
  1950. if(listView.toolMode == .selectToolMode) {
  1951. if NSIsEmptyRect(listView.currentSelectionRect()) {
  1952. currentMenu.insertItem(self.zoomSelectionMenuItem(), at: 0)
  1953. currentMenu.insertItem(NSMenuItem.separator(), at: 0)
  1954. }
  1955. currentMenu.insertItem(self.printingMenu(), at: 0)
  1956. currentMenu.insertItem(self.setTTSStype(), at: 0)
  1957. currentMenu.insertItem(self.setCropStype(), at: 0)
  1958. currentMenu.insertItem(self.setSnapshotStype(), at: 0)
  1959. let export = NSMenuItem(title: NSLocalizedString("Export", comment: ""), action: nil, target: self)
  1960. export.submenu = self.exportMenu()
  1961. currentMenu.insertItem(export, at: currentMenu.items.count)
  1962. }else{
  1963. currentMenu.insertItem(NSMenuItem.separator(), at: 2)
  1964. currentMenu.insertItem(self.setTTSStype(), at: 2)
  1965. currentMenu.insertItem(self.setCropStype(), at: 2)
  1966. currentMenu.insertItem(self.setSnapshotStype(), at: 2)
  1967. currentMenu.insertItem(NSMenuItem.separator(), at: 2)
  1968. currentMenu.insertItem(self.addOutlineStype(), at: 2)
  1969. currentMenu.insertItem(NSMenuItem.separator(), at: 2)
  1970. currentMenu.insertItem(self.enterAnnotationStype(), at: 2)
  1971. currentMenu.insertItem(NSMenuItem.separator(), at: 2)
  1972. if(currentMenu.items.count > 4) {
  1973. currentMenu.insertItem(NSMenuItem.separator(), at: 5)
  1974. }
  1975. if(currentMenu.items.count > 5) {
  1976. currentMenu.insertItem(self.addBookmarkMenu(), at: 6)
  1977. }
  1978. // if (currentMenu.items.count > 6 && self.isReadMode) {
  1979. // currentMenu.removeItem(currentMenu.item(withTitle: "Zoom")!)
  1980. // }
  1981. // currentMenu.insertItem(self.findStringMenu(), at: currentMenu.items.count)
  1982. currentMenu.insertItem(self.setAutoScrollStype(), at: currentMenu.items.count)
  1983. }
  1984. currentMenu.insertItem(self.setAnnotationToolStype(), at: 5)
  1985. }
  1986. for item in currentMenu.items {
  1987. if (item.action == NSSelectorFromString("menuItemClick_HidenorShowNote:")) {
  1988. // 显示与隐藏注释 item action 截取
  1989. item.action = #selector(menuItemClick_HidenorShowNote)
  1990. item.target = self
  1991. break
  1992. }
  1993. }
  1994. }
  1995. func pdfListViewAddAnnotations(_ pdfListView: CPDFListView!, forAdd annotations: [CPDFAnnotation]!, in pdfPage: CPDFPage!) {
  1996. var addRedact = false
  1997. var saveWatermark = false
  1998. var saveWatermarkType: KMSubscribeWaterMarkType = .none
  1999. for anno in annotations {
  2000. if (anno.isKind(of: CPDFRedactAnnotation.self)) {
  2001. addRedact = true
  2002. // break
  2003. } else if (anno.isKind(of: CPDFLinkAnnotation.self)) { // link 注释
  2004. saveWatermark = true
  2005. saveWatermarkType = .link
  2006. } else if (anno.isKind(of: CPDFListStampAnnotation.self)) { // 图章注释
  2007. saveWatermark = true
  2008. saveWatermarkType = .stamp
  2009. } else if (anno.isKind(of: CPDFListSignatureAnnotation.self)) { // 签名注释
  2010. saveWatermark = true
  2011. saveWatermarkType = .sign
  2012. }
  2013. }
  2014. if (saveWatermark) {
  2015. self.recordSaveWatermarkFlag(type: saveWatermarkType)
  2016. }
  2017. self.hasAddRedact = addRedact
  2018. if self.isReadMode || self.listView.toolMode == .moveToolMode {
  2019. self.listView.toolMode = .textToolMode
  2020. self.listView.annotationType = .unkown
  2021. self.toolbarController.toolbarType = .Annatiton
  2022. }
  2023. if (self.rightMouseEventing) {
  2024. self.rightMouseEventing = false
  2025. if (self.toolbarController.ignoreCurrentAnnotationTypeChange && self.listView.annotationType == .ink) {
  2026. self.listView.toolMode = .textToolMode
  2027. self.listView.annotationType = .unkown
  2028. }
  2029. }
  2030. self.toolbarController.ignoreCurrentAnnotationTypeChange = false
  2031. }
  2032. func pdfListViewDidSelectionEnd(_ pdfListView: CPDFListView!) {
  2033. if (!self.listView.isEqual(to: pdfListView)) {
  2034. return
  2035. }
  2036. if (self.listView.toolMode != .selectToolMode) {
  2037. return
  2038. }
  2039. if (self.topTipBox.isHidden || self.topTipBox.contentView?.subviews.count == 0) {
  2040. return
  2041. }
  2042. let tipView = self.topTipBox.contentView?.subviews.first
  2043. if (tipView?.isKind(of: KMCropTipView.self) == false) {
  2044. return
  2045. }
  2046. (tipView as! KMCropTipView).setString(string: "请按 Enter 键确定裁剪区域")
  2047. }
  2048. func pdfListViewKeyDowClosePanel(_ speedy: CPDFViewSidebarSpeedMode, event theEvent: NSEvent!) {
  2049. if(speedy == .right) {
  2050. self.toggleRightPane()
  2051. } else if (speedy == .left) {
  2052. self.menuItemAction_hiddenLeftSide(speedy)
  2053. }
  2054. }
  2055. func pdfListViewEventMarkupColor(with annotation: CPDFAnnotation!) -> [NSColor]! {
  2056. if (annotation.isKind(of: CPDFMarkupAnnotation.self)) {
  2057. if (annotation as! CPDFMarkupAnnotation).markupType() == .highlight {
  2058. return KMAnnotationPropertiesColorManager.manager.markHighlightColors
  2059. } else {
  2060. return KMAnnotationPropertiesColorManager.manager.markOtherColors
  2061. }
  2062. } else {
  2063. return KMAnnotationPropertiesColorManager.manager.markOtherColors
  2064. }
  2065. }
  2066. func pdfListViewHaveDocumentAttribute() -> Bool {
  2067. if(!self.listView.document.allowsCopying) {
  2068. KMPasswordInputWindow.openWindow(window: self.view.window!, type: .owner, url: self.listView.document.documentURL) { [weak self] result, password in
  2069. if (result == .cancel) {
  2070. return
  2071. }
  2072. self?.isSaveKeyChain = false
  2073. self?.listView.document.unlock(withPassword: password)
  2074. self?.hiddenSecureLimitTip()
  2075. }
  2076. return false
  2077. }
  2078. return true
  2079. }
  2080. func addTopTip(_ view: NSView?) {
  2081. if (Thread.isMainThread) {
  2082. if (view == nil) {
  2083. let contentView: NSView = self.topTipBox.contentView!
  2084. for subview in contentView.subviews {
  2085. subview.removeFromSuperview()
  2086. }
  2087. self.topTipBox.isHidden = true
  2088. return
  2089. }
  2090. let contentView: NSView = self.topTipBox.contentView!
  2091. for subview in contentView.subviews {
  2092. subview.removeFromSuperview()
  2093. }
  2094. self.topTipBox.isHidden = false
  2095. self.topTipBox.contentView?.addSubview(view!)
  2096. } else {
  2097. DispatchQueue.main.async {
  2098. if (view == nil) {
  2099. let contentView: NSView = self.topTipBox.contentView!
  2100. for subview in contentView.subviews {
  2101. subview.removeFromSuperview()
  2102. }
  2103. self.topTipBox.isHidden = true
  2104. return
  2105. }
  2106. let contentView: NSView = self.topTipBox.contentView!
  2107. for subview in contentView.subviews {
  2108. subview.removeFromSuperview()
  2109. }
  2110. self.topTipBox.isHidden = false
  2111. self.topTipBox.contentView?.addSubview(view!)
  2112. }
  2113. }
  2114. }
  2115. func pdfListView(_ sender: CPDFListView!, showSnapshotAtPageNumber pageNum: Int, for rect: NSRect, scaleFactor: CGFloat, autoFits: Bool) {
  2116. let swc = KMSnapshotWindowController(windowNibName: "SnapshotWindow")
  2117. swc.delegate = self
  2118. swc.setPdfDocument(self.listView.document, goToPageNumber: pageNum, rect: rect, scaleFactor: scaleFactor, autoFits: autoFits)
  2119. // [swc setForceOnTop:[self interactionMode] != SKNormalMode];
  2120. self.myDocument?.addWindowController(swc)
  2121. }
  2122. // MARK: Split View
  2123. func changePDFDocument(isChange: Bool, replaceBlock: @escaping (String) -> Void) {
  2124. let openPanel = NSOpenPanel()
  2125. openPanel.allowedFileTypes = ["pdf", "PDF"]
  2126. openPanel.allowsMultipleSelection = false
  2127. guard let mainWindow = NSApp.mainWindow else {
  2128. return
  2129. }
  2130. openPanel.beginSheetModal(for: mainWindow) { [weak self] response in
  2131. if response == NSApplication.ModalResponse.OK {
  2132. guard let url = openPanel.url else {
  2133. return
  2134. }
  2135. if let document = CPDFDocument(url: url) {
  2136. self!.secondaryPdfView.document = nil
  2137. self!.secondaryPdfView.document = document
  2138. if isChange {
  2139. self!.openSecondaryPdfView!.view.removeFromSuperview()
  2140. }
  2141. replaceBlock(document.documentURL?.path ?? "")
  2142. } else {
  2143. let alert = NSAlert()
  2144. alert.alertStyle = .critical
  2145. alert.messageText = NSLocalizedString("An error occurred while opening this document. The file is damaged and could not be repaired.", comment: "")
  2146. alert.runModal()
  2147. }
  2148. }
  2149. }
  2150. }
  2151. }
  2152. extension KMMainViewController: KMEditImagePropertyViewControllerDelegate {
  2153. func editImagePropertyViewControllerDidChanged(controller: KMEditImagePropertyViewController, type: KMEditImagePropertyViewControllerChangeType) {
  2154. self.isPDFTextImageEdited = true
  2155. }
  2156. }
  2157. extension KMMainViewController: KMSnapshotWindowControllerDelegate {
  2158. func snapshotControllerWillClose(_ controller: KMSnapshotWindowController) {
  2159. var flag: KMSnapshotModel?
  2160. for model in self.leftSideViewController.snapshots {
  2161. if controller.isEqual(model.windowC) {
  2162. flag = model
  2163. }
  2164. }
  2165. if flag != nil {
  2166. self.leftSideViewController.snapshots.removeObject(flag!)
  2167. Task { @MainActor in
  2168. self.leftSideViewController.snapshotTableView.reloadData()
  2169. if self.leftSideViewController.snapshots.isEmpty {
  2170. self.leftSideViewController.leftView.segmentedControl.selectedSegment = 3
  2171. }
  2172. }
  2173. }
  2174. }
  2175. func snapshotController(_ controller: KMSnapshotWindowController, miniaturizedRect isMiniaturize: Bool) -> NSRect {
  2176. var row = NSNotFound
  2177. for (i,sp) in self.leftSideViewController.snapshots.enumerated() {
  2178. if controller.isEqual(sp.windowC) {
  2179. row = i
  2180. }
  2181. }
  2182. if isMiniaturize {
  2183. // if (isMiniaturize && [self interactionMode] != SKPresentationMode) {
  2184. // if ([self interactionMode] != SKLegacyFullScreenMode && [self rightSidePaneIsOpen] == NO) {
  2185. // [self toggleRightSidePane:self];
  2186. // } else if ([self interactionMode] == SKLegacyFullScreenMode && ([rightSideWindow state] == NSDrawerClosedState || [rightSideWindow state] == NSDrawerClosingState)) {
  2187. // [rightSideWindow expand];
  2188. // [NSTimer scheduledTimerWithTimeInterval:1.0 target:self selector:@selector(hideRightSideWindow:) userInfo:NULL repeats:NO];
  2189. // }
  2190. // [self setRightSidePaneState:SKSidePaneStateSnapshot];
  2191. if (row != NSNotFound) {
  2192. self.leftSideViewController.leftView.segmentedControl.selectedSegment = 3
  2193. self.leftSideViewController.snapshotTableView.scrollRowToVisible(row)
  2194. }
  2195. }
  2196. var rect: NSRect = .zero
  2197. if (row != NSNotFound) {
  2198. rect = self.leftSideViewController.snapshotTableView.frameOfCell(atColumn: 0, row: row)
  2199. } else {
  2200. rect.origin = KMBottomLeftPoint(self.leftSideViewController.snapshotTableView.visibleRect)
  2201. rect.size.width = 1.0
  2202. rect.size.height = 1.0
  2203. }
  2204. rect = self.leftSideViewController.snapshotTableView.convertRectToScreen(rect)
  2205. return rect
  2206. }
  2207. func snapshotControllerDidFinishSetup(_ controller: KMSnapshotWindowController) {
  2208. // NSImage *image = [controller thumbnailWithSize:snapshotCacheSize];
  2209. let image = controller.thumbnailWithSize(400)
  2210. controller.thumbnail = image
  2211. let model = KMSnapshotModel()
  2212. model.windowC = controller
  2213. self.leftSideViewController.snapshots.append(model)
  2214. Task { @MainActor in
  2215. self.leftSideViewController.snapshotTableView.reloadData()
  2216. }
  2217. }
  2218. }