KMMainViewController.swift 132 KB

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