KMMainViewController.swift 129 KB

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