KMMainViewController.swift 168 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830183118321833183418351836183718381839184018411842184318441845184618471848184918501851185218531854185518561857185818591860186118621863186418651866186718681869187018711872187318741875187618771878187918801881188218831884188518861887188818891890189118921893189418951896189718981899190019011902190319041905190619071908190919101911191219131914191519161917191819191920192119221923192419251926192719281929193019311932193319341935193619371938193919401941194219431944194519461947194819491950195119521953195419551956195719581959196019611962196319641965196619671968196919701971197219731974197519761977197819791980198119821983198419851986198719881989199019911992199319941995199619971998199920002001200220032004200520062007200820092010201120122013201420152016201720182019202020212022202320242025202620272028202920302031203220332034203520362037203820392040204120422043204420452046204720482049205020512052205320542055205620572058205920602061206220632064206520662067206820692070207120722073207420752076207720782079208020812082208320842085208620872088208920902091209220932094209520962097209820992100210121022103210421052106210721082109211021112112211321142115211621172118211921202121212221232124212521262127212821292130213121322133213421352136213721382139214021412142214321442145214621472148214921502151215221532154215521562157215821592160216121622163216421652166216721682169217021712172217321742175217621772178217921802181218221832184218521862187218821892190219121922193219421952196219721982199220022012202220322042205220622072208220922102211221222132214221522162217221822192220222122222223222422252226222722282229223022312232223322342235223622372238223922402241224222432244224522462247224822492250225122522253225422552256225722582259226022612262226322642265226622672268226922702271227222732274227522762277227822792280228122822283228422852286228722882289229022912292229322942295229622972298229923002301230223032304230523062307230823092310231123122313231423152316231723182319232023212322232323242325232623272328232923302331233223332334233523362337233823392340234123422343234423452346234723482349235023512352235323542355235623572358235923602361236223632364236523662367236823692370237123722373237423752376237723782379238023812382238323842385238623872388238923902391239223932394239523962397239823992400240124022403240424052406240724082409241024112412241324142415241624172418241924202421242224232424242524262427242824292430243124322433243424352436243724382439244024412442244324442445244624472448244924502451245224532454245524562457245824592460246124622463246424652466246724682469247024712472247324742475247624772478247924802481248224832484248524862487248824892490249124922493249424952496249724982499250025012502250325042505250625072508250925102511251225132514251525162517251825192520252125222523252425252526252725282529253025312532253325342535253625372538253925402541254225432544254525462547254825492550255125522553255425552556255725582559256025612562256325642565256625672568256925702571257225732574257525762577257825792580258125822583258425852586258725882589259025912592259325942595259625972598259926002601260226032604260526062607260826092610261126122613261426152616261726182619262026212622262326242625262626272628262926302631263226332634263526362637263826392640264126422643264426452646264726482649265026512652265326542655265626572658265926602661266226632664266526662667266826692670267126722673267426752676267726782679268026812682268326842685268626872688268926902691269226932694269526962697269826992700270127022703270427052706270727082709271027112712271327142715271627172718271927202721272227232724272527262727272827292730273127322733273427352736273727382739274027412742274327442745274627472748274927502751275227532754275527562757275827592760276127622763276427652766276727682769277027712772277327742775277627772778277927802781278227832784278527862787278827892790279127922793279427952796279727982799280028012802280328042805280628072808280928102811281228132814281528162817281828192820282128222823282428252826282728282829283028312832283328342835283628372838283928402841284228432844284528462847284828492850285128522853285428552856285728582859286028612862286328642865286628672868286928702871287228732874287528762877287828792880288128822883288428852886288728882889289028912892289328942895289628972898289929002901290229032904290529062907290829092910291129122913291429152916291729182919292029212922292329242925292629272928292929302931293229332934293529362937293829392940294129422943294429452946294729482949295029512952295329542955295629572958295929602961296229632964296529662967296829692970297129722973297429752976297729782979298029812982298329842985298629872988298929902991299229932994299529962997299829993000300130023003300430053006300730083009301030113012301330143015301630173018301930203021302230233024302530263027302830293030303130323033303430353036303730383039304030413042304330443045304630473048304930503051305230533054305530563057305830593060306130623063306430653066306730683069307030713072307330743075307630773078307930803081308230833084308530863087308830893090309130923093309430953096309730983099310031013102310331043105310631073108310931103111311231133114311531163117311831193120312131223123312431253126312731283129313031313132313331343135313631373138313931403141314231433144314531463147314831493150315131523153315431553156315731583159316031613162316331643165316631673168316931703171317231733174317531763177317831793180318131823183318431853186318731883189319031913192319331943195319631973198319932003201320232033204320532063207320832093210321132123213321432153216321732183219322032213222322332243225322632273228322932303231323232333234323532363237323832393240324132423243324432453246324732483249325032513252325332543255325632573258325932603261326232633264326532663267326832693270327132723273327432753276327732783279328032813282328332843285328632873288328932903291329232933294329532963297329832993300330133023303330433053306330733083309331033113312331333143315331633173318331933203321332233233324332533263327332833293330333133323333333433353336333733383339334033413342334333443345334633473348334933503351335233533354335533563357335833593360336133623363336433653366336733683369337033713372337333743375337633773378337933803381338233833384338533863387338833893390339133923393339433953396339733983399340034013402340334043405340634073408340934103411341234133414341534163417341834193420342134223423342434253426342734283429343034313432343334343435343634373438343934403441344234433444344534463447344834493450345134523453345434553456345734583459346034613462346334643465346634673468346934703471347234733474347534763477347834793480348134823483348434853486348734883489349034913492349334943495349634973498349935003501350235033504350535063507350835093510351135123513351435153516351735183519352035213522352335243525352635273528352935303531353235333534353535363537353835393540354135423543354435453546354735483549355035513552355335543555355635573558355935603561356235633564356535663567356835693570357135723573357435753576357735783579358035813582358335843585358635873588358935903591359235933594359535963597359835993600360136023603360436053606360736083609361036113612361336143615361636173618361936203621362236233624362536263627362836293630363136323633363436353636363736383639364036413642364336443645364636473648364936503651365236533654365536563657365836593660366136623663366436653666366736683669367036713672367336743675367636773678367936803681368236833684368536863687368836893690369136923693369436953696369736983699370037013702370337043705370637073708370937103711371237133714371537163717371837193720372137223723372437253726372737283729373037313732373337343735373637373738373937403741374237433744374537463747374837493750375137523753375437553756375737583759376037613762376337643765376637673768376937703771377237733774377537763777377837793780378137823783378437853786378737883789379037913792379337943795379637973798379938003801380238033804380538063807380838093810381138123813381438153816381738183819382038213822382338243825382638273828382938303831383238333834383538363837383838393840384138423843384438453846384738483849385038513852385338543855385638573858385938603861386238633864386538663867386838693870387138723873387438753876387738783879388038813882388338843885388638873888388938903891389238933894389538963897389838993900390139023903390439053906390739083909391039113912391339143915391639173918391939203921392239233924392539263927392839293930393139323933393439353936393739383939394039413942394339443945394639473948394939503951395239533954395539563957395839593960396139623963396439653966396739683969397039713972397339743975397639773978397939803981398239833984398539863987398839893990399139923993399439953996399739983999400040014002400340044005
  1. //
  2. // KMMainViewController.swift
  3. // PDF Reader Pro
  4. //
  5. // Created by wanjun on 2022/12/15.
  6. //
  7. import Cocoa
  8. @objcMembers class KMMainViewController: KMBaseViewController, NSTextFieldDelegate {
  9. @IBOutlet var contendBox: NSBox!
  10. @IBOutlet var toolbarBox: NSBox! //工具栏Box
  11. @IBOutlet var bottomContendBox: NSBox! //
  12. @IBOutlet var sidebarBox: NSBox! //左侧边栏Box
  13. @IBOutlet var infoContendSplitView: KMPDFSplitView!
  14. @IBOutlet var infoSplitLeftView: NSView!
  15. @IBOutlet var infoSplitRightView: NSView!
  16. @IBOutlet var infoSplitCenterView: NSView!
  17. @IBOutlet var pdfSplitView: NSSplitView!
  18. @IBOutlet var pdfSplitTopView: NSView!
  19. @IBOutlet var pdfSplitBottomView: NSView!
  20. @IBOutlet var toolbarBoxHeightConst: NSLayoutConstraint!
  21. @IBOutlet var infoSplitViewLeftConst: NSLayoutConstraint!
  22. var viewManager: KMPDFViewManager = KMPDFViewManager.init()
  23. var toolbarManager: KMPDFToolbarManager = KMPDFToolbarManager.init()
  24. var listView: CPDFListView = CPDFListView.init()
  25. var document: CPDFDocument?
  26. var myDocument: NSDocument?
  27. var insertDocuments: Set<CPDFDocument> = [] //插入新文档时,SDK会出现崩溃,临时记录
  28. //工具栏
  29. private var pdfToolbarController: KMPDFToolbarController?
  30. //BOTA SideBar
  31. private var sideBarController: KMPDFSideBarController?
  32. //页面编辑
  33. private var pageEditViewController: KMNPageEditViewController?
  34. //DisplaySetting
  35. private var displaySettingController: KMNDisplayViewController?
  36. //SPlitPDF分屏视图
  37. private var splitPDFController: KMSplitPDFViewController?
  38. private var pdfBottomToolbar: KMSplitToolbar?
  39. //PPT操作界面
  40. var presentationTopViewController: KMPresentationTopViewController?
  41. //MARK: - 旧代码,有需要用到的拿出来,写好备注
  42. @IBOutlet var PDFContendView: NSView!
  43. @IBOutlet var centerContentView: NSView!
  44. @IBOutlet weak var readContentView: NSView!
  45. @IBOutlet weak var tipCurrentPageBox: KMBox!
  46. @IBOutlet weak var rightView: NSView!
  47. @IBOutlet weak var leftView: NSView!
  48. @IBOutlet weak var mianSplitView: KMSplitView!
  49. @IBOutlet weak var newPDFSplitView: KMSplitView!
  50. @IBOutlet weak var pdfContentView: NSView!
  51. @IBOutlet var childToolbarController: KMToolbarViewController!
  52. @IBOutlet var toolbarController: KMToolbarController!
  53. @IBOutlet weak var heightOffset: NSLayoutConstraint!
  54. //页码显示器
  55. @IBOutlet weak var pageNumberDisplayView: KMPageNumberDisplayView!
  56. var model = KMMainModel()
  57. //自动滚动
  58. var autoFlowOptionsSheetController: KMAutoFlowOptionsSheetController?
  59. //Search
  60. var searchIndex: Int = 0
  61. //Form
  62. var formAlertView: KMFormAlertView?
  63. //Secure
  64. var secureAlertView: KMSecureAlertView?
  65. //对比
  66. var isCompareModel: Bool = false {
  67. didSet {
  68. self.toolbarController.updataItemVisible()
  69. }
  70. }
  71. //合并
  72. var mergeWindowController: KMMergeWindowController?
  73. //水印
  74. var watermarkWindowController: KMWatermarkWindowController?
  75. //密码弹窗
  76. var passwordWindow: KMPasswordInputWindow?
  77. //对比
  78. var compressWIndowControllerNew: KMCompressWIndowControllerNew?
  79. //
  80. var securityWindowController: KMSecurityWindowController?
  81. //引导
  82. var guideInfoWindowController: KMGuideInfoWindowController?
  83. //春季活动
  84. var recommondPopWindowVC: KMRecommondPopWindow?
  85. var removeAllAnnotationsStore = KMPDFViewRemoveAllAnnotationsStore()
  86. private var _needSave = false
  87. var needSave: Bool {
  88. set {
  89. _needSave = newValue
  90. if (_needSave == false) {
  91. self.clearIsPDFDocumentEdited()
  92. }
  93. }
  94. get {
  95. return _needSave
  96. }
  97. }
  98. var isPDFDocumentEdited: Bool {
  99. get {
  100. return self.model.isPDFDocumentEdited
  101. }
  102. }
  103. var leftSideViewController: KMLeftSideViewController = KMLeftSideViewController.init(type: KMLeftMethodMode())
  104. var rightSideViewController: KMRightSideViewController!
  105. var searchResults: [KMSearchMode] = []
  106. var mwcFlags: MwcFlags = MwcFlags()
  107. weak var browserWindowController: KMBrowserWindowController? //慎直接使用这个方法
  108. var cropSettingWindowController: KMCropSettingWindowController!
  109. var currentWindowController: NSWindowController!
  110. var savedNormalSetup: NSMutableDictionary = NSMutableDictionary()
  111. //数字签名
  112. var digitalSignController: KMPDFDigitalSignViewController?
  113. var redactController: KMPDFRedactViewController!
  114. let CPDFOfficeLeftSidePaneWidthKey = "CPDFOfficeLeftSidePaneWidthKey"
  115. let CPDFOfficeRightSidePaneWidthKey = "CPDFOfficeRightSidePaneWidthKey"
  116. var extract: KMExtractImageWindowController?
  117. var functionWidth: Double {
  118. get {
  119. if self.viewManager.isPDFReadMode {
  120. if !self.model.isShowBOTA {
  121. return 0
  122. }
  123. }
  124. return 48-4
  125. }
  126. }
  127. var pageNumber: UInt?
  128. var secondaryPdfContentView: NSView?
  129. var lastSplitPDFHeight: Float = 0.0
  130. var pdfEditController: KMPDFEditViewController? {
  131. get {
  132. return self.getPDFEditController()
  133. }
  134. }
  135. var autoSaveTimer: Timer?
  136. private var _documentFirstLoad: Bool = true
  137. var eventMonitor: Any?
  138. var keyEventMonitor: Any?
  139. var mouseRightMenuEvent: NSEvent?
  140. lazy private var homeVC: KMNHomeViewController? = {
  141. let vc = KMNHomeViewController()
  142. return vc
  143. }()
  144. private var background_mask: NSView?
  145. fileprivate var _secureOptions: [CPDFDocumentWriteOption : Any]?
  146. var secureOptions: [CPDFDocumentWriteOption : Any]? {
  147. get {
  148. return self._secureOptions
  149. }
  150. }
  151. var documentAttribute: [CPDFDocumentAttribute : Any]?
  152. fileprivate var _removeSecureFlag = false
  153. var removeSecureFlag: Bool {
  154. get {
  155. return self._removeSecureFlag
  156. }
  157. }
  158. fileprivate var _saveWatermarkFlag = false
  159. var saveWatermarkFlag: Bool {
  160. get {
  161. return self._saveWatermarkFlag
  162. }
  163. }
  164. private var mainWindow_: NSWindow?
  165. var mainWindow: NSWindow? {
  166. get {
  167. return self.mainWindow_
  168. }
  169. set {
  170. self.mainWindow_ = newValue
  171. }
  172. }
  173. var setDocument: CPDFDocument? {
  174. get {
  175. return document
  176. }
  177. set {
  178. if document != newValue {
  179. document = newValue
  180. }
  181. listView.document = document
  182. listView.document?.delegate = self
  183. self.listView.layoutDocumentView()
  184. self.leftSideViewController.refreshUIForDocumentChanged()
  185. }
  186. }
  187. var setPageNumber: UInt {
  188. get {
  189. return pageNumber!
  190. }
  191. set {
  192. let pageCount = listView.document?.pageCount ?? 0
  193. var value = newValue
  194. if value > pageCount {
  195. value = pageCount
  196. }
  197. if value > 0 && listView.currentPage().pageIndex() != value-1 {
  198. listView.go(to: listView.document?.page(at: value-1))
  199. }
  200. if pageNumber != value {
  201. pageNumber = value
  202. }
  203. }
  204. }
  205. let editPDFHanddler = KMEditPDfHanddler()
  206. var distanceMeasureInfoWindowController: CDistanceMeasureInfoWindowController?
  207. var perimeterMeasureInfoWindowController: CPerimeterMeasureInfoWindowController?
  208. var areaMeasureInfoWindowController: CAreaMeasureInfoWindowController?
  209. var srHanddler: KMSearchReplaceHanddler = KMSearchReplaceHanddler()
  210. //MARK: - func
  211. deinit {
  212. NotificationCenter.default.removeObserver(self)
  213. self.listView.delegate = nil
  214. self.listView.document?.delegate = nil
  215. self.editPDFHanddler.clearData()
  216. self.removeEventMonitor()
  217. self.removeKeyEventMonitor()
  218. }
  219. override func viewDidLoad() {
  220. super.viewDidLoad()
  221. // Do view setup here.
  222. toolbarManager.pdfViewManager = viewManager
  223. }
  224. override func viewDidAppear() {
  225. super.viewDidAppear()
  226. setupUI()
  227. }
  228. func setupUI() {
  229. initPDFView()
  230. initToolbar()
  231. initSideBar()
  232. setUpSplitView()
  233. }
  234. //MARK: - PDFView
  235. func initPDFView() {
  236. listView.autoresizingMask = [.width, .height]
  237. listView.document = self.document
  238. listView.delegate = self
  239. listView.pdfListViewDelegate = self
  240. reloadPDFSplitInfo()
  241. }
  242. //MARK: - SplitView
  243. func setUpSplitView() {
  244. infoContendSplitView.wantsLayer = true
  245. infoContendSplitView.layer?.backgroundColor = NSColor.clear.cgColor
  246. infoContendSplitView.delegate = self
  247. infoContendSplitView.layer?.masksToBounds = true
  248. infoContendSplitView.setPosition(-10, ofDividerAt: 0)
  249. infoContendSplitView.setPosition(CGRectGetWidth(infoContendSplitView.frame), ofDividerAt: 1)
  250. }
  251. func setupSplitPDFController() {
  252. if splitPDFController == nil {
  253. splitPDFController = KMSplitPDFViewController.init()
  254. }
  255. splitPDFController?.view.frame = pdfSplitBottomView.bounds
  256. splitPDFController?.view.autoresizingMask = [.height, .width]
  257. splitPDFController?.viewManager = self.viewManager
  258. splitPDFController?.delegate = self
  259. splitPDFController?.reloadData()
  260. pdfSplitBottomView.addSubview(splitPDFController!.view)
  261. }
  262. //MARK: - 工具栏
  263. func initToolbar() {
  264. toolbarBox.borderWidth = 0
  265. if pdfToolbarController == nil {
  266. pdfToolbarController = KMPDFToolbarController.init()
  267. }
  268. pdfToolbarController?.view.frame = toolbarBox.bounds
  269. pdfToolbarController?.view.autoresizingMask = [.width, .height]
  270. pdfToolbarController?.delegate = self
  271. toolbarBox.contentView = pdfToolbarController?.view
  272. pdfToolbarController?.viewManager = viewManager
  273. pdfToolbarController?.toolbarManager = toolbarManager
  274. pdfToolbarController?.pdfView = listView
  275. pdfToolbarController?.setUpData()
  276. refreshToolbarView()
  277. }
  278. func refreshToolbarView() {
  279. let _manager = viewManager
  280. if _manager.toolMode == .Markup ||
  281. _manager.toolMode == .Edit ||
  282. _manager.toolMode == .Form ||
  283. _manager.toolMode == .Fill ||
  284. _manager.toolMode == .Convert ||
  285. _manager.toolMode == .Protect ||
  286. _manager.toolMode == .Tools {
  287. toolbarBoxHeightConst.constant = 80
  288. } else {
  289. if _manager.isPageEditMode {
  290. toolbarBoxHeightConst.constant = 80
  291. } else {
  292. toolbarBoxHeightConst.constant = 40
  293. }
  294. }
  295. }
  296. //MARK: - 侧边栏
  297. func initSideBar() {
  298. sidebarBox.borderWidth = 0
  299. if sideBarController == nil {
  300. sideBarController = KMPDFSideBarController.init()
  301. }
  302. sideBarController?.view.frame = sidebarBox.bounds
  303. sideBarController?.view.autoresizingMask = [.width, .height]
  304. sidebarBox.contentView = sideBarController?.view
  305. sideBarController?.pdfView = listView
  306. sideBarController?.delegate = self
  307. sideBarController?.pdfViewManager = viewManager
  308. sideBarController?.reloadData()
  309. }
  310. //MARK: - PDFDisplayView
  311. func updatePDFDisplaySettingView() {
  312. if viewManager.showDisplayView {
  313. infoSplitViewLeftConst.constant = 264
  314. } else {
  315. infoSplitViewLeftConst.constant = 44
  316. }
  317. if viewManager.showDisplayView {
  318. if displaySettingController == nil {
  319. displaySettingController = KMNDisplayViewController.init()
  320. }
  321. displaySettingController?.view.frame = CGRectMake(0, 0, 264, CGRectGetHeight(bottomContendBox.frame))
  322. displaySettingController?.view.autoresizingMask = [.height, .maxXMargin]
  323. bottomContendBox.addSubview(displaySettingController!.view)
  324. displaySettingController?.pdfView = self.listView
  325. displaySettingController?.viewManager = self.viewManager
  326. displaySettingController?.delegate = self
  327. displaySettingController?.reloadData()
  328. } else {
  329. displaySettingController?.view.removeFromSuperview()
  330. displaySettingController = nil
  331. }
  332. }
  333. //MARK: - 页面编辑
  334. func enterPageEditMode() {
  335. pageEditViewController = KMNPageEditViewController(self.document)
  336. if(pageEditViewController != nil) {
  337. bottomContendBox.addSubview(pageEditViewController!.view)
  338. pageEditViewController?.view.frame = bottomContendBox.bounds
  339. pageEditViewController?.thumbnailBaseViewDelegate = self
  340. pageEditViewController?.view.autoresizingMask = [.width,.height]
  341. }
  342. }
  343. func exitPageEditMode() {
  344. if pageEditViewController != nil {
  345. pageEditViewController?.view.removeFromSuperview()
  346. pageEditViewController = nil
  347. }
  348. }
  349. //MARK: - 阅读模式
  350. func openPDFReadMode() {
  351. if viewManager.showDisplayView {
  352. viewManager.showDisplayView = false
  353. pdfToolbarController?.reloadLeftIconView()
  354. updatePDFDisplaySettingView()
  355. }
  356. infoSplitViewLeftConst.constant = 0
  357. toolbarBoxHeightConst.constant = 0
  358. }
  359. func exitPDFReadMode() {
  360. viewManager.isPDFReadMode = false
  361. infoSplitViewLeftConst.constant = 44
  362. refreshToolbarView()
  363. }
  364. //MARK: - PPT
  365. func togglePresentation(_ sender: Any?) {
  366. if self.canExitPresentation() {
  367. exitFullScreen()
  368. } else if self.canEnterPresentation() {
  369. NotificationCenter.default.addObserver(self, selector: #selector(willEnterInteractionModeNotification), name: NSWindow.willEnterInteractionModeNotification, object: nil)
  370. NotificationCenter.default.addObserver(self, selector: #selector(didEnterInteractionModeNotification), name: NSWindow.didEnterInteractionModeNotification, object: nil)
  371. NotificationCenter.default.addObserver(self, selector: #selector(willShowFullScreenNotification), name: NSWindow.willShowFullScreenNotification, object: nil)
  372. NotificationCenter.default.addObserver(self, selector: #selector(didShowFullScreenNotification), name: NSWindow.didShowFullScreenNotification, object: nil)
  373. view.window?.enterPresentation(provider: self)
  374. }
  375. }
  376. func enterPresentationMode() {
  377. let scrollView = listView.documentView().enclosingScrollView
  378. savedNormalSetup.setValue(scrollView?.hasHorizontalScroller, forKey: KMMainModel.Key.kHasHorizontalScroller)
  379. savedNormalSetup.setValue(scrollView?.hasVerticalScroller, forKey: KMMainModel.Key.kHasVerticalsCroller)
  380. savedNormalSetup.setValue(scrollView?.autohidesScrollers, forKey: KMMainModel.Key.kAutoHidesScrollers)
  381. listView.backgroundColor = NSColor.clear
  382. listView.setDisplay(.singlePage)
  383. listView.autoScales = true
  384. listView.displayBox = .cropBox
  385. listView.displaysPageBreaks = false
  386. scrollView?.autohidesScrollers = true
  387. scrollView?.hasHorizontalScroller = false
  388. scrollView?.hasVerticalScroller = false
  389. listView.setCurrentSelection(nil, animate: true)
  390. }
  391. func exitPresentationMode() {
  392. self.selectDisplay(display: KMPDFDisplayType(rawValue: KMPDFDisplayType.RawValue(self.listView.fetchDisplayViewMode().rawValue)) ?? .singlePage, viewSettingIsReload: false)
  393. NotificationCenter.default.removeObserver(self, name: NSWindow.willEnterInteractionModeNotification, object: nil)
  394. NotificationCenter.default.removeObserver(self, name: NSWindow.didEnterInteractionModeNotification, object: nil)
  395. NotificationCenter.default.removeObserver(self, name: NSWindow.willShowFullScreenNotification, object: nil)
  396. NotificationCenter.default.removeObserver(self, name: NSWindow.willShowFullScreenNotification, object: nil)
  397. }
  398. func exitFullScreen() {
  399. if self.canExitPresentation() == true {
  400. let mainDocument = self.myDocument as? KMMainDocument
  401. let browserWindowController = mainDocument?.browser?.windowController as? KMBrowserWindowController
  402. browserWindowController?.exitFullscreen()
  403. }
  404. }
  405. func exitFullscreenMode() {
  406. if self.interactionMode == .presentation {
  407. self.exitPresentationMode()
  408. }
  409. self.applyPDFSettings(self.savedNormalSetup)
  410. self.savedNormalSetup.removeAllObjects()
  411. listView.layoutDocumentView()
  412. listView.requiresDisplay()
  413. if let backgroundColor = UserDefaults.standard.color(forKey: KMBackgroundColorKey) {
  414. listView.backgroundColor = backgroundColor
  415. }
  416. }
  417. func applyPDFSettings(_ setup: NSDictionary) {
  418. if let data = setup.object(forKey: KMMainModel.Key.kAutoScales) as? NSNumber {
  419. self.listView.autoScales = data.boolValue
  420. }
  421. if self.listView.autoScales == false {
  422. if let data = setup.object(forKey: KMMainModel.Key.kScaleFactor) as? NSNumber {
  423. self.listView.scaleFactor = data.floatValue.cgFloat
  424. }
  425. }
  426. if let data = setup.object(forKey: KMMainModel.Key.kDisplayMode) as? NSNumber {
  427. self.listView.setDisplay(CPDFDisplayViewMode(rawValue: data.intValue) ?? .singlePage)
  428. }
  429. if let data = setup.object(forKey: KMMainModel.Key.kDisplaysAsBook) as? NSNumber {
  430. self.listView.displaysAsBook = data.boolValue
  431. }
  432. if let data = setup.object(forKey: KMMainModel.Key.kDisplaysPageBreaks) as? NSNumber {
  433. self.listView.displaysPageBreaks = data.boolValue
  434. }
  435. if let data = setup.object(forKey: KMMainModel.Key.kDisplayBox) as? NSNumber {
  436. }
  437. self.listView.layoutDocumentView()
  438. }
  439. func currentPDFSettings() -> NSDictionary {
  440. let setup = NSMutableDictionary()
  441. setup[KMMainModel.Key.kDisplaysPageBreaks] = NSNumber(value: listView.displaysPageBreaks)
  442. setup[KMMainModel.Key.kDisplaysAsBook] = NSNumber(value: listView.displaysAsBook)
  443. setup[KMMainModel.Key.kDisplayBox] = NSNumber(value: listView.displayBox.rawValue)
  444. setup[KMMainModel.Key.kScaleFactor] = NSNumber(value: listView.scaleFactor)
  445. setup[KMMainModel.Key.kAutoScales] = NSNumber(value: listView.autoScales)
  446. setup[KMMainModel.Key.kDisplayMode] = NSNumber(value: listView.fetchDisplayViewMode().rawValue)
  447. return setup
  448. }
  449. func canEnterFullscreen() -> Bool {
  450. if (mwcFlags.isSwitchingFullScreen != 0) {
  451. return false
  452. }
  453. if useNativeFullScreen() {
  454. return interactionMode == .normal || interactionMode == .presentation
  455. } else {
  456. return !self.listView.document.isLocked && (interactionMode == .normal || interactionMode == .presentation) && self.view.window?.tabbedWindows?.count ?? 0 < 2
  457. }
  458. }
  459. override func canEnterPresentation() -> Bool {
  460. let can = super.canEnterPresentation()
  461. if can == false {
  462. return false
  463. }
  464. guard let doc = self.listView.document, doc.isLocked == false else {
  465. return false
  466. }
  467. return can
  468. }
  469. func fadeOutFullScreenWindow() {
  470. guard let fullScreenWindow = self.view.window as? KMFullScreenWindow else {
  471. NSSound.beep()
  472. return
  473. }
  474. let mainWindow = fullScreenWindow.interactionParent
  475. let collectionBehavior = mainWindow?.collectionBehavior
  476. mainWindow?.alphaValue = 0
  477. if let data = mainWindow?.responds(to: NSSelectorFromString("setAnimationBehavior:")), data {
  478. mainWindow?.animationBehavior = .none
  479. }
  480. // trick to make sure the main window shows up in the same space as the fullscreen window
  481. fullScreenWindow.addChildWindow(mainWindow!, ordered: .below)
  482. fullScreenWindow.removeChildWindow(mainWindow!)
  483. fullScreenWindow.level = .popUpMenu
  484. // these can change due to the child window trick
  485. mainWindow?.level = .normal
  486. mainWindow?.alphaValue = 1.0
  487. mainWindow?.collectionBehavior = collectionBehavior!
  488. mainWindow?.display()
  489. mainWindow?.makeFirstResponder(self.listView)
  490. mainWindow?.recalculateKeyViewLoop()
  491. // mainWindow?.delegate = self
  492. mainWindow?.makeKey()
  493. if let data = mainWindow?.responds(to: NSSelectorFromString("setAnimationBehavior:")), data {
  494. mainWindow?.animationBehavior = .default
  495. }
  496. NSApp.removeWindowsItem(fullScreenWindow)
  497. fullScreenWindow.fadeOut()
  498. }
  499. //MARK: - PDF分屏视图
  500. func reloadPDFSplitInfo() {
  501. if listView.viewSplitMode == .disable {
  502. pdfSplitView.isHidden = true
  503. listView.frame = infoSplitCenterView.bounds
  504. infoSplitCenterView.addSubview(listView)
  505. if splitPDFController != nil {
  506. splitPDFController = nil
  507. }
  508. } else {
  509. pdfSplitView.isHidden = false
  510. listView.frame = pdfSplitTopView.bounds
  511. pdfSplitTopView.addSubview(listView)
  512. setUpPDFBottomToolbar()
  513. setupSplitPDFController()
  514. if listView.viewSplitMode == .horizontal {
  515. pdfSplitView.isVertical = true
  516. } else if listView.viewSplitMode == .vertical {
  517. pdfSplitView.isVertical = false
  518. }
  519. }
  520. }
  521. func setUpPDFBottomToolbar() {
  522. if pdfBottomToolbar != nil {
  523. pdfBottomToolbar = nil
  524. }
  525. pdfBottomToolbar = KMSplitToolbar.init()
  526. pdfBottomToolbar?.frame = CGRectMake(CGRectGetWidth(pdfSplitTopView.frame)/2-144, 20, 288, 40)
  527. pdfBottomToolbar?.pdfView = self.listView
  528. pdfBottomToolbar?.reloadData()
  529. pdfSplitTopView.addSubview(pdfBottomToolbar!)
  530. }
  531. func reloadPDFBottomToolbar() {
  532. if viewManager.splitShowBottomBar {
  533. pdfBottomToolbar?.isHidden = false
  534. pdfBottomToolbar?.reloadData()
  535. } else {
  536. pdfBottomToolbar?.isHidden = true
  537. }
  538. }
  539. }
  540. //MARK: - NSSplitViewDelegate
  541. extension KMMainViewController: NSSplitViewDelegate {
  542. func splitView(_ splitView: NSSplitView, shouldHideDividerAt dividerIndex: Int) -> Bool {
  543. return true
  544. }
  545. func splitView(_ splitView: NSSplitView, canCollapseSubview subview: NSView) -> Bool {
  546. return true
  547. }
  548. func splitView(_ splitView: NSSplitView, constrainSplitPosition proposedPosition: CGFloat, ofSubviewAt dividerIndex: Int) -> CGFloat {
  549. if dividerIndex == 0 {
  550. if proposedPosition > CGRectGetWidth(infoContendSplitView.frame)/2 - 10 {
  551. print(CGRectGetWidth(infoContendSplitView.frame)/2 - 10, NSDate())
  552. return CGRectGetWidth(infoContendSplitView.frame)/2 - 10
  553. }
  554. } else if dividerIndex == 1 {
  555. print(CGRectGetWidth(infoContendSplitView.frame)/2 - 10, NSDate())
  556. }
  557. return proposedPosition
  558. }
  559. func splitViewDidResizeSubviews(_ notification: Notification) {
  560. NSObject.cancelPreviousPerformRequests(withTarget: self, selector: #selector(splitViewResizeFinish), object: nil)
  561. self.perform(#selector(splitViewResizeFinish), with: nil, afterDelay: 0.15)
  562. }
  563. @objc func splitViewResizeFinish() {
  564. if infoContendSplitView.isSubviewCollapsed(infoSplitLeftView) {
  565. if viewManager.pdfSideBarType != .none {
  566. viewManager.pdfSideBarType = .none
  567. sideBarController?.reloadBOTAData()
  568. }
  569. }
  570. }
  571. }
  572. //MARK: - KMPDFSideBarControllerDelegate 左侧Sidebar代理
  573. extension KMMainViewController: KMPDFSideBarControllerDelegate {
  574. func kmPDFSideBarControllerDidSidebarTypeUpdated(_ view: KMPDFSideBarController) {
  575. if viewManager.pdfSideBarType == .none {
  576. infoContendSplitView.setPosition(-20, ofDividerAt: 0)
  577. } else if viewManager.pdfSideBarType == .search {
  578. infoContendSplitView.setPosition(264, ofDividerAt: 0)
  579. } else if viewManager.pdfSideBarType == .thumbnail {
  580. infoContendSplitView.setPosition(264, ofDividerAt: 0)
  581. } else if viewManager.pdfSideBarType == .outline {
  582. infoContendSplitView.setPosition(264, ofDividerAt: 0)
  583. } else if viewManager.pdfSideBarType == .bookmark {
  584. infoContendSplitView.setPosition(264, ofDividerAt: 0)
  585. } else if viewManager.pdfSideBarType == .annotation {
  586. infoContendSplitView.setPosition(264, ofDividerAt: 0)
  587. }
  588. }
  589. func kmPDFSideBarControllerDidGotoPage(_ view: KMPDFSideBarController, _ pageIndex: Int) {
  590. listView.go(toPageIndex: pageIndex, animated: true)
  591. }
  592. }
  593. //MARK: - KMPDFToolbarControllerDelegate 工具栏代理
  594. extension KMMainViewController: KMPDFToolbarControllerDelegate {
  595. func kmPDFToolbarControllerDidToolbarItemClicked(_ controller: KMPDFToolbarController, _ itemIdentifier: String) {
  596. print("toolbar点击", itemIdentifier)
  597. if itemIdentifier == KMPDFToolbar_ViewDisplay_Identifier {
  598. updatePDFDisplaySettingView()
  599. } else if itemIdentifier == KMPDFToolbar_PageEdit_Identifier {
  600. if viewManager.isPageEditMode == true {
  601. enterPageEditMode()
  602. } else {
  603. exitPageEditMode()
  604. }
  605. } else if itemIdentifier == KMPDFToolbar_convert_word_Identifier {
  606. let winC = KMConvertWordWindowController()
  607. let model = KMDocumentModel(url: listView.document.documentURL)
  608. winC.documentModel = model
  609. winC.own_beginSheetModal(for: self.view.window, completionHandler: nil)
  610. } else if itemIdentifier == KMPDFToolbar_convert_ppt_Identifier {
  611. let winC = KMConvertPPTsWindowController()
  612. winC.subType = 1
  613. let model = KMDocumentModel(url: listView.document.documentURL)
  614. winC.documentModel = model
  615. winC.own_beginSheetModal(for: self.view.window, completionHandler: nil)
  616. } else if itemIdentifier == KMPDFToolbar_convert_RTF_Identifier {
  617. let winC = KMConvertPPTsWindowController()
  618. winC.subType = 2
  619. let model = KMDocumentModel(url: listView.document.documentURL)
  620. winC.documentModel = model
  621. winC.own_beginSheetModal(for: self.view.window, completionHandler: nil)
  622. } else if itemIdentifier == KMPDFToolbar_convert_Text_Identifier {
  623. let winC = KMConvertPPTsWindowController()
  624. winC.subType = 4
  625. let model = KMDocumentModel(url: listView.document.documentURL)
  626. winC.documentModel = model
  627. winC.own_beginSheetModal(for: self.view.window, completionHandler: nil)
  628. } else if itemIdentifier == KMPDFToolbar_convert_CSV_Identifier {
  629. let winC = KMConvertPPTsWindowController()
  630. winC.subType = 5
  631. let model = KMDocumentModel(url: listView.document.documentURL)
  632. winC.documentModel = model
  633. winC.own_beginSheetModal(for: self.view.window, completionHandler: nil)
  634. } else if itemIdentifier == KMPDFToolbar_convert_excel_Identifier {
  635. let winC = KMConvertExcelWindowController()
  636. let model = KMDocumentModel(url: listView.document.documentURL)
  637. winC.documentModel = model
  638. winC.own_beginSheetModal(for: self.view.window, completionHandler: nil)
  639. } else if itemIdentifier == KMPDFToolbar_PageEdit_InsertFile_Identifier {
  640. pageEditViewController?.insertFromPDFAction()
  641. } else if itemIdentifier == KMPDFToolbar_PageEdit_InsertBlank_Identifier {
  642. pageEditViewController?.insertFromBlankAction()
  643. } else if itemIdentifier == KMPDFToolbar_PageEdit_InsertClip_Identifier {
  644. pageEditViewController?.insertFromClipboardAction()
  645. } else if itemIdentifier == KMPDFToolbar_PageEdit_InsertScanner_Identifier {
  646. pageEditViewController?.insertFromScannerAction()
  647. } else if itemIdentifier == KMPDFToolbar_PageEdit_Extract_Identifier {
  648. pageEditViewController?.extractPDFAction()
  649. } else if itemIdentifier == KMPDFToolbar_PageEdit_Replace_Identifier {
  650. pageEditViewController?.replacePDFAction()
  651. } else if itemIdentifier == KMPDFToolbar_PageEdit_Split_Identifier {
  652. pageEditViewController?.splitPDFAction()
  653. } else if itemIdentifier == KMPDFToolbar_PageEdit_Reverse_Identifier {
  654. pageEditViewController?.reversePDFAction()
  655. } else if itemIdentifier == KMPDFToolbar_PageEdit_LeftRotate_Identifier {
  656. pageEditViewController?.rotatePageLeftAction()
  657. } else if itemIdentifier == KMPDFToolbar_PageEdit_RightRotate_Identifier{
  658. pageEditViewController?.rotatePageRightAction()
  659. } else if itemIdentifier == KMPDFToolbar_PageEdit_Delete_Identifier {
  660. pageEditViewController?.deletePageAction()
  661. } else if itemIdentifier == KMPDFToolbar_PageEdit_Reduce_Identifier {
  662. pageEditViewController?.zoomOutPageAction()
  663. if(pageEditViewController?.canZoomInPageSize() == false) {
  664. toolbarManager.page_Increase_Property.isDisabled = true
  665. } else {
  666. toolbarManager.page_Increase_Property.isDisabled = false
  667. }
  668. if(pageEditViewController?.canZoomOutPageSize() == false) {
  669. toolbarManager.page_Reduce_Property.isDisabled = true
  670. } else {
  671. toolbarManager.page_Reduce_Property.isDisabled = false
  672. }
  673. controller.refreshSecondToolbarItemsState()
  674. } else if itemIdentifier == KMPDFToolbar_PageEdit_Increase_Identifier {
  675. pageEditViewController?.zoomInPageAction()
  676. if(pageEditViewController?.canZoomInPageSize() == false) {
  677. toolbarManager.page_Increase_Property.isDisabled = true
  678. } else {
  679. toolbarManager.page_Increase_Property.isDisabled = false
  680. }
  681. if(pageEditViewController?.canZoomOutPageSize() == false) {
  682. toolbarManager.page_Reduce_Property.isDisabled = true
  683. } else {
  684. toolbarManager.page_Reduce_Property.isDisabled = false
  685. }
  686. controller.refreshSecondToolbarItemsState()
  687. } else if itemIdentifier == KMPDFToolbar_PageEdit_page_oddPage_Identifier {
  688. pageEditViewController?.thumbnailChoosePageStyle = .odd
  689. if(toolbarManager.page_pageInfo_Property.creatable == true) {
  690. toolbarManager.page_pageInfo_Property.creatable = false
  691. controller.refreshSecondToolbarItemsState()
  692. }
  693. } else if itemIdentifier == KMPDFToolbar_PageEdit_page_EvenPage_Identifier {
  694. pageEditViewController?.thumbnailChoosePageStyle = .even
  695. if(toolbarManager.page_pageInfo_Property.creatable == true) {
  696. toolbarManager.page_pageInfo_Property.creatable = false
  697. controller.refreshSecondToolbarItemsState()
  698. }
  699. } else if itemIdentifier == KMPDFToolbar_PageEdit_page_PortraitPage_Identifier {
  700. pageEditViewController?.thumbnailChoosePageStyle = .horizontal
  701. if(toolbarManager.page_pageInfo_Property.creatable == true) {
  702. toolbarManager.page_pageInfo_Property.creatable = false
  703. controller.refreshSecondToolbarItemsState()
  704. }
  705. } else if itemIdentifier == KMPDFToolbar_PageEdit_page_LandscapePage_Identifier {
  706. pageEditViewController?.thumbnailChoosePageStyle = .vertical
  707. if(toolbarManager.page_pageInfo_Property.creatable == true) {
  708. toolbarManager.page_pageInfo_Property.creatable = false
  709. controller.refreshSecondToolbarItemsState()
  710. }
  711. } else if itemIdentifier == KMPDFToolbar_PageEdit_page_AllPage_Identifier {
  712. pageEditViewController?.thumbnailChoosePageStyle = .allPage
  713. if(toolbarManager.page_pageInfo_Property.creatable == true) {
  714. toolbarManager.page_pageInfo_Property.creatable = false
  715. controller.refreshSecondToolbarItemsState()
  716. }
  717. } else if itemIdentifier == KMPDFToolbar_PageEdit_page_CustomPage_Identifier {
  718. pageEditViewController?.thumbnailChoosePageStyle = .custom
  719. toolbarManager.page_pageInfo_Property.text = nil
  720. if(toolbarManager.page_pageInfo_Property.creatable == false) {
  721. toolbarManager.page_pageInfo_Property.creatable = true
  722. }
  723. controller.refreshSecondToolbarItemsState()
  724. }
  725. refreshToolbarView()
  726. }
  727. }
  728. //MARK: - KMNDisplayViewControllerDelegate代理
  729. extension KMMainViewController: KMNDisplayViewControllerDelegate {
  730. //Display Mode
  731. func displayViewControllerDidDisplayModeChanged(_ controller: KMNDisplayViewController) {
  732. listView.layoutDocumentView()
  733. }
  734. //阅读模式
  735. func displayViewControllerDidReadModeUpdated(_ controller: KMNDisplayViewController) {
  736. if viewManager.isPDFReadMode {
  737. openPDFReadMode()
  738. } else {
  739. exitPDFReadMode()
  740. }
  741. }
  742. //PPT
  743. func displayViewControllerDidGotoSlideShow(_ controller: KMNDisplayViewController) {
  744. togglePresentation(nil)
  745. }
  746. //SplitView
  747. func displayViewControllerDidSplitModeChanged(_ controller: KMNDisplayViewController) {
  748. reloadPDFSplitInfo()
  749. }
  750. func displayViewControllerDidSplitFileChanged(_ controller: KMNDisplayViewController) {
  751. splitPDFController?.reloadData()
  752. }
  753. func displayViewControllerDidToolbarStateChanged(_ controller: KMNDisplayViewController) {
  754. splitPDFController?.refreshToolbarState()
  755. reloadPDFBottomToolbar()
  756. }
  757. }
  758. //MARK: - PPT
  759. extension KMMainViewController: KMInteractionProviderProtocol {
  760. func providerContentView(fullScreenWindow: NSWindow, inset: CGFloat) -> NSView? {
  761. if(interactionMode == .presentation) {
  762. if listView.presentationDrawView == nil {
  763. listView.createPresentationDraw()
  764. }
  765. presentationTopViewController = KMPresentationTopViewController.init(nibName: "KMPresentationTopViewController", bundle: nil)
  766. presentationTopViewController?.pdfView = listView
  767. presentationTopViewController?.delegate = self
  768. presentationTopViewController?.isSelectionPre = true
  769. listView.isPresentationMode = true
  770. presentationTopViewController?.view.frame = CGRect(x: 0, y: (fullScreenWindow.contentView?.bounds.height ?? 0) - 42, width: fullScreenWindow.contentView?.bounds.width ?? 0, height: 42)
  771. if((presentationTopViewController) != nil) {
  772. fullScreenWindow.contentView?.addSubview(presentationTopViewController!.view)
  773. }
  774. } else {
  775. listView.frame = NSInsetRect(fullScreenWindow.contentView?.bounds ?? .zero, 0, 0)
  776. }
  777. fullScreenWindow.contentView?.addSubview(listView)
  778. if(interactionMode == .presentation) {
  779. let frame = fullScreenWindow.frame
  780. listView.frame = CGRectMake(0, 0, frame.size.width, frame.size.height-42)
  781. listView.autoresizingMask = [.width, .maxYMargin]
  782. }
  783. return view
  784. }
  785. @objc func willEnterInteractionModeNotification(_ sender: Notification) {
  786. guard let win = sender.object as? NSWindow, win.isEqual(to: self.view.window) else {
  787. return
  788. }
  789. let interactionMode = sender.userInfo?[NSWindow.UserInfo.interactionModeKey] as? KMInteractionMode
  790. if interactionMode == .presentation {
  791. let backgroundColor = NSColor.black
  792. let level = UserDefaults.standard.bool(forKey: "SKUseNormalLevelForPresentationKey") ? NSWindow.Level.normal : NSWindow.Level.popUpMenu
  793. let wasInteractionMode = self.interactionMode
  794. if wasInteractionMode == .normal {
  795. self.savedNormalSetup.setDictionary(self.currentPDFSettings() as! [AnyHashable : Any])
  796. }
  797. if wasInteractionMode == .legacyFullScreen {
  798. self.enterPresentationMode()
  799. self.pdfSplitView.frame = CGRect(x: 0, y: 0, width: NSWidth(centerContentView.bounds), height: NSHeight(centerContentView.bounds)-1)
  800. self.centerContentView.addSubview(pdfSplitView)
  801. self.listView.frame = (self.view.window?.contentView?.bounds)!
  802. self.view.window?.contentView?.addSubview(listView)
  803. // self.view.window?.backgroundColor = backgroundColor
  804. self.view.window?.level = level
  805. self.listView.layoutDocumentView()
  806. self.listView.requiresDisplay()
  807. self.forceSubwindowsOnTop(false)
  808. }
  809. } else {
  810. KMPrint("2")
  811. }
  812. }
  813. @objc func didEnterInteractionModeNotification(_ sender: Notification) {
  814. guard let win = sender.object as? NSWindow, win.isEqual(to: self.view.window) else {
  815. return
  816. }
  817. if self.interactionMode == .presentation {
  818. self.listView.layoutDocumentView()
  819. self.listView.requiresDisplay()
  820. }
  821. }
  822. @objc func willShowFullScreenNotification(_ sender: Notification) {
  823. guard let win = sender.object as? NSWindow, win.isEqual(to: self.view.window) else {
  824. return
  825. }
  826. if self.interactionMode == .presentation {
  827. let view = self.view.window?.firstResponder as? NSView
  828. if let data = view?.isDescendant(of: self.pdfSplitView), data {
  829. self.view.window?.makeFirstResponder(nil)
  830. }
  831. }
  832. }
  833. @objc func didShowFullScreenNotification(_ sender: Notification) {
  834. guard let win = sender.object as? NSWindow, win.isEqual(to: self.view.window) else {
  835. return
  836. }
  837. if self.interactionMode == .presentation {
  838. self.enterPresentationMode()
  839. }
  840. }
  841. }
  842. // MARK: -KMPresentationTopViewControllerDelegate (幻灯片)
  843. extension KMMainViewController: KMPresentationTopViewControllerDelegate {
  844. func presentationTopViewExit(_ presentationTopViewController: KMPresentationTopViewController, withButton: NSButton) {
  845. self.exitFullScreen()
  846. }
  847. func presentationTopViewClear(_ presentationTopViewController: KMPresentationTopViewController, withButton: NSButton) {
  848. listView.presentationDrawView?.clear()
  849. }
  850. func presentationTopViewUndo(_ presentationTopViewController: KMPresentationTopViewController, withButton: NSButton) {
  851. let presentationDrawView = listView.presentationDrawView
  852. if presentationDrawView?.canUndo() == true {
  853. presentationDrawView?.undo()
  854. }
  855. }
  856. func presentationTopViewType(_ presentationTopViewController: KMPresentationTopViewController, withButton: NSButton, isSeletion: Bool) {
  857. listView.isPresentationMode = isSeletion
  858. if listView.isEnterPresentationDrawMode() == true {
  859. listView.exitPresentationDrawMode()
  860. }
  861. }
  862. func presentationTopViewDrawColor(_ presentationTopViewController: KMPresentationTopViewController, withView: NSView,color:NSColor?) {
  863. if color == nil{
  864. listView.exitPresentationDrawMode()
  865. } else {
  866. if listView.isEnterPresentationDrawMode() == false {
  867. listView.enterPresentationDrawMode()
  868. }
  869. listView.changePresentationDrawModelColor(color)
  870. }
  871. }
  872. }
  873. //MARK: - KMSplitPDFViewControllerDelegate SplitPDFView分屏视图
  874. extension KMMainViewController: KMSplitPDFViewControllerDelegate {
  875. func splitPDFViewControllerDidUpdateFilePath(_ controller: KMSplitPDFViewController) {
  876. displaySettingController?.reloadData()
  877. }
  878. func splitPDFViewControllerDidUpdatePDFScale(_ controller: KMSplitPDFViewController) {
  879. if let scaleFactor = controller.pdfView?.scaleFactor {
  880. listView.scaleFactor = scaleFactor
  881. }
  882. }
  883. func splitPDFViewControllerDidUpdatePDFPageIndex(_ controller: KMSplitPDFViewController) {
  884. if let pageIndex = controller.pdfView?.currentPageIndex {
  885. listView.go(toPageIndex: pageIndex, animated: false)
  886. }
  887. }
  888. }
  889. //MARK: - CPDFViewDelegate PDFView代理
  890. extension KMMainViewController: CPDFViewDelegate,CPDFListViewDelegate {
  891. func pdfViewDocumentDidLoaded(_ pdfView: CPDFView!) {
  892. sideBarController?.reloadPageTurnerData()
  893. }
  894. func pdfViewCurrentPageDidChanged(_ pdfView: CPDFView!) {
  895. sideBarController?.reloadPageTurnerData()
  896. reloadPDFBottomToolbar()
  897. //分屏视图
  898. if viewManager.splitSyncScroll {
  899. if splitPDFController?.inPDFFirst == false && splitPDFController?.outPDFFirst == false {
  900. splitPDFController?.outPDFFirst = true
  901. if let splitPDFView = splitPDFController?.pdfView, let document = splitPDFView.document {
  902. var index = pdfView.currentPageIndex
  903. if index > document.pageCount {
  904. index = Int(splitPDFView.document.pageCount - 1)
  905. }
  906. splitPDFView.go(toPageIndex: index, animated: false)
  907. }
  908. NSObject.cancelPreviousPerformRequests(withTarget: self, selector: #selector(pdfUpdatedFinish), object: nil)
  909. self.perform(#selector(pdfUpdatedFinish), with: nil, afterDelay: 0.35)
  910. } else if splitPDFController?.outPDFFirst == true {
  911. if let splitPDFView = splitPDFController?.pdfView, let document = splitPDFView.document {
  912. var index = pdfView.currentPageIndex
  913. if index > document.pageCount {
  914. index = Int(splitPDFView.document.pageCount - 1)
  915. }
  916. splitPDFView.go(toPageIndex: index, animated: false)
  917. }
  918. NSObject.cancelPreviousPerformRequests(withTarget: self, selector: #selector(pdfUpdatedFinish), object: nil)
  919. self.perform(#selector(pdfUpdatedFinish), with: nil, afterDelay: 0.35)
  920. }
  921. }
  922. }
  923. func pdfViewScaleDidChanged(_ pdfView: CPDFView!) {
  924. pdfToolbarController?.reloadSelectZoomView()
  925. reloadPDFBottomToolbar()
  926. //分屏视图
  927. if viewManager.splitSyncScroll {
  928. if splitPDFController?.inPDFFirst == false && splitPDFController?.outPDFFirst == false {
  929. splitPDFController?.outPDFFirst = true
  930. NSObject.cancelPreviousPerformRequests(withTarget: self, selector: #selector(pdfUpdatedFinish), object: nil)
  931. self.perform(#selector(pdfUpdatedFinish), with: nil, afterDelay: 0.35)
  932. } else if splitPDFController?.outPDFFirst == true {
  933. if let splitPDFView = splitPDFController?.pdfView {
  934. splitPDFView.scaleFactor = pdfView.scaleFactor
  935. }
  936. NSObject.cancelPreviousPerformRequests(withTarget: self, selector: #selector(pdfUpdatedFinish), object: nil)
  937. self.perform(#selector(pdfUpdatedFinish), with: nil, afterDelay: 0.35)
  938. }
  939. }
  940. }
  941. func pdfViewDidClick(onLink pdfView: CPDFView!, withURL url: String!) {
  942. if let urlString = url, urlString == kKMPurchaseProductURLString {
  943. //跳转订阅比较表
  944. let _ = KMComparativeTableViewController.show(window: NSApp.mainWindow ?? NSWindow())
  945. return
  946. }
  947. if url.hasPrefix("smb://") {
  948. NSWorkspace.shared.openFile(url)
  949. } else {
  950. KMTools.openURL(urlString: url)
  951. }
  952. }
  953. func pdfViewPerformURL(_ pdfView: CPDFView!, withContent content: String!) {
  954. KMPrint("pdfViewPerformURL")
  955. if content != nil {
  956. NSWorkspace.shared.open(URL(string: content)!)
  957. } else {
  958. let alert = NSAlert()
  959. alert.alertStyle = .critical
  960. alert.informativeText = NSLocalizedString("The hyperlink is invalid.", comment: "")
  961. alert.messageText = ""
  962. alert.addButton(withTitle: NSLocalizedString("OK", comment: ""))
  963. alert.runModal()
  964. return
  965. }
  966. }
  967. func pdfViewPerformPrint(_ pdfView: CPDFView!) {
  968. KMPrint("pdfViewPerformPrint")
  969. self.showPrintWindow()
  970. }
  971. func pdfViewPerformGo(toPage pdfView: CPDFView!) {
  972. KMPrint("pdfViewPerformGo")
  973. }
  974. func pdfViewOpenPDF(_ pdfView: CPDFView!, forRemoteGoTo action: CPDFAction!) {
  975. KMPrint("pdfViewOpenPDF")
  976. }
  977. func pdfViewPerformReset(_ pdfView: CPDFView!) {
  978. KMPrint("pdfViewPerformReset")
  979. pdfView.document?.resetForm()
  980. }
  981. func pdfViewEditingBlockDidChanged(_ pdfView: CPDFView!) {
  982. KMPrint("pdfViewEditingBlockDidChanged")
  983. }
  984. func pdfViewAsBookBookmark() -> NSImage! {
  985. return NSImage(named: "KMImageNameBookmarkIcon")!
  986. }
  987. func pdfViewEditingSelectionDidChanged(_ pdfView: CPDFView!) {
  988. self.editPDFHanddler.pdfViewEditingSelectionDidChanged(pdfView)
  989. }
  990. func pdfViewEditingAreaDidChanged(_ pdfView: CPDFView!) {
  991. self.editPDFHanddler.pdfViewEditingAreaDidChanged(pdfView)
  992. }
  993. func pdfViewEditingCropBoundsDidChanged(_ pdfView: CPDFView!, editing editArea: CPDFEditArea!) {
  994. self.editPDFHanddler.pdfViewEditingCropBoundsDidChanged(pdfView, editing: editArea)
  995. }
  996. //编辑PDF 创建图片区域回调
  997. func pdfViewEditingAddImageArea(_ pdfView: CPDFView!, add page: CPDFPage!, add rect: CGRect) {
  998. self.editPDFHanddler.pdfViewEditingAddImageArea(pdfView, add: page, add: rect)
  999. }
  1000. func pdfViewEditingAddTextArea(_ pdfView: CPDFView!, add page: CPDFPage!, add rect: CGRect) {
  1001. self.editPDFHanddler.pdfViewEditingAddTextArea(pdfView, add: page, add: rect)
  1002. }
  1003. func pdfViewMobileEditingBegan(_ point: CGPoint, for pdfView: CPDFView!, forEditing editingAreas: [CPDFEditArea]!) {
  1004. self.editPDFHanddler.pdfViewMobileEditingBegan(point, for: pdfView, forEditing: editingAreas)
  1005. }
  1006. func pdfViewMobileEditingMove(_ point: CGPoint, for pdfView: CPDFView!, forEditing editingAreas: [CPDFEditArea]!) {
  1007. self.editPDFHanddler.pdfViewMobileEditingMove(point, for: pdfView, forEditing: editingAreas)
  1008. }
  1009. func pdfViewMobileEditingEnd(_ point: CGPoint, for pdfView: CPDFView!, forEditing editingAreas: [CPDFEditArea]!) {
  1010. self.editPDFHanddler.pdfViewMobileEditingEnd(point, for: pdfView, forEditing: editingAreas)
  1011. }
  1012. func pdfViewEditingSelectCharDidChanged(_ pdfView: CPDFView!) {
  1013. self.editPDFHanddler.pdfViewEditingSelectCharDidChanged(pdfView)
  1014. }
  1015. func pdfViewEditingExitCropMode(_ pdfView: CPDFView!, forEditing editingArea: CPDFEditImageArea!) {
  1016. self.editPDFHanddler.pdfViewEditingExitCropMode(pdfView, forEditing: editingArea)
  1017. }
  1018. func pdfListViewKeyDownIsContinue(_ pdfListView: CPDFListView!, theEvent: NSEvent!) -> Bool {
  1019. let command = theEvent.modifierFlags.contains(.command)
  1020. let control = theEvent.modifierFlags.contains(.control)
  1021. KMPrint(theEvent.keyCode)
  1022. if self.listView.isEditing() == true {
  1023. if control && theEvent.keyCode == 11 { // ctr + b
  1024. self.editPDFHanddler.fontBoldAction()
  1025. return false
  1026. } else if control && theEvent.keyCode == 34 { // ctr +i
  1027. self.editPDFHanddler.fontItalicAction()
  1028. return false
  1029. } else if theEvent.keyCode == 36 { // enter
  1030. if self.listView.isCropMode {
  1031. self.editPDFHanddler.cropComfirmAction()
  1032. return false
  1033. }
  1034. }
  1035. }
  1036. if (theEvent.keyCode == 11 && command) { // command + B [添加书签]
  1037. self.menuItemBookMarkClick_add(sender: NSMenuItem())
  1038. return false
  1039. } else if (command && control && theEvent.keyCode == 14) { // command + control + E [注释 橡皮擦]
  1040. return false
  1041. } else if (theEvent.keyCode == 123) { // 向左
  1042. if(self.listView.isEditing() && !self.listView.isSelecteditAreaNotEdit()) {
  1043. return false
  1044. } else {
  1045. if (self.pdfViewCanHorizontalScroll() == false && self.listView.canGoToPreviousPage()) {
  1046. self.listView.goToPreviousPage(nil)
  1047. return false
  1048. }
  1049. }
  1050. } else if (theEvent.keyCode == 126) { // 向上
  1051. if(self.listView.isEditing() && !self.listView.isSelecteditAreaNotEdit()) {
  1052. return false
  1053. } else {
  1054. if (self.listView.isContinousScroll()) {
  1055. return true
  1056. }
  1057. if (self.pdfViewCanVerticalScroll() == false && self.listView.canGoToPreviousPage()) {
  1058. self.listView.goToPreviousPage(nil)
  1059. return false
  1060. }
  1061. }
  1062. } else if (theEvent.keyCode == 124) { // 向右
  1063. if(self.listView.isEditing() && !self.listView.isSelecteditAreaNotEdit()) {
  1064. return false
  1065. } else {
  1066. if (self.pdfViewCanHorizontalScroll() == false && self.listView.canGoToNextPage()) {
  1067. self.listView.goToNextPage(nil)
  1068. return false
  1069. }
  1070. }
  1071. } else if (theEvent.keyCode == 125) { // 向下
  1072. if(self.listView.isEditing() && !self.listView.isSelecteditAreaNotEdit()) {
  1073. return false
  1074. } else {
  1075. if (self.listView.isContinousScroll()) {
  1076. return true
  1077. }
  1078. if (self.pdfViewCanVerticalScroll() == false && self.listView.canGoToNextPage()) {
  1079. self.listView.goToNextPage(nil)
  1080. return false
  1081. }
  1082. }
  1083. } else if (theEvent.keyCode == 36) {
  1084. if self.listView.annotationType == .addImage || self.listView.annotationType == .addText {
  1085. if self.listView.isEditImage {
  1086. self.menuItemEditingClick_CropImage(sender: NSMenuItem())
  1087. }
  1088. }
  1089. }
  1090. if theEvent.keyCode == 53 {
  1091. //ESC
  1092. self.exitFullScreen()
  1093. if viewManager.isPDFReadMode {
  1094. self.exitPDFReadMode()
  1095. }
  1096. self.leftSideViewCancelSelect()
  1097. }
  1098. return true
  1099. }
  1100. func pdfListViewMenuValidate(_ pdfListView: CPDFListView!, menuItem: NSMenuItem!, isTakesEffect: UnsafeMutablePointer<ObjCBool>!) -> Bool {
  1101. guard let action = menuItem.action else {
  1102. isTakesEffect.pointee = false
  1103. return false
  1104. }
  1105. if (KMSystemMenu.isEditSelector(sel: action)) {
  1106. if (KMSystemMenu.Edit.deleteSelector == action) {
  1107. isTakesEffect.pointee = true
  1108. return self.listView.activeAnnotations.count > 0
  1109. } else if (KMSystemMenu.Edit.copySelector == action) {
  1110. isTakesEffect.pointee = true
  1111. return true//self.listView.canCopy()
  1112. } else if (KMSystemMenu.Edit.cutSelector == action) {
  1113. isTakesEffect.pointee = true
  1114. return self.listView.canCopy()
  1115. } else if (KMSystemMenu.Edit.pasteSelector == action) {
  1116. isTakesEffect.pointee = true
  1117. return self.listView.canPaste()
  1118. }
  1119. }
  1120. isTakesEffect.pointee = false
  1121. return false
  1122. }
  1123. func pdfViewEditingOperationDidChanged(_ pdfView: CPDFView!) {
  1124. self.editPDFHanddler.pdfViewEditingOperationDidChanged(pdfView)
  1125. }
  1126. func pdfViewEditingDoubleClick(_ pdfView: CPDFView!, imageArea editArea: CPDFEditArea!) {
  1127. self.editPDFHanddler.pdfViewEditingDoubleClick(pdfView, imageArea: editArea)
  1128. }
  1129. //MARK: - CPDFListViewDelegate
  1130. func cPDFListView(_ pdfListView: CPDFListView, didDelete annotation: CPDFAnnotation, in pdfPage: CPDFPage) {
  1131. self.leftSideViewController.updateThumbnail(at: Int(pdfPage.pageIndex()))
  1132. }
  1133. func pdfListViewChangeatioActiveAnnotations(_ pdfListView: CPDFListView!, forActiveAnnotations annotations: [CPDFAnnotation]!, isRightMenu: Bool) {
  1134. self.view.window?.makeFirstResponder(self.listView)
  1135. if isRightMenu {
  1136. } else if annotations.count > 0 {
  1137. if annotations.count > 1 {
  1138. let fristAnnotation = annotations.first
  1139. var isSameAnnotation = true
  1140. let className = NSStringFromClass(fristAnnotation!.classForCoder)
  1141. for annotation in annotations {
  1142. let cunrrentClassName = NSStringFromClass(annotation.classForCoder)
  1143. if (className == "CPDFSquareAnnotation") ||
  1144. (className == "CPDFCircleAnnotation") ||
  1145. (className == "CPDFLineAnnotation") {
  1146. if (cunrrentClassName != "CPDFSquareAnnotation") &&
  1147. (cunrrentClassName != "CPDFCircleAnnotation") &&
  1148. (cunrrentClassName != "CPDFLineAnnotation") {
  1149. isSameAnnotation = false
  1150. }
  1151. } else {
  1152. if className != cunrrentClassName {
  1153. isSameAnnotation = false
  1154. }
  1155. }
  1156. }
  1157. if isSameAnnotation == false {
  1158. self.rightSideViewController?.reloadDataWithPDFView(pdfView: pdfListView, isShow: false)
  1159. } else {
  1160. self.rightSideViewController?.reloadDataWithPDFView(pdfView: pdfListView, isShow: true)
  1161. self.openRightPane()
  1162. }
  1163. } else {
  1164. let fristAnnotation = annotations.first
  1165. let className = NSStringFromClass(fristAnnotation!.classForCoder)
  1166. if self.viewManager.isPDFReadMode {
  1167. self.rightSideViewController?.reloadDataWithPDFView(pdfView: pdfListView, isShow: false)
  1168. self.closeRightPane()
  1169. } else {
  1170. self.rightSideViewController?.reloadDataWithPDFView(pdfView: pdfListView, isShow: true)
  1171. if className != "CPDFStampAnnotation" &&
  1172. className != "CPDFSignatureAnnotation" &&
  1173. className != "CPDFListStampAnnotation" {
  1174. self.openRightPane()
  1175. }
  1176. }
  1177. }
  1178. if (listView.activeAnnotation.isKind(of: CPDFLineAnnotation.self)) {
  1179. if (!(listView.activeAnnotation as! CPDFLineAnnotation).isMeasure) {
  1180. cancelMeasureType()
  1181. } else {
  1182. if distanceMeasureInfoWindowController == nil {
  1183. let measureInfo = CPDFDistanceMeasureInfo()
  1184. distanceMeasureInfoWindowController = CDistanceMeasureInfoWindowController()
  1185. distanceMeasureInfoWindowController?.measureInfo = measureInfo
  1186. distanceMeasureInfoWindowController?.delegate = self
  1187. }
  1188. }
  1189. } else if (!listView.activeAnnotation.isKind(of: CPDFPolygonAnnotation.self) && !listView.activeAnnotation.isKind(of: CPDFPolylineAnnotation.self)) {
  1190. cancelMeasureType()
  1191. } else if (listView.activeAnnotation.isKind(of: CPDFPolygonAnnotation.self) || listView.activeAnnotation.isKind(of: CPDFPolylineAnnotation.self)) {
  1192. if perimeterMeasureInfoWindowController == nil {
  1193. let measureInfo = CPDFPerimeterMeasureInfo()
  1194. perimeterMeasureInfoWindowController = CPerimeterMeasureInfoWindowController()
  1195. perimeterMeasureInfoWindowController?.measureInfo = measureInfo
  1196. perimeterMeasureInfoWindowController?.delegate = self
  1197. }
  1198. if areaMeasureInfoWindowController == nil {
  1199. let measureInfo = CPDFAreaMeasureInfo()
  1200. areaMeasureInfoWindowController = CAreaMeasureInfoWindowController()
  1201. areaMeasureInfoWindowController?.measureInfo = measureInfo
  1202. areaMeasureInfoWindowController?.delegate = self
  1203. }
  1204. }
  1205. } else if (annotations.count == 0){
  1206. if pdfListView.annotationType == .unkown {
  1207. self.rightSideViewController?.reloadDataWithPDFView(pdfView: pdfListView, isShow: false)
  1208. self.closeRightPane()
  1209. } else {
  1210. if self.viewManager.isPDFReadMode {
  1211. self.rightSideViewController?.reloadDataWithPDFView(pdfView: pdfListView, isShow: false)
  1212. self.closeRightPane()
  1213. } else {
  1214. self.rightSideViewController?.reloadDataWithPDFView(pdfView: pdfListView, isShow: true)
  1215. self.openRightPane()
  1216. }
  1217. }
  1218. }
  1219. }
  1220. func pdfListViewChangedAnnotationType(_ pdfListView: CPDFListView!, for annotationType: CAnnotationType) {
  1221. if(annotationType == .unkown) {
  1222. self.rightSideViewController.isHidden = true
  1223. self.closeRightPane()
  1224. }
  1225. let aType = annotationType
  1226. if aType.isMarkup() || aType == .anchored || aType == .freeText || aType.isSquare() || aType == .link {
  1227. KMDataManager.ud_set(annotationType.rawValue, forKey: SKLastAnnotationModeKey)
  1228. }
  1229. }
  1230. ///开始定位链接注释
  1231. func pdfListViewLinkDestinationStart(_ pdfListView: CPDFListView!, withActiveAnnotation annotation: CPDFAnnotation!) {
  1232. }
  1233. ///刷新链接注释
  1234. func pdfListViewLinkDestinationEnd(_ pdfListView: CPDFListView!, withActiveAnnotation annotation: CPDFAnnotation!) {
  1235. }
  1236. func pdfListViewMenuItemsEditing(at point: CGPoint, for page: CPDFPage!, menuItems: [NSMenuItem]!) -> [NSMenuItem]! {
  1237. if (listView.toolMode != CToolMode.editPDFToolMode) {
  1238. return menuItems
  1239. }
  1240. var tMenuItems = menuItems;
  1241. if(listView.isSelectEditCharRange() ||
  1242. listView.isSelecteditArea(with: point)) {
  1243. tMenuItems?.append(NSMenuItem.separator())
  1244. }
  1245. let areas = self.listView.editingAreas() ?? []
  1246. if areas.count == 1 {
  1247. let fristAreas = areas.first
  1248. if fristAreas is CPDFEditImageArea {
  1249. self.listView.selectImageAreas = fristAreas as? CPDFEditImageArea
  1250. if self.listView.isEditImage {
  1251. tMenuItems?.removeAll()
  1252. tMenuItems?.append(self.corpImageMenuItem())
  1253. tMenuItems?.append(self.cancelCorpImageMenuItem())
  1254. tMenuItems?.append(self.restoreCorpImageMenuItem())
  1255. } else {
  1256. tMenuItems?.append(NSMenuItem.separator())
  1257. tMenuItems?.append(self.cutImageArea())
  1258. tMenuItems?.append(self.replaceImageArea())
  1259. tMenuItems?.append(self.exportImageArea())
  1260. }
  1261. } else {
  1262. if tMenuItems?.count != 1 {
  1263. tMenuItems?.swapAt(0, 1)
  1264. }
  1265. }
  1266. } else if areas.count == 0 {
  1267. tMenuItems?.append(NSMenuItem.separator())
  1268. tMenuItems?.append(self.addText())
  1269. tMenuItems?.append(self.addImage())
  1270. }
  1271. return tMenuItems
  1272. }
  1273. func pdfListViewMenu(forEvent pdfListView: CPDFListView!, for theEvent: NSEvent!, click menu: AutoreleasingUnsafeMutablePointer<NSMenu?>!, isMoveSelectAnno: Bool) {
  1274. self.mouseRightMenuEvent = theEvent
  1275. var currentMenu : NSMenu = menu.pointee!
  1276. if let activeAnno = listView.activeAnnotation as? KMTableAnnotation {//Table
  1277. var pagePoint = NSPoint()
  1278. _ = self.listView.pageAndPoint(&pagePoint, for: theEvent, nearest: true)
  1279. currentMenu.removeAllItems()
  1280. let annotation = activeAnno
  1281. annotation.completeEditCellText()
  1282. if !(NSIsEmptyRect(annotation.drawRect)) {
  1283. annotation.drawLine(pagePoint)
  1284. NotificationCenter.default.post(name: NSNotification.Name.KMPDFViewTableAnnotationDidChange, object: self, userInfo: ["point": NSValue(point: pagePoint)])
  1285. }
  1286. if (annotation.rowNumber - annotation.currentCell.row - 1) < 0 {
  1287. return
  1288. }
  1289. currentMenu = tableMenu(currentMenu, withTable: listView.activeAnnotation as! KMTableAnnotation, point: pagePoint)
  1290. listView.needsDisplay = true
  1291. return
  1292. }
  1293. var pagePoint: NSPoint = .zero
  1294. if let page = self.listView.pageAndPoint(&pagePoint, for: theEvent, nearest: true) {
  1295. let anno = page.annotation(at: pagePoint)
  1296. let item1 = NSMenuItem(title: NSLocalizedString("Delete", comment: ""), action: #selector(menuItemActionMeasureDelete), target: self)
  1297. item1.representedObject = anno
  1298. let item2 = NSMenuItem(title: NSLocalizedString("Edit Note", comment: ""), action: #selector(menuItemActionMeasureEditNote), target: self)
  1299. item2.representedObject = anno
  1300. let item3 = NSMenuItem(title: NSLocalizedString("Settings", comment: ""), action: #selector(menuItemActionMeasureSetting), target: self)
  1301. item3.representedObject = anno
  1302. if let data = anno as? CPDFPolygonAnnotation { // 多变形
  1303. currentMenu.removeAllItems()
  1304. currentMenu.insertItem(item1, at: 0)
  1305. currentMenu.insertItem(item2, at: 1)
  1306. currentMenu.insertItem(item3, at: 2)
  1307. return
  1308. }
  1309. if let data = anno as? CPDFPolylineAnnotation {
  1310. currentMenu.removeAllItems()
  1311. currentMenu.insertItem(item1, at: 0)
  1312. currentMenu.insertItem(item2, at: 1)
  1313. currentMenu.insertItem(item3, at: 2)
  1314. return
  1315. }
  1316. if let data = anno as? CPDFLineAnnotation, data.isMeasure {
  1317. currentMenu.removeAllItems()
  1318. currentMenu.insertItem(item1, at: 0)
  1319. currentMenu.insertItem(item2, at: 1)
  1320. currentMenu.insertItem(item3, at: 2)
  1321. return
  1322. }
  1323. }
  1324. if (listView.toolMode == .selectToolMode){
  1325. currentMenu.insertItem(NSMenuItem.separator(), at: 3)
  1326. currentMenu.insertItem(self.printingMenu(), at: 3)
  1327. currentMenu.insertItem(self.setTTSStype(), at: 3)
  1328. currentMenu.insertItem(self.setCropStype(), at: 3)
  1329. currentMenu.insertItem(self.setSnapshotStype(), at: 3)
  1330. let export = NSMenuItem(title: NSLocalizedString("Export", comment: ""), action: nil, target: self)
  1331. export.submenu = self.exportMenu()
  1332. currentMenu.insertItem(export, at: 3)
  1333. currentMenu.insertItem(NSMenuItem.separator(), at: 3)
  1334. if listView.activeAnnotation == nil{
  1335. currentMenu.insertItem(self.setAnnotationToolStype(), at: 3)
  1336. currentMenu.insertItem(NSMenuItem.separator(), at: 3)
  1337. }
  1338. currentMenu.insertItem(NSMenuItem.separator(), at: currentMenu.items.count - 3)
  1339. currentMenu.insertItem(self.addReadModelStype(), at: currentMenu.items.count - 3)
  1340. currentMenu.insertItem(NSMenuItem.separator(), at: 0)
  1341. currentMenu.insertItem(self.setAITranslateStype(), at: 0)
  1342. currentMenu.insertItem(self.setAIProofreadStype(), at: 0)
  1343. currentMenu.insertItem(self.setAIRewriteStype(), at: 0)
  1344. return
  1345. }
  1346. if (listView.toolMode == .moveToolMode || listView.toolMode == .magnifyToolMode){
  1347. currentMenu.insertItem(NSMenuItem.separator(), at: 0)
  1348. currentMenu.insertItem(self.setTTSStype(), at: 0)
  1349. currentMenu.insertItem(self.setCropStype(), at: 0)
  1350. currentMenu.insertItem(self.setSnapshotStype(), at: 0)
  1351. currentMenu.insertItem(NSMenuItem.separator(), at: 0)
  1352. currentMenu.insertItem(self.addOutlineStype(), at: 0)
  1353. currentMenu.insertItem(self.addBookmarkMenu(), at: 0)
  1354. if listView.activeAnnotation == nil{
  1355. currentMenu.insertItem(NSMenuItem.separator(), at: 0)
  1356. currentMenu.insertItem(self.setAnnotationToolStype(), at: 0)
  1357. }
  1358. currentMenu.insertItem(NSMenuItem.separator(), at: 0)
  1359. currentMenu.insertItem(self.setAITranslateStype(), at: 0)
  1360. currentMenu.insertItem(self.setAIProofreadStype(), at: 0)
  1361. currentMenu.insertItem(self.setAIRewriteStype(), at: 0)
  1362. return
  1363. }
  1364. if currentMenu.items.count > 3 {
  1365. currentMenu.insertItem(NSMenuItem.separator(), at: currentMenu.items.count - 3)
  1366. currentMenu.insertItem(self.addReadModelStype(), at: currentMenu.items.count - 3)
  1367. }
  1368. if listView.currentSelection != nil && listView.activeAnnotations.count < 1{
  1369. if listView.currentSelection.selectionType() == .text {
  1370. currentMenu.insertItem(NSMenuItem.separator(), at: 3)
  1371. currentMenu.insertItem(self.setSearchBaiduStype(), at: 3)
  1372. currentMenu.insertItem(NSMenuItem.separator(), at: 3)
  1373. currentMenu.insertItem(self.setLookUpStype(), at: 3)
  1374. currentMenu.insertItem(NSMenuItem.separator(), at: 3)
  1375. currentMenu.insertItem(self.addOutlineStype(), at: 3)
  1376. currentMenu.insertItem(NSMenuItem.separator(), at: 3)
  1377. currentMenu.insertItem(self.setAnnotationToolStype(), at: 3)
  1378. currentMenu.insertItem(self.setTTSStype(), at: 3)
  1379. currentMenu.insertItem(NSMenuItem.separator(), at: 3)
  1380. currentMenu.insertItem(self.setShareStype(), at: 3)
  1381. currentMenu.insertItem(NSMenuItem.separator(), at: 3)
  1382. }
  1383. currentMenu.insertItem(self.enterAnnotationStype(), at: 3)
  1384. currentMenu.insertItem(NSMenuItem.separator(), at: 3)
  1385. if listView.currentSelection.selectionType() == .image{
  1386. currentMenu.insertItem(NSMenuItem.separator(), at: 6)
  1387. currentMenu.insertItem(self.addOutlineStype(), at: 6)
  1388. currentMenu.insertItem(NSMenuItem.separator(), at: 6)
  1389. currentMenu.insertItem(self.setAnnotationToolStype(), at: 6)
  1390. }
  1391. if listView.currentSelection.selectionType() == .text {
  1392. currentMenu.insertItem(NSMenuItem.separator(), at: currentMenu.items.count)
  1393. currentMenu.insertItem(self.setTranslateStype(), at: currentMenu.items.count)
  1394. currentMenu.insertItem(NSMenuItem.separator(), at: currentMenu.items.count)
  1395. }
  1396. }
  1397. if listView.activeAnnotation != nil || isMoveSelectAnno {
  1398. if let data = self.listView.activeAnnotation?.type?.lowercased(), data == "stamp"{
  1399. currentMenu.insertItem(NSMenuItem.separator(), at: currentMenu.items.count - 15)
  1400. currentMenu.insertItem(self.enterAnnotationStype(), at: currentMenu.items.count - 15)
  1401. currentMenu.insertItem(NSMenuItem.separator(), at: currentMenu.items.count - 15)
  1402. }else{
  1403. currentMenu.insertItem(NSMenuItem.separator(), at: currentMenu.items.count - 15)
  1404. currentMenu.insertItem(self.enterAnnotationStype(), at: currentMenu.items.count - 15)
  1405. if let anno = self.listView.activeAnnotation, anno.isKind(of: CPDFStampAnnotation.self) {
  1406. } else {
  1407. currentMenu.insertItem(NSMenuItem.separator(), at: currentMenu.items.count - 15)
  1408. currentMenu.insertItem(self.setShareStype(), at: currentMenu.items.count - 15)
  1409. }
  1410. currentMenu.insertItem(NSMenuItem.separator(), at: currentMenu.items.count - 15)
  1411. }
  1412. }
  1413. if listView.activeAnnotation == nil && listView.currentSelection == nil{
  1414. currentMenu.insertItem(NSMenuItem.separator(), at: currentMenu.items.count)
  1415. if(listView.toolMode == .selectToolMode) {
  1416. if NSIsEmptyRect(listView.currentSelectionRect()) {
  1417. currentMenu.insertItem(self.zoomSelectionMenuItem(), at: 0)
  1418. currentMenu.insertItem(NSMenuItem.separator(), at: 0)
  1419. }
  1420. currentMenu.insertItem(self.printingMenu(), at: 0)
  1421. currentMenu.insertItem(self.setTTSStype(), at: 0)
  1422. currentMenu.insertItem(self.setCropStype(), at: 0)
  1423. currentMenu.insertItem(self.setSnapshotStype(), at: 0)
  1424. let export = NSMenuItem(title: NSLocalizedString("Export", comment: ""), action: nil, target: self)
  1425. export.submenu = self.exportMenu()
  1426. currentMenu.insertItem(export, at: currentMenu.items.count)
  1427. }else{
  1428. currentMenu.insertItem(NSMenuItem.separator(), at: 2)
  1429. currentMenu.insertItem(self.setTTSStype(), at: 2)
  1430. currentMenu.insertItem(self.setCropStype(), at: 2)
  1431. currentMenu.insertItem(self.setSnapshotStype(), at: 2)
  1432. currentMenu.insertItem(NSMenuItem.separator(), at: 2)
  1433. currentMenu.insertItem(self.addOutlineStype(), at: 2)
  1434. currentMenu.insertItem(NSMenuItem.separator(), at: 2)
  1435. currentMenu.insertItem(self.enterAnnotationStype(), at: 2)
  1436. currentMenu.insertItem(NSMenuItem.separator(), at: 2)
  1437. if(currentMenu.items.count > 4) {
  1438. currentMenu.insertItem(NSMenuItem.separator(), at: 5)
  1439. }
  1440. if(currentMenu.items.count > 5) {
  1441. currentMenu.insertItem(self.addBookmarkMenu(), at: 6)
  1442. }
  1443. currentMenu.insertItem(self.setAutoScrollStype(), at: currentMenu.items.count)
  1444. }
  1445. currentMenu.insertItem(self.setAnnotationToolStype(), at: 5)
  1446. }
  1447. currentMenu.insertItem(NSMenuItem.separator(), at: 0)
  1448. currentMenu.insertItem(self.setAITranslateStype(), at: 0)
  1449. currentMenu.insertItem(self.setAIProofreadStype(), at: 0)
  1450. currentMenu.insertItem(self.setAIRewriteStype(), at: 0)
  1451. for item in currentMenu.items {
  1452. if (item.action == NSSelectorFromString("menuItemClick_HidenorShowNote:")) {
  1453. // 显示与隐藏注释 item action 截取
  1454. item.action = #selector(menuItemClick_HidenorShowNote)
  1455. item.target = self
  1456. break
  1457. }
  1458. }
  1459. }
  1460. func pdfListViewAddAnnotations(_ pdfListView: CPDFListView!, forAdd annotations: [CPDFAnnotation]!, in pdfPage: CPDFPage!) {
  1461. var addRedact = false
  1462. for anno in annotations {
  1463. if (anno.isKind(of: CPDFRedactAnnotation.self)) {
  1464. addRedact = true
  1465. } else if anno is CPDFSquareAnnotation || anno is CPDFCircleAnnotation {
  1466. anno.contents = pdfPage?.string(for: anno.bounds) ?? ""
  1467. }
  1468. }
  1469. self.model.hasAddRedact = addRedact
  1470. if self.listView.toolMode == .moveToolMode {
  1471. self.listView.toolMode = .textToolMode
  1472. self.listView.annotationType = .unkown
  1473. self.toolbarController.toolbarType = .Annatiton
  1474. }
  1475. if (self.model.rightMouseEventing) {
  1476. self.model.rightMouseEventing = false
  1477. if (self.toolbarController.ignoreCurrentAnnotationTypeChange && self.listView.annotationType == .ink) {
  1478. self.listView.toolMode = .textToolMode
  1479. self.listView.annotationType = .unkown
  1480. }
  1481. }
  1482. self.toolbarController.ignoreCurrentAnnotationTypeChange = false
  1483. self.leftSideViewController.refreshUIForAddAnnotation(annos: annotations, page: pdfPage)
  1484. }
  1485. func pdfListViewRemoveAnnotations(_ pdfListView: CPDFListView!, forRemove annotations: [CPDFAnnotation]!, in pdfPage: CPDFPage!) {
  1486. self.leftSideViewController.annoList_refreshUIForDeleteAnnotations(annos: annotations, page: pdfPage)
  1487. }
  1488. func pdfListViewDidSelectionEnd(_ pdfListView: CPDFListView!) {
  1489. if (!self.listView.isEqual(to: pdfListView)) {
  1490. return
  1491. }
  1492. if (self.listView.toolMode != .selectToolMode) {
  1493. return
  1494. }
  1495. }
  1496. func pdfListViewKeyDowClosePanel(_ speedy: CPDFViewSidebarSpeedMode, event theEvent: NSEvent!) {
  1497. if(speedy == .right) {
  1498. self.toggleRightPane()
  1499. } else if (speedy == .left) {
  1500. self.menuItemAction_hiddenLeftSide(speedy)
  1501. }
  1502. }
  1503. func pdfListViewEventMarkupColor(with annotation: CPDFAnnotation!) -> [NSColor]! {
  1504. if (annotation.isKind(of: CPDFMarkupAnnotation.self)) {
  1505. if (annotation as! CPDFMarkupAnnotation).markupType() == .highlight {
  1506. return KMAnnotationPropertiesColorManager.manager.markHighlightColors
  1507. } else {
  1508. return KMAnnotationPropertiesColorManager.manager.markOtherColors
  1509. }
  1510. } else {
  1511. return KMAnnotationPropertiesColorManager.manager.markOtherColors
  1512. }
  1513. }
  1514. func pdfListViewHaveDocumentAttribute() -> Bool {
  1515. if(!self.listView.document.allowsCopying) {
  1516. self.removeOwnerPassword()
  1517. return false
  1518. }
  1519. return true
  1520. }
  1521. func pdfListView(_ sender: CPDFListView!, showSnapshotAtPageNumber pageNum: Int, for rect: NSRect, scaleFactor: CGFloat, autoFits: Bool) {
  1522. let swc = KMSnapshotWindowController(windowNibName: "SnapshotWindow")
  1523. swc.delegate = self
  1524. swc.setPdfDocument(self.listView.document, goToPageNumber: pageNum, rect: rect, scaleFactor: scaleFactor, autoFits: autoFits)
  1525. swc.forceOnTop = self.interactionMode != .normal
  1526. self.myDocument?.addWindowController(swc)
  1527. }
  1528. func pdfListView(_ pdfView: CPDFListView!, documentDataDidChanged docData: Any!, withInfo info: [AnyHashable : Any]!) {
  1529. if let data = info?[CPDFListView.outlineKey] as? Bool, data { // 大纲改变
  1530. guard let ol = docData as? CPDFOutline else {
  1531. return
  1532. }
  1533. let add = info?[CPDFListView.outlineAddKey] as? Bool ?? false
  1534. let remove = info?[CPDFListView.outlineRemoveKey] as? Bool ?? false
  1535. if add {
  1536. self.leftSideViewController.addOutlineAfter(ol)
  1537. }
  1538. if remove {
  1539. self.leftSideViewController.removeOutlineAfter(ol)
  1540. }
  1541. let demote = info?[CPDFListView.outlineDemoteKey] as? Bool ?? false
  1542. let promote = info?[CPDFListView.outlinePromoteKey] as? Bool ?? false
  1543. if demote {
  1544. self.leftSideViewController.demoteOutlineAfter(ol)
  1545. }
  1546. if promote {
  1547. self.leftSideViewController.promoteOutlineAfter(ol)
  1548. }
  1549. }
  1550. }
  1551. //TextEdit
  1552. func pdfListViewDidTextFontChanged(_ pdfListView: CPDFListView!) {
  1553. self.rightSideViewController.eidtPDFTextProperty.reloadData()
  1554. }
  1555. func pdfListViewDidTextColorChanged(_ pdfListView: CPDFListView!, with color: NSColor!) {
  1556. self.rightSideViewController.eidtPDFTextProperty.fontColorChangeAction()
  1557. }
  1558. func pdfListViewAnnotationMeasureInfoChange(_ pdfListView: CPDFListView!, with annotation: CPDFAnnotation!) {
  1559. guard let data = annotation else {
  1560. if distanceMeasureInfoWindowController?.window?.isVisible == true {
  1561. distanceMeasureInfoWindowController?.clearData()
  1562. }
  1563. return
  1564. }
  1565. if let lineAnnotation = annotation as? CPDFLineAnnotation {
  1566. handleLineAnnotation(lineAnnotation)
  1567. } else if let polylineAnnotation = annotation as? CPDFPolylineAnnotation {
  1568. handlePolylineAnnotation(polylineAnnotation)
  1569. } else if let polygonAnnotation = annotation as? CPDFPolygonAnnotation {
  1570. handlePolygonAnnotation(polygonAnnotation)
  1571. }
  1572. }
  1573. func pdfListViewMeasureCancel(_ pdfListView: CPDFListView!) {
  1574. cancelMeasureType()
  1575. }
  1576. func tableMenu(_ menu: NSMenu, withTable table: KMTableAnnotation, point: CGPoint) -> NSMenu {
  1577. if table.currentCell.row >= 0 && table.currentCell.column >= 0 {
  1578. 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"]
  1579. let actions = ["formAnnotTextEdit:", "", "addRowAbove:", "addRowBelow:", "", "addColumnBefore:", "addColumnAfter:", "", "deleteRow:", "deleteColumn:", "deleteTabel", "cutCell:", "copyCell:", "pasteCell:", "pasteAndMatchStyle:", "deleteCellContents:", "clearAll:"]
  1580. for i in 0..<itemTitles.count {
  1581. var item: NSMenuItem? = nil
  1582. if itemTitles[i] == "" {
  1583. item = NSMenuItem.separator()
  1584. menu.insertItem(item!, at: i)
  1585. } else {
  1586. item = NSMenuItem(title: itemTitles[i], action: nil, keyEquivalent: "")
  1587. item!.target = self
  1588. item!.action = NSSelectorFromString(actions[i])
  1589. if itemTitles[i] == "Paste" /*&& !_copyCellData*/ {
  1590. item!.action = nil
  1591. } else if itemTitles[i] == "Paste and Match Style" /*&& !_copyCellData */{
  1592. item!.action = nil
  1593. } else if itemTitles[i] == "Add Row Above" {
  1594. let path1 = table.crossLines[table.rowNumber - table.currentCell.row]
  1595. let path2 = table.crossLines[table.rowNumber - table.currentCell.row - 1]
  1596. if (path1 as AnyObject).lineJoinStyle == NSBezierPath.LineJoinStyle.round && table.headerCount() >= 5 {
  1597. item!.action = nil
  1598. } else if (path2 as AnyObject).lineJoinStyle == NSBezierPath.LineJoinStyle.bevel && table.footerCount() >= 5 {
  1599. item!.action = nil
  1600. }
  1601. }
  1602. item!.title = NSLocalizedString(item!.title, comment: "")
  1603. item!.representedObject = NSValue(point: point)
  1604. menu.insertItem(item!, at: i)
  1605. }
  1606. }
  1607. } else {
  1608. let itemTitles = ["Cut", "Copy", "Paste", "Delete"]
  1609. let actions = ["cut:", "copy:", "paste:", "delete:"]
  1610. for i in 0..<itemTitles.count {
  1611. let item = NSMenuItem(title: itemTitles[i], action: nil, keyEquivalent: "")
  1612. item.target = self
  1613. item.action = NSSelectorFromString(actions[i])
  1614. item.title = NSLocalizedString(item.title, comment: "")
  1615. menu.insertItem(item, at: i)
  1616. item.representedObject = NSValue(point: point)
  1617. }
  1618. }
  1619. return menu
  1620. }
  1621. private func handleLineAnnotation(_ annotation: CPDFLineAnnotation) {
  1622. if perimeterMeasureInfoWindowController?.window?.isVisible == true {
  1623. perimeterMeasureInfoWindowController?.hideFloatingWindow()
  1624. distanceMeasureInfoWindowController?.showWindow(self)
  1625. } else if areaMeasureInfoWindowController?.window?.isVisible == true {
  1626. areaMeasureInfoWindowController?.hideFloatingWindow()
  1627. distanceMeasureInfoWindowController?.showWindow(self)
  1628. } else if distanceMeasureInfoWindowController?.window?.isVisible == false {
  1629. distanceMeasureInfoWindowController?.showWindow(self)
  1630. }
  1631. let measureInfo = annotation.measureInfo
  1632. let startPoint = annotation.startPoint
  1633. let endPoint = annotation.endPoint
  1634. let angle = atan2(endPoint.y - startPoint.y, endPoint.x - startPoint.x) * (180.0 / .pi)
  1635. distanceMeasureInfoWindowController?.angleLabel.stringValue = String(format: "%.2f°", abs(angle))
  1636. distanceMeasureInfoWindowController?.xLabel.stringValue = String(format: "%.0f", abs(endPoint.x - startPoint.x))
  1637. distanceMeasureInfoWindowController?.yLabel.stringValue = String(format: "%.0f", abs(endPoint.y - startPoint.y))
  1638. distanceMeasureInfoWindowController?.reloadData(with: measureInfo!)
  1639. }
  1640. private func handlePolylineAnnotation(_ annotation: CPDFPolylineAnnotation) {
  1641. if distanceMeasureInfoWindowController?.window?.isVisible == true {
  1642. distanceMeasureInfoWindowController?.hideFloatingWindow()
  1643. perimeterMeasureInfoWindowController?.showWindow(self)
  1644. } else if areaMeasureInfoWindowController?.window?.isVisible == true {
  1645. areaMeasureInfoWindowController?.hideFloatingWindow()
  1646. perimeterMeasureInfoWindowController?.showWindow(self)
  1647. } else if perimeterMeasureInfoWindowController?.window?.isVisible == false {
  1648. perimeterMeasureInfoWindowController?.showWindow(self)
  1649. }
  1650. let measureInfo = annotation.measureInfo
  1651. let savePoints = annotation.savePoints()
  1652. var angle: CGFloat = 0
  1653. if savePoints.count >= 3 {
  1654. let count = savePoints.count
  1655. let startPoint = savePoints[count - 3].pointValue
  1656. let midPoint = savePoints[count - 2].pointValue
  1657. let endPoint = savePoints.last!.pointValue
  1658. angle = angleBetweenPoints(startPoint, midPoint, endPoint)
  1659. }
  1660. angle = 180 - angle
  1661. perimeterMeasureInfoWindowController?.angleLabel.stringValue = String(format: "%.2f°", abs(angle))
  1662. perimeterMeasureInfoWindowController?.reloadData(with: measureInfo!)
  1663. }
  1664. private func handlePolygonAnnotation(_ annotation: CPDFPolygonAnnotation) {
  1665. if distanceMeasureInfoWindowController?.window?.isVisible == true {
  1666. distanceMeasureInfoWindowController?.hideFloatingWindow()
  1667. areaMeasureInfoWindowController?.showWindow(self)
  1668. } else if perimeterMeasureInfoWindowController?.window?.isVisible == true {
  1669. perimeterMeasureInfoWindowController?.hideFloatingWindow()
  1670. areaMeasureInfoWindowController?.showWindow(self)
  1671. } else if areaMeasureInfoWindowController?.window?.isVisible == false {
  1672. areaMeasureInfoWindowController?.showWindow(self)
  1673. }
  1674. let measureInfo = annotation.measureInfo
  1675. let savePoints = annotation.savePoints
  1676. var angle: CGFloat = 0
  1677. if savePoints.count >= 3 {
  1678. let count = savePoints.count
  1679. let startPoint = (savePoints[count - 3] as AnyObject).pointValue
  1680. let midPoint = (savePoints[count - 2] as AnyObject).pointValue
  1681. let endPoint = (savePoints.lastObject as AnyObject).pointValue
  1682. angle = angleBetweenPoints(startPoint!, midPoint!, endPoint!)
  1683. }
  1684. angle = 180 - angle
  1685. areaMeasureInfoWindowController?.angleLabel.stringValue = String(format: "%.2f°", abs(angle))
  1686. areaMeasureInfoWindowController?.reloadData(measureInfo!)
  1687. }
  1688. private func angleBetweenPoints(_ startPoint: CGPoint, _ midPoint: CGPoint, _ endPoint: CGPoint) -> CGFloat {
  1689. let vector1 = CGPoint(x: midPoint.x - startPoint.x, y: midPoint.y - startPoint.y)
  1690. let vector2 = CGPoint(x: endPoint.x - midPoint.x, y: endPoint.y - midPoint.y)
  1691. let dotProduct = vector1.x * vector2.x + vector1.y * vector2.y
  1692. let magnitude1 = sqrt(vector1.x * vector1.x + vector1.y * vector1.y)
  1693. let magnitude2 = sqrt(vector2.x * vector2.x + vector2.y * vector2.y)
  1694. return acos(dotProduct / (magnitude1 * magnitude2)) * (180.0 / .pi)
  1695. }
  1696. @objc func pdfUpdatedFinish() {
  1697. splitPDFController?.inPDFFirst = false
  1698. splitPDFController?.outPDFFirst = false
  1699. }
  1700. }
  1701. //MARK: - KMNThumbnailBaseViewDelegate
  1702. extension KMMainViewController: KMNThumbnailBaseViewDelegate {
  1703. func clickThumbnailViewControlle(pageEditVC:KMNThumbnailBaseViewController?,currentIndex:Int) {
  1704. exitPageEditMode()
  1705. viewManager.isPageEditMode = false
  1706. pdfToolbarController?.reloadPageEditView()
  1707. }
  1708. func insertPDFThumbnailViewControlle(pageEditVC: KMNThumbnailBaseViewController?, pdfDocment: CPDFDocument?) {
  1709. if(pdfDocment != nil) {
  1710. insertDocuments.insert(pdfDocment!)
  1711. }
  1712. }
  1713. func changeIndexPathsThumbnailViewControlle(pageEditVC: KMNThumbnailBaseViewController?, selectionIndexPaths: Set<IndexPath>, selectionStrings: String) {
  1714. toolbarManager.page_pageInfo_Property.text = selectionStrings
  1715. if(toolbarManager.page_pageInfo_Property.creatable == false) {
  1716. toolbarManager.page_pageInfo_Property.creatable = true
  1717. }
  1718. pdfToolbarController?.refreshSecondToolbarItemsState()
  1719. }
  1720. }
  1721. //MARK: -
  1722. //MARK: -
  1723. //MARK: -
  1724. //MARK: - 旧代码,需要用到的内容需要拖出来,写好注释
  1725. extension KMMainViewController {
  1726. func awakeFromNibFunction() {
  1727. self.addBackgroundMaskView()
  1728. self.PDFContendView.backgroundColor(NSColor.km_init(hex: "FFFFFF"))
  1729. listView.delegate = self
  1730. listView.pdfListViewDelegate = self
  1731. if (document != nil) {
  1732. self.listView.document = self.document
  1733. self.listView.document?.delegate = self
  1734. let autoScale = listView.autoScales
  1735. if !autoScale {
  1736. listView.scaleFactor = 1.0
  1737. }
  1738. }
  1739. self.initPDFLeftViewVC()
  1740. self.initRightSideView()
  1741. self.toolbarController.listView = self.listView
  1742. self.toolbarController.mainViewController = self
  1743. self.leftSideViewController.mainViewController = self
  1744. self.newPDFSplitView.delegate = self
  1745. }
  1746. func viewDidAppearFunction() {
  1747. //春季活动
  1748. if ((KMAdvertisementManager.manager.info.popWindowContent) != nil) {
  1749. if KMAdvertisementManager.manager.info.popWindowContent!.content!.count > 0 {
  1750. let info = KMAdvertisementManager.manager.info.popWindowContent!.content?.first
  1751. if KMAdvertisementManager.checkAdvertisementValid(info!) {
  1752. self.loadRecommondPopWindow()
  1753. }
  1754. }
  1755. }
  1756. self.addEventMonitor()
  1757. self.view.window?.makeFirstResponder(self.listView)
  1758. // 更新属性页面的信息
  1759. NotificationCenter.default.post(name: KMInfoWindowC.windowDidBecomeMainNotification, object: self.myDocument)
  1760. self.interfaceThemeDidChanged(self.view.window?.appearance?.name ?? (NSApp.appearance?.name ?? .aqua))
  1761. if (self.document == nil) {
  1762. return
  1763. }
  1764. if (self.document == nil || self.document!.isLocked == false) {
  1765. self.loadFunctionGuide()
  1766. }
  1767. if (self.document?.isLocked == false) {
  1768. if self.model.needConvertNotes && self.tabViewIsDragging() == false {
  1769. self.showConvertNotesProgress()
  1770. }
  1771. return
  1772. }
  1773. if (self.view.window == nil) {
  1774. return
  1775. }
  1776. if (self.model.password != nil) {
  1777. if let data = self.listView.document?.unlock(withPassword: self.model.password), data {
  1778. self.model.isSaveKeyChain = false
  1779. if self.model.needConvertNotes && self.tabViewIsDragging() == false {
  1780. self.showConvertNotesProgress()
  1781. }
  1782. return
  1783. }
  1784. }
  1785. DispatchQueue.main.asyncAfter(deadline: DispatchTime.now() + 0.3) {
  1786. if self.view.window != nil && self.tabViewIsDragging() == false {
  1787. self.passwordWindow = KMPasswordInputWindow.openWindow(window: self.view.window!, url: self.document!.documentURL) { [weak self] result , password in
  1788. if (result == .cancel) {
  1789. (self?.myDocument as? KMMainDocument)?.browser?.closeTab()
  1790. return
  1791. }
  1792. self?.model.isSaveKeyChain = true
  1793. self?.listView.document = self?.document
  1794. self?.document?.unlock(withPassword: password)
  1795. }
  1796. } else {
  1797. if self.model.needConvertNotes && self.tabViewIsDragging() == false {
  1798. self.showConvertNotesProgress()
  1799. }
  1800. }
  1801. }
  1802. }
  1803. func viewWillDisappearFunction() {
  1804. if self.interactionMode != .presentation {
  1805. self.removeEventMonitor()
  1806. }
  1807. self.editPDFHanddler.hiddenWindows()
  1808. }
  1809. func viewWillLayoutFunction() {
  1810. if (KMTools.isFullScreen(self.view.window ?? NSWindow())) { // 全屏
  1811. self.listView.backgroundColor = KMPreferenceManager.shared.displayBackgroundFullScreenColor
  1812. } else {
  1813. self.listView.backgroundColor = KMPreferenceManager.shared.displayBackgroundNormalColor
  1814. }
  1815. if let guideWC = self.guideInfoWindowController{
  1816. var rect = self.view.window!.frame
  1817. rect.size.height -= 20
  1818. guideWC.window?.setFrame(rect, display: false)
  1819. guideWC.window?.minSize = rect.size
  1820. guideWC.window?.maxSize = rect.size
  1821. guideWC.show()
  1822. }
  1823. }
  1824. func viewDidLoadOld() {
  1825. mwcFlags.settingUpWindow = 1
  1826. toolbarController.delegate = self
  1827. self.editPDFHanddler.viewC = self
  1828. self.srHanddler.pdfView = self.listView
  1829. self.initToolbar()
  1830. if (UserDefaults.standard.object(forKey: CPDFOfficeLeftSidePaneWidthKey) != nil) {
  1831. UserDefaults.standard.set(256, forKey: CPDFOfficeLeftSidePaneWidthKey)
  1832. UserDefaults.standard.synchronize()
  1833. }
  1834. if (UserDefaults.standard.object(forKey: CPDFOfficeRightSidePaneWidthKey) != nil) {
  1835. UserDefaults.standard.set(256, forKey: CPDFOfficeRightSidePaneWidthKey)
  1836. UserDefaults.standard.synchronize()
  1837. }
  1838. let position = mianSplitView.maxPossiblePositionOfDivider(at: 1)
  1839. mianSplitView.setPosition(position, ofDividerAt: 0)
  1840. mianSplitView.setPosition(mianSplitView.minPossiblePositionOfDivider(at: 0), ofDividerAt: 0)
  1841. pdfSplitView.setPosition(mianSplitView.maxPossiblePositionOfDivider(at: 1), ofDividerAt: 0)
  1842. if (KMPreferenceManager.shared.openLastUnlockedDocumentWhenAppStart) {
  1843. if (self.listView.document != nil) {
  1844. let pageNumber = KMPreferenceManager.shared.getPageNumber(forKey: self.listView.document?.documentURL.path ?? "")
  1845. let pageScale = KMPreferenceManager.shared.getPageScale(forKey: self.listView.document?.documentURL.path ?? "")
  1846. if (pageNumber != nil && pageNumber! >= 0 && pageNumber! < (self.listView.document?.pageCount ?? 0)) {
  1847. DispatchQueue.main.asyncAfter(deadline: .now() + 0.5) {
  1848. if (pageScale != nil) {
  1849. self.listView.scaleFactor = CGFloat(pageScale!)
  1850. }
  1851. self.listView.go(toPageIndex: pageNumber!, animated: false)
  1852. }
  1853. } else {
  1854. self._goToFirstPageForFristAppear()
  1855. }
  1856. }
  1857. } else {
  1858. self._goToFirstPageForFristAppear()
  1859. }
  1860. pageNumberDisplayView.delegate = self
  1861. tipCurrentPageBox.moveCallback = { [unowned self] mouseEntered, mouseBox in
  1862. if !viewManager.isPDFReadMode {
  1863. if mouseEntered {
  1864. self.pageNumberDisplayView.hover = true
  1865. } else {
  1866. self.pageNumberDisplayView.hover = false
  1867. }
  1868. }
  1869. }
  1870. NotificationCenter.default.addObserver(self, selector: #selector(rename(_:)), name: NSNotification.Name.init(rawValue: "KMTabControllerRename"), object: nil)
  1871. NotificationCenter.default.addObserver(self, selector: #selector(closeTab(_:)), name: NSNotification.Name.init(rawValue: "KMTabControllerCloseTabs"), object: nil)
  1872. NotificationCenter.default.addObserver(self, selector: #selector(showInFinder(_:)), name: NSNotification.Name.init(rawValue: "KMTabControllerShowInFinder"), object: nil)
  1873. NotificationCenter.default.addObserver(self, selector: #selector(preferenceDidChangeNotification), name: KMPreferenceManager.didChangeNotification, object: nil)
  1874. NotificationCenter.default.addObserver(self, selector: #selector(documentDidUnlockNotification), name: Notification.Name("CPDFDocumentDidUnlockNotification"), object: nil)
  1875. NotificationCenter.default.addObserver(self, selector: #selector(annotationsAttributeHasChange), name: NSNotification.Name.CPDFListViewAnnotationsAttributeHasChange, object:nil)
  1876. NotificationCenter.default.addObserver(self, selector: #selector(applicationWillTerminateNotification), name: NSApplication.willTerminateNotification, object: nil)
  1877. NotificationCenter.default.addObserver(self, selector: #selector(CPDFDocumentPageCountChangedNotification), name: NSNotification.Name.init(rawValue: "CPDFDocumentPageCountChangedNotification"), object: nil)
  1878. NotificationCenter.default.addObserver(self, selector: #selector(CEditPDFToolModeChangeStateUnkownNotification), name: Notification.Name.init("CEditPDFToolModeChangeStateUnkown"), object: nil)
  1879. NotificationCenter.default.addObserver(self, selector: #selector(handlePageChangedNotification), name: NSNotification.Name.CPDFViewPageChanged, object: self.listView)
  1880. NotificationCenter.default.addObserver(self, selector: #selector(handleDisplayBoxChangedNotification), name: NSNotification.Name.CPDFViewDisplayBoxChanged, object: self.listView)
  1881. NotificationCenter.default.addObserver(self, selector: #selector(didAddContentViewNotification), name: NSWindow.didAddContentViewNotification, object: nil)
  1882. NotificationCenter.default.addObserver(self, selector: #selector(addAutoSaveEvent), name: AutoSaveManager.kTimeValueChangedNotificationName, object: nil)
  1883. NotificationCenter.default.addObserver(self, selector: #selector(didRemoveAnnotationNotification), name: NSNotification.Name.CPDFPageDidRemoveAnnotation, object: nil)
  1884. Task {
  1885. self.addAutoSaveEvent()
  1886. }
  1887. self.toolbarController.selectItem(KMDocumentAnnotationToolbarItemIdentifier)
  1888. self.closeRightPane()
  1889. self.addKeyEventMonitor()
  1890. self.addAdsBannerView()
  1891. var snapshotSetups: NSArray?
  1892. if KMPreferenceManager.shared.rememberSnapshot {
  1893. if let fileUrl = (self.myDocument as? KMMainDocument)?.fileURL {
  1894. snapshotSetups = SKBookmarkController.shared().snapshotsForRecentDocument(at: fileUrl) as NSArray?
  1895. }
  1896. }
  1897. if let cnt = snapshotSetups?.count, cnt > 0 {
  1898. if let data = self.listView.document?.isLocked, data {
  1899. self.savedNormalSetup.setObject(snapshotSetups as Any, forKey: "snapshots" as NSCopying)
  1900. } else {
  1901. self.showSnapshots(setups: snapshotSetups)
  1902. }
  1903. }
  1904. let readModel = UserDefaults.standard.bool(forKey: "kKMPDFViewIsReadMode")
  1905. if readModel == true {
  1906. self.openPDFReadMode()
  1907. }
  1908. let hasWindowSetup = savedNormalSetup.count > 0
  1909. if UserDefaults.standard.dictionary(forKey: KMDefaultPDFDisplaySettingsKey) != nil {
  1910. let pdfSettings: NSDictionary = hasWindowSetup ? savedNormalSetup : UserDefaults.standard.dictionary(forKey: KMDefaultPDFDisplaySettingsKey)! as NSDictionary
  1911. self.applyPDFSettings(pdfSettings)
  1912. } else {
  1913. self.applyPDFSettings(savedNormalSetup)
  1914. }
  1915. //文字
  1916. let fontManager = NSFontManager.shared
  1917. fontManager.target = self
  1918. fontManager.action = #selector(changeFont(_:))
  1919. }
  1920. //MARK: - PDFListView
  1921. func initPDFLeftViewVC() {
  1922. var frame = self.leftView.frame
  1923. frame.size.width += 44
  1924. self.leftView.frame = frame
  1925. leftSideViewController.isFirst = true
  1926. leftSideViewController.listView = self.listView
  1927. leftSideViewController.view.frame = CGRect(x: 0, y:0 , width: self.leftView.frame.size.width, height: self.leftView.frame.size.height)
  1928. leftSideViewController.view.autoresizingMask = [.height,.width]
  1929. leftSideViewController.delegate = self
  1930. self.leftView.addSubview(leftSideViewController.view)
  1931. }
  1932. func initRightSideView() {
  1933. self.rightSideViewController = KMRightSideViewController.init()
  1934. self.rightSideViewController.view.frame = CGRect(x: 0, y: 0, width: self.rightView.frame.width, height: self.rightView.frame.size.height)
  1935. self.rightSideViewController.view.autoresizingMask = [.height,.width]
  1936. self.rightSideViewController.listView = self.listView
  1937. self.rightSideViewController.isHidden = true
  1938. self.rightSideViewController.delegate = self
  1939. self.rightView.addSubview(self.rightSideViewController.view)
  1940. self.rightSideViewController.propertyDidChange = { [weak self] model in
  1941. if let anno = model as? CSelfSignAnnotation {
  1942. self?.leftSideViewController.refreshUIForAnnoAttributeDidChange(anno, attributes: nil)
  1943. }
  1944. }
  1945. }
  1946. func addAdsBannerView() {
  1947. #if VERSION_FREE
  1948. if !IAPProductsManager.default().isAvailableAllFunction(){
  1949. guard let document = self.listView.document else {
  1950. return
  1951. }
  1952. if !document.isLocked {
  1953. KMAdsManager.defaultManager.beginSheetModalForView(self.readContentView, directions: .down, adPosY: 30, animated: false) { pageIndex in
  1954. }
  1955. }
  1956. NotificationCenter.default.addObserver(self, selector: #selector(purchaseStateUpdateNoti), name: NSNotification.Name(rawValue: "KMIAPProductPurchasedNotification"), object: nil)
  1957. NotificationCenter.default.addObserver(self, selector: #selector(purchaseStateUpdateNoti), name: NSNotification.Name(rawValue: "kDeviceActivateNotification"), object: nil)
  1958. }
  1959. #endif
  1960. }
  1961. // MARK: Private Methods
  1962. private func _isArabicLanguage() -> Bool {
  1963. return NSLocalizedString("Right click a color and select “Change Color...“.", comment: "") == "انقر بزر الماوس الأيمن فوق اللون وحدد \"تغيير اللون...\"."
  1964. }
  1965. internal func removeNotifications() {
  1966. NotificationCenter.default.removeObserver(self)
  1967. self.leftSideViewController.clearAnnotationFilterData()
  1968. self.leftSideViewController.clearNotification()
  1969. }
  1970. func checkShouldAutoOpenLeftVC() {
  1971. if KMPreference.shared.showLeftSideBar == false {
  1972. return
  1973. }
  1974. if self.model.leftPanelOpen {
  1975. return
  1976. }
  1977. let readModel = UserDefaults.standard.bool(forKey: "kKMPDFViewIsReadMode")
  1978. if readModel == true {
  1979. return
  1980. }
  1981. DispatchQueue.main.async {
  1982. self.leftSideViewController.showThumbnail()
  1983. self.toolbarController.findItem(KMLeftControlToolbarItemIdentifier)?.isSelected = true
  1984. }
  1985. }
  1986. func applyLeftSideWidth(_ leftSideWidth: CGFloat, rightSideWidth: CGFloat) -> Void {
  1987. mianSplitView.setPosition(leftSideWidth, ofDividerAt: 0)
  1988. mianSplitView.setPosition(mianSplitView.maxPossiblePositionOfDivider(at: 1) - mianSplitView.dividerThickness - rightSideWidth, ofDividerAt: 1)
  1989. self.model.lastLeftPanWidth = leftSideWidth
  1990. self.model.lastRightPanWidth = rightSideWidth
  1991. }
  1992. func removeAllAnnotations() {
  1993. let alert = NSAlert()
  1994. alert.messageText = NSLocalizedString("This will permanently remove all annotations. Are you sure to continue?", comment: "")
  1995. alert.addButton(withTitle: NSLocalizedString("Yes", comment:""))
  1996. alert.addButton(withTitle: NSLocalizedString("No", comment:""))
  1997. if (alert.runModal() != .alertFirstButtonReturn) {
  1998. return
  1999. }
  2000. DispatchQueue.main.async {
  2001. self.removeAllAnnotationsStore.store(t: self.listView)
  2002. }
  2003. }
  2004. @objc func cancelMeasureType() {
  2005. self.hideMeasureFloatingWindows()
  2006. self.toolbarController?.findItem(KMToolbarMeasureItemIdentifier)?.isSelected = false
  2007. }
  2008. func hideMeasureFloatingWindows() {
  2009. if distanceMeasureInfoWindowController?.window?.isVisible == true {
  2010. distanceMeasureInfoWindowController?.hideFloatingWindow()
  2011. } else if perimeterMeasureInfoWindowController?.window?.isVisible == true {
  2012. perimeterMeasureInfoWindowController?.hideFloatingWindow()
  2013. } else if areaMeasureInfoWindowController?.window?.isVisible == true {
  2014. areaMeasureInfoWindowController?.hideFloatingWindow()
  2015. }
  2016. }
  2017. func showMeasureFloatingWindowsIfNeed() {
  2018. let toolMode = self.listView.toolMode
  2019. if toolMode != .measureToolMode {
  2020. return
  2021. }
  2022. let type = self.listView.annotationType
  2023. if type == .line {
  2024. self.distanceMeasureInfoWindowController?.window?.orderFront(nil)
  2025. } else if type == .polyLine {
  2026. self.perimeterMeasureInfoWindowController?.window?.orderFront(nil)
  2027. } else if type == .polyGon {
  2028. self.areaMeasureInfoWindowController?.window?.orderFront(nil)
  2029. } else if type == .square {
  2030. self.areaMeasureInfoWindowController?.window?.orderFront(nil)
  2031. }
  2032. }
  2033. // MARK: - 标记密文
  2034. func enterRedact() {
  2035. if !IAPProductsManager.default().isAvailableAllFunction(){
  2036. let winC = KMPurchaseCompareWindowController.sharedInstance()
  2037. winC?.kEventName = "Reading_Redact_BuyNow"
  2038. winC?.showWindow(nil)
  2039. return
  2040. }
  2041. if self.listView.document?.allowsPrinting == false || self.listView.document?.allowsCopying == false {
  2042. Task {
  2043. _ = await KMAlertTool.runModel(message: KMLocalizedString("This is a secured document. Editing is not permitted."))
  2044. }
  2045. return
  2046. }
  2047. if self.hasEnterRedact() {
  2048. self.exitRedact()
  2049. return
  2050. }
  2051. self.commitEditingIfNeed()
  2052. self.leftSideViewController.thumbnailTableView.isEnabled = false
  2053. self.leftSideViewController.tocOutlineView.isEnabled = false
  2054. self.leftSideViewController.noteOutlineView.isEnabled = false
  2055. self.leftSideViewController.findTableView.isEnabled = false
  2056. self.leftSideViewController.groupedFindTableView.isEnabled = false
  2057. self.leftSideViewController.snapshotTableView.isEnabled = false
  2058. let ttsWindowC = KMTTSWindowController.share
  2059. if ttsWindowC.pdfView?.document?.documentURL.path == self.listView.document?.documentURL.path {
  2060. if let data = ttsWindowC.window?.isVisible, data {
  2061. ttsWindowC.stopSpeaking()
  2062. ttsWindowC.close()
  2063. }
  2064. }
  2065. NSColorPanel.shared.showsAlpha = false
  2066. redactController = KMPDFRedactViewController(url: self.listView.document!.documentURL, password: self.listView.document?.password)
  2067. self.addChild(redactController)
  2068. self.PDFContendView.addSubview(redactController.view)
  2069. redactController.view.frame = self.PDFContendView.bounds
  2070. redactController.view.autoresizingMask = [.width, .height]
  2071. self.listView.isHidden = true
  2072. redactController.scaleFactor = self.listView.scaleFactor
  2073. redactController.titleBack = { [weak self] title in
  2074. self?.view.window?.title = title
  2075. }
  2076. redactController.callback = { [weak self] result, currentPageIndex, saveResult, saveUrl in
  2077. self?.listView.go(toPageIndex: self!.redactController.redactPdfView.currentPageIndex, animated: false)
  2078. if result == false { // 退出
  2079. self?.exitRedact()
  2080. return
  2081. }
  2082. let controller = self?._getPDFRedactController()
  2083. controller?.redactPdfView.newAddAnnotation.removeAll()
  2084. self?.exitRedact()
  2085. if saveResult {
  2086. let newDocument = CPDFDocument(url: saveUrl)
  2087. if let data = newDocument?.isLocked, data {
  2088. newDocument?.unlock(withPassword: self?.listView.document?.password ?? "")
  2089. }
  2090. self?.document = newDocument
  2091. self?.listView.document = newDocument
  2092. self?.listView.layoutDocumentView()
  2093. }
  2094. }
  2095. redactController.setCurrentPageIndex(self.listView.currentPageIndex)
  2096. }
  2097. func exitRedact() {
  2098. self.leftSideViewController.thumbnailTableView.isEnabled = true
  2099. self.leftSideViewController.tocOutlineView.isEnabled = true
  2100. self.leftSideViewController.noteOutlineView.isEnabled = true
  2101. self.leftSideViewController.findTableView.isEnabled = true
  2102. self.leftSideViewController.groupedFindTableView.isEnabled = true
  2103. self.leftSideViewController.snapshotTableView.isEnabled = true
  2104. let controller = self._getPDFRedactController()
  2105. if let data = controller {
  2106. if data.redactPdfView.newAddAnnotation.count > 0 {
  2107. KMAlertTool.runModel(message: "", informative: KMLocalizedString("There are unapplied redactions in this file. Exit will not save redaction."), buttons: [KMLocalizedString("Exit"), KMLocalizedString("Cancel")]) { response in
  2108. if response == .alertFirstButtonReturn {
  2109. controller?.redactPdfView.newAddAnnotation.removeAll()
  2110. self.exitRedact()
  2111. }
  2112. }
  2113. return
  2114. }
  2115. }
  2116. NSColorPanel.shared.showsAlpha = true
  2117. self.toolbarController.findItem(KMDocumentRedactToolbarItemIdentifier)?.isSelected = false
  2118. controller?.redactPdfView.resignMonitor()
  2119. controller?.view.removeFromSuperview()
  2120. controller?.removeFromParent()
  2121. self.listView.isHidden = false
  2122. self.listView.annotationType = .unkown
  2123. }
  2124. func hasEnterRedact() -> Bool {
  2125. return self._getPDFRedactController() != nil
  2126. }
  2127. //MARK: - AI
  2128. func showAITypeChooseView(aiConfigType: AIConfigType) -> Void {
  2129. if (self.document != nil) {
  2130. AIChatInfoManager.defaultManager.currentFilePath = (self.document?.documentURL.path)!
  2131. } else {
  2132. AIChatInfoManager.defaultManager.currentFilePath = ""
  2133. }
  2134. let windowVC: AINewConfigWindowController = AINewConfigWindowController.currentWC()
  2135. windowVC.chooseCurFileHandle = {[unowned self] windowVC in
  2136. if AIChatInfoManager.defaultManager.currentFilePath.isEmpty == false {
  2137. let documentArray = NSDocumentController.shared.documents
  2138. var didFileEdit: Bool = false
  2139. var curDoc: KMMainDocument!
  2140. for document in documentArray {
  2141. if document.fileURL?.path == AIChatInfoManager.defaultManager.currentFilePath {
  2142. didFileEdit = document.isDocumentEdited
  2143. curDoc = document as! KMMainDocument
  2144. break
  2145. }
  2146. }
  2147. if didFileEdit {
  2148. let tempFileURL = FileManager.default.temporaryDirectory.appendingPathComponent(AIChatInfoManager.defaultManager.currentFilePath.lastPathComponent)
  2149. if FileManager.default.fileExists(atPath: tempFileURL.path) {
  2150. do {
  2151. try FileManager.default.removeItem(at: tempFileURL)
  2152. } catch {
  2153. }
  2154. }
  2155. if curDoc != nil {
  2156. curDoc.mainViewController?.SaveTempPDFDocumentToURLPath(tempPath: tempFileURL.path)
  2157. }
  2158. }
  2159. windowVC.window?.becomeMain()
  2160. }
  2161. }
  2162. if windowVC.window?.isVisible == true && windowVC.didSetOriginFrame == true {
  2163. } else {
  2164. var windowRect = windowVC.window?.frame
  2165. windowRect!.origin.x = NSMaxX(self.view.window!.frame) - (windowRect?.size.width)!
  2166. windowRect!.origin.y = NSMaxY(self.view.window!.frame) - (windowRect?.size.height)! - 64
  2167. windowVC.window?.setFrame(windowRect!, display: true)
  2168. windowVC.didSetOriginFrame = true
  2169. }
  2170. windowVC.eventLabel = "AITools_Tbr"
  2171. windowVC.showWindow(nil)
  2172. if (aiConfigType != .none) {
  2173. windowVC.eventLabel = "AITools_Start"
  2174. if self.listView.currentSelection?.string()?.isEmpty == false {
  2175. windowVC.setCurrentPDFSelection(self.listView.currentSelection.string())
  2176. }
  2177. windowVC.chooseAIFunctionWithType(aiConfigType)
  2178. }
  2179. }
  2180. @objc func aiTipIconViewShowStateChangeNoti() {
  2181. }
  2182. //MARK: - 引导
  2183. func loadFunctionGuide() -> Void {
  2184. DispatchQueue.main.asyncAfter(deadline: DispatchTime.now() + 1) {
  2185. if self.view.window != nil {
  2186. self.loadOpenFileFunctionGuide(.openFileNormal)
  2187. }
  2188. }
  2189. }
  2190. func loadOpenFileFunctionGuide(_ showType: KMGuideInfoType) -> Void {
  2191. if showType == .openFileNormal && KMGuideInfoWindowController.availableShow(.openFileNormal) {
  2192. let leftPanelItem:KMToolbarItemView = self.toolbarController.findItem("KMLeftControlToolbarItemIdentifier")!
  2193. self.guideInfoWindowController = KMGuideInfoWindowController.currentWC()
  2194. guard let guideWC = self.guideInfoWindowController else { return }
  2195. guideWC.type = .openFileNormal
  2196. guideWC.openPanelRect = (self.view.window?.contentView?.convert(leftPanelItem.frame, from: leftPanelItem.superview)) ?? .zero
  2197. guideWC.window?.collectionBehavior = [.canJoinAllSpaces]
  2198. guideWC.normalGuideFinishHandle = { [weak self] windowVC in
  2199. let rightPanelItem = self?.toolbarController.findItem(KMRightControlToolbarItemIdentifier)
  2200. let digitalPanelItem = self?.toolbarController.findItem(KMDocumentSignToolbarItemIdentifier)
  2201. if let data = rightPanelItem, data.isHidden {
  2202. let view = self?.toolbarController.mainToolBarView?.toolbar?.moreButton
  2203. windowVC.rightPanelRect = (self?.view.window?.contentView?.convert(view?.frame ?? .zero, from: view?.superview)) ?? .zero
  2204. } else {
  2205. windowVC.rightPanelRect = (self?.view.window?.contentView?.convert(rightPanelItem?.frame ?? .zero, from: rightPanelItem?.superview)) ?? .zero
  2206. }
  2207. guideWC.digitalBoxRect = (self?.view.window?.contentView?.convert(digitalPanelItem?.frame ?? .zero, from: digitalPanelItem?.superview)) ?? .zero
  2208. }
  2209. guideWC.finishHandle = { [weak self] windowVC, type in
  2210. if type == .windowNewFinish ||
  2211. type == . windowDigitalFinish {
  2212. self?.checkFirstTrialController()
  2213. }
  2214. }
  2215. guideWC.openFileToggleHandle = { [weak self] windowVC, type in
  2216. self?.checkFirstTrialController()
  2217. }
  2218. var rect = self.view.window!.frame
  2219. rect.size.height -= 20
  2220. guideWC.window?.setFrame(rect, display: false)
  2221. guideWC.window?.minSize = rect.size
  2222. guideWC.window?.maxSize = rect.size
  2223. self.view.window?.addChildWindow(guideWC.window!, ordered: .above)
  2224. guideWC.show()
  2225. } else if showType == .digitalSignGuide && KMGuideInfoWindowController.availableShow(.digitalSignGuide) {
  2226. self.guideInfoWindowController = KMGuideInfoWindowController.currentWC()
  2227. guard let guideWC = self.guideInfoWindowController else { return }
  2228. guideWC.type = .digitalSignGuide
  2229. guard let digitalPanelItem = self.toolbarController.findItem(KMDocumentSignToolbarItemIdentifier) else {
  2230. return
  2231. }
  2232. guideWC.digitalBoxRect = (self.view.window?.contentView?.convert(digitalPanelItem.frame, from: digitalPanelItem.superview))!
  2233. guideWC.window?.collectionBehavior = [.canJoinAllSpaces]
  2234. guideWC.finishHandle = { [weak self] windowVC, type in
  2235. self?.checkFirstTrialController()
  2236. }
  2237. var rect = self.view.window!.frame
  2238. rect.size.height -= 20
  2239. guideWC.window?.setFrame(rect, display: false)
  2240. guideWC.window?.minSize = rect.size
  2241. guideWC.window?.maxSize = rect.size
  2242. self.view.window?.addChildWindow(guideWC.window!, ordered: .above)
  2243. guideWC.show()
  2244. } else if showType == .pdfCompareGuide && KMGuideInfoWindowController.availableShow(.pdfCompareGuide) {
  2245. DispatchQueue.main.asyncAfter(deadline: DispatchTime.now() + 0.2) {
  2246. self.guideInfoWindowController = KMGuideInfoWindowController.currentWC()
  2247. guard let guideWC = self.guideInfoWindowController else { return }
  2248. guideWC.type = .pdfCompareGuide
  2249. guard let digitalPanelItem = self.toolbarController.findItem(KMDocumentSignToolbarItemIdentifier) else {
  2250. return
  2251. }
  2252. guard let win = self.view.window else {
  2253. return
  2254. }
  2255. guideWC.digitalBoxRect = (win.contentView?.convert(digitalPanelItem.frame, from: digitalPanelItem.superview)) ?? .zero
  2256. let compareItem = self.toolbarController.findItem(KMToolbarComparisonItemIdentifier)
  2257. guideWC.compareItemRect = (win.contentView?.convert(compareItem?.frame ?? .zero, from: compareItem?.superview)) ?? .zero
  2258. guideWC.finishHandle = { [weak self] winC, type in
  2259. if type == .windowNewFinish {
  2260. DispatchQueue.main.async {
  2261. self?.loadOpenFileFunctionGuide(.measureGuide)
  2262. }
  2263. return
  2264. }
  2265. }
  2266. guideWC.window?.collectionBehavior = [.canJoinAllSpaces]
  2267. var rect = self.view.window!.frame
  2268. rect.size.height -= 20
  2269. guideWC.window?.setFrame(rect, display: false)
  2270. guideWC.window?.minSize = rect.size
  2271. guideWC.window?.maxSize = rect.size
  2272. self.view.window?.addChildWindow(guideWC.window!, ordered: .above)
  2273. guideWC.show()
  2274. }
  2275. } else if showType == .measureGuide && KMGuideInfoWindowController.availableShow(.measureGuide) {
  2276. DispatchQueue.main.asyncAfter(deadline: DispatchTime.now() + 0.2) {
  2277. self.guideInfoWindowController = KMGuideInfoWindowController.currentWC()
  2278. guard let guideWC = self.guideInfoWindowController else { return }
  2279. guard let _ = self.view.window else {
  2280. return
  2281. }
  2282. guideWC.type = .measureGuide
  2283. guard let digitalPanelItem = self.toolbarController.findItem(KMDocumentSignToolbarItemIdentifier) else {
  2284. return
  2285. }
  2286. guideWC.digitalBoxRect = (self.view.window?.contentView?.convert(digitalPanelItem.frame, from: digitalPanelItem.superview)) ?? .zero
  2287. let compareItem:KMToolbarItemView = self.toolbarController.findItem(KMToolbarMeasureItemIdentifier)!
  2288. guideWC.compareItemRect = (self.view.window?.contentView?.convert(compareItem.frame, from: compareItem.superview)) ?? .zero
  2289. guideWC.window?.collectionBehavior = [.canJoinAllSpaces]
  2290. var rect = self.view.window?.frame ?? .zero
  2291. rect.size.height -= 20
  2292. guideWC.window?.setFrame(rect, display: false)
  2293. guideWC.window?.minSize = rect.size
  2294. guideWC.window?.maxSize = rect.size
  2295. self.view.window?.addChildWindow(guideWC.window!, ordered: .above)
  2296. guideWC.show()
  2297. }
  2298. } else if showType == .convertGuide && KMGuideInfoWindowController.availableShow(.convertGuide) {
  2299. DispatchQueue.main.asyncAfter(deadline: DispatchTime.now() + 1) {
  2300. self.guideInfoWindowController = KMGuideInfoWindowController.currentWC()
  2301. guard let guideWC = self.guideInfoWindowController else { return }
  2302. guideWC.type = .convertGuide
  2303. guard let digitalPanelItem = self.toolbarController.findItem(KMDocumentSignToolbarItemIdentifier) else {
  2304. return
  2305. }
  2306. guard let win = self.view.window else {
  2307. return
  2308. }
  2309. guideWC.digitalBoxRect = (self.view.window?.contentView?.convert(digitalPanelItem.frame, from: digitalPanelItem.superview)) ?? .zero
  2310. guideWC.purchaseHandle = { [weak self] windowVC in
  2311. #if VERSION_DMG
  2312. if IAPProductsManager.default().isAvailableAllFunction() {
  2313. if IAPProductsManager.default().isAvailableAdvancedPDFToOffice() {
  2314. //Convert:
  2315. self?.showAllConvertWindow(convertT: .Word)
  2316. } else {
  2317. let limitWC = KMPurchaseLimitWindowController.currentLimitWC()
  2318. limitWC.continueBlock = { windowController in
  2319. }
  2320. limitWC.window?.center()
  2321. limitWC.showWindow(nil)
  2322. }
  2323. } else {
  2324. KMPurchaseCompareWindowController.sharedInstance().showWindow(nil)
  2325. }
  2326. #else
  2327. if IAPProductsManager.default().isAvailableAllFunction() {
  2328. if IAPProductsManager.default().isAvailableAdvancedPDFToOffice() {
  2329. //Convert:
  2330. } else {
  2331. var vc = KMToolCompareWindowController(toolType: .Convert, selectNum: 1)
  2332. vc.showWindow(nil)
  2333. }
  2334. } else {
  2335. KMPurchaseCompareWindowController.sharedInstance().showWindow(nil)
  2336. }
  2337. #endif
  2338. }
  2339. guideWC.window?.collectionBehavior = [.canJoinAllSpaces]
  2340. var rect = self.view.window?.frame ?? .zero
  2341. rect.size.height -= 20
  2342. guideWC.window?.setFrame(rect, display: false)
  2343. guideWC.window?.minSize = rect.size
  2344. guideWC.window?.maxSize = rect.size
  2345. self.view.window?.addChildWindow(guideWC.window!, ordered: .above)
  2346. guideWC.show()
  2347. }
  2348. } else {
  2349. }
  2350. }
  2351. func checkFirstTrialController() -> Void {
  2352. #if VERSION_DMG
  2353. //打开文档后引导相关
  2354. if VerificationManager.default().status == .none {
  2355. let appVersion = Bundle.main.infoDictionary?["CFBundleShortVersionString"] as? String ?? ""
  2356. let lastVersion = UserDefaults.standard.object(forKey: "SKLastTrialVersionMainDocumentLaunchedKey") as? String ?? ""
  2357. if lastVersion.isEmpty || lastVersion != appVersion {
  2358. UserDefaults.standard.setValue(appVersion, forKey: "SKLastTrialVersionMainDocumentLaunchedKey")
  2359. UserDefaults.standard.synchronize()
  2360. KMPurchaseCompareWindowController.sharedInstance().showWindow(nil)
  2361. }
  2362. }
  2363. #endif
  2364. }
  2365. // MARK: - 页面编辑
  2366. open func enterPageEdit(_ pages: [Int] = []) {
  2367. if let doc = self.listView.document {
  2368. if doc.allowsCopying == false || doc.allowsPrinting == false {
  2369. KMBaseWindowController.checkPassword(url: doc.documentURL, type: .owner) { result, pwd in
  2370. if result && pwd.isEmpty == false {
  2371. self.listView.document?.unlock(withPassword: pwd)
  2372. Task { @MainActor in
  2373. self.enterPageEdit(pages)
  2374. }
  2375. } else {
  2376. self.exitPageEdit()
  2377. }
  2378. }
  2379. return
  2380. }
  2381. }
  2382. //选中page
  2383. var tPages = pages
  2384. if tPages.count == 0 {
  2385. if self.leftSideViewController.type.methodType == .Thumbnail {
  2386. tPages = self.leftSideViewController.thumb_fetchSelectedRows() ?? [self.listView.currentPageIndex]
  2387. }
  2388. }
  2389. if (hasEnterPageEdit()) {
  2390. exitPageEdit()
  2391. return
  2392. }
  2393. if (self.toolbarController != nil && self.toolbarController.mainToolBarView != nil) {
  2394. let toolBarView: KMToolbarViewController = self.toolbarController.mainToolBarView!
  2395. for (key, value) in toolBarView.toolbarItems {
  2396. if (key == KMRightControlToolbarItemIdentifier || key == KMLeftControlToolbarItemIdentifier) {
  2397. (value as! KMToolbarItemView).unEnabled = true
  2398. }
  2399. }
  2400. }
  2401. self.editPDFHanddler.clearData()
  2402. let controller = KMPDFEditViewController(self.listView.document)
  2403. controller.selectedPages = tPages
  2404. controller.listView = self.listView
  2405. self.addChild(controller)
  2406. self.PDFContendView.addSubview(controller.view)
  2407. controller.view.frame = self.PDFContendView.bounds
  2408. controller.view.autoresizingMask = [.width,.height]
  2409. self.listView.isHidden = true
  2410. controller.itemClick = { [weak self] index, params in
  2411. if (index == 1) { /// 双击退出
  2412. self?.enterEditMode(self!.leftSideViewController, [])
  2413. DispatchQueue.main.async {
  2414. let pageIndex: Int = params.first as! Int
  2415. self?.listView.go(toPageIndex: pageIndex, animated: true)
  2416. }
  2417. } else if (index == 2) { // 打印
  2418. self?.showPrintWindow(pageRange: KMPrintPageRange(type: .custom, selectPages: params.first as! [Int]))
  2419. }
  2420. }
  2421. controller.documentEditedCallback = { [weak self] params in
  2422. self?.recordIsPDFDocumentEdited()
  2423. }
  2424. controller.selectionDidChange = { selectedIndexs in
  2425. var indexSet = IndexSet()
  2426. for indexPath in selectedIndexs {
  2427. indexSet.insert(indexPath.item)
  2428. }
  2429. if indexSet.count != 0 {
  2430. }
  2431. }
  2432. }
  2433. open func exitPageEdit() {
  2434. if (self.toolbarController != nil && self.toolbarController.mainToolBarView != nil) {
  2435. let toolBarView: KMToolbarViewController = self.toolbarController.mainToolBarView!
  2436. for (key, value) in toolBarView.toolbarItems {
  2437. if (key == KMRightControlToolbarItemIdentifier || key == KMLeftControlToolbarItemIdentifier) {
  2438. (value as! KMToolbarItemView).unEnabled = false
  2439. }
  2440. }
  2441. }
  2442. self.toolbarController.findItem(KMDocumentPageToolbarItemIdentifier)?.isSelected = false
  2443. let editController = getPDFEditController()
  2444. if (editController == nil) {
  2445. return
  2446. }
  2447. self.listView.annotationType = .highlight
  2448. // FIXME: - sdk修复插入特定文档crash后,这行代码可以去掉
  2449. self.leftSideViewController.model.insertedDocumentSet.formUnion(editController?.model.insertedDocumentSet ?? [])
  2450. editController?.view.removeFromSuperview()
  2451. editController?.removeFromParent()
  2452. self.listView.isHidden = false
  2453. self.listView.layoutDocumentView()
  2454. self.view.window?.makeFirstResponder(self.listView)
  2455. self.listView.annotationType = .unkown
  2456. self.listView.go(toPageIndex: editController!.listViewCurrentIndex, animated: false)
  2457. if let data = editController?.isEdited, data {
  2458. self.leftSideViewController.reloadThumbnailDataIfNeed()
  2459. self.leftSideViewController.note_reloadDataIfNeed()
  2460. self.leftSideViewController.refreshUIOfOutlineIfNeed()
  2461. self.leftSideViewController.refreshUIOfSeachListIfNeed()
  2462. self.leftSideViewController.refreshUIOfBookmarkIfNeed()
  2463. }
  2464. }
  2465. open func hasEnterPageEdit() -> Bool {
  2466. return self.getPDFEditController() != nil
  2467. }
  2468. // MARK: - Edit PDF
  2469. func enterEditPDF() {
  2470. self.editPDFHanddler.enterEditPDF()
  2471. }
  2472. // MARK: - 数字签名
  2473. func hasShowDigitalSign() -> Bool {
  2474. return self.digitalSignController?.view.superview != nil
  2475. }
  2476. func canEnterDigitalSign() -> Bool {
  2477. guard let doc = self.listView.document else {
  2478. return false
  2479. }
  2480. return doc.allowsPrinting && doc.allowsCopying
  2481. }
  2482. func enterDigitalSign() {
  2483. self.listView.toolMode = .textToolMode
  2484. if self.hasShowDigitalSign() {
  2485. self.exitDigitalSign()
  2486. } else {
  2487. if self.needSaveDocument() {
  2488. self.saveDocumentWithProgressAlert { [unowned self] params in
  2489. if (self.listView.document != nil) {
  2490. self.showDigitalSignWindow(withFilePathURL: self.listView.document.documentURL)
  2491. }
  2492. }
  2493. return
  2494. }
  2495. if (self.listView.document != nil) {
  2496. self.showDigitalSignWindow(withFilePathURL: self.listView.document.documentURL)
  2497. }
  2498. }
  2499. }
  2500. func exitDigitalSign() {
  2501. self.digitalSignController?.view.removeFromSuperview()
  2502. // KMDocumentDigitalSignToolbarItemIdentifier
  2503. self.toolbarController.findItem(KMDocumentSignToolbarItemIdentifier)?.isSelected = false
  2504. }
  2505. func showDigitalSignWindow(withFilePathURL fileURL: URL) {
  2506. if !IAPProductsManager.default().isAvailableAllFunction(){
  2507. let winC = KMPurchaseCompareWindowController.sharedInstance()
  2508. winC?.kEventName = "Reading_DigitalSign_BuyNow"
  2509. winC?.showWindow(nil)
  2510. return
  2511. }
  2512. if hasShowDigitalSign() {
  2513. self.exitDigitalSign()
  2514. }
  2515. var currentPageIndex = listView.document?.index(for: listView.currentPage()) ?? 0
  2516. var password: String = ""
  2517. self.toolbarController.toolbarType = .None
  2518. password = listView.document?.password ?? ""
  2519. digitalSignController = KMPDFDigitalSignViewController()
  2520. digitalSignController?.currentPageIndex = Int(currentPageIndex)
  2521. digitalSignController?.url = listView.document?.documentURL
  2522. digitalSignController?.password = password
  2523. digitalSignController?.scaleFactor = listView.scaleFactor
  2524. digitalSignController?.titleChangeBlock = { title, index in
  2525. currentPageIndex = UInt(index)
  2526. }
  2527. digitalSignController?.buttonActionBlock = { [weak self] type, isChanged in
  2528. if type == .cancel {
  2529. if let page = self?.listView.document?.page(at: currentPageIndex) {
  2530. self?.listView.go(to: page)
  2531. }
  2532. self?.exitDigitalSign()
  2533. }
  2534. }
  2535. if let digitalSignView = digitalSignController?.view, let splitViewSuperview = mianSplitView.superview {
  2536. digitalSignView.frame = splitViewSuperview.bounds
  2537. digitalSignView.autoresizingMask = [.width, .height]
  2538. splitViewSuperview.addSubview(digitalSignView)
  2539. digitalSignController?.setCurrentPageIndex(Int(currentPageIndex))
  2540. }
  2541. }
  2542. // MARK: - Toolbar
  2543. func toolbarItemClickForExitMode(_ toolbarItem: KMToolbarItemView) {
  2544. if(toolbarItem.itemIdentifier != KMDocumentPageToolbarItemIdentifier) {
  2545. if (hasEnterPageEdit()) {
  2546. self.exitPageEdit()
  2547. }
  2548. }
  2549. if toolbarItem.itemIdentifier != KMDocumentRedactToolbarItemIdentifier {
  2550. if self.hasEnterRedact() {
  2551. self.exitRedact()
  2552. }
  2553. }
  2554. if toolbarItem.itemIdentifier != KMDocumentDigitalSignToolbarItemIdentifier {
  2555. if self.hasShowDigitalSign() {
  2556. self.exitDigitalSign()
  2557. }
  2558. }
  2559. if toolbarItem.itemIdentifier != KMDocumentEditToolbarItemIdentifier && toolbarItem.itemIdentifier != KMRightControlToolbarItemIdentifier && toolbarItem.itemIdentifier != KMLeftControlToolbarItemIdentifier {
  2560. self.commitEditingIfNeed()
  2561. }
  2562. }
  2563. // MARK: - Private Methods
  2564. private func getPDFEditController() -> KMPDFEditViewController? {
  2565. var editController: KMPDFEditViewController?
  2566. for controller in self.children {
  2567. if (controller.isKind(of: KMPDFEditViewController.self)) {
  2568. editController = (controller as! KMPDFEditViewController)
  2569. break
  2570. }
  2571. }
  2572. return editController
  2573. }
  2574. private func _getPDFRedactController() -> KMPDFRedactViewController? {
  2575. var controller: KMPDFRedactViewController?
  2576. for childC in self.children {
  2577. if (childC.isKind(of: KMPDFRedactViewController.self)) {
  2578. controller = (childC as! KMPDFRedactViewController)
  2579. break
  2580. }
  2581. }
  2582. return controller
  2583. }
  2584. private func addBackgroundMaskView() {
  2585. self.removeBackgroundMaskView()
  2586. if let superview = self.mianSplitView.superview {
  2587. let view = NSView()
  2588. superview.addSubview(view)
  2589. view.frame = superview.bounds
  2590. view.autoresizingMask = [.width, .height]
  2591. view.wantsLayer = true
  2592. view.layer?.backgroundColor = .white
  2593. self.background_mask = view
  2594. }
  2595. }
  2596. private func removeBackgroundMaskView() {
  2597. self.background_mask?.removeFromSuperview()
  2598. self.background_mask = nil
  2599. }
  2600. private func _goToFirstPageForFristAppear() {
  2601. DispatchQueue.main.asyncAfter(wallDeadline: .now()+0.1) {
  2602. self.listView.go(toPageIndex: 0, animated: false)
  2603. }
  2604. }
  2605. func isPDFPageCountExceedsLimit(filePath: String) -> Bool {
  2606. let url = URL(fileURLWithPath: filePath)
  2607. guard let document = PDFDocument(url: url) else {
  2608. return false
  2609. }
  2610. let pageCount = document.pageCount
  2611. return pageCount > 30
  2612. }
  2613. // MARK: - Redact 【标记密文】
  2614. func exeRedactConfirm(_ type: KMRedactConfirmType, callback: @escaping () -> ()?) {
  2615. let windowController = KMRedactConfirmWindowController(type)
  2616. self.currentWindowController = windowController
  2617. self.view.window?.beginSheet(windowController.window!)
  2618. windowController.itemClick = { [weak self] index in
  2619. if (index == 2) { /// 取消
  2620. self?.view.window?.endSheet((self?.currentWindowController.window)!)
  2621. self?.currentWindowController = nil
  2622. callback()
  2623. return
  2624. }
  2625. self?.view.window?.endSheet((self?.currentWindowController.window)!)
  2626. self?.currentWindowController = nil
  2627. let panel = NSSavePanel()
  2628. panel.nameFieldStringValue = "[新文件]"+((self?.listView.document?.documentURL.lastPathComponent) ?? "")
  2629. let button = NSButton.init(checkboxWithTitle: "保存后打开文档", target: nil, action: nil)
  2630. button.state = .on
  2631. panel.accessoryView = button
  2632. panel.isExtensionHidden = true
  2633. panel.beginSheetModal(for: (self?.view.window!)!) { response in
  2634. if response != .OK {
  2635. callback()
  2636. return
  2637. }
  2638. if (type == .redactOne) {
  2639. let anno = self!.listView.activeAnnotation
  2640. if (anno == nil || (anno?.isKind(of: CPDFRedactAnnotation.self)) == false) {
  2641. callback()
  2642. return
  2643. }
  2644. (anno as! CPDFRedactAnnotation).applyRedaction()
  2645. } else if (type == .redactAll) {
  2646. self?.listView.document?.applyRedactions()
  2647. } else if (type == .eraserOne) {
  2648. let anno = self!.listView.activeAnnotation
  2649. if (anno == nil || (anno?.isKind(of: CPDFRedactAnnotation.self)) == false) {
  2650. callback()
  2651. return
  2652. }
  2653. anno?.page.erasureRedact(from: anno!.bounds)
  2654. } else if (type == .eraserAll) {
  2655. KMRedactTools.eraserDocument((self?.listView.document)!) { result, errorAnno in
  2656. if (result == false) {
  2657. callback()
  2658. return
  2659. }
  2660. }
  2661. }
  2662. self!.listView.document?.write(to: panel.url)
  2663. if (button.state == .on) {
  2664. NSDocumentController.shared.openDocument(withContentsOf: panel.url!, display: true) { document, alreadyOpen, error in
  2665. }
  2666. } else {
  2667. NSWorkspace.shared.activateFileViewerSelecting([panel.url!])
  2668. }
  2669. callback()
  2670. }
  2671. }
  2672. }
  2673. // MARK: - Secure 【安全】
  2674. public func showSecureLimitTip() {
  2675. self.hiddenSecureLimitTip()
  2676. if self.secureAlertView == nil {
  2677. self.secureAlertView = KMSecureAlertView()
  2678. self.secureAlertView?.show(in: self.listView)
  2679. self.secureAlertView?.closeAction = { [unowned self] view in
  2680. self.hiddenSecureLimitTip()
  2681. self.removeFromAlertView()
  2682. self.showFormAlertView()
  2683. }
  2684. self.secureAlertView?.passwordAction = { [unowned self] view in
  2685. self.removeOwnerPassword()
  2686. self.removeFromAlertView()
  2687. self.showFormAlertView()
  2688. }
  2689. }
  2690. }
  2691. func removeOwnerPassword() {
  2692. guard let doc = self.listView.document else {
  2693. NSSound.beep()
  2694. return
  2695. }
  2696. if doc.allowsCopying && doc.allowsPrinting {
  2697. NSSound.beep()
  2698. return
  2699. }
  2700. _ = KMPasswordInputWindow.openWindow(window: self.view.window!, type: .owner, url: doc.documentURL) { [weak self] result, password in
  2701. if result == .cancel { /// 关闭
  2702. return
  2703. }
  2704. /// 解密成功
  2705. self?.hiddenSecureLimitTip()
  2706. self?.model.isSaveKeyChain = false
  2707. self?.listView.document?.unlock(withPassword: password)
  2708. }
  2709. }
  2710. public func hiddenSecureLimitTip() {
  2711. self.secureAlertView?.removeFromSuperview()
  2712. self.secureAlertView = nil
  2713. }
  2714. //MARK: - Form
  2715. func showFormAlertView() {
  2716. if (formAlertView == nil) {
  2717. formAlertView = KMFormAlertView()
  2718. formAlertView?.isCloseSecureView = self.secureAlertView != nil ? false : true
  2719. formAlertView?.showInView(self.listView)
  2720. } else {
  2721. self.removeFromAlertView()
  2722. }
  2723. }
  2724. func removeFromAlertView() {
  2725. formAlertView?.removeFromSuperview()
  2726. formAlertView = nil
  2727. }
  2728. override func mouseMoved(with event: NSEvent) {
  2729. self.view.window?.mouseMoved(with: event)
  2730. }
  2731. func savePageNumberIfNeed() {
  2732. if (KMPreferenceManager.shared.openLastUnlockedDocumentWhenAppStart) {
  2733. let scaleFactor = self.listView.scaleFactor ?? 0
  2734. if scaleFactor <= 0 {
  2735. return
  2736. }
  2737. if self.listView.document != nil {
  2738. KMPreferenceManager.shared.setPageNumber(self.listView.currentPageIndex, forKey: self.listView.document.documentURL.path)
  2739. KMPreferenceManager.shared.setPageScale(Float(self.listView.scaleFactor), forKey: self.listView.document.documentURL.path)
  2740. }
  2741. }
  2742. }
  2743. // MARK: - 显示合并窗口
  2744. public func showMergeWindow(url: URL? = nil, _ password: String?) {
  2745. DispatchQueue.main.async {
  2746. var documentURL = url
  2747. if documentURL == nil {
  2748. documentURL = self.listView.document?.documentURL
  2749. }
  2750. guard let _url = documentURL else { return }
  2751. guard let document = PDFDocument(url: _url) else { return }
  2752. self.mergeWindowController = KMMergeWindowController(document: document, password: password ?? "")
  2753. self.mergeWindowController!.oriDucumentUrl = self.listView.document?.documentURL
  2754. self.mergeWindowController!.pageIndex = self.listView.currentPageIndex
  2755. self.mergeWindowController!.cancelAction = { [unowned self] controller in
  2756. self.view.window?.endSheet(mergeWindowController!.window!)
  2757. }
  2758. self.mergeWindowController!.mergeAction = { [unowned self] controller, filePath in
  2759. self.view.window?.endSheet(mergeWindowController!.window!)
  2760. }
  2761. self.toolbarController.cancelSelected(KMToolbarToolMergeItemIdentifier)
  2762. self.view.window?.beginSheet(self.mergeWindowController!.window!)
  2763. }
  2764. }
  2765. // MARK: - 显示加密弹窗
  2766. public func showSecureWindow(_ url: URL) {
  2767. self.securityWindowController = KMSecurityWindowController(windowNibName: "KMSecurityWindowController")
  2768. guard let securityWindowController = securityWindowController else { return }
  2769. securityWindowController.documentURL = self.listView.document?.documentURL
  2770. securityWindowController.batchAction = { [unowned self] controller, files in
  2771. self.view.window?.endSheet((securityWindowController.window)!)
  2772. self.toolbarController.cancelSelected(KMToolbarToolCompressItemIdentifier)
  2773. let batchWindowController = KMBatchOperateWindowController.sharedWindowController
  2774. let batchOperateFile = KMBatchOperateFile(filePath: self.document?.documentURL.path ?? "", type: .AddPassword)
  2775. batchWindowController.switchToOperateType(.AddPassword, files: [batchOperateFile])
  2776. batchWindowController.window?.makeKeyAndOrderFront("")
  2777. }
  2778. securityWindowController.doneAction = { [unowned self] controller, options, attribute in
  2779. let openPanel = NSOpenPanel()
  2780. openPanel.canChooseFiles = false
  2781. openPanel.canChooseDirectories = true
  2782. openPanel.canCreateDirectories = true
  2783. openPanel.beginSheetModal(for: NSWindow.currentWindow()) { (result) in
  2784. if result == NSApplication.ModalResponse.OK {
  2785. for fileURL in openPanel.urls {
  2786. let document = CPDFDocument(url: self.document?.documentURL)
  2787. if document != nil {
  2788. document!.setDocumentAttributes(attribute)
  2789. let path = fileURL.path.stringByAppendingPathComponent(url.deletingPathExtension().lastPathComponent) + "_SetPassword" + "." + url.pathExtension
  2790. let success = document!.write(to: NSURL(fileURLWithPath: path) as URL, withOptions: options)
  2791. if success {
  2792. self.view.window?.endSheet((securityWindowController.window)!)
  2793. NSWorkspace.shared.activateFileViewerSelecting([URL(fileURLWithPath: path)])
  2794. }
  2795. }
  2796. }
  2797. }
  2798. }
  2799. }
  2800. securityWindowController.cancelAction = { [unowned self] controller in
  2801. self.view.window?.endSheet((securityWindowController.window)!)
  2802. }
  2803. NSWindow.currentWindow().beginSheet(securityWindowController.window!)
  2804. }
  2805. // MARK: - 保存文档
  2806. internal func needSaveDocument() -> Bool {
  2807. if (self.isPDFDocumentEdited) {
  2808. return self.isPDFDocumentEdited
  2809. }
  2810. if (self.needSave) {
  2811. return self.needSave
  2812. }
  2813. let document: KMMainDocument? = self.myDocument as? KMMainDocument
  2814. if (document?.isDocumentEdited == nil || document?.isDocumentEdited == false) {
  2815. return false
  2816. }
  2817. return true
  2818. }
  2819. internal func saveDocument(overlookDocumentIfEdited overlook: Bool = false) {
  2820. let document: KMMainDocument? = self.myDocument as? KMMainDocument
  2821. if (overlook) {
  2822. document?.save(nil)
  2823. return
  2824. }
  2825. if (self.isPDFDocumentEdited) {
  2826. self.clearIsPDFDocumentEdited()
  2827. self.needSave = false
  2828. document?.save(nil)
  2829. return
  2830. }
  2831. if (document?.isDocumentEdited == nil || document?.isDocumentEdited == false) {
  2832. return
  2833. }
  2834. document?.save(nil)
  2835. }
  2836. internal func asyncSaveDocument(overlookDocumentIfEdited overlook: Bool = false, callback:@escaping KMCommonBlock) {
  2837. let document: KMMainDocument? = self.myDocument as? KMMainDocument
  2838. if (overlook) {
  2839. DispatchQueue.main.async {
  2840. document?.save(nil)
  2841. callback()
  2842. }
  2843. return
  2844. }
  2845. if (self.isPDFDocumentEdited) {
  2846. self.clearIsPDFDocumentEdited()
  2847. self.needSave = false
  2848. DispatchQueue.main.async {
  2849. document?.save(nil)
  2850. callback()
  2851. }
  2852. return
  2853. }
  2854. if (document?.isDocumentEdited == nil || document?.isDocumentEdited == false) {
  2855. callback()
  2856. return
  2857. }
  2858. DispatchQueue.main.async {
  2859. document?.save(nil)
  2860. callback()
  2861. }
  2862. }
  2863. internal func saveDocumentWithProgressAlert(callback:@escaping KMCommonBlock) {
  2864. // 显示进度
  2865. AutoSaveManager.manager.isSaving = true
  2866. self.showProgressWindow(message: NSLocalizedString("Save", comment: "") + "PDF")
  2867. self.progressC?.maxValue = 3.0
  2868. self.progressC?.increment(by: 1.0)
  2869. // 保存文档
  2870. self.asyncSaveDocument { [weak self] params in
  2871. // 执行进度 [假进度]
  2872. self?.progressC?.increment(by: 1.0)
  2873. self?.progressC?.increment(by: 1.0)
  2874. DispatchQueue.main.asyncAfter(deadline: .now()+0.1) {
  2875. // 隐藏进度
  2876. self?.hiddenProgressWindow()
  2877. DispatchQueue.main.asyncAfter(deadline: .now()+1) {
  2878. AutoSaveManager.manager.isSaving = false
  2879. }
  2880. // 回调
  2881. callback()
  2882. }
  2883. }
  2884. }
  2885. func SaveTempPDFDocumentToURLPath(tempPath: String) {
  2886. self.document?.write(toFile: tempPath)
  2887. }
  2888. // MARK: - 定时保存
  2889. func addAutoSaveEvent() {
  2890. if (self.autoSaveTimer != nil) {
  2891. self.autoSaveTimer?.invalidate()
  2892. self.autoSaveTimer = nil
  2893. }
  2894. if self.document != nil {
  2895. self.autoSaveTimer = Timer.scheduledTimer(withTimeInterval: AutoSaveManager.manager.timeInterval * 60, repeats: true, block: { [weak self] timer in
  2896. self?.autoSaveTimerAction(timer)
  2897. })
  2898. }
  2899. self.checkAutoSaveInfo()
  2900. }
  2901. func checkAutoSaveInfo() {
  2902. guard let cnt = AutoSaveManager.manager.autoSavePaths?.count, cnt > 0 else {
  2903. return
  2904. }
  2905. if AutoSaveManager.manager.autoSaveAlertShow {
  2906. return
  2907. }
  2908. AutoSaveManager.manager.autoSaveDidEndAction = false
  2909. AutoSaveManager.manager.autoSaveAlertShow = true
  2910. let blockSaveWindow = AutoSavePopController()
  2911. blockSaveWindow.cancelHandle = { [weak self] windowController in
  2912. AutoSaveManager.manager.autoSaveDidEndAction = true
  2913. AutoSaveManager.manager.clearCache()
  2914. self?.km_quick_endSheet()
  2915. }
  2916. blockSaveWindow.confirmHandle = { [weak self] windowController in
  2917. self?.km_quick_endSheet()
  2918. self?.saveAutoSaveInfo()
  2919. }
  2920. self.km_beginSheet(windowC: blockSaveWindow)
  2921. }
  2922. func saveAutoSaveInfo() {
  2923. let openPanel = NSOpenPanel()
  2924. openPanel.canChooseDirectories = true
  2925. openPanel.canChooseFiles = false
  2926. openPanel.allowsMultipleSelection = false
  2927. let win = NSApp.keyWindow != nil ? NSApp.keyWindow : self.view.window
  2928. openPanel.beginSheetModal(for: win!) { result in
  2929. if (result == .OK) {
  2930. let folderPath = openPanel.url?.path ?? openPanel.url?.absoluteString
  2931. for path in AutoSaveManager.manager.opendPaths ?? [] {
  2932. let _path = path as? String
  2933. var newPath = "\(folderPath ?? "")/\(_path?.lastPathComponent ?? "")"
  2934. newPath = self.getValidFilePath(newPath)
  2935. do {
  2936. try FileManager.default.moveItem(atPath: _path ?? "", toPath: newPath)
  2937. } catch {
  2938. NSWorkspace.shared.activateFileViewerSelecting([URL(fileURLWithPath: newPath)])
  2939. }
  2940. }
  2941. AutoSaveManager.manager.clearCache()
  2942. }
  2943. AutoSaveManager.manager.autoSaveDidEndAction = true
  2944. }
  2945. }
  2946. func autoSaveTimerAction(_ timer: Timer) {
  2947. if (self.document == nil || self.listView.document?.documentURL.path == nil) {
  2948. return
  2949. }
  2950. if AutoSaveManager.manager.autoSaveDidEndAction == false {
  2951. //防止提示弹窗出现后,未进行任何操作又进入自动保存的机制
  2952. return
  2953. }
  2954. if let data = self.document?.isLocked, data {
  2955. return
  2956. }
  2957. if AutoSaveManager.manager.autoSaveEnabled == false {
  2958. return
  2959. }
  2960. let documentArray = NSDocumentController.shared.documents
  2961. var didFileEdit = false
  2962. for doc in documentArray {
  2963. if doc.fileURL?.path == self.document?.documentURL.path {
  2964. didFileEdit = doc.isDocumentEdited
  2965. break
  2966. }
  2967. }
  2968. if (didFileEdit == false) {
  2969. return
  2970. }
  2971. AutoSaveManager.manager.isSaving = true
  2972. let savePath = AutoSaveManager.manager.autoSaveWithPath(self.listView.document?.documentURL.path ?? "")
  2973. if (!self.document!.isLocked) {
  2974. self.document?.write(to: URL(fileURLWithPath: savePath))
  2975. }
  2976. DispatchQueue.main.asyncAfter(deadline: .now() + 1.5) {
  2977. AutoSaveManager.manager.isSaving = false
  2978. }
  2979. }
  2980. func removeAutoSaveInfo() {
  2981. if self.autoSaveTimer != nil {
  2982. self.autoSaveTimer?.invalidate()
  2983. self.autoSaveTimer = nil
  2984. }
  2985. if AutoSaveManager.manager.autoSaveDidEndAction == false {
  2986. //防止提示弹窗出现后,未进行任何操作又进入自动保存的机制
  2987. return
  2988. }
  2989. if AutoSaveManager.manager.autoSaveEnabled == false {
  2990. return
  2991. }
  2992. if self.document == nil || self.listView.document?.documentURL.path == nil {
  2993. return
  2994. }
  2995. AutoSaveManager.manager.removeAutoSavePath(self.listView.document?.documentURL.path ?? "")
  2996. }
  2997. // MARK: - 选择 PDFDisplay 模式
  2998. @objc public func selectDisplay(display: KMPDFDisplayType, viewSettingIsReload: Bool = true) {
  2999. let toolModel = self.listView.toolMode
  3000. self.viewManager.isPDFReadMode = false
  3001. switch display {
  3002. case .singlePage:
  3003. self.listView.setDisplay(.singlePage)
  3004. break
  3005. case .singlePageContinuous:
  3006. self.listView.setDisplay(.singlePageContinuous)
  3007. break
  3008. case .twoUp:
  3009. self.listView.setDisplay(.twoUp)
  3010. break
  3011. case .twoUpContinuous:
  3012. self.listView.setDisplay(.twoUpContinuous)
  3013. break
  3014. case .bookMode:
  3015. self.listView.displaysAsBook = true
  3016. self.listView.displayTwoUp = true
  3017. self.listView.displayDirection = .horizontal
  3018. break
  3019. case .bookContinuous:
  3020. self.listView.displaysAsBook = true
  3021. self.listView.displayTwoUp = true
  3022. self.listView.displayDirection = .vertical
  3023. break
  3024. case .readModel:
  3025. self.openPDFReadMode()
  3026. break
  3027. case .readContinuous:
  3028. self.openPDFReadMode()
  3029. break
  3030. }
  3031. self.listView.layoutDocumentView()
  3032. if (toolModel == .editPDFToolMode) {
  3033. if self.rightSideViewController.eidtPDFImageProperty != nil {
  3034. self.rightSideViewController.eidtPDFImageProperty?.cancelCutImageAction("")
  3035. self.rightSideViewController.isHidden = true
  3036. self.closeRightPane()
  3037. }
  3038. }
  3039. }
  3040. // MARK: - 选择缩放模式
  3041. @objc public func selectZoom(_ type: KMPDFZoomType) {
  3042. switch type {
  3043. case .width:
  3044. self.listView.autoScales = true
  3045. break
  3046. case .fit:
  3047. if let pageHeight = self.listView.currentPage()?.size.height, pageHeight > 0 {
  3048. let pdfviewHeight = self.listView.bounds.size.height
  3049. self.listView.scaleFactor = pdfviewHeight/pageHeight
  3050. self.listView.autoScales = false
  3051. }
  3052. break
  3053. case .actualSize:
  3054. if self.listView.scaleFactor != 1.0 {
  3055. self.listView.scaleFactor = 1.0
  3056. self.listView.autoScales = false
  3057. }
  3058. break
  3059. }
  3060. }
  3061. internal func createPdf(index:Int) {
  3062. }
  3063. // MARK - Event 监听
  3064. private func addEventMonitor() {
  3065. if (self.eventMonitor != nil) {
  3066. self.removeEventMonitor()
  3067. }
  3068. self.eventMonitor = NSEvent.addLocalMonitorForEvents(matching: [.scrollWheel, .leftMouseDown, .leftMouseUp]) { [weak self] event in
  3069. if (event.type == .scrollWheel && event.modifierFlags.contains(.option)) { // Alt + 鼠标滚轮
  3070. self?.listView.magnifyWheel(event)
  3071. return nil
  3072. } else if event.type == .leftMouseDown {
  3073. let point = event.locationInView(self?.listView ?? NSView())
  3074. let presentationDrawView = self?.listView.presentationDrawView
  3075. if let data = self?.interactionMode, data == .presentation,CGRectContainsPoint(self?.listView.frame ?? .zero, point),presentationDrawView?.isHidden == true { // 幻灯片模式下
  3076. if point.x >= (self?.listView.frame.maxX ?? 0) / 2 {
  3077. let can = self?.listView.canGoToNextPage() ?? false
  3078. if can {
  3079. self?.listView.goToNextPage(nil)
  3080. }
  3081. } else {
  3082. let can = self?.listView.canGoToPreviousPage() ?? false
  3083. if can {
  3084. self?.listView.goToPreviousPage(nil)
  3085. }
  3086. }
  3087. return nil
  3088. }
  3089. }
  3090. return event
  3091. }
  3092. }
  3093. func addKeyEventMonitor() {
  3094. if (self.keyEventMonitor != nil) {
  3095. self.removeKeyEventMonitor()
  3096. }
  3097. keyEventMonitor = NSEvent.addLocalMonitorForEvents(matching: .keyDown) { [weak self] event in
  3098. if event.keyCode == 53 {
  3099. if let data = self?.interactionMode, data == .presentation { // 幻灯片模式下
  3100. self?.exitFullScreen()
  3101. return nil
  3102. }
  3103. if self?.listView.toolMode == .editPDFToolMode {
  3104. if self != nil {
  3105. //使用editingSelectionString获取内容文字
  3106. if self!.listView.editingAreas() != nil {
  3107. if self!.listView.editingAreas().count > 0 && self!.listView.isEditable() {
  3108. self!.listView.clearEditingSelectCharItem()
  3109. } else if self!.listView.editingAreas().count > 0 {
  3110. if self?.listView.annotationType == .addImage ||
  3111. self?.listView.annotationType == .addText {
  3112. let textItem = self?.toolbarController.findItem(KMToolbarAddTextEditPDFItemIdentifier)
  3113. let imageItem = self?.toolbarController.findItem(KMToolbarAddImageEditPDFItemIdentifier)
  3114. textItem?.isSelected = false
  3115. imageItem?.isSelected = false
  3116. }
  3117. self?.rightSideViewController.isHidden = true
  3118. self?.listView.endEditIsRemoveBlock(with: self!.listView.editingAreas().first as? CPDFEditArea)
  3119. self?.listView.updateEditing([])
  3120. self?.listView.isEditImage = false
  3121. self?.listView.setNeedsDisplayPageViewFor(self!.listView.currentPage())
  3122. if self?.listView.annotationType == .addImage {
  3123. self?.listView.change([.text, .image])
  3124. }
  3125. self?.listView.annotationType = .editTextImage
  3126. self?.closeRightPane()
  3127. } else if(self?.listView.annotationType == .addImage || self!.listView.annotationType == .addText) {
  3128. if self?.listView.annotationType == .addImage ||
  3129. self?.listView.annotationType == .addText {
  3130. let textItem = self?.toolbarController.findItem(KMToolbarAddTextEditPDFItemIdentifier)
  3131. let imageItem = self?.toolbarController.findItem(KMToolbarAddImageEditPDFItemIdentifier)
  3132. textItem?.isSelected = false
  3133. imageItem?.isSelected = false
  3134. }
  3135. self?.rightSideViewController.isHidden = true
  3136. self?.listView.setShouAddEdit([])
  3137. self?.listView.change([.text, .image])
  3138. self?.listView.annotationType = .editTextImage
  3139. self?.closeRightPane()
  3140. }
  3141. } else {
  3142. if self?.listView.annotationType == .addImage ||
  3143. self?.listView.annotationType == .addText {
  3144. let textItem = self?.toolbarController.findItem(KMToolbarAddTextEditPDFItemIdentifier)
  3145. let imageItem = self?.toolbarController.findItem(KMToolbarAddImageEditPDFItemIdentifier)
  3146. textItem?.isSelected = false
  3147. imageItem?.isSelected = false
  3148. }
  3149. }
  3150. }
  3151. }
  3152. } else {
  3153. if let data = self?.interactionMode, data == .presentation { // 幻灯片模式下
  3154. self?.listView.keyDown(with: event)
  3155. return nil
  3156. } else {
  3157. let cmd = event.modifierFlags.contains(.command)
  3158. let shift = event.modifierFlags.contains(.shift)
  3159. if event.keyCode == 6 { // z
  3160. let editPDFIng = self?.editPDFHanddler.isEditing ?? false
  3161. if cmd && shift { // 恢复
  3162. let can = self?.editPDFHanddler.listView?.canEditTextRedo() ?? false
  3163. if can == false {
  3164. return event
  3165. }
  3166. if editPDFIng {
  3167. _ = CustomAlertView.alertView(message: NSLocalizedString("Redo", comment: ""), fromView: self!.view, withStyle: .black)
  3168. }
  3169. } else if cmd { // 撤回
  3170. let can = self?.editPDFHanddler.listView?.canEditTextUndo() ?? false
  3171. if can == false {
  3172. return event
  3173. }
  3174. if editPDFIng {
  3175. _ = CustomAlertView.alertView(message: NSLocalizedString("Undo", comment: ""), fromView: self!.view, withStyle: .black)
  3176. }
  3177. }
  3178. }
  3179. }
  3180. }
  3181. return event
  3182. }
  3183. }
  3184. func removeKeyEventMonitor() {
  3185. if (self.keyEventMonitor != nil) {
  3186. KMPrint("removeKeyEventMonitor 已移除事件监听")
  3187. NSEvent.removeMonitor(self.keyEventMonitor as Any)
  3188. self.keyEventMonitor = nil
  3189. }
  3190. }
  3191. private func removeEventMonitor() {
  3192. if (self.eventMonitor != nil) {
  3193. KMPrint("已移除事件监听")
  3194. NSEvent.removeMonitor(self.eventMonitor as Any)
  3195. self.eventMonitor = nil
  3196. }
  3197. }
  3198. // MARK: - Tools
  3199. func pdfViewCanHorizontalScroll() -> Bool {
  3200. let scroll = self.listView.scroll()
  3201. if (scroll == nil) {
  3202. return false
  3203. }
  3204. return scroll?.horizontalScroller?.isHidden == nil ? false : !(scroll!.horizontalScroller!.isHidden)
  3205. }
  3206. func pdfViewCanVerticalScroll() -> Bool {
  3207. let scroll = self.listView.scroll()
  3208. if (scroll == nil) {
  3209. return false
  3210. }
  3211. return scroll?.verticalScroller?.isHidden == nil ? false : !(scroll!.verticalScroller!.isHidden)
  3212. }
  3213. // MARK: - Public Methods
  3214. // 清理数据 [eg. 通知]
  3215. public func clearData() {
  3216. KMThumbnailCache.shared.clearCache()
  3217. self.removeNotifications()
  3218. if (self.listView.spellingTag() > 0) {
  3219. NSSpellChecker.shared.closeSpellDocument(withTag: self.listView.spellingTag())
  3220. }
  3221. self.removeAutoSaveInfo()
  3222. KMAdsManager.defaultManager.dismissSheetModal(for: self.readContentView)
  3223. self.myDocument = nil
  3224. }
  3225. public func clearSecureOptions() {
  3226. self._secureOptions = nil
  3227. self.documentAttribute = nil
  3228. }
  3229. public func recordRemoveSecureFlag() {
  3230. self._removeSecureFlag = true
  3231. self.clearSecureOptions()
  3232. self.recordIsPDFDocumentEdited(type: .removePassword)
  3233. self._needSave = true
  3234. }
  3235. public func clearRemoveSecureFlag() {
  3236. self._removeSecureFlag = false
  3237. }
  3238. public func clearSaveWatermarkFlag() {
  3239. km_synchronized(self) {
  3240. self._saveWatermarkFlag = false
  3241. }
  3242. }
  3243. public func recordIsPDFDocumentEdited(type: KMSubscribeWaterMarkType = .none) {
  3244. km_synchronized(self) {
  3245. self.model.isPDFDocumentEdited = true
  3246. if type == .editText || type == .editImage {
  3247. self.leftSideViewController.updateThumbnail(at: self.listView.currentPageIndex)
  3248. }
  3249. if let _document = self.myDocument {
  3250. KMTools.setDocumentEditedState(document: _document)
  3251. }
  3252. }
  3253. }
  3254. public func clearIsPDFDocumentEdited() {
  3255. km_synchronized(self) {
  3256. self.model.isPDFDocumentEdited = false
  3257. }
  3258. }
  3259. func showSnapshots(setups: NSArray?) {
  3260. if self.listView.document != nil {
  3261. for setup in setups ?? [] {
  3262. let swc = KMSnapshotWindowController()
  3263. swc.delegate = self
  3264. swc.setPdfDocument(self.listView.document, setup: setup as? NSDictionary)
  3265. swc.setForceOnTop(self.interactionMode != .normal)
  3266. self.myDocument?.addWindowController(swc)
  3267. }
  3268. }
  3269. }
  3270. func dealDocumentDidLoaded() {
  3271. self.removeBackgroundMaskView()
  3272. if (!self.listView.document!.allowsCopying || !self.listView.document!.allowsPrinting) {
  3273. self.showSecureLimitTip()
  3274. }
  3275. if self.model.needConvertNotes {
  3276. self.showConvertNotesProgress()
  3277. }
  3278. if (self._documentFirstLoad) {
  3279. self.checkShouldAutoOpenLeftVC()
  3280. if (KMPreferenceManager.shared.openLastUnlockedDocumentWhenAppStart) {
  3281. let pageNumber = KMPreferenceManager.shared.getPageNumber(forKey: self.listView.document?.documentURL.path ?? "")
  3282. let pageScale = KMPreferenceManager.shared.getPageScale(forKey: self.listView.document?.documentURL.path ?? "")
  3283. if (pageScale != nil) {
  3284. self.listView.scaleFactor = CGFloat(pageScale!)
  3285. }
  3286. if (pageNumber != nil && pageNumber! >= 0 && pageNumber! < (self.listView.document?.pageCount ?? 0)) {
  3287. self.listView.go(toPageIndex: pageNumber!, animated: false)
  3288. } else {
  3289. self._goToFirstPageForFristAppear()
  3290. }
  3291. } else {
  3292. self._goToFirstPageForFristAppear()
  3293. }
  3294. self._documentFirstLoad = false
  3295. }
  3296. }
  3297. func tabViewIsDragging() -> Bool {
  3298. let level = self.view.window?.level ?? .normal
  3299. return level == .floating
  3300. }
  3301. // MARK: - Noti Actions
  3302. internal func documentDidUnlockNotification(_ sender: Notification) {
  3303. if (self.listView.document != nil && self.listView.document.isEqual(to: sender.object)) {
  3304. if (self.myDocument == nil) {
  3305. return
  3306. }
  3307. if (self.listView.document.allowsPrinting && self.listView.document.allowsCopying) {
  3308. self.hiddenSecureLimitTip()
  3309. }
  3310. let isUnlockFromKeychain = (self.myDocument as? KMMainDocument)?.isUnlockFromKeychain ?? false
  3311. if (isUnlockFromKeychain || self.model.isSaveKeyChain == false) {
  3312. return
  3313. }
  3314. let type = KMPreferenceManager.shared.savePasswordType
  3315. if (type == .never) {
  3316. return
  3317. }
  3318. if (type == .always) {
  3319. self.myDocument?.savePasswordInKeychain(self.listView.document.password, self.listView.document)
  3320. return
  3321. }
  3322. // 保存到钥匙串
  3323. let alert = NSAlert()
  3324. alert.messageText = NSLocalizedString("Remember Password?", comment: "")
  3325. alert.informativeText = NSLocalizedString("Do you want to save this password in your Keychain?", comment: "")
  3326. alert.addButton(withTitle: NSLocalizedString("Yes", comment: ""))
  3327. alert.addButton(withTitle: NSLocalizedString("No", comment: ""))
  3328. if (alert.runModal() == .alertFirstButtonReturn) { // 保存密码
  3329. self.myDocument?.savePasswordInKeychain(self.listView.document.password, self.listView.document)
  3330. return
  3331. }
  3332. }
  3333. }
  3334. func annotationsAttributeHasChange(_ sender: Notification) {
  3335. guard let dict = sender.object as? [String : Any] else {
  3336. return
  3337. }
  3338. if let anno = dict["object"] as? CPDFAnnotation {
  3339. let value = dict["keyPath"] as? String ?? ""
  3340. let didEnd = dict["didEnd"] as? Bool ?? false
  3341. if didEnd {
  3342. if value == CPDFAnnotationBoundsKey {
  3343. if anno is CPDFSquareAnnotation || anno is CPDFCircleAnnotation {
  3344. anno.contents = anno.page?.string(for: anno.bounds) ?? ""
  3345. }
  3346. }
  3347. if anno.km_isMeasure() && anno.contents == nil {
  3348. anno.contents = anno.string() ?? ""
  3349. }
  3350. self.leftSideViewController.refreshUIForAnnoAttributeDidChange(anno, attributes: ["keyPath" : value])
  3351. } else {
  3352. if value != CPDFAnnotationBoundsKey && value != CPDFAnnotationStartPointKey && value != CPDFAnnotationEndPointKey && value != CPDFAnnotationPathsKey { // 改变bounds(箭头、直线注释 开始点和结束点, 手绘注释的paths)的操作会卡顿,比如移动
  3353. self.leftSideViewController.refreshUIForAnnoAttributeDidChange(anno, attributes: ["keyPath" : value])
  3354. }
  3355. }
  3356. }
  3357. }
  3358. internal func applicationWillTerminateNotification(_ sender: Notification) {
  3359. self.savePageNumberIfNeed()
  3360. self.saveDocument()
  3361. }
  3362. func CPDFDocumentPageCountChangedNotification(_ sender: Notification) {
  3363. self.leftSideViewController.refreshUIForAnnoAttributeDidChange(nil, attributes: nil)
  3364. }
  3365. func CEditPDFToolModeChangeStateUnkownNotification(_ sender: Notification) {
  3366. var editSelectd = false
  3367. if (self.listView.annotationType == .addText || self.listView.annotationType == .addImage) && self.listView.toolMode == .editPDFToolMode {
  3368. editSelectd = true
  3369. }
  3370. if self.listView.toolMode == .editPDFToolMode {
  3371. if editSelectd {
  3372. self.toolbarController.cancelSelected(KMToolbarAddTextEditPDFItemIdentifier)
  3373. }
  3374. }
  3375. }
  3376. @objc func handlePageChangedNotification(_ sender: Notification) {
  3377. if self.mwcFlags.isSwitchingFullScreen > 0 {
  3378. return
  3379. }
  3380. let page = self.listView.currentPage()
  3381. let pageIndex = page?.pageIndex() ?? 0
  3382. self.leftSideViewController.thumb_selectRowIndexsIfNeed(IndexSet(integer: IndexSet.Element(pageIndex)))
  3383. self.leftSideViewController.thumbnailTableView.needsDisplay = true
  3384. self.leftSideViewController.tocOutlineView.needsDisplay = true
  3385. }
  3386. @objc func handleDisplayBoxChangedNotification(_ sender: Notification) {
  3387. self.leftSideViewController.reloadThumbnailDataIfNeed()
  3388. }
  3389. }