KMMainViewController.swift 176 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786178717881789179017911792179317941795179617971798179918001801180218031804180518061807180818091810181118121813181418151816181718181819182018211822182318241825182618271828182918301831183218331834183518361837183818391840184118421843184418451846184718481849185018511852185318541855185618571858185918601861186218631864186518661867186818691870187118721873187418751876187718781879188018811882188318841885188618871888188918901891189218931894189518961897189818991900190119021903190419051906190719081909191019111912191319141915191619171918191919201921192219231924192519261927192819291930193119321933193419351936193719381939194019411942194319441945194619471948194919501951195219531954195519561957195819591960196119621963196419651966196719681969197019711972197319741975197619771978197919801981198219831984198519861987198819891990199119921993199419951996199719981999200020012002200320042005200620072008200920102011201220132014201520162017201820192020202120222023202420252026202720282029203020312032203320342035203620372038203920402041204220432044204520462047204820492050205120522053205420552056205720582059206020612062206320642065206620672068206920702071207220732074207520762077207820792080208120822083208420852086208720882089209020912092209320942095209620972098209921002101210221032104210521062107210821092110211121122113211421152116211721182119212021212122212321242125212621272128212921302131213221332134213521362137213821392140214121422143214421452146214721482149215021512152215321542155215621572158215921602161216221632164216521662167216821692170217121722173217421752176217721782179218021812182218321842185218621872188218921902191219221932194219521962197219821992200220122022203220422052206220722082209221022112212221322142215221622172218221922202221222222232224222522262227222822292230223122322233223422352236223722382239224022412242224322442245224622472248224922502251225222532254225522562257225822592260226122622263226422652266226722682269227022712272227322742275227622772278227922802281228222832284228522862287228822892290229122922293229422952296229722982299230023012302230323042305230623072308230923102311231223132314231523162317231823192320232123222323232423252326232723282329233023312332233323342335233623372338233923402341234223432344234523462347234823492350235123522353235423552356235723582359236023612362236323642365236623672368236923702371237223732374237523762377237823792380238123822383238423852386238723882389239023912392239323942395239623972398239924002401240224032404240524062407240824092410241124122413241424152416241724182419242024212422242324242425242624272428242924302431243224332434243524362437243824392440244124422443244424452446244724482449245024512452245324542455245624572458245924602461246224632464246524662467246824692470247124722473247424752476247724782479248024812482248324842485248624872488248924902491249224932494249524962497249824992500250125022503250425052506250725082509251025112512251325142515251625172518251925202521252225232524252525262527252825292530253125322533253425352536253725382539254025412542254325442545254625472548254925502551255225532554255525562557255825592560256125622563256425652566256725682569257025712572257325742575257625772578257925802581258225832584258525862587258825892590259125922593259425952596259725982599260026012602260326042605260626072608260926102611261226132614261526162617261826192620262126222623262426252626262726282629263026312632263326342635263626372638263926402641264226432644264526462647264826492650265126522653265426552656265726582659266026612662266326642665266626672668266926702671267226732674267526762677267826792680268126822683268426852686268726882689269026912692269326942695269626972698269927002701270227032704270527062707270827092710271127122713271427152716271727182719272027212722272327242725272627272728272927302731273227332734273527362737273827392740274127422743274427452746274727482749275027512752275327542755275627572758275927602761276227632764276527662767276827692770277127722773277427752776277727782779278027812782278327842785278627872788278927902791279227932794279527962797279827992800280128022803280428052806280728082809281028112812281328142815281628172818281928202821282228232824282528262827282828292830283128322833283428352836283728382839284028412842284328442845284628472848284928502851285228532854285528562857285828592860286128622863286428652866286728682869287028712872287328742875287628772878287928802881288228832884288528862887288828892890289128922893289428952896289728982899290029012902290329042905290629072908290929102911291229132914291529162917291829192920292129222923292429252926292729282929293029312932293329342935293629372938293929402941294229432944294529462947294829492950295129522953295429552956295729582959296029612962296329642965296629672968296929702971297229732974297529762977297829792980298129822983298429852986298729882989299029912992299329942995299629972998299930003001300230033004300530063007300830093010301130123013301430153016301730183019302030213022302330243025302630273028302930303031303230333034303530363037303830393040304130423043304430453046304730483049305030513052305330543055305630573058305930603061306230633064306530663067306830693070307130723073307430753076307730783079308030813082308330843085308630873088308930903091309230933094309530963097309830993100310131023103310431053106310731083109311031113112311331143115311631173118311931203121312231233124312531263127312831293130313131323133313431353136313731383139314031413142314331443145314631473148314931503151315231533154315531563157315831593160316131623163316431653166316731683169317031713172317331743175317631773178317931803181318231833184318531863187318831893190319131923193319431953196319731983199320032013202320332043205320632073208320932103211321232133214321532163217321832193220322132223223322432253226322732283229323032313232323332343235323632373238323932403241324232433244324532463247324832493250325132523253325432553256325732583259326032613262326332643265326632673268326932703271327232733274327532763277327832793280328132823283328432853286328732883289329032913292329332943295329632973298329933003301330233033304330533063307330833093310331133123313331433153316331733183319332033213322332333243325332633273328332933303331333233333334333533363337333833393340334133423343334433453346334733483349335033513352335333543355335633573358335933603361336233633364336533663367336833693370337133723373337433753376337733783379338033813382338333843385338633873388338933903391339233933394339533963397339833993400340134023403340434053406340734083409341034113412341334143415341634173418341934203421342234233424342534263427342834293430343134323433343434353436343734383439344034413442344334443445344634473448344934503451345234533454345534563457345834593460346134623463346434653466346734683469347034713472347334743475347634773478347934803481348234833484348534863487348834893490349134923493349434953496349734983499350035013502350335043505350635073508350935103511351235133514351535163517351835193520352135223523352435253526352735283529353035313532353335343535353635373538353935403541354235433544354535463547354835493550355135523553355435553556355735583559356035613562356335643565356635673568356935703571357235733574357535763577357835793580358135823583358435853586358735883589359035913592359335943595359635973598359936003601360236033604360536063607360836093610361136123613361436153616361736183619362036213622362336243625362636273628362936303631363236333634363536363637363836393640364136423643364436453646364736483649365036513652365336543655365636573658365936603661366236633664366536663667366836693670367136723673367436753676367736783679368036813682368336843685368636873688368936903691369236933694369536963697369836993700370137023703370437053706370737083709371037113712371337143715371637173718371937203721372237233724372537263727372837293730373137323733373437353736373737383739374037413742374337443745374637473748374937503751375237533754375537563757375837593760376137623763376437653766376737683769377037713772377337743775377637773778377937803781378237833784378537863787378837893790379137923793379437953796379737983799380038013802380338043805380638073808380938103811381238133814381538163817381838193820382138223823382438253826382738283829383038313832383338343835383638373838383938403841384238433844384538463847384838493850385138523853385438553856385738583859386038613862386338643865386638673868386938703871387238733874387538763877387838793880388138823883388438853886388738883889389038913892389338943895389638973898389939003901390239033904390539063907390839093910391139123913391439153916391739183919392039213922392339243925392639273928392939303931393239333934393539363937393839393940394139423943394439453946394739483949395039513952395339543955395639573958395939603961396239633964396539663967396839693970397139723973397439753976397739783979398039813982398339843985398639873988398939903991399239933994399539963997399839994000400140024003400440054006400740084009401040114012401340144015401640174018401940204021402240234024402540264027402840294030403140324033403440354036403740384039404040414042404340444045404640474048404940504051405240534054405540564057405840594060406140624063406440654066406740684069407040714072407340744075407640774078407940804081408240834084408540864087408840894090409140924093409440954096409740984099410041014102410341044105410641074108410941104111411241134114411541164117411841194120412141224123412441254126412741284129413041314132413341344135413641374138413941404141414241434144414541464147414841494150415141524153415441554156415741584159416041614162416341644165416641674168416941704171417241734174417541764177417841794180418141824183418441854186418741884189419041914192419341944195419641974198419942004201420242034204420542064207420842094210421142124213
  1. //
  2. // KMMainViewController.swift
  3. // PDF Reader Pro
  4. //
  5. // Created by wanjun on 2022/12/15.
  6. //
  7. import Cocoa
  8. import KMComponentLibrary
  9. @objcMembers class KMMainViewController: KMBaseViewController, NSTextFieldDelegate {
  10. @IBOutlet var contendBox: NSBox!
  11. @IBOutlet var toolbarBox: NSBox! //工具栏Box
  12. @IBOutlet var bottomContendBox: NSBox! //
  13. @IBOutlet var sidebarBox: NSBox! //左侧边栏Box
  14. @IBOutlet var infoContendSplitView: KMPDFSplitView!
  15. @IBOutlet var infoSplitLeftView: NSView!
  16. @IBOutlet var infoSplitRightView: NSView!
  17. @IBOutlet var infoSplitCenterView: NSView!
  18. @IBOutlet var pdfSplitView: NSSplitView!
  19. @IBOutlet var pdfSplitTopView: NSView!
  20. @IBOutlet var pdfSplitBottomView: NSView!
  21. @IBOutlet var toolbarBoxHeightConst: NSLayoutConstraint!
  22. @IBOutlet var infoSplitViewLeftConst: NSLayoutConstraint!
  23. var viewManager: KMPDFViewManager = KMPDFViewManager.init()
  24. var toolbarManager: KMPDFToolbarManager = KMPDFToolbarManager.init()
  25. var listView: CPDFListView = CPDFListView.init()
  26. var document: CPDFDocument?
  27. var myDocument: NSDocument?
  28. var insertDocuments: Set<CPDFDocument> = [] //插入新文档时,SDK会出现崩溃,临时记录
  29. //工具栏
  30. private var pdfToolbarController: KMPDFToolbarController?
  31. //BOTA SideBar
  32. private var sideBarController: KMPDFSideBarController?
  33. //页面编辑
  34. private var pageEditViewController: KMNPageEditViewController?
  35. //DisplaySetting
  36. private var displaySettingController: KMNDisplayViewController?
  37. //SPlitPDF分屏视图
  38. private var splitPDFController: KMSplitPDFViewController?
  39. private var pdfBottomToolbar: KMSplitToolbar?
  40. //PPT操作界面
  41. var presentationTopViewController: KMPresentationTopViewController?
  42. //水印
  43. var watermarkViewController: KMWatermarkController?
  44. var watermarkToolbarView: KMWatermarkToolbarView?
  45. //左边
  46. var botaViewController: KMNLeftSideViewController?
  47. //MARK: - 旧代码,有需要用到的拿出来,写好备注
  48. @IBOutlet var PDFContendView: NSView!
  49. @IBOutlet var centerContentView: NSView!
  50. @IBOutlet weak var readContentView: NSView!
  51. @IBOutlet weak var tipCurrentPageBox: KMBox!
  52. @IBOutlet weak var rightView: NSView!
  53. @IBOutlet weak var leftView: NSView!
  54. @IBOutlet weak var mianSplitView: KMSplitView!
  55. @IBOutlet weak var newPDFSplitView: KMSplitView!
  56. @IBOutlet weak var pdfContentView: NSView!
  57. @IBOutlet var childToolbarController: KMToolbarViewController!
  58. @IBOutlet var toolbarController: KMToolbarController!
  59. @IBOutlet weak var heightOffset: NSLayoutConstraint!
  60. //页码显示器
  61. @IBOutlet weak var pageNumberDisplayView: KMPageNumberDisplayView!
  62. var model = KMMainModel()
  63. //自动滚动
  64. var autoFlowOptionsSheetController: KMAutoFlowOptionsSheetController?
  65. //Search
  66. var searchIndex: Int = 0
  67. //Form
  68. var formAlertView: KMFormAlertView?
  69. //Secure
  70. var secureAlertView: KMSecureAlertView?
  71. //对比
  72. var isCompareModel: Bool = false {
  73. didSet {
  74. self.toolbarController.updataItemVisible()
  75. }
  76. }
  77. //合并
  78. var mergeWindowController: KMMergeWindowController?
  79. //水印
  80. var watermarkWindowController: KMWatermarkWindowController?
  81. //密码弹窗
  82. var passwordWindow: KMPasswordInputWindow?
  83. //对比
  84. var compressWIndowControllerNew: KMCompressWIndowControllerNew?
  85. //
  86. var securityWindowController: KMSecurityWindowController?
  87. //引导
  88. var guideInfoWindowController: KMGuideInfoWindowController?
  89. //春季活动
  90. var recommondPopWindowVC: KMRecommondPopWindow?
  91. var removeAllAnnotationsStore = KMPDFViewRemoveAllAnnotationsStore()
  92. private var _needSave = false
  93. var needSave: Bool {
  94. set {
  95. _needSave = newValue
  96. if (_needSave == false) {
  97. self.clearIsPDFDocumentEdited()
  98. }
  99. }
  100. get {
  101. return _needSave
  102. }
  103. }
  104. var isPDFDocumentEdited: Bool {
  105. get {
  106. return self.model.isPDFDocumentEdited
  107. }
  108. }
  109. var leftSideViewController: KMLeftSideViewController = KMLeftSideViewController.init(type: KMLeftMethodMode())
  110. var rightSideViewController: KMRightSideViewController!
  111. var searchResults: [KMSearchMode] = []
  112. var mwcFlags: MwcFlags = MwcFlags()
  113. weak var browserWindowController: KMBrowserWindowController? //慎直接使用这个方法
  114. var cropSettingWindowController: KMCropSettingWindowController!
  115. var currentWindowController: NSWindowController!
  116. var savedNormalSetup: NSMutableDictionary = NSMutableDictionary()
  117. //数字签名
  118. var digitalSignController: KMPDFDigitalSignViewController?
  119. var redactController: KMPDFRedactViewController!
  120. let CPDFOfficeLeftSidePaneWidthKey = "CPDFOfficeLeftSidePaneWidthKey"
  121. let CPDFOfficeRightSidePaneWidthKey = "CPDFOfficeRightSidePaneWidthKey"
  122. var extract: KMExtractImageWindowController?
  123. var functionWidth: Double {
  124. get {
  125. if self.viewManager.isPDFReadMode {
  126. if !self.model.isShowBOTA {
  127. return 0
  128. }
  129. }
  130. return 48-4
  131. }
  132. }
  133. var pageNumber: UInt?
  134. var secondaryPdfContentView: NSView?
  135. var lastSplitPDFHeight: Float = 0.0
  136. var pdfEditController: KMPDFEditViewController? {
  137. get {
  138. return self.getPDFEditController()
  139. }
  140. }
  141. var autoSaveTimer: Timer?
  142. private var _documentFirstLoad: Bool = true
  143. var eventMonitor: Any?
  144. var keyEventMonitor: Any?
  145. var mouseRightMenuEvent: NSEvent?
  146. lazy private var homeVC: KMNHomeViewController? = {
  147. let vc = KMNHomeViewController()
  148. return vc
  149. }()
  150. private var background_mask: NSView?
  151. fileprivate var _secureOptions: [CPDFDocumentWriteOption : Any]?
  152. var secureOptions: [CPDFDocumentWriteOption : Any]? {
  153. get {
  154. return self._secureOptions
  155. }
  156. }
  157. var documentAttribute: [CPDFDocumentAttribute : Any]?
  158. fileprivate var _removeSecureFlag = false
  159. var removeSecureFlag: Bool {
  160. get {
  161. return self._removeSecureFlag
  162. }
  163. }
  164. fileprivate var _saveWatermarkFlag = false
  165. var saveWatermarkFlag: Bool {
  166. get {
  167. return self._saveWatermarkFlag
  168. }
  169. }
  170. private var mainWindow_: NSWindow?
  171. var mainWindow: NSWindow? {
  172. get {
  173. return self.mainWindow_
  174. }
  175. set {
  176. self.mainWindow_ = newValue
  177. }
  178. }
  179. var setDocument: CPDFDocument? {
  180. get {
  181. return document
  182. }
  183. set {
  184. if document != newValue {
  185. document = newValue
  186. }
  187. listView.document = document
  188. botaViewController?.changeDocument(document: document)
  189. }
  190. }
  191. var setPageNumber: UInt {
  192. get {
  193. return pageNumber!
  194. }
  195. set {
  196. let pageCount = listView.document?.pageCount ?? 0
  197. var value = newValue
  198. if value > pageCount {
  199. value = pageCount
  200. }
  201. if value > 0 && listView.currentPage().pageIndex() != value-1 {
  202. listView.go(to: listView.document?.page(at: value-1))
  203. }
  204. if pageNumber != value {
  205. pageNumber = value
  206. }
  207. }
  208. }
  209. let editPDFHanddler = KMEditPDfHanddler()
  210. var distanceMeasureInfoWindowController: CDistanceMeasureInfoWindowController?
  211. var perimeterMeasureInfoWindowController: CPerimeterMeasureInfoWindowController?
  212. var areaMeasureInfoWindowController: CAreaMeasureInfoWindowController?
  213. var srHanddler: KMSearchReplaceHanddler = KMSearchReplaceHanddler()
  214. //MARK: - func
  215. deinit {
  216. NotificationCenter.default.removeObserver(self)
  217. self.listView.delegate = nil
  218. self.listView.document?.delegate = nil
  219. self.editPDFHanddler.clearData()
  220. self.removeEventMonitor()
  221. self.removeKeyEventMonitor()
  222. }
  223. override func viewDidLoad() {
  224. super.viewDidLoad()
  225. // Do view setup here.
  226. toolbarManager.pdfViewManager = viewManager
  227. }
  228. override func viewDidAppear() {
  229. super.viewDidAppear()
  230. setupUI()
  231. }
  232. func setupUI() {
  233. initPDFView()
  234. initToolbar()
  235. initSideBar()
  236. setUpSplitView()
  237. }
  238. private func documentLoadComplete() {
  239. initBotaView()
  240. }
  241. func leftSidePaneIsOpen() -> Bool {
  242. if(botaViewController != nil) {
  243. return infoContendSplitView.isSubviewCollapsed(botaViewController!.view)
  244. }
  245. return false
  246. }
  247. private func toggleOpenLeftSide(pdfSideBarType: KMPDFSidebarType) {
  248. if(leftSidePaneIsOpen() == false) {
  249. infoContendSplitView.setPosition(264, ofDividerAt: 0)
  250. }
  251. if pdfSideBarType == .search {
  252. KMPrint(" search")
  253. } else if pdfSideBarType == .thumbnail {
  254. botaViewController?.leftsideType = pdfSideBarType
  255. KMPrint(" thumbnail")
  256. } else if pdfSideBarType == .outline {
  257. KMPrint(" outline")
  258. } else if pdfSideBarType == .bookmark {
  259. KMPrint(" bookmark")
  260. } else if pdfSideBarType == .annotation {
  261. KMPrint(" annotation")
  262. }
  263. }
  264. private func toggleCloseLeftSide() {
  265. if(leftSidePaneIsOpen() == true) {
  266. infoContendSplitView.setPosition(-20, ofDividerAt: 0)
  267. }
  268. }
  269. //MARK: - PDFView
  270. func initPDFView() {
  271. listView.autoresizingMask = [.width, .height]
  272. listView.delegate = self
  273. listView.pdfListViewDelegate = self
  274. listView.document = self.document
  275. reloadPDFSplitInfo()
  276. }
  277. //MARK: - SplitView
  278. func setUpSplitView() {
  279. infoContendSplitView.wantsLayer = true
  280. infoContendSplitView.layer?.backgroundColor = NSColor.clear.cgColor
  281. infoContendSplitView.delegate = self
  282. infoContendSplitView.layer?.masksToBounds = true
  283. infoContendSplitView.setPosition(-10, ofDividerAt: 0)
  284. infoContendSplitView.setPosition(CGRectGetWidth(infoContendSplitView.frame), ofDividerAt: 1)
  285. }
  286. func setupSplitPDFController() {
  287. if splitPDFController == nil {
  288. splitPDFController = KMSplitPDFViewController.init()
  289. }
  290. splitPDFController?.view.frame = pdfSplitBottomView.bounds
  291. splitPDFController?.view.autoresizingMask = [.height, .width]
  292. splitPDFController?.viewManager = self.viewManager
  293. splitPDFController?.delegate = self
  294. splitPDFController?.reloadData()
  295. pdfSplitBottomView.addSubview(splitPDFController!.view)
  296. }
  297. //MARK: - 工具栏
  298. func initToolbar() {
  299. toolbarBox.borderWidth = 0
  300. if pdfToolbarController == nil {
  301. pdfToolbarController = KMPDFToolbarController.init()
  302. }
  303. pdfToolbarController?.view.frame = toolbarBox.bounds
  304. pdfToolbarController?.view.autoresizingMask = [.width, .height]
  305. pdfToolbarController?.delegate = self
  306. toolbarBox.contentView = pdfToolbarController?.view
  307. pdfToolbarController?.viewManager = viewManager
  308. pdfToolbarController?.toolbarManager = toolbarManager
  309. pdfToolbarController?.pdfView = listView
  310. pdfToolbarController?.setUpData()
  311. refreshToolbarView()
  312. }
  313. func refreshToolbarView() {
  314. let _manager = viewManager
  315. if _manager.isPageEditMode {
  316. toolbarBoxHeightConst.constant = 80
  317. } else if _manager.isWatermarkMode {
  318. toolbarBoxHeightConst.constant = 40
  319. } else if _manager.toolMode == .Markup ||
  320. _manager.toolMode == .Edit ||
  321. _manager.toolMode == .Form ||
  322. _manager.toolMode == .Fill ||
  323. _manager.toolMode == .Convert ||
  324. _manager.toolMode == .Protect ||
  325. _manager.toolMode == .Tools {
  326. toolbarBoxHeightConst.constant = 80
  327. } else {
  328. toolbarBoxHeightConst.constant = 40
  329. }
  330. }
  331. //MARK: - 侧边栏
  332. func initSideBar() {
  333. sidebarBox.borderWidth = 0
  334. if sideBarController == nil {
  335. sideBarController = KMPDFSideBarController.init()
  336. }
  337. sideBarController?.view.frame = sidebarBox.bounds
  338. sideBarController?.view.autoresizingMask = [.width, .height]
  339. sidebarBox.contentView = sideBarController?.view
  340. sideBarController?.pdfView = listView
  341. sideBarController?.delegate = self
  342. sideBarController?.pdfViewManager = viewManager
  343. sideBarController?.reloadData()
  344. }
  345. //MARK: - 侧边栏
  346. func initBotaView() {
  347. if botaViewController == nil {
  348. botaViewController = KMNLeftSideViewController(listView.document)
  349. }
  350. botaViewController?.leftSideViewDelegate = self
  351. botaViewController?.view.frame = infoSplitLeftView.bounds
  352. botaViewController?.view.autoresizingMask = [.width, .height]
  353. if botaViewController != nil {
  354. infoSplitLeftView?.addSubview(botaViewController!.view)
  355. }
  356. }
  357. //MARK: - PDFDisplayView
  358. func updatePDFDisplaySettingView() {
  359. if viewManager.showDisplayView {
  360. infoSplitViewLeftConst.constant = 264
  361. } else {
  362. infoSplitViewLeftConst.constant = 44
  363. }
  364. if viewManager.showDisplayView {
  365. if displaySettingController == nil {
  366. displaySettingController = KMNDisplayViewController.init()
  367. }
  368. displaySettingController?.view.frame = CGRectMake(0, 0, 264, CGRectGetHeight(bottomContendBox.frame))
  369. displaySettingController?.view.autoresizingMask = [.height, .maxXMargin]
  370. bottomContendBox.addSubview(displaySettingController!.view)
  371. displaySettingController?.pdfView = self.listView
  372. displaySettingController?.viewManager = self.viewManager
  373. displaySettingController?.delegate = self
  374. displaySettingController?.reloadData()
  375. } else {
  376. displaySettingController?.view.removeFromSuperview()
  377. displaySettingController = nil
  378. }
  379. }
  380. //MARK: - 页面编辑
  381. func enterPageEditMode() {
  382. pageEditViewController = KMNPageEditViewController(self.document)
  383. if(pageEditViewController != nil) {
  384. bottomContendBox.addSubview(pageEditViewController!.view)
  385. pageEditViewController?.view.frame = bottomContendBox.bounds
  386. pageEditViewController?.thumbnailBaseViewDelegate = self
  387. pageEditViewController?.selectionIndexPaths = [IndexPath(item: listView.currentPageIndex, section: 0)]
  388. pageEditViewController?.view.autoresizingMask = [.width,.height]
  389. }
  390. }
  391. func exitPageEditMode() {
  392. if pageEditViewController != nil {
  393. pageEditViewController?.view.removeFromSuperview()
  394. pageEditViewController = nil
  395. }
  396. }
  397. //MARK: - 阅读模式
  398. func openPDFReadMode() {
  399. if viewManager.showDisplayView {
  400. viewManager.showDisplayView = false
  401. pdfToolbarController?.reloadLeftIconView()
  402. updatePDFDisplaySettingView()
  403. }
  404. infoSplitViewLeftConst.constant = 0
  405. toolbarBoxHeightConst.constant = 0
  406. view.window?.makeFirstResponder(listView)
  407. }
  408. func exitPDFReadMode() {
  409. viewManager.isPDFReadMode = false
  410. updatePDFDisplaySettingView()
  411. refreshToolbarView()
  412. }
  413. //MARK: - PPT
  414. func togglePresentation(_ sender: Any?) {
  415. if self.canExitPresentation() {
  416. exitFullScreen()
  417. } else if self.canEnterPresentation() {
  418. NotificationCenter.default.addObserver(self, selector: #selector(willEnterInteractionModeNotification), name: NSWindow.willEnterInteractionModeNotification, object: nil)
  419. NotificationCenter.default.addObserver(self, selector: #selector(didEnterInteractionModeNotification), name: NSWindow.didEnterInteractionModeNotification, object: nil)
  420. NotificationCenter.default.addObserver(self, selector: #selector(willShowFullScreenNotification), name: NSWindow.willShowFullScreenNotification, object: nil)
  421. NotificationCenter.default.addObserver(self, selector: #selector(didShowFullScreenNotification), name: NSWindow.didShowFullScreenNotification, object: nil)
  422. view.window?.enterPresentation(provider: self)
  423. }
  424. }
  425. func enterPresentationMode() {
  426. let scrollView = listView.documentView().enclosingScrollView
  427. savedNormalSetup.setValue(scrollView?.hasHorizontalScroller, forKey: KMMainModel.Key.kHasHorizontalScroller)
  428. savedNormalSetup.setValue(scrollView?.hasVerticalScroller, forKey: KMMainModel.Key.kHasVerticalsCroller)
  429. savedNormalSetup.setValue(scrollView?.autohidesScrollers, forKey: KMMainModel.Key.kAutoHidesScrollers)
  430. listView.backgroundColor = NSColor.clear
  431. listView.setDisplay(.singlePage)
  432. listView.autoScales = true
  433. listView.displayBox = .cropBox
  434. listView.displaysPageBreaks = false
  435. scrollView?.autohidesScrollers = true
  436. scrollView?.hasHorizontalScroller = false
  437. scrollView?.hasVerticalScroller = false
  438. listView.setCurrentSelection(nil, animate: true)
  439. }
  440. func exitPresentationMode() {
  441. NotificationCenter.default.removeObserver(self, name: NSWindow.willEnterInteractionModeNotification, object: nil)
  442. NotificationCenter.default.removeObserver(self, name: NSWindow.didEnterInteractionModeNotification, object: nil)
  443. NotificationCenter.default.removeObserver(self, name: NSWindow.willShowFullScreenNotification, object: nil)
  444. NotificationCenter.default.removeObserver(self, name: NSWindow.willShowFullScreenNotification, object: nil)
  445. }
  446. func exitFullScreen() {
  447. if self.canExitPresentation() == true {
  448. let mainDocument = self.myDocument as? KMMainDocument
  449. let browserWindowController = mainDocument?.browser?.windowController as? KMBrowserWindowController
  450. browserWindowController?.exitFullscreen()
  451. }
  452. }
  453. func exitFullscreenMode() {
  454. if self.interactionMode == .presentation {
  455. self.exitPresentationMode()
  456. }
  457. self.applyPDFSettings(self.savedNormalSetup)
  458. self.savedNormalSetup.removeAllObjects()
  459. listView.layoutDocumentView()
  460. listView.requiresDisplay()
  461. if let backgroundColor = UserDefaults.standard.color(forKey: KMBackgroundColorKey) {
  462. listView.backgroundColor = backgroundColor
  463. }
  464. }
  465. func applyPDFSettings(_ setup: NSDictionary) {
  466. if let data = setup.object(forKey: KMMainModel.Key.kAutoScales) as? NSNumber {
  467. self.listView.autoScales = data.boolValue
  468. }
  469. if self.listView.autoScales == false {
  470. if let data = setup.object(forKey: KMMainModel.Key.kScaleFactor) as? NSNumber {
  471. self.listView.scaleFactor = data.floatValue.cgFloat
  472. }
  473. }
  474. if let data = setup.object(forKey: KMMainModel.Key.kDisplayMode) as? NSNumber {
  475. self.listView.setDisplay(CPDFDisplayViewMode(rawValue: data.intValue) ?? .singlePage)
  476. }
  477. if let data = setup.object(forKey: KMMainModel.Key.kDisplaysAsBook) as? NSNumber {
  478. self.listView.displaysAsBook = data.boolValue
  479. }
  480. if let data = setup.object(forKey: KMMainModel.Key.kDisplaysPageBreaks) as? NSNumber {
  481. self.listView.displaysPageBreaks = data.boolValue
  482. }
  483. if let data = setup.object(forKey: KMMainModel.Key.kDisplayBox) as? NSNumber {
  484. }
  485. self.listView.layoutDocumentView()
  486. }
  487. func currentPDFSettings() -> NSDictionary {
  488. let setup = NSMutableDictionary()
  489. setup[KMMainModel.Key.kDisplaysPageBreaks] = NSNumber(value: listView.displaysPageBreaks)
  490. setup[KMMainModel.Key.kDisplaysAsBook] = NSNumber(value: listView.displaysAsBook)
  491. setup[KMMainModel.Key.kDisplayBox] = NSNumber(value: listView.displayBox.rawValue)
  492. setup[KMMainModel.Key.kScaleFactor] = NSNumber(value: listView.scaleFactor)
  493. setup[KMMainModel.Key.kAutoScales] = NSNumber(value: listView.autoScales)
  494. setup[KMMainModel.Key.kDisplayMode] = NSNumber(value: listView.fetchDisplayViewMode().rawValue)
  495. return setup
  496. }
  497. func canEnterFullscreen() -> Bool {
  498. if (mwcFlags.isSwitchingFullScreen != 0) {
  499. return false
  500. }
  501. if useNativeFullScreen() {
  502. return interactionMode == .normal || interactionMode == .presentation
  503. } else {
  504. return !self.listView.document.isLocked && (interactionMode == .normal || interactionMode == .presentation) && self.view.window?.tabbedWindows?.count ?? 0 < 2
  505. }
  506. }
  507. override func canEnterPresentation() -> Bool {
  508. let can = super.canEnterPresentation()
  509. if can == false {
  510. return false
  511. }
  512. guard let doc = self.listView.document, doc.isLocked == false else {
  513. return false
  514. }
  515. return can
  516. }
  517. func fadeOutFullScreenWindow() {
  518. guard let fullScreenWindow = self.view.window as? KMFullScreenWindow else {
  519. NSSound.beep()
  520. return
  521. }
  522. let mainWindow = fullScreenWindow.interactionParent
  523. let collectionBehavior = mainWindow?.collectionBehavior
  524. mainWindow?.alphaValue = 0
  525. if let data = mainWindow?.responds(to: NSSelectorFromString("setAnimationBehavior:")), data {
  526. mainWindow?.animationBehavior = .none
  527. }
  528. // trick to make sure the main window shows up in the same space as the fullscreen window
  529. fullScreenWindow.addChildWindow(mainWindow!, ordered: .below)
  530. fullScreenWindow.removeChildWindow(mainWindow!)
  531. fullScreenWindow.level = .popUpMenu
  532. // these can change due to the child window trick
  533. mainWindow?.level = .normal
  534. mainWindow?.alphaValue = 1.0
  535. mainWindow?.collectionBehavior = collectionBehavior!
  536. mainWindow?.display()
  537. mainWindow?.makeFirstResponder(self.listView)
  538. mainWindow?.recalculateKeyViewLoop()
  539. // mainWindow?.delegate = self
  540. mainWindow?.makeKey()
  541. if let data = mainWindow?.responds(to: NSSelectorFromString("setAnimationBehavior:")), data {
  542. mainWindow?.animationBehavior = .default
  543. }
  544. NSApp.removeWindowsItem(fullScreenWindow)
  545. fullScreenWindow.fadeOut()
  546. }
  547. //MARK: - PDF分屏视图
  548. func reloadPDFSplitInfo() {
  549. if listView.viewSplitMode == .disable {
  550. pdfSplitView.isHidden = true
  551. listView.frame = infoSplitCenterView.bounds
  552. infoSplitCenterView.addSubview(listView)
  553. if splitPDFController != nil {
  554. splitPDFController = nil
  555. }
  556. } else {
  557. pdfSplitView.isHidden = false
  558. listView.frame = pdfSplitTopView.bounds
  559. pdfSplitTopView.addSubview(listView)
  560. setUpPDFBottomToolbar()
  561. setupSplitPDFController()
  562. if listView.viewSplitMode == .horizontal {
  563. pdfSplitView.isVertical = true
  564. } else if listView.viewSplitMode == .vertical {
  565. pdfSplitView.isVertical = false
  566. }
  567. }
  568. }
  569. func setUpPDFBottomToolbar() {
  570. if pdfBottomToolbar != nil {
  571. pdfBottomToolbar = nil
  572. }
  573. pdfBottomToolbar = KMSplitToolbar.init()
  574. pdfBottomToolbar?.frame = CGRectMake(CGRectGetWidth(pdfSplitTopView.frame)/2-144, 20, 288, 40)
  575. pdfBottomToolbar?.pdfView = self.listView
  576. pdfBottomToolbar?.reloadData()
  577. pdfSplitTopView.addSubview(pdfBottomToolbar!)
  578. }
  579. func reloadPDFBottomToolbar() {
  580. if viewManager.splitShowBottomBar {
  581. pdfBottomToolbar?.isHidden = false
  582. pdfBottomToolbar?.reloadData()
  583. } else {
  584. pdfBottomToolbar?.isHidden = true
  585. }
  586. }
  587. //MARK: - Watermark水印
  588. func showWatermarkController() {
  589. listView.isHidden = true
  590. viewManager.isWatermarkMode = true
  591. if watermarkToolbarView == nil {
  592. watermarkToolbarView = KMWatermarkToolbarView()
  593. }
  594. watermarkToolbarView?.frame = toolbarBox.bounds
  595. if KMWatermarkManager.defaultManager.watermarks.count == 0 {
  596. watermarkToolbarView?.watermarkMode = .AddWatermark
  597. } else {
  598. watermarkToolbarView?.watermarkMode = .Template
  599. }
  600. watermarkToolbarView?.delegate = self
  601. watermarkToolbarView?.autoresizingMask = [.width, .height]
  602. toolbarBox.contentView = watermarkToolbarView
  603. if watermarkViewController == nil {
  604. watermarkViewController = KMWatermarkController.init()
  605. }
  606. watermarkViewController?.view.frame = CGRectMake(44, 0, CGRectGetWidth(bottomContendBox.frame)-44, CGRectGetHeight(bottomContendBox.frame))
  607. watermarkViewController?.view.autoresizingMask = [.maxXMargin, .width, .height]
  608. watermarkViewController?.delegate = self
  609. bottomContendBox.addSubview(watermarkViewController!.view)
  610. watermarkViewController?.watermarkMode = watermarkToolbarView?.watermarkMode ?? .Template
  611. updateWatermarkDocument()
  612. }
  613. func updateWatermarkDocument() {
  614. guard let controller = watermarkViewController else { return }
  615. let document = CPDFDocument.init()
  616. let page = listView.document.page(at: UInt(listView.currentPageIndex))
  617. document?.insertPageObject(page, at: 0)
  618. watermarkViewController?.pdfDocument = document
  619. watermarkViewController?.reloadData()
  620. }
  621. func exitWatermarkController() {
  622. listView.isHidden = false
  623. viewManager.isWatermarkMode = false
  624. watermarkToolbarView?.removeFromSuperview()
  625. watermarkToolbarView = nil
  626. watermarkViewController?.view.removeFromSuperview()
  627. watermarkViewController = nil
  628. refreshToolbarView()
  629. toolbarBox.contentView = pdfToolbarController?.view
  630. }
  631. //移除文档水印
  632. func removePDFWatermark() {
  633. let watermarks = self.listView.document.watermarks()
  634. if (watermarks == nil || watermarks!.count <= 0) {
  635. let alert = NSAlert()
  636. alert.alertStyle = .warning
  637. alert.messageText = NSLocalizedString("Could not find a removable watermark in this document. If you see a watermark, it was not added with PDF Reader Pro and therefore cannot be detected.", comment: "")
  638. alert.addButton(withTitle: NSLocalizedString("Confirm", comment: ""))
  639. alert.runModal()
  640. return
  641. }
  642. let alert = NSAlert()
  643. alert.alertStyle = .warning
  644. alert.messageText = NSLocalizedString("Are you sure you want to remove the watermark?", comment: "")
  645. alert.addButton(withTitle: NSLocalizedString("Delete", comment: ""))
  646. alert.addButton(withTitle: NSLocalizedString("Cancel", comment: ""))
  647. let result = alert.runModal()
  648. if (result == .alertFirstButtonReturn) {
  649. for watermark in watermarks! {
  650. listView.document.removeWatermark(watermark)
  651. }
  652. listView.layoutDocumentView()
  653. }
  654. }
  655. func batchAddWatermark() {
  656. }
  657. func batchRemoveWatermark() {
  658. }
  659. }
  660. //MARK: - NSSplitViewDelegate
  661. extension KMMainViewController: NSSplitViewDelegate {
  662. func splitView(_ splitView: NSSplitView, shouldHideDividerAt dividerIndex: Int) -> Bool {
  663. return true
  664. }
  665. func splitView(_ splitView: NSSplitView, canCollapseSubview subview: NSView) -> Bool {
  666. return true
  667. }
  668. func splitView(_ splitView: NSSplitView, constrainMaxCoordinate proposedMaximumPosition: CGFloat, ofSubviewAt dividerIndex: Int) -> CGFloat {
  669. return proposedMaximumPosition
  670. }
  671. func splitView(_ splitView: NSSplitView, constrainMinCoordinate proposedMinimumPosition: CGFloat, ofSubviewAt dividerIndex: Int) -> CGFloat {
  672. return proposedMinimumPosition
  673. }
  674. func splitView(_ splitView: NSSplitView, constrainSplitPosition proposedPosition: CGFloat, ofSubviewAt dividerIndex: Int) -> CGFloat {
  675. if dividerIndex == 0 {
  676. if proposedPosition > CGRectGetWidth(infoContendSplitView.frame)/2 - 10 {
  677. print(CGRectGetWidth(infoContendSplitView.frame)/2 - 10, NSDate())
  678. return CGRectGetWidth(infoContendSplitView.frame)/2 - 10
  679. }
  680. } else if dividerIndex == 1 {
  681. print(CGRectGetWidth(infoContendSplitView.frame)/2 - 10, NSDate())
  682. }
  683. return proposedPosition
  684. }
  685. func splitViewDidResizeSubviews(_ notification: Notification) {
  686. let splitView = notification.object as? NSSplitView
  687. if((splitView?.isEqual(to: infoContendSplitView)) == true) {
  688. leftSplitViewResizeFinish()
  689. }
  690. NSObject.cancelPreviousPerformRequests(withTarget: self, selector: #selector(splitViewResizeFinish), object: nil)
  691. self.perform(#selector(splitViewResizeFinish), with: nil, afterDelay: 0.15)
  692. }
  693. @objc func leftSplitViewResizeFinish() {
  694. botaViewController?.changeLeftSideBounds()
  695. }
  696. @objc func splitViewResizeFinish() {
  697. if infoContendSplitView.isSubviewCollapsed(infoSplitLeftView) {
  698. if viewManager.pdfSideBarType != .none {
  699. viewManager.pdfSideBarType = .none
  700. sideBarController?.reloadBOTAData()
  701. }
  702. }
  703. }
  704. }
  705. //MARK: - KMPDFSideBarControllerDelegate 左侧Sidebar代理
  706. extension KMMainViewController: KMPDFSideBarControllerDelegate {
  707. func kmPDFSideBarControllerDidSidebarTypeUpdated(_ view: KMPDFSideBarController) {
  708. if viewManager.pdfSideBarType == .none {
  709. toggleCloseLeftSide()
  710. } else {
  711. toggleOpenLeftSide(pdfSideBarType: viewManager.pdfSideBarType)
  712. }
  713. }
  714. func kmPDFSideBarControllerDidGotoPage(_ view: KMPDFSideBarController, _ pageIndex: Int) {
  715. listView.go(toPageIndex: pageIndex, animated: true)
  716. }
  717. }
  718. //MARK: - KMPDFToolbarControllerDelegate 工具栏代理
  719. extension KMMainViewController: KMPDFToolbarControllerDelegate {
  720. func kmPDFToolbarControllerDidToolbarItemClicked(_ controller: KMPDFToolbarController, _ itemIdentifier: String) {
  721. print("toolbar点击", itemIdentifier)
  722. if itemIdentifier == KMPDFToolbar_ViewDisplay_Identifier {
  723. updatePDFDisplaySettingView()
  724. } else if itemIdentifier == KMPDFToolbar_PageEdit_Identifier {
  725. if viewManager.isPageEditMode == true {
  726. enterPageEditMode()
  727. } else {
  728. exitPageEditMode()
  729. }
  730. } else if itemIdentifier == KMPDFToolbar_convert_word_Identifier {
  731. let winC = KMConvertWordWindowController()
  732. let model = KMDocumentModel(url: listView.document.documentURL)
  733. winC.documentModel = model
  734. winC.own_beginSheetModal(for: self.view.window, completionHandler: nil)
  735. } else if itemIdentifier == KMPDFToolbar_convert_ppt_Identifier {
  736. let winC = KMConvertPPTsWindowController()
  737. winC.subType = 1
  738. let model = KMDocumentModel(url: listView.document.documentURL)
  739. winC.documentModel = model
  740. winC.own_beginSheetModal(for: self.view.window, completionHandler: nil)
  741. } else if itemIdentifier == KMPDFToolbar_convert_RTF_Identifier {
  742. let winC = KMConvertPPTsWindowController()
  743. winC.subType = 2
  744. let model = KMDocumentModel(url: listView.document.documentURL)
  745. winC.documentModel = model
  746. winC.own_beginSheetModal(for: self.view.window, completionHandler: nil)
  747. } else if itemIdentifier == KMPDFToolbar_convert_Text_Identifier {
  748. let winC = KMConvertPPTsWindowController()
  749. winC.subType = 4
  750. let model = KMDocumentModel(url: listView.document.documentURL)
  751. winC.documentModel = model
  752. winC.own_beginSheetModal(for: self.view.window, completionHandler: nil)
  753. } else if itemIdentifier == KMPDFToolbar_convert_CSV_Identifier {
  754. let winC = KMConvertPPTsWindowController()
  755. winC.subType = 5
  756. let model = KMDocumentModel(url: listView.document.documentURL)
  757. winC.documentModel = model
  758. winC.own_beginSheetModal(for: self.view.window, completionHandler: nil)
  759. } else if itemIdentifier == KMPDFToolbar_convert_excel_Identifier {
  760. let winC = KMConvertExcelWindowController()
  761. let model = KMDocumentModel(url: listView.document.documentURL)
  762. winC.documentModel = model
  763. winC.own_beginSheetModal(for: self.view.window, completionHandler: nil)
  764. } else if itemIdentifier == KMPDFToolbar_convert_HTML_Identifier {
  765. let winC = KMConvertHtmlWindowController()
  766. let model = KMDocumentModel(url: listView.document.documentURL)
  767. winC.documentModel = model
  768. winC.own_beginSheetModal(for: self.view.window, completionHandler: nil)
  769. } else if itemIdentifier == KMPDFToolbar_convert_Json_Identifier {
  770. let winC = KMConvertJsonWindowController()
  771. let model = KMDocumentModel(url: listView.document.documentURL)
  772. winC.documentModel = model
  773. winC.own_beginSheetModal(for: view.window, completionHandler: nil)
  774. } else if itemIdentifier == KMPDFToolbar_convert_image_Identifier {
  775. let winC = KMConvertImageWindowController()
  776. let model = KMDocumentModel(url: listView.document.documentURL)
  777. winC.documentModel = model
  778. winC.own_beginSheetModal(for: view.window, completionHandler: nil)
  779. } else if itemIdentifier == KMPDFToolbar_convert_imageToPDF_Identifier {
  780. NSApplication.ShowImageToPDFWindow()
  781. } else if itemIdentifier == KMPDFToolbar_PageEdit_InsertFile_Identifier {
  782. pageEditViewController?.insertFromPDFAction()
  783. } else if itemIdentifier == KMPDFToolbar_PageEdit_InsertBlank_Identifier {
  784. pageEditViewController?.insertFromBlankAction()
  785. } else if itemIdentifier == KMPDFToolbar_PageEdit_InsertClip_Identifier {
  786. pageEditViewController?.insertFromClipboardAction()
  787. } else if itemIdentifier == KMPDFToolbar_PageEdit_InsertScanner_Identifier {
  788. pageEditViewController?.insertFromScannerAction()
  789. } else if itemIdentifier == KMPDFToolbar_PageEdit_Extract_Identifier {
  790. pageEditViewController?.extractPDFAction()
  791. } else if itemIdentifier == KMPDFToolbar_PageEdit_Replace_Identifier {
  792. pageEditViewController?.replacePDFAction()
  793. } else if itemIdentifier == KMPDFToolbar_PageEdit_Split_Identifier {
  794. pageEditViewController?.splitPDFAction()
  795. } else if itemIdentifier == KMPDFToolbar_PageEdit_Reverse_Identifier {
  796. pageEditViewController?.reversePDFAction()
  797. } else if itemIdentifier == KMPDFToolbar_PageEdit_LeftRotate_Identifier {
  798. pageEditViewController?.rotatePageLeftAction()
  799. } else if itemIdentifier == KMPDFToolbar_PageEdit_RightRotate_Identifier{
  800. pageEditViewController?.rotatePageRightAction()
  801. } else if itemIdentifier == KMPDFToolbar_PageEdit_Delete_Identifier {
  802. pageEditViewController?.deletePageAction()
  803. } else if itemIdentifier == KMPDFToolbar_PageEdit_Reduce_Identifier {
  804. pageEditViewController?.zoomOutPageAction()
  805. if(pageEditViewController?.canZoomInPageSize() == false) {
  806. toolbarManager.page_Increase_Property.isDisabled = true
  807. } else {
  808. toolbarManager.page_Increase_Property.isDisabled = false
  809. }
  810. if(pageEditViewController?.canZoomOutPageSize() == false) {
  811. toolbarManager.page_Reduce_Property.isDisabled = true
  812. } else {
  813. toolbarManager.page_Reduce_Property.isDisabled = false
  814. }
  815. controller.refreshSecondToolbarItemsState()
  816. } else if itemIdentifier == KMPDFToolbar_PageEdit_Increase_Identifier {
  817. pageEditViewController?.zoomInPageAction()
  818. if(pageEditViewController?.canZoomInPageSize() == false) {
  819. toolbarManager.page_Increase_Property.isDisabled = true
  820. } else {
  821. toolbarManager.page_Increase_Property.isDisabled = false
  822. }
  823. if(pageEditViewController?.canZoomOutPageSize() == false) {
  824. toolbarManager.page_Reduce_Property.isDisabled = true
  825. } else {
  826. toolbarManager.page_Reduce_Property.isDisabled = false
  827. }
  828. controller.refreshSecondToolbarItemsState()
  829. } else if itemIdentifier == KMPDFToolbar_PageEdit_page_oddPage_Identifier {
  830. pageEditViewController?.thumbnailChoosePageStyle = .odd
  831. if(toolbarManager.page_pageInfo_Property.creatable == true) {
  832. toolbarManager.page_pageInfo_Property.creatable = false
  833. controller.refreshSecondToolbarItemsState()
  834. }
  835. } else if itemIdentifier == KMPDFToolbar_PageEdit_page_EvenPage_Identifier {
  836. pageEditViewController?.thumbnailChoosePageStyle = .even
  837. if(toolbarManager.page_pageInfo_Property.creatable == true) {
  838. toolbarManager.page_pageInfo_Property.creatable = false
  839. controller.refreshSecondToolbarItemsState()
  840. }
  841. } else if itemIdentifier == KMPDFToolbar_PageEdit_page_PortraitPage_Identifier {
  842. pageEditViewController?.thumbnailChoosePageStyle = .horizontal
  843. if(toolbarManager.page_pageInfo_Property.creatable == true) {
  844. toolbarManager.page_pageInfo_Property.creatable = false
  845. controller.refreshSecondToolbarItemsState()
  846. }
  847. } else if itemIdentifier == KMPDFToolbar_PageEdit_page_LandscapePage_Identifier {
  848. pageEditViewController?.thumbnailChoosePageStyle = .vertical
  849. if(toolbarManager.page_pageInfo_Property.creatable == true) {
  850. toolbarManager.page_pageInfo_Property.creatable = false
  851. controller.refreshSecondToolbarItemsState()
  852. }
  853. } else if itemIdentifier == KMPDFToolbar_PageEdit_page_AllPage_Identifier {
  854. pageEditViewController?.thumbnailChoosePageStyle = .allPage
  855. if(toolbarManager.page_pageInfo_Property.creatable == true) {
  856. toolbarManager.page_pageInfo_Property.creatable = false
  857. controller.refreshSecondToolbarItemsState()
  858. }
  859. } else if itemIdentifier == KMPDFToolbar_PageEdit_page_CustomPage_Identifier {
  860. pageEditViewController?.thumbnailChoosePageStyle = .custom
  861. toolbarManager.page_pageInfo_Property.text = nil
  862. if(toolbarManager.page_pageInfo_Property.creatable == false) {
  863. toolbarManager.page_pageInfo_Property.creatable = true
  864. }
  865. controller.refreshSecondToolbarItemsState()
  866. } else if itemIdentifier == KMPDFToolbar_edit_addWatermark_Identifier {
  867. showWatermarkController()
  868. } else if itemIdentifier == KMPDFToolbar_edit_removeWatermark_Identifier {
  869. removePDFWatermark()
  870. } else if itemIdentifier == KMPDFToolbar_edit_batch_AddWatermark_Identifier {
  871. batchAddWatermark()
  872. } else if itemIdentifier == KMPDFToolbar_edit_batchRemoveWatermark_Identifier {
  873. batchRemoveWatermark()
  874. } else {
  875. print("click else")
  876. }
  877. refreshToolbarView()
  878. }
  879. func kmPDFToolbarControllerDidSelectTextDidBeginEditing(_ controller: KMPDFToolbarController, _ view: ComponentSelect) {
  880. }
  881. func kmPDFToolbarControllerDidSelectTextDidChange(_ controller: KMPDFToolbarController, _ view: ComponentSelect) {
  882. }
  883. func kmPDFToolbarControllerDidSelectTextDidEndEditing(_ controller: KMPDFToolbarController, _ view: ComponentSelect) {
  884. }
  885. }
  886. //MARK: - KMNDisplayViewControllerDelegate代理
  887. extension KMMainViewController: KMNDisplayViewControllerDelegate {
  888. //Display Mode
  889. func displayViewControllerDidDisplayModeChanged(_ controller: KMNDisplayViewController) {
  890. listView.layoutDocumentView()
  891. }
  892. //阅读模式
  893. func displayViewControllerDidReadModeUpdated(_ controller: KMNDisplayViewController) {
  894. if viewManager.isPDFReadMode {
  895. openPDFReadMode()
  896. } else {
  897. exitPDFReadMode()
  898. }
  899. }
  900. //PPT
  901. func displayViewControllerDidGotoSlideShow(_ controller: KMNDisplayViewController) {
  902. togglePresentation(nil)
  903. }
  904. //SplitView
  905. func displayViewControllerDidSplitModeChanged(_ controller: KMNDisplayViewController) {
  906. reloadPDFSplitInfo()
  907. }
  908. func displayViewControllerDidSplitFileChanged(_ controller: KMNDisplayViewController) {
  909. splitPDFController?.reloadData()
  910. }
  911. func displayViewControllerDidToolbarStateChanged(_ controller: KMNDisplayViewController) {
  912. splitPDFController?.refreshToolbarState()
  913. reloadPDFBottomToolbar()
  914. }
  915. }
  916. //MARK: - PPT
  917. extension KMMainViewController: KMInteractionProviderProtocol {
  918. func providerContentView(fullScreenWindow: NSWindow, inset: CGFloat) -> NSView? {
  919. if(interactionMode == .presentation) {
  920. if listView.presentationDrawView == nil {
  921. listView.createPresentationDraw()
  922. }
  923. presentationTopViewController = KMPresentationTopViewController.init(nibName: "KMPresentationTopViewController", bundle: nil)
  924. presentationTopViewController?.pdfView = listView
  925. presentationTopViewController?.delegate = self
  926. presentationTopViewController?.isSelectionPre = true
  927. listView.isPresentationMode = true
  928. presentationTopViewController?.view.frame = CGRect(x: 0, y: (fullScreenWindow.contentView?.bounds.height ?? 0) - 42, width: fullScreenWindow.contentView?.bounds.width ?? 0, height: 42)
  929. if((presentationTopViewController) != nil) {
  930. fullScreenWindow.contentView?.addSubview(presentationTopViewController!.view)
  931. }
  932. } else {
  933. listView.frame = NSInsetRect(fullScreenWindow.contentView?.bounds ?? .zero, 0, 0)
  934. }
  935. fullScreenWindow.contentView?.addSubview(listView)
  936. if(interactionMode == .presentation) {
  937. let frame = fullScreenWindow.frame
  938. listView.frame = CGRectMake(0, 0, frame.size.width, frame.size.height-42)
  939. listView.autoresizingMask = [.width, .maxYMargin]
  940. }
  941. return view
  942. }
  943. @objc func willEnterInteractionModeNotification(_ sender: Notification) {
  944. guard let win = sender.object as? NSWindow, win.isEqual(to: self.view.window) else {
  945. return
  946. }
  947. let interactionMode = sender.userInfo?[NSWindow.UserInfo.interactionModeKey] as? KMInteractionMode
  948. if interactionMode == .presentation {
  949. let backgroundColor = NSColor.black
  950. let level = UserDefaults.standard.bool(forKey: "SKUseNormalLevelForPresentationKey") ? NSWindow.Level.normal : NSWindow.Level.popUpMenu
  951. let wasInteractionMode = self.interactionMode
  952. if wasInteractionMode == .normal {
  953. self.savedNormalSetup.setDictionary(self.currentPDFSettings() as! [AnyHashable : Any])
  954. }
  955. if wasInteractionMode == .legacyFullScreen {
  956. self.enterPresentationMode()
  957. self.pdfSplitView.frame = CGRect(x: 0, y: 0, width: NSWidth(centerContentView.bounds), height: NSHeight(centerContentView.bounds)-1)
  958. self.centerContentView.addSubview(pdfSplitView)
  959. self.listView.frame = (self.view.window?.contentView?.bounds)!
  960. self.view.window?.contentView?.addSubview(listView)
  961. // self.view.window?.backgroundColor = backgroundColor
  962. self.view.window?.level = level
  963. self.listView.layoutDocumentView()
  964. self.listView.requiresDisplay()
  965. self.forceSubwindowsOnTop(false)
  966. }
  967. } else {
  968. KMPrint("2")
  969. }
  970. }
  971. @objc func didEnterInteractionModeNotification(_ sender: Notification) {
  972. guard let win = sender.object as? NSWindow, win.isEqual(to: self.view.window) else {
  973. return
  974. }
  975. if self.interactionMode == .presentation {
  976. self.listView.layoutDocumentView()
  977. self.listView.requiresDisplay()
  978. }
  979. }
  980. @objc func willShowFullScreenNotification(_ sender: Notification) {
  981. guard let win = sender.object as? NSWindow, win.isEqual(to: self.view.window) else {
  982. return
  983. }
  984. if self.interactionMode == .presentation {
  985. let view = self.view.window?.firstResponder as? NSView
  986. if let data = view?.isDescendant(of: self.pdfSplitView), data {
  987. self.view.window?.makeFirstResponder(nil)
  988. }
  989. }
  990. }
  991. @objc func didShowFullScreenNotification(_ sender: Notification) {
  992. guard let win = sender.object as? NSWindow, win.isEqual(to: self.view.window) else {
  993. return
  994. }
  995. if self.interactionMode == .presentation {
  996. self.enterPresentationMode()
  997. }
  998. }
  999. }
  1000. // MARK: -KMPresentationTopViewControllerDelegate (幻灯片)
  1001. extension KMMainViewController: KMPresentationTopViewControllerDelegate {
  1002. func presentationTopViewExit(_ presentationTopViewController: KMPresentationTopViewController, withButton: NSButton) {
  1003. self.exitFullScreen()
  1004. }
  1005. func presentationTopViewClear(_ presentationTopViewController: KMPresentationTopViewController, withButton: NSButton) {
  1006. listView.presentationDrawView?.clear()
  1007. }
  1008. func presentationTopViewUndo(_ presentationTopViewController: KMPresentationTopViewController, withButton: NSButton) {
  1009. let presentationDrawView = listView.presentationDrawView
  1010. if presentationDrawView?.canUndo() == true {
  1011. presentationDrawView?.undo()
  1012. }
  1013. }
  1014. func presentationTopViewType(_ presentationTopViewController: KMPresentationTopViewController, withButton: NSButton, isSeletion: Bool) {
  1015. listView.isPresentationMode = isSeletion
  1016. if listView.isEnterPresentationDrawMode() == true {
  1017. listView.exitPresentationDrawMode()
  1018. }
  1019. }
  1020. func presentationTopViewDrawColor(_ presentationTopViewController: KMPresentationTopViewController, withView: NSView,color:NSColor?) {
  1021. if color == nil{
  1022. listView.exitPresentationDrawMode()
  1023. } else {
  1024. if listView.isEnterPresentationDrawMode() == false {
  1025. listView.enterPresentationDrawMode()
  1026. }
  1027. listView.changePresentationDrawModelColor(color)
  1028. }
  1029. }
  1030. }
  1031. //MARK: - KMSplitPDFViewControllerDelegate SplitPDFView分屏视图
  1032. extension KMMainViewController: KMSplitPDFViewControllerDelegate {
  1033. func splitPDFViewControllerDidUpdateFilePath(_ controller: KMSplitPDFViewController) {
  1034. displaySettingController?.reloadData()
  1035. }
  1036. func splitPDFViewControllerDidUpdatePDFScale(_ controller: KMSplitPDFViewController) {
  1037. if let scaleFactor = controller.pdfView?.scaleFactor {
  1038. listView.scaleFactor = scaleFactor
  1039. }
  1040. }
  1041. func splitPDFViewControllerDidUpdatePDFPageIndex(_ controller: KMSplitPDFViewController) {
  1042. if let pageIndex = controller.pdfView?.currentPageIndex {
  1043. listView.go(toPageIndex: pageIndex, animated: false)
  1044. }
  1045. }
  1046. }
  1047. //MARK: - KMWatermarkToolbarViewDelegate 水印相关代理
  1048. extension KMMainViewController: KMWatermarkControllerDelegate {
  1049. func kmWatermarkControllerDidUpdateMode(_ view: KMWatermarkController) {
  1050. watermarkToolbarView?.watermarkMode = view.watermarkMode
  1051. }
  1052. func kmWatermarkControllerDidWatermarkUpdated(_ view: KMWatermarkController) {
  1053. if view.currentWatermark != nil {
  1054. watermarkToolbarView?.applyEnable = true
  1055. } else {
  1056. watermarkToolbarView?.applyEnable = false
  1057. }
  1058. watermarkToolbarView?.reloadData()
  1059. }
  1060. }
  1061. extension KMMainViewController: KMWatermarkToolbarViewDelegate {
  1062. func kmWatermarkToolbarViewDidUpdateMode(_ view: KMWatermarkToolbarView) {
  1063. watermarkViewController?.watermarkMode = watermarkToolbarView?.watermarkMode ?? .Template
  1064. }
  1065. func kmWatermarkToolbarViewDidChooseBatch(_ view: KMWatermarkToolbarView) {
  1066. }
  1067. func kmWatermarkToolbarViewDidChooseApply(_ view: KMWatermarkToolbarView) {
  1068. }
  1069. func kmWatermarkToolbarViewDidChooseExit(_ view: KMWatermarkToolbarView) {
  1070. exitWatermarkController()
  1071. }
  1072. }
  1073. //MARK: - CPDFViewDelegate PDFView代理
  1074. extension KMMainViewController: CPDFViewDelegate,CPDFListViewDelegate {
  1075. func pdfViewDocumentDidLoaded(_ pdfView: CPDFView!) {
  1076. sideBarController?.reloadPageTurnerData()
  1077. documentLoadComplete()
  1078. }
  1079. func pdfViewCurrentPageDidChanged(_ pdfView: CPDFView!) {
  1080. sideBarController?.reloadPageTurnerData()
  1081. var indexpaths: Set<IndexPath> = []
  1082. indexpaths.insert(IndexPath(item: listView.currentPageIndex, section: 0))
  1083. botaViewController?.thumnailViewController?.selectionIndexPaths = indexpaths
  1084. reloadPDFBottomToolbar()
  1085. //分屏视图
  1086. if viewManager.splitSyncScroll {
  1087. if splitPDFController?.inPDFFirst == false && splitPDFController?.outPDFFirst == false {
  1088. splitPDFController?.outPDFFirst = true
  1089. if let splitPDFView = splitPDFController?.pdfView, let document = splitPDFView.document {
  1090. var index = pdfView.currentPageIndex
  1091. if index > document.pageCount {
  1092. index = Int(splitPDFView.document.pageCount - 1)
  1093. }
  1094. splitPDFView.go(toPageIndex: index, animated: false)
  1095. }
  1096. NSObject.cancelPreviousPerformRequests(withTarget: self, selector: #selector(pdfUpdatedFinish), object: nil)
  1097. self.perform(#selector(pdfUpdatedFinish), with: nil, afterDelay: 0.35)
  1098. } else if splitPDFController?.outPDFFirst == true {
  1099. if let splitPDFView = splitPDFController?.pdfView, let document = splitPDFView.document {
  1100. var index = pdfView.currentPageIndex
  1101. if index > document.pageCount {
  1102. index = Int(splitPDFView.document.pageCount - 1)
  1103. }
  1104. splitPDFView.go(toPageIndex: index, animated: false)
  1105. }
  1106. NSObject.cancelPreviousPerformRequests(withTarget: self, selector: #selector(pdfUpdatedFinish), object: nil)
  1107. self.perform(#selector(pdfUpdatedFinish), with: nil, afterDelay: 0.35)
  1108. }
  1109. }
  1110. }
  1111. func pdfViewScaleDidChanged(_ pdfView: CPDFView!) {
  1112. pdfToolbarController?.reloadSelectZoomView()
  1113. reloadPDFBottomToolbar()
  1114. //分屏视图
  1115. if viewManager.splitSyncScroll {
  1116. if splitPDFController?.inPDFFirst == false && splitPDFController?.outPDFFirst == false {
  1117. splitPDFController?.outPDFFirst = true
  1118. NSObject.cancelPreviousPerformRequests(withTarget: self, selector: #selector(pdfUpdatedFinish), object: nil)
  1119. self.perform(#selector(pdfUpdatedFinish), with: nil, afterDelay: 0.35)
  1120. } else if splitPDFController?.outPDFFirst == true {
  1121. if let splitPDFView = splitPDFController?.pdfView {
  1122. splitPDFView.scaleFactor = pdfView.scaleFactor
  1123. }
  1124. NSObject.cancelPreviousPerformRequests(withTarget: self, selector: #selector(pdfUpdatedFinish), object: nil)
  1125. self.perform(#selector(pdfUpdatedFinish), with: nil, afterDelay: 0.35)
  1126. }
  1127. }
  1128. }
  1129. func pdfViewDidClick(onLink pdfView: CPDFView!, withURL url: String!) {
  1130. if let urlString = url, urlString == kKMPurchaseProductURLString {
  1131. //跳转订阅比较表
  1132. let _ = KMComparativeTableViewController.show(window: NSApp.mainWindow ?? NSWindow())
  1133. return
  1134. }
  1135. if url.hasPrefix("smb://") {
  1136. NSWorkspace.shared.openFile(url)
  1137. } else {
  1138. KMTools.openURL(urlString: url)
  1139. }
  1140. }
  1141. func pdfViewPerformURL(_ pdfView: CPDFView!, withContent content: String!) {
  1142. KMPrint("pdfViewPerformURL")
  1143. if content != nil {
  1144. NSWorkspace.shared.open(URL(string: content)!)
  1145. } else {
  1146. let alert = NSAlert()
  1147. alert.alertStyle = .critical
  1148. alert.informativeText = NSLocalizedString("The hyperlink is invalid.", comment: "")
  1149. alert.messageText = ""
  1150. alert.addButton(withTitle: NSLocalizedString("OK", comment: ""))
  1151. alert.runModal()
  1152. return
  1153. }
  1154. }
  1155. func pdfViewPerformPrint(_ pdfView: CPDFView!) {
  1156. KMPrint("pdfViewPerformPrint")
  1157. self.showPrintWindow()
  1158. }
  1159. func pdfViewPerformGo(toPage pdfView: CPDFView!) {
  1160. KMPrint("pdfViewPerformGo")
  1161. }
  1162. func pdfViewOpenPDF(_ pdfView: CPDFView!, forRemoteGoTo action: CPDFAction!) {
  1163. KMPrint("pdfViewOpenPDF")
  1164. }
  1165. func pdfViewPerformReset(_ pdfView: CPDFView!) {
  1166. KMPrint("pdfViewPerformReset")
  1167. pdfView.document?.resetForm()
  1168. }
  1169. func pdfViewEditingBlockDidChanged(_ pdfView: CPDFView!) {
  1170. KMPrint("pdfViewEditingBlockDidChanged")
  1171. }
  1172. func pdfViewAsBookBookmark() -> NSImage! {
  1173. return NSImage(named: "KMImageNameBookmarkIcon")!
  1174. }
  1175. func pdfViewEditingSelectionDidChanged(_ pdfView: CPDFView!) {
  1176. self.editPDFHanddler.pdfViewEditingSelectionDidChanged(pdfView)
  1177. }
  1178. func pdfViewEditingAreaDidChanged(_ pdfView: CPDFView!) {
  1179. self.editPDFHanddler.pdfViewEditingAreaDidChanged(pdfView)
  1180. }
  1181. func pdfViewEditingCropBoundsDidChanged(_ pdfView: CPDFView!, editing editArea: CPDFEditArea!) {
  1182. self.editPDFHanddler.pdfViewEditingCropBoundsDidChanged(pdfView, editing: editArea)
  1183. }
  1184. //编辑PDF 创建图片区域回调
  1185. func pdfViewEditingAddImageArea(_ pdfView: CPDFView!, add page: CPDFPage!, add rect: CGRect) {
  1186. self.editPDFHanddler.pdfViewEditingAddImageArea(pdfView, add: page, add: rect)
  1187. }
  1188. func pdfViewEditingAddTextArea(_ pdfView: CPDFView!, add page: CPDFPage!, add rect: CGRect) {
  1189. self.editPDFHanddler.pdfViewEditingAddTextArea(pdfView, add: page, add: rect)
  1190. }
  1191. func pdfViewMobileEditingBegan(_ point: CGPoint, for pdfView: CPDFView!, forEditing editingAreas: [CPDFEditArea]!) {
  1192. self.editPDFHanddler.pdfViewMobileEditingBegan(point, for: pdfView, forEditing: editingAreas)
  1193. }
  1194. func pdfViewMobileEditingMove(_ point: CGPoint, for pdfView: CPDFView!, forEditing editingAreas: [CPDFEditArea]!) {
  1195. self.editPDFHanddler.pdfViewMobileEditingMove(point, for: pdfView, forEditing: editingAreas)
  1196. }
  1197. func pdfViewMobileEditingEnd(_ point: CGPoint, for pdfView: CPDFView!, forEditing editingAreas: [CPDFEditArea]!) {
  1198. self.editPDFHanddler.pdfViewMobileEditingEnd(point, for: pdfView, forEditing: editingAreas)
  1199. }
  1200. func pdfViewEditingSelectCharDidChanged(_ pdfView: CPDFView!) {
  1201. self.editPDFHanddler.pdfViewEditingSelectCharDidChanged(pdfView)
  1202. }
  1203. func pdfViewEditingExitCropMode(_ pdfView: CPDFView!, forEditing editingArea: CPDFEditImageArea!) {
  1204. self.editPDFHanddler.pdfViewEditingExitCropMode(pdfView, forEditing: editingArea)
  1205. }
  1206. func pdfListViewKeyDownIsContinue(_ pdfListView: CPDFListView!, theEvent: NSEvent!) -> Bool {
  1207. let command = theEvent.modifierFlags.contains(.command)
  1208. let control = theEvent.modifierFlags.contains(.control)
  1209. KMPrint(theEvent.keyCode)
  1210. if self.listView.isEditing() == true {
  1211. if control && theEvent.keyCode == 11 { // ctr + b
  1212. self.editPDFHanddler.fontBoldAction()
  1213. return false
  1214. } else if control && theEvent.keyCode == 34 { // ctr +i
  1215. self.editPDFHanddler.fontItalicAction()
  1216. return false
  1217. } else if theEvent.keyCode == 36 { // enter
  1218. if self.listView.isCropMode {
  1219. self.editPDFHanddler.cropComfirmAction()
  1220. return false
  1221. }
  1222. }
  1223. }
  1224. if (theEvent.keyCode == 11 && command) { // command + B [添加书签]
  1225. self.menuItemBookMarkClick_add(sender: NSMenuItem())
  1226. return false
  1227. } else if (command && control && theEvent.keyCode == 14) { // command + control + E [注释 橡皮擦]
  1228. return false
  1229. } else if (theEvent.keyCode == 123) { // 向左
  1230. if(self.listView.isEditing() && !self.listView.isSelecteditAreaNotEdit()) {
  1231. return false
  1232. } else {
  1233. if (self.pdfViewCanHorizontalScroll() == false && self.listView.canGoToPreviousPage()) {
  1234. self.listView.goToPreviousPage(nil)
  1235. return false
  1236. }
  1237. }
  1238. } else if (theEvent.keyCode == 126) { // 向上
  1239. if(self.listView.isEditing() && !self.listView.isSelecteditAreaNotEdit()) {
  1240. return false
  1241. } else {
  1242. if (self.listView.isContinousScroll()) {
  1243. return true
  1244. }
  1245. if (self.pdfViewCanVerticalScroll() == false && self.listView.canGoToPreviousPage()) {
  1246. self.listView.goToPreviousPage(nil)
  1247. return false
  1248. }
  1249. }
  1250. } else if (theEvent.keyCode == 124) { // 向右
  1251. if(self.listView.isEditing() && !self.listView.isSelecteditAreaNotEdit()) {
  1252. return false
  1253. } else {
  1254. if (self.pdfViewCanHorizontalScroll() == false && self.listView.canGoToNextPage()) {
  1255. self.listView.goToNextPage(nil)
  1256. return false
  1257. }
  1258. }
  1259. } else if (theEvent.keyCode == 125) { // 向下
  1260. if(self.listView.isEditing() && !self.listView.isSelecteditAreaNotEdit()) {
  1261. return false
  1262. } else {
  1263. if (self.listView.isContinousScroll()) {
  1264. return true
  1265. }
  1266. if (self.pdfViewCanVerticalScroll() == false && self.listView.canGoToNextPage()) {
  1267. self.listView.goToNextPage(nil)
  1268. return false
  1269. }
  1270. }
  1271. } else if (theEvent.keyCode == 36) {
  1272. if self.listView.annotationType == .addImage || self.listView.annotationType == .addText {
  1273. if self.listView.isEditImage {
  1274. self.menuItemEditingClick_CropImage(sender: NSMenuItem())
  1275. }
  1276. }
  1277. }
  1278. if theEvent.keyCode == 53 {
  1279. //ESC
  1280. // self.exitFullScreen()
  1281. if viewManager.isPDFReadMode {
  1282. self.exitPDFReadMode()
  1283. }
  1284. self.leftSideViewCancelSelect()
  1285. }
  1286. return true
  1287. }
  1288. func pdfListViewMenuValidate(_ pdfListView: CPDFListView!, menuItem: NSMenuItem!, isTakesEffect: UnsafeMutablePointer<ObjCBool>!) -> Bool {
  1289. guard let action = menuItem.action else {
  1290. isTakesEffect.pointee = false
  1291. return false
  1292. }
  1293. if (KMSystemMenu.isEditSelector(sel: action)) {
  1294. if (KMSystemMenu.Edit.deleteSelector == action) {
  1295. isTakesEffect.pointee = true
  1296. return self.listView.activeAnnotations.count > 0
  1297. } else if (KMSystemMenu.Edit.copySelector == action) {
  1298. isTakesEffect.pointee = true
  1299. return true//self.listView.canCopy()
  1300. } else if (KMSystemMenu.Edit.cutSelector == action) {
  1301. isTakesEffect.pointee = true
  1302. return self.listView.canCopy()
  1303. } else if (KMSystemMenu.Edit.pasteSelector == action) {
  1304. isTakesEffect.pointee = true
  1305. return self.listView.canPaste()
  1306. }
  1307. }
  1308. isTakesEffect.pointee = false
  1309. return false
  1310. }
  1311. func pdfViewEditingOperationDidChanged(_ pdfView: CPDFView!) {
  1312. self.editPDFHanddler.pdfViewEditingOperationDidChanged(pdfView)
  1313. }
  1314. func pdfViewEditingDoubleClick(_ pdfView: CPDFView!, imageArea editArea: CPDFEditArea!) {
  1315. self.editPDFHanddler.pdfViewEditingDoubleClick(pdfView, imageArea: editArea)
  1316. }
  1317. //MARK: - CPDFListViewDelegate
  1318. func cPDFListView(_ pdfListView: CPDFListView, didDelete annotation: CPDFAnnotation, in pdfPage: CPDFPage) {
  1319. self.leftSideViewController.updateThumbnail(at: Int(pdfPage.pageIndex()))
  1320. }
  1321. func pdfListViewChangeatioActiveAnnotations(_ pdfListView: CPDFListView!, forActiveAnnotations annotations: [CPDFAnnotation]!, isRightMenu: Bool) {
  1322. self.view.window?.makeFirstResponder(self.listView)
  1323. if isRightMenu {
  1324. } else if annotations.count > 0 {
  1325. if annotations.count > 1 {
  1326. let fristAnnotation = annotations.first
  1327. var isSameAnnotation = true
  1328. let className = NSStringFromClass(fristAnnotation!.classForCoder)
  1329. for annotation in annotations {
  1330. let cunrrentClassName = NSStringFromClass(annotation.classForCoder)
  1331. if (className == "CPDFSquareAnnotation") ||
  1332. (className == "CPDFCircleAnnotation") ||
  1333. (className == "CPDFLineAnnotation") {
  1334. if (cunrrentClassName != "CPDFSquareAnnotation") &&
  1335. (cunrrentClassName != "CPDFCircleAnnotation") &&
  1336. (cunrrentClassName != "CPDFLineAnnotation") {
  1337. isSameAnnotation = false
  1338. }
  1339. } else {
  1340. if className != cunrrentClassName {
  1341. isSameAnnotation = false
  1342. }
  1343. }
  1344. }
  1345. if isSameAnnotation == false {
  1346. self.rightSideViewController?.reloadDataWithPDFView(pdfView: pdfListView, isShow: false)
  1347. } else {
  1348. self.rightSideViewController?.reloadDataWithPDFView(pdfView: pdfListView, isShow: true)
  1349. self.openRightPane()
  1350. }
  1351. } else {
  1352. let fristAnnotation = annotations.first
  1353. let className = NSStringFromClass(fristAnnotation!.classForCoder)
  1354. if self.viewManager.isPDFReadMode {
  1355. self.rightSideViewController?.reloadDataWithPDFView(pdfView: pdfListView, isShow: false)
  1356. self.closeRightPane()
  1357. } else {
  1358. self.rightSideViewController?.reloadDataWithPDFView(pdfView: pdfListView, isShow: true)
  1359. if className != "CPDFStampAnnotation" &&
  1360. className != "CPDFSignatureAnnotation" &&
  1361. className != "CPDFListStampAnnotation" {
  1362. self.openRightPane()
  1363. }
  1364. }
  1365. }
  1366. if (listView.activeAnnotation.isKind(of: CPDFLineAnnotation.self)) {
  1367. if (!(listView.activeAnnotation as! CPDFLineAnnotation).isMeasure) {
  1368. cancelMeasureType()
  1369. } else {
  1370. if distanceMeasureInfoWindowController == nil {
  1371. let measureInfo = CPDFDistanceMeasureInfo()
  1372. distanceMeasureInfoWindowController = CDistanceMeasureInfoWindowController()
  1373. distanceMeasureInfoWindowController?.measureInfo = measureInfo
  1374. distanceMeasureInfoWindowController?.delegate = self
  1375. }
  1376. }
  1377. } else if (!listView.activeAnnotation.isKind(of: CPDFPolygonAnnotation.self) && !listView.activeAnnotation.isKind(of: CPDFPolylineAnnotation.self)) {
  1378. cancelMeasureType()
  1379. } else if (listView.activeAnnotation.isKind(of: CPDFPolygonAnnotation.self) || listView.activeAnnotation.isKind(of: CPDFPolylineAnnotation.self)) {
  1380. if perimeterMeasureInfoWindowController == nil {
  1381. let measureInfo = CPDFPerimeterMeasureInfo()
  1382. perimeterMeasureInfoWindowController = CPerimeterMeasureInfoWindowController()
  1383. perimeterMeasureInfoWindowController?.measureInfo = measureInfo
  1384. perimeterMeasureInfoWindowController?.delegate = self
  1385. }
  1386. if areaMeasureInfoWindowController == nil {
  1387. let measureInfo = CPDFAreaMeasureInfo()
  1388. areaMeasureInfoWindowController = CAreaMeasureInfoWindowController()
  1389. areaMeasureInfoWindowController?.measureInfo = measureInfo
  1390. areaMeasureInfoWindowController?.delegate = self
  1391. }
  1392. }
  1393. } else if (annotations.count == 0){
  1394. if pdfListView.annotationType == .unkown {
  1395. self.rightSideViewController?.reloadDataWithPDFView(pdfView: pdfListView, isShow: false)
  1396. self.closeRightPane()
  1397. } else {
  1398. if self.viewManager.isPDFReadMode {
  1399. self.rightSideViewController?.reloadDataWithPDFView(pdfView: pdfListView, isShow: false)
  1400. self.closeRightPane()
  1401. } else {
  1402. self.rightSideViewController?.reloadDataWithPDFView(pdfView: pdfListView, isShow: true)
  1403. self.openRightPane()
  1404. }
  1405. }
  1406. }
  1407. }
  1408. func pdfListViewChangedAnnotationType(_ pdfListView: CPDFListView!, for annotationType: CAnnotationType) {
  1409. if(annotationType == .unkown) {
  1410. self.rightSideViewController.isHidden = true
  1411. self.closeRightPane()
  1412. }
  1413. let aType = annotationType
  1414. if aType.isMarkup() || aType == .anchored || aType == .freeText || aType.isSquare() || aType == .link {
  1415. KMDataManager.ud_set(annotationType.rawValue, forKey: SKLastAnnotationModeKey)
  1416. }
  1417. }
  1418. ///开始定位链接注释
  1419. func pdfListViewLinkDestinationStart(_ pdfListView: CPDFListView!, withActiveAnnotation annotation: CPDFAnnotation!) {
  1420. }
  1421. ///刷新链接注释
  1422. func pdfListViewLinkDestinationEnd(_ pdfListView: CPDFListView!, withActiveAnnotation annotation: CPDFAnnotation!) {
  1423. }
  1424. func pdfListViewMenuItemsEditing(at point: CGPoint, for page: CPDFPage!, menuItems: [NSMenuItem]!) -> [NSMenuItem]! {
  1425. if (listView.toolMode != CToolMode.editPDFToolMode) {
  1426. return menuItems
  1427. }
  1428. var tMenuItems = menuItems;
  1429. if(listView.isSelectEditCharRange() ||
  1430. listView.isSelecteditArea(with: point)) {
  1431. tMenuItems?.append(NSMenuItem.separator())
  1432. }
  1433. let areas = self.listView.editingAreas() ?? []
  1434. if areas.count == 1 {
  1435. let fristAreas = areas.first
  1436. if fristAreas is CPDFEditImageArea {
  1437. self.listView.selectImageAreas = fristAreas as? CPDFEditImageArea
  1438. if self.listView.isEditImage {
  1439. tMenuItems?.removeAll()
  1440. tMenuItems?.append(self.corpImageMenuItem())
  1441. tMenuItems?.append(self.cancelCorpImageMenuItem())
  1442. tMenuItems?.append(self.restoreCorpImageMenuItem())
  1443. } else {
  1444. tMenuItems?.append(NSMenuItem.separator())
  1445. tMenuItems?.append(self.cutImageArea())
  1446. tMenuItems?.append(self.replaceImageArea())
  1447. tMenuItems?.append(self.exportImageArea())
  1448. }
  1449. } else {
  1450. if tMenuItems?.count != 1 {
  1451. tMenuItems?.swapAt(0, 1)
  1452. }
  1453. }
  1454. } else if areas.count == 0 {
  1455. tMenuItems?.append(NSMenuItem.separator())
  1456. tMenuItems?.append(self.addText())
  1457. tMenuItems?.append(self.addImage())
  1458. }
  1459. return tMenuItems
  1460. }
  1461. func pdfListViewMenu(forEvent pdfListView: CPDFListView!, for theEvent: NSEvent!, click menu: AutoreleasingUnsafeMutablePointer<NSMenu?>!, isMoveSelectAnno: Bool) {
  1462. self.mouseRightMenuEvent = theEvent
  1463. var currentMenu : NSMenu = menu.pointee!
  1464. if let activeAnno = listView.activeAnnotation as? KMTableAnnotation {//Table
  1465. var pagePoint = NSPoint()
  1466. _ = self.listView.pageAndPoint(&pagePoint, for: theEvent, nearest: true)
  1467. currentMenu.removeAllItems()
  1468. let annotation = activeAnno
  1469. annotation.completeEditCellText()
  1470. if !(NSIsEmptyRect(annotation.drawRect)) {
  1471. annotation.drawLine(pagePoint)
  1472. NotificationCenter.default.post(name: NSNotification.Name.KMPDFViewTableAnnotationDidChange, object: self, userInfo: ["point": NSValue(point: pagePoint)])
  1473. }
  1474. if (annotation.rowNumber - annotation.currentCell.row - 1) < 0 {
  1475. return
  1476. }
  1477. currentMenu = tableMenu(currentMenu, withTable: listView.activeAnnotation as! KMTableAnnotation, point: pagePoint)
  1478. listView.needsDisplay = true
  1479. return
  1480. }
  1481. var pagePoint: NSPoint = .zero
  1482. if let page = self.listView.pageAndPoint(&pagePoint, for: theEvent, nearest: true) {
  1483. let anno = page.annotation(at: pagePoint)
  1484. let item1 = NSMenuItem(title: NSLocalizedString("Delete", comment: ""), action: #selector(menuItemActionMeasureDelete), target: self)
  1485. item1.representedObject = anno
  1486. let item2 = NSMenuItem(title: NSLocalizedString("Edit Note", comment: ""), action: #selector(menuItemActionMeasureEditNote), target: self)
  1487. item2.representedObject = anno
  1488. let item3 = NSMenuItem(title: NSLocalizedString("Settings", comment: ""), action: #selector(menuItemActionMeasureSetting), target: self)
  1489. item3.representedObject = anno
  1490. if let data = anno as? CPDFPolygonAnnotation { // 多变形
  1491. currentMenu.removeAllItems()
  1492. currentMenu.insertItem(item1, at: 0)
  1493. currentMenu.insertItem(item2, at: 1)
  1494. currentMenu.insertItem(item3, at: 2)
  1495. return
  1496. }
  1497. if let data = anno as? CPDFPolylineAnnotation {
  1498. currentMenu.removeAllItems()
  1499. currentMenu.insertItem(item1, at: 0)
  1500. currentMenu.insertItem(item2, at: 1)
  1501. currentMenu.insertItem(item3, at: 2)
  1502. return
  1503. }
  1504. if let data = anno as? CPDFLineAnnotation, data.isMeasure {
  1505. currentMenu.removeAllItems()
  1506. currentMenu.insertItem(item1, at: 0)
  1507. currentMenu.insertItem(item2, at: 1)
  1508. currentMenu.insertItem(item3, at: 2)
  1509. return
  1510. }
  1511. }
  1512. if (listView.toolMode == .selectToolMode){
  1513. currentMenu.insertItem(NSMenuItem.separator(), at: 3)
  1514. currentMenu.insertItem(self.printingMenu(), at: 3)
  1515. currentMenu.insertItem(self.setTTSStype(), at: 3)
  1516. currentMenu.insertItem(self.setCropStype(), at: 3)
  1517. currentMenu.insertItem(self.setSnapshotStype(), at: 3)
  1518. let export = NSMenuItem(title: NSLocalizedString("Export", comment: ""), action: nil, target: self)
  1519. export.submenu = self.exportMenu()
  1520. currentMenu.insertItem(export, at: 3)
  1521. currentMenu.insertItem(NSMenuItem.separator(), at: 3)
  1522. if listView.activeAnnotation == nil{
  1523. currentMenu.insertItem(self.setAnnotationToolStype(), at: 3)
  1524. currentMenu.insertItem(NSMenuItem.separator(), at: 3)
  1525. }
  1526. currentMenu.insertItem(NSMenuItem.separator(), at: currentMenu.items.count - 3)
  1527. currentMenu.insertItem(self.addReadModelStype(), at: currentMenu.items.count - 3)
  1528. currentMenu.insertItem(NSMenuItem.separator(), at: 0)
  1529. currentMenu.insertItem(self.setAITranslateStype(), at: 0)
  1530. currentMenu.insertItem(self.setAIProofreadStype(), at: 0)
  1531. currentMenu.insertItem(self.setAIRewriteStype(), at: 0)
  1532. return
  1533. }
  1534. if (listView.toolMode == .moveToolMode || listView.toolMode == .magnifyToolMode){
  1535. currentMenu.insertItem(NSMenuItem.separator(), at: 0)
  1536. currentMenu.insertItem(self.setTTSStype(), at: 0)
  1537. currentMenu.insertItem(self.setCropStype(), at: 0)
  1538. currentMenu.insertItem(self.setSnapshotStype(), at: 0)
  1539. currentMenu.insertItem(NSMenuItem.separator(), at: 0)
  1540. currentMenu.insertItem(self.addOutlineStype(), at: 0)
  1541. currentMenu.insertItem(self.addBookmarkMenu(), at: 0)
  1542. if listView.activeAnnotation == nil{
  1543. currentMenu.insertItem(NSMenuItem.separator(), at: 0)
  1544. currentMenu.insertItem(self.setAnnotationToolStype(), at: 0)
  1545. }
  1546. currentMenu.insertItem(NSMenuItem.separator(), at: 0)
  1547. currentMenu.insertItem(self.setAITranslateStype(), at: 0)
  1548. currentMenu.insertItem(self.setAIProofreadStype(), at: 0)
  1549. currentMenu.insertItem(self.setAIRewriteStype(), at: 0)
  1550. return
  1551. }
  1552. if currentMenu.items.count > 3 {
  1553. currentMenu.insertItem(NSMenuItem.separator(), at: currentMenu.items.count - 3)
  1554. currentMenu.insertItem(self.addReadModelStype(), at: currentMenu.items.count - 3)
  1555. }
  1556. if listView.currentSelection != nil && listView.activeAnnotations.count < 1{
  1557. if listView.currentSelection.selectionType() == .text {
  1558. currentMenu.insertItem(NSMenuItem.separator(), at: 3)
  1559. currentMenu.insertItem(self.setSearchBaiduStype(), at: 3)
  1560. currentMenu.insertItem(NSMenuItem.separator(), at: 3)
  1561. currentMenu.insertItem(self.setLookUpStype(), at: 3)
  1562. currentMenu.insertItem(NSMenuItem.separator(), at: 3)
  1563. currentMenu.insertItem(self.addOutlineStype(), at: 3)
  1564. currentMenu.insertItem(NSMenuItem.separator(), at: 3)
  1565. currentMenu.insertItem(self.setAnnotationToolStype(), at: 3)
  1566. currentMenu.insertItem(self.setTTSStype(), at: 3)
  1567. currentMenu.insertItem(NSMenuItem.separator(), at: 3)
  1568. currentMenu.insertItem(self.setShareStype(), at: 3)
  1569. currentMenu.insertItem(NSMenuItem.separator(), at: 3)
  1570. }
  1571. currentMenu.insertItem(self.enterAnnotationStype(), at: 3)
  1572. currentMenu.insertItem(NSMenuItem.separator(), at: 3)
  1573. if listView.currentSelection.selectionType() == .image{
  1574. currentMenu.insertItem(NSMenuItem.separator(), at: 6)
  1575. currentMenu.insertItem(self.addOutlineStype(), at: 6)
  1576. currentMenu.insertItem(NSMenuItem.separator(), at: 6)
  1577. currentMenu.insertItem(self.setAnnotationToolStype(), at: 6)
  1578. }
  1579. if listView.currentSelection.selectionType() == .text {
  1580. currentMenu.insertItem(NSMenuItem.separator(), at: currentMenu.items.count)
  1581. currentMenu.insertItem(self.setTranslateStype(), at: currentMenu.items.count)
  1582. currentMenu.insertItem(NSMenuItem.separator(), at: currentMenu.items.count)
  1583. }
  1584. }
  1585. if listView.activeAnnotation != nil || isMoveSelectAnno {
  1586. if let data = self.listView.activeAnnotation?.type?.lowercased(), data == "stamp"{
  1587. currentMenu.insertItem(NSMenuItem.separator(), at: currentMenu.items.count - 15)
  1588. currentMenu.insertItem(self.enterAnnotationStype(), at: currentMenu.items.count - 15)
  1589. currentMenu.insertItem(NSMenuItem.separator(), at: currentMenu.items.count - 15)
  1590. }else{
  1591. currentMenu.insertItem(NSMenuItem.separator(), at: currentMenu.items.count - 15)
  1592. currentMenu.insertItem(self.enterAnnotationStype(), at: currentMenu.items.count - 15)
  1593. if let anno = self.listView.activeAnnotation, anno.isKind(of: CPDFStampAnnotation.self) {
  1594. } else {
  1595. currentMenu.insertItem(NSMenuItem.separator(), at: currentMenu.items.count - 15)
  1596. currentMenu.insertItem(self.setShareStype(), at: currentMenu.items.count - 15)
  1597. }
  1598. currentMenu.insertItem(NSMenuItem.separator(), at: currentMenu.items.count - 15)
  1599. }
  1600. }
  1601. if listView.activeAnnotation == nil && listView.currentSelection == nil{
  1602. currentMenu.insertItem(NSMenuItem.separator(), at: currentMenu.items.count)
  1603. if(listView.toolMode == .selectToolMode) {
  1604. if NSIsEmptyRect(listView.currentSelectionRect()) {
  1605. currentMenu.insertItem(self.zoomSelectionMenuItem(), at: 0)
  1606. currentMenu.insertItem(NSMenuItem.separator(), at: 0)
  1607. }
  1608. currentMenu.insertItem(self.printingMenu(), at: 0)
  1609. currentMenu.insertItem(self.setTTSStype(), at: 0)
  1610. currentMenu.insertItem(self.setCropStype(), at: 0)
  1611. currentMenu.insertItem(self.setSnapshotStype(), at: 0)
  1612. let export = NSMenuItem(title: NSLocalizedString("Export", comment: ""), action: nil, target: self)
  1613. export.submenu = self.exportMenu()
  1614. currentMenu.insertItem(export, at: currentMenu.items.count)
  1615. }else{
  1616. currentMenu.insertItem(NSMenuItem.separator(), at: 2)
  1617. currentMenu.insertItem(self.setTTSStype(), at: 2)
  1618. currentMenu.insertItem(self.setCropStype(), at: 2)
  1619. currentMenu.insertItem(self.setSnapshotStype(), at: 2)
  1620. currentMenu.insertItem(NSMenuItem.separator(), at: 2)
  1621. currentMenu.insertItem(self.addOutlineStype(), at: 2)
  1622. currentMenu.insertItem(NSMenuItem.separator(), at: 2)
  1623. currentMenu.insertItem(self.enterAnnotationStype(), at: 2)
  1624. currentMenu.insertItem(NSMenuItem.separator(), at: 2)
  1625. if(currentMenu.items.count > 4) {
  1626. currentMenu.insertItem(NSMenuItem.separator(), at: 5)
  1627. }
  1628. if(currentMenu.items.count > 5) {
  1629. currentMenu.insertItem(self.addBookmarkMenu(), at: 6)
  1630. }
  1631. currentMenu.insertItem(self.setAutoScrollStype(), at: currentMenu.items.count)
  1632. }
  1633. currentMenu.insertItem(self.setAnnotationToolStype(), at: 5)
  1634. }
  1635. currentMenu.insertItem(NSMenuItem.separator(), at: 0)
  1636. currentMenu.insertItem(self.setAITranslateStype(), at: 0)
  1637. currentMenu.insertItem(self.setAIProofreadStype(), at: 0)
  1638. currentMenu.insertItem(self.setAIRewriteStype(), at: 0)
  1639. for item in currentMenu.items {
  1640. if (item.action == NSSelectorFromString("menuItemClick_HidenorShowNote:")) {
  1641. // 显示与隐藏注释 item action 截取
  1642. item.action = #selector(menuItemClick_HidenorShowNote)
  1643. item.target = self
  1644. break
  1645. }
  1646. }
  1647. }
  1648. func pdfListViewAddAnnotations(_ pdfListView: CPDFListView!, forAdd annotations: [CPDFAnnotation]!, in pdfPage: CPDFPage!) {
  1649. var addRedact = false
  1650. for anno in annotations {
  1651. if (anno.isKind(of: CPDFRedactAnnotation.self)) {
  1652. addRedact = true
  1653. } else if anno is CPDFSquareAnnotation || anno is CPDFCircleAnnotation {
  1654. anno.contents = pdfPage?.string(for: anno.bounds) ?? ""
  1655. }
  1656. }
  1657. self.model.hasAddRedact = addRedact
  1658. if self.listView.toolMode == .moveToolMode {
  1659. self.listView.toolMode = .textToolMode
  1660. self.listView.annotationType = .unkown
  1661. self.toolbarController.toolbarType = .Annatiton
  1662. }
  1663. if (self.model.rightMouseEventing) {
  1664. self.model.rightMouseEventing = false
  1665. if (self.toolbarController.ignoreCurrentAnnotationTypeChange && self.listView.annotationType == .ink) {
  1666. self.listView.toolMode = .textToolMode
  1667. self.listView.annotationType = .unkown
  1668. }
  1669. }
  1670. self.toolbarController.ignoreCurrentAnnotationTypeChange = false
  1671. self.leftSideViewController.refreshUIForAddAnnotation(annos: annotations, page: pdfPage)
  1672. }
  1673. func pdfListViewRemoveAnnotations(_ pdfListView: CPDFListView!, forRemove annotations: [CPDFAnnotation]!, in pdfPage: CPDFPage!) {
  1674. self.leftSideViewController.annoList_refreshUIForDeleteAnnotations(annos: annotations, page: pdfPage)
  1675. }
  1676. func pdfListViewDidSelectionEnd(_ pdfListView: CPDFListView!) {
  1677. if (!self.listView.isEqual(to: pdfListView)) {
  1678. return
  1679. }
  1680. if (self.listView.toolMode != .selectToolMode) {
  1681. return
  1682. }
  1683. }
  1684. func pdfListViewKeyDowClosePanel(_ speedy: CPDFViewSidebarSpeedMode, event theEvent: NSEvent!) {
  1685. if(speedy == .right) {
  1686. self.toggleRightPane()
  1687. } else if (speedy == .left) {
  1688. self.menuItemAction_hiddenLeftSide(speedy)
  1689. }
  1690. }
  1691. func pdfListViewEventMarkupColor(with annotation: CPDFAnnotation!) -> [NSColor]! {
  1692. if (annotation.isKind(of: CPDFMarkupAnnotation.self)) {
  1693. if (annotation as! CPDFMarkupAnnotation).markupType() == .highlight {
  1694. return KMAnnotationPropertiesColorManager.manager.markHighlightColors
  1695. } else {
  1696. return KMAnnotationPropertiesColorManager.manager.markOtherColors
  1697. }
  1698. } else {
  1699. return KMAnnotationPropertiesColorManager.manager.markOtherColors
  1700. }
  1701. }
  1702. func pdfListViewHaveDocumentAttribute() -> Bool {
  1703. if(!self.listView.document.allowsCopying) {
  1704. self.removeOwnerPassword()
  1705. return false
  1706. }
  1707. return true
  1708. }
  1709. func pdfListView(_ sender: CPDFListView!, showSnapshotAtPageNumber pageNum: Int, for rect: NSRect, scaleFactor: CGFloat, autoFits: Bool) {
  1710. let swc = KMSnapshotWindowController(windowNibName: "SnapshotWindow")
  1711. swc.delegate = self
  1712. swc.setPdfDocument(self.listView.document, goToPageNumber: pageNum, rect: rect, scaleFactor: scaleFactor, autoFits: autoFits)
  1713. swc.forceOnTop = self.interactionMode != .normal
  1714. self.myDocument?.addWindowController(swc)
  1715. }
  1716. func pdfListView(_ pdfView: CPDFListView!, documentDataDidChanged docData: Any!, withInfo info: [AnyHashable : Any]!) {
  1717. if let data = info?[CPDFListView.outlineKey] as? Bool, data { // 大纲改变
  1718. guard let ol = docData as? CPDFOutline else {
  1719. return
  1720. }
  1721. let add = info?[CPDFListView.outlineAddKey] as? Bool ?? false
  1722. let remove = info?[CPDFListView.outlineRemoveKey] as? Bool ?? false
  1723. if add {
  1724. self.leftSideViewController.addOutlineAfter(ol)
  1725. }
  1726. if remove {
  1727. self.leftSideViewController.removeOutlineAfter(ol)
  1728. }
  1729. let demote = info?[CPDFListView.outlineDemoteKey] as? Bool ?? false
  1730. let promote = info?[CPDFListView.outlinePromoteKey] as? Bool ?? false
  1731. if demote {
  1732. self.leftSideViewController.demoteOutlineAfter(ol)
  1733. }
  1734. if promote {
  1735. self.leftSideViewController.promoteOutlineAfter(ol)
  1736. }
  1737. }
  1738. }
  1739. //TextEdit
  1740. func pdfListViewDidTextFontChanged(_ pdfListView: CPDFListView!) {
  1741. self.rightSideViewController.eidtPDFTextProperty.reloadData()
  1742. }
  1743. func pdfListViewDidTextColorChanged(_ pdfListView: CPDFListView!, with color: NSColor!) {
  1744. self.rightSideViewController.eidtPDFTextProperty.fontColorChangeAction()
  1745. }
  1746. func pdfListViewAnnotationMeasureInfoChange(_ pdfListView: CPDFListView!, with annotation: CPDFAnnotation!) {
  1747. guard let data = annotation else {
  1748. if distanceMeasureInfoWindowController?.window?.isVisible == true {
  1749. distanceMeasureInfoWindowController?.clearData()
  1750. }
  1751. return
  1752. }
  1753. if let lineAnnotation = annotation as? CPDFLineAnnotation {
  1754. handleLineAnnotation(lineAnnotation)
  1755. } else if let polylineAnnotation = annotation as? CPDFPolylineAnnotation {
  1756. handlePolylineAnnotation(polylineAnnotation)
  1757. } else if let polygonAnnotation = annotation as? CPDFPolygonAnnotation {
  1758. handlePolygonAnnotation(polygonAnnotation)
  1759. }
  1760. }
  1761. func pdfListViewMeasureCancel(_ pdfListView: CPDFListView!) {
  1762. cancelMeasureType()
  1763. }
  1764. func tableMenu(_ menu: NSMenu, withTable table: KMTableAnnotation, point: CGPoint) -> NSMenu {
  1765. if table.currentCell.row >= 0 && table.currentCell.column >= 0 {
  1766. 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"]
  1767. let actions = ["formAnnotTextEdit:", "", "addRowAbove:", "addRowBelow:", "", "addColumnBefore:", "addColumnAfter:", "", "deleteRow:", "deleteColumn:", "deleteTabel", "cutCell:", "copyCell:", "pasteCell:", "pasteAndMatchStyle:", "deleteCellContents:", "clearAll:"]
  1768. for i in 0..<itemTitles.count {
  1769. var item: NSMenuItem? = nil
  1770. if itemTitles[i] == "" {
  1771. item = NSMenuItem.separator()
  1772. menu.insertItem(item!, at: i)
  1773. } else {
  1774. item = NSMenuItem(title: itemTitles[i], action: nil, keyEquivalent: "")
  1775. item!.target = self
  1776. item!.action = NSSelectorFromString(actions[i])
  1777. if itemTitles[i] == "Paste" /*&& !_copyCellData*/ {
  1778. item!.action = nil
  1779. } else if itemTitles[i] == "Paste and Match Style" /*&& !_copyCellData */{
  1780. item!.action = nil
  1781. } else if itemTitles[i] == "Add Row Above" {
  1782. let path1 = table.crossLines[table.rowNumber - table.currentCell.row]
  1783. let path2 = table.crossLines[table.rowNumber - table.currentCell.row - 1]
  1784. if (path1 as AnyObject).lineJoinStyle == NSBezierPath.LineJoinStyle.round && table.headerCount() >= 5 {
  1785. item!.action = nil
  1786. } else if (path2 as AnyObject).lineJoinStyle == NSBezierPath.LineJoinStyle.bevel && table.footerCount() >= 5 {
  1787. item!.action = nil
  1788. }
  1789. }
  1790. item!.title = NSLocalizedString(item!.title, comment: "")
  1791. item!.representedObject = NSValue(point: point)
  1792. menu.insertItem(item!, at: i)
  1793. }
  1794. }
  1795. } else {
  1796. let itemTitles = ["Cut", "Copy", "Paste", "Delete"]
  1797. let actions = ["cut:", "copy:", "paste:", "delete:"]
  1798. for i in 0..<itemTitles.count {
  1799. let item = NSMenuItem(title: itemTitles[i], action: nil, keyEquivalent: "")
  1800. item.target = self
  1801. item.action = NSSelectorFromString(actions[i])
  1802. item.title = NSLocalizedString(item.title, comment: "")
  1803. menu.insertItem(item, at: i)
  1804. item.representedObject = NSValue(point: point)
  1805. }
  1806. }
  1807. return menu
  1808. }
  1809. private func handleLineAnnotation(_ annotation: CPDFLineAnnotation) {
  1810. if perimeterMeasureInfoWindowController?.window?.isVisible == true {
  1811. perimeterMeasureInfoWindowController?.hideFloatingWindow()
  1812. distanceMeasureInfoWindowController?.showWindow(self)
  1813. } else if areaMeasureInfoWindowController?.window?.isVisible == true {
  1814. areaMeasureInfoWindowController?.hideFloatingWindow()
  1815. distanceMeasureInfoWindowController?.showWindow(self)
  1816. } else if distanceMeasureInfoWindowController?.window?.isVisible == false {
  1817. distanceMeasureInfoWindowController?.showWindow(self)
  1818. }
  1819. let measureInfo = annotation.measureInfo
  1820. let startPoint = annotation.startPoint
  1821. let endPoint = annotation.endPoint
  1822. let angle = atan2(endPoint.y - startPoint.y, endPoint.x - startPoint.x) * (180.0 / .pi)
  1823. distanceMeasureInfoWindowController?.angleLabel.stringValue = String(format: "%.2f°", abs(angle))
  1824. distanceMeasureInfoWindowController?.xLabel.stringValue = String(format: "%.0f", abs(endPoint.x - startPoint.x))
  1825. distanceMeasureInfoWindowController?.yLabel.stringValue = String(format: "%.0f", abs(endPoint.y - startPoint.y))
  1826. distanceMeasureInfoWindowController?.reloadData(with: measureInfo!)
  1827. }
  1828. private func handlePolylineAnnotation(_ annotation: CPDFPolylineAnnotation) {
  1829. if distanceMeasureInfoWindowController?.window?.isVisible == true {
  1830. distanceMeasureInfoWindowController?.hideFloatingWindow()
  1831. perimeterMeasureInfoWindowController?.showWindow(self)
  1832. } else if areaMeasureInfoWindowController?.window?.isVisible == true {
  1833. areaMeasureInfoWindowController?.hideFloatingWindow()
  1834. perimeterMeasureInfoWindowController?.showWindow(self)
  1835. } else if perimeterMeasureInfoWindowController?.window?.isVisible == false {
  1836. perimeterMeasureInfoWindowController?.showWindow(self)
  1837. }
  1838. let measureInfo = annotation.measureInfo
  1839. let savePoints = annotation.savePoints()
  1840. var angle: CGFloat = 0
  1841. if savePoints.count >= 3 {
  1842. let count = savePoints.count
  1843. let startPoint = savePoints[count - 3].pointValue
  1844. let midPoint = savePoints[count - 2].pointValue
  1845. let endPoint = savePoints.last!.pointValue
  1846. angle = angleBetweenPoints(startPoint, midPoint, endPoint)
  1847. }
  1848. angle = 180 - angle
  1849. perimeterMeasureInfoWindowController?.angleLabel.stringValue = String(format: "%.2f°", abs(angle))
  1850. perimeterMeasureInfoWindowController?.reloadData(with: measureInfo!)
  1851. }
  1852. private func handlePolygonAnnotation(_ annotation: CPDFPolygonAnnotation) {
  1853. if distanceMeasureInfoWindowController?.window?.isVisible == true {
  1854. distanceMeasureInfoWindowController?.hideFloatingWindow()
  1855. areaMeasureInfoWindowController?.showWindow(self)
  1856. } else if perimeterMeasureInfoWindowController?.window?.isVisible == true {
  1857. perimeterMeasureInfoWindowController?.hideFloatingWindow()
  1858. areaMeasureInfoWindowController?.showWindow(self)
  1859. } else if areaMeasureInfoWindowController?.window?.isVisible == false {
  1860. areaMeasureInfoWindowController?.showWindow(self)
  1861. }
  1862. let measureInfo = annotation.measureInfo
  1863. let savePoints = annotation.savePoints
  1864. var angle: CGFloat = 0
  1865. if savePoints.count >= 3 {
  1866. let count = savePoints.count
  1867. let startPoint = (savePoints[count - 3] as AnyObject).pointValue
  1868. let midPoint = (savePoints[count - 2] as AnyObject).pointValue
  1869. let endPoint = (savePoints.lastObject as AnyObject).pointValue
  1870. angle = angleBetweenPoints(startPoint!, midPoint!, endPoint!)
  1871. }
  1872. angle = 180 - angle
  1873. areaMeasureInfoWindowController?.angleLabel.stringValue = String(format: "%.2f°", abs(angle))
  1874. areaMeasureInfoWindowController?.reloadData(measureInfo!)
  1875. }
  1876. private func angleBetweenPoints(_ startPoint: CGPoint, _ midPoint: CGPoint, _ endPoint: CGPoint) -> CGFloat {
  1877. let vector1 = CGPoint(x: midPoint.x - startPoint.x, y: midPoint.y - startPoint.y)
  1878. let vector2 = CGPoint(x: endPoint.x - midPoint.x, y: endPoint.y - midPoint.y)
  1879. let dotProduct = vector1.x * vector2.x + vector1.y * vector2.y
  1880. let magnitude1 = sqrt(vector1.x * vector1.x + vector1.y * vector1.y)
  1881. let magnitude2 = sqrt(vector2.x * vector2.x + vector2.y * vector2.y)
  1882. return acos(dotProduct / (magnitude1 * magnitude2)) * (180.0 / .pi)
  1883. }
  1884. @objc func pdfUpdatedFinish() {
  1885. splitPDFController?.inPDFFirst = false
  1886. splitPDFController?.outPDFFirst = false
  1887. }
  1888. }
  1889. //MARK: - KMNThumbnailBaseViewDelegate
  1890. extension KMMainViewController: KMNThumbnailBaseViewDelegate {
  1891. func clickThumbnailViewControlle(pageEditVC:KMNThumbnailBaseViewController?,currentIndex:Int) {
  1892. exitPageEditMode()
  1893. viewManager.isPageEditMode = false
  1894. pdfToolbarController?.reloadPageEditView()
  1895. }
  1896. func insertPDFThumbnailViewControlle(pageEditVC: KMNThumbnailBaseViewController?, pdfDocment: CPDFDocument?) {
  1897. if(pdfDocment != nil) {
  1898. insertDocuments.insert(pdfDocment!)
  1899. }
  1900. }
  1901. func changeIndexPathsThumbnailViewControlle(pageEditVC: KMNThumbnailBaseViewController?, selectionIndexPaths: Set<IndexPath>, selectionStrings: String) {
  1902. toolbarManager.page_pageInfo_Property.text = selectionStrings
  1903. if(toolbarManager.page_pageInfo_Property.creatable == false) {
  1904. toolbarManager.page_pageInfo_Property.creatable = true
  1905. }
  1906. pdfToolbarController?.refreshSecondToolbarItemsState()
  1907. }
  1908. }
  1909. extension KMMainViewController: KMNLeftSideViewControllerDelegate {
  1910. func enterPageEditLeftSideViewController(leftSideViewController: KMNLeftSideViewController) {
  1911. if viewManager.isPageEditMode == false {
  1912. viewManager.isPageEditMode = true
  1913. if(pdfToolbarController != nil) {
  1914. kmPDFToolbarControllerDidToolbarItemClicked(pdfToolbarController!, KMPDFToolbar_PageEdit_Identifier)
  1915. pdfToolbarController?.reloadSecondToolbar()
  1916. }
  1917. }
  1918. }
  1919. func changeSelectePageLeftSideViewController(leftSideViewController: KMNLeftSideViewController, pageIndex: Int) {
  1920. if(listView.currentPageIndex != pageIndex) {
  1921. listView.go(toPageIndex: pageIndex, animated: true)
  1922. }
  1923. }
  1924. }
  1925. //MARK: -
  1926. //MARK: -
  1927. //MARK: -
  1928. //MARK: - 旧代码,需要用到的内容需要拖出来,写好注释
  1929. extension KMMainViewController {
  1930. func awakeFromNibFunction() {
  1931. self.addBackgroundMaskView()
  1932. self.PDFContendView.backgroundColor(NSColor.km_init(hex: "FFFFFF"))
  1933. listView.delegate = self
  1934. listView.pdfListViewDelegate = self
  1935. if (document != nil) {
  1936. self.listView.document = self.document
  1937. self.listView.document?.delegate = self
  1938. let autoScale = listView.autoScales
  1939. if !autoScale {
  1940. listView.scaleFactor = 1.0
  1941. }
  1942. }
  1943. self.initPDFLeftViewVC()
  1944. self.initRightSideView()
  1945. self.toolbarController.listView = self.listView
  1946. self.toolbarController.mainViewController = self
  1947. self.leftSideViewController.mainViewController = self
  1948. self.newPDFSplitView.delegate = self
  1949. }
  1950. func viewDidAppearFunction() {
  1951. //春季活动
  1952. if ((KMAdvertisementManager.manager.info.popWindowContent) != nil) {
  1953. if KMAdvertisementManager.manager.info.popWindowContent!.content!.count > 0 {
  1954. let info = KMAdvertisementManager.manager.info.popWindowContent!.content?.first
  1955. if KMAdvertisementManager.checkAdvertisementValid(info!) {
  1956. self.loadRecommondPopWindow()
  1957. }
  1958. }
  1959. }
  1960. self.addEventMonitor()
  1961. self.view.window?.makeFirstResponder(self.listView)
  1962. // 更新属性页面的信息
  1963. NotificationCenter.default.post(name: KMInfoWindowC.windowDidBecomeMainNotification, object: self.myDocument)
  1964. self.interfaceThemeDidChanged(self.view.window?.appearance?.name ?? (NSApp.appearance?.name ?? .aqua))
  1965. if (self.document == nil) {
  1966. return
  1967. }
  1968. if (self.document == nil || self.document!.isLocked == false) {
  1969. self.loadFunctionGuide()
  1970. }
  1971. if (self.document?.isLocked == false) {
  1972. if self.model.needConvertNotes && self.tabViewIsDragging() == false {
  1973. self.showConvertNotesProgress()
  1974. }
  1975. return
  1976. }
  1977. if (self.view.window == nil) {
  1978. return
  1979. }
  1980. if (self.model.password != nil) {
  1981. if let data = self.listView.document?.unlock(withPassword: self.model.password), data {
  1982. self.model.isSaveKeyChain = false
  1983. if self.model.needConvertNotes && self.tabViewIsDragging() == false {
  1984. self.showConvertNotesProgress()
  1985. }
  1986. return
  1987. }
  1988. }
  1989. DispatchQueue.main.asyncAfter(deadline: DispatchTime.now() + 0.3) {
  1990. if self.view.window != nil && self.tabViewIsDragging() == false {
  1991. self.passwordWindow = KMPasswordInputWindow.openWindow(window: self.view.window!, url: self.document!.documentURL) { [weak self] result , password in
  1992. if (result == .cancel) {
  1993. (self?.myDocument as? KMMainDocument)?.browser?.closeTab()
  1994. return
  1995. }
  1996. self?.model.isSaveKeyChain = true
  1997. self?.listView.document = self?.document
  1998. self?.document?.unlock(withPassword: password)
  1999. }
  2000. } else {
  2001. if self.model.needConvertNotes && self.tabViewIsDragging() == false {
  2002. self.showConvertNotesProgress()
  2003. }
  2004. }
  2005. }
  2006. }
  2007. func viewWillDisappearFunction() {
  2008. if self.interactionMode != .presentation {
  2009. self.removeEventMonitor()
  2010. }
  2011. self.editPDFHanddler.hiddenWindows()
  2012. }
  2013. func viewWillLayoutFunction() {
  2014. if (KMTools.isFullScreen(self.view.window ?? NSWindow())) { // 全屏
  2015. self.listView.backgroundColor = KMPreferenceManager.shared.displayBackgroundFullScreenColor
  2016. } else {
  2017. self.listView.backgroundColor = KMPreferenceManager.shared.displayBackgroundNormalColor
  2018. }
  2019. if let guideWC = self.guideInfoWindowController{
  2020. var rect = self.view.window!.frame
  2021. rect.size.height -= 20
  2022. guideWC.window?.setFrame(rect, display: false)
  2023. guideWC.window?.minSize = rect.size
  2024. guideWC.window?.maxSize = rect.size
  2025. guideWC.show()
  2026. }
  2027. }
  2028. func viewDidLoadOld() {
  2029. mwcFlags.settingUpWindow = 1
  2030. toolbarController.delegate = self
  2031. self.editPDFHanddler.viewC = self
  2032. self.srHanddler.pdfView = self.listView
  2033. self.initToolbar()
  2034. if (UserDefaults.standard.object(forKey: CPDFOfficeLeftSidePaneWidthKey) != nil) {
  2035. UserDefaults.standard.set(256, forKey: CPDFOfficeLeftSidePaneWidthKey)
  2036. UserDefaults.standard.synchronize()
  2037. }
  2038. if (UserDefaults.standard.object(forKey: CPDFOfficeRightSidePaneWidthKey) != nil) {
  2039. UserDefaults.standard.set(256, forKey: CPDFOfficeRightSidePaneWidthKey)
  2040. UserDefaults.standard.synchronize()
  2041. }
  2042. let position = mianSplitView.maxPossiblePositionOfDivider(at: 1)
  2043. mianSplitView.setPosition(position, ofDividerAt: 0)
  2044. mianSplitView.setPosition(mianSplitView.minPossiblePositionOfDivider(at: 0), ofDividerAt: 0)
  2045. pdfSplitView.setPosition(mianSplitView.maxPossiblePositionOfDivider(at: 1), ofDividerAt: 0)
  2046. if (KMPreferenceManager.shared.openLastUnlockedDocumentWhenAppStart) {
  2047. if (self.listView.document != nil) {
  2048. let pageNumber = KMPreferenceManager.shared.getPageNumber(forKey: self.listView.document?.documentURL.path ?? "")
  2049. let pageScale = KMPreferenceManager.shared.getPageScale(forKey: self.listView.document?.documentURL.path ?? "")
  2050. if (pageNumber != nil && pageNumber! >= 0 && pageNumber! < (self.listView.document?.pageCount ?? 0)) {
  2051. DispatchQueue.main.asyncAfter(deadline: .now() + 0.5) {
  2052. if (pageScale != nil) {
  2053. self.listView.scaleFactor = CGFloat(pageScale!)
  2054. }
  2055. self.listView.go(toPageIndex: pageNumber!, animated: false)
  2056. }
  2057. } else {
  2058. self._goToFirstPageForFristAppear()
  2059. }
  2060. }
  2061. } else {
  2062. self._goToFirstPageForFristAppear()
  2063. }
  2064. pageNumberDisplayView.delegate = self
  2065. tipCurrentPageBox.moveCallback = { [unowned self] mouseEntered, mouseBox in
  2066. if !viewManager.isPDFReadMode {
  2067. if mouseEntered {
  2068. self.pageNumberDisplayView.hover = true
  2069. } else {
  2070. self.pageNumberDisplayView.hover = false
  2071. }
  2072. }
  2073. }
  2074. NotificationCenter.default.addObserver(self, selector: #selector(rename(_:)), name: NSNotification.Name.init(rawValue: "KMTabControllerRename"), object: nil)
  2075. NotificationCenter.default.addObserver(self, selector: #selector(closeTab(_:)), name: NSNotification.Name.init(rawValue: "KMTabControllerCloseTabs"), object: nil)
  2076. NotificationCenter.default.addObserver(self, selector: #selector(showInFinder(_:)), name: NSNotification.Name.init(rawValue: "KMTabControllerShowInFinder"), object: nil)
  2077. NotificationCenter.default.addObserver(self, selector: #selector(preferenceDidChangeNotification), name: KMPreferenceManager.didChangeNotification, object: nil)
  2078. NotificationCenter.default.addObserver(self, selector: #selector(documentDidUnlockNotification), name: Notification.Name("CPDFDocumentDidUnlockNotification"), object: nil)
  2079. NotificationCenter.default.addObserver(self, selector: #selector(annotationsAttributeHasChange), name: NSNotification.Name.CPDFListViewAnnotationsAttributeHasChange, object:nil)
  2080. NotificationCenter.default.addObserver(self, selector: #selector(applicationWillTerminateNotification), name: NSApplication.willTerminateNotification, object: nil)
  2081. NotificationCenter.default.addObserver(self, selector: #selector(CPDFDocumentPageCountChangedNotification), name: NSNotification.Name.init(rawValue: "CPDFDocumentPageCountChangedNotification"), object: nil)
  2082. NotificationCenter.default.addObserver(self, selector: #selector(CEditPDFToolModeChangeStateUnkownNotification), name: Notification.Name.init("CEditPDFToolModeChangeStateUnkown"), object: nil)
  2083. NotificationCenter.default.addObserver(self, selector: #selector(handlePageChangedNotification), name: NSNotification.Name.CPDFViewPageChanged, object: self.listView)
  2084. NotificationCenter.default.addObserver(self, selector: #selector(handleDisplayBoxChangedNotification), name: NSNotification.Name.CPDFViewDisplayBoxChanged, object: self.listView)
  2085. NotificationCenter.default.addObserver(self, selector: #selector(didAddContentViewNotification), name: NSWindow.didAddContentViewNotification, object: nil)
  2086. NotificationCenter.default.addObserver(self, selector: #selector(addAutoSaveEvent), name: AutoSaveManager.kTimeValueChangedNotificationName, object: nil)
  2087. NotificationCenter.default.addObserver(self, selector: #selector(didRemoveAnnotationNotification), name: NSNotification.Name.CPDFPageDidRemoveAnnotation, object: nil)
  2088. Task {
  2089. self.addAutoSaveEvent()
  2090. }
  2091. self.toolbarController.selectItem(KMDocumentAnnotationToolbarItemIdentifier)
  2092. self.closeRightPane()
  2093. self.addKeyEventMonitor()
  2094. self.addAdsBannerView()
  2095. var snapshotSetups: NSArray?
  2096. if KMPreferenceManager.shared.rememberSnapshot {
  2097. if let fileUrl = (self.myDocument as? KMMainDocument)?.fileURL {
  2098. snapshotSetups = SKBookmarkController.shared().snapshotsForRecentDocument(at: fileUrl) as NSArray?
  2099. }
  2100. }
  2101. if let cnt = snapshotSetups?.count, cnt > 0 {
  2102. if let data = self.listView.document?.isLocked, data {
  2103. self.savedNormalSetup.setObject(snapshotSetups as Any, forKey: "snapshots" as NSCopying)
  2104. } else {
  2105. self.showSnapshots(setups: snapshotSetups)
  2106. }
  2107. }
  2108. let readModel = UserDefaults.standard.bool(forKey: "kKMPDFViewIsReadMode")
  2109. if readModel == true {
  2110. self.openPDFReadMode()
  2111. }
  2112. let hasWindowSetup = savedNormalSetup.count > 0
  2113. if UserDefaults.standard.dictionary(forKey: KMDefaultPDFDisplaySettingsKey) != nil {
  2114. let pdfSettings: NSDictionary = hasWindowSetup ? savedNormalSetup : UserDefaults.standard.dictionary(forKey: KMDefaultPDFDisplaySettingsKey)! as NSDictionary
  2115. self.applyPDFSettings(pdfSettings)
  2116. } else {
  2117. self.applyPDFSettings(savedNormalSetup)
  2118. }
  2119. //文字
  2120. let fontManager = NSFontManager.shared
  2121. fontManager.target = self
  2122. fontManager.action = #selector(changeFont(_:))
  2123. }
  2124. //MARK: - PDFListView
  2125. func initPDFLeftViewVC() {
  2126. var frame = self.leftView.frame
  2127. frame.size.width += 44
  2128. self.leftView.frame = frame
  2129. leftSideViewController.isFirst = true
  2130. leftSideViewController.listView = self.listView
  2131. leftSideViewController.view.frame = CGRect(x: 0, y:0 , width: self.leftView.frame.size.width, height: self.leftView.frame.size.height)
  2132. leftSideViewController.view.autoresizingMask = [.height,.width]
  2133. leftSideViewController.delegate = self
  2134. self.leftView.addSubview(leftSideViewController.view)
  2135. }
  2136. func initRightSideView() {
  2137. self.rightSideViewController = KMRightSideViewController.init()
  2138. self.rightSideViewController.view.frame = CGRect(x: 0, y: 0, width: self.rightView.frame.width, height: self.rightView.frame.size.height)
  2139. self.rightSideViewController.view.autoresizingMask = [.height,.width]
  2140. self.rightSideViewController.listView = self.listView
  2141. self.rightSideViewController.isHidden = true
  2142. self.rightSideViewController.delegate = self
  2143. self.rightView.addSubview(self.rightSideViewController.view)
  2144. self.rightSideViewController.propertyDidChange = { [weak self] model in
  2145. if let anno = model as? CSelfSignAnnotation {
  2146. self?.leftSideViewController.refreshUIForAnnoAttributeDidChange(anno, attributes: nil)
  2147. }
  2148. }
  2149. }
  2150. func addAdsBannerView() {
  2151. #if VERSION_FREE
  2152. if !IAPProductsManager.default().isAvailableAllFunction(){
  2153. guard let document = self.listView.document else {
  2154. return
  2155. }
  2156. if !document.isLocked {
  2157. KMAdsManager.defaultManager.beginSheetModalForView(self.readContentView, directions: .down, adPosY: 30, animated: false) { pageIndex in
  2158. }
  2159. }
  2160. NotificationCenter.default.addObserver(self, selector: #selector(purchaseStateUpdateNoti), name: NSNotification.Name(rawValue: "KMIAPProductPurchasedNotification"), object: nil)
  2161. NotificationCenter.default.addObserver(self, selector: #selector(purchaseStateUpdateNoti), name: NSNotification.Name(rawValue: "kDeviceActivateNotification"), object: nil)
  2162. }
  2163. #endif
  2164. }
  2165. // MARK: Private Methods
  2166. private func _isArabicLanguage() -> Bool {
  2167. return NSLocalizedString("Right click a color and select “Change Color...“.", comment: "") == "انقر بزر الماوس الأيمن فوق اللون وحدد \"تغيير اللون...\"."
  2168. }
  2169. internal func removeNotifications() {
  2170. NotificationCenter.default.removeObserver(self)
  2171. self.leftSideViewController.clearAnnotationFilterData()
  2172. self.leftSideViewController.clearNotification()
  2173. }
  2174. func checkShouldAutoOpenLeftVC() {
  2175. if KMPreference.shared.showLeftSideBar == false {
  2176. return
  2177. }
  2178. if self.model.leftPanelOpen {
  2179. return
  2180. }
  2181. let readModel = UserDefaults.standard.bool(forKey: "kKMPDFViewIsReadMode")
  2182. if readModel == true {
  2183. return
  2184. }
  2185. DispatchQueue.main.async {
  2186. self.leftSideViewController.showThumbnail()
  2187. self.toolbarController.findItem(KMLeftControlToolbarItemIdentifier)?.isSelected = true
  2188. }
  2189. }
  2190. func applyLeftSideWidth(_ leftSideWidth: CGFloat, rightSideWidth: CGFloat) -> Void {
  2191. mianSplitView.setPosition(leftSideWidth, ofDividerAt: 0)
  2192. mianSplitView.setPosition(mianSplitView.maxPossiblePositionOfDivider(at: 1) - mianSplitView.dividerThickness - rightSideWidth, ofDividerAt: 1)
  2193. self.model.lastLeftPanWidth = leftSideWidth
  2194. self.model.lastRightPanWidth = rightSideWidth
  2195. }
  2196. func removeAllAnnotations() {
  2197. let alert = NSAlert()
  2198. alert.messageText = NSLocalizedString("This will permanently remove all annotations. Are you sure to continue?", comment: "")
  2199. alert.addButton(withTitle: NSLocalizedString("Yes", comment:""))
  2200. alert.addButton(withTitle: NSLocalizedString("No", comment:""))
  2201. if (alert.runModal() != .alertFirstButtonReturn) {
  2202. return
  2203. }
  2204. DispatchQueue.main.async {
  2205. self.removeAllAnnotationsStore.store(t: self.listView)
  2206. }
  2207. }
  2208. @objc func cancelMeasureType() {
  2209. self.hideMeasureFloatingWindows()
  2210. self.toolbarController?.findItem(KMToolbarMeasureItemIdentifier)?.isSelected = false
  2211. }
  2212. func hideMeasureFloatingWindows() {
  2213. if distanceMeasureInfoWindowController?.window?.isVisible == true {
  2214. distanceMeasureInfoWindowController?.hideFloatingWindow()
  2215. } else if perimeterMeasureInfoWindowController?.window?.isVisible == true {
  2216. perimeterMeasureInfoWindowController?.hideFloatingWindow()
  2217. } else if areaMeasureInfoWindowController?.window?.isVisible == true {
  2218. areaMeasureInfoWindowController?.hideFloatingWindow()
  2219. }
  2220. }
  2221. func showMeasureFloatingWindowsIfNeed() {
  2222. let toolMode = self.listView.toolMode
  2223. if toolMode != .measureToolMode {
  2224. return
  2225. }
  2226. let type = self.listView.annotationType
  2227. if type == .line {
  2228. self.distanceMeasureInfoWindowController?.window?.orderFront(nil)
  2229. } else if type == .polyLine {
  2230. self.perimeterMeasureInfoWindowController?.window?.orderFront(nil)
  2231. } else if type == .polyGon {
  2232. self.areaMeasureInfoWindowController?.window?.orderFront(nil)
  2233. } else if type == .square {
  2234. self.areaMeasureInfoWindowController?.window?.orderFront(nil)
  2235. }
  2236. }
  2237. // MARK: - 标记密文
  2238. func enterRedact() {
  2239. if !IAPProductsManager.default().isAvailableAllFunction(){
  2240. let winC = KMPurchaseCompareWindowController.sharedInstance()
  2241. winC?.kEventName = "Reading_Redact_BuyNow"
  2242. winC?.showWindow(nil)
  2243. return
  2244. }
  2245. if self.listView.document?.allowsPrinting == false || self.listView.document?.allowsCopying == false {
  2246. Task {
  2247. _ = await KMAlertTool.runModel(message: KMLocalizedString("This is a secured document. Editing is not permitted."))
  2248. }
  2249. return
  2250. }
  2251. if self.hasEnterRedact() {
  2252. self.exitRedact()
  2253. return
  2254. }
  2255. self.commitEditingIfNeed()
  2256. self.leftSideViewController.thumbnailTableView.isEnabled = false
  2257. self.leftSideViewController.tocOutlineView.isEnabled = false
  2258. self.leftSideViewController.noteOutlineView.isEnabled = false
  2259. self.leftSideViewController.findTableView.isEnabled = false
  2260. self.leftSideViewController.groupedFindTableView.isEnabled = false
  2261. self.leftSideViewController.snapshotTableView.isEnabled = false
  2262. let ttsWindowC = KMTTSWindowController.share
  2263. if ttsWindowC.pdfView?.document?.documentURL.path == self.listView.document?.documentURL.path {
  2264. if let data = ttsWindowC.window?.isVisible, data {
  2265. ttsWindowC.stopSpeaking()
  2266. ttsWindowC.close()
  2267. }
  2268. }
  2269. NSColorPanel.shared.showsAlpha = false
  2270. redactController = KMPDFRedactViewController(url: self.listView.document!.documentURL, password: self.listView.document?.password)
  2271. self.addChild(redactController)
  2272. self.PDFContendView.addSubview(redactController.view)
  2273. redactController.view.frame = self.PDFContendView.bounds
  2274. redactController.view.autoresizingMask = [.width, .height]
  2275. self.listView.isHidden = true
  2276. redactController.scaleFactor = self.listView.scaleFactor
  2277. redactController.titleBack = { [weak self] title in
  2278. self?.view.window?.title = title
  2279. }
  2280. redactController.callback = { [weak self] result, currentPageIndex, saveResult, saveUrl in
  2281. self?.listView.go(toPageIndex: self!.redactController.redactPdfView.currentPageIndex, animated: false)
  2282. if result == false { // 退出
  2283. self?.exitRedact()
  2284. return
  2285. }
  2286. let controller = self?._getPDFRedactController()
  2287. controller?.redactPdfView.newAddAnnotation.removeAll()
  2288. self?.exitRedact()
  2289. if saveResult {
  2290. let newDocument = CPDFDocument(url: saveUrl)
  2291. if let data = newDocument?.isLocked, data {
  2292. newDocument?.unlock(withPassword: self?.listView.document?.password ?? "")
  2293. }
  2294. self?.document = newDocument
  2295. self?.listView.document = newDocument
  2296. self?.listView.layoutDocumentView()
  2297. }
  2298. }
  2299. redactController.setCurrentPageIndex(self.listView.currentPageIndex)
  2300. }
  2301. func exitRedact() {
  2302. self.leftSideViewController.thumbnailTableView.isEnabled = true
  2303. self.leftSideViewController.tocOutlineView.isEnabled = true
  2304. self.leftSideViewController.noteOutlineView.isEnabled = true
  2305. self.leftSideViewController.findTableView.isEnabled = true
  2306. self.leftSideViewController.groupedFindTableView.isEnabled = true
  2307. self.leftSideViewController.snapshotTableView.isEnabled = true
  2308. let controller = self._getPDFRedactController()
  2309. if let data = controller {
  2310. if data.redactPdfView.newAddAnnotation.count > 0 {
  2311. KMAlertTool.runModel(message: "", informative: KMLocalizedString("There are unapplied redactions in this file. Exit will not save redaction."), buttons: [KMLocalizedString("Exit"), KMLocalizedString("Cancel")]) { response in
  2312. if response == .alertFirstButtonReturn {
  2313. controller?.redactPdfView.newAddAnnotation.removeAll()
  2314. self.exitRedact()
  2315. }
  2316. }
  2317. return
  2318. }
  2319. }
  2320. NSColorPanel.shared.showsAlpha = true
  2321. self.toolbarController.findItem(KMDocumentRedactToolbarItemIdentifier)?.isSelected = false
  2322. controller?.redactPdfView.resignMonitor()
  2323. controller?.view.removeFromSuperview()
  2324. controller?.removeFromParent()
  2325. self.listView.isHidden = false
  2326. self.listView.annotationType = .unkown
  2327. }
  2328. func hasEnterRedact() -> Bool {
  2329. return self._getPDFRedactController() != nil
  2330. }
  2331. //MARK: - AI
  2332. func showAITypeChooseView(aiConfigType: AIConfigType) -> Void {
  2333. if (self.document != nil) {
  2334. AIChatInfoManager.defaultManager.currentFilePath = (self.document?.documentURL.path)!
  2335. } else {
  2336. AIChatInfoManager.defaultManager.currentFilePath = ""
  2337. }
  2338. let windowVC: AINewConfigWindowController = AINewConfigWindowController.currentWC()
  2339. windowVC.chooseCurFileHandle = {[unowned self] windowVC in
  2340. if AIChatInfoManager.defaultManager.currentFilePath.isEmpty == false {
  2341. let documentArray = NSDocumentController.shared.documents
  2342. var didFileEdit: Bool = false
  2343. var curDoc: KMMainDocument!
  2344. for document in documentArray {
  2345. if document.fileURL?.path == AIChatInfoManager.defaultManager.currentFilePath {
  2346. didFileEdit = document.isDocumentEdited
  2347. curDoc = document as! KMMainDocument
  2348. break
  2349. }
  2350. }
  2351. if didFileEdit {
  2352. let tempFileURL = FileManager.default.temporaryDirectory.appendingPathComponent(AIChatInfoManager.defaultManager.currentFilePath.lastPathComponent)
  2353. if FileManager.default.fileExists(atPath: tempFileURL.path) {
  2354. do {
  2355. try FileManager.default.removeItem(at: tempFileURL)
  2356. } catch {
  2357. }
  2358. }
  2359. if curDoc != nil {
  2360. curDoc.mainViewController?.SaveTempPDFDocumentToURLPath(tempPath: tempFileURL.path)
  2361. }
  2362. }
  2363. windowVC.window?.becomeMain()
  2364. }
  2365. }
  2366. if windowVC.window?.isVisible == true && windowVC.didSetOriginFrame == true {
  2367. } else {
  2368. var windowRect = windowVC.window?.frame
  2369. windowRect!.origin.x = NSMaxX(self.view.window!.frame) - (windowRect?.size.width)!
  2370. windowRect!.origin.y = NSMaxY(self.view.window!.frame) - (windowRect?.size.height)! - 64
  2371. windowVC.window?.setFrame(windowRect!, display: true)
  2372. windowVC.didSetOriginFrame = true
  2373. }
  2374. windowVC.eventLabel = "AITools_Tbr"
  2375. windowVC.showWindow(nil)
  2376. if (aiConfigType != .none) {
  2377. windowVC.eventLabel = "AITools_Start"
  2378. if self.listView.currentSelection?.string()?.isEmpty == false {
  2379. windowVC.setCurrentPDFSelection(self.listView.currentSelection.string())
  2380. }
  2381. windowVC.chooseAIFunctionWithType(aiConfigType)
  2382. }
  2383. }
  2384. @objc func aiTipIconViewShowStateChangeNoti() {
  2385. }
  2386. //MARK: - 引导
  2387. func loadFunctionGuide() -> Void {
  2388. DispatchQueue.main.asyncAfter(deadline: DispatchTime.now() + 1) {
  2389. if self.view.window != nil {
  2390. self.loadOpenFileFunctionGuide(.openFileNormal)
  2391. }
  2392. }
  2393. }
  2394. func loadOpenFileFunctionGuide(_ showType: KMGuideInfoType) -> Void {
  2395. if showType == .openFileNormal && KMGuideInfoWindowController.availableShow(.openFileNormal) {
  2396. let leftPanelItem:KMToolbarItemView = self.toolbarController.findItem("KMLeftControlToolbarItemIdentifier")!
  2397. self.guideInfoWindowController = KMGuideInfoWindowController.currentWC()
  2398. guard let guideWC = self.guideInfoWindowController else { return }
  2399. guideWC.type = .openFileNormal
  2400. guideWC.openPanelRect = (self.view.window?.contentView?.convert(leftPanelItem.frame, from: leftPanelItem.superview)) ?? .zero
  2401. guideWC.window?.collectionBehavior = [.canJoinAllSpaces]
  2402. guideWC.normalGuideFinishHandle = { [weak self] windowVC in
  2403. let rightPanelItem = self?.toolbarController.findItem(KMRightControlToolbarItemIdentifier)
  2404. let digitalPanelItem = self?.toolbarController.findItem(KMDocumentSignToolbarItemIdentifier)
  2405. if let data = rightPanelItem, data.isHidden {
  2406. let view = self?.toolbarController.mainToolBarView?.toolbar?.moreButton
  2407. windowVC.rightPanelRect = (self?.view.window?.contentView?.convert(view?.frame ?? .zero, from: view?.superview)) ?? .zero
  2408. } else {
  2409. windowVC.rightPanelRect = (self?.view.window?.contentView?.convert(rightPanelItem?.frame ?? .zero, from: rightPanelItem?.superview)) ?? .zero
  2410. }
  2411. guideWC.digitalBoxRect = (self?.view.window?.contentView?.convert(digitalPanelItem?.frame ?? .zero, from: digitalPanelItem?.superview)) ?? .zero
  2412. }
  2413. guideWC.finishHandle = { [weak self] windowVC, type in
  2414. if type == .windowNewFinish ||
  2415. type == . windowDigitalFinish {
  2416. self?.checkFirstTrialController()
  2417. }
  2418. }
  2419. guideWC.openFileToggleHandle = { [weak self] windowVC, type in
  2420. self?.checkFirstTrialController()
  2421. }
  2422. var rect = self.view.window!.frame
  2423. rect.size.height -= 20
  2424. guideWC.window?.setFrame(rect, display: false)
  2425. guideWC.window?.minSize = rect.size
  2426. guideWC.window?.maxSize = rect.size
  2427. self.view.window?.addChildWindow(guideWC.window!, ordered: .above)
  2428. guideWC.show()
  2429. } else if showType == .digitalSignGuide && KMGuideInfoWindowController.availableShow(.digitalSignGuide) {
  2430. self.guideInfoWindowController = KMGuideInfoWindowController.currentWC()
  2431. guard let guideWC = self.guideInfoWindowController else { return }
  2432. guideWC.type = .digitalSignGuide
  2433. guard let digitalPanelItem = self.toolbarController.findItem(KMDocumentSignToolbarItemIdentifier) else {
  2434. return
  2435. }
  2436. guideWC.digitalBoxRect = (self.view.window?.contentView?.convert(digitalPanelItem.frame, from: digitalPanelItem.superview))!
  2437. guideWC.window?.collectionBehavior = [.canJoinAllSpaces]
  2438. guideWC.finishHandle = { [weak self] windowVC, type in
  2439. self?.checkFirstTrialController()
  2440. }
  2441. var rect = self.view.window!.frame
  2442. rect.size.height -= 20
  2443. guideWC.window?.setFrame(rect, display: false)
  2444. guideWC.window?.minSize = rect.size
  2445. guideWC.window?.maxSize = rect.size
  2446. self.view.window?.addChildWindow(guideWC.window!, ordered: .above)
  2447. guideWC.show()
  2448. } else if showType == .pdfCompareGuide && KMGuideInfoWindowController.availableShow(.pdfCompareGuide) {
  2449. DispatchQueue.main.asyncAfter(deadline: DispatchTime.now() + 0.2) {
  2450. self.guideInfoWindowController = KMGuideInfoWindowController.currentWC()
  2451. guard let guideWC = self.guideInfoWindowController else { return }
  2452. guideWC.type = .pdfCompareGuide
  2453. guard let digitalPanelItem = self.toolbarController.findItem(KMDocumentSignToolbarItemIdentifier) else {
  2454. return
  2455. }
  2456. guard let win = self.view.window else {
  2457. return
  2458. }
  2459. guideWC.digitalBoxRect = (win.contentView?.convert(digitalPanelItem.frame, from: digitalPanelItem.superview)) ?? .zero
  2460. let compareItem = self.toolbarController.findItem(KMToolbarComparisonItemIdentifier)
  2461. guideWC.compareItemRect = (win.contentView?.convert(compareItem?.frame ?? .zero, from: compareItem?.superview)) ?? .zero
  2462. guideWC.finishHandle = { [weak self] winC, type in
  2463. if type == .windowNewFinish {
  2464. DispatchQueue.main.async {
  2465. self?.loadOpenFileFunctionGuide(.measureGuide)
  2466. }
  2467. return
  2468. }
  2469. }
  2470. guideWC.window?.collectionBehavior = [.canJoinAllSpaces]
  2471. var rect = self.view.window!.frame
  2472. rect.size.height -= 20
  2473. guideWC.window?.setFrame(rect, display: false)
  2474. guideWC.window?.minSize = rect.size
  2475. guideWC.window?.maxSize = rect.size
  2476. self.view.window?.addChildWindow(guideWC.window!, ordered: .above)
  2477. guideWC.show()
  2478. }
  2479. } else if showType == .measureGuide && KMGuideInfoWindowController.availableShow(.measureGuide) {
  2480. DispatchQueue.main.asyncAfter(deadline: DispatchTime.now() + 0.2) {
  2481. self.guideInfoWindowController = KMGuideInfoWindowController.currentWC()
  2482. guard let guideWC = self.guideInfoWindowController else { return }
  2483. guard let _ = self.view.window else {
  2484. return
  2485. }
  2486. guideWC.type = .measureGuide
  2487. guard let digitalPanelItem = self.toolbarController.findItem(KMDocumentSignToolbarItemIdentifier) else {
  2488. return
  2489. }
  2490. guideWC.digitalBoxRect = (self.view.window?.contentView?.convert(digitalPanelItem.frame, from: digitalPanelItem.superview)) ?? .zero
  2491. let compareItem:KMToolbarItemView = self.toolbarController.findItem(KMToolbarMeasureItemIdentifier)!
  2492. guideWC.compareItemRect = (self.view.window?.contentView?.convert(compareItem.frame, from: compareItem.superview)) ?? .zero
  2493. guideWC.window?.collectionBehavior = [.canJoinAllSpaces]
  2494. var rect = self.view.window?.frame ?? .zero
  2495. rect.size.height -= 20
  2496. guideWC.window?.setFrame(rect, display: false)
  2497. guideWC.window?.minSize = rect.size
  2498. guideWC.window?.maxSize = rect.size
  2499. self.view.window?.addChildWindow(guideWC.window!, ordered: .above)
  2500. guideWC.show()
  2501. }
  2502. } else if showType == .convertGuide && KMGuideInfoWindowController.availableShow(.convertGuide) {
  2503. DispatchQueue.main.asyncAfter(deadline: DispatchTime.now() + 1) {
  2504. self.guideInfoWindowController = KMGuideInfoWindowController.currentWC()
  2505. guard let guideWC = self.guideInfoWindowController else { return }
  2506. guideWC.type = .convertGuide
  2507. guard let digitalPanelItem = self.toolbarController.findItem(KMDocumentSignToolbarItemIdentifier) else {
  2508. return
  2509. }
  2510. guard let win = self.view.window else {
  2511. return
  2512. }
  2513. guideWC.digitalBoxRect = (self.view.window?.contentView?.convert(digitalPanelItem.frame, from: digitalPanelItem.superview)) ?? .zero
  2514. guideWC.purchaseHandle = { [weak self] windowVC in
  2515. #if VERSION_DMG
  2516. if IAPProductsManager.default().isAvailableAllFunction() {
  2517. if IAPProductsManager.default().isAvailableAdvancedPDFToOffice() {
  2518. //Convert:
  2519. self?.showAllConvertWindow(convertT: .Word)
  2520. } else {
  2521. let limitWC = KMPurchaseLimitWindowController.currentLimitWC()
  2522. limitWC.continueBlock = { windowController in
  2523. }
  2524. limitWC.window?.center()
  2525. limitWC.showWindow(nil)
  2526. }
  2527. } else {
  2528. KMPurchaseCompareWindowController.sharedInstance().showWindow(nil)
  2529. }
  2530. #else
  2531. if IAPProductsManager.default().isAvailableAllFunction() {
  2532. if IAPProductsManager.default().isAvailableAdvancedPDFToOffice() {
  2533. //Convert:
  2534. } else {
  2535. var vc = KMToolCompareWindowController(toolType: .Convert, selectNum: 1)
  2536. vc.showWindow(nil)
  2537. }
  2538. } else {
  2539. KMPurchaseCompareWindowController.sharedInstance().showWindow(nil)
  2540. }
  2541. #endif
  2542. }
  2543. guideWC.window?.collectionBehavior = [.canJoinAllSpaces]
  2544. var rect = self.view.window?.frame ?? .zero
  2545. rect.size.height -= 20
  2546. guideWC.window?.setFrame(rect, display: false)
  2547. guideWC.window?.minSize = rect.size
  2548. guideWC.window?.maxSize = rect.size
  2549. self.view.window?.addChildWindow(guideWC.window!, ordered: .above)
  2550. guideWC.show()
  2551. }
  2552. } else {
  2553. }
  2554. }
  2555. func checkFirstTrialController() -> Void {
  2556. #if VERSION_DMG
  2557. //打开文档后引导相关
  2558. if VerificationManager.default().status == .none {
  2559. let appVersion = Bundle.main.infoDictionary?["CFBundleShortVersionString"] as? String ?? ""
  2560. let lastVersion = UserDefaults.standard.object(forKey: "SKLastTrialVersionMainDocumentLaunchedKey") as? String ?? ""
  2561. if lastVersion.isEmpty || lastVersion != appVersion {
  2562. UserDefaults.standard.setValue(appVersion, forKey: "SKLastTrialVersionMainDocumentLaunchedKey")
  2563. UserDefaults.standard.synchronize()
  2564. KMPurchaseCompareWindowController.sharedInstance().showWindow(nil)
  2565. }
  2566. }
  2567. #endif
  2568. }
  2569. // MARK: - 页面编辑
  2570. open func enterPageEdit(_ pages: [Int] = []) {
  2571. if let doc = self.listView.document {
  2572. if doc.allowsCopying == false || doc.allowsPrinting == false {
  2573. KMBaseWindowController.checkPassword(url: doc.documentURL, type: .owner) { result, pwd in
  2574. if result && pwd.isEmpty == false {
  2575. self.listView.document?.unlock(withPassword: pwd)
  2576. Task { @MainActor in
  2577. self.enterPageEdit(pages)
  2578. }
  2579. } else {
  2580. self.exitPageEdit()
  2581. }
  2582. }
  2583. return
  2584. }
  2585. }
  2586. //选中page
  2587. var tPages = pages
  2588. if tPages.count == 0 {
  2589. if self.leftSideViewController.type.methodType == .Thumbnail {
  2590. tPages = self.leftSideViewController.thumb_fetchSelectedRows() ?? [self.listView.currentPageIndex]
  2591. }
  2592. }
  2593. if (hasEnterPageEdit()) {
  2594. exitPageEdit()
  2595. return
  2596. }
  2597. if (self.toolbarController != nil && self.toolbarController.mainToolBarView != nil) {
  2598. let toolBarView: KMToolbarViewController = self.toolbarController.mainToolBarView!
  2599. for (key, value) in toolBarView.toolbarItems {
  2600. if (key == KMRightControlToolbarItemIdentifier || key == KMLeftControlToolbarItemIdentifier) {
  2601. (value as! KMToolbarItemView).unEnabled = true
  2602. }
  2603. }
  2604. }
  2605. self.editPDFHanddler.clearData()
  2606. let controller = KMPDFEditViewController(self.listView.document)
  2607. controller.selectedPages = tPages
  2608. controller.listView = self.listView
  2609. self.addChild(controller)
  2610. self.PDFContendView.addSubview(controller.view)
  2611. controller.view.frame = self.PDFContendView.bounds
  2612. controller.view.autoresizingMask = [.width,.height]
  2613. self.listView.isHidden = true
  2614. controller.itemClick = { [weak self] index, params in
  2615. if (index == 1) { /// 双击退出
  2616. self?.enterEditMode(self!.leftSideViewController, [])
  2617. DispatchQueue.main.async {
  2618. let pageIndex: Int = params.first as! Int
  2619. self?.listView.go(toPageIndex: pageIndex, animated: true)
  2620. }
  2621. } else if (index == 2) { // 打印
  2622. self?.showPrintWindow(pageRange: KMPrintPageRange(type: .custom, selectPages: params.first as! [Int]))
  2623. }
  2624. }
  2625. controller.documentEditedCallback = { [weak self] params in
  2626. self?.recordIsPDFDocumentEdited()
  2627. }
  2628. controller.selectionDidChange = { selectedIndexs in
  2629. var indexSet = IndexSet()
  2630. for indexPath in selectedIndexs {
  2631. indexSet.insert(indexPath.item)
  2632. }
  2633. if indexSet.count != 0 {
  2634. }
  2635. }
  2636. }
  2637. open func exitPageEdit() {
  2638. if (self.toolbarController != nil && self.toolbarController.mainToolBarView != nil) {
  2639. let toolBarView: KMToolbarViewController = self.toolbarController.mainToolBarView!
  2640. for (key, value) in toolBarView.toolbarItems {
  2641. if (key == KMRightControlToolbarItemIdentifier || key == KMLeftControlToolbarItemIdentifier) {
  2642. (value as! KMToolbarItemView).unEnabled = false
  2643. }
  2644. }
  2645. }
  2646. self.toolbarController.findItem(KMDocumentPageToolbarItemIdentifier)?.isSelected = false
  2647. let editController = getPDFEditController()
  2648. if (editController == nil) {
  2649. return
  2650. }
  2651. self.listView.annotationType = .highlight
  2652. // FIXME: - sdk修复插入特定文档crash后,这行代码可以去掉
  2653. self.leftSideViewController.model.insertedDocumentSet.formUnion(editController?.model.insertedDocumentSet ?? [])
  2654. editController?.view.removeFromSuperview()
  2655. editController?.removeFromParent()
  2656. self.listView.isHidden = false
  2657. self.listView.layoutDocumentView()
  2658. self.view.window?.makeFirstResponder(self.listView)
  2659. self.listView.annotationType = .unkown
  2660. self.listView.go(toPageIndex: editController!.listViewCurrentIndex, animated: false)
  2661. if let data = editController?.isEdited, data {
  2662. self.leftSideViewController.reloadThumbnailDataIfNeed()
  2663. self.leftSideViewController.note_reloadDataIfNeed()
  2664. self.leftSideViewController.refreshUIOfOutlineIfNeed()
  2665. self.leftSideViewController.refreshUIOfSeachListIfNeed()
  2666. self.leftSideViewController.refreshUIOfBookmarkIfNeed()
  2667. }
  2668. }
  2669. open func hasEnterPageEdit() -> Bool {
  2670. return self.getPDFEditController() != nil
  2671. }
  2672. // MARK: - Edit PDF
  2673. func enterEditPDF() {
  2674. self.editPDFHanddler.enterEditPDF()
  2675. }
  2676. // MARK: - 数字签名
  2677. func hasShowDigitalSign() -> Bool {
  2678. return self.digitalSignController?.view.superview != nil
  2679. }
  2680. func canEnterDigitalSign() -> Bool {
  2681. guard let doc = self.listView.document else {
  2682. return false
  2683. }
  2684. return doc.allowsPrinting && doc.allowsCopying
  2685. }
  2686. func enterDigitalSign() {
  2687. self.listView.toolMode = .textToolMode
  2688. if self.hasShowDigitalSign() {
  2689. self.exitDigitalSign()
  2690. } else {
  2691. if self.needSaveDocument() {
  2692. self.saveDocumentWithProgressAlert { [unowned self] params in
  2693. if (self.listView.document != nil) {
  2694. self.showDigitalSignWindow(withFilePathURL: self.listView.document.documentURL)
  2695. }
  2696. }
  2697. return
  2698. }
  2699. if (self.listView.document != nil) {
  2700. self.showDigitalSignWindow(withFilePathURL: self.listView.document.documentURL)
  2701. }
  2702. }
  2703. }
  2704. func exitDigitalSign() {
  2705. self.digitalSignController?.view.removeFromSuperview()
  2706. // KMDocumentDigitalSignToolbarItemIdentifier
  2707. self.toolbarController.findItem(KMDocumentSignToolbarItemIdentifier)?.isSelected = false
  2708. }
  2709. func showDigitalSignWindow(withFilePathURL fileURL: URL) {
  2710. if !IAPProductsManager.default().isAvailableAllFunction(){
  2711. let winC = KMPurchaseCompareWindowController.sharedInstance()
  2712. winC?.kEventName = "Reading_DigitalSign_BuyNow"
  2713. winC?.showWindow(nil)
  2714. return
  2715. }
  2716. if hasShowDigitalSign() {
  2717. self.exitDigitalSign()
  2718. }
  2719. var currentPageIndex = listView.document?.index(for: listView.currentPage()) ?? 0
  2720. var password: String = ""
  2721. self.toolbarController.toolbarType = .None
  2722. password = listView.document?.password ?? ""
  2723. digitalSignController = KMPDFDigitalSignViewController()
  2724. digitalSignController?.currentPageIndex = Int(currentPageIndex)
  2725. digitalSignController?.url = listView.document?.documentURL
  2726. digitalSignController?.password = password
  2727. digitalSignController?.scaleFactor = listView.scaleFactor
  2728. digitalSignController?.titleChangeBlock = { title, index in
  2729. currentPageIndex = UInt(index)
  2730. }
  2731. digitalSignController?.buttonActionBlock = { [weak self] type, isChanged in
  2732. if type == .cancel {
  2733. if let page = self?.listView.document?.page(at: currentPageIndex) {
  2734. self?.listView.go(to: page)
  2735. }
  2736. self?.exitDigitalSign()
  2737. }
  2738. }
  2739. if let digitalSignView = digitalSignController?.view, let splitViewSuperview = mianSplitView.superview {
  2740. digitalSignView.frame = splitViewSuperview.bounds
  2741. digitalSignView.autoresizingMask = [.width, .height]
  2742. splitViewSuperview.addSubview(digitalSignView)
  2743. digitalSignController?.setCurrentPageIndex(Int(currentPageIndex))
  2744. }
  2745. }
  2746. // MARK: - Toolbar
  2747. func toolbarItemClickForExitMode(_ toolbarItem: KMToolbarItemView) {
  2748. if(toolbarItem.itemIdentifier != KMDocumentPageToolbarItemIdentifier) {
  2749. if (hasEnterPageEdit()) {
  2750. self.exitPageEdit()
  2751. }
  2752. }
  2753. if toolbarItem.itemIdentifier != KMDocumentRedactToolbarItemIdentifier {
  2754. if self.hasEnterRedact() {
  2755. self.exitRedact()
  2756. }
  2757. }
  2758. if toolbarItem.itemIdentifier != KMDocumentDigitalSignToolbarItemIdentifier {
  2759. if self.hasShowDigitalSign() {
  2760. self.exitDigitalSign()
  2761. }
  2762. }
  2763. if toolbarItem.itemIdentifier != KMDocumentEditToolbarItemIdentifier && toolbarItem.itemIdentifier != KMRightControlToolbarItemIdentifier && toolbarItem.itemIdentifier != KMLeftControlToolbarItemIdentifier {
  2764. self.commitEditingIfNeed()
  2765. }
  2766. }
  2767. // MARK: - Private Methods
  2768. private func getPDFEditController() -> KMPDFEditViewController? {
  2769. var editController: KMPDFEditViewController?
  2770. for controller in self.children {
  2771. if (controller.isKind(of: KMPDFEditViewController.self)) {
  2772. editController = (controller as! KMPDFEditViewController)
  2773. break
  2774. }
  2775. }
  2776. return editController
  2777. }
  2778. private func _getPDFRedactController() -> KMPDFRedactViewController? {
  2779. var controller: KMPDFRedactViewController?
  2780. for childC in self.children {
  2781. if (childC.isKind(of: KMPDFRedactViewController.self)) {
  2782. controller = (childC as! KMPDFRedactViewController)
  2783. break
  2784. }
  2785. }
  2786. return controller
  2787. }
  2788. private func addBackgroundMaskView() {
  2789. self.removeBackgroundMaskView()
  2790. if let superview = self.mianSplitView.superview {
  2791. let view = NSView()
  2792. superview.addSubview(view)
  2793. view.frame = superview.bounds
  2794. view.autoresizingMask = [.width, .height]
  2795. view.wantsLayer = true
  2796. view.layer?.backgroundColor = .white
  2797. self.background_mask = view
  2798. }
  2799. }
  2800. private func removeBackgroundMaskView() {
  2801. self.background_mask?.removeFromSuperview()
  2802. self.background_mask = nil
  2803. }
  2804. private func _goToFirstPageForFristAppear() {
  2805. DispatchQueue.main.asyncAfter(wallDeadline: .now()+0.1) {
  2806. self.listView.go(toPageIndex: 0, animated: false)
  2807. }
  2808. }
  2809. func isPDFPageCountExceedsLimit(filePath: String) -> Bool {
  2810. let url = URL(fileURLWithPath: filePath)
  2811. guard let document = PDFDocument(url: url) else {
  2812. return false
  2813. }
  2814. let pageCount = document.pageCount
  2815. return pageCount > 30
  2816. }
  2817. // MARK: - Redact 【标记密文】
  2818. func exeRedactConfirm(_ type: KMRedactConfirmType, callback: @escaping () -> ()?) {
  2819. let windowController = KMRedactConfirmWindowController(type)
  2820. self.currentWindowController = windowController
  2821. self.view.window?.beginSheet(windowController.window!)
  2822. windowController.itemClick = { [weak self] index in
  2823. if (index == 2) { /// 取消
  2824. self?.view.window?.endSheet((self?.currentWindowController.window)!)
  2825. self?.currentWindowController = nil
  2826. callback()
  2827. return
  2828. }
  2829. self?.view.window?.endSheet((self?.currentWindowController.window)!)
  2830. self?.currentWindowController = nil
  2831. let panel = NSSavePanel()
  2832. panel.nameFieldStringValue = "[新文件]"+((self?.listView.document?.documentURL.lastPathComponent) ?? "")
  2833. let button = NSButton.init(checkboxWithTitle: "保存后打开文档", target: nil, action: nil)
  2834. button.state = .on
  2835. panel.accessoryView = button
  2836. panel.isExtensionHidden = true
  2837. panel.beginSheetModal(for: (self?.view.window!)!) { response in
  2838. if response != .OK {
  2839. callback()
  2840. return
  2841. }
  2842. if (type == .redactOne) {
  2843. let anno = self!.listView.activeAnnotation
  2844. if (anno == nil || (anno?.isKind(of: CPDFRedactAnnotation.self)) == false) {
  2845. callback()
  2846. return
  2847. }
  2848. (anno as! CPDFRedactAnnotation).applyRedaction()
  2849. } else if (type == .redactAll) {
  2850. self?.listView.document?.applyRedactions()
  2851. } else if (type == .eraserOne) {
  2852. let anno = self!.listView.activeAnnotation
  2853. if (anno == nil || (anno?.isKind(of: CPDFRedactAnnotation.self)) == false) {
  2854. callback()
  2855. return
  2856. }
  2857. anno?.page.erasureRedact(from: anno!.bounds)
  2858. } else if (type == .eraserAll) {
  2859. KMRedactTools.eraserDocument((self?.listView.document)!) { result, errorAnno in
  2860. if (result == false) {
  2861. callback()
  2862. return
  2863. }
  2864. }
  2865. }
  2866. self!.listView.document?.write(to: panel.url)
  2867. if (button.state == .on) {
  2868. NSDocumentController.shared.openDocument(withContentsOf: panel.url!, display: true) { document, alreadyOpen, error in
  2869. }
  2870. } else {
  2871. NSWorkspace.shared.activateFileViewerSelecting([panel.url!])
  2872. }
  2873. callback()
  2874. }
  2875. }
  2876. }
  2877. // MARK: - Secure 【安全】
  2878. public func showSecureLimitTip() {
  2879. self.hiddenSecureLimitTip()
  2880. if self.secureAlertView == nil {
  2881. self.secureAlertView = KMSecureAlertView()
  2882. self.secureAlertView?.show(in: self.listView)
  2883. self.secureAlertView?.closeAction = { [unowned self] view in
  2884. self.hiddenSecureLimitTip()
  2885. self.removeFromAlertView()
  2886. self.showFormAlertView()
  2887. }
  2888. self.secureAlertView?.passwordAction = { [unowned self] view in
  2889. self.removeOwnerPassword()
  2890. self.removeFromAlertView()
  2891. self.showFormAlertView()
  2892. }
  2893. }
  2894. }
  2895. func removeOwnerPassword() {
  2896. guard let doc = self.listView.document else {
  2897. NSSound.beep()
  2898. return
  2899. }
  2900. if doc.allowsCopying && doc.allowsPrinting {
  2901. NSSound.beep()
  2902. return
  2903. }
  2904. _ = KMPasswordInputWindow.openWindow(window: self.view.window!, type: .owner, url: doc.documentURL) { [weak self] result, password in
  2905. if result == .cancel { /// 关闭
  2906. return
  2907. }
  2908. /// 解密成功
  2909. self?.hiddenSecureLimitTip()
  2910. self?.model.isSaveKeyChain = false
  2911. self?.listView.document?.unlock(withPassword: password)
  2912. }
  2913. }
  2914. public func hiddenSecureLimitTip() {
  2915. self.secureAlertView?.removeFromSuperview()
  2916. self.secureAlertView = nil
  2917. }
  2918. //MARK: - Form
  2919. func showFormAlertView() {
  2920. if (formAlertView == nil) {
  2921. formAlertView = KMFormAlertView()
  2922. formAlertView?.isCloseSecureView = self.secureAlertView != nil ? false : true
  2923. formAlertView?.showInView(self.listView)
  2924. } else {
  2925. self.removeFromAlertView()
  2926. }
  2927. }
  2928. func removeFromAlertView() {
  2929. formAlertView?.removeFromSuperview()
  2930. formAlertView = nil
  2931. }
  2932. override func mouseMoved(with event: NSEvent) {
  2933. self.view.window?.mouseMoved(with: event)
  2934. }
  2935. func savePageNumberIfNeed() {
  2936. if (KMPreferenceManager.shared.openLastUnlockedDocumentWhenAppStart) {
  2937. let scaleFactor = self.listView.scaleFactor ?? 0
  2938. if scaleFactor <= 0 {
  2939. return
  2940. }
  2941. if self.listView.document != nil {
  2942. KMPreferenceManager.shared.setPageNumber(self.listView.currentPageIndex, forKey: self.listView.document.documentURL.path)
  2943. KMPreferenceManager.shared.setPageScale(Float(self.listView.scaleFactor), forKey: self.listView.document.documentURL.path)
  2944. }
  2945. }
  2946. }
  2947. // MARK: - 显示合并窗口
  2948. public func showMergeWindow(url: URL? = nil, _ password: String?) {
  2949. DispatchQueue.main.async {
  2950. var documentURL = url
  2951. if documentURL == nil {
  2952. documentURL = self.listView.document?.documentURL
  2953. }
  2954. guard let _url = documentURL else { return }
  2955. guard let document = PDFDocument(url: _url) else { return }
  2956. self.mergeWindowController = KMMergeWindowController(document: document, password: password ?? "")
  2957. self.mergeWindowController!.oriDucumentUrl = self.listView.document?.documentURL
  2958. self.mergeWindowController!.pageIndex = self.listView.currentPageIndex
  2959. self.mergeWindowController!.cancelAction = { [unowned self] controller in
  2960. self.view.window?.endSheet(mergeWindowController!.window!)
  2961. }
  2962. self.mergeWindowController!.mergeAction = { [unowned self] controller, filePath in
  2963. self.view.window?.endSheet(mergeWindowController!.window!)
  2964. }
  2965. self.toolbarController.cancelSelected(KMToolbarToolMergeItemIdentifier)
  2966. self.view.window?.beginSheet(self.mergeWindowController!.window!)
  2967. }
  2968. }
  2969. // MARK: - 显示加密弹窗
  2970. public func showSecureWindow(_ url: URL) {
  2971. self.securityWindowController = KMSecurityWindowController(windowNibName: "KMSecurityWindowController")
  2972. guard let securityWindowController = securityWindowController else { return }
  2973. securityWindowController.documentURL = self.listView.document?.documentURL
  2974. securityWindowController.batchAction = { [unowned self] controller, files in
  2975. self.view.window?.endSheet((securityWindowController.window)!)
  2976. self.toolbarController.cancelSelected(KMToolbarToolCompressItemIdentifier)
  2977. let batchWindowController = KMBatchOperateWindowController.sharedWindowController
  2978. let batchOperateFile = KMBatchOperateFile(filePath: self.document?.documentURL.path ?? "", type: .AddPassword)
  2979. batchWindowController.switchToOperateType(.AddPassword, files: [batchOperateFile])
  2980. batchWindowController.window?.makeKeyAndOrderFront("")
  2981. }
  2982. securityWindowController.doneAction = { [unowned self] controller, options, attribute in
  2983. let openPanel = NSOpenPanel()
  2984. openPanel.canChooseFiles = false
  2985. openPanel.canChooseDirectories = true
  2986. openPanel.canCreateDirectories = true
  2987. openPanel.beginSheetModal(for: NSWindow.currentWindow()) { (result) in
  2988. if result == NSApplication.ModalResponse.OK {
  2989. for fileURL in openPanel.urls {
  2990. let document = CPDFDocument(url: self.document?.documentURL)
  2991. if document != nil {
  2992. document!.setDocumentAttributes(attribute)
  2993. let path = fileURL.path.stringByAppendingPathComponent(url.deletingPathExtension().lastPathComponent) + "_SetPassword" + "." + url.pathExtension
  2994. let success = document!.write(to: NSURL(fileURLWithPath: path) as URL, withOptions: options)
  2995. if success {
  2996. self.view.window?.endSheet((securityWindowController.window)!)
  2997. NSWorkspace.shared.activateFileViewerSelecting([URL(fileURLWithPath: path)])
  2998. }
  2999. }
  3000. }
  3001. }
  3002. }
  3003. }
  3004. securityWindowController.cancelAction = { [unowned self] controller in
  3005. self.view.window?.endSheet((securityWindowController.window)!)
  3006. }
  3007. NSWindow.currentWindow().beginSheet(securityWindowController.window!)
  3008. }
  3009. // MARK: - 保存文档
  3010. internal func needSaveDocument() -> Bool {
  3011. if (self.isPDFDocumentEdited) {
  3012. return self.isPDFDocumentEdited
  3013. }
  3014. if (self.needSave) {
  3015. return self.needSave
  3016. }
  3017. let document: KMMainDocument? = self.myDocument as? KMMainDocument
  3018. if (document?.isDocumentEdited == nil || document?.isDocumentEdited == false) {
  3019. return false
  3020. }
  3021. return true
  3022. }
  3023. internal func saveDocument(overlookDocumentIfEdited overlook: Bool = false) {
  3024. let document: KMMainDocument? = self.myDocument as? KMMainDocument
  3025. if (overlook) {
  3026. document?.save(nil)
  3027. return
  3028. }
  3029. if (self.isPDFDocumentEdited) {
  3030. self.clearIsPDFDocumentEdited()
  3031. self.needSave = false
  3032. document?.save(nil)
  3033. return
  3034. }
  3035. if (document?.isDocumentEdited == nil || document?.isDocumentEdited == false) {
  3036. return
  3037. }
  3038. document?.save(nil)
  3039. }
  3040. internal func asyncSaveDocument(overlookDocumentIfEdited overlook: Bool = false, callback:@escaping KMCommonBlock) {
  3041. let document: KMMainDocument? = self.myDocument as? KMMainDocument
  3042. if (overlook) {
  3043. DispatchQueue.main.async {
  3044. document?.save(nil)
  3045. callback()
  3046. }
  3047. return
  3048. }
  3049. if (self.isPDFDocumentEdited) {
  3050. self.clearIsPDFDocumentEdited()
  3051. self.needSave = false
  3052. DispatchQueue.main.async {
  3053. document?.save(nil)
  3054. callback()
  3055. }
  3056. return
  3057. }
  3058. if (document?.isDocumentEdited == nil || document?.isDocumentEdited == false) {
  3059. callback()
  3060. return
  3061. }
  3062. DispatchQueue.main.async {
  3063. document?.save(nil)
  3064. callback()
  3065. }
  3066. }
  3067. internal func saveDocumentWithProgressAlert(callback:@escaping KMCommonBlock) {
  3068. // 显示进度
  3069. AutoSaveManager.manager.isSaving = true
  3070. self.showProgressWindow(message: NSLocalizedString("Save", comment: "") + "PDF")
  3071. self.progressC?.maxValue = 3.0
  3072. self.progressC?.increment(by: 1.0)
  3073. // 保存文档
  3074. self.asyncSaveDocument { [weak self] params in
  3075. // 执行进度 [假进度]
  3076. self?.progressC?.increment(by: 1.0)
  3077. self?.progressC?.increment(by: 1.0)
  3078. DispatchQueue.main.asyncAfter(deadline: .now()+0.1) {
  3079. // 隐藏进度
  3080. self?.hiddenProgressWindow()
  3081. DispatchQueue.main.asyncAfter(deadline: .now()+1) {
  3082. AutoSaveManager.manager.isSaving = false
  3083. }
  3084. // 回调
  3085. callback()
  3086. }
  3087. }
  3088. }
  3089. func SaveTempPDFDocumentToURLPath(tempPath: String) {
  3090. self.document?.write(toFile: tempPath)
  3091. }
  3092. // MARK: - 定时保存
  3093. func addAutoSaveEvent() {
  3094. if (self.autoSaveTimer != nil) {
  3095. self.autoSaveTimer?.invalidate()
  3096. self.autoSaveTimer = nil
  3097. }
  3098. if self.document != nil {
  3099. self.autoSaveTimer = Timer.scheduledTimer(withTimeInterval: AutoSaveManager.manager.timeInterval * 60, repeats: true, block: { [weak self] timer in
  3100. self?.autoSaveTimerAction(timer)
  3101. })
  3102. }
  3103. self.checkAutoSaveInfo()
  3104. }
  3105. func checkAutoSaveInfo() {
  3106. guard let cnt = AutoSaveManager.manager.autoSavePaths?.count, cnt > 0 else {
  3107. return
  3108. }
  3109. if AutoSaveManager.manager.autoSaveAlertShow {
  3110. return
  3111. }
  3112. AutoSaveManager.manager.autoSaveDidEndAction = false
  3113. AutoSaveManager.manager.autoSaveAlertShow = true
  3114. let blockSaveWindow = AutoSavePopController()
  3115. blockSaveWindow.cancelHandle = { [weak self] windowController in
  3116. AutoSaveManager.manager.autoSaveDidEndAction = true
  3117. AutoSaveManager.manager.clearCache()
  3118. self?.km_quick_endSheet()
  3119. }
  3120. blockSaveWindow.confirmHandle = { [weak self] windowController in
  3121. self?.km_quick_endSheet()
  3122. self?.saveAutoSaveInfo()
  3123. }
  3124. self.km_beginSheet(windowC: blockSaveWindow)
  3125. }
  3126. func saveAutoSaveInfo() {
  3127. let openPanel = NSOpenPanel()
  3128. openPanel.canChooseDirectories = true
  3129. openPanel.canChooseFiles = false
  3130. openPanel.allowsMultipleSelection = false
  3131. let win = NSApp.keyWindow != nil ? NSApp.keyWindow : self.view.window
  3132. openPanel.beginSheetModal(for: win!) { result in
  3133. if (result == .OK) {
  3134. let folderPath = openPanel.url?.path ?? openPanel.url?.absoluteString
  3135. for path in AutoSaveManager.manager.opendPaths ?? [] {
  3136. let _path = path as? String
  3137. var newPath = "\(folderPath ?? "")/\(_path?.lastPathComponent ?? "")"
  3138. newPath = self.getValidFilePath(newPath)
  3139. do {
  3140. try FileManager.default.moveItem(atPath: _path ?? "", toPath: newPath)
  3141. } catch {
  3142. NSWorkspace.shared.activateFileViewerSelecting([URL(fileURLWithPath: newPath)])
  3143. }
  3144. }
  3145. AutoSaveManager.manager.clearCache()
  3146. }
  3147. AutoSaveManager.manager.autoSaveDidEndAction = true
  3148. }
  3149. }
  3150. func autoSaveTimerAction(_ timer: Timer) {
  3151. if (self.document == nil || self.listView.document?.documentURL.path == nil) {
  3152. return
  3153. }
  3154. if AutoSaveManager.manager.autoSaveDidEndAction == false {
  3155. //防止提示弹窗出现后,未进行任何操作又进入自动保存的机制
  3156. return
  3157. }
  3158. if let data = self.document?.isLocked, data {
  3159. return
  3160. }
  3161. if AutoSaveManager.manager.autoSaveEnabled == false {
  3162. return
  3163. }
  3164. let documentArray = NSDocumentController.shared.documents
  3165. var didFileEdit = false
  3166. for doc in documentArray {
  3167. if doc.fileURL?.path == self.document?.documentURL.path {
  3168. didFileEdit = doc.isDocumentEdited
  3169. break
  3170. }
  3171. }
  3172. if (didFileEdit == false) {
  3173. return
  3174. }
  3175. AutoSaveManager.manager.isSaving = true
  3176. let savePath = AutoSaveManager.manager.autoSaveWithPath(self.listView.document?.documentURL.path ?? "")
  3177. if (!self.document!.isLocked) {
  3178. self.document?.write(to: URL(fileURLWithPath: savePath))
  3179. }
  3180. DispatchQueue.main.asyncAfter(deadline: .now() + 1.5) {
  3181. AutoSaveManager.manager.isSaving = false
  3182. }
  3183. }
  3184. func removeAutoSaveInfo() {
  3185. if self.autoSaveTimer != nil {
  3186. self.autoSaveTimer?.invalidate()
  3187. self.autoSaveTimer = nil
  3188. }
  3189. if AutoSaveManager.manager.autoSaveDidEndAction == false {
  3190. //防止提示弹窗出现后,未进行任何操作又进入自动保存的机制
  3191. return
  3192. }
  3193. if AutoSaveManager.manager.autoSaveEnabled == false {
  3194. return
  3195. }
  3196. if self.document == nil || self.listView.document?.documentURL.path == nil {
  3197. return
  3198. }
  3199. AutoSaveManager.manager.removeAutoSavePath(self.listView.document?.documentURL.path ?? "")
  3200. }
  3201. // MARK: - 选择 PDFDisplay 模式
  3202. public func setPDFDisplay(pdfViewMode: CPDFDisplayViewMode) {
  3203. listView.setDisplay(pdfViewMode)
  3204. }
  3205. // MARK: - 选择缩放模式
  3206. @objc public func selectZoom(_ type: KMPDFZoomType) {
  3207. switch type {
  3208. case .width:
  3209. self.listView.autoScales = true
  3210. break
  3211. case .fit:
  3212. if let pageHeight = self.listView.currentPage()?.size.height, pageHeight > 0 {
  3213. let pdfviewHeight = self.listView.bounds.size.height
  3214. self.listView.scaleFactor = pdfviewHeight/pageHeight
  3215. self.listView.autoScales = false
  3216. }
  3217. break
  3218. case .actualSize:
  3219. if self.listView.scaleFactor != 1.0 {
  3220. self.listView.scaleFactor = 1.0
  3221. self.listView.autoScales = false
  3222. }
  3223. break
  3224. }
  3225. }
  3226. internal func createPdf(index:Int) {
  3227. }
  3228. // MARK - Event 监听
  3229. private func addEventMonitor() {
  3230. if (self.eventMonitor != nil) {
  3231. self.removeEventMonitor()
  3232. }
  3233. self.eventMonitor = NSEvent.addLocalMonitorForEvents(matching: [.scrollWheel, .leftMouseDown, .leftMouseUp]) { [weak self] event in
  3234. if (event.type == .scrollWheel && event.modifierFlags.contains(.option)) { // Alt + 鼠标滚轮
  3235. self?.listView.magnifyWheel(event)
  3236. return nil
  3237. } else if event.type == .leftMouseDown {
  3238. let point = event.locationInView(self?.listView ?? NSView())
  3239. let presentationDrawView = self?.listView.presentationDrawView
  3240. if let data = self?.interactionMode, data == .presentation,CGRectContainsPoint(self?.listView.frame ?? .zero, point),presentationDrawView?.isHidden == true { // 幻灯片模式下
  3241. if point.x >= (self?.listView.frame.maxX ?? 0) / 2 {
  3242. let can = self?.listView.canGoToNextPage() ?? false
  3243. if can {
  3244. self?.listView.goToNextPage(nil)
  3245. }
  3246. } else {
  3247. let can = self?.listView.canGoToPreviousPage() ?? false
  3248. if can {
  3249. self?.listView.goToPreviousPage(nil)
  3250. }
  3251. }
  3252. return nil
  3253. }
  3254. }
  3255. return event
  3256. }
  3257. }
  3258. func addKeyEventMonitor() {
  3259. if (self.keyEventMonitor != nil) {
  3260. self.removeKeyEventMonitor()
  3261. }
  3262. keyEventMonitor = NSEvent.addLocalMonitorForEvents(matching: .keyDown) { [weak self] event in
  3263. if event.keyCode == 53 {
  3264. if let data = self?.interactionMode, data == .presentation { // 幻灯片模式下
  3265. self?.exitFullScreen()
  3266. return nil
  3267. }
  3268. if self?.listView.toolMode == .editPDFToolMode {
  3269. if self != nil {
  3270. //使用editingSelectionString获取内容文字
  3271. if self!.listView.editingAreas() != nil {
  3272. if self!.listView.editingAreas().count > 0 && self!.listView.isEditable() {
  3273. self!.listView.clearEditingSelectCharItem()
  3274. } else if self!.listView.editingAreas().count > 0 {
  3275. if self?.listView.annotationType == .addImage ||
  3276. self?.listView.annotationType == .addText {
  3277. let textItem = self?.toolbarController.findItem(KMToolbarAddTextEditPDFItemIdentifier)
  3278. let imageItem = self?.toolbarController.findItem(KMToolbarAddImageEditPDFItemIdentifier)
  3279. textItem?.isSelected = false
  3280. imageItem?.isSelected = false
  3281. }
  3282. self?.rightSideViewController.isHidden = true
  3283. self?.listView.endEditIsRemoveBlock(with: self!.listView.editingAreas().first as? CPDFEditArea)
  3284. self?.listView.updateEditing([])
  3285. self?.listView.isEditImage = false
  3286. self?.listView.setNeedsDisplayPageViewFor(self!.listView.currentPage())
  3287. if self?.listView.annotationType == .addImage {
  3288. self?.listView.change([.text, .image])
  3289. }
  3290. self?.listView.annotationType = .editTextImage
  3291. self?.closeRightPane()
  3292. } else if(self?.listView.annotationType == .addImage || self!.listView.annotationType == .addText) {
  3293. if self?.listView.annotationType == .addImage ||
  3294. self?.listView.annotationType == .addText {
  3295. let textItem = self?.toolbarController.findItem(KMToolbarAddTextEditPDFItemIdentifier)
  3296. let imageItem = self?.toolbarController.findItem(KMToolbarAddImageEditPDFItemIdentifier)
  3297. textItem?.isSelected = false
  3298. imageItem?.isSelected = false
  3299. }
  3300. self?.rightSideViewController.isHidden = true
  3301. self?.listView.setShouAddEdit([])
  3302. self?.listView.change([.text, .image])
  3303. self?.listView.annotationType = .editTextImage
  3304. self?.closeRightPane()
  3305. }
  3306. } else {
  3307. if self?.listView.annotationType == .addImage ||
  3308. self?.listView.annotationType == .addText {
  3309. let textItem = self?.toolbarController.findItem(KMToolbarAddTextEditPDFItemIdentifier)
  3310. let imageItem = self?.toolbarController.findItem(KMToolbarAddImageEditPDFItemIdentifier)
  3311. textItem?.isSelected = false
  3312. imageItem?.isSelected = false
  3313. }
  3314. }
  3315. }
  3316. }
  3317. } else {
  3318. if let data = self?.interactionMode, data == .presentation { // 幻灯片模式下
  3319. self?.listView.keyDown(with: event)
  3320. return nil
  3321. } else {
  3322. let cmd = event.modifierFlags.contains(.command)
  3323. let shift = event.modifierFlags.contains(.shift)
  3324. if event.keyCode == 6 { // z
  3325. let editPDFIng = self?.editPDFHanddler.isEditing ?? false
  3326. if cmd && shift { // 恢复
  3327. let can = self?.editPDFHanddler.listView?.canEditTextRedo() ?? false
  3328. if can == false {
  3329. return event
  3330. }
  3331. if editPDFIng {
  3332. _ = CustomAlertView.alertView(message: NSLocalizedString("Redo", comment: ""), fromView: self!.view, withStyle: .black)
  3333. }
  3334. } else if cmd { // 撤回
  3335. let can = self?.editPDFHanddler.listView?.canEditTextUndo() ?? false
  3336. if can == false {
  3337. return event
  3338. }
  3339. if editPDFIng {
  3340. _ = CustomAlertView.alertView(message: NSLocalizedString("Undo", comment: ""), fromView: self!.view, withStyle: .black)
  3341. }
  3342. }
  3343. }
  3344. }
  3345. }
  3346. return event
  3347. }
  3348. }
  3349. func removeKeyEventMonitor() {
  3350. if (self.keyEventMonitor != nil) {
  3351. KMPrint("removeKeyEventMonitor 已移除事件监听")
  3352. NSEvent.removeMonitor(self.keyEventMonitor as Any)
  3353. self.keyEventMonitor = nil
  3354. }
  3355. }
  3356. private func removeEventMonitor() {
  3357. if (self.eventMonitor != nil) {
  3358. KMPrint("已移除事件监听")
  3359. NSEvent.removeMonitor(self.eventMonitor as Any)
  3360. self.eventMonitor = nil
  3361. }
  3362. }
  3363. // MARK: - Tools
  3364. func pdfViewCanHorizontalScroll() -> Bool {
  3365. let scroll = self.listView.scroll()
  3366. if (scroll == nil) {
  3367. return false
  3368. }
  3369. return scroll?.horizontalScroller?.isHidden == nil ? false : !(scroll!.horizontalScroller!.isHidden)
  3370. }
  3371. func pdfViewCanVerticalScroll() -> Bool {
  3372. let scroll = self.listView.scroll()
  3373. if (scroll == nil) {
  3374. return false
  3375. }
  3376. return scroll?.verticalScroller?.isHidden == nil ? false : !(scroll!.verticalScroller!.isHidden)
  3377. }
  3378. // MARK: - Public Methods
  3379. // 清理数据 [eg. 通知]
  3380. public func clearData() {
  3381. KMThumbnailCache.shared.clearCache()
  3382. self.removeNotifications()
  3383. if (self.listView.spellingTag() > 0) {
  3384. NSSpellChecker.shared.closeSpellDocument(withTag: self.listView.spellingTag())
  3385. }
  3386. self.removeAutoSaveInfo()
  3387. self.myDocument = nil
  3388. }
  3389. public func clearSecureOptions() {
  3390. self._secureOptions = nil
  3391. self.documentAttribute = nil
  3392. }
  3393. public func recordRemoveSecureFlag() {
  3394. self._removeSecureFlag = true
  3395. self.clearSecureOptions()
  3396. self.recordIsPDFDocumentEdited(type: .removePassword)
  3397. self._needSave = true
  3398. }
  3399. public func clearRemoveSecureFlag() {
  3400. self._removeSecureFlag = false
  3401. }
  3402. public func clearSaveWatermarkFlag() {
  3403. km_synchronized(self) {
  3404. self._saveWatermarkFlag = false
  3405. }
  3406. }
  3407. public func recordIsPDFDocumentEdited(type: KMSubscribeWaterMarkType = .none) {
  3408. km_synchronized(self) {
  3409. self.model.isPDFDocumentEdited = true
  3410. if type == .editText || type == .editImage {
  3411. self.leftSideViewController.updateThumbnail(at: self.listView.currentPageIndex)
  3412. }
  3413. if let _document = self.myDocument {
  3414. KMTools.setDocumentEditedState(document: _document)
  3415. }
  3416. }
  3417. }
  3418. public func clearIsPDFDocumentEdited() {
  3419. km_synchronized(self) {
  3420. self.model.isPDFDocumentEdited = false
  3421. }
  3422. }
  3423. func showSnapshots(setups: NSArray?) {
  3424. if self.listView.document != nil {
  3425. for setup in setups ?? [] {
  3426. let swc = KMSnapshotWindowController()
  3427. swc.delegate = self
  3428. swc.setPdfDocument(self.listView.document, setup: setup as? NSDictionary)
  3429. swc.setForceOnTop(self.interactionMode != .normal)
  3430. self.myDocument?.addWindowController(swc)
  3431. }
  3432. }
  3433. }
  3434. func dealDocumentDidLoaded() {
  3435. self.removeBackgroundMaskView()
  3436. if (!self.listView.document!.allowsCopying || !self.listView.document!.allowsPrinting) {
  3437. self.showSecureLimitTip()
  3438. }
  3439. if self.model.needConvertNotes {
  3440. self.showConvertNotesProgress()
  3441. }
  3442. if (self._documentFirstLoad) {
  3443. self.checkShouldAutoOpenLeftVC()
  3444. if (KMPreferenceManager.shared.openLastUnlockedDocumentWhenAppStart) {
  3445. let pageNumber = KMPreferenceManager.shared.getPageNumber(forKey: self.listView.document?.documentURL.path ?? "")
  3446. let pageScale = KMPreferenceManager.shared.getPageScale(forKey: self.listView.document?.documentURL.path ?? "")
  3447. if (pageScale != nil) {
  3448. self.listView.scaleFactor = CGFloat(pageScale!)
  3449. }
  3450. if (pageNumber != nil && pageNumber! >= 0 && pageNumber! < (self.listView.document?.pageCount ?? 0)) {
  3451. self.listView.go(toPageIndex: pageNumber!, animated: false)
  3452. } else {
  3453. self._goToFirstPageForFristAppear()
  3454. }
  3455. } else {
  3456. self._goToFirstPageForFristAppear()
  3457. }
  3458. self._documentFirstLoad = false
  3459. }
  3460. }
  3461. func tabViewIsDragging() -> Bool {
  3462. let level = self.view.window?.level ?? .normal
  3463. return level == .floating
  3464. }
  3465. // MARK: - Noti Actions
  3466. internal func documentDidUnlockNotification(_ sender: Notification) {
  3467. if (self.listView.document != nil && self.listView.document.isEqual(to: sender.object)) {
  3468. if (self.myDocument == nil) {
  3469. return
  3470. }
  3471. if (self.listView.document.allowsPrinting && self.listView.document.allowsCopying) {
  3472. self.hiddenSecureLimitTip()
  3473. }
  3474. let isUnlockFromKeychain = (self.myDocument as? KMMainDocument)?.isUnlockFromKeychain ?? false
  3475. if (isUnlockFromKeychain || self.model.isSaveKeyChain == false) {
  3476. return
  3477. }
  3478. let type = KMPreferenceManager.shared.savePasswordType
  3479. if (type == .never) {
  3480. return
  3481. }
  3482. if (type == .always) {
  3483. self.myDocument?.savePasswordInKeychain(self.listView.document.password, self.listView.document)
  3484. return
  3485. }
  3486. // 保存到钥匙串
  3487. let alert = NSAlert()
  3488. alert.messageText = NSLocalizedString("Remember Password?", comment: "")
  3489. alert.informativeText = NSLocalizedString("Do you want to save this password in your Keychain?", comment: "")
  3490. alert.addButton(withTitle: NSLocalizedString("Yes", comment: ""))
  3491. alert.addButton(withTitle: NSLocalizedString("No", comment: ""))
  3492. if (alert.runModal() == .alertFirstButtonReturn) { // 保存密码
  3493. self.myDocument?.savePasswordInKeychain(self.listView.document.password, self.listView.document)
  3494. return
  3495. }
  3496. }
  3497. }
  3498. func annotationsAttributeHasChange(_ sender: Notification) {
  3499. guard let dict = sender.object as? [String : Any] else {
  3500. return
  3501. }
  3502. if let anno = dict["object"] as? CPDFAnnotation {
  3503. let value = dict["keyPath"] as? String ?? ""
  3504. let didEnd = dict["didEnd"] as? Bool ?? false
  3505. if didEnd {
  3506. if value == CPDFAnnotationBoundsKey {
  3507. if anno is CPDFSquareAnnotation || anno is CPDFCircleAnnotation {
  3508. anno.contents = anno.page?.string(for: anno.bounds) ?? ""
  3509. }
  3510. }
  3511. if anno.km_isMeasure() && anno.contents == nil {
  3512. anno.contents = anno.string() ?? ""
  3513. }
  3514. self.leftSideViewController.refreshUIForAnnoAttributeDidChange(anno, attributes: ["keyPath" : value])
  3515. } else {
  3516. if value != CPDFAnnotationBoundsKey && value != CPDFAnnotationStartPointKey && value != CPDFAnnotationEndPointKey && value != CPDFAnnotationPathsKey { // 改变bounds(箭头、直线注释 开始点和结束点, 手绘注释的paths)的操作会卡顿,比如移动
  3517. self.leftSideViewController.refreshUIForAnnoAttributeDidChange(anno, attributes: ["keyPath" : value])
  3518. }
  3519. }
  3520. }
  3521. }
  3522. internal func applicationWillTerminateNotification(_ sender: Notification) {
  3523. self.savePageNumberIfNeed()
  3524. self.saveDocument()
  3525. }
  3526. func CPDFDocumentPageCountChangedNotification(_ sender: Notification) {
  3527. self.leftSideViewController.refreshUIForAnnoAttributeDidChange(nil, attributes: nil)
  3528. }
  3529. func CEditPDFToolModeChangeStateUnkownNotification(_ sender: Notification) {
  3530. var editSelectd = false
  3531. if (self.listView.annotationType == .addText || self.listView.annotationType == .addImage) && self.listView.toolMode == .editPDFToolMode {
  3532. editSelectd = true
  3533. }
  3534. if self.listView.toolMode == .editPDFToolMode {
  3535. if editSelectd {
  3536. self.toolbarController.cancelSelected(KMToolbarAddTextEditPDFItemIdentifier)
  3537. }
  3538. }
  3539. }
  3540. @objc func handlePageChangedNotification(_ sender: Notification) {
  3541. if self.mwcFlags.isSwitchingFullScreen > 0 {
  3542. return
  3543. }
  3544. let page = self.listView.currentPage()
  3545. let pageIndex = page?.pageIndex() ?? 0
  3546. self.leftSideViewController.thumb_selectRowIndexsIfNeed(IndexSet(integer: IndexSet.Element(pageIndex)))
  3547. self.leftSideViewController.thumbnailTableView.needsDisplay = true
  3548. self.leftSideViewController.tocOutlineView.needsDisplay = true
  3549. }
  3550. @objc func handleDisplayBoxChangedNotification(_ sender: Notification) {
  3551. self.leftSideViewController.reloadThumbnailDataIfNeed()
  3552. }
  3553. }