KMMainViewController.swift 142 KB

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