KMMainViewController.swift 148 KB

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