KMMainViewController.swift 132 KB

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