KMMainViewController.swift 150 KB

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