KMMainViewController.swift 148 KB

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