KMMainViewController.swift 137 KB

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