KMMainViewController.swift 129 KB

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