KMMainViewController.swift 152 KB

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