KMMainViewController.swift 146 KB

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