KMMainViewController.swift 134 KB

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