KMMainViewController.swift 146 KB

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