KMMainViewController.swift 215 KB

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