KMMainViewController.swift 147 KB

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