KMMainViewController.swift 369 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724172517261727172817291730173117321733173417351736173717381739174017411742174317441745174617471748174917501751175217531754175517561757175817591760176117621763176417651766176717681769177017711772177317741775177617771778177917801781178217831784178517861787178817891790179117921793179417951796179717981799180018011802180318041805180618071808180918101811181218131814181518161817181818191820182118221823182418251826182718281829183018311832183318341835183618371838183918401841184218431844184518461847184818491850185118521853185418551856185718581859186018611862186318641865186618671868186918701871187218731874187518761877187818791880188118821883188418851886188718881889189018911892189318941895189618971898189919001901190219031904190519061907190819091910191119121913191419151916191719181919192019211922192319241925192619271928192919301931193219331934193519361937193819391940194119421943194419451946194719481949195019511952195319541955195619571958195919601961196219631964196519661967196819691970197119721973197419751976197719781979198019811982198319841985198619871988198919901991199219931994199519961997199819992000200120022003200420052006200720082009201020112012201320142015201620172018201920202021202220232024202520262027202820292030203120322033203420352036203720382039204020412042204320442045204620472048204920502051205220532054205520562057205820592060206120622063206420652066206720682069207020712072207320742075207620772078207920802081208220832084208520862087208820892090209120922093209420952096209720982099210021012102210321042105210621072108210921102111211221132114211521162117211821192120212121222123212421252126212721282129213021312132213321342135213621372138213921402141214221432144214521462147214821492150215121522153215421552156215721582159216021612162216321642165216621672168216921702171217221732174217521762177217821792180218121822183218421852186218721882189219021912192219321942195219621972198219922002201220222032204220522062207220822092210221122122213221422152216221722182219222022212222222322242225222622272228222922302231223222332234223522362237223822392240224122422243224422452246224722482249225022512252225322542255225622572258225922602261226222632264226522662267226822692270227122722273227422752276227722782279228022812282228322842285228622872288228922902291229222932294229522962297229822992300230123022303230423052306230723082309231023112312231323142315231623172318231923202321232223232324232523262327232823292330233123322333233423352336233723382339234023412342234323442345234623472348234923502351235223532354235523562357235823592360236123622363236423652366236723682369237023712372237323742375237623772378237923802381238223832384238523862387238823892390239123922393239423952396239723982399240024012402240324042405240624072408240924102411241224132414241524162417241824192420242124222423242424252426242724282429243024312432243324342435243624372438243924402441244224432444244524462447244824492450245124522453245424552456245724582459246024612462246324642465246624672468246924702471247224732474247524762477247824792480248124822483248424852486248724882489249024912492249324942495249624972498249925002501250225032504250525062507250825092510251125122513251425152516251725182519252025212522252325242525252625272528252925302531253225332534253525362537253825392540254125422543254425452546254725482549255025512552255325542555255625572558255925602561256225632564256525662567256825692570257125722573257425752576257725782579258025812582258325842585258625872588258925902591259225932594259525962597259825992600260126022603260426052606260726082609261026112612261326142615261626172618261926202621262226232624262526262627262826292630263126322633263426352636263726382639264026412642264326442645264626472648264926502651265226532654265526562657265826592660266126622663266426652666266726682669267026712672267326742675267626772678267926802681268226832684268526862687268826892690269126922693269426952696269726982699270027012702270327042705270627072708270927102711271227132714271527162717271827192720272127222723272427252726272727282729273027312732273327342735273627372738273927402741274227432744274527462747274827492750275127522753275427552756275727582759276027612762276327642765276627672768276927702771277227732774277527762777277827792780278127822783278427852786278727882789279027912792279327942795279627972798279928002801280228032804280528062807280828092810281128122813281428152816281728182819282028212822282328242825282628272828282928302831283228332834283528362837283828392840284128422843284428452846284728482849285028512852285328542855285628572858285928602861286228632864286528662867286828692870287128722873287428752876287728782879288028812882288328842885288628872888288928902891289228932894289528962897289828992900290129022903290429052906290729082909291029112912291329142915291629172918291929202921292229232924292529262927292829292930293129322933293429352936293729382939294029412942294329442945294629472948294929502951295229532954295529562957295829592960296129622963296429652966296729682969297029712972297329742975297629772978297929802981298229832984298529862987298829892990299129922993299429952996299729982999300030013002300330043005300630073008300930103011301230133014301530163017301830193020302130223023302430253026302730283029303030313032303330343035303630373038303930403041304230433044304530463047304830493050305130523053305430553056305730583059306030613062306330643065306630673068306930703071307230733074307530763077307830793080308130823083308430853086308730883089309030913092309330943095309630973098309931003101310231033104310531063107310831093110311131123113311431153116311731183119312031213122312331243125312631273128312931303131313231333134313531363137313831393140314131423143314431453146314731483149315031513152315331543155315631573158315931603161316231633164316531663167316831693170317131723173317431753176317731783179318031813182318331843185318631873188318931903191319231933194319531963197319831993200320132023203320432053206320732083209321032113212321332143215321632173218321932203221322232233224322532263227322832293230323132323233323432353236323732383239324032413242324332443245324632473248324932503251325232533254325532563257325832593260326132623263326432653266326732683269327032713272327332743275327632773278327932803281328232833284328532863287328832893290329132923293329432953296329732983299330033013302330333043305330633073308330933103311331233133314331533163317331833193320332133223323332433253326332733283329333033313332333333343335333633373338333933403341334233433344334533463347334833493350335133523353335433553356335733583359336033613362336333643365336633673368336933703371337233733374337533763377337833793380338133823383338433853386338733883389339033913392339333943395339633973398339934003401340234033404340534063407340834093410341134123413341434153416341734183419342034213422342334243425342634273428342934303431343234333434343534363437343834393440344134423443344434453446344734483449345034513452345334543455345634573458345934603461346234633464346534663467346834693470347134723473347434753476347734783479348034813482348334843485348634873488348934903491349234933494349534963497349834993500350135023503350435053506350735083509351035113512351335143515351635173518351935203521352235233524352535263527352835293530353135323533353435353536353735383539354035413542354335443545354635473548354935503551355235533554355535563557355835593560356135623563356435653566356735683569357035713572357335743575357635773578357935803581358235833584358535863587358835893590359135923593359435953596359735983599360036013602360336043605360636073608360936103611361236133614361536163617361836193620362136223623362436253626362736283629363036313632363336343635363636373638363936403641364236433644364536463647364836493650365136523653365436553656365736583659366036613662366336643665366636673668366936703671367236733674367536763677367836793680368136823683368436853686368736883689369036913692369336943695369636973698369937003701370237033704370537063707370837093710371137123713371437153716371737183719372037213722372337243725372637273728372937303731373237333734373537363737373837393740374137423743374437453746374737483749375037513752375337543755375637573758375937603761376237633764376537663767376837693770377137723773377437753776377737783779378037813782378337843785378637873788378937903791379237933794379537963797379837993800380138023803380438053806380738083809381038113812381338143815381638173818381938203821382238233824382538263827382838293830383138323833383438353836383738383839384038413842384338443845384638473848384938503851385238533854385538563857385838593860386138623863386438653866386738683869387038713872387338743875387638773878387938803881388238833884388538863887388838893890389138923893389438953896389738983899390039013902390339043905390639073908390939103911391239133914391539163917391839193920392139223923392439253926392739283929393039313932393339343935393639373938393939403941394239433944394539463947394839493950395139523953395439553956395739583959396039613962396339643965396639673968396939703971397239733974397539763977397839793980398139823983398439853986398739883989399039913992399339943995399639973998399940004001400240034004400540064007400840094010401140124013401440154016401740184019402040214022402340244025402640274028402940304031403240334034403540364037403840394040404140424043404440454046404740484049405040514052405340544055405640574058405940604061406240634064406540664067406840694070407140724073407440754076407740784079408040814082408340844085408640874088408940904091409240934094409540964097409840994100410141024103410441054106410741084109411041114112411341144115411641174118411941204121412241234124412541264127412841294130413141324133413441354136413741384139414041414142414341444145414641474148414941504151415241534154415541564157415841594160416141624163416441654166416741684169417041714172417341744175417641774178417941804181418241834184418541864187418841894190419141924193419441954196419741984199420042014202420342044205420642074208420942104211421242134214421542164217421842194220422142224223422442254226422742284229423042314232423342344235423642374238423942404241424242434244424542464247424842494250425142524253425442554256425742584259426042614262426342644265426642674268426942704271427242734274427542764277427842794280428142824283428442854286428742884289429042914292429342944295429642974298429943004301430243034304430543064307430843094310431143124313431443154316431743184319432043214322432343244325432643274328432943304331433243334334433543364337433843394340434143424343434443454346434743484349435043514352435343544355435643574358435943604361436243634364436543664367436843694370437143724373437443754376437743784379438043814382438343844385438643874388438943904391439243934394439543964397439843994400440144024403440444054406440744084409441044114412441344144415441644174418441944204421442244234424442544264427442844294430443144324433443444354436443744384439444044414442444344444445444644474448444944504451445244534454445544564457445844594460446144624463446444654466446744684469447044714472447344744475447644774478447944804481448244834484448544864487448844894490449144924493449444954496449744984499450045014502450345044505450645074508450945104511451245134514451545164517451845194520452145224523452445254526452745284529453045314532453345344535453645374538453945404541454245434544454545464547454845494550455145524553455445554556455745584559456045614562456345644565456645674568456945704571457245734574457545764577457845794580458145824583458445854586458745884589459045914592459345944595459645974598459946004601460246034604460546064607460846094610461146124613461446154616461746184619462046214622462346244625462646274628462946304631463246334634463546364637463846394640464146424643464446454646464746484649465046514652465346544655465646574658465946604661466246634664466546664667466846694670467146724673467446754676467746784679468046814682468346844685468646874688468946904691469246934694469546964697469846994700470147024703470447054706470747084709471047114712471347144715471647174718471947204721472247234724472547264727472847294730473147324733473447354736473747384739474047414742474347444745474647474748474947504751475247534754475547564757475847594760476147624763476447654766476747684769477047714772477347744775477647774778477947804781478247834784478547864787478847894790479147924793479447954796479747984799480048014802480348044805480648074808480948104811481248134814481548164817481848194820482148224823482448254826482748284829483048314832483348344835483648374838483948404841484248434844484548464847484848494850485148524853485448554856485748584859486048614862486348644865486648674868486948704871487248734874487548764877487848794880488148824883488448854886488748884889489048914892489348944895489648974898489949004901490249034904490549064907490849094910491149124913491449154916491749184919492049214922492349244925492649274928492949304931493249334934493549364937493849394940494149424943494449454946494749484949495049514952495349544955495649574958495949604961496249634964496549664967496849694970497149724973497449754976497749784979498049814982498349844985498649874988498949904991499249934994499549964997499849995000500150025003500450055006500750085009501050115012501350145015501650175018501950205021502250235024502550265027502850295030503150325033503450355036503750385039504050415042504350445045504650475048504950505051505250535054505550565057505850595060506150625063506450655066506750685069507050715072507350745075507650775078507950805081508250835084508550865087508850895090509150925093509450955096509750985099510051015102510351045105510651075108510951105111511251135114511551165117511851195120512151225123512451255126512751285129513051315132513351345135513651375138513951405141514251435144514551465147514851495150515151525153515451555156515751585159516051615162516351645165516651675168516951705171517251735174517551765177517851795180518151825183518451855186518751885189519051915192519351945195519651975198519952005201520252035204520552065207520852095210521152125213521452155216521752185219522052215222522352245225522652275228522952305231523252335234523552365237523852395240524152425243524452455246524752485249525052515252525352545255525652575258525952605261526252635264526552665267526852695270527152725273527452755276527752785279528052815282528352845285528652875288528952905291529252935294529552965297529852995300530153025303530453055306530753085309531053115312531353145315531653175318531953205321532253235324532553265327532853295330533153325333533453355336533753385339534053415342534353445345534653475348534953505351535253535354535553565357535853595360536153625363536453655366536753685369537053715372537353745375537653775378537953805381538253835384538553865387538853895390539153925393539453955396539753985399540054015402540354045405540654075408540954105411541254135414541554165417541854195420542154225423542454255426542754285429543054315432543354345435543654375438543954405441544254435444544554465447544854495450545154525453545454555456545754585459546054615462546354645465546654675468546954705471547254735474547554765477547854795480548154825483548454855486548754885489549054915492549354945495549654975498549955005501550255035504550555065507550855095510551155125513551455155516551755185519552055215522552355245525552655275528552955305531553255335534553555365537553855395540554155425543554455455546554755485549555055515552555355545555555655575558555955605561556255635564556555665567556855695570557155725573557455755576557755785579558055815582558355845585558655875588558955905591559255935594559555965597559855995600560156025603560456055606560756085609561056115612561356145615561656175618561956205621562256235624562556265627562856295630563156325633563456355636563756385639564056415642564356445645564656475648564956505651565256535654565556565657565856595660566156625663566456655666566756685669567056715672567356745675567656775678567956805681568256835684568556865687568856895690569156925693569456955696569756985699570057015702570357045705570657075708570957105711571257135714571557165717571857195720572157225723572457255726572757285729573057315732573357345735573657375738573957405741574257435744574557465747574857495750575157525753575457555756575757585759576057615762576357645765576657675768576957705771577257735774577557765777577857795780578157825783578457855786578757885789579057915792579357945795579657975798579958005801580258035804580558065807580858095810581158125813581458155816581758185819582058215822582358245825582658275828582958305831583258335834583558365837583858395840584158425843584458455846584758485849585058515852585358545855585658575858585958605861586258635864586558665867586858695870587158725873587458755876587758785879588058815882588358845885588658875888588958905891589258935894589558965897589858995900590159025903590459055906590759085909591059115912591359145915591659175918591959205921592259235924592559265927592859295930593159325933593459355936593759385939594059415942594359445945594659475948594959505951595259535954595559565957595859595960596159625963596459655966596759685969597059715972597359745975597659775978597959805981598259835984598559865987598859895990599159925993599459955996599759985999600060016002600360046005600660076008600960106011601260136014601560166017601860196020602160226023602460256026602760286029603060316032603360346035603660376038603960406041604260436044604560466047604860496050605160526053605460556056605760586059606060616062606360646065606660676068606960706071607260736074607560766077607860796080608160826083608460856086608760886089609060916092609360946095609660976098609961006101610261036104610561066107610861096110611161126113611461156116611761186119612061216122612361246125612661276128612961306131613261336134613561366137613861396140614161426143614461456146614761486149615061516152615361546155615661576158615961606161616261636164616561666167616861696170617161726173617461756176617761786179618061816182618361846185618661876188618961906191619261936194619561966197619861996200620162026203620462056206620762086209621062116212621362146215621662176218621962206221622262236224622562266227622862296230623162326233623462356236623762386239624062416242624362446245624662476248624962506251625262536254625562566257625862596260626162626263626462656266626762686269627062716272627362746275627662776278627962806281628262836284628562866287628862896290629162926293629462956296629762986299630063016302630363046305630663076308630963106311631263136314631563166317631863196320632163226323632463256326632763286329633063316332633363346335633663376338633963406341634263436344634563466347634863496350635163526353635463556356635763586359636063616362636363646365636663676368636963706371637263736374637563766377637863796380638163826383638463856386638763886389639063916392639363946395639663976398639964006401640264036404640564066407640864096410641164126413641464156416641764186419642064216422642364246425642664276428642964306431643264336434643564366437643864396440644164426443644464456446644764486449645064516452645364546455645664576458645964606461646264636464646564666467646864696470647164726473647464756476647764786479648064816482648364846485648664876488648964906491649264936494649564966497649864996500650165026503650465056506650765086509651065116512651365146515651665176518651965206521652265236524652565266527652865296530653165326533653465356536653765386539654065416542654365446545654665476548654965506551655265536554655565566557655865596560656165626563656465656566656765686569657065716572657365746575657665776578657965806581658265836584658565866587658865896590659165926593659465956596659765986599660066016602660366046605660666076608660966106611661266136614661566166617661866196620662166226623662466256626662766286629663066316632663366346635663666376638663966406641664266436644664566466647664866496650665166526653665466556656665766586659666066616662666366646665666666676668666966706671667266736674667566766677667866796680668166826683668466856686668766886689669066916692669366946695669666976698669967006701670267036704670567066707670867096710671167126713671467156716671767186719672067216722672367246725672667276728672967306731673267336734673567366737673867396740674167426743674467456746674767486749675067516752675367546755675667576758675967606761676267636764676567666767676867696770677167726773677467756776677767786779678067816782678367846785678667876788678967906791679267936794679567966797679867996800680168026803680468056806680768086809681068116812681368146815681668176818681968206821682268236824682568266827682868296830683168326833683468356836683768386839684068416842684368446845684668476848684968506851685268536854685568566857685868596860686168626863686468656866686768686869687068716872687368746875687668776878687968806881688268836884688568866887688868896890689168926893689468956896689768986899690069016902690369046905690669076908690969106911691269136914691569166917691869196920692169226923692469256926692769286929693069316932693369346935693669376938693969406941694269436944694569466947694869496950695169526953695469556956695769586959696069616962696369646965696669676968696969706971697269736974697569766977697869796980698169826983698469856986698769886989699069916992699369946995699669976998699970007001700270037004700570067007700870097010701170127013701470157016701770187019702070217022702370247025702670277028702970307031703270337034703570367037703870397040704170427043704470457046704770487049705070517052705370547055705670577058705970607061706270637064706570667067706870697070707170727073707470757076707770787079708070817082708370847085708670877088708970907091709270937094709570967097709870997100710171027103710471057106710771087109711071117112711371147115711671177118711971207121712271237124712571267127712871297130713171327133713471357136713771387139714071417142714371447145714671477148714971507151715271537154715571567157715871597160716171627163716471657166716771687169717071717172717371747175717671777178717971807181718271837184718571867187718871897190719171927193719471957196719771987199720072017202720372047205720672077208720972107211721272137214721572167217721872197220722172227223722472257226722772287229723072317232723372347235723672377238723972407241724272437244724572467247724872497250725172527253725472557256725772587259726072617262726372647265726672677268726972707271727272737274727572767277727872797280728172827283728472857286728772887289729072917292729372947295729672977298729973007301730273037304730573067307730873097310731173127313731473157316731773187319732073217322732373247325732673277328732973307331733273337334733573367337733873397340734173427343734473457346734773487349735073517352735373547355735673577358735973607361736273637364736573667367736873697370737173727373737473757376737773787379738073817382738373847385738673877388738973907391739273937394739573967397739873997400740174027403740474057406740774087409741074117412741374147415741674177418741974207421742274237424742574267427742874297430743174327433743474357436743774387439744074417442744374447445744674477448744974507451745274537454745574567457745874597460746174627463746474657466746774687469747074717472747374747475747674777478747974807481748274837484748574867487748874897490749174927493749474957496749774987499750075017502750375047505750675077508750975107511751275137514751575167517751875197520752175227523752475257526752775287529753075317532753375347535753675377538753975407541754275437544754575467547754875497550755175527553755475557556755775587559756075617562756375647565756675677568756975707571757275737574757575767577757875797580758175827583758475857586758775887589759075917592759375947595759675977598759976007601760276037604760576067607760876097610761176127613761476157616761776187619762076217622762376247625762676277628762976307631763276337634763576367637763876397640764176427643764476457646764776487649765076517652765376547655765676577658765976607661766276637664766576667667766876697670767176727673767476757676767776787679768076817682768376847685768676877688768976907691769276937694769576967697769876997700770177027703770477057706770777087709771077117712771377147715771677177718771977207721772277237724772577267727772877297730773177327733773477357736773777387739774077417742774377447745774677477748774977507751775277537754775577567757775877597760776177627763776477657766776777687769777077717772777377747775777677777778777977807781778277837784778577867787778877897790779177927793779477957796779777987799780078017802780378047805780678077808780978107811781278137814781578167817781878197820782178227823782478257826782778287829783078317832783378347835783678377838783978407841784278437844784578467847784878497850785178527853785478557856785778587859786078617862786378647865786678677868786978707871787278737874787578767877787878797880788178827883788478857886788778887889789078917892789378947895789678977898789979007901790279037904790579067907790879097910791179127913791479157916791779187919792079217922792379247925792679277928792979307931793279337934793579367937793879397940794179427943794479457946794779487949795079517952795379547955795679577958795979607961796279637964796579667967796879697970797179727973797479757976797779787979798079817982798379847985798679877988798979907991799279937994799579967997799879998000800180028003800480058006800780088009801080118012801380148015801680178018801980208021802280238024802580268027802880298030803180328033803480358036803780388039804080418042804380448045804680478048804980508051805280538054805580568057805880598060806180628063806480658066806780688069807080718072807380748075807680778078807980808081808280838084808580868087808880898090809180928093809480958096809780988099810081018102810381048105810681078108810981108111811281138114811581168117811881198120812181228123812481258126812781288129813081318132813381348135813681378138813981408141814281438144814581468147814881498150815181528153815481558156815781588159816081618162816381648165816681678168816981708171817281738174817581768177817881798180818181828183818481858186818781888189819081918192819381948195819681978198819982008201820282038204820582068207820882098210821182128213821482158216821782188219822082218222822382248225822682278228822982308231823282338234823582368237823882398240824182428243824482458246824782488249825082518252825382548255825682578258825982608261826282638264826582668267826882698270827182728273827482758276827782788279828082818282828382848285828682878288828982908291829282938294829582968297829882998300830183028303830483058306830783088309831083118312831383148315831683178318831983208321832283238324832583268327832883298330833183328333833483358336833783388339834083418342834383448345834683478348834983508351835283538354835583568357835883598360836183628363836483658366836783688369837083718372837383748375837683778378837983808381838283838384838583868387838883898390839183928393839483958396839783988399840084018402840384048405840684078408840984108411841284138414841584168417841884198420842184228423842484258426842784288429843084318432843384348435843684378438843984408441844284438444844584468447844884498450845184528453845484558456845784588459846084618462
  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: NSNumber = 264 // 最小值
  10. let CPDFViewIsReadModeKey = "kKMPDFViewIsReadMode"
  11. let CPDFViewLeftSidePaneWidthKey = "CPDFOfficeLeftSidePaneWidthKey"
  12. struct KMNMWCFlags {
  13. var settingUpWindow: Bool = true
  14. }
  15. @objcMembers class KMMainViewController: KMNBaseViewController, 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: NSSplitView!
  21. @IBOutlet var infoSplitLeftView: NSView!
  22. @IBOutlet var infoSplitRightView: NSView!
  23. @IBOutlet var infoSplitCenterView: NSView!
  24. @IBOutlet var infoSplitCenterSubView: NSBox!
  25. @IBOutlet var pdfSplitView: NSSplitView!
  26. @IBOutlet var pdfSplitTopView: NSView!
  27. @IBOutlet var pdfSplitBottomView: NSView!
  28. @IBOutlet var toolbarBoxHeightConst: NSLayoutConstraint!
  29. @IBOutlet var infoSplitViewLeftConst: NSLayoutConstraint!
  30. @IBOutlet var infoSplitViewRightConst: NSLayoutConstraint!
  31. @IBOutlet var infoSplitViewTopConst: NSLayoutConstraint!
  32. var viewManager: KMPDFViewManager = KMPDFViewManager.init()
  33. var toolbarManager: KMPDFToolbarManager = KMPDFToolbarManager.init()
  34. var listView: CPDFListView = CPDFListView.init()
  35. var document: CPDFDocument?
  36. var myDocument: NSDocument?
  37. var isFirstOpen: Bool = true
  38. var insertDocuments: Set<CPDFDocument> = [] //插入新文档时,SDK会出现崩溃,临时记录
  39. //工具栏
  40. private var pdfToolbarController: KMPDFToolbarController?
  41. //BOTA SideBar
  42. private var sideBarController: KMPDFSideBarController?
  43. //页面编辑
  44. private var pageEditViewController: KMNPageEditViewController?
  45. //DisplaySetting
  46. private var displaySettingController: KMNDisplayViewController?
  47. //SPlitPDF分屏视图
  48. private var splitPDFController: KMSplitPDFViewController?
  49. private var pageNumberToolbar: KMPageNumberPromptView?
  50. //PPT操作界面
  51. var presentationTopViewController: KMPresentationTopViewController?
  52. //Edit
  53. var editToolbarView: KMEditToolbarView?
  54. //水印
  55. var watermarkViewController: KMWatermarkController?
  56. //背景
  57. var backgroundViewController: KMBackgroundController?
  58. //Header&Footer
  59. var headerFooterViewController: KMHeaderFooterController?
  60. //Bates
  61. var batesViewController: KMBatesController?
  62. //Crop
  63. var cropController: KMCropController?
  64. //左边
  65. var botaViewController: KMNLeftSideViewController?
  66. //右边
  67. var rightSideController: KMRightSideController?
  68. let alertTipViewController: KMNAlertTipViewController = KMNAlertTipViewController(nibName: "KMNAlertTipViewController", bundle: nil)
  69. //合并
  70. var mergeWindowController: KMMergeWindowController?
  71. //春季活动
  72. var recommondPopWindowVC: KMRecommondPopWindow?
  73. //数字签名状态
  74. var signaturestateVC: CDSignatureCertificateStateViewController = CDSignatureCertificateStateViewController.init()
  75. //PDFView右键菜单
  76. private var groupListMenuGroup: ComponentGroup? = ComponentGroup.createFromNib(in: ComponentLibrary.shared.componentBundle())
  77. var textFieldSheet: KMTextFieldSheetController = KMTextFieldSheetController.init(windowNibName: "KMTextFieldSheetController")
  78. @IBOutlet weak var leftView: NSView!
  79. var model = KMMainModel()
  80. //Search
  81. var searchIndex: Int = 0
  82. //对比
  83. var isCompareModel: Bool = false
  84. //密码弹窗
  85. var passwordWindow: KMPasswordInputWindow?
  86. var securityWindowController: KMSecurityWindowController?
  87. //压缩
  88. var compressWindowController: KMCompressWindowController?
  89. //引导
  90. var guideInfoWindowController: KMGuideInfoWindowController?
  91. //测量
  92. var distanceMeasureInfoWindowController: CDistanceMeasureInfoWindowController?
  93. var perimeterMeasureInfoWindowController: CPerimeterMeasureInfoWindowController?
  94. var areaMeasureInfoWindowController: CAreaMeasureInfoWindowController?
  95. //打印
  96. var bookletWindowController: KMPDFBookletWindowController?
  97. var multiplePrintWindowController: KMPDFMultiplePrintWindowController?
  98. var posterPrintWindowController: KMPDFPosterPrintWindowController?
  99. var removeAllAnnotationsStore = KMPDFViewRemoveAllAnnotationsStore()
  100. var componentMessageView: ComponentMessage = ComponentMessage()
  101. var blockSaveWindow = AutoSavePopController()
  102. private var _needSave = false
  103. var needSave: Bool {
  104. set {
  105. _needSave = newValue
  106. if (_needSave == false) {
  107. self.clearIsPDFDocumentEdited()
  108. }
  109. }
  110. get {
  111. return _needSave
  112. }
  113. }
  114. var isPDFDocumentEdited: Bool {
  115. get {
  116. return self.model.isPDFDocumentEdited
  117. }
  118. }
  119. var newMwcFlags = KMNMWCFlags(settingUpWindow: true)
  120. var searchResults: [KMSearchMode] = []
  121. var mwcFlags: MwcFlags = MwcFlags()
  122. weak var browserWindowController: KMBrowserWindowController? //慎直接使用这个方法
  123. var currentWindowController: NSWindowController!
  124. var savedNormalSetup: NSMutableDictionary = NSMutableDictionary()
  125. let CPDFOfficeLeftSidePaneWidthKey = "CPDFOfficeLeftSidePaneWidthKey"
  126. let CPDFOfficeRightSidePaneWidthKey = "CPDFOfficeRightSidePaneWidthKey"
  127. var extract: KMExtractImageWindowController?
  128. var pageNumber: UInt?
  129. var autoSaveTimer: Timer?
  130. private var _documentFirstLoad: Bool = true
  131. var eventMonitor: Any?
  132. var keyEventMonitor: Any?
  133. var mouseRightMenuEvent: NSEvent?
  134. lazy private var homeVC: KMNHomeViewController? = {
  135. let vc = KMNHomeViewController()
  136. return vc
  137. }()
  138. fileprivate var _secureOptions: [CPDFDocumentWriteOption : Any]?
  139. var secureOptions: [CPDFDocumentWriteOption : Any]? {
  140. get {
  141. return self._secureOptions
  142. }
  143. }
  144. var documentAttribute: [CPDFDocumentAttribute : Any]?
  145. fileprivate var _removeSecureFlag = false
  146. var removeSecureFlag: Bool {
  147. get {
  148. return self._removeSecureFlag
  149. }
  150. }
  151. fileprivate var _saveWatermarkFlag = false
  152. var saveWatermarkFlag: Bool {
  153. get {
  154. return self._saveWatermarkFlag
  155. }
  156. }
  157. private var mainWindow_: NSWindow?
  158. var mainWindow: NSWindow? {
  159. get {
  160. return self.mainWindow_
  161. }
  162. set {
  163. self.mainWindow_ = newValue
  164. }
  165. }
  166. var setDocument: CPDFDocument? {
  167. get {
  168. return document
  169. }
  170. set {
  171. if document != newValue {
  172. document = newValue
  173. }
  174. listView.document = document
  175. botaViewController?.changeDocument(document: document)
  176. }
  177. }
  178. var setPageNumber: UInt {
  179. get {
  180. return pageNumber!
  181. }
  182. set {
  183. let pageCount = listView.document?.pageCount ?? 0
  184. var value = newValue
  185. if value > pageCount {
  186. value = pageCount
  187. }
  188. if value > 0 && listView.currentPage().pageIndex() != value-1 {
  189. listView.go(to: listView.document?.page(at: value-1))
  190. }
  191. if pageNumber != value {
  192. pageNumber = value
  193. }
  194. }
  195. }
  196. //MARK: - func
  197. deinit {
  198. NotificationCenter.default.removeObserver(self)
  199. self.listView.delegate = nil
  200. self.listView.document?.delegate = nil
  201. self.removeEventMonitor()
  202. }
  203. override func viewDidLoad() {
  204. super.viewDidLoad()
  205. // Do view setup here.
  206. setupData()
  207. setupUI()
  208. }
  209. override func viewDidAppear() {
  210. super.viewDidAppear()
  211. reloadPopUIWindow()
  212. addEventMonitor()
  213. addKeyEventMonitor()
  214. }
  215. override func viewDidDisappear() {
  216. super.viewDidDisappear()
  217. toggleClosePopUIWindow()
  218. }
  219. override func initContentView() {
  220. super.initContentView()
  221. }
  222. override func updateUIThemeColor() {
  223. super.updateUIThemeColor()
  224. }
  225. override func updateUILanguage() {
  226. super.updateUILanguage()
  227. }
  228. //MARK: - private
  229. func setupUI() {
  230. initPDFView()
  231. initToolbar()
  232. initSideBar()
  233. setUpSplitView()
  234. }
  235. func setupData() {
  236. toolbarManager.pdfViewManager = viewManager
  237. if (UserDefaults.standard.object(forKey: CPDFViewLeftSidePaneWidthKey) != nil) {
  238. UserDefaults.standard.set(MIN_SIDE_PANE_WIDTH, forKey: CPDFViewLeftSidePaneWidthKey)
  239. UserDefaults.standard.synchronize()
  240. }
  241. newMwcFlags.settingUpWindow = true
  242. Task {
  243. self.addAutoSaveEvent()
  244. }
  245. }
  246. @objc func editFontColorItemPanelAction(_ sender: Any) {
  247. if let color = (sender as? NSColorPanel)?.color {
  248. listView.changeEditingTextarea_Color(color: color)
  249. }
  250. }
  251. //MARK: - document load成功
  252. private func documentLoadComplete() {
  253. initLeftSideController()
  254. addNotificationCenter()
  255. activityLoadMethod()
  256. let readModel = UserDefaults.standard.bool(forKey: CPDFViewIsReadModeKey)
  257. if readModel == true {
  258. self.openPDFReadMode()
  259. }
  260. reloadDigitalSigns()
  261. alertTipViewController.showInView(listView: listView, subView: infoSplitCenterView)
  262. alertTipViewController.formFieldHighlightCallback = { [weak self] in
  263. let value = CPDFKitConfig.sharedInstance().enableFormFieldHighlight()
  264. CPDFAnnotation.updateHighlightFormFiled(self?.listView, highlightFormFiled: !value)
  265. self?.toolbarManager.refreshDefaultConfigItem()
  266. }
  267. alertTipViewController.enterPasswordCallback = { [weak self] in
  268. self?.removeOwnerPassword()
  269. }
  270. alertTipViewController.digitalDetailsCallback = { [weak self] in
  271. }
  272. alertTipViewController.redactApplyCallback = { [weak self] in
  273. self?.redactApplyAction()
  274. }
  275. alertTipViewController.heightCallback = { [weak self] height in
  276. self?.infoSplitViewTopConst.constant = height
  277. }
  278. newMwcFlags.settingUpWindow = false
  279. loadUserDefaultsData()
  280. }
  281. private func reloadDigitalSigns() {
  282. let signatures = listView.document.signatures()
  283. for i in 0 ..< (signatures?.count ?? 0) {
  284. let signature:CPDFSignature = signatures?[i] ?? CPDFSignature()
  285. if signature.signers.count > 0 {
  286. signature.verifySignature(with: listView.document)//耗时,注意
  287. }
  288. }
  289. listView.signatures = signatures
  290. }
  291. //MARK: - 活动加载相关
  292. private func activityLoadMethod() {
  293. }
  294. private func addNotificationCenter() {
  295. NotificationCenter.default.addObserver(self, selector: #selector(annotationsAttributeHasChange), name: NSNotification.Name.CPDFListViewAnnotationsAttributeHasChange, object:nil)
  296. NotificationCenter.default.addObserver(self, selector: #selector(signatureStateChangeNoti), name: NSNotification.Name(rawValue: "CSignatureTrustCerDidChangeNotification"), object: nil)
  297. NotificationCenter.default.addObserver(self, selector: #selector(pdfViewScrollViewDidScroll), name: NSScrollView.didLiveScrollNotification, object: listView.documentView())
  298. NotificationCenter.default.addObserver(self, selector: #selector(pageCountChangedNotification), name: NSNotification.Name.CPDFDocumentPageCountChanged, object: listView.document)
  299. NotificationCenter.default.addObserver(self, selector: #selector(documentDidUnlockNotification), name: Notification.Name("CPDFDocumentDidUnlockNotification"), object: nil)
  300. NotificationCenter.default.addObserver(self, selector: #selector(applicationWillTerminateNotification), name: NSApplication.willTerminateNotification, object: nil)
  301. NotificationCenter.default.addObserver(self, selector: #selector(pdfViewHighlightFormFiledUpdateNoti), name: kPDFViewHighlightFormFiledUpdateNotiName, object: nil)
  302. NotificationCenter.default.addObserver(self, selector: #selector(rename(_:)), name: NSNotification.Name.init(rawValue: "KMTabControllerRename"), object: nil)
  303. NotificationCenter.default.addObserver(self, selector: #selector(showInFinder(_:)), name: NSNotification.Name.init(rawValue: "KMTabControllerShowInFinder"), object: nil)
  304. }
  305. internal func removeNotifications() {
  306. NotificationCenter.default.removeObserver(self)
  307. }
  308. //MARK: - 初始化默认PDF数据
  309. private func loadUserDefaultsData() {
  310. applyLeftSideWidth(0, rightSideWidth: 0) //初始打开左边栏
  311. //初始化侧边栏打开内容
  312. if SettingsManager.sharedInstance.leftPanelType == .defaultOpen {
  313. if SettingsManager.sharedInstance.defaultOpen == .thumbnail {
  314. viewManager.pdfSideBarType = .thumbnail
  315. } else if SettingsManager.sharedInstance.defaultOpen == .outline {
  316. viewManager.pdfSideBarType = .outline
  317. } else if SettingsManager.sharedInstance.defaultOpen == .bookmark {
  318. viewManager.pdfSideBarType = .bookmark
  319. } else if SettingsManager.sharedInstance.defaultOpen == .annotation {
  320. viewManager.pdfSideBarType = .annotation
  321. }
  322. } else if SettingsManager.sharedInstance.leftPanelType == .sameAsLastOpen {
  323. if let value = UserDefaults.standard.value(forKey: "KMPDFSidebarTypeKey"), let data = value as? Int {
  324. let pdfSideBarType: KMPDFSidebarType = KMPDFSidebarType(rawValue: data) ?? .none
  325. viewManager.pdfSideBarType = pdfSideBarType
  326. }
  327. } else if SettingsManager.sharedInstance.leftPanelType == .hideLeftSide {
  328. viewManager.pdfSideBarType = .none
  329. } else if SettingsManager.sharedInstance.leftPanelType == .prioritizeOutline {
  330. if let rootOutline = self.listView.document.outlineRoot(), rootOutline.numberOfChildren > 0 {
  331. viewManager.pdfSideBarType = .outline
  332. }
  333. }
  334. if viewManager.pdfSideBarType == .none {
  335. toggleCloseLeftSide()
  336. } else {
  337. DispatchQueue.main.asyncAfter(deadline: DispatchTime.now() + 0.15) {
  338. self.toggleCloseLeftSide()
  339. self.toggleOpenLeftSide(pdfSideBarType: self.viewManager.pdfSideBarType)
  340. }
  341. }
  342. //Layout & Zoom
  343. let layoutType = SettingsManager.sharedInstance.layoutType
  344. if layoutType == .singlePage {
  345. self.updatePDFViewDisplayMode(viewMode: .singlePage)
  346. } else if layoutType == .singlePageContinue {
  347. self.updatePDFViewDisplayMode(viewMode: .singlePageContinuous)
  348. } else if layoutType == .twoPage {
  349. self.updatePDFViewDisplayMode(viewMode: .twoUp)
  350. } else if layoutType == .twoPageContinue {
  351. self.updatePDFViewDisplayMode(viewMode: .twoUpContinuous)
  352. } else if layoutType == .bookMode {
  353. self.updatePDFViewDisplayMode(isbookMode: true, direction: .horizontal)
  354. } else if layoutType == .bookModeContinue {
  355. self.updatePDFViewDisplayMode(isbookMode: true, direction: .vertical)
  356. }
  357. if self.listView.document != nil {
  358. if let pageIndex = KMPreferenceManager.shared.getPageNumber(forKey: self.listView.document.documentURL.path) {
  359. DispatchQueue.main.asyncAfter(deadline: DispatchTime.now() + 0.15) {
  360. self.listView.go(toPageIndex: pageIndex, animated: false)
  361. }
  362. }
  363. if let scale = KMPreferenceManager.shared.getPageScale(forKey: self.listView.document.documentURL.path) {
  364. self.listView.scaleFactor = CGFloat(scale)
  365. } else {
  366. let zoomType = SettingsManager.sharedInstance.zoomType
  367. self.refreshPDFViewZoomInfo(zoomType)
  368. }
  369. }
  370. }
  371. func refreshPDFViewZoomInfo(_ zoomType: zoomInfoType) {
  372. if zoomType == .adaptationWidth {
  373. listView.autoScales = true
  374. } else if zoomType == .adapPage {
  375. let pageHeight = listView.currentPage().size.height
  376. let pdfviewHeight = listView.bounds.size.height
  377. listView.scaleFactor = pdfviewHeight/pageHeight
  378. listView.autoScales = false
  379. } else if zoomType == .actualSize {
  380. if listView.scaleFactor != 1.0 {
  381. listView.scaleFactor = 1.0
  382. listView.autoScales = false
  383. }
  384. } else if zoomType == .percent_10 {
  385. listView.scaleFactor = 0.1
  386. } else if zoomType == .percent_25 {
  387. listView.scaleFactor = 0.25
  388. } else if zoomType == .percent_50 {
  389. listView.scaleFactor = 0.5
  390. } else if zoomType == .percent_75 {
  391. listView.scaleFactor = 0.75
  392. } else if zoomType == .percent_100 {
  393. listView.scaleFactor = 1.0
  394. } else if zoomType == .percent_150 {
  395. listView.scaleFactor = 1.5
  396. } else if zoomType == .percent_200 {
  397. listView.scaleFactor = 2.0
  398. } else if zoomType == .percent_400 {
  399. listView.scaleFactor = 4.0
  400. } else if zoomType == .percent_800 {
  401. listView.scaleFactor = 8.0
  402. }
  403. }
  404. func applyLeftSideWidth(_ leftSideWidth: CGFloat, rightSideWidth: CGFloat) -> Void {
  405. infoContendSplitView.setPosition(infoContendSplitView.maxPossiblePositionOfDivider(at: 1) - infoContendSplitView.dividerThickness - rightSideWidth, ofDividerAt: 1)
  406. infoContendSplitView.setPosition(leftSideWidth, ofDividerAt: 0)
  407. }
  408. //MARK: - PDFView
  409. func initPDFView() {
  410. listView.autoresizingMask = [.width, .height]
  411. listView.autoScales = true
  412. listView.delegate = self
  413. listView.pdfListViewDelegate = self
  414. listView.document = self.document
  415. listView.pageBreakMargins = NSEdgeInsetsMake(10, 0, 10, 10)
  416. listView.hideNotes = false
  417. if let _ = UserDefaults.standard.value(forKey: "kPDFViewShowFormFieldNameKey") {
  418. listView.showFormFieldName = UserDefaults.getDefaultBoolValue(forKey: "kPDFViewShowFormFieldNameKey")
  419. } else {
  420. listView.showFormFieldName = true
  421. }
  422. reloadPDFSplitInfo()
  423. }
  424. func updatePDFViewAnnotationMode() {
  425. let toolbarMode = viewManager.toolMode
  426. let subToolMode = viewManager.subToolMode
  427. listView.isHidden = false
  428. if toolbarMode == .None {
  429. listView.toolMode = .CTextToolMode
  430. listView.annotationType = .unkown
  431. } else if toolbarMode == .Markup {
  432. if subToolMode == .None {
  433. listView.toolMode = .CTextToolMode
  434. } else {
  435. listView.toolMode = .CNoteToolMode
  436. }
  437. //MARK: -Markup
  438. if subToolMode == .None {
  439. listView.annotationType = .unkown
  440. } else if subToolMode == .Highlight {
  441. listView.annotationType = .highlight
  442. } else if subToolMode == .Underline {
  443. listView.annotationType = .underline
  444. } else if subToolMode == .Waveline {
  445. listView.annotationType = .squiggly
  446. } else if subToolMode == .Strikethrough {
  447. listView.annotationType = .strikeOut
  448. } else if subToolMode == .Text {
  449. listView.annotationType = .freeText
  450. } else if subToolMode == .Note {
  451. listView.annotationType = .anchored
  452. } else if subToolMode == .Pen {
  453. listView.annotationType = .ink
  454. } else if subToolMode == .Eraser {
  455. listView.annotationType = .eraser
  456. } else if subToolMode == .Rectangle {
  457. listView.annotationType = .square
  458. } else if subToolMode == .Circle {
  459. listView.annotationType = .circle
  460. } else if subToolMode == .Arrow {
  461. listView.annotationType = .arrow
  462. } else if subToolMode == .Line {
  463. listView.annotationType = .line
  464. } else if subToolMode == .Measure {
  465. listView.annotationType = CPDFMeasureDefaultInfo.default_measureType()
  466. refreshMeasureInfo()
  467. } else if subToolMode == .Stamp {
  468. listView.annotationType = .stamp
  469. } else if subToolMode == .Sign {
  470. listView.annotationType = .signSignature
  471. }
  472. } else if toolbarMode == .Edit {
  473. //MARK: -编辑
  474. if subToolMode == .None {
  475. if listView.toolMode != .CEditPDFToolMode {
  476. listView.toolMode = .CEditPDFToolMode
  477. listView.configPDFEditingInfo()
  478. }
  479. let editingPDFLoadType: CEditingLoadType = listView.editingPDFLoadType()
  480. listView.setShouAddEdit([])
  481. listView.change([.text, .image])
  482. } else if subToolMode == .Edit_text {
  483. if listView.toolMode != .CEditPDFToolMode {
  484. listView.toolMode = .CEditPDFToolMode
  485. listView.configPDFEditingInfo()
  486. }
  487. listView.setShouAddEdit([.text])
  488. listView.change(.text)
  489. } else if subToolMode == .Edit_Image {
  490. if listView.toolMode != .CEditPDFToolMode {
  491. listView.toolMode = .CEditPDFToolMode
  492. listView.configPDFEditingInfo()
  493. }
  494. listView.setShouAddEdit([.image])
  495. listView.change(.image)
  496. } else if subToolMode == .Edit_Link {
  497. listView.toolMode = .CEditLinkToolMode
  498. listView.annotationType = .link
  499. } else if subToolMode == .Edit_Crop {
  500. listView.isHidden = true
  501. listView.toolMode = .CCropToolMode
  502. }
  503. if viewManager.editType == .watermark ||
  504. viewManager.editType == .background ||
  505. viewManager.editType == .header_Footer ||
  506. viewManager.editType == .bates {
  507. listView.isHidden = true
  508. listView.toolMode = .CTextToolMode
  509. }
  510. if subToolMode != .Edit_Crop {
  511. removeCropController()
  512. }
  513. self.showOCREditAlert()
  514. } else if toolbarMode == .Form {
  515. //MARK: -Form表单
  516. listView.toolMode = .CFormToolMode
  517. if subToolMode == .None {
  518. listView.annotationType = .unkown
  519. } else if subToolMode == .Form_text {
  520. listView.annotationType = .textField
  521. } else if subToolMode == .Form_checkbox {
  522. listView.annotationType = .checkBox
  523. } else if subToolMode == .Form_radio {
  524. listView.annotationType = .radioButton
  525. } else if subToolMode == .Form_list {
  526. listView.annotationType = .listMenu
  527. } else if subToolMode == .Form_dropdown {
  528. listView.annotationType = .comboBox
  529. } else if subToolMode == .Form_OK {
  530. listView.annotationType = .actionButton
  531. } else if subToolMode == .Form_digitalSign {
  532. listView.annotationType = .signature
  533. }
  534. } else if toolbarMode == .Fill {
  535. //MARK: -填充
  536. if subToolMode == .None {
  537. listView.toolMode = .CTextToolMode
  538. } else {
  539. listView.toolMode = .CNoteToolMode
  540. }
  541. if subToolMode == .None {
  542. } else if subToolMode == .Fill_tick {
  543. listView.annotationType = .signTure
  544. } else if subToolMode == .fill_fork {
  545. listView.annotationType = .signFalse
  546. } else if subToolMode == .fill_rectangle {
  547. listView.annotationType = .signCircle
  548. } else if subToolMode == .fill_line {
  549. listView.annotationType = .signLine
  550. } else if subToolMode == .fill_dot {
  551. listView.annotationType = .signDot
  552. } else if subToolMode == .fill_date {
  553. listView.annotationType = .signDate
  554. } else if subToolMode == .fill_sign {
  555. listView.annotationType = .signSignature
  556. }
  557. } else if toolbarMode == .Convert {
  558. //MARK: -转档
  559. listView.toolMode = .CTextToolMode
  560. } else if toolbarMode == .Protect {
  561. //MARK: -Protect
  562. listView.toolMode = .CTextToolMode
  563. if subToolMode == .Redact {
  564. //密文
  565. listView.annotationType = .redact
  566. listView.toolMode = .CRedactToolMode
  567. } else if subToolMode == .Digital_Sign {
  568. //数字签名
  569. listView.annotationType = .digitalSign
  570. listView.toolMode = .CDigitalSignToolMode
  571. self.enterDigitalSignature()
  572. }
  573. } else if toolbarMode == .Tools {
  574. //MARK: -工具
  575. // if subToolMode == .Tool_OCR {
  576. // listView.toolMode = .COCRToolMode
  577. // } else {
  578. // listView.toolMode = .CTextToolMode
  579. // }
  580. }
  581. if (toolbarMode != .Edit) {
  582. self.closeOCREditAlert()
  583. }
  584. }
  585. func showOrHideNotes() {
  586. self.listView.hideNotes = !self.listView.hideNotes
  587. let items = [toolbarManager.highlightProperty, toolbarManager.UnderlineProperty,
  588. toolbarManager.wavelineProperty, toolbarManager.strikethroughProperty,
  589. toolbarManager.textProperty, toolbarManager.noteProperty,
  590. toolbarManager.penProperty, toolbarManager.eraserProperty,
  591. toolbarManager.rectangleProperty, toolbarManager.circleProperty,
  592. toolbarManager.arrowProperty, toolbarManager.lineProperty,
  593. toolbarManager.measureProperty, toolbarManager.stampProperty,
  594. toolbarManager.signProperty]
  595. for item in items {
  596. item.isDisabled = listView.hideNotes
  597. }
  598. pdfToolbarController?.resetSecondToolbar(forceRefresh: true)
  599. }
  600. //MARK: - SplitView
  601. func setUpSplitView() {
  602. infoContendSplitView.wantsLayer = true
  603. infoContendSplitView.layer?.backgroundColor = NSColor.clear.cgColor
  604. infoContendSplitView.delegate = self
  605. infoContendSplitView.layer?.masksToBounds = true
  606. }
  607. func setupSplitPDFController() {
  608. if splitPDFController == nil {
  609. splitPDFController = KMSplitPDFViewController.init()
  610. }
  611. splitPDFController?.view.frame = pdfSplitBottomView.bounds
  612. splitPDFController?.view.autoresizingMask = [.height, .width]
  613. splitPDFController?.viewManager = self.viewManager
  614. splitPDFController?.delegate = self
  615. splitPDFController?.pdfView?.pdfListViewDelegate = self
  616. splitPDFController?.reloadData()
  617. pdfSplitBottomView.addSubview(splitPDFController!.view)
  618. }
  619. //MARK: - 工具栏
  620. func initToolbar() {
  621. toolbarBox.borderWidth = 0
  622. if pdfToolbarController == nil {
  623. pdfToolbarController = KMPDFToolbarController.init()
  624. }
  625. pdfToolbarController?.view.frame = toolbarBox.bounds
  626. pdfToolbarController?.view.autoresizingMask = [.width, .height]
  627. pdfToolbarController?.delegate = self
  628. toolbarBox.contentView = pdfToolbarController?.view
  629. pdfToolbarController?.viewManager = viewManager
  630. pdfToolbarController?.toolbarManager = toolbarManager
  631. pdfToolbarController?.pdfView = listView
  632. pdfToolbarController?.setUpData()
  633. refreshToolbarViewHeightInfo()
  634. if listView.showFormFieldName {
  635. toolbarManager.form_ShowName_Property.righticon = NSImage(named: "tick_Green")
  636. } else {
  637. toolbarManager.form_ShowName_Property.righticon = nil
  638. }
  639. DispatchQueue.main.asyncAfter(deadline: DispatchTime.now() + 0.15) {
  640. self.pdfToolbarController?.clickWithIdentify(KMPDFToolbar_Markup_Identifier)
  641. }
  642. }
  643. func refreshToolbarViewHeightInfo() {
  644. let _viewManager = viewManager
  645. if viewManager.isPageEditMode {
  646. toolbarBoxHeightConst.constant = 80
  647. } else if viewManager.editType == .watermark ||
  648. viewManager.editType == .background ||
  649. viewManager.editType == .header_Footer ||
  650. viewManager.editType == .bates {
  651. toolbarBoxHeightConst.constant = 40
  652. } else if _viewManager.toolMode == .Markup ||
  653. _viewManager.toolMode == .Edit ||
  654. _viewManager.toolMode == .Form ||
  655. _viewManager.toolMode == .Fill ||
  656. _viewManager.toolMode == .Convert ||
  657. _viewManager.toolMode == .Protect ||
  658. _viewManager.toolMode == .Tools {
  659. toolbarBoxHeightConst.constant = 80
  660. if _viewManager.subToolMode == .Redact {
  661. toolbarBoxHeightConst.constant = 40
  662. }
  663. } else {
  664. toolbarBoxHeightConst.constant = 40
  665. }
  666. }
  667. func toolbarViewModeChanged() {
  668. updatePDFViewAnnotationMode()
  669. refreshToolbarRightViewInfo()
  670. if viewManager.toolMode != .Edit && viewManager.subToolMode != .Edit_Crop {
  671. removeCropController()
  672. }
  673. }
  674. func updatePDFViewToolsType(_ viewToolsType: KMPDFViewToolsType) {
  675. viewManager.viewToolsType = viewToolsType
  676. pdfToolbarController?.reloadToolsView()
  677. if let toolbarVC = pdfToolbarController {
  678. kmPDFToolbarControllerDidViewToolsChanged(toolbarVC)
  679. }
  680. }
  681. //MARK: - 右边属性栏
  682. func refreshToolbarRightViewInfo() {
  683. //统一刷新viewManager.showRightSide, 由这个参数控制右边属性边框的展开与隐藏
  684. if viewManager.showRightSide == true {
  685. toolbarManager.rightViewProperty.state = .pressed
  686. toggleOpenRightSide()
  687. rightSideController?.reloadDataWithPDFView(pdfView: listView)
  688. } else {
  689. toggleCloseRightSide()
  690. }
  691. if viewManager.showRightSide == true {
  692. toolbarManager.rightViewProperty.state = .pressed
  693. } else {
  694. toolbarManager.rightViewProperty.state = .normal
  695. }
  696. pdfToolbarController?.reloadRightToolsView()
  697. }
  698. //MARK: - 侧边工具栏
  699. func initSideBar() {
  700. sidebarBox.borderWidth = 0
  701. if sideBarController == nil {
  702. sideBarController = KMPDFSideBarController.init()
  703. }
  704. sideBarController?.view.frame = sidebarBox.bounds
  705. sideBarController?.view.autoresizingMask = [.width, .height]
  706. sidebarBox.contentView = sideBarController?.view
  707. sideBarController?.pdfView = listView
  708. sideBarController?.delegate = self
  709. sideBarController?.pdfViewManager = viewManager
  710. sideBarController?.reloadData()
  711. }
  712. func reloadSideBar() {
  713. sideBarController?.reloadData()
  714. if viewManager.editType == .none {
  715. sideBarController?.searchItem.isHidden = false
  716. sideBarController?.thumbnailItem.isHidden = false
  717. sideBarController?.outlineItem.isHidden = false
  718. sideBarController?.bookmarkItem.isHidden = false
  719. sideBarController?.annotationItem.isHidden = false
  720. sideBarController?.aiToolItem.isHidden = false
  721. } else {
  722. sideBarController?.searchItem.isHidden = true
  723. sideBarController?.thumbnailItem.isHidden = true
  724. sideBarController?.outlineItem.isHidden = true
  725. sideBarController?.bookmarkItem.isHidden = true
  726. sideBarController?.annotationItem.isHidden = true
  727. sideBarController?.aiToolItem.isHidden = true
  728. }
  729. }
  730. //MARK: - 左边侧边栏
  731. func initLeftSideController() {
  732. if botaViewController == nil {
  733. botaViewController = KMNLeftSideViewController(listView.document)
  734. }
  735. botaViewController?.leftSideViewDelegate = self
  736. botaViewController?.view.frame = infoSplitLeftView.bounds
  737. botaViewController?.view.autoresizingMask = [.width, .height]
  738. if botaViewController != nil {
  739. infoSplitLeftView?.addSubview(botaViewController!.view)
  740. }
  741. }
  742. private func leftSidePaneIsOpen() -> Bool {
  743. return !infoContendSplitView.isSubviewCollapsed(infoSplitLeftView) //第一次点击时存在问题,待解决
  744. }
  745. func toggleOpenLeftSide(pdfSideBarType: KMPDFSidebarType) {
  746. if(leftSidePaneIsOpen() == false) {
  747. let leftWidthNumber = UserDefaults.standard.object(forKey: CPDFViewLeftSidePaneWidthKey) as? NSNumber ?? MIN_SIDE_PANE_WIDTH
  748. infoContendSplitView.setPosition(MIN_SIDE_PANE_WIDTH.doubleValue, ofDividerAt: 0) //暂时无法记录上一次打开的宽度
  749. }
  750. if pdfSideBarType == .search {
  751. botaViewController?.searchViewC.handdler.pdfView = listView
  752. botaViewController?.leftsideType = .search
  753. } else if pdfSideBarType == .thumbnail {
  754. botaViewController?.leftsideType = pdfSideBarType
  755. } else if pdfSideBarType == .outline {
  756. botaViewController?.outlineViewC.handdler.pdfView = listView
  757. botaViewController?.leftsideType = pdfSideBarType
  758. } else if pdfSideBarType == .bookmark {
  759. botaViewController?.bookmarkViewC.handdler.pdfView = listView
  760. botaViewController?.leftsideType = pdfSideBarType
  761. } else if pdfSideBarType == .annotation {
  762. botaViewController?.annoController.listView = listView
  763. botaViewController?.leftsideType = .annotation
  764. } else if pdfSideBarType == .aiTools {
  765. botaViewController?.leftsideType = .aiTools
  766. }
  767. }
  768. func toggleCloseLeftSide() {
  769. if(leftSidePaneIsOpen() == true) {
  770. infoContendSplitView.setPosition(0, ofDividerAt: 0)
  771. }
  772. }
  773. //MARK: - 右侧属性栏
  774. func initRightSideController() {
  775. if rightSideController == nil {
  776. rightSideController = KMRightSideController.init()
  777. rightSideController?.delegate = self
  778. }
  779. rightSideController?.view.frame = CGRectMake(0, 0, MIN_SIDE_PANE_WIDTH.doubleValue, 680)
  780. rightSideController?.view.autoresizingMask = [.height, .maxXMargin]
  781. }
  782. func removeRightSideController() {
  783. rightSideController?.view.removeFromSuperview()
  784. rightSideController = nil
  785. }
  786. @objc func toggleOpenRightSide() -> Void {
  787. if rightSideController != nil {
  788. return
  789. }
  790. initRightSideController()
  791. rightSideController?.view.frame = infoSplitRightView.bounds
  792. rightSideController?.view.autoresizingMask = [.width, .height]
  793. infoSplitRightView.addSubview(rightSideController!.view)
  794. infoContendSplitView.setPosition(CGRectGetWidth(view.frame)-MIN_SIDE_PANE_WIDTH.doubleValue, ofDividerAt: 1)
  795. rightSideController?.viewManager = self.viewManager
  796. rightSideController?.reloadDataWithPDFView(pdfView: listView)
  797. }
  798. @objc func toggleCloseRightSide() -> Void {
  799. removeRightSideController()
  800. infoContendSplitView.setPosition(CGRectGetWidth(view.frame), ofDividerAt: 1)
  801. viewManager.showRightSide = false
  802. pdfToolbarController?.reloadRightToolsView()
  803. }
  804. func refreshRightSide() -> Void {
  805. if let rightVC = rightSideController, let _ = rightSideController?.view.superview {
  806. rightVC.reloadDataWithPDFView(pdfView: listView)
  807. }
  808. }
  809. //MARK: - PDFDisplayView
  810. func updatePDFDisplaySettingView() {
  811. if viewManager.showDisplayView {
  812. infoSplitViewLeftConst.constant = 0
  813. infoContendSplitView.setPosition(MIN_SIDE_PANE_WIDTH.doubleValue, ofDividerAt: 0)
  814. } else {
  815. if viewManager.isPDFReadMode == false {
  816. infoSplitViewLeftConst.constant = 44
  817. if viewManager.pdfSideBarType == .none {
  818. toggleCloseLeftSide()
  819. } else {
  820. toggleOpenLeftSide(pdfSideBarType: viewManager.pdfSideBarType)
  821. }
  822. } else {
  823. toggleCloseLeftSide()
  824. }
  825. }
  826. if viewManager.showDisplayView {
  827. if displaySettingController == nil {
  828. displaySettingController = KMNDisplayViewController.init()
  829. }
  830. displaySettingController?.view.frame = CGRectMake(0, 0, MIN_SIDE_PANE_WIDTH.doubleValue, CGRectGetHeight(bottomContendBox.frame))
  831. displaySettingController?.view.autoresizingMask = [.height, .width]
  832. infoSplitLeftView.addSubview(displaySettingController!.view)
  833. displaySettingController?.pdfView = self.listView
  834. displaySettingController?.viewManager = self.viewManager
  835. displaySettingController?.delegate = self
  836. displaySettingController?.reloadData()
  837. } else {
  838. displaySettingController?.view.removeFromSuperview()
  839. displaySettingController = nil
  840. }
  841. }
  842. //MARK: - 页面编辑
  843. func enterPageEditMode() {
  844. if(pageEditViewController == nil) {
  845. pageEditViewController = KMNPageEditViewController(self.document)
  846. pageEditViewController?.view.frame = bottomContendBox.bounds
  847. pageEditViewController?.thumbnailBaseViewDelegate = self
  848. pageEditViewController?.selectionIndexPaths = [IndexPath(item: listView.currentPageIndex, section: 0)]
  849. pageEditViewController?.view.autoresizingMask = [.width,.height]
  850. pageEditViewController?.currentUndoManager = listView.undoManager
  851. }
  852. bottomContendBox.addSubview(pageEditViewController!.view)
  853. toolbarManager.page_pageInfo_Property.text = String(listView.currentPageIndex + 1)
  854. pdfToolbarController?.refreshSecondToolbarItemsState()
  855. listView.isHidden = true
  856. listView.updateActiveAnnotations([])
  857. listView.updateEditing([])
  858. }
  859. func exitPageEditMode() {
  860. if pageEditViewController != nil {
  861. pageEditViewController?.view.removeFromSuperview()
  862. }
  863. listView.isHidden = false
  864. if listView.document?.isModified() == true {
  865. listView.layoutDocumentView()
  866. botaViewController?.reloadData()
  867. }
  868. }
  869. //MARK: - 阅读模式
  870. func openPDFReadMode() {
  871. if viewManager.showDisplayView {
  872. UserDefaults.setDefaultBoolValue(true, toKey: "ShowDisplayViewWhenExitPDFReadMode")
  873. viewManager.showDisplayView = false
  874. pdfToolbarController?.reloadLeftIconView()
  875. updatePDFDisplaySettingView()
  876. }
  877. if infoSplitViewLeftConst.constant != 0 {
  878. infoSplitViewLeftConst.constant = 0
  879. updatePDFDisplaySettingView()
  880. }
  881. if viewManager.pdfSideBarType != .none {
  882. UserDefaults.setDefaultIntValue(viewManager.pdfSideBarType.rawValue, toKey: "viewManagerPdfSideBarTypeRawValue")
  883. viewManager.pdfSideBarType = .none
  884. }
  885. if listView.toolMode != .CNoteToolMode {
  886. listView.toolMode = .CNoteToolMode
  887. viewManager.viewToolsType = .Select
  888. pdfToolbarController?.reloadToolsView()
  889. }
  890. toolbarBoxHeightConst.constant = 0
  891. view.window?.makeFirstResponder(listView)
  892. self.componentMessageView.properties = ComponentMessageProperty(messageType: .normal_custom, title: KMLocalizedString("Read Mode On"))
  893. self.componentMessageView.frame = CGRectMake((CGRectGetWidth(self.view.frame) - self.componentMessageView.properties.propertyInfo.viewWidth)/2,
  894. CGRectGetHeight(self.view.frame) - self.componentMessageView.properties.propertyInfo.viewHeight - 8,
  895. self.componentMessageView.properties.propertyInfo.viewWidth,
  896. self.componentMessageView.properties.propertyInfo.viewHeight)
  897. self.componentMessageView.reloadData()
  898. self.componentMessageView.show(inView: self.view, autoHideSeconde: 2)
  899. setUpPDFPageNumberToolbar()
  900. if viewManager.toolMode != .Edit && viewManager.subToolMode != .Edit_Crop {
  901. removeCropController()
  902. }
  903. }
  904. func exitPDFReadMode() {
  905. viewManager.isPDFReadMode = false
  906. if UserDefaults.getDefaultBoolValue(forKey: "ShowDisplayViewWhenExitPDFReadMode") == true {
  907. if viewManager.showDisplayView == false {
  908. viewManager.showDisplayView = true
  909. pdfToolbarController?.reloadLeftIconView()
  910. }
  911. UserDefaults.setDefaultBoolValue(false, toKey: "ShowDisplayViewWhenExitPDFReadMode")
  912. }
  913. if let index = UserDefaults.getDefaultIntValue(forKey: "viewManagerPdfSideBarTypeRawValue") {
  914. let type = KMPDFSidebarType(rawValue: index) ?? .none
  915. viewManager.pdfSideBarType = type
  916. UserDefaults.standard.removeObject(forKey: "viewManagerPdfSideBarTypeRawValue")
  917. UserDefaults.standard.synchronize()
  918. }
  919. updatePDFDisplaySettingView()
  920. refreshToolbarViewHeightInfo()
  921. reloadPDFPageNumberToolbar()
  922. DispatchQueue.main.asyncAfter(deadline: DispatchTime.now() + 0.1) {
  923. self.componentMessageView.properties = ComponentMessageProperty(messageType: .normal_custom, title: KMLocalizedString("Read Mode Off"))
  924. self.componentMessageView.frame = CGRectMake((CGRectGetWidth(self.infoSplitCenterView.frame) - self.componentMessageView.properties.propertyInfo.viewWidth)/2,
  925. CGRectGetHeight(self.infoSplitCenterView.frame) - self.componentMessageView.properties.propertyInfo.viewHeight - 8,
  926. self.componentMessageView.properties.propertyInfo.viewWidth,
  927. self.componentMessageView.properties.propertyInfo.viewHeight)
  928. self.componentMessageView.reloadData()
  929. self.componentMessageView.show(inView: self.infoSplitCenterView, autoHideSeconde: 2)
  930. }
  931. }
  932. //MARK: - PPT
  933. func togglePresentation(_ sender: Any?) {
  934. if self.canExitPresentation() {
  935. exitFullScreen()
  936. } else if self.canEnterPresentation() {
  937. NotificationCenter.default.addObserver(self, selector: #selector(willEnterInteractionModeNotification), name: NSWindow.willEnterInteractionModeNotification, object: nil)
  938. NotificationCenter.default.addObserver(self, selector: #selector(didEnterInteractionModeNotification), name: NSWindow.didEnterInteractionModeNotification, object: nil)
  939. NotificationCenter.default.addObserver(self, selector: #selector(willShowFullScreenNotification), name: NSWindow.willShowFullScreenNotification, object: nil)
  940. NotificationCenter.default.addObserver(self, selector: #selector(didShowFullScreenNotification), name: NSWindow.didShowFullScreenNotification, object: nil)
  941. view.window?.enterPresentation(provider: self)
  942. if listView.toolMode != .CNoteToolMode {
  943. listView.toolMode = .CNoteToolMode
  944. viewManager.viewToolsType = .Select
  945. pdfToolbarController?.reloadToolsView()
  946. }
  947. }
  948. }
  949. func enterPresentationMode() {
  950. let scrollView = listView.documentView().enclosingScrollView
  951. savedNormalSetup.setValue(scrollView?.hasHorizontalScroller, forKey: KMMainModel.Key.kHasHorizontalScroller)
  952. savedNormalSetup.setValue(scrollView?.hasVerticalScroller, forKey: KMMainModel.Key.kHasVerticalsCroller)
  953. savedNormalSetup.setValue(scrollView?.autohidesScrollers, forKey: KMMainModel.Key.kAutoHidesScrollers)
  954. listView.backgroundColor = NSColor.clear
  955. listView.setDisplay(.singlePage)
  956. listView.autoScales = true
  957. listView.displayBox = .cropBox
  958. listView.displaysPageBreaks = false
  959. scrollView?.autohidesScrollers = true
  960. scrollView?.hasHorizontalScroller = false
  961. scrollView?.hasVerticalScroller = false
  962. listView.setCurrentSelection(nil, animate: true)
  963. }
  964. func exitPresentationMode() {
  965. NotificationCenter.default.removeObserver(self, name: NSWindow.willEnterInteractionModeNotification, object: nil)
  966. NotificationCenter.default.removeObserver(self, name: NSWindow.didEnterInteractionModeNotification, object: nil)
  967. NotificationCenter.default.removeObserver(self, name: NSWindow.willShowFullScreenNotification, object: nil)
  968. NotificationCenter.default.removeObserver(self, name: NSWindow.willShowFullScreenNotification, object: nil)
  969. }
  970. func exitFullScreen() {
  971. if self.canExitPresentation() == true {
  972. let mainDocument = self.myDocument as? KMMainDocument
  973. let browserWindowController = mainDocument?.browser?.windowController as? KMBrowserWindowController
  974. browserWindowController?.exitFullscreen()
  975. }
  976. }
  977. func exitFullscreenMode() {
  978. if self.interactionMode == .presentation {
  979. self.exitPresentationMode()
  980. }
  981. self.applyPDFSettings(self.savedNormalSetup)
  982. self.savedNormalSetup.removeAllObjects()
  983. listView.layoutDocumentView()
  984. listView.requiresDisplay()
  985. if let backgroundColor = UserDefaults.standard.color(forKey: KMBackgroundColorKey) {
  986. listView.backgroundColor = backgroundColor
  987. }
  988. reloadPDFSplitInfo()
  989. }
  990. func applyPDFSettings(_ setup: NSDictionary) {
  991. if let data = setup.object(forKey: KMMainModel.Key.kAutoScales) as? NSNumber {
  992. self.listView.autoScales = data.boolValue
  993. }
  994. if self.listView.autoScales == false {
  995. if let data = setup.object(forKey: KMMainModel.Key.kScaleFactor) as? NSNumber {
  996. self.listView.scaleFactor = data.floatValue.cgFloat
  997. }
  998. }
  999. if let data = setup.object(forKey: KMMainModel.Key.kDisplayMode) as? NSNumber {
  1000. self.listView.setDisplay(CPDFDisplayViewMode(rawValue: data.intValue) ?? .singlePage)
  1001. }
  1002. if let data = setup.object(forKey: KMMainModel.Key.kDisplaysAsBook) as? NSNumber {
  1003. self.listView.displaysAsBook = data.boolValue
  1004. }
  1005. if let data = setup.object(forKey: KMMainModel.Key.kDisplaysPageBreaks) as? NSNumber {
  1006. self.listView.displaysPageBreaks = data.boolValue
  1007. }
  1008. if let data = setup.object(forKey: KMMainModel.Key.kDisplayBox) as? NSNumber {
  1009. }
  1010. self.listView.layoutDocumentView()
  1011. }
  1012. func currentPDFSettings() -> NSDictionary {
  1013. let setup = NSMutableDictionary()
  1014. setup[KMMainModel.Key.kDisplaysPageBreaks] = NSNumber(value: listView.displaysPageBreaks)
  1015. setup[KMMainModel.Key.kDisplaysAsBook] = NSNumber(value: listView.displaysAsBook)
  1016. setup[KMMainModel.Key.kDisplayBox] = NSNumber(value: listView.displayBox.rawValue)
  1017. setup[KMMainModel.Key.kScaleFactor] = NSNumber(value: listView.scaleFactor)
  1018. setup[KMMainModel.Key.kAutoScales] = NSNumber(value: listView.autoScales)
  1019. setup[KMMainModel.Key.kDisplayMode] = NSNumber(value: listView.fetchDisplayViewMode().rawValue)
  1020. return setup
  1021. }
  1022. func canEnterFullscreen() -> Bool {
  1023. if (mwcFlags.isSwitchingFullScreen != 0) {
  1024. return false
  1025. }
  1026. if useNativeFullScreen() {
  1027. return interactionMode == .normal || interactionMode == .presentation
  1028. } else {
  1029. return !self.listView.document.isLocked && (interactionMode == .normal || interactionMode == .presentation) && self.view.window?.tabbedWindows?.count ?? 0 < 2
  1030. }
  1031. }
  1032. override func canEnterPresentation() -> Bool {
  1033. let can = super.canEnterPresentation()
  1034. if can == false {
  1035. return false
  1036. }
  1037. guard let doc = self.listView.document, doc.isLocked == false else {
  1038. return false
  1039. }
  1040. return can
  1041. }
  1042. func fadeOutFullScreenWindow() {
  1043. guard let fullScreenWindow = self.view.window as? KMFullScreenWindow else {
  1044. NSSound.beep()
  1045. return
  1046. }
  1047. let mainWindow = fullScreenWindow.interactionParent
  1048. let collectionBehavior = mainWindow?.collectionBehavior
  1049. mainWindow?.alphaValue = 0
  1050. if let data = mainWindow?.responds(to: NSSelectorFromString("setAnimationBehavior:")), data {
  1051. mainWindow?.animationBehavior = .none
  1052. }
  1053. // trick to make sure the main window shows up in the same space as the fullscreen window
  1054. fullScreenWindow.addChildWindow(mainWindow!, ordered: .below)
  1055. fullScreenWindow.removeChildWindow(mainWindow!)
  1056. fullScreenWindow.level = .popUpMenu
  1057. // these can change due to the child window trick
  1058. mainWindow?.level = .normal
  1059. mainWindow?.alphaValue = 1.0
  1060. mainWindow?.collectionBehavior = collectionBehavior!
  1061. mainWindow?.display()
  1062. mainWindow?.makeFirstResponder(self.listView)
  1063. mainWindow?.recalculateKeyViewLoop()
  1064. // mainWindow?.delegate = self
  1065. mainWindow?.makeKey()
  1066. if let data = mainWindow?.responds(to: NSSelectorFromString("setAnimationBehavior:")), data {
  1067. mainWindow?.animationBehavior = .default
  1068. }
  1069. NSApp.removeWindowsItem(fullScreenWindow)
  1070. fullScreenWindow.fadeOut()
  1071. }
  1072. //MARK: - PDF分屏视图
  1073. func reloadPDFSplitInfo() {
  1074. if listView.viewSplitMode == .disable {
  1075. pdfSplitView.isHidden = true
  1076. listView.frame = infoSplitCenterSubView.bounds
  1077. infoSplitCenterSubView.addSubview(listView)
  1078. if splitPDFController != nil {
  1079. splitPDFController = nil
  1080. }
  1081. } else {
  1082. pdfSplitView.isHidden = false
  1083. listView.frame = pdfSplitTopView.bounds
  1084. pdfSplitTopView.addSubview(listView)
  1085. setUpPDFPageNumberToolbar()
  1086. setupSplitPDFController()
  1087. if listView.viewSplitMode == .horizontal {
  1088. pdfSplitView.isVertical = false
  1089. } else if listView.viewSplitMode == .vertical {
  1090. pdfSplitView.isVertical = true
  1091. }
  1092. }
  1093. }
  1094. func setUpPDFPageNumberToolbar() {
  1095. if pageNumberToolbar != nil {
  1096. pageNumberToolbar?.removeFromSuperview()
  1097. pageNumberToolbar = nil
  1098. }
  1099. if pageNumberToolbar == nil {
  1100. pageNumberToolbar = KMPageNumberPromptView.init()
  1101. }
  1102. if viewManager.isPDFReadMode {
  1103. pageNumberToolbar?.frame = CGRectMake(CGRectGetWidth(listView.frame)/2-366/2, 20, 366, 40)
  1104. pageNumberToolbar?.hideBackForwordButton(false)
  1105. } else {
  1106. pageNumberToolbar?.frame = CGRectMake(CGRectGetWidth(listView.frame)/2-288/2, 20, 288, 40)
  1107. pageNumberToolbar?.hideBackForwordButton(true)
  1108. }
  1109. pageNumberToolbar?.autoresizingMask = [.minXMargin, .maxXMargin, .maxYMargin]
  1110. pageNumberToolbar?.pdfView = self.listView
  1111. pageNumberToolbar?.reloadData()
  1112. pageNumberToolbar?.isHidden = true
  1113. listView.addSubview(pageNumberToolbar!)
  1114. reloadPDFPageNumberToolbar()
  1115. }
  1116. func reloadPDFPageNumberToolbar() {
  1117. if viewManager.isPDFReadMode == true ||
  1118. (viewManager.splitShowBottomBar && listView.viewSplitMode != .disable) {
  1119. pageNumberToolbar?.isHidden = false
  1120. pageNumberToolbar?.reloadData()
  1121. } else {
  1122. pageNumberToolbar?.isHidden = true
  1123. }
  1124. }
  1125. //MARK: - Edit模式
  1126. func showEditToolbarView() {
  1127. if editToolbarView == nil {
  1128. editToolbarView = KMEditToolbarView()
  1129. }
  1130. editToolbarView?.frame = toolbarBox.bounds
  1131. editToolbarView?.delegate = self
  1132. editToolbarView?.autoresizingMask = [.width, .height]
  1133. toolbarBox.contentView = editToolbarView
  1134. reloadSideBar()
  1135. }
  1136. func exitEditToolbarView() {
  1137. viewManager.editType = .none
  1138. viewManager.subToolMode = .None
  1139. editToolbarView?.removeFromSuperview()
  1140. editToolbarView = nil
  1141. watermarkViewController?.view.removeFromSuperview()
  1142. watermarkViewController = nil
  1143. backgroundViewController?.view.removeFromSuperview()
  1144. backgroundViewController = nil
  1145. headerFooterViewController?.view.removeFromSuperview()
  1146. headerFooterViewController = nil
  1147. batesViewController?.view.removeFromSuperview()
  1148. batesViewController = nil
  1149. refreshToolbarViewHeightInfo()
  1150. toolbarBox.contentView = pdfToolbarController?.view
  1151. updatePDFViewAnnotationMode()
  1152. reloadSideBar()
  1153. KMWatermarkManager.defaultManager.defaultWatermarkData = KMWatermarkModel.defaultWDData()
  1154. }
  1155. func updateEditModeDocumentWhenPageChanged() {
  1156. if viewManager.editType == .watermark {
  1157. updateWatermarkDocument()
  1158. } else if viewManager.editType == .background {
  1159. updateBackgroundDocument()
  1160. } else if viewManager.editType == .header_Footer {
  1161. updateHeaderFooterDocument()
  1162. } else if viewManager.editType == .bates {
  1163. updateBatesDocument()
  1164. } else if viewManager.subToolMode == .Edit_Crop {
  1165. updateCropDocument()
  1166. }
  1167. }
  1168. func menuItemAction_FontPanel() {
  1169. NSFontManager.shared.target = self
  1170. NSFontManager.shared.action = #selector(changeFont(_:))
  1171. NSFontManager.shared.orderFrontFontPanel(nil)
  1172. }
  1173. func menuItemAction_FontAction(_ index: Int) {
  1174. if index == 0 {
  1175. self.listView.setEditingTextarea(isBold: true)
  1176. } else if index == 1 {
  1177. self.listView.setEditingTextarea(isItalic: true)
  1178. } else if index == 2 {
  1179. self.listView.fontAddAction()
  1180. } else if index == 3 {
  1181. self.listView.fontReduceAction()
  1182. } else if index == 4 {
  1183. let colorPanel = NSColorPanel.shared
  1184. colorPanel.setTarget(self)
  1185. colorPanel.showsAlpha = false
  1186. colorPanel.setAction(#selector(self.menuItemAction_FontColor(_:)))
  1187. colorPanel.orderFront(nil)
  1188. }
  1189. }
  1190. func menuItemAction_FontAlign(_ index: Int) {
  1191. if index == 0 {
  1192. self.listView.setEditingTextarea_Alignment(align: .left)
  1193. } else if index == 1 {
  1194. self.listView.setEditingTextarea_Alignment(align: .center)
  1195. } else if index == 2 {
  1196. self.listView.setEditingTextarea_Alignment(align: .right)
  1197. }
  1198. }
  1199. func menuItemAction_CustomFont(_ index: Int) {
  1200. if index == 0 {
  1201. let model = KMEditPDFTextManager.manager.fetchUserDefaultData(type: .h1)
  1202. self.updateEditPDFTextFontModel(model)
  1203. } else if index == 1 {
  1204. let model = KMEditPDFTextManager.manager.fetchUserDefaultData(type: .h2)
  1205. self.updateEditPDFTextFontModel(model)
  1206. } else if index == 2 {
  1207. let model = KMEditPDFTextManager.manager.fetchUserDefaultData(type: .h3)
  1208. self.updateEditPDFTextFontModel(model)
  1209. } else if index == 3 {
  1210. let model = KMEditPDFTextManager.manager.fetchUserDefaultData(type: .b1)
  1211. self.updateEditPDFTextFontModel(model)
  1212. } else if index == 4 {
  1213. let model = KMEditPDFTextManager.manager.fetchUserDefaultData(type: .b2)
  1214. self.updateEditPDFTextFontModel(model)
  1215. } else if index == 5 {
  1216. let model = KMEditPDFTextManager.manager.fetchUserDefaultData(type: .b3)
  1217. self.updateEditPDFTextFontModel(model)
  1218. }
  1219. }
  1220. @objc func menuItemAction_FontColor(_ sender: Any) {
  1221. if let color = (sender as? NSColorPanel)?.color {
  1222. listView.changeEditingTextarea_Color(color: color)
  1223. }
  1224. }
  1225. @objc func changeFont(_ sender: NSFontManager) {
  1226. let newFont = sender.convert(NSFont.systemFont(ofSize: 14))
  1227. let value = CPDFFont(familyName: newFont.fontName, fontStyle: newFont.style ?? "Regular")
  1228. listView.setEditingTextarea_font(font: value)
  1229. listView.setEditingTextarea_FontSize(size: newFont.pointSize)
  1230. rightSideController?.reloadData()
  1231. }
  1232. //MARK: - 数字签名
  1233. func writeSignatureToWidget(_ widget: CPDFSignatureWidgetAnnotation, _ path: String, _ password: String, _ config: CPDFSignatureConfig, _ isLock: Bool) ->() {
  1234. let fileName = listView.document.documentURL?.lastPathComponent
  1235. let fileNameWithoutExtension = URL(fileURLWithPath: fileName!).deletingPathExtension().lastPathComponent
  1236. let outputSavePanel = NSSavePanel()
  1237. outputSavePanel.directoryURL = listView.document.documentURL.deletingLastPathComponent()
  1238. outputSavePanel.title = KMLocalizedString("", comment: "Save as PDF")
  1239. outputSavePanel.allowedFileTypes = ["pdf"]
  1240. outputSavePanel.nameFieldStringValue = fileNameWithoutExtension + "_" + KMLocalizedString("Signed", comment: "")
  1241. let result = outputSavePanel.runModal()
  1242. if result == .OK {
  1243. let contentArr = NSMutableArray()
  1244. var locationStr = ""
  1245. var reasonStr = KMLocalizedString("none", comment: "")
  1246. for item in config.contents {
  1247. if item.key == KMLocalizedString("Reason", comment: "") {
  1248. if item.value == KMLocalizedString("<your signing reason here>", comment: "") {
  1249. item.value = " " + KMLocalizedString("none", comment: "")
  1250. }
  1251. reasonStr = item.value
  1252. } else if item.key == KMLocalizedString("Location", comment: "") {
  1253. if item.value == KMLocalizedString("<your signing location here>", comment: "") {
  1254. item.value = " "
  1255. }
  1256. locationStr = item.value
  1257. }
  1258. contentArr.add(item)
  1259. }
  1260. config.contents = contentArr as? [CPDFSignatureConfigItem]
  1261. widget.setFieldName(widget.getValidName(inPage: widget.page))
  1262. widget.signAppearanceConfig(config)
  1263. let success = listView.document.writeSignature(to: outputSavePanel.url, withWidget: widget, pkcs12Cert: path, password: password, location: locationStr, reason: reasonStr, permissions: .forbidChange)
  1264. widget.removeSignature()
  1265. if success {
  1266. DispatchQueue.main.asyncAfter(deadline: DispatchTime.now() + 0.3) {
  1267. NSDocumentController.shared.openDocument(withContentsOf: outputSavePanel.url!, display: true) { document, documentWasAlreadyOpen, error in
  1268. if error != nil {
  1269. NSApp.presentError(error!)
  1270. return
  1271. }
  1272. }
  1273. }
  1274. } else {
  1275. let alert = NSAlert.init()
  1276. alert.messageText = KMLocalizedString("Save failed!", comment: "")
  1277. alert.addButton(withTitle: KMLocalizedString("OK", comment: ""))
  1278. alert.runModal()
  1279. }
  1280. widget.page.removeAnnotation(widget)
  1281. listView.setNeedsDisplayAnnotationViewFor(widget.page)
  1282. } else {
  1283. widget.page.removeAnnotation(widget)
  1284. listView.setNeedsDisplayAnnotationViewFor(widget.page)
  1285. }
  1286. }
  1287. func popUpSignatureWidgetState(_ signature: CPDFSignature, _ pdfListView: CPDFListView) ->(){
  1288. signaturestateVC.signature = signature
  1289. signaturestateVC.pdfListView = pdfListView
  1290. signaturestateVC.actionBlock = { [weak self, weak signaturestateVC] stateVCSelf, actionType in
  1291. guard let weakSelf = self, let stateVC = signaturestateVC else { return }
  1292. if actionType == .cancel {
  1293. stateVC.dismiss(stateVCSelf)
  1294. } else if actionType == .confirm {
  1295. if let signer = signature.signers.first, let data = signer.certificates {
  1296. let signatureDetail = DSignatureDetailsViewController.init()
  1297. signatureDetail.certificates = data
  1298. signatureDetail.signature = signature
  1299. signatureDetail.pdfListView = pdfListView
  1300. stateVCSelf.presentAsSheet(signatureDetail)
  1301. } else {
  1302. NSSound.beep()
  1303. }
  1304. }
  1305. }
  1306. self.presentAsSheet(signaturestateVC)
  1307. signaturestateVC.reloadData()
  1308. }
  1309. func enterDigitalSignature() {
  1310. if UserDefaults.standard.object(forKey: "kDigitalSignature") != nil {
  1311. return
  1312. }
  1313. let alert = NSAlert()
  1314. alert.alertStyle = .informational
  1315. alert.messageText = KMLocalizedString("Using your mouse, click and drag to draw the area where you would like the signature to appear. Once you finish dragging out the desired area, you will be taken to the next step of the signing process. ")
  1316. alert.addButton(withTitle: KMLocalizedString("OK"))
  1317. alert.showsSuppressionButton = true
  1318. let response = alert.runModal()
  1319. if response.rawValue == 1000 {
  1320. if alert.suppressionButton?.state == .on {
  1321. UserDefaults.standard.set("YES", forKey: "kDigitalSignature")
  1322. UserDefaults.standard.synchronize()
  1323. }
  1324. }
  1325. }
  1326. // MARK: - 显示合并窗口
  1327. public func showMergeWindow(url: URL? = nil) {
  1328. DispatchQueue.main.async {
  1329. // var documentURL = url
  1330. //
  1331. // let filePath = documentURL?.path ?? ""
  1332. // if !FileManager.default.fileExists(atPath: filePath) {
  1333. // let alert = NSAlert.init()
  1334. // alert.alertStyle = .critical
  1335. // alert.messageText = "\(filePath.lastPathComponent) \(NSLocalizedString("File Not Exist", comment: ""))"
  1336. // alert.runModal()
  1337. // return
  1338. // }
  1339. //
  1340. // guard let _url = documentURL else { return }
  1341. // guard let document = PDFDocument(url: _url) else { return }
  1342. self.mergeWindowController = KMMergeWindowController(windowNibName: "KMMergeWindowController")
  1343. // self.mergeWindowController!.password = self.listView.document.password ?? ""
  1344. // self.mergeWindowController!.oriDucumentUrl = self.listView.document?.documentURL
  1345. // self.mergeWindowController!.pageIndex = self.listView.currentPageIndex
  1346. self.mergeWindowController!.cancelAction = { [unowned self] controller in
  1347. self.view.window?.endSheet(mergeWindowController!.window!)
  1348. }
  1349. self.mergeWindowController!.mergeAction = { [unowned self] controller, filePath in
  1350. self.view.window?.endSheet(mergeWindowController!.window!)
  1351. }
  1352. self.view.window?.beginSheet(self.mergeWindowController!.window!)
  1353. }
  1354. }
  1355. //MARK: - Crop裁剪
  1356. func showCropController() {
  1357. if cropController == nil {
  1358. cropController = KMCropController.init()
  1359. cropController?.view.frame = infoSplitCenterView.bounds
  1360. cropController?.view.autoresizingMask = [.width, .height]
  1361. cropController?.delegate = self
  1362. infoSplitCenterView.addSubview(cropController!.view)
  1363. if viewManager.showRightSide == false {
  1364. viewManager.showRightSide = true
  1365. refreshToolbarRightViewInfo()
  1366. }
  1367. updateCropDocument()
  1368. }
  1369. }
  1370. func updateCropDocument() {
  1371. guard let controller = cropController else { return }
  1372. controller.pdfDocument = nil
  1373. let page = listView.document.page(at: UInt(listView.currentPageIndex))
  1374. let editDocument = CPDFDocument.init()
  1375. editDocument?.insertPageObject(page, at: 0)
  1376. if let editPage = editDocument?.page(at: 0) {
  1377. let mediaRect = editPage.bounds(for: .mediaBox)
  1378. editPage.setBounds(mediaRect, for: .cropBox)
  1379. if let rect = KMCropManager.defaultManager.cropRect {
  1380. controller.selectionRect = rect
  1381. } else {
  1382. if KMCropManager.defaultManager.cropSeparateOn {
  1383. let rect = KMCropTools.getPageForegroundBox(editPage)
  1384. controller.selectionRect = rect
  1385. } else if KMCropManager.defaultManager.cropAutoOn {
  1386. let rect = KMCropTools.getPageForegroundBox(editPage)
  1387. controller.selectionRect = rect
  1388. } else {
  1389. controller.selectionRect = page?.bounds(for: .cropBox) ?? .zero
  1390. }
  1391. }
  1392. if let cropVC = rightSideController?.edit_cropController {
  1393. cropVC.pageCropBounds = page?.bounds(for: .cropBox) ?? .zero
  1394. cropVC.reloadData()
  1395. }
  1396. }
  1397. controller.pdfDocument = editDocument
  1398. controller.reloadData()
  1399. }
  1400. func removeCropController() {
  1401. if cropController != nil {
  1402. cropController?.view.removeFromSuperview()
  1403. cropController = nil
  1404. KMCropManager.defaultManager.clear()
  1405. toolbarManager.edit_crop_Property.state = .normal
  1406. }
  1407. }
  1408. // MARK: - Secure 【安全】
  1409. public func hiddenSecureLimitTip() {
  1410. }
  1411. func savePageNumberIfNeed() {
  1412. let scaleFactor = self.listView.scaleFactor
  1413. if scaleFactor <= 0 {
  1414. return
  1415. }
  1416. if self.listView.document != nil {
  1417. KMPreferenceManager.shared.setPageNumber(self.listView.currentPageIndex, forKey: self.listView.document.documentURL.path)
  1418. KMPreferenceManager.shared.setPageScale(Float(scaleFactor), forKey: self.listView.document.documentURL.path)
  1419. }
  1420. }
  1421. // MARK: - 显示加密弹窗
  1422. public func showSecureWindow() {
  1423. guard let url = self.listView.document?.documentURL else {
  1424. return
  1425. }
  1426. self.securityWindowController = KMSecurityWindowController(windowNibName: "KMSecurityWindowController")
  1427. guard let securityWindowController = securityWindowController else { return }
  1428. securityWindowController.documentURL = self.listView.document?.documentURL
  1429. securityWindowController.batchAction = { [unowned self] controller, files in
  1430. self.view.window?.endSheet((securityWindowController.window)!)
  1431. self.showBatchWindow(type: .security, files: [URL(fileURLWithPath: self.document?.documentURL.path ?? "")])
  1432. }
  1433. securityWindowController.doneAction = { [unowned self] controller, options, attribute in
  1434. let openPanel = NSOpenPanel()
  1435. openPanel.canChooseFiles = false
  1436. openPanel.canChooseDirectories = true
  1437. openPanel.canCreateDirectories = true
  1438. openPanel.beginSheetModal(for: NSWindow.currentWindow()) { (result) in
  1439. if result == NSApplication.ModalResponse.OK {
  1440. for fileURL in openPanel.urls {
  1441. let document = CPDFDocument(url: self.document?.documentURL)
  1442. if document != nil {
  1443. document!.setDocumentAttributes(attribute)
  1444. let path = fileURL.path.stringByAppendingPathComponent(url.deletingPathExtension().lastPathComponent) + "_SetPassword" + "." + url.pathExtension
  1445. let success = document!.write(to: NSURL(fileURLWithPath: path) as URL, withOptions: options)
  1446. if success {
  1447. self.view.window?.endSheet((securityWindowController.window)!)
  1448. NSWorkspace.shared.activateFileViewerSelecting([URL(fileURLWithPath: path)])
  1449. }
  1450. }
  1451. }
  1452. }
  1453. }
  1454. }
  1455. securityWindowController.cancelAction = { [unowned self] controller in
  1456. self.view.window?.endSheet((securityWindowController.window)!)
  1457. }
  1458. NSWindow.currentWindow().beginSheet(securityWindowController.window!)
  1459. }
  1460. // MARK: - 移除文档密码
  1461. public func showRemoveSecureWindow() {
  1462. var isDocumentLocked: Bool = false
  1463. if self.document?.allowsCopying == false || self.document?.allowsPrinting == false {
  1464. isDocumentLocked = true
  1465. } else if (self.document?.password ?? "").count > 0 {
  1466. isDocumentLocked = true
  1467. }
  1468. if isDocumentLocked == false {
  1469. let alert = NSAlert()
  1470. alert.alertStyle = .warning
  1471. alert.messageText = KMLocalizedString("This document doesn’t contain any security settings and doesn‘t need to be removed.")
  1472. alert.addButton(withTitle: KMLocalizedString("OK"))
  1473. alert.beginSheetModal(for: NSWindow.currentWindow()) { returnCode in
  1474. }
  1475. } else {
  1476. let controller = KMRemovePasswordWindowController(windowNibName: "KMRemovePasswordWindowController")
  1477. controller.pdfDocument = self.document
  1478. self.currentWindowController = controller
  1479. controller.batchAction = { [unowned self] controller, files in
  1480. self.view.window?.endSheet((self.currentWindowController.window)!)
  1481. self.currentWindowController = nil
  1482. var array: [URL] = []
  1483. for item in files {
  1484. array.append(NSURL(fileURLWithPath: item.filePath) as URL)
  1485. }
  1486. self.showBatchWindow(type: .batchRemove, subType: KMBatchRemoveOptions.security.rawValue, files: array)
  1487. }
  1488. controller.cancelAction = { [unowned self] controller in
  1489. self.view.window?.endSheet((self.currentWindowController.window)!)
  1490. self.currentWindowController = nil
  1491. }
  1492. controller.doneAction = { [unowned self] controller in
  1493. self.view.window?.endSheet((self.currentWindowController.window)!)
  1494. self.currentWindowController = nil
  1495. NSWindowController.checkPassword(url: self.document!.documentURL!, type: .owner, password: self.document?.password ?? "") { [unowned self] success, resultPassword in
  1496. if success {
  1497. let savePanel = NSSavePanel()
  1498. savePanel.nameFieldStringValue = self.listView.document.documentURL.deletingPathExtension().lastPathComponent + "_RemovePassword"
  1499. savePanel.allowedFileTypes = ["pdf"]
  1500. savePanel.beginSheetModal(for: NSApp.mainWindow!) {[unowned self] result in
  1501. guard result == .OK else { return }
  1502. /// 删除安全性设置
  1503. if (!self.listView.document!.allowsCopying || !self.listView.document!.allowsPrinting) {
  1504. self.model.isSaveKeyChain = false
  1505. self.listView.document.unlock(withPassword: resultPassword)
  1506. }
  1507. let document = CPDFDocument.init(url: self.listView.document.documentURL)
  1508. guard let document = document else { return }
  1509. document.unlock(withPassword: resultPassword)
  1510. let success = document.writeDecrypt(to: savePanel.url)
  1511. if success {
  1512. self.hiddenSecureLimitTip()
  1513. NSWorkspace.shared.activateFileViewerSelecting([savePanel.url!])
  1514. } else {
  1515. self.hiddenSecureLimitTip()
  1516. }
  1517. }
  1518. }
  1519. }
  1520. }
  1521. NSWindow.currentWindow().beginSheet(controller.window!)
  1522. }
  1523. }
  1524. //MARK: - Unlock Document
  1525. func unlockPDFDocument() {
  1526. NSWindowController.checkPassword(url: self.document!.documentURL!, type: .owner, password: self.document?.password ?? "") { [unowned self] success, resultPassword in
  1527. self.listView.document.unlock(withPassword: resultPassword)
  1528. }
  1529. }
  1530. //MARK: - PopUI
  1531. func reloadPopUIWindow() {
  1532. if listView.toolMode == .CSelectToolMode {
  1533. let pageRect = listView.currentSelectionRect()
  1534. let page:CPDFPage? = listView.currentSelectionPage()
  1535. if listView.selectionRect != CGRectZero && page != nil {
  1536. let positioningRect = listView.convert(pageRect, from: page)
  1537. if (CGRectIntersectsRect(positioningRect, listView.frame)) {
  1538. reloadPopUIOperation()
  1539. return
  1540. }
  1541. }
  1542. toggleClosePopUIWindow()
  1543. } else if listView.toolMode == .COCRToolMode {
  1544. let pageRect = listView.currentSelectionRect()
  1545. let page:CPDFPage? = listView.currentSelectionPage()
  1546. if listView.selectionRect != CGRectZero && page != nil {
  1547. let positioningRect = listView.convert(pageRect, from: page)
  1548. if (CGRectIntersectsRect(positioningRect, listView.frame)) {
  1549. reloadPopUIOperation()
  1550. return
  1551. }
  1552. }
  1553. toggleClosePopUIWindow()
  1554. } else if(listView.isEditing() == false) {
  1555. let activeAnnotations:[CPDFAnnotation] = listView.activeAnnotations as! [CPDFAnnotation]
  1556. if(activeAnnotations.count > 0) {
  1557. if let page = activeAnnotations.first?.page {
  1558. let pageRect = listView.selectionMultipleBounds(with: activeAnnotations)
  1559. let positioningRect = listView.convert(pageRect, from: page)
  1560. if (CGRectIntersectsRect(positioningRect, listView.frame)) {
  1561. reloadPopUIActiveAnnotations(activeAnnotations: activeAnnotations)
  1562. } else {
  1563. toggleClosePopUIWindow()
  1564. }
  1565. } else {
  1566. toggleClosePopUIWindow()
  1567. }
  1568. } else {
  1569. toggleClosePopUIWindow()
  1570. }
  1571. if(listView.popOver?.isShown == true || (groupListMenuGroup?.superview) != nil) { //右键菜单弹出时,或者Pop编辑框弹出时不显示Pop
  1572. toggleClosePopUIWindow()
  1573. }
  1574. } else {
  1575. let editAreas:[CPDFEditArea] = listView.km_EditingAreas()
  1576. if(editAreas.count > 0) {
  1577. if let page = editAreas.first?.page {
  1578. let pageRect = listView.selectionMultipleBounds(withEditArea: editAreas)
  1579. let positioningRect = listView.convert(pageRect, from: page)
  1580. if (CGRectIntersectsRect(positioningRect, listView.frame)) {
  1581. reloadPopUIContentEdits(editAreas: editAreas)
  1582. } else {
  1583. toggleClosePopUIWindow()
  1584. }
  1585. } else {
  1586. toggleClosePopUIWindow()
  1587. }
  1588. } else {
  1589. toggleClosePopUIWindow()
  1590. }
  1591. if(listView.popOver?.isShown == true || (groupListMenuGroup?.superview) != nil) { //右键菜单弹出时,或者Pop编辑框弹出时不显示Pop
  1592. toggleClosePopUIWindow()
  1593. }
  1594. }
  1595. }
  1596. func toggleClosePopUIWindow() {
  1597. let popWindow = KMNAnnotationPopToolbarWindow.shared
  1598. if popWindow.isVisible == true {
  1599. closeAnnotationPopWindow()
  1600. }
  1601. let editPopWindow = KMNContentEditPopToolbarWindow.shared
  1602. if editPopWindow.isVisible == true {
  1603. closePopContentEditWindow()
  1604. }
  1605. let operationWindow = KMNOperationPopToolbarWindow.shared
  1606. if operationWindow.isVisible == true {
  1607. closePopOperationWindow()
  1608. }
  1609. }
  1610. func closeAnnotationPopWindow() {
  1611. KMNAnnotationPopToolbarWindow.shared.closeWindow(listView: listView)
  1612. }
  1613. func closePopContentEditWindow() {
  1614. KMNContentEditPopToolbarWindow.shared.closeWindow(listView: listView)
  1615. }
  1616. func closePopOperationWindow() {
  1617. KMNOperationPopToolbarWindow.shared.closeWindow(listView: listView)
  1618. }
  1619. func reloadPopUIOperation() {
  1620. if listView.selectionRect != CGRectZero {
  1621. let popWindow = KMNOperationPopToolbarWindow.shared
  1622. popWindow.show(relativeTo: CGRectZero, of: self.listView, preferredEdge: .maxY)
  1623. self.listView.window?.addChildWindow(popWindow, ordered: .above)
  1624. let operationViewController = KMNPopOperationViewController.shared
  1625. operationViewController.listView = listView
  1626. if listView.toolMode == .CSelectToolMode {
  1627. operationViewController.popType = .crop
  1628. operationViewController.cropCurrentCallback = {[weak self] in
  1629. let rect = self?.listView.currentSelectionRect() ?? CGRect.zero
  1630. let orgPage : CPDFPage = self?.listView.currentSelectionPage() ?? CPDFPage()
  1631. self?.cropPages(atIndexs: [orgPage.pageIndex()], to: [rect])
  1632. self?.closePopOperationWindow()
  1633. }
  1634. } else if listView.toolMode == .COCRToolMode {
  1635. operationViewController.popType = .ocr
  1636. operationViewController.OCRAction = { [weak self] in
  1637. self?.convertSelectionRectOCR(rect: self?.listView.currentSelectionRect() ?? CGRectZero)
  1638. }
  1639. }
  1640. operationViewController.updatePDFViewCallback = {[weak self] in
  1641. self?.closePopOperationWindow()
  1642. self?.listView.setNeedsDisplayForVisiblePages()
  1643. }
  1644. updatePopOperationPopWinodwFrame()
  1645. } else {
  1646. closePopOperationWindow()
  1647. }
  1648. }
  1649. func reloadPopUIActiveAnnotations(activeAnnotations:[CPDFAnnotation]) {
  1650. let annotationMode = KMNAnnotationPopMode(pdfAnnotations: activeAnnotations )
  1651. let popVC = KMNPopAnnotationViewController.shared
  1652. if annotationMode.popType == .popTypeNone || !SettingsManager.sharedInstance.showQuickActionBar {
  1653. closeAnnotationPopWindow()
  1654. } else {
  1655. let win = KMNAnnotationPopToolbarWindow.shared
  1656. win.annotationPopMode = annotationMode
  1657. win.show(relativeTo: CGRectZero, of: self.listView, preferredEdge: .maxY)
  1658. self.listView.window?.addChildWindow(win, ordered: .above)
  1659. popVC.listView = listView
  1660. popVC.annotationPopMode = annotationMode
  1661. popVC.isOpenPane = viewManager.showRightSide
  1662. updateAnnotationsPopWinodwFrame()
  1663. popVC.updatePDFViewCallback = {[weak self] in
  1664. self?.rightSideController?.reloadDataWithPDFView(pdfView: self?.listView ?? CPDFListView())
  1665. self?.listView.setNeedsDisplayMultiAnnotations(annotationMode.annotations)
  1666. NotificationCenter.default.post(name: toolbarImageColorChangedNotificationName, object: nil)
  1667. }
  1668. popVC.paneCallback = {[weak self] isOpen in
  1669. if isOpen == true {
  1670. self?.viewManager.showRightSide = true
  1671. } else {
  1672. self?.viewManager.showRightSide = false
  1673. }
  1674. self?.refreshToolbarRightViewInfo()
  1675. }
  1676. }
  1677. }
  1678. func reloadPopUIContentEdits(editAreas:[CPDFEditArea]) {
  1679. let editingAreas = listView.km_EditingAreas()
  1680. let editMode = KMNEditContentPopMode(currentEditAreas: editingAreas)
  1681. let popVC = KMNPopContentEditViewController.shared
  1682. if editMode.popType == .editNone || !SettingsManager.sharedInstance.showQuickActionBar {
  1683. closePopContentEditWindow()
  1684. } else {
  1685. let win = KMNContentEditPopToolbarWindow.shared
  1686. win.editContentPopMode = editMode
  1687. win.show(relativeTo: CGRectZero, of: self.listView, preferredEdge: .maxY)
  1688. self.listView.window?.addChildWindow(win, ordered: .above)
  1689. popVC.listView = listView
  1690. popVC.editContentPopMode = editMode
  1691. popVC.isOpenPane = viewManager.showRightSide
  1692. popVC.editContentPopMode = editMode
  1693. updateContentEditPopWinodwFrame()
  1694. popVC.paneCallback = {[weak self] isOpen in
  1695. if isOpen == true {
  1696. self?.viewManager.showRightSide = false
  1697. } else {
  1698. self?.viewManager.showRightSide = true
  1699. }
  1700. self?.refreshToolbarRightViewInfo()
  1701. }
  1702. popVC.updatePDFViewCallback = { [weak self] in
  1703. self?.rightSideController?.reloadEditingAreas()
  1704. }
  1705. }
  1706. }
  1707. func updateAnnotationsPopWinodwFrame() {
  1708. let popWindow = KMNAnnotationPopToolbarWindow.shared
  1709. popWindow.updateFrame(listView: listView)
  1710. }
  1711. func updateContentEditPopWinodwFrame() {
  1712. let popWindow = KMNContentEditPopToolbarWindow.shared
  1713. popWindow.updateFrame(listView: listView)
  1714. }
  1715. func updatePopOperationPopWinodwFrame() {
  1716. let popWindow = KMNOperationPopToolbarWindow.shared
  1717. popWindow.updateFrame(listView: listView,page: listView.currentSelectionPage())
  1718. }
  1719. //MARK: - 安全
  1720. func removeOwnerPassword() {
  1721. guard let doc = listView.document else {
  1722. NSSound.beep()
  1723. return
  1724. }
  1725. if doc.permissionsStatus != .user {
  1726. NSSound.beep()
  1727. return
  1728. }
  1729. _ = KMPasswordInputWindow.openWindow(window: self.view.window!, type: .owner, url: doc.documentURL) { [weak self] result, password in
  1730. if result == .cancel { /// 关闭
  1731. return
  1732. }
  1733. self?.listView.document?.unlock(withPassword: password)
  1734. if doc.permissionsStatus == .owner {
  1735. self?.alertTipViewController.reloadSecureAlertUI()
  1736. self?.alertTipViewController.reloadAlertUIFrame()
  1737. }
  1738. }
  1739. }
  1740. //MARK: - Watermark水印
  1741. func showWatermarkController() {
  1742. viewManager.editType = .watermark
  1743. showEditToolbarView()
  1744. editToolbarView?.editType = .watermark
  1745. if KMWatermarkManager.defaultManager.watermarks.count == 0 {
  1746. editToolbarView?.editSubType = .add
  1747. } else {
  1748. editToolbarView?.editSubType = .template
  1749. }
  1750. editToolbarView?.reloadData()
  1751. if watermarkViewController == nil {
  1752. watermarkViewController = KMWatermarkController.init()
  1753. }
  1754. watermarkViewController?.view.frame = CGRectMake(44, 0, CGRectGetWidth(bottomContendBox.frame)-44, CGRectGetHeight(bottomContendBox.frame))
  1755. watermarkViewController?.view.autoresizingMask = [.maxXMargin, .width, .height]
  1756. watermarkViewController?.delegate = self
  1757. bottomContendBox.contentView?.addSubview(watermarkViewController!.view)
  1758. watermarkViewController?.editSubType = editToolbarView?.editSubType ?? .template
  1759. watermarkViewController?.reloadData()
  1760. updateWatermarkDocument()
  1761. watermarkViewController?.loadData()
  1762. }
  1763. func updateWatermarkDocument() {
  1764. guard let controller = watermarkViewController else { return }
  1765. var editDocument = CPDFDocument.init()
  1766. if let vcDoc = controller.pdfDocument {
  1767. editDocument = vcDoc
  1768. }
  1769. let page = listView.document.page(at: UInt(listView.currentPageIndex))
  1770. editDocument?.insertPageObject(page, at: 0)
  1771. if editDocument?.pageCount == 2 {
  1772. let theIndex = IndexSet(integer: 1)
  1773. editDocument?.removePage(at: theIndex)
  1774. }
  1775. if watermarkViewController?.pdfDocument == nil {
  1776. watermarkViewController?.pdfDocument = editDocument
  1777. }
  1778. watermarkViewController?.resetUI()
  1779. watermarkViewController?.reloadData()
  1780. watermarkViewController?.loadData()
  1781. }
  1782. //移除文档水印
  1783. func removePDFWatermark() {
  1784. let watermarks = self.listView.document.watermarks()
  1785. if (watermarks == nil || watermarks!.count <= 0) {
  1786. let alert = NSAlert()
  1787. alert.alertStyle = .warning
  1788. alert.messageText = KMLocalizedString("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: "")
  1789. alert.addButton(withTitle: KMLocalizedString("Confirm", comment: ""))
  1790. alert.runModal()
  1791. return
  1792. }
  1793. let alert = NSAlert()
  1794. alert.alertStyle = .warning
  1795. alert.messageText = KMLocalizedString("Are you sure you want to remove the watermark?", comment: "")
  1796. alert.addButton(withTitle: KMLocalizedString("Delete", comment: ""))
  1797. alert.addButton(withTitle: KMLocalizedString("Cancel", comment: ""))
  1798. let result = alert.runModal()
  1799. if (result == .alertFirstButtonReturn) {
  1800. for watermark in watermarks! {
  1801. listView.document.removeWatermark(watermark)
  1802. }
  1803. listView.layoutDocumentView()
  1804. _ = KMNCustomAlertView.alertView(message: KMLocalizedString("Watermark removed"),
  1805. type: .success,
  1806. fromView: bottomContendBox,
  1807. point:CGPointMake(CGRectGetWidth(bottomContendBox.frame)/2, CGRectGetHeight(bottomContendBox.frame)-28))
  1808. }
  1809. }
  1810. func batchAddWatermark() {
  1811. self.showBatchWindow(type: .watermark, files: [URL(fileURLWithPath: self.document?.documentURL.path ?? "")])
  1812. }
  1813. func batchRemoveWatermark() {
  1814. self.showBatchWindow(type: .batchRemove, subType: KMBatchRemoveOptions.watermark.rawValue, files: [URL(fileURLWithPath: self.document?.documentURL.path ?? "")])
  1815. }
  1816. //MARK: - Background背景
  1817. func showBackgroundController() {
  1818. viewManager.editType = .background
  1819. showEditToolbarView()
  1820. editToolbarView?.editType = .background
  1821. if KMBackgroundManager.defaultManager.datas.count == 0 {
  1822. editToolbarView?.editSubType = .add
  1823. } else {
  1824. editToolbarView?.editSubType = .template
  1825. }
  1826. editToolbarView?.reloadData()
  1827. if backgroundViewController == nil {
  1828. backgroundViewController = KMBackgroundController.init()
  1829. }
  1830. backgroundViewController?.view.frame = CGRectMake(44, 0, CGRectGetWidth(bottomContendBox.frame)-44, CGRectGetHeight(bottomContendBox.frame))
  1831. backgroundViewController?.view.autoresizingMask = [.maxXMargin, .width, .height]
  1832. backgroundViewController?.delegate = self
  1833. bottomContendBox.contentView?.addSubview(backgroundViewController!.view)
  1834. backgroundViewController?.editSubType = editToolbarView?.editSubType ?? .template
  1835. backgroundViewController?.resetUI()
  1836. updateBackgroundDocument()
  1837. }
  1838. func updateBackgroundDocument() {
  1839. guard let controller = backgroundViewController else { return }
  1840. controller.pdfDocument = nil
  1841. let editDocument = CPDFDocument.init()
  1842. let page = listView.document.page(at: UInt(listView.currentPageIndex))
  1843. editDocument?.insertPageObject(page, at: 0)
  1844. backgroundViewController?.pdfDocument = editDocument
  1845. backgroundViewController?.reloadData()
  1846. }
  1847. func removePDFBackground() {
  1848. let alert = NSAlert()
  1849. alert.alertStyle = .warning
  1850. alert.messageText = KMLocalizedString("Are you sure you want to remove the background?", comment: "")
  1851. alert.addButton(withTitle: KMLocalizedString("Delete", comment: ""))
  1852. alert.addButton(withTitle: KMLocalizedString("Cancel", comment: ""))
  1853. let result = alert.runModal()
  1854. if (result == .alertFirstButtonReturn) {
  1855. let background = listView.document.background()
  1856. background?.clear()
  1857. listView.document?.refreshPageData()
  1858. listView.layoutDocumentView()
  1859. self.recordIsPDFDocumentEdited()
  1860. _ = KMNCustomAlertView.alertView(message: KMLocalizedString("Background removed"),
  1861. type: .success,
  1862. fromView: bottomContendBox,
  1863. point:CGPointMake(CGRectGetWidth(bottomContendBox.frame)/2, CGRectGetHeight(bottomContendBox.frame)-28))
  1864. }
  1865. }
  1866. func batchAddBackground() {
  1867. self.showBatchWindow(type: .background, files: [URL(fileURLWithPath: self.document?.documentURL.path ?? "")])
  1868. }
  1869. func batchRemoveBackground() {
  1870. self.showBatchWindow(type: .batchRemove, subType: KMBatchRemoveOptions.background.rawValue, files: [URL(fileURLWithPath: self.document?.documentURL.path ?? "")])
  1871. }
  1872. //MARK: - header&footer
  1873. func showHeaderFooterController() {
  1874. viewManager.editType = .header_Footer
  1875. showEditToolbarView()
  1876. editToolbarView?.editType = .header_Footer
  1877. if KMHeaderFooterManager.defaultManager.headFooterObjects.count == 0 {
  1878. editToolbarView?.editSubType = .add
  1879. } else {
  1880. editToolbarView?.editSubType = .template
  1881. }
  1882. editToolbarView?.reloadData()
  1883. if headerFooterViewController == nil {
  1884. headerFooterViewController = KMHeaderFooterController.init()
  1885. }
  1886. headerFooterViewController?.view.frame = CGRectMake(44, 0, CGRectGetWidth(bottomContendBox.frame)-44, CGRectGetHeight(bottomContendBox.frame))
  1887. headerFooterViewController?.view.autoresizingMask = [.maxXMargin, .width, .height]
  1888. headerFooterViewController?.totalPDFCount = Int(listView.document.pageCount)
  1889. headerFooterViewController?.delegate = self
  1890. bottomContendBox.contentView?.addSubview(headerFooterViewController!.view)
  1891. headerFooterViewController?.editSubType = editToolbarView?.editSubType ?? .template
  1892. updateHeaderFooterDocument()
  1893. }
  1894. func updateHeaderFooterDocument() {
  1895. guard let controller = headerFooterViewController else { return }
  1896. controller.pdfDocument = nil
  1897. let editDocument = CPDFDocument.init()
  1898. let page = listView.document.page(at: UInt(listView.currentPageIndex))
  1899. editDocument?.insertPageObject(page, at: 0)
  1900. headerFooterViewController?.totalPDFCount = Int(listView.document.pageCount)
  1901. headerFooterViewController?.pdfDocument = editDocument
  1902. headerFooterViewController?.resetUI()
  1903. headerFooterViewController?.reloadData()
  1904. }
  1905. func removeHeaderFooter() {
  1906. let alert = NSAlert()
  1907. alert.alertStyle = .warning
  1908. alert.messageText = KMLocalizedString("Are you sure you want to remove the Header & Footer?", comment: "")
  1909. alert.addButton(withTitle: KMLocalizedString("Delete", comment: ""))
  1910. alert.addButton(withTitle: KMLocalizedString("Cancel", comment: ""))
  1911. let result = alert.runModal()
  1912. if (result == .alertFirstButtonReturn) {
  1913. let headerFooter = listView.document.headerFooter()
  1914. headerFooter?.clear()
  1915. listView.document?.refreshPageData()
  1916. listView.layoutDocumentView()
  1917. self.recordIsPDFDocumentEdited()
  1918. _ = KMNCustomAlertView.alertView(message: KMLocalizedString("Header & Footer removed"),
  1919. type: .success,
  1920. fromView: bottomContendBox,
  1921. point:CGPointMake(CGRectGetWidth(bottomContendBox.frame)/2, CGRectGetHeight(bottomContendBox.frame)-28))
  1922. }
  1923. }
  1924. func batchAddHeaderFooter() {
  1925. self.showBatchWindow(type: .headerAndFooter, files: [URL(fileURLWithPath: self.document?.documentURL.path ?? "")])
  1926. }
  1927. func batchRemoveHeaderFooter() {
  1928. self.showBatchWindow(type: .batchRemove, subType: KMBatchRemoveOptions.headerAndFooter.rawValue, files: [URL(fileURLWithPath: self.document?.documentURL.path ?? "")])
  1929. }
  1930. //MARK: - Bates
  1931. func showBatesController() {
  1932. viewManager.editType = .bates
  1933. showEditToolbarView()
  1934. editToolbarView?.editType = viewManager.editType
  1935. if KMBatesManager.defaultManager.datas.count == 0 {
  1936. editToolbarView?.editSubType = .add
  1937. } else {
  1938. editToolbarView?.editSubType = .template
  1939. }
  1940. editToolbarView?.reloadData()
  1941. if batesViewController == nil {
  1942. batesViewController = KMBatesController.init()
  1943. }
  1944. batesViewController?.view.frame = CGRectMake(44, 0, CGRectGetWidth(bottomContendBox.frame)-44, CGRectGetHeight(bottomContendBox.frame))
  1945. batesViewController?.view.autoresizingMask = [.maxXMargin, .width, .height]
  1946. batesViewController?.delegate = self
  1947. batesViewController?.totalPDFCount = Int(listView.document.pageCount)
  1948. bottomContendBox.contentView?.addSubview(batesViewController!.view)
  1949. batesViewController?.editSubType = editToolbarView?.editSubType ?? .template
  1950. updateBatesDocument()
  1951. batesViewController?.resetUI()
  1952. }
  1953. func updateBatesDocument() {
  1954. guard let controller = batesViewController else { return }
  1955. controller.pdfDocument = nil
  1956. let editDocument = CPDFDocument.init()
  1957. let page = listView.document.page(at: UInt(listView.currentPageIndex))
  1958. editDocument?.insertPageObject(page, at: 0)
  1959. batesViewController?.pdfDocument = editDocument
  1960. batesViewController?.reloadData()
  1961. }
  1962. func removePDFBates() {
  1963. let alert = NSAlert()
  1964. alert.alertStyle = .warning
  1965. alert.messageText = KMLocalizedString("Are you sure you want to remove the Bates?", comment: "")
  1966. alert.addButton(withTitle: KMLocalizedString("Delete", comment: ""))
  1967. alert.addButton(withTitle: KMLocalizedString("Cancel", comment: ""))
  1968. let result = alert.runModal()
  1969. if (result == .alertFirstButtonReturn) {
  1970. let bates = listView.document.bates()
  1971. bates?.clear()
  1972. listView.document?.refreshPageData()
  1973. listView.layoutDocumentView()
  1974. self.recordIsPDFDocumentEdited()
  1975. _ = KMNCustomAlertView.alertView(message: KMLocalizedString("Bates removed"),
  1976. type: .success,
  1977. fromView: bottomContendBox,
  1978. point:CGPointMake(CGRectGetWidth(bottomContendBox.frame)/2, CGRectGetHeight(bottomContendBox.frame)-28))
  1979. }
  1980. }
  1981. func batchAddBates() {
  1982. self.showBatchWindow(type: .batesNumber, files: [URL(fileURLWithPath: self.document?.documentURL.path ?? "")])
  1983. }
  1984. func batchRemoveBates() {
  1985. self.showBatchWindow(type: .batchRemove, subType: KMBatchRemoveOptions.batesNumber.rawValue, files: [URL(fileURLWithPath: self.document?.documentURL.path ?? "")])
  1986. }
  1987. //MARK: - Crop Action
  1988. // 白边距,统一大小
  1989. @objc func auto_cropPagesWhiteMargin(_ pageIndexs: [UInt]) {
  1990. var size = NSZeroSize
  1991. for i in pageIndexs {
  1992. let page = self.listView.document.page(at: i)
  1993. let rect = KMCropTools.getPageForegroundBox(page!)
  1994. size.width = fmax(size.width, NSWidth(rect))
  1995. size.height = fmax(size.height, NSHeight(rect))
  1996. }
  1997. var rectArray: Array<NSRect> = []
  1998. for i in pageIndexs {
  1999. progressC?.increment(by: Double(i))
  2000. progressC?.doubleValue = Double(i)
  2001. let page = self.listView.document.page(at: i)
  2002. var rect = KMCropTools.getPageForegroundBox(page!)
  2003. let bounds: NSRect = (page?.bounds(for: .mediaBox))!
  2004. if (rect.minX - bounds.minX > bounds.maxX-rect.maxX) {
  2005. rect.origin.x = rect.maxX-size.width
  2006. }
  2007. rect.origin.y = rect.maxY-size.height
  2008. rect.size = size
  2009. if (NSWidth(rect) > NSWidth(bounds)) {
  2010. rect.size.width = NSWidth(bounds)
  2011. }
  2012. if (NSHeight(rect) > NSHeight(bounds)) {
  2013. rect.size.height = NSHeight(bounds)
  2014. }
  2015. if (NSMinX(rect) < NSMinX(bounds)) {
  2016. rect.origin.x = NSMinX(bounds)
  2017. } else if (NSMaxX(rect) > NSMaxX(bounds)) {
  2018. rect.origin.x = NSMaxX(bounds) - NSWidth(rect)
  2019. }
  2020. if (NSMinY(rect) < NSMinY(bounds)) {
  2021. rect.origin.y = NSMinY(bounds)
  2022. } else if (NSMaxY(rect) > NSMaxY(bounds)) {
  2023. rect.origin.y = NSMaxY(bounds) - NSHeight(rect)
  2024. }
  2025. rectArray.append(rect)
  2026. }
  2027. self.cropPages(atIndexs: pageIndexs, to: rectArray)
  2028. }
  2029. func cropPages(atIndexs pageIndexs: [UInt], to rects: Array<NSRect>) {
  2030. let currentPage = self.listView.currentPage()
  2031. let visibleRect: NSRect = self.listView.convert(self.listView.convert(self.listView.documentView().visibleRect, from: self.listView.documentView()), to: self.listView.currentPage())
  2032. var oldRectArray: Array<NSRect> = []
  2033. let rectCount = rects.count
  2034. for i in pageIndexs {
  2035. if let page = self.listView.document.page(at: i) {
  2036. let rect = NSIntersectionRect(rects[Int(i) % rectCount], (page.bounds(for: .mediaBox)))
  2037. let oldRect = page.bounds(for: .cropBox)
  2038. oldRectArray.append(oldRect)
  2039. page.setBounds(rect, for: .cropBox)
  2040. }
  2041. }
  2042. let undoManager = self.listView.undoManager
  2043. (undoManager?.prepare(withInvocationTarget: self) as AnyObject).cropPages(atIndexs: pageIndexs, to: oldRectArray)
  2044. /// 刷新预览视图
  2045. self.listView.layoutDocumentView()
  2046. self.listView.displayBox = .cropBox
  2047. self.listView.go(to: currentPage)
  2048. self.listView.go(to: visibleRect, on: currentPage)
  2049. }
  2050. //MARK: - 文件对比
  2051. func beginCompareAction(_ index: Int) {
  2052. guard let filePath = self.document?.documentURL.path else { return }
  2053. if !FileManager.default.fileExists(atPath: filePath) {
  2054. let alert = NSAlert.init()
  2055. alert.alertStyle = .critical
  2056. alert.messageText = "\(filePath.lastPathComponent) \(NSLocalizedString("File Not Exist", comment: ""))"
  2057. alert.runModal()
  2058. return
  2059. }
  2060. let controller = KMCompareWindowController(windowNibName: "KMCompareWindowController")
  2061. self.currentWindowController = controller
  2062. controller.password = self.document?.password ?? ""
  2063. controller.filePath = (self.document?.documentURL.path)!
  2064. controller.cancelAction = { [unowned self] controller in
  2065. self.view.window?.endSheet((self.currentWindowController.window)!)
  2066. self.currentWindowController = nil
  2067. }
  2068. controller.contentComplete = { [unowned self] controller, pdfCompareContent, result, oldDocument, document in
  2069. self.view.window?.endSheet((self.currentWindowController.window)!)
  2070. self.currentWindowController = nil
  2071. self.openContentCompareVC(with: pdfCompareContent, results: result, oldDocument: oldDocument, document: document)
  2072. }
  2073. controller.coveringComplete = { [unowned self] controller, document in
  2074. self.view.window?.endSheet((self.currentWindowController.window)!)
  2075. self.currentWindowController = nil
  2076. self.openCoveringCompareVC(with: document)
  2077. }
  2078. if index == 1 {
  2079. controller.fileType = .content
  2080. } else {
  2081. controller.fileType = .coverting
  2082. }
  2083. NSWindow.currentWindow().beginSheet(controller.window!)
  2084. }
  2085. //文件对比
  2086. func openContentCompareVC(with pdfCompareContent: CPDFCompareContent?, results: [CPDFCompareResults], oldDocument: CPDFDocument, document: CPDFDocument) {
  2087. self.isCompareModel = true
  2088. let compareContentView = KMCompareContentView()
  2089. compareContentView.oldDocument = oldDocument
  2090. compareContentView.document = document
  2091. compareContentView.compareResults = results
  2092. compareContentView.saveHandle = { [unowned self] view in
  2093. DispatchQueue.main.asyncAfter(deadline: DispatchTime.now() + 0.25) { [unowned self] in
  2094. let saveController = KMCompareSaveWindow(windowNibName: "KMCompareSaveWindow")
  2095. self.currentWindowController = saveController
  2096. saveController.cancelHandle = { [unowned self] controller in
  2097. self.view.window!.endSheet(controller.window!)
  2098. self.currentWindowController = nil
  2099. }
  2100. saveController.saveHandle = { [unowned self] controller, saveType in
  2101. let folderPath = controller.fileSaveFolderPath
  2102. if folderPath != nil {
  2103. if !FileManager.default.fileExists(atPath: folderPath) {
  2104. try? FileManager.default.createDirectory(atPath: folderPath, withIntermediateDirectories: true, attributes: nil)
  2105. }
  2106. #if VERSION_DMG
  2107. #else
  2108. let url = URL(fileURLWithPath: folderPath)
  2109. let fileAccess = AppSandboxFileAccess()
  2110. fileAccess?.persistPermissionURL(url)
  2111. if let bookmarkData = try?url.bookmarkData(options: [.withSecurityScope]) {
  2112. fileAccess?.bookmarkPersistanceDelegate.setBookmarkData(bookmarkData, for: url)
  2113. let urlString = url.path
  2114. let _url = URL(fileURLWithPath: urlString)
  2115. fileAccess?.bookmarkPersistanceDelegate.setBookmarkData(bookmarkData, for: _url)
  2116. }
  2117. #endif
  2118. var savePath: String
  2119. switch saveType {
  2120. case 0:
  2121. let filePath = oldDocument.documentURL.path
  2122. let fileName = filePath.deletingPathExtension.lastPathComponent
  2123. savePath = "\(folderPath)/\(fileName)_compare\(filePath.extension)"
  2124. savePath = self.getValidFilePath(savePath)
  2125. oldDocument.write(to: URL(fileURLWithPath: savePath))
  2126. NSWorkspace.shared.activateFileViewerSelecting([URL(fileURLWithPath: savePath)])
  2127. case 1:
  2128. let filePath = document.documentURL.path
  2129. let fileName = filePath.deletingPathExtension.lastPathComponent
  2130. savePath = "\(folderPath)/\(fileName)_compare\(filePath.extension)"
  2131. savePath = self.getValidFilePath(savePath)
  2132. document.write(to: URL(fileURLWithPath: savePath))
  2133. NSWorkspace.shared.activateFileViewerSelecting([URL(fileURLWithPath: savePath)])
  2134. case 2:
  2135. let filePath = oldDocument.documentURL.path
  2136. let fileName = filePath.deletingPathExtension.lastPathComponent
  2137. savePath = "\(folderPath)/MergedCompareFile\(filePath.extension)"
  2138. savePath = self.getValidFilePath(savePath)
  2139. pdfCompareContent!.saveAsComparisonDocument(withFilePath: savePath)
  2140. NSWorkspace.shared.activateFileViewerSelecting([URL(fileURLWithPath: savePath)])
  2141. default:
  2142. break
  2143. }
  2144. }
  2145. self.view.window!.endSheet(controller.window!)
  2146. self.currentWindowController = nil
  2147. }
  2148. NSWindow.currentWindow().beginSheet(saveController.window!)
  2149. }
  2150. }
  2151. compareContentView.closeHandle = { [unowned self] view in
  2152. self.isCompareModel = false
  2153. view.removeFromSuperview()
  2154. }
  2155. contendBox.addSubview(compareContentView)
  2156. compareContentView.frame = contendBox.bounds
  2157. compareContentView.autoresizingMask = [.width,.height]
  2158. }
  2159. func openCoveringCompareVC(with pdfDocument: CPDFDocument) {
  2160. self.isCompareModel = true
  2161. let coveringView = KMCompareCoveringView()
  2162. coveringView.pdfDocument = pdfDocument
  2163. coveringView.closeHandle = { [unowned self] view in
  2164. self.isCompareModel = false
  2165. view.removeFromSuperview()
  2166. }
  2167. coveringView.saveHandle = { [unowned self] view in
  2168. let savePanel = NSSavePanel()
  2169. savePanel.nameFieldStringValue = "untitled"
  2170. savePanel.allowedFileTypes = ["pdf"]
  2171. savePanel.beginSheetModal(for: NSWindow.currentWindow()) { result in
  2172. if result == .OK {
  2173. pdfDocument.write(to: savePanel.url!)
  2174. NSWorkspace.shared.activateFileViewerSelecting([savePanel.url!])
  2175. }
  2176. }
  2177. }
  2178. contendBox.addSubview(coveringView)
  2179. coveringView.frame = contendBox.bounds
  2180. coveringView.autoresizingMask = [.width,.height]
  2181. }
  2182. func getValidFilePath(_ oldPath: String) -> String {
  2183. let fileManager = FileManager.default
  2184. do {
  2185. let fileAttributes = try fileManager.attributesOfItem(atPath: oldPath)
  2186. guard let fileType = fileAttributes[FileAttributeKey.type] as? String else {
  2187. return oldPath
  2188. }
  2189. var i = 1
  2190. var newPath = oldPath
  2191. while fileManager.fileExists(atPath: newPath) {
  2192. if fileType == FileAttributeType.typeDirectory.rawValue {
  2193. newPath = oldPath + "(\(i))"
  2194. } else {
  2195. let fileExtension = (oldPath as NSString).pathExtension
  2196. newPath = ((oldPath as NSString).deletingPathExtension as NSString).appendingFormat("(\(i)).\(fileExtension)" as NSString) as String
  2197. }
  2198. i += 1
  2199. }
  2200. return newPath
  2201. } catch {
  2202. print("Error getting file attributes: \(error)")
  2203. return oldPath
  2204. }
  2205. }
  2206. //MARK: - TTS
  2207. @IBAction func startSpeaking(_ sender: Any?) {
  2208. self.showTTSWindow()
  2209. let ttsView = KMTTSWindowController.share
  2210. // ttsView.buttonItemClick_Play(ttsView.playButton)
  2211. }
  2212. @IBAction func stopSpeaking(_ sender: Any) {
  2213. let ttsWindowC = KMTTSWindowController.share
  2214. if ttsWindowC.pdfView?.document?.documentURL.path == self.listView.document?.documentURL.path {
  2215. if let data = ttsWindowC.window?.isVisible, data {
  2216. ttsWindowC.stopSpeaking()
  2217. ttsWindowC.close()
  2218. }
  2219. }
  2220. }
  2221. func showTTSWindow() {
  2222. var lastPDFView: CPDFView?
  2223. let ttsView = KMTTSWindowController.share
  2224. if (ttsView.window?.isVisible ?? false) {
  2225. lastPDFView = ttsView.pdfView
  2226. if lastPDFView?.document?.documentURL?.path == self.listView.document?.documentURL?.path {
  2227. lastPDFView = nil
  2228. ttsView.window?.orderOut(nil)
  2229. } else {
  2230. ttsView.pdfView = self.listView
  2231. ttsView.showWindow(nil)
  2232. }
  2233. } else {
  2234. ttsView.pdfView = self.listView
  2235. ttsView.showWindow(nil)
  2236. }
  2237. ttsView.closeWindowCallback = { (isCloseWindow: Bool) in
  2238. if isCloseWindow {
  2239. }
  2240. }
  2241. if let currentSelection = self.listView.currentSelection {
  2242. if let data = currentSelection.selectionsByLine, data.isEmpty == false {
  2243. ttsView.startSpeakingPDFSelection(currentSelection)
  2244. }
  2245. }
  2246. if let lastPDFView = lastPDFView {
  2247. lastPDFView.setHighlightedSelections([])
  2248. ttsView.stopSpeaking()
  2249. }
  2250. }
  2251. //MARK: 导出图片
  2252. func extractImageAction(num: Int) {
  2253. guard let filePath = self.document?.documentURL.path else { return }
  2254. if !FileManager.default.fileExists(atPath: filePath) {
  2255. let alert = NSAlert.init()
  2256. alert.alertStyle = .critical
  2257. alert.messageText = "\(filePath.lastPathComponent) \(NSLocalizedString("File Not Exist", comment: ""))"
  2258. alert.runModal()
  2259. return
  2260. }
  2261. if !IAPProductsManager.default().isAvailableAllFunction(){
  2262. let winC = KMPurchaseCompareWindowController.sharedInstance()
  2263. winC?.kEventName = "Reading_ExtractImage_BuyNow"
  2264. winC?.showWindow(nil)
  2265. return
  2266. }
  2267. if !(self.listView.document.allowsPrinting || self.listView.document.allowsCopying) {
  2268. let alert = NSAlert()
  2269. alert.alertStyle = .critical
  2270. alert.messageText = KMLocalizedString("This is a secured document. Editing is not permitted.", comment: "")
  2271. alert.runModal()
  2272. return
  2273. }
  2274. let document = self.listView.document
  2275. var fileURL = document?.documentURL
  2276. if num == 1 {
  2277. let pageCount = document?.pageCount ?? 0
  2278. let indeSet = NSMutableIndexSet()
  2279. indeSet.add(in: NSRange(location: 0, length: Int(pageCount)))
  2280. if indeSet.count == 0 {
  2281. return
  2282. }
  2283. let lastPathName = fileURL?.deletingPathExtension().lastPathComponent ?? ""
  2284. let tFileName = (String(format: "%@_Extract Images", lastPathName))
  2285. let outputSavePanel = NSSavePanel()
  2286. outputSavePanel.title = KMLocalizedString("Save as PDF", comment: "")
  2287. outputSavePanel.allowsOtherFileTypes = true
  2288. outputSavePanel.isExtensionHidden = true
  2289. outputSavePanel.canCreateDirectories = true
  2290. outputSavePanel.nameFieldStringValue = tFileName
  2291. outputSavePanel.beginSheetModal(for: self.view.window!, completionHandler: { (result) in
  2292. if result == NSApplication.ModalResponse.OK {
  2293. DispatchQueue.main.async {
  2294. self.beginProgressSheet(withMessage: KMLocalizedString("Extracting all pictures...", comment: "") + "...", maxValue: 0)
  2295. let tDestFile = outputSavePanel.url!.path
  2296. let uniquePath = KMExtractImageWindowController.createDestFolder(path: tDestFile, isUnique: false)
  2297. let pdfconverter = PDFConvertObject()
  2298. pdfconverter.extractResourcesFromPDF(at: fileURL?.path ?? "", pdfPassword: document?.password, selectIndexSet: indeSet as IndexSet, destDocPath: uniquePath, moreOptions: nil)
  2299. self.dismissProgressSheet()
  2300. let fileManager = FileManager.default
  2301. if fileManager.fileExists(atPath: tDestFile) {
  2302. let workspace = NSWorkspace.shared
  2303. let url = URL(fileURLWithPath: tDestFile)
  2304. workspace.activateFileViewerSelecting([url])
  2305. }
  2306. }
  2307. }
  2308. })
  2309. return
  2310. }
  2311. if fileURL != nil {
  2312. self.myDocument?.save(nil)
  2313. } else {
  2314. let myDocument = self.myDocument
  2315. let str = String(format: "%@.pdf", myDocument?.displayName ?? "")
  2316. let writeSuccess = document!.write(to: URL(fileURLWithPath: (kTempSavePath?.stringByAppendingPathComponent(str))!))
  2317. if writeSuccess {
  2318. var documentTemp = CPDFDocument(url: URL(fileURLWithPath: (kTempSavePath?.stringByAppendingPathComponent(str))!))
  2319. fileURL = document?.documentURL
  2320. } else {
  2321. NSSound.beep()
  2322. return
  2323. }
  2324. }
  2325. extract = KMExtractImageWindowController(windowNibName: "KMExtractImageWindowController")
  2326. extract?.docPath = fileURL?.path ?? ""
  2327. extract?.password = document?.password ?? ""
  2328. extract?.currentPage = self.listView.currentPageIndex
  2329. extract?.own_beginSheetModal(for: self.view.window, completionHandler: { result in
  2330. })
  2331. extract?.selectCurrentPageBtn()
  2332. }
  2333. func beginProgressSheet(withMessage message: String, maxValue: UInt) {
  2334. let progress = SKProgressController()
  2335. progress.window?.backgroundColor = NSColor.km_init(hex: "#36383B")
  2336. progress.window?.contentView?.wantsLayer = true
  2337. progress.window?.contentView?.layer?.backgroundColor = NSColor.km_init(hex: "#36383B").cgColor
  2338. progress.progressField.textColor = NSColor.white
  2339. progress.message = KMLocalizedString("Converting...", comment: "")
  2340. progressC = progress
  2341. progressC?.message = message
  2342. if maxValue > 0 {
  2343. progressC?.indeterminate = false
  2344. progressC?.maxValue = Double(maxValue)
  2345. progressC?.progressBar.doubleValue = 0.3
  2346. } else {
  2347. progressC?.indeterminate = true
  2348. }
  2349. progressC?.own_beginSheetModal(for: self.view.window, completionHandler: { result in
  2350. })
  2351. }
  2352. func dismissProgressSheet() {
  2353. progressC?.stopAnimation()
  2354. progressC?.own_closeEndSheet()
  2355. progressC = nil
  2356. }
  2357. //MARK: - 打印
  2358. internal func showPrintWindow(pageRange: KMPrintPageRange = KMPrintPageRange(type: .allPage, selectPages: [])) {
  2359. self.saveDocument()
  2360. if (self.listView.document != nil && !self.listView.document.allowsPrinting) { // 有打印限制
  2361. KMPasswordInputWindow.openWindow(window: self.view.window!, type: .owner, url: self.listView.document.documentURL) { [weak self] result ,password in
  2362. if (result == .cancel) {
  2363. return
  2364. }
  2365. // 解除权限
  2366. self?.listView.document.unlock(withPassword: password)
  2367. // 隐藏提示
  2368. self?.hiddenSecureLimitTip()
  2369. // 去打印
  2370. KMPrintWindowController.openDocument(inputDocument: self?.listView.document, inputPageRange: pageRange)
  2371. }
  2372. return
  2373. }
  2374. KMPrintWindowController.openDocument(inputDocument: self.listView.document, inputPageRange: pageRange)
  2375. }
  2376. //Poster
  2377. func showPosterPrintWindow() {
  2378. guard let document = self.document else { return }
  2379. guard let pdfDocument = PDFDocument(url: document.documentURL) else { return }
  2380. if self.posterPrintWindowController == nil {
  2381. posterPrintWindowController = KMPDFPosterPrintWindowController.init(pdfDocument: pdfDocument)
  2382. }
  2383. if let window = posterPrintWindowController?.window {
  2384. NSApp.mainWindow?.beginSheet(window, completionHandler: { response in
  2385. })
  2386. }
  2387. }
  2388. //Multiple
  2389. func showMultiplePrintWindow() {
  2390. guard let document = self.document else { return }
  2391. guard let pdfDocument = PDFDocument(url: document.documentURL) else { return }
  2392. if self.multiplePrintWindowController == nil {
  2393. multiplePrintWindowController = KMPDFMultiplePrintWindowController.init(pdfDocument: pdfDocument)
  2394. }
  2395. if let window = multiplePrintWindowController?.window {
  2396. NSApp.mainWindow?.beginSheet(window, completionHandler: { response in
  2397. })
  2398. }
  2399. }
  2400. //Booklet
  2401. func showBookletPrintWindow() {
  2402. guard let document = self.document else { return }
  2403. guard let pdfDocument = PDFDocument(url: document.documentURL) else { return }
  2404. if self.bookletWindowController == nil {
  2405. bookletWindowController = KMPDFBookletWindowController.init(document: pdfDocument)
  2406. }
  2407. if let window = bookletWindowController?.window {
  2408. NSApp.mainWindow?.beginSheet(window, completionHandler: { response in
  2409. })
  2410. }
  2411. }
  2412. //MARK: - FileInfo
  2413. func showFileInfo() {
  2414. KMInfoWindowController.shared.showWindow(nil)
  2415. }
  2416. //MARK: - Share Action
  2417. @objc private func shareDocument(sender: NSView) {
  2418. let document = self.listView.document ?? CPDFDocument()
  2419. if document?.documentURL == nil {
  2420. return
  2421. }
  2422. var doucumentURL : URL = self.listView.document.documentURL
  2423. if doucumentURL.path.count > 0 {
  2424. let docDir = NSTemporaryDirectory()
  2425. let documentName : String = doucumentURL.path.lastPathComponent
  2426. let path = docDir.stringByAppendingPathComponent(documentName)
  2427. let writeSuccess = self.listView.document.write(to: URL(fileURLWithPath: path))
  2428. if writeSuccess == false {
  2429. __NSBeep()
  2430. return;
  2431. }
  2432. doucumentURL = URL(fileURLWithPath: path)
  2433. }
  2434. let array = [doucumentURL]
  2435. let picker = NSSharingServicePicker.init(items: array)
  2436. if sender.window != nil {
  2437. picker.show(relativeTo: sender.bounds, of: sender, preferredEdge: NSRectEdge.minY)
  2438. } else {
  2439. 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)
  2440. }
  2441. }
  2442. @objc private func shareFlatten(sender: NSView) {
  2443. let document = self.listView.document ?? CPDFDocument()
  2444. var path: String?
  2445. if document?.documentURL != nil {
  2446. path = document?.documentURL.path ?? ""
  2447. }
  2448. if path?.count ?? 0 > 0 {
  2449. let docDir = NSTemporaryDirectory()
  2450. let documentName : String = path?.lastPathComponent ?? ""
  2451. path = docDir.stringByAppendingPathComponent(documentName)
  2452. }
  2453. let pathFolder = path?.fileURL.deletingLastPathComponent().path
  2454. var tfileName = path?.deletingPathExtension.lastPathComponent
  2455. let tStdFileSuffix = "_flatten"
  2456. tfileName = (tfileName ?? "") + tStdFileSuffix + ".pdf"
  2457. path = (pathFolder ?? "") + "/" + (tfileName ?? "")
  2458. let success : Bool = document?.writeFlatten(to: URL(fileURLWithPath: path ?? "")) ?? false
  2459. if success {
  2460. let url = URL(fileURLWithPath: path ?? "")
  2461. let picker = NSSharingServicePicker.init(items: [url])
  2462. if sender.window != nil {
  2463. picker.show(relativeTo: sender.bounds, of: sender, preferredEdge: NSRectEdge.minY)
  2464. } else {
  2465. 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)
  2466. }
  2467. }
  2468. }
  2469. @objc private func shareOriginalPDF(sender: NSView) {
  2470. guard let pdfDoc = self.listView.document else {
  2471. NSSound.beep()
  2472. return
  2473. }
  2474. if !pdfDoc.allowsCopying || !pdfDoc.allowsPrinting {
  2475. let alert = NSAlert()
  2476. alert.alertStyle = .critical
  2477. alert.messageText = KMLocalizedString("This is a secured document. Editing is not permitted.", comment: "")
  2478. alert.runModal()
  2479. return
  2480. }
  2481. let document = self.listView.document ?? CPDFDocument()
  2482. var path: String?
  2483. if document?.documentURL != nil {
  2484. path = document?.documentURL.path ?? ""
  2485. }
  2486. if path?.count ?? 0 > 0 {
  2487. let docDir = NSTemporaryDirectory()
  2488. let documentName : String = path?.lastPathComponent ?? ""
  2489. path = docDir.stringByAppendingPathComponent(documentName)
  2490. }
  2491. var writeSuccess = document?.write(to: URL(fileURLWithPath: path ?? ""))
  2492. if writeSuccess == false {
  2493. __NSBeep()
  2494. return;
  2495. }
  2496. let newDocument = CPDFDocument(url: URL(fileURLWithPath: path ?? ""))
  2497. let cnt = newDocument?.pageCount ?? 0
  2498. for i in 0 ..< cnt {
  2499. let page = newDocument!.page(at: i)
  2500. var annotations : [CPDFAnnotation] = []
  2501. for annotation in page!.annotations {
  2502. annotations.append(annotation)
  2503. }
  2504. for annotation in annotations {
  2505. annotation.page.removeAnnotation(annotation)
  2506. }
  2507. }
  2508. writeSuccess = newDocument?.write(to:URL(fileURLWithPath: path ?? ""))
  2509. if writeSuccess ?? false {
  2510. let url = URL(fileURLWithPath: path ?? "")
  2511. let picker = NSSharingServicePicker.init(items: [url])
  2512. if sender.window != nil {
  2513. picker.show(relativeTo: sender.bounds, of: sender, preferredEdge: NSRectEdge.minY)
  2514. } else {
  2515. 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)
  2516. }
  2517. }
  2518. }
  2519. @objc func shareFromService(sender: NSMenuItem) {
  2520. if ((NSApp.mainWindow?.windowController is KMBrowserWindowController) == false) {
  2521. return
  2522. }
  2523. var string = ""
  2524. if let freeTextAnnotation = listView.activeAnnotation as? CPDFFreeTextAnnotation {
  2525. string = freeTextAnnotation.contents ?? ""
  2526. } else if let markupAnnotation = listView.activeAnnotation as? CPDFMarkupAnnotation {
  2527. if let page = markupAnnotation.page {
  2528. if let selection = page.selection(for: markupAnnotation.bounds) {
  2529. string = selection.string() ?? ""
  2530. }
  2531. }
  2532. } else {
  2533. string = listView.currentSelection?.string() ?? ""
  2534. }
  2535. let windowControler = NSApp.mainWindow?.windowController as! KMBrowserWindowController
  2536. let model = windowControler.browser?.tabStripModel
  2537. if let cnt = model?.count(), cnt <= 0 {
  2538. return
  2539. }
  2540. if let data = model?.activeTabContents().isHome, data {
  2541. return
  2542. }
  2543. let document: KMMainDocument = model?.activeTabContents() as! KMMainDocument
  2544. if string.count > 0 {
  2545. let represent : NSSharingService = sender.representedObject as! NSSharingService
  2546. represent.perform(withItems: [string])
  2547. return
  2548. }
  2549. let represent = sender.representedObject as? NSSharingService
  2550. represent?.perform(withItems: [string])
  2551. }
  2552. //MARK: - PDFView Menu
  2553. func clickPresentationMenu(point:NSPoint)->KMNMenuStruct {
  2554. var viewHeight: CGFloat = 8
  2555. var menuItemArr: [ComponentMenuitemProperty] = []
  2556. var items: [(String, String)] = []
  2557. items.append(("Next Page", PDFViewMenuIdentifier_PageNext))
  2558. items.append(("Previous Page", PDFViewMenuIdentifier_PagePrevious))
  2559. items.append(("First", PDFViewMenuIdentifier_PageFirst))
  2560. items.append(("Last", PDFViewMenuIdentifier_PageLast))
  2561. items.append(("", ""))
  2562. items.append(("Laser pointer", PDFViewMenuIdentifier_Presentation_LaserPoint))
  2563. items.append(("Brush", PDFViewMenuIdentifier_Presentation_Brush))
  2564. items.append(("", ""))
  2565. items.append(("Exit Presentation", PDFViewMenuIdentifier_Presentation_Exit))
  2566. for (i, value) in items {
  2567. if value.count == 0 {
  2568. let property: ComponentMenuitemProperty = ComponentMenuitemProperty.divider()
  2569. menuItemArr.append(property)
  2570. viewHeight += 8
  2571. } else {
  2572. let properties_Menuitem: ComponentMenuitemProperty = ComponentMenuitemProperty(multipleSelect: false,
  2573. itemSelected: false,
  2574. isDisabled: false,
  2575. keyEquivalent: nil,
  2576. text: KMLocalizedString(i),
  2577. identifier: value,representedObject: point)
  2578. if value == PDFViewMenuIdentifier_PageNext {
  2579. properties_Menuitem.keyEquivalent = "▶"
  2580. } else if value == PDFViewMenuIdentifier_PagePrevious {
  2581. properties_Menuitem.keyEquivalent = "◀"
  2582. } else if value == PDFViewMenuIdentifier_PageFirst {
  2583. properties_Menuitem.keyEquivalent = "⌘ ◀"
  2584. } else if value == PDFViewMenuIdentifier_PageLast {
  2585. properties_Menuitem.keyEquivalent = "⌘ ▶"
  2586. } else if value == PDFViewMenuIdentifier_Presentation_Exit {
  2587. properties_Menuitem.keyEquivalent = "ESC"
  2588. }
  2589. if(value == PDFViewMenuIdentifier_Presentation_LaserPoint) {
  2590. if((listView.presentationDrawView != nil) && listView.presentationDrawView.isHidden == false) {
  2591. } else {
  2592. properties_Menuitem.righticon = NSImage(named: "KMNImageNameMenuSelect")
  2593. }
  2594. } else if value == PDFViewMenuIdentifier_Presentation_Brush {
  2595. if((listView.presentationDrawView != nil) && listView.presentationDrawView.isHidden == false) {
  2596. properties_Menuitem.righticon = NSImage(named: "KMNImageNameMenuSelect")
  2597. } else {
  2598. }
  2599. }
  2600. menuItemArr.append(properties_Menuitem)
  2601. viewHeight += 36
  2602. }
  2603. }
  2604. let menuStruct = KMNMenuStruct(menuitems: menuItemArr, viewHeight: viewHeight)
  2605. return menuStruct
  2606. }
  2607. func gotoPage(_ sender: Any?) {
  2608. var pages : [String] = []
  2609. for i in 0 ..< self.listView.document.pageCount {
  2610. pages.append("\(i)")
  2611. }
  2612. self.textFieldSheet.callback = { [weak self] stringValue in
  2613. guard let index = Int(stringValue) else {
  2614. return
  2615. }
  2616. if (self?.listView == nil) {
  2617. return
  2618. }
  2619. if (index > 0 && index <= self!.listView.document.pageCount) {
  2620. self?.listView.go(toPageIndex: index-1, animated: true)
  2621. }
  2622. }
  2623. self.textFieldSheet.showWindow(nil)
  2624. self.textFieldSheet.pageBox.addItems(withObjectValues: pages)
  2625. self.textFieldSheet.stringValue = "\(self.listView.currentPageIndex+1)"
  2626. }
  2627. //MARK: - 添加书签
  2628. @objc func menuItemBookMarkClick_add(sender:NSMenuItem?) {
  2629. if self.listView.document?.bookmark(forPageIndex: UInt(self.listView.currentPageIndex)) == nil {
  2630. let index = self.listView.currentPageIndex
  2631. self.listView.document?.addBookmark("\(KMLocalizedString("Page", comment: "")) \(index+1)", forPageIndex: UInt(index))
  2632. self.listView.updateRender(true)
  2633. } else {
  2634. self.listView.document?.removeBookmark(forPageIndex: UInt(self.listView.currentPageIndex))
  2635. self.listView.updateRender(true)
  2636. }
  2637. botaViewController?.reloadData()
  2638. self.listView.undoManager?.setActionName("")//添加undo事件就可删除
  2639. }
  2640. //MARK: - 页面旋转
  2641. func rotateLeft(page:CPDFPage,listView:CPDFListView?) {
  2642. Task { @MainActor in
  2643. let rotation = page.rotation
  2644. page.leftRotate()
  2645. listView?.layoutDocumentView()
  2646. if(listView == self.listView) {
  2647. var pageIndexes = IndexSet()
  2648. pageIndexes.insert(Int(page.pageIndex()))
  2649. KMNThumbnailManager.reloadThumImage(document: self.listView.document, pageIndexs: pageIndexes)
  2650. botaViewController?.reloadData()
  2651. }
  2652. }
  2653. }
  2654. func rotateRight(page:CPDFPage,listView:CPDFListView?) {
  2655. Task { @MainActor in
  2656. let rotation = page.rotation
  2657. page.rightRotate()
  2658. listView?.layoutDocumentView()
  2659. if(listView == self.listView) {
  2660. var pageIndexes = IndexSet()
  2661. pageIndexes.insert(Int(page.pageIndex()))
  2662. KMNThumbnailManager.reloadThumImage(document: self.listView.document, pageIndexs: pageIndexes)
  2663. botaViewController?.reloadData()
  2664. }
  2665. }
  2666. }
  2667. //MARK: - 自动滚动
  2668. func isAutoFlowOn() -> Bool {
  2669. return listView.isAutoFlow()
  2670. }
  2671. func toggleAutoFlow(_ sender: Any?) {
  2672. if (listView.isAutoFlow()) {
  2673. listView.stopAutoFlow()
  2674. } else {
  2675. listView.startAutoFlow()
  2676. }
  2677. }
  2678. //MARK: - 高亮Form
  2679. func highlightFormFiled(_ sender: Any?) {
  2680. let enabled = CPDFKitConfig.sharedInstance().enableFormFieldHighlight()
  2681. CPDFKitConfig.sharedInstance().setEnableFormFieldHighlight(!enabled)
  2682. listView.setNeedsDisplayForVisiblePages()
  2683. self.alertTipViewController.reloadFormAlertUI()
  2684. }
  2685. //MARK: - 高亮Link
  2686. func highlightLinks(_ sender: Any?) {
  2687. let enabled = CPDFKitConfig.sharedInstance().enableLinkFieldHighlight()
  2688. CPDFAnnotation.updateLinkFieldHighlight(listView, linkFieldHighlight: !enabled)
  2689. }
  2690. //MARK: - 重置Form
  2691. func resetForm(_ sender: Any?) {
  2692. listView.resetFormAnnotation()
  2693. }
  2694. //MARK: - 属性
  2695. @IBAction func menuItemAction_property(_ sender: Any?) {
  2696. showFileInfo()
  2697. }
  2698. //MARK: - 打印
  2699. @IBAction func menuItemAction_print(_ sender: Any?) {
  2700. self.showPrintWindow()
  2701. }
  2702. //MARK: - Flattened
  2703. func saveAsFlattenedPDFAction() {
  2704. DispatchQueue.main.async {
  2705. NSPanel.savePanel(self.view.window!, true) { panel in
  2706. panel.nameFieldStringValue = self.listView.document.documentURL.deletingPathExtension().lastPathComponent + "_flatten" + ".pdf"
  2707. } completion: { response, url, isOpen in
  2708. if (response == .cancel) {
  2709. return
  2710. }
  2711. var result = self.listView.document.writeFlatten(to: url!)
  2712. if (!result) {
  2713. return
  2714. }
  2715. if (isOpen) {
  2716. NSDocumentController.shared.km_safe_openDocument(withContentsOf: url!, display: true) { _, _, _ in
  2717. }
  2718. } else {
  2719. NSWorkspace.shared.activateFileViewerSelecting([url!])
  2720. }
  2721. }
  2722. }
  2723. }
  2724. func showInFinder() {
  2725. NSWorkspace.shared.activateFileViewerSelecting([self.listView.document.documentURL])
  2726. }
  2727. //MARK: - DisplayViewMode
  2728. func getPDFViewPageLayoutType() -> pageLayoutType {
  2729. if listView.displayMode() == .singlePage {
  2730. return .singlePage
  2731. } else if listView.displayMode() == .singlePageContinuous {
  2732. return .singlePageContinue
  2733. } else if listView.displayMode() == .twoUp {
  2734. if listView.displaysAsBook == true {
  2735. return .bookMode
  2736. }
  2737. return .twoPage
  2738. } else if listView.displayMode() == .twoUpContinuous {
  2739. if listView.displaysAsBook == true {
  2740. return .bookMode
  2741. }
  2742. return .twoPageContinue
  2743. }
  2744. return .singlePage
  2745. }
  2746. func updatePDFViewDisplayMode(viewMode mode: CPDFDisplayViewMode = .singlePage, isbookMode bookMode: Bool = false, direction directionValue: CPDFDisplayDirection? = nil) {
  2747. if bookMode == true {
  2748. //书本模式
  2749. listView.displaysAsBook = true
  2750. listView.displayTwoUp = true
  2751. if let value = directionValue {
  2752. listView.displayDirection = value
  2753. }
  2754. } else {
  2755. listView.setDisplay(mode)
  2756. }
  2757. listView.layoutDocumentView()
  2758. }
  2759. //MARK: - 新增大纲
  2760. @objc func addOutLineItemAction() {
  2761. toggleOpenLeftSide(pdfSideBarType: .outline)
  2762. botaViewController?.outlineViewC.addOutline()
  2763. }
  2764. //MARK: - 搜索
  2765. @objc func searchBaiduAction() {
  2766. let label = self.listView.currentSelection?.string() ?? ""
  2767. let query = label.addingPercentEncoding(withAllowedCharacters: .urlQueryAllowed) ?? ""
  2768. if let url = URL(string: "https://www.baidu.com/s?wd=\(query)") {
  2769. NSWorkspace.shared.open(url)
  2770. }
  2771. }
  2772. //MARK: - 转档
  2773. func showConvertWindow(_ convertType: KMPDFConvertType) {
  2774. var winC: KMConvertBaseWindowController = KMConvertBaseWindowController()
  2775. let model = KMDocumentModel(url: listView.document.documentURL)
  2776. model.password = listView.document.password ?? ""
  2777. if convertType == .word {
  2778. winC = KMConvertWordWindowController()
  2779. winC.documentModel = model
  2780. winC.own_beginSheetModal(for: self.view.window, completionHandler: nil)
  2781. } else if convertType == .ppt {
  2782. winC = KMConvertPPTsWindowController()
  2783. winC.subType = 1
  2784. winC.documentModel = model
  2785. winC.own_beginSheetModal(for: self.view.window, completionHandler: nil)
  2786. } else if convertType == .rtf {
  2787. winC = KMConvertPPTsWindowController()
  2788. winC.subType = 2
  2789. winC.documentModel = model
  2790. winC.own_beginSheetModal(for: self.view.window, completionHandler: nil)
  2791. } else if convertType == .text {
  2792. winC = KMConvertPPTsWindowController()
  2793. winC.subType = 4
  2794. winC.documentModel = model
  2795. winC.own_beginSheetModal(for: self.view.window, completionHandler: nil)
  2796. } else if convertType == .csv {
  2797. winC = KMConvertCSVWindowController()
  2798. winC.subType = 5
  2799. winC.documentModel = model
  2800. winC.own_beginSheetModal(for: self.view.window, completionHandler: nil)
  2801. } else if convertType == .excel {
  2802. winC = KMConvertExcelWindowController()
  2803. winC.documentModel = model
  2804. winC.own_beginSheetModal(for: self.view.window, completionHandler: nil)
  2805. } else if convertType == .html {
  2806. winC = KMConvertHtmlWindowController()
  2807. winC.documentModel = model
  2808. winC.own_beginSheetModal(for: self.view.window, completionHandler: nil)
  2809. } else if convertType == .json {
  2810. winC = KMConvertJsonWindowController()
  2811. winC.documentModel = model
  2812. winC.own_beginSheetModal(for: view.window, completionHandler: nil)
  2813. } else if convertType == .jpeg ||
  2814. convertType == .jpg ||
  2815. convertType == .png ||
  2816. convertType == .gif ||
  2817. convertType == .tiff ||
  2818. convertType == .tga ||
  2819. convertType == .bmp ||
  2820. convertType == .jp2{
  2821. winC = KMConvertImageWindowController()
  2822. winC.documentModel = model
  2823. winC.own_beginSheetModal(for: view.window, completionHandler: nil)
  2824. if let settingView = winC.settingView as? KMConvertImageSettingView {
  2825. settingView.selectConvertType(convertType: convertType)
  2826. }
  2827. }
  2828. winC.batchAction = { [unowned self] in
  2829. let model = KMBatchProcessingTableViewModel.initWithFilePath(url: listView.document.documentURL)
  2830. model.password = listView.document.password ?? ""
  2831. self.showBatchWindow(type: .convertPDF, subType: convertType.rawValue, files: [], fileModels: [model])
  2832. }
  2833. }
  2834. //MARK: - 选择Form注释
  2835. @objc func selectAllFormAnnotation (currentPage:CPDFPage) {
  2836. var formActiveAnnotations:[CPDFAnnotation] = []
  2837. for i in 0 ..< listView.document.pageCount {
  2838. let page = listView.document.page(at: i)
  2839. if(page?.pageIndex() == currentPage.pageIndex()) {
  2840. let annotations = page?.annotations
  2841. for j in 0 ..< (annotations?.count ?? 0) {
  2842. if let an = annotations?[j] as? CPDFAnnotation {
  2843. if (an.isKind(of: CPDFWidgetAnnotation.self) == true) {
  2844. formActiveAnnotations.append(an)
  2845. }
  2846. }
  2847. }
  2848. }
  2849. }
  2850. listView.updateActiveAnnotations(formActiveAnnotations)
  2851. }
  2852. @objc func selectAllNomerAnnotation (currentPage:CPDFPage) {
  2853. var normalActiveAnnotations:[CPDFAnnotation] = []
  2854. for i in 0 ..< listView.document.pageCount {
  2855. let page = listView.document.page(at: i)
  2856. if(page?.pageIndex() == currentPage.pageIndex()) {
  2857. let annotations = page?.annotations
  2858. for j in 0 ..< (annotations?.count ?? 0) {
  2859. if let an = annotations?[j] as? CPDFAnnotation {
  2860. if an.isKind(of: CPDFWidgetAnnotation.self) == true ||
  2861. an.isKind(of: CPDFLinkAnnotation.self) == true ||
  2862. an.isKind(of: CPDFRedactAnnotation.self) == true {
  2863. } else {
  2864. normalActiveAnnotations.append(an)
  2865. }
  2866. }
  2867. }
  2868. }
  2869. }
  2870. listView.updateActiveAnnotations(normalActiveAnnotations)
  2871. }
  2872. @objc func selectAllRedactAnnotation (currentPage:CPDFPage) {
  2873. var selectAllRedactAnnotation: [CPDFAnnotation] = []
  2874. for i in 0 ..< listView.document.pageCount {
  2875. let page = listView.document.page(at: i)
  2876. if(page?.pageIndex() == currentPage.pageIndex()) {
  2877. let annotations = page?.annotations
  2878. for j in 0 ..< (annotations?.count ?? 0) {
  2879. if let an = annotations?[j] as? CPDFAnnotation {
  2880. if an.isKind(of: CPDFRedactAnnotation.self) == true {
  2881. selectAllRedactAnnotation.append(an)
  2882. }
  2883. }
  2884. }
  2885. }
  2886. }
  2887. listView.updateActiveAnnotations(selectAllRedactAnnotation)
  2888. listView.setNeedsDisplayForVisiblePages()
  2889. }
  2890. //MARK: 搜索 & 替换
  2891. func showSearchPopWindow(type: KMNBotaSearchType, keyborad: String?, replaceText: String?, results: [KMSearchMode]) {
  2892. let toolMode = self.listView.toolMode
  2893. let isEditing = self.listView.isEditing()
  2894. var winH: CGFloat = 112
  2895. if type == .replace {
  2896. if IAPProductsManager.default().isAvailableAllFunction() == false {
  2897. let winC = KMPurchaseCompareWindowController.sharedInstance()
  2898. winC?.kEventName = "Reading_ReplaceText_BuyNow"
  2899. winC?.showWindow(nil)
  2900. return
  2901. }
  2902. if toolMode == .CEditPDFToolMode && isEditing {
  2903. } else { // 进入内容编辑模式
  2904. viewManager.toolMode = .Edit
  2905. updatePDFViewAnnotationMode()
  2906. }
  2907. winH = 208
  2908. }
  2909. self.view.window?.makeFirstResponder(nil)
  2910. let winC = KMSearchReplaceWindowController(with: listView, type: type)
  2911. self.currentWindowController = winC
  2912. winC.replaceCallback = { [weak self] in
  2913. let toolMode = self?.listView.toolMode ?? .none
  2914. let isEditing = self?.listView.isEditing() ?? false
  2915. if toolMode == .CEditPDFToolMode && isEditing {
  2916. } else { // 进入内容编辑模式
  2917. self?.viewManager.toolMode = .Edit
  2918. self?.updatePDFViewAnnotationMode()
  2919. }
  2920. }
  2921. winC.itemClick = { [weak self] idx, params in
  2922. if idx == 1 {
  2923. self?.toggleOpenLeftSide(pdfSideBarType: .search)
  2924. guard let handdler = params.first as? KMNSearchHanddler else {
  2925. return
  2926. }
  2927. let viewC = self?.botaViewController?.searchViewC
  2928. viewC?.update(keyborad: handdler.searchKey, replaceKey: handdler.replaceKey, results: handdler.searchSectionResults)
  2929. }
  2930. }
  2931. let targetView = self.pdfToolbarController?.leftViewButton
  2932. let point = targetView?.convert(targetView?.frame.origin ?? .zero, to: nil) ?? .zero
  2933. // 200 248
  2934. let x = point.x + (self.view.window?.frame.origin.x ?? 0) - 32
  2935. let y = point.y + (self.view.window?.frame.origin.y ?? 0) - winH - 32
  2936. let winFramePoint = NSPoint(x: x, y: y)
  2937. winC.window?.setFrameOrigin(winFramePoint)
  2938. winC.update(keyborad: keyborad, replaceKey: replaceText, results: results)
  2939. self.view.window?.addChildWindow(winC.window!, ordered: .above)
  2940. }
  2941. func searchPDF() {
  2942. }
  2943. func find_ReplacePDF() {
  2944. }
  2945. func fineNext() {
  2946. }
  2947. func findPrevious() {
  2948. }
  2949. func useSelectionForFind() {
  2950. }
  2951. // MARK: -显示加密弹窗
  2952. //MARK: - 测量
  2953. func refreshMeasureInfo() {
  2954. if distanceMeasureInfoWindowController == nil {
  2955. distanceMeasureInfoWindowController = CDistanceMeasureInfoWindowController()
  2956. }
  2957. if perimeterMeasureInfoWindowController == nil {
  2958. perimeterMeasureInfoWindowController = CPerimeterMeasureInfoWindowController()
  2959. }
  2960. if areaMeasureInfoWindowController == nil {
  2961. areaMeasureInfoWindowController = CAreaMeasureInfoWindowController()
  2962. }
  2963. showMeasureFloatingWindowsIfNeed()
  2964. }
  2965. @objc func cancelMeasureType() {
  2966. self.hideMeasureFloatingWindows()
  2967. }
  2968. func hideMeasureFloatingWindows() {
  2969. if distanceMeasureInfoWindowController?.window?.isVisible == true {
  2970. distanceMeasureInfoWindowController?.hideFloatingWindow()
  2971. } else if perimeterMeasureInfoWindowController?.window?.isVisible == true {
  2972. perimeterMeasureInfoWindowController?.hideFloatingWindow()
  2973. } else if areaMeasureInfoWindowController?.window?.isVisible == true {
  2974. areaMeasureInfoWindowController?.hideFloatingWindow()
  2975. }
  2976. }
  2977. func showMeasureFloatingWindowsIfNeed() {
  2978. cancelMeasureType()
  2979. let toolMode = self.listView.toolMode
  2980. if toolMode != .CNoteToolMode {
  2981. return
  2982. }
  2983. if let data = self.listView.activeAnnotation as? CPDFPolylineAnnotation {
  2984. } else if let data = self.listView.activeAnnotation as? CPDFPolygonAnnotation {
  2985. } else if let data = self.listView.activeAnnotation as? CPDFLineAnnotation, data.isMeasure {
  2986. } else {
  2987. let type = self.listView.annotationType
  2988. if type == .measureLine {
  2989. distanceMeasureInfoWindowController?.measureInfo = listView.distanceMeasureInfo
  2990. distanceMeasureInfoWindowController?.window?.orderFront(nil)
  2991. } else if type == .measurePolyLine {
  2992. perimeterMeasureInfoWindowController?.measureInfo = listView.perimeterMeasureInfo
  2993. perimeterMeasureInfoWindowController?.window?.orderFront(nil)
  2994. } else if type == .measurePolyGon {
  2995. areaMeasureInfoWindowController?.measureInfo = listView.polygonAreaMeasureInfo
  2996. areaMeasureInfoWindowController?.window?.orderFront(nil)
  2997. } else if type == .measureSquare {
  2998. areaMeasureInfoWindowController?.measureInfo = listView.squareAreaMeasureInfo
  2999. areaMeasureInfoWindowController?.window?.orderFront(nil)
  3000. } else {
  3001. cancelMeasureType()
  3002. }
  3003. }
  3004. }
  3005. func showMeasureSettingWindow() {
  3006. let distanceSettingWC = CDistanceSettingWindowController(measureInfo: self.listView.distanceMeasureInfo)
  3007. self.distanceMeasureInfoWindowController?.hideFloatingWindow()
  3008. distanceSettingWC.delegate = self
  3009. distanceSettingWC.own_beginSheetModal(for: self.view.window) { string in
  3010. }
  3011. }
  3012. }
  3013. //MARK: Compress
  3014. extension KMMainViewController {
  3015. // func showCompressController(_ url: URL) {
  3016. // let filePath = url.path
  3017. // if !FileManager.default.fileExists(atPath: filePath) {
  3018. // let alert = NSAlert.init()
  3019. // alert.alertStyle = .critical
  3020. // alert.messageText = "\(filePath.lastPathComponent) \(NSLocalizedString("File Not Exist", comment: ""))"
  3021. // alert.runModal()
  3022. // return
  3023. // }
  3024. //
  3025. // let document = CPDFDocument(url: url)
  3026. // document?.unlock(withPassword: model.password)
  3027. //
  3028. // if !document!.allowsPrinting && !document!.allowsCopying {
  3029. // KMPasswordInputWindow.openWindow(window: NSWindow.currentWindow(), type: .owner, url: url) { [unowned self] result, password in
  3030. // if (result == .success) {
  3031. // let model = KMBatchProcessingTableViewModel.initWithFilePath(url: listView.document.documentURL)
  3032. // model.password = password ?? ""
  3033. // model.isLock = false
  3034. // self.showCompressController(model: model)
  3035. // }
  3036. // }
  3037. // } else {
  3038. // let model = KMBatchProcessingTableViewModel.initWithFilePath(url: listView.document.documentURL)
  3039. // self.showCompressController(model: model)
  3040. // }
  3041. // }
  3042. func showCompressController(model: KMBatchProcessingTableViewModel) {
  3043. let filePath = model.filePath
  3044. if !FileManager.default.fileExists(atPath: filePath) {
  3045. let alert = NSAlert.init()
  3046. alert.alertStyle = .critical
  3047. alert.messageText = "\(filePath.lastPathComponent) \(NSLocalizedString("File Not Exist", comment: ""))"
  3048. alert.runModal()
  3049. return
  3050. }
  3051. let document = CPDFDocument(url: model.filePath.fileURL)
  3052. document?.unlock(withPassword: model.password)
  3053. if !document!.allowsPrinting && !document!.allowsCopying {
  3054. KMPasswordInputWindow.openWindow(window: NSWindow.currentWindow(), type: .owner, url: document!.documentURL) { [unowned self] result, password in
  3055. if (result == .success) {
  3056. // let model = KMBatchProcessingTableViewModel.initWithFilePath(url: model.filePath.fileURL)
  3057. model.password = password ?? ""
  3058. model.isLock = false
  3059. self.showCompress(model: model)
  3060. }
  3061. }
  3062. } else {
  3063. self.showCompress(model: model)
  3064. }
  3065. }
  3066. func showCompress(model: KMBatchProcessingTableViewModel) {
  3067. self.compressWindowController = KMCompressWindowController(windowNibName: "KMCompressWindowController")
  3068. self.compressWindowController?.password = model.password
  3069. self.compressWindowController?.documentURL = model.filePath.fileURL
  3070. let controllerWindow = self.view.window
  3071. controllerWindow?.beginSheet(self.compressWindowController!.window!)
  3072. self.compressWindowController?.itemClick = { [unowned self] in
  3073. controllerWindow?.endSheet((self.compressWindowController?.window)!)
  3074. }
  3075. self.compressWindowController?.batchAction = { [unowned self] view, filePaths in
  3076. controllerWindow?.endSheet((self.compressWindowController?.window)!)
  3077. self.showBatchWindow(type: .compress, files: filePaths)
  3078. }
  3079. self.compressWindowController?.resultCallback = { [unowned self] result, openDocument, fileURL, error in
  3080. controllerWindow?.endSheet((self.compressWindowController?.window)!)
  3081. if (result) {
  3082. if (openDocument) {
  3083. NSDocumentController.shared.openDocument(withContentsOf: fileURL, display: true) { document, result, error in }
  3084. } else {
  3085. NSWorkspace.shared.activateFileViewerSelecting([fileURL])
  3086. }
  3087. } else {
  3088. let alert = NSAlert()
  3089. alert.messageText = KMLocalizedString("Compress Faild", comment: "")
  3090. alert.runModal()
  3091. }
  3092. }
  3093. }
  3094. }
  3095. //MARK: - OCR
  3096. extension KMMainViewController {
  3097. //window
  3098. func showOCRWindow() {
  3099. if !IAPProductsManager.default().isAvailableAllFunction(){
  3100. let winC = KMPurchaseCompareWindowController.sharedInstance()
  3101. winC?.showWindow(nil)
  3102. return
  3103. }
  3104. let window = KMOCRSettingWindowController(windowNibName: "KMOCRSettingWindowController")
  3105. window.OCRAction = {[unowned self] controller, model in
  3106. self.convertOCRScanFile(window: window, document: self.listView.document, model: model)
  3107. }
  3108. window.cancelAction = {[unowned self] controller in
  3109. self.view.window?.endSheet(window.window ?? NSWindow())
  3110. }
  3111. self.view.window?.beginSheet(window.window ?? NSWindow())
  3112. // self.km_beginSheet(windowC: window)
  3113. }
  3114. func showOCREditAlert() {
  3115. DispatchQueue.main.asyncAfter(deadline: DispatchTime.now() + 0.3) { [unowned self] in
  3116. alertTipViewController.showInView(listView: listView, subView: infoSplitCenterView)
  3117. alertTipViewController.reloadOCRAlertUI()
  3118. alertTipViewController.reloadAlertUIFrame()
  3119. alertTipViewController.OCRApplyCallback = { [unowned self] in
  3120. self.showOCRWindow()
  3121. }
  3122. }
  3123. }
  3124. func closeOCREditAlert() {
  3125. guard let view = alertTipViewController.OCRComponentAlert else { return }
  3126. alertTipViewController.reloadOCRAlertUI()
  3127. alertTipViewController.reloadAlertUIFrame()
  3128. }
  3129. func showOCRToolAlert(_ string: String) {
  3130. let alertView = ComponentMessage()
  3131. alertView.properties = ComponentMessageProperty(messageType: .normal_custom, title: KMLocalizedString(string))
  3132. alertView.frame = CGRectMake((CGRectGetWidth(self.listView.frame) - alertView.properties.propertyInfo.viewWidth) / 2,
  3133. CGRectGetHeight(self.listView.frame) - alertView.properties.propertyInfo.viewHeight - 8,
  3134. alertView.properties.propertyInfo.viewWidth,
  3135. alertView.properties.propertyInfo.viewHeight)
  3136. alertView.reloadData()
  3137. self.listView.addSubview(alertView)
  3138. // 自动移除视图
  3139. DispatchQueue.main.asyncAfter(deadline: .now() + 3) {
  3140. self.removeOCRToolAlert(alertView)
  3141. }
  3142. }
  3143. private func removeOCRToolAlert(_ alertView: NSView) {
  3144. // 淡出动画
  3145. NSAnimationContext.runAnimationGroup({ context in
  3146. context.duration = 0.3
  3147. alertView.animator().alphaValue = 0
  3148. }, completionHandler: {
  3149. alertView.removeFromSuperview()
  3150. })
  3151. }
  3152. //OCR
  3153. func convertOCRScanFile(window: KMOCRSettingWindowController, document: CPDFDocument, model: KMOCRModel) {
  3154. KMCompressManager.shared.showLoadingWindow(window: window.window)
  3155. KMCompressManager.shared.cancelAction = {
  3156. KMOCRManager.manager.cancelRecognition()
  3157. }
  3158. //当前页面需要提前设置
  3159. if model.pageRangeType == .current {
  3160. model.pageRange = [self.listView.currentPageIndex]
  3161. }
  3162. KMOCRManager.manager.convertScanFile(document: document, model: model, progress: { progress in
  3163. KMCompressManager.shared.updateLoadingProgress(value: progress)
  3164. }) { [weak self] document, text, error in
  3165. KMCompressManager.shared.dismissLoadiingWindow(window: window.window)
  3166. window.endLoading()
  3167. window.km_quick_endSheet()
  3168. if !model.saveAsPDF {
  3169. self?.listView.layoutDocumentView()
  3170. self?.needSave = true
  3171. }
  3172. }
  3173. }
  3174. func convertOCR(document: CPDFDocument, model: KMOCRModel) {
  3175. // self.view.window?.windowController.beginLoading()
  3176. //当前页面需要提前设置
  3177. if model.pageRangeType == .current {
  3178. model.pageRange = [self.listView.currentPageIndex]
  3179. }
  3180. KMOCRManager.manager.clearOCRTextData()
  3181. KMOCRManager.manager.convertOCR(document: document, model: model, beginProgress: { [weak self] progress in
  3182. KMCompressManager.shared.showLoadingWindow(window: self?.view.window)
  3183. }, progress: { [weak self] progress in
  3184. KMCompressManager.shared.updateLoadingProgress(value: progress)
  3185. }) { [weak self] document, text, error in
  3186. // self?.view.window?.windowController.endLoading()
  3187. // window.km_quick_endSheet()
  3188. if !model.saveAsPDF {
  3189. self?.listView.layoutDocumentView()
  3190. self?.needSave = true
  3191. }
  3192. KMCompressManager.shared.dismissLoadiingWindow(window: self?.view.window)
  3193. }
  3194. KMCompressManager.shared.cancelAction = {
  3195. KMOCRManager.manager.cancelRecognition()
  3196. }
  3197. }
  3198. func convertOCRSaveAsTXT(text: String) {
  3199. NSPanel.savePanel(NSWindow.currentWindow()) { panel in
  3200. let url: URL = self.listView.document.documentURL
  3201. panel.nameFieldStringValue = ""+url.deletingPathExtension().lastPathComponent+"_OCR"
  3202. panel.allowedFileTypes = ["txt"]
  3203. } completion: { [unowned self] response, url in
  3204. if (response == .cancel) {
  3205. return
  3206. }
  3207. let saveAsPDFFilePath = url?.path ?? ""
  3208. let outputURL = URL(fileURLWithPath: saveAsPDFFilePath)
  3209. try? text.write(to: outputURL, atomically: true, encoding: .utf8)
  3210. }
  3211. }
  3212. func convertSelectionRectOCR(rect: NSRect) {
  3213. let rect = NSIntegralRect(rect)
  3214. let orgPage : CPDFPage = listView.currentSelectionPage() ?? CPDFPage()
  3215. if let page : CPDFPage = orgPage.copy() as? CPDFPage {
  3216. KMCompressManager.shared.showLoadingWindow(window: self.view.window)
  3217. KMCompressManager.shared.cancelAction = {
  3218. KMOCRManager.manager.cancelRecognition()
  3219. }
  3220. page.setBounds(rect, for: .cropBox)
  3221. let image = page.thumbnail(of: rect.size) ?? NSImage()
  3222. guard let model = self.rightSideController?.tool_OCRController?.model else { return }
  3223. model.pageRange = [Int(orgPage.pageIndex())]
  3224. KMOCRManager.manager.clearOCRTextData()
  3225. KMOCRManager.manager.convertOCR(images: [image], model: model, progress: { progress in
  3226. KMCompressManager.shared.updateLoadingProgress(value: progress)
  3227. }) { [weak self] document, text, error in
  3228. KMCompressManager.shared.dismissLoadiingWindow(window: self?.view.window)
  3229. self?.rightSideController?.tool_OCRController?.model.text = text ?? ""
  3230. self?.rightSideController?.tool_OCRController?.reloadData()
  3231. //关闭窗口
  3232. // self?.listView.selectionRect = NSZeroRect
  3233. // self?.listView.selectionPageIndex = UInt(NSNotFound)
  3234. // self?.closePopOperationWindow()
  3235. // self?.listView.setNeedsDisplayForVisiblePages()
  3236. }
  3237. }
  3238. }
  3239. }
  3240. //MARK: Batch
  3241. extension KMMainViewController {
  3242. func showBatchWindow(type: KMBatchCollectionViewType, fileModels: [KMBatchProcessingTableViewModel]?) {
  3243. self.showBatchWindow(type: type, subType: 0, files: [], fileModels: fileModels ?? [])
  3244. }
  3245. func showBatchWindow(type: KMBatchCollectionViewType, files: [URL]?) {
  3246. self.showBatchWindow(type: type, subType: 0, files: files ?? [], fileModels: [])
  3247. }
  3248. func showBatchWindow(type: KMBatchCollectionViewType, subType: Int = 0, files: [URL] = [], fileModels: [KMBatchProcessingTableViewModel] = []) {
  3249. let batchWindowController = KMBatchWindowController.manager
  3250. batchWindowController.window?.makeKeyAndOrderFront("")
  3251. if files.count != 0 {
  3252. batchWindowController.inputData = files
  3253. }
  3254. if fileModels.count != 0 {
  3255. batchWindowController.inputDataModel = fileModels
  3256. }
  3257. batchWindowController.type = type
  3258. batchWindowController.inputSubType = subType
  3259. }
  3260. }
  3261. //MARK: - 代理方法
  3262. //MARK: - NSSplitViewDelegate
  3263. extension KMMainViewController: NSSplitViewDelegate {
  3264. func splitView(_ splitView: NSSplitView, canCollapseSubview subview: NSView) -> Bool {
  3265. if splitView == infoContendSplitView {
  3266. return subview.isEqual(to: infoSplitCenterView) == false
  3267. }
  3268. return false
  3269. }
  3270. func splitView(_ splitView: NSSplitView, shouldCollapseSubview subview: NSView, forDoubleClickOnDividerAt dividerIndex: Int) -> Bool {
  3271. if splitView == infoContendSplitView {
  3272. if(subview.isEqual(to: infoSplitLeftView)) {
  3273. } else if(subview.isEqual(to: infoSplitRightView)) {
  3274. }
  3275. }
  3276. return false
  3277. }
  3278. func splitView(_ splitView: NSSplitView, shouldHideDividerAt dividerIndex: Int) -> Bool {
  3279. if splitView == infoContendSplitView {
  3280. return splitView == infoContendSplitView
  3281. } else if splitView == pdfSplitView {
  3282. return splitView == pdfSplitView
  3283. }
  3284. return false
  3285. }
  3286. func splitView(_ splitView: NSSplitView, constrainMaxCoordinate proposedMaximumPosition: CGFloat, ofSubviewAt dividerIndex: Int) -> CGFloat {
  3287. if splitView == infoContendSplitView {
  3288. if dividerIndex == 0 {
  3289. if viewManager.showDisplayView {
  3290. return MIN_SIDE_PANE_WIDTH.doubleValue
  3291. }
  3292. return infoContendSplitView.bounds.width/2
  3293. } else if (dividerIndex == 1) {
  3294. return proposedMaximumPosition - MIN_SIDE_PANE_WIDTH.doubleValue
  3295. }
  3296. }
  3297. return proposedMaximumPosition
  3298. }
  3299. func splitView(_ splitView: NSSplitView, constrainMinCoordinate proposedMinimumPosition: CGFloat, ofSubviewAt dividerIndex: Int) -> CGFloat {
  3300. if(splitView == infoContendSplitView && dividerIndex == 0) {
  3301. return proposedMinimumPosition + MIN_SIDE_PANE_WIDTH.doubleValue
  3302. }
  3303. return proposedMinimumPosition
  3304. }
  3305. func splitView(_ splitView: NSSplitView, shouldAdjustSizeOfSubview view: NSView) -> Bool {
  3306. if splitView == infoContendSplitView {
  3307. if view == splitView.subviews[0] || view == splitView.subviews[2] {
  3308. return false
  3309. }
  3310. }
  3311. return true
  3312. }
  3313. func splitViewDidResizeSubviews(_ notification: Notification) {
  3314. let splitView = notification.object as? NSSplitView
  3315. if(splitView == infoContendSplitView) {
  3316. leftSplitViewResizeFinish()
  3317. if(newMwcFlags.settingUpWindow == false && self.view.window?.frameAutosaveName != nil) {
  3318. let leftWidth = infoContendSplitView.isSubviewCollapsed(infoSplitLeftView) ? 0.0 : infoSplitLeftView.frame.width
  3319. UserDefaults.standard.set(leftWidth, forKey: CPDFViewLeftSidePaneWidthKey)
  3320. UserDefaults.standard.synchronize()
  3321. }
  3322. if listView.isEditing() == false {
  3323. updateAnnotationsPopWinodwFrame()
  3324. } else {
  3325. updateContentEditPopWinodwFrame()
  3326. }
  3327. }
  3328. NSObject.cancelPreviousPerformRequests(withTarget: self, selector: #selector(splitViewResizeFinish), object: nil)
  3329. self.perform(#selector(splitViewResizeFinish), with: nil, afterDelay: 0.15)
  3330. }
  3331. @objc func leftSplitViewResizeFinish() {
  3332. botaViewController?.changeLeftSideBounds()
  3333. }
  3334. @objc func splitViewResizeFinish() {
  3335. if infoContendSplitView.isSubviewCollapsed(infoSplitLeftView) {
  3336. if viewManager.pdfSideBarType != .none {
  3337. viewManager.pdfSideBarType = .none
  3338. sideBarController?.reloadBOTAData()
  3339. }
  3340. }
  3341. }
  3342. }
  3343. //MARK: - KMPDFSideBarControllerDelegate 左侧Sidebar代理
  3344. extension KMMainViewController: KMPDFSideBarControllerDelegate {
  3345. func kmPDFSideBarControllerDidSidebarTypeUpdated(_ view: KMPDFSideBarController) {
  3346. if viewManager.pdfSideBarType == .none {
  3347. toggleCloseLeftSide()
  3348. } else {
  3349. toggleOpenLeftSide(pdfSideBarType: viewManager.pdfSideBarType)
  3350. }
  3351. }
  3352. func kmPDFSideBarControllerDidGotoPage(_ view: KMPDFSideBarController, _ pageIndex: Int) {
  3353. listView.go(toPageIndex: pageIndex, animated: true)
  3354. }
  3355. }
  3356. //MARK: - KMPDFToolbarControllerDelegate 工具栏代理
  3357. extension KMMainViewController: KMPDFToolbarControllerDelegate {
  3358. //MARK: -ViewTools发生变化时调用
  3359. func kmPDFToolbarControllerDidViewToolsChanged(_ controller: KMPDFToolbarController) {
  3360. let viewToolsType = viewManager.viewToolsType
  3361. if viewToolsType == .Select {
  3362. listView.toolMode = .CNoteToolMode
  3363. } else if viewToolsType == .Scroll {
  3364. listView.toolMode = .CMoveToolMode
  3365. } else if viewToolsType == .Content_Selection {
  3366. listView.toolMode = .CSelectToolMode
  3367. } else if viewToolsType == .Magnify {
  3368. listView.toolMode = .CMagnifyToolMode
  3369. } else if viewToolsType == .AreaZoom {
  3370. listView.toolMode = .CSelectZoomToolMode
  3371. }
  3372. refreshToolbarViewHeightInfo()
  3373. }
  3374. //MARK: -一级工具栏状态发生变化时调用
  3375. func kmPDFToolbarControllerDidToolModeChanged(_ controller: KMPDFToolbarController) {
  3376. refreshToolbarViewHeightInfo()
  3377. toolbarViewModeChanged()
  3378. }
  3379. //MARK: -点击工具栏按钮
  3380. func kmPDFToolbarControllerDidToolbarItemClickedEnable(_ controller: KMPDFToolbarController, _ itemIdentifier: String) -> Bool {
  3381. if viewManager.subToolMode == .Edit_Crop && itemIdentifier == KMPDFToolbar_edit_crop_Identifier {
  3382. if rightSideController?.edit_cropController?.cropEnable() == true {
  3383. let alert = NSAlert()
  3384. alert.messageText = KMLocalizedString("There are unapplied settings, do you want to apply them?", comment: "")
  3385. alert.informativeText = KMLocalizedString("If not, the changes will be lost.", comment: "")
  3386. alert.addButton(withTitle: KMLocalizedString("Apply", comment: ""))
  3387. alert.addButton(withTitle: KMLocalizedString("Cancel", comment: ""))
  3388. let result = alert.runModal()
  3389. if (result == .alertFirstButtonReturn) {
  3390. //Apply
  3391. if let button = self.rightSideController?.edit_cropController?.cropButton {
  3392. self.rightSideController?.edit_cropController?.cropButtonClicked(button)
  3393. }
  3394. } else if (result == .alertSecondButtonReturn) {
  3395. //Cancel
  3396. return true
  3397. }
  3398. return false
  3399. }
  3400. }
  3401. return true
  3402. }
  3403. func kmPDFToolbarControllerDidToolbarItemClicked(_ controller: KMPDFToolbarController, _ itemIdentifier: String) {
  3404. print("toolbar点击", itemIdentifier)
  3405. if toolbarManager.getSubToolItemIdentifys(KMPDFToolbar_PageEdit_Identifier).contains(itemIdentifier) {
  3406. //MARK: -页面编辑
  3407. if itemIdentifier == KMPDFToolbar_PageEdit_InsertFile_Identifier {
  3408. pageEditViewController?.insertFromPDFAction()
  3409. } else if itemIdentifier == KMPDFToolbar_PageEdit_InsertBlank_Identifier {
  3410. pageEditViewController?.insertFromBlankAction()
  3411. } else if itemIdentifier == KMPDFToolbar_PageEdit_InsertClip_Identifier {
  3412. pageEditViewController?.insertFromClipboardAction()
  3413. } else if itemIdentifier == KMPDFToolbar_PageEdit_InsertScanner_Identifier {
  3414. pageEditViewController?.insertFromScannerAction()
  3415. } else if itemIdentifier == KMPDFToolbar_PageEdit_Extract_Identifier {
  3416. pageEditViewController?.extractPDFAction()
  3417. } else if itemIdentifier == KMPDFToolbar_PageEdit_Replace_Identifier {
  3418. pageEditViewController?.replacePDFAction()
  3419. } else if itemIdentifier == KMPDFToolbar_PageEdit_Split_Identifier {
  3420. pageEditViewController?.splitPDFAction()
  3421. } else if itemIdentifier == KMPDFToolbar_PageEdit_Reverse_Identifier {
  3422. pageEditViewController?.reversePDFAction()
  3423. } else if itemIdentifier == KMPDFToolbar_PageEdit_LeftRotate_Identifier {
  3424. pageEditViewController?.rotatePageLeftAction()
  3425. } else if itemIdentifier == KMPDFToolbar_PageEdit_RightRotate_Identifier{
  3426. pageEditViewController?.rotatePageRightAction()
  3427. } else if itemIdentifier == KMPDFToolbar_PageEdit_Delete_Identifier {
  3428. pageEditViewController?.deletePageAction()
  3429. } else if itemIdentifier == KMPDFToolbar_PageEdit_Reduce_Identifier {
  3430. pageEditViewController?.zoomOutPageAction()
  3431. if(pageEditViewController?.canZoomInPageSize() == false) {
  3432. toolbarManager.page_Increase_Property.isDisabled = true
  3433. } else {
  3434. toolbarManager.page_Increase_Property.isDisabled = false
  3435. }
  3436. if(pageEditViewController?.canZoomOutPageSize() == false) {
  3437. toolbarManager.page_Reduce_Property.isDisabled = true
  3438. } else {
  3439. toolbarManager.page_Reduce_Property.isDisabled = false
  3440. }
  3441. controller.refreshSecondToolbarItemsState()
  3442. } else if itemIdentifier == KMPDFToolbar_PageEdit_Increase_Identifier {
  3443. pageEditViewController?.zoomInPageAction()
  3444. if(pageEditViewController?.canZoomInPageSize() == false) {
  3445. toolbarManager.page_Increase_Property.isDisabled = true
  3446. } else {
  3447. toolbarManager.page_Increase_Property.isDisabled = false
  3448. }
  3449. if(pageEditViewController?.canZoomOutPageSize() == false) {
  3450. toolbarManager.page_Reduce_Property.isDisabled = true
  3451. } else {
  3452. toolbarManager.page_Reduce_Property.isDisabled = false
  3453. }
  3454. controller.refreshSecondToolbarItemsState()
  3455. } else if itemIdentifier == KMPDFToolbar_PageEdit_page_oddPage_Identifier {
  3456. pageEditViewController?.thumbnailChoosePageStyle = .odd
  3457. if(toolbarManager.page_pageInfo_Property.creatable == true) {
  3458. toolbarManager.page_pageInfo_Property.creatable = false
  3459. controller.refreshSecondToolbarItemsState()
  3460. }
  3461. } else if itemIdentifier == KMPDFToolbar_PageEdit_page_EvenPage_Identifier {
  3462. pageEditViewController?.thumbnailChoosePageStyle = .even
  3463. if(toolbarManager.page_pageInfo_Property.creatable == true) {
  3464. toolbarManager.page_pageInfo_Property.creatable = false
  3465. controller.refreshSecondToolbarItemsState()
  3466. }
  3467. } else if itemIdentifier == KMPDFToolbar_PageEdit_page_PortraitPage_Identifier {
  3468. pageEditViewController?.thumbnailChoosePageStyle = .horizontal
  3469. if(toolbarManager.page_pageInfo_Property.creatable == true) {
  3470. toolbarManager.page_pageInfo_Property.creatable = false
  3471. controller.refreshSecondToolbarItemsState()
  3472. }
  3473. } else if itemIdentifier == KMPDFToolbar_PageEdit_page_LandscapePage_Identifier {
  3474. pageEditViewController?.thumbnailChoosePageStyle = .vertical
  3475. if(toolbarManager.page_pageInfo_Property.creatable == true) {
  3476. toolbarManager.page_pageInfo_Property.creatable = false
  3477. controller.refreshSecondToolbarItemsState()
  3478. }
  3479. } else if itemIdentifier == KMPDFToolbar_PageEdit_page_AllPage_Identifier {
  3480. pageEditViewController?.thumbnailChoosePageStyle = .allPage
  3481. if(toolbarManager.page_pageInfo_Property.creatable == true) {
  3482. toolbarManager.page_pageInfo_Property.creatable = false
  3483. controller.refreshSecondToolbarItemsState()
  3484. }
  3485. } else if itemIdentifier == KMPDFToolbar_PageEdit_page_CustomPage_Identifier {
  3486. pageEditViewController?.thumbnailChoosePageStyle = .custom
  3487. toolbarManager.page_pageInfo_Property.text = nil
  3488. if(toolbarManager.page_pageInfo_Property.creatable == false) {
  3489. toolbarManager.page_pageInfo_Property.creatable = true
  3490. }
  3491. controller.refreshSecondToolbarItemsState()
  3492. }
  3493. } else if toolbarManager.getSubToolItemIdentifys(KMPDFToolbar_Markup_Identifier).contains(itemIdentifier) {
  3494. //MARK: -Markup
  3495. if itemIdentifier == KMPDFToolbar_eye_Identifier {
  3496. self.showOrHideNotes()
  3497. }
  3498. if viewManager.subToolMode == .None {
  3499. if SettingsManager.sharedInstance.autoExpandPropertyPanel == true {
  3500. viewManager.showRightSide = false
  3501. }
  3502. } else if SettingsManager.sharedInstance.autoExpandPropertyPanel == true {
  3503. viewManager.showRightSide = true
  3504. } else if viewManager.subToolMode == .Stamp || viewManager.subToolMode == .Sign {
  3505. viewManager.showRightSide = true
  3506. }
  3507. self.refreshToolbarRightViewInfo()
  3508. if let currentSelect = listView.currentSelection {
  3509. if(currentSelect.selectionType() == .text) {
  3510. let annotationType: CAnnotationType = KMPDFViewManager.getValidPDFAnnotationType(viewManager.subToolMode)
  3511. if annotationType != .unkown {
  3512. listView.addAnnotation(with: annotationType, selection: currentSelect, page: currentSelect.page, bounds: currentSelect.bounds)
  3513. }
  3514. }
  3515. }
  3516. toolbarViewModeChanged()
  3517. } else if toolbarManager.getSubToolItemIdentifys(KMPDFToolbar_Edit_Identifier).contains(itemIdentifier) {
  3518. //MARK: -编辑
  3519. if itemIdentifier == KMPDFToolbar_edit_addWatermark_Identifier {
  3520. showWatermarkController()
  3521. } else if itemIdentifier == KMPDFToolbar_edit_removeWatermark_Identifier {
  3522. removePDFWatermark()
  3523. } else if itemIdentifier == KMPDFToolbar_edit_batch_AddWatermark_Identifier {
  3524. batchAddWatermark()
  3525. } else if itemIdentifier == KMPDFToolbar_edit_batchRemoveWatermark_Identifier {
  3526. batchRemoveWatermark()
  3527. } else if itemIdentifier == KMPDFToolbar_edit_addBG_Identifier {
  3528. showBackgroundController()
  3529. } else if itemIdentifier == KMPDFToolbar_edit_removeBG_Identifier {
  3530. removePDFBackground()
  3531. } else if itemIdentifier == KMPDFToolbar_edit_batch_AddBG_Identifier {
  3532. batchAddBackground()
  3533. } else if itemIdentifier == KMPDFToolbar_edit_batchRemoveBG_Identifier {
  3534. batchRemoveBackground()
  3535. } else if itemIdentifier == KMPDFToolbar_edit_addHF_Identifier {
  3536. showHeaderFooterController()
  3537. } else if itemIdentifier == KMPDFToolbar_edit_removeHF_Identifier {
  3538. removeHeaderFooter()
  3539. } else if itemIdentifier == KMPDFToolbar_edit_batch_AddHF_Identifier {
  3540. batchAddHeaderFooter()
  3541. } else if itemIdentifier == KMPDFToolbar_edit_batchRemoveHF_Identifier {
  3542. batchRemoveHeaderFooter()
  3543. } else if itemIdentifier == KMPDFToolbar_edit_addBates_Identifier {
  3544. showBatesController()
  3545. } else if itemIdentifier == KMPDFToolbar_edit_removeBates_Identifier {
  3546. removePDFBates()
  3547. } else if itemIdentifier == KMPDFToolbar_edit_batch_AddBates_Identifier {
  3548. batchAddBates()
  3549. } else if itemIdentifier == KMPDFToolbar_edit_batchRemoveBates_Identifier {
  3550. batchRemoveBates()
  3551. } else if itemIdentifier == KMPDFToolbar_edit_crop_Identifier {
  3552. showCropController()
  3553. }
  3554. if viewManager.subToolMode == .None {
  3555. if SettingsManager.sharedInstance.autoExpandPropertyPanel == true {
  3556. viewManager.showRightSide = false
  3557. }
  3558. } else if SettingsManager.sharedInstance.autoExpandPropertyPanel == true {
  3559. viewManager.showRightSide = true
  3560. }
  3561. self.refreshToolbarRightViewInfo()
  3562. toolbarViewModeChanged()
  3563. } else if toolbarManager.getSubToolItemIdentifys(KMPDFToolbar_Form_Identifier).contains(itemIdentifier) {
  3564. //MARK: -Form表单
  3565. if itemIdentifier == KMPDFToolbar_form_HighlightFields_Identifier {
  3566. let value = CPDFKitConfig.sharedInstance().enableFormFieldHighlight()
  3567. CPDFAnnotation.updateHighlightFormFiled(listView, highlightFormFiled: !value)
  3568. self.toolbarManager.refreshDefaultConfigItem()
  3569. self.alertTipViewController.reloadFormAlertUI()
  3570. } else if itemIdentifier == KMPDFToolbar_form_ShowName_Identifier {
  3571. listView.showFormFieldName = !listView.showFormFieldName
  3572. if listView.showFormFieldName {
  3573. toolbarManager.form_ShowName_Property.righticon = NSImage(named: "tick_Green")
  3574. } else {
  3575. toolbarManager.form_ShowName_Property.righticon = nil
  3576. }
  3577. listView.setNeedsDisplayForVisiblePages()
  3578. } else if itemIdentifier == KMPDFToolbar_form_ClearForm_Identifier {
  3579. listView.resetFormAnnotation()
  3580. } else if itemIdentifier == KMPDFToolbar_form_Align_Left_Identifier {
  3581. listView.change(listView.activeAnnotations as? [CPDFAnnotation], alignmentType: .left)
  3582. listView.setNeedsDisplayForVisiblePages()
  3583. } else if itemIdentifier == KMPDFToolbar_form_Align_Hori_Identifier {
  3584. listView.change(listView.activeAnnotations as? [CPDFAnnotation], alignmentType: .horizontally)
  3585. listView.setNeedsDisplayForVisiblePages()
  3586. } else if itemIdentifier == KMPDFToolbar_form_Align_Right_Identifier {
  3587. listView.change(listView.activeAnnotations as? [CPDFAnnotation], alignmentType: .right)
  3588. listView.setNeedsDisplayForVisiblePages()
  3589. } else if itemIdentifier == KMPDFToolbar_form_Align_Top_Identifier {
  3590. listView.change(listView.activeAnnotations as? [CPDFAnnotation], alignmentType: .top)
  3591. listView.setNeedsDisplayForVisiblePages()
  3592. } else if itemIdentifier == KMPDFToolbar_form_Align_Vert_Identifier {
  3593. listView.change(listView.activeAnnotations as? [CPDFAnnotation], alignmentType: .vertical)
  3594. listView.setNeedsDisplayForVisiblePages()
  3595. } else if itemIdentifier == KMPDFToolbar_form_Align_Bottom_Identifier {
  3596. listView.change(listView.activeAnnotations as? [CPDFAnnotation], alignmentType: .bottom)
  3597. listView.setNeedsDisplayForVisiblePages()
  3598. } else if itemIdentifier == KMPDFToolbar_form_Distribute_Vert_Identifier {
  3599. listView.change(listView.activeAnnotations as? [CPDFAnnotation], alignmentType: .disVertical)
  3600. listView.setNeedsDisplayForVisiblePages()
  3601. } else if itemIdentifier == KMPDFToolbar_form_Distribute_Hori_Identifier {
  3602. listView.change(listView.activeAnnotations as? [CPDFAnnotation], alignmentType: .disHorizontally)
  3603. listView.setNeedsDisplayForVisiblePages()
  3604. }
  3605. if itemIdentifier == KMPDFToolbar_form_HighlightFields_Identifier ||
  3606. itemIdentifier == KMPDFToolbar_form_ShowName_Identifier ||
  3607. itemIdentifier == KMPDFToolbar_form_ClearForm_Identifier ||
  3608. itemIdentifier == KMPDFToolbar_form_Align_Left_Identifier ||
  3609. itemIdentifier == KMPDFToolbar_form_Align_Hori_Identifier ||
  3610. itemIdentifier == KMPDFToolbar_form_Align_Right_Identifier ||
  3611. itemIdentifier == KMPDFToolbar_form_Align_Top_Identifier ||
  3612. itemIdentifier == KMPDFToolbar_form_Align_Vert_Identifier ||
  3613. itemIdentifier == KMPDFToolbar_form_Align_Bottom_Identifier ||
  3614. itemIdentifier == KMPDFToolbar_form_Distribute_Vert_Identifier ||
  3615. itemIdentifier == KMPDFToolbar_form_Distribute_Hori_Identifier {
  3616. } else {
  3617. toolbarViewModeChanged()
  3618. }
  3619. } else if toolbarManager.getSubToolItemIdentifys(KMPDFToolbar_Fill_Identifier).contains(itemIdentifier) {
  3620. //MARK: -填充
  3621. if viewManager.subToolMode == .None {
  3622. if SettingsManager.sharedInstance.autoExpandPropertyPanel == true {
  3623. viewManager.showRightSide = false
  3624. }
  3625. } else if SettingsManager.sharedInstance.autoExpandPropertyPanel == true {
  3626. viewManager.showRightSide = true
  3627. }
  3628. self.refreshToolbarRightViewInfo()
  3629. toolbarViewModeChanged()
  3630. } else if toolbarManager.getSubToolItemIdentifys(KMPDFToolbar_Convert_Identifier).contains(itemIdentifier) {
  3631. //MARK: -转档
  3632. if itemIdentifier == KMPDFToolbar_convert_word_Identifier {
  3633. self.showConvertWindow(.word)
  3634. } else if itemIdentifier == KMPDFToolbar_convert_ppt_Identifier {
  3635. self.showConvertWindow(.ppt)
  3636. } else if itemIdentifier == KMPDFToolbar_convert_RTF_Identifier {
  3637. self.showConvertWindow(.rtf)
  3638. } else if itemIdentifier == KMPDFToolbar_convert_Text_Identifier {
  3639. self.showConvertWindow(.text)
  3640. } else if itemIdentifier == KMPDFToolbar_convert_CSV_Identifier {
  3641. self.showConvertWindow(.csv)
  3642. } else if itemIdentifier == KMPDFToolbar_convert_excel_Identifier {
  3643. self.showConvertWindow(.excel)
  3644. } else if itemIdentifier == KMPDFToolbar_convert_HTML_Identifier {
  3645. self.showConvertWindow(.html)
  3646. } else if itemIdentifier == KMPDFToolbar_convert_Json_Identifier {
  3647. self.showConvertWindow(.json)
  3648. } else if itemIdentifier == KMPDFToolbar_convert_image_Identifier {
  3649. self.showConvertWindow(.jpeg)
  3650. } else if itemIdentifier == KMPDFToolbar_convert_imageToPDF_Identifier {
  3651. self.showBatchWindow(type: .imageToPDF, files: [])
  3652. }
  3653. self.refreshToolbarRightViewInfo()
  3654. toolbarViewModeChanged()
  3655. } else if toolbarManager.getSubToolItemIdentifys(KMPDFToolbar_Protect_Identifier).contains(itemIdentifier) {
  3656. //MARK: -Protect
  3657. if itemIdentifier == KMPDFToolbar_protect_redact_Identifier {
  3658. toolbarViewModeChanged()
  3659. if viewManager.showRightSide == true {
  3660. viewManager.showRightSide = false
  3661. pdfToolbarController?.reloadRightToolsView()
  3662. toggleCloseRightSide()
  3663. }
  3664. self.enterRedactAlert()
  3665. } else if itemIdentifier == KMPDFToolbar_protect_redact_Property_Identifier {
  3666. self.showRedactProperty(readactAnnotation: nil)
  3667. toolbarViewModeChanged()
  3668. } else if itemIdentifier == KMPDFToolbar_protect_redact_Apply_Identifier {
  3669. toolbarViewModeChanged()
  3670. self.redactApplyAction(needAlert: false)
  3671. } else if itemIdentifier == KMPDFToolbar_protect_redact_Exit_Identifier {
  3672. toolbarViewModeChanged()
  3673. alertTipViewController.reloadRedactAlertUI()
  3674. alertTipViewController.reloadAlertUIFrame()
  3675. } else if itemIdentifier == KMPDFToolbar_protect_security_Identifier {
  3676. self.showSecureWindow()
  3677. } else if itemIdentifier == KMPDFToolbar_protect_removeSecurity_Identifier {
  3678. self.showRemoveSecureWindow()
  3679. } else if itemIdentifier == KMPDFToolbar_protect_digitalSign_Identifier {
  3680. self.toolbarViewModeChanged()
  3681. }
  3682. alertTipViewController.reloadAlertUIFrame()
  3683. } else if toolbarManager.getSubToolItemIdentifys(KMPDFToolbar_Tools_Identifier).contains(itemIdentifier) {
  3684. //MARK: -工具
  3685. if itemIdentifier == KMPDFToolbar_tools_compress_Identifier {
  3686. let model = KMBatchProcessingTableViewModel.initWithFilePath(url: listView.document.documentURL)
  3687. model.password = listView.document.password ?? ""
  3688. self.showCompressController(model: model)
  3689. } else if itemIdentifier == KMPDFToolbar_tools_batch_compress_Identifier {
  3690. let model = KMBatchProcessingTableViewModel.initWithFilePath(url: listView.document.documentURL)
  3691. model.password = listView.document.password ?? ""
  3692. self.showBatchWindow(type: .compress, files: [], fileModels: [model])
  3693. } else if itemIdentifier == KMPDFToolbar_tools_OCR_Identifier {
  3694. viewManager.showRightSide = !viewManager.showRightSide
  3695. self.refreshToolbarRightViewInfo()
  3696. } else if itemIdentifier == KMPDFToolbar_tools_merge_Identifier {
  3697. self.showMergeWindow()
  3698. } else if itemIdentifier == KMPDFToolbar_tools_TTS_Identifier {
  3699. self.showTTSWindow()
  3700. } else if itemIdentifier == KMPDFToolbar_tools_extractImage_Identifier {
  3701. self.extractImageAction(num: 2)
  3702. } else if itemIdentifier == KMPDFToolbar_tools_AITools_Identifier {
  3703. self.viewManager.pdfSideBarType = .aiTools
  3704. self.sideBarController?.reloadData()
  3705. if let sideVC = self.sideBarController {
  3706. self.kmPDFSideBarControllerDidSidebarTypeUpdated(sideVC)
  3707. }
  3708. } else if itemIdentifier == KMPDFToolbar_tools_compare_side_Identifier {
  3709. self.beginCompareAction(1)
  3710. } else if itemIdentifier == KMPDFToolbar_tools_compare_Overlay_Identifier {
  3711. self.beginCompareAction(2)
  3712. } else if itemIdentifier == KMPDFToolbar_tools_batch_Identifier {
  3713. let model = KMBatchProcessingTableViewModel.initWithFilePath(url: listView.document.documentURL)
  3714. model.password = listView.document.password ?? ""
  3715. self.showBatchWindow(type: .convertPDF, files: [], fileModels: [model])
  3716. }
  3717. if viewManager.subToolMode == .None {
  3718. if SettingsManager.sharedInstance.autoExpandPropertyPanel == true {
  3719. viewManager.showRightSide = false
  3720. }
  3721. } else if SettingsManager.sharedInstance.autoExpandPropertyPanel == true {
  3722. viewManager.showRightSide = true
  3723. }
  3724. self.refreshToolbarRightViewInfo()
  3725. toolbarViewModeChanged()
  3726. } else if itemIdentifier == KMPDFToolbar_ViewDisplay_Identifier {
  3727. //MARK: -Display
  3728. updatePDFDisplaySettingView()
  3729. } else if toolbarManager.getSubToolItemIdentifys(KMPDFToolbar_Right_Identifiers).contains(itemIdentifier) {
  3730. if(itemIdentifier == KMPDFToolbar_undo_Identifier) {
  3731. //MARK: -Undo
  3732. if(listView.isEditing()) {
  3733. if(listView.canEditTextUndo()){
  3734. listView.editTextUndo()
  3735. }
  3736. } else {
  3737. listView.undoManager?.undo()
  3738. }
  3739. } else if(itemIdentifier == KMPDFToolbar_redo_Identifier) {
  3740. //MARK: -Redo
  3741. if(listView.isEditing()) {
  3742. if(listView.canEditTextRedo()) {
  3743. listView.editTextRedo()
  3744. }
  3745. } else {
  3746. listView.undoManager?.redo()
  3747. }
  3748. } else if(itemIdentifier == KMPDFToolbar_fileInfo_Identifier) {
  3749. self.showFileInfo()
  3750. } else if(itemIdentifier == KMPDFToolbar_share_PDF_Identifier ||
  3751. itemIdentifier == KMPDFToolbar_share_Flattened_Identifier ||
  3752. itemIdentifier == KMPDFToolbar_share_Original_Identifier) {
  3753. //MARK: -Share
  3754. if(itemIdentifier == KMPDFToolbar_share_PDF_Identifier) {
  3755. if let view = controller.findViewWith(KMPDFToolbar_share_Identifier) {
  3756. shareDocument(sender: view)
  3757. }
  3758. } else if(itemIdentifier == KMPDFToolbar_share_Flattened_Identifier) {
  3759. if let view = controller.findViewWith(KMPDFToolbar_share_Identifier) {
  3760. shareFlatten(sender: view)
  3761. }
  3762. } else if(itemIdentifier == KMPDFToolbar_share_Original_Identifier) {
  3763. if let view = controller.findViewWith(KMPDFToolbar_share_Identifier) {
  3764. shareOriginalPDF(sender: view)
  3765. }
  3766. }
  3767. } else if itemIdentifier == KMPDFToolbar_save_Identifier {
  3768. myDocument?.save(nil)
  3769. } else if itemIdentifier == KMPDFToolbar_print_Identifier {
  3770. self.showPrintWindow()
  3771. } else if itemIdentifier == KMPDFToolbar_tts_Identifier {
  3772. self.showTTSWindow()
  3773. } else if itemIdentifier == KMPDFToolbar_ppt_Identifier {
  3774. self.togglePresentation(nil)
  3775. } else if itemIdentifier == KMPDFToolbar_batch_Identifier {
  3776. let model = KMBatchProcessingTableViewModel.initWithFilePath(url: listView.document.documentURL)
  3777. model.password = listView.document.password ?? ""
  3778. self.showBatchWindow(type: .convertPDF, files: [], fileModels: [model])
  3779. }
  3780. } else if itemIdentifier == KMPDFToolbar_PageEdit_Identifier {
  3781. //MARK: -页面编辑
  3782. if viewManager.isPageEditMode == true {
  3783. enterPageEditMode()
  3784. } else {
  3785. exitPageEditMode()
  3786. }
  3787. } else if itemIdentifier == KMPDFToolbar_rightView_Identifier {
  3788. //MARK: -属性栏
  3789. self.refreshToolbarRightViewInfo()
  3790. } else {
  3791. print("click else")
  3792. }
  3793. refreshToolbarViewHeightInfo()
  3794. refreshRightSide()
  3795. }
  3796. func kmPDFToolbarControllerDidSelectTextDidBeginEditing(_ controller: KMPDFToolbarController, _ view: ComponentSelect) {
  3797. }
  3798. func kmPDFToolbarControllerDidSelectTextDidChange(_ controller: KMPDFToolbarController, _ view: ComponentSelect) {
  3799. }
  3800. func kmPDFToolbarControllerDidSelectTextDidEndEditing(_ controller: KMPDFToolbarController, _ view: ComponentSelect) {
  3801. if view.properties == toolbarManager.page_pageInfo_Property {
  3802. if viewManager.isPageEditMode == true {
  3803. let fileAttribute = KMNFileAttribute()
  3804. fileAttribute.password = listView.document?.password ?? ""
  3805. fileAttribute.pdfDocument = listView.document
  3806. fileAttribute.filePath = listView.document?.documentURL.path ?? ""
  3807. fileAttribute.bAllPage = false
  3808. fileAttribute.pagesType = .PagesString
  3809. fileAttribute.pagesString = view.properties.text ?? ""
  3810. let fetchSelectPages = fileAttribute.fetchSelectPages()
  3811. if (fetchSelectPages.isEmpty) {
  3812. let alert = NSAlert()
  3813. alert.alertStyle = .critical
  3814. alert.messageText = String(format: "%@ %@", fileAttribute.filePath.lastPathComponent, KMLocalizedString("Invalid page range or the page number is out of range. Please try again."))
  3815. alert.runModal()
  3816. toolbarManager.page_pageInfo_Property.text = ""
  3817. controller.refreshSecondToolbarItemsState()
  3818. } else {
  3819. var tIndexPaths: Set<IndexPath> = []
  3820. for i in 0 ..< fetchSelectPages.count {
  3821. tIndexPaths.insert(IndexPath(item: (fetchSelectPages[i] - 1), section: 0))
  3822. }
  3823. pageEditViewController?.selectionIndexPaths = tIndexPaths
  3824. }
  3825. }
  3826. }
  3827. }
  3828. func kmPDFToolbarControllerDidExitPageEditMode(_ controller: KMPDFToolbarController) {
  3829. exitPageEditMode()
  3830. }
  3831. }
  3832. //MARK: - KMRightSideControllerDelegate右边属性栏代理
  3833. extension KMMainViewController: KMRightSideControllerDelegate {
  3834. func kmRightSideControllerRotateLeft(_ annotations: [CPDFStampAnnotation], withPDFView pdfView: CPDFListView?) {
  3835. CPDFStampAnnotation.rotateLeft(annotations, withPDFView: pdfView)
  3836. (undoManager?.prepare(withInvocationTarget: self) as AnyObject).kmRightSideControllerRotateRight(annotations, withPDFView: pdfView)
  3837. }
  3838. func kmRightSideControllerRotateRight(_ annotations: [CPDFStampAnnotation], withPDFView pdfView: CPDFListView?) {
  3839. CPDFStampAnnotation.rotateRight(annotations, withPDFView: pdfView)
  3840. (undoManager?.prepare(withInvocationTarget: self) as AnyObject).kmRightSideControllerRotateLeft(annotations, withPDFView: pdfView)
  3841. }
  3842. func kmRightSideControllerDidContendVCUpdated(_ controller: KMRightSideController) {
  3843. //MARK: -Crop
  3844. if (controller.contentViewController is KMCropPropertyController) {
  3845. if let cropVC = rightSideController?.edit_cropController {
  3846. cropVC.pdfView = controller.pdfView
  3847. if cropVC.delegate == nil {
  3848. cropVC.delegate = cropController
  3849. }
  3850. cropVC.reloadData()
  3851. }
  3852. }
  3853. reloadPopUIWindow()
  3854. }
  3855. func kmRightSideControllerOCRShowTypeChange(_ controller: KMRightSideController, _ type: KMOCRShowType) {
  3856. if type == .area {
  3857. self.listView.toolMode = .COCRToolMode
  3858. self.showOCRToolAlert(KMLocalizedString("Please select the area that needs OCR and click the “OCR” button to start"))
  3859. } else {
  3860. self.listView.toolMode = .CTextToolMode
  3861. }
  3862. }
  3863. func kmRightSideControllerOCRDoneAction(_ controller: KMRightSideController, _ model: KMOCRModel) {
  3864. if model.showType == .area {
  3865. self.convertOCRSaveAsTXT(text: model.text)
  3866. } else {
  3867. if model.saveAsPDF {
  3868. if model.saveType == .PDF {
  3869. } else {
  3870. }
  3871. } else {
  3872. }
  3873. self.convertOCR(document: self.listView.document, model: model)
  3874. }
  3875. }
  3876. func kmRightSideControllerOCRLanguageChangeAction(_ controller: KMRightSideController, _ model: KMOCRModel) {
  3877. self.convertSelectionRectOCR(rect: self.listView.currentSelectionRect())
  3878. }
  3879. //测量设置界面
  3880. func kmRightSideControllerShowMeasureSetting(_ controller: KMRightSideController) {
  3881. showMeasureSettingWindow()
  3882. }
  3883. //裁剪模块
  3884. func kmRightSideControllerDidRevertCropInfo(_ controller: KMRightSideController) {
  3885. if let cropVC = cropController {
  3886. cropVC.selectionRect = rightSideController?.edit_cropController?.pageBounds ?? CGRectZero
  3887. cropVC.reloadSelectionRect()
  3888. self.kmCropControllerDidChangedSelectionOrMagnification(cropVC)
  3889. }
  3890. }
  3891. }
  3892. //MARK: - KMNDisplayViewControllerDelegate代理
  3893. extension KMMainViewController: KMNDisplayViewControllerDelegate {
  3894. //Display Mode
  3895. func displayViewControllerDidDisplayModeChanged(_ controller: KMNDisplayViewController) {
  3896. listView.layoutDocumentView()
  3897. }
  3898. //阅读模式
  3899. func displayViewControllerDidReadModeUpdated(_ controller: KMNDisplayViewController) {
  3900. if viewManager.isPDFReadMode {
  3901. openPDFReadMode()
  3902. } else {
  3903. exitPDFReadMode()
  3904. }
  3905. }
  3906. //PPT
  3907. func displayViewControllerDidGotoSlideShow(_ controller: KMNDisplayViewController) {
  3908. togglePresentation(nil)
  3909. }
  3910. //SplitView
  3911. func displayViewControllerDidSplitModeChanged(_ controller: KMNDisplayViewController) {
  3912. reloadPDFSplitInfo()
  3913. }
  3914. func displayViewControllerDidSplitFileChanged(_ controller: KMNDisplayViewController) {
  3915. splitPDFController?.reloadData()
  3916. }
  3917. func displayViewControllerDidToolbarStateChanged(_ controller: KMNDisplayViewController) {
  3918. splitPDFController?.refreshToolbarState()
  3919. reloadPDFPageNumberToolbar()
  3920. }
  3921. }
  3922. //MARK: - PPT
  3923. extension KMMainViewController: KMInteractionProviderProtocol {
  3924. func providerContentView(fullScreenWindow: NSWindow, inset: CGFloat) -> NSView? {
  3925. if(interactionMode == .presentation) {
  3926. if listView.presentationDrawView == nil {
  3927. listView.createPresentationDraw()
  3928. }
  3929. presentationTopViewController = KMPresentationTopViewController.init(nibName: "KMPresentationTopViewController", bundle: nil)
  3930. presentationTopViewController?.pdfView = listView
  3931. presentationTopViewController?.delegate = self
  3932. presentationTopViewController?.isSelectionPre = true
  3933. listView.isPresentationMode = true
  3934. presentationTopViewController?.view.frame = CGRect(x: 0, y: (fullScreenWindow.contentView?.bounds.height ?? 0) - 42, width: fullScreenWindow.contentView?.bounds.width ?? 0, height: 42)
  3935. if((presentationTopViewController) != nil) {
  3936. fullScreenWindow.contentView?.addSubview(presentationTopViewController!.view)
  3937. }
  3938. } else {
  3939. listView.frame = NSInsetRect(fullScreenWindow.contentView?.bounds ?? .zero, 0, 0)
  3940. }
  3941. fullScreenWindow.contentView?.addSubview(listView)
  3942. if(interactionMode == .presentation) {
  3943. let frame = fullScreenWindow.frame
  3944. listView.frame = CGRectMake(0, 0, frame.size.width, frame.size.height-42)
  3945. listView.autoresizingMask = [.width, .maxYMargin]
  3946. }
  3947. return view
  3948. }
  3949. @objc func willEnterInteractionModeNotification(_ sender: Notification) {
  3950. guard let win = sender.object as? NSWindow, win.isEqual(to: self.view.window) else {
  3951. return
  3952. }
  3953. let interactionMode = sender.userInfo?[NSWindow.UserInfo.interactionModeKey] as? KMInteractionMode
  3954. if interactionMode == .presentation {
  3955. let backgroundColor = NSColor.black
  3956. let level = UserDefaults.standard.bool(forKey: "SKUseNormalLevelForPresentationKey") ? NSWindow.Level.normal : NSWindow.Level.popUpMenu
  3957. let wasInteractionMode = self.interactionMode
  3958. if wasInteractionMode == .normal {
  3959. self.savedNormalSetup.setDictionary(self.currentPDFSettings() as! [AnyHashable : Any])
  3960. }
  3961. if wasInteractionMode == .legacyFullScreen {
  3962. self.enterPresentationMode()
  3963. self.listView.frame = (self.view.window?.contentView?.bounds)!
  3964. self.view.window?.contentView?.addSubview(listView)
  3965. // self.view.window?.backgroundColor = backgroundColor
  3966. self.view.window?.level = level
  3967. self.listView.layoutDocumentView()
  3968. self.listView.requiresDisplay()
  3969. }
  3970. } else {
  3971. KMPrint("2")
  3972. }
  3973. }
  3974. @objc func didEnterInteractionModeNotification(_ sender: Notification) {
  3975. guard let win = sender.object as? NSWindow, win.isEqual(to: self.view.window) else {
  3976. return
  3977. }
  3978. if self.interactionMode == .presentation {
  3979. self.listView.layoutDocumentView()
  3980. self.listView.requiresDisplay()
  3981. }
  3982. }
  3983. @objc func willShowFullScreenNotification(_ sender: Notification) {
  3984. guard let win = sender.object as? NSWindow, win.isEqual(to: self.view.window) else {
  3985. return
  3986. }
  3987. if self.interactionMode == .presentation {
  3988. let view = self.view.window?.firstResponder as? NSView
  3989. if let data = view?.isDescendant(of: self.pdfSplitView), data {
  3990. self.view.window?.makeFirstResponder(nil)
  3991. }
  3992. }
  3993. }
  3994. @objc func didShowFullScreenNotification(_ sender: Notification) {
  3995. guard let win = sender.object as? NSWindow, win.isEqual(to: self.view.window) else {
  3996. return
  3997. }
  3998. if self.interactionMode == .presentation {
  3999. self.enterPresentationMode()
  4000. }
  4001. }
  4002. }
  4003. // MARK: -KMPresentationTopViewControllerDelegate (幻灯片)
  4004. extension KMMainViewController: KMPresentationTopViewControllerDelegate {
  4005. func presentationTopViewExit(_ presentationTopViewController: KMPresentationTopViewController, withButton: NSButton) {
  4006. self.exitFullScreen()
  4007. }
  4008. func presentationTopViewClear(_ presentationTopViewController: KMPresentationTopViewController, withButton: NSButton) {
  4009. listView.presentationDrawView?.clear()
  4010. }
  4011. func presentationTopViewUndo(_ presentationTopViewController: KMPresentationTopViewController, withButton: NSButton) {
  4012. let presentationDrawView = listView.presentationDrawView
  4013. if presentationDrawView?.canUndo() == true {
  4014. presentationDrawView?.undo()
  4015. }
  4016. }
  4017. func presentationTopViewType(_ presentationTopViewController: KMPresentationTopViewController, withButton: NSButton, isSeletion: Bool) {
  4018. listView.isPresentationMode = isSeletion
  4019. if listView.isEnterPresentationDrawMode() == true {
  4020. listView.exitPresentationDrawMode()
  4021. }
  4022. }
  4023. func presentationTopViewDrawColor(_ presentationTopViewController: KMPresentationTopViewController, withView: NSView,color:NSColor?) {
  4024. if color == nil{
  4025. listView.exitPresentationDrawMode()
  4026. } else {
  4027. if listView.isEnterPresentationDrawMode() == false {
  4028. listView.enterPresentationDrawMode()
  4029. }
  4030. listView.changePresentationDrawModelColor(color)
  4031. }
  4032. }
  4033. }
  4034. //MARK: - KMSplitPDFViewControllerDelegate SplitPDFView分屏视图
  4035. extension KMMainViewController: KMSplitPDFViewControllerDelegate {
  4036. func splitPDFViewControllerDidUpdateFilePath(_ controller: KMSplitPDFViewController) {
  4037. displaySettingController?.reloadData()
  4038. }
  4039. func splitPDFViewControllerDidUpdatePDFScale(_ controller: KMSplitPDFViewController) {
  4040. if let scaleFactor = controller.pdfView?.scaleFactor {
  4041. listView.scaleFactor = scaleFactor
  4042. }
  4043. }
  4044. func splitPDFViewControllerDidUpdatePDFPageIndex(_ controller: KMSplitPDFViewController) {
  4045. if let pageIndex = controller.pdfView?.currentPageIndex {
  4046. listView.go(toPageIndex: pageIndex, animated: false)
  4047. }
  4048. }
  4049. }
  4050. //MARK: - Edit编辑相关代理
  4051. extension KMMainViewController: KMEditToolbarViewDelegate {
  4052. func kmEditToolbarViewDidUpdateMode(_ view: KMEditToolbarView) {
  4053. if view.editType == .watermark {
  4054. watermarkViewController?.editSubType = editToolbarView?.editSubType ?? .template
  4055. watermarkViewController?.reloadData()
  4056. watermarkViewController?.loadData()
  4057. } else if view.editType == .background {
  4058. backgroundViewController?.editSubType = editToolbarView?.editSubType ?? .template
  4059. backgroundViewController?.resetUI()
  4060. backgroundViewController?.reloadData()
  4061. } else if view.editType == .header_Footer {
  4062. headerFooterViewController?.editSubType = editToolbarView?.editSubType ?? .template
  4063. headerFooterViewController?.resetUI()
  4064. headerFooterViewController?.reloadData()
  4065. } else if view.editType == .bates {
  4066. batesViewController?.editSubType = editToolbarView?.editSubType ?? .template
  4067. batesViewController?.resetUI()
  4068. batesViewController?.reloadData()
  4069. }
  4070. }
  4071. func kmEditToolbarViewDidChooseBatch(_ view: KMEditToolbarView) {
  4072. if view.editType == .watermark {
  4073. self.showBatchWindow(type: .watermark, files: [URL(fileURLWithPath: self.document?.documentURL.path ?? "")])
  4074. } else if view.editType == .background {
  4075. self.showBatchWindow(type: .background, files: [URL(fileURLWithPath: self.document?.documentURL.path ?? "")])
  4076. } else if view.editType == .header_Footer {
  4077. self.showBatchWindow(type: .headerAndFooter, files: [URL(fileURLWithPath: self.document?.documentURL.path ?? "")])
  4078. } else if view.editType == .bates {
  4079. self.showBatchWindow(type: .batesNumber, files: [URL(fileURLWithPath: self.document?.documentURL.path ?? "")])
  4080. }
  4081. }
  4082. func kmEditToolbarViewDidChooseApply(_ view: KMEditToolbarView) {
  4083. let pageInfo = view.pageRangeSelectView.getSelectedPageIndex(listView.document)
  4084. let pageIndex = pageInfo.0
  4085. let isCurrentPage = pageInfo.1
  4086. if pageIndex.isEmpty {
  4087. let alert = NSAlert()
  4088. alert.alertStyle = .critical
  4089. alert.messageText = KMLocalizedString("Invalid page range or the page number is out of range. Please try again.")
  4090. alert.runModal()
  4091. return
  4092. }
  4093. var pageString = view.pageRangeSelectView.getSelectedPageString(listView.document, pageIndex)
  4094. if isCurrentPage {
  4095. pageString = String(format: "%ld", listView.currentPageIndex)
  4096. }
  4097. if view.editType == .watermark {
  4098. if view.editSubType == .edit, let propertyVC = watermarkViewController?.propertyController, propertyVC.isOriginalDataDictChanged() == true {
  4099. propertyVC.showSaveEditChangeAlert(completion: { response in
  4100. if response == NSApplication.ModalResponse.alertFirstButtonReturn {
  4101. //OK
  4102. propertyVC.saveDataEdit()
  4103. self.applyWatermarkInfo(pageString)
  4104. } else {
  4105. //Cancel
  4106. propertyVC.cancelDataEdit()
  4107. }
  4108. })
  4109. } else {
  4110. self.applyWatermarkInfo(pageString)
  4111. }
  4112. } else if view.editType == .background {
  4113. if view.editSubType == .edit, let propertyVC = backgroundViewController?.propertyController, propertyVC.isOriginalDataDictChanged() == true {
  4114. propertyVC.showSaveEditChangeAlert(completion: { response in
  4115. if response == NSApplication.ModalResponse.alertFirstButtonReturn {
  4116. //OK
  4117. propertyVC.saveDataEdit()
  4118. self.applyBackgroundInfo(pageString)
  4119. } else {
  4120. //Cancel
  4121. propertyVC.cancelDataEdit()
  4122. }
  4123. })
  4124. } else {
  4125. self.applyBackgroundInfo(pageString)
  4126. }
  4127. } else if view.editType == .header_Footer {
  4128. if view.editSubType == .edit, let propertyVC = headerFooterViewController?.propertyController, propertyVC.isOriginalDataDictChanged() == true {
  4129. propertyVC.showSaveEditChangeAlert { response in
  4130. if response == NSApplication.ModalResponse.alertFirstButtonReturn {
  4131. //OK
  4132. propertyVC.saveDataEdit()
  4133. self.applyHeaderFooterInfo(pageString)
  4134. } else {
  4135. //Cancel
  4136. propertyVC.cancelDataEdit()
  4137. }
  4138. }
  4139. } else {
  4140. self.applyHeaderFooterInfo(pageString)
  4141. }
  4142. } else if view.editType == .bates {
  4143. if view.editSubType == .edit, let propertyVC = batesViewController?.propertyController, propertyVC.isOriginalDataDictChanged() == true {
  4144. propertyVC.showSaveEditChangeAlert { response in
  4145. if response == NSApplication.ModalResponse.alertFirstButtonReturn {
  4146. //OK
  4147. propertyVC.saveDataEdit()
  4148. self.applyBatesInfo(pageString)
  4149. } else {
  4150. //Cancel
  4151. propertyVC.cancelDataEdit()
  4152. }
  4153. }
  4154. } else {
  4155. self.applyBatesInfo(pageString)
  4156. }
  4157. }
  4158. }
  4159. func kmEditToolbarViewDidChooseExit(_ view: KMEditToolbarView) {
  4160. //在编辑数据时,先判断是否要保存数据。
  4161. if view.editType == .watermark, view.editSubType == .edit, let propertyVC = watermarkViewController?.propertyController, propertyVC.isOriginalDataDictChanged() == true {
  4162. propertyVC.showSaveEditChangeAlert { response in
  4163. DispatchQueue.main.async {
  4164. if response == NSApplication.ModalResponse.alertFirstButtonReturn {
  4165. //OK
  4166. propertyVC.saveDataEdit()
  4167. self.kmEditToolbarViewDidChooseExit(view)
  4168. } else {
  4169. //Cancel
  4170. propertyVC.cancelDataEdit()
  4171. }
  4172. }
  4173. }
  4174. return
  4175. } else if view.editType == .background, view.editSubType == .edit, let propertyVC = backgroundViewController?.propertyController, propertyVC.isOriginalDataDictChanged() == true {
  4176. propertyVC.showSaveEditChangeAlert { response in
  4177. DispatchQueue.main.async {
  4178. if response == NSApplication.ModalResponse.alertFirstButtonReturn {
  4179. //OK
  4180. propertyVC.saveDataEdit()
  4181. self.kmEditToolbarViewDidChooseExit(view)
  4182. } else {
  4183. //Cancel
  4184. propertyVC.cancelDataEdit()
  4185. }
  4186. }
  4187. }
  4188. return
  4189. } else if view.editType == .header_Footer, view.editSubType == .edit, let propertyVC = watermarkViewController?.propertyController, propertyVC.isOriginalDataDictChanged() == true {
  4190. propertyVC.showSaveEditChangeAlert { response in
  4191. DispatchQueue.main.async {
  4192. if response == NSApplication.ModalResponse.alertFirstButtonReturn {
  4193. //OK
  4194. propertyVC.saveDataEdit()
  4195. self.kmEditToolbarViewDidChooseExit(view)
  4196. } else {
  4197. //Cancel
  4198. propertyVC.cancelDataEdit()
  4199. }
  4200. }
  4201. }
  4202. return
  4203. } else if view.editType == .bates, view.editSubType == .edit, let propertyVC = watermarkViewController?.propertyController, propertyVC.isOriginalDataDictChanged() == true {
  4204. propertyVC.showSaveEditChangeAlert { response in
  4205. DispatchQueue.main.async {
  4206. if response == NSApplication.ModalResponse.alertFirstButtonReturn {
  4207. //OK
  4208. propertyVC.saveDataEdit()
  4209. self.kmEditToolbarViewDidChooseExit(view)
  4210. } else {
  4211. //Cancel
  4212. propertyVC.cancelDataEdit()
  4213. }
  4214. }
  4215. }
  4216. return
  4217. }
  4218. if view.applyEnable {
  4219. let alert = NSAlert()
  4220. if view.editType == .watermark {
  4221. alert.messageText = KMLocalizedString("There are unapplied Watermark settings, do you want to apply them?", comment: "")
  4222. } else if view.editType == .background {
  4223. alert.messageText = KMLocalizedString("There are unapplied Background settings, do you want to apply them?", comment: "")
  4224. } else if view.editType == .header_Footer {
  4225. alert.messageText = KMLocalizedString("There are unapplied Header & Footer settings, do you want to apply them?", comment: "")
  4226. } else if view.editType == .bates {
  4227. alert.messageText = KMLocalizedString("There are unapplied Bates settings, do you want to apply them?", comment: "")
  4228. }
  4229. alert.informativeText = KMLocalizedString("If not, the changes will be lost.", comment: "")
  4230. alert.addButton(withTitle: KMLocalizedString("Apply", comment: ""))
  4231. alert.addButton(withTitle: KMLocalizedString("Don't Apply", comment: ""))
  4232. alert.addButton(withTitle: KMLocalizedString("Cancel", comment: ""))
  4233. let result = alert.runModal()
  4234. if (result == .alertFirstButtonReturn) {
  4235. self.kmEditToolbarViewDidChooseApply(view)
  4236. } else if (result == .alertSecondButtonReturn) {
  4237. //"Don't Apply"
  4238. exitEditToolbarView()
  4239. } else if (result == .alertThirdButtonReturn) {
  4240. //Cancel
  4241. }
  4242. } else {
  4243. exitEditToolbarView()
  4244. }
  4245. }
  4246. func applyWatermarkInfo(_ pageString: String) {
  4247. if let model = watermarkViewController?.currentWatermarkData {
  4248. let watermark = KMWatermarkModel.returnWaterMarkWith(model, listView.document)
  4249. watermark.pageString = pageString
  4250. listView.document.addWatermark(watermark)
  4251. listView.layoutDocumentView()
  4252. self.recordIsPDFDocumentEdited()
  4253. }
  4254. exitEditToolbarView()
  4255. }
  4256. func applyBackgroundInfo(_ pageString: String) {
  4257. if let model = backgroundViewController?.backgroundModel {
  4258. if let background = listView.document.background() {
  4259. KMBackgroundManager.defaultManager.updateBackground(background, withModel: model)
  4260. background.pageString = pageString
  4261. background.update()
  4262. listView.document?.refreshPageData()
  4263. listView.layoutDocumentView()
  4264. self.recordIsPDFDocumentEdited()
  4265. }
  4266. }
  4267. exitEditToolbarView()
  4268. }
  4269. func applyHeaderFooterInfo(_ pageString: String) {
  4270. if let model = headerFooterViewController?.headerFooterModel {
  4271. if let headerFooter = listView.document.headerFooter() {
  4272. KMHeaderFooterManager.defaultManager.updateCPDFHeaderFooter(headerFooter, withModel: model, Int(listView.document.pageCount))
  4273. headerFooter.pageString = pageString
  4274. headerFooter.update()
  4275. listView.document?.refreshPageData()
  4276. listView.layoutDocumentView()
  4277. self.recordIsPDFDocumentEdited()
  4278. }
  4279. }
  4280. exitEditToolbarView()
  4281. }
  4282. func applyBatesInfo(_ pageString: String) {
  4283. if let model = batesViewController?.batesModel {
  4284. if let bates = listView.document.bates() {
  4285. KMBatesManager.defaultManager.updateCPDFBates(bates, withModel: model, Int(listView.document.pageCount))
  4286. bates.pageString = pageString
  4287. bates.update()
  4288. listView.document?.refreshPageData()
  4289. listView.layoutDocumentView()
  4290. self.recordIsPDFDocumentEdited()
  4291. }
  4292. }
  4293. exitEditToolbarView()
  4294. }
  4295. }
  4296. //MARK: - KMCropControllerDelegate 裁剪相关代理
  4297. extension KMMainViewController: KMCropControllerDelegate {
  4298. func kmCropControllerDidCrop(_ controller: KMCropController, _ cropRect: CGRect, _ view: KMPageRangeSelectView) {
  4299. let rangeSelectResult = view.getSelectedPageIndex(listView.document)
  4300. let indexs = rangeSelectResult.0
  4301. let isCurrentPage = rangeSelectResult.1
  4302. var uIndexs: [UInt] = []
  4303. for index in indexs {
  4304. if index > 0 {
  4305. uIndexs.append(UInt(index-1))
  4306. }
  4307. }
  4308. if isCurrentPage {
  4309. uIndexs = [UInt(listView.currentPageIndex)]
  4310. }
  4311. cropPages(atIndexs: uIndexs, to: [cropRect])
  4312. removeCropController()
  4313. viewManager.subToolMode = .None
  4314. if let toolbarVC = self.pdfToolbarController {
  4315. toolbarVC.refreshSecondToolbarItemsState()
  4316. self.kmPDFToolbarControllerDidToolbarItemClicked(toolbarVC, KMPDFToolbar_edit_crop_Identifier)
  4317. }
  4318. }
  4319. func kmCropControllerDidCropSeparate(_ controller: KMCropController, _ view: KMPageRangeSelectView) {
  4320. let rangeSelectResult = view.getSelectedPageIndex(listView.document)
  4321. let indexs = rangeSelectResult.0
  4322. let isCurrentPage = rangeSelectResult.1
  4323. var rectArray: Array<NSRect> = []
  4324. var uIndexs: [UInt] = []
  4325. for index in indexs {
  4326. if index > 0 {
  4327. uIndexs.append(UInt(index-1))
  4328. let page = self.listView.document.page(at: UInt(index-1))
  4329. let rect = KMCropTools.getPageForegroundBox(page!)
  4330. rectArray.append(rect)
  4331. }
  4332. }
  4333. if isCurrentPage {
  4334. uIndexs = [UInt(listView.currentPageIndex)]
  4335. }
  4336. cropPages(atIndexs: uIndexs, to: rectArray)
  4337. removeCropController()
  4338. viewManager.subToolMode = .None
  4339. if let toolbarVC = self.pdfToolbarController {
  4340. toolbarVC.refreshSecondToolbarItemsState()
  4341. self.kmPDFToolbarControllerDidToolbarItemClicked(toolbarVC, KMPDFToolbar_edit_crop_Identifier)
  4342. }
  4343. }
  4344. func kmCropControllerDidCropAuto(_ controller: KMCropController, _ view: KMPageRangeSelectView) {
  4345. let rangeSelectResult = view.getSelectedPageIndex(listView.document)
  4346. let indexs = rangeSelectResult.0
  4347. let isCurrentPage = rangeSelectResult.1
  4348. var uIndexs: [UInt] = []
  4349. for index in indexs {
  4350. if index > 0 {
  4351. uIndexs.append(UInt(index-1))
  4352. }
  4353. }
  4354. if isCurrentPage {
  4355. uIndexs = [UInt(listView.currentPageIndex)]
  4356. }
  4357. auto_cropPagesWhiteMargin(uIndexs)
  4358. removeCropController()
  4359. viewManager.subToolMode = .None
  4360. if let toolbarVC = self.pdfToolbarController {
  4361. toolbarVC.refreshSecondToolbarItemsState()
  4362. self.kmPDFToolbarControllerDidToolbarItemClicked(toolbarVC, KMPDFToolbar_edit_crop_Identifier)
  4363. }
  4364. }
  4365. func kmCropControllerDidChangedSelectionOrMagnification(_ controller: KMCropController) {
  4366. if let cropVC = rightSideController?.edit_cropController {
  4367. if cropVC.pdfView != controller.pdfView {
  4368. cropVC.pdfView = controller.pdfView
  4369. }
  4370. cropVC.reloadData()
  4371. rightSideController?.reloadRightButtonState()
  4372. }
  4373. }
  4374. }
  4375. //MARK: - KMWatermarkControllerDelegate 水印相关代理
  4376. extension KMMainViewController: KMWatermarkControllerDelegate {
  4377. func kmWatermarkControllerDidUpdateMode(_ view: KMWatermarkController) {
  4378. editToolbarView?.editSubType = view.editSubType
  4379. editToolbarView?.reloadData()
  4380. }
  4381. func kmWatermarkControllerDidWatermarkUpdated(_ view: KMWatermarkController) {
  4382. var applyEnable = true
  4383. if let model = view.currentWatermarkData {
  4384. if model.watermarkType == .text {
  4385. if model.text == nil || model.text?.count == 0 {
  4386. applyEnable = false
  4387. }
  4388. } else if model.watermarkType == .image {
  4389. if model.imagePath == nil {
  4390. applyEnable = false
  4391. }
  4392. }
  4393. } else {
  4394. applyEnable = false
  4395. }
  4396. editToolbarView?.applyEnable = applyEnable
  4397. editToolbarView?.reloadData()
  4398. }
  4399. }
  4400. //MARK: - KMBackgroundControllerDelegate 背景代理
  4401. extension KMMainViewController: KMBackgroundControllerDelegate {
  4402. func kmBackgroundControllerDidUpdateMode(_ view: KMBackgroundController) {
  4403. editToolbarView?.editSubType = view.editSubType
  4404. }
  4405. func kmBackgroundControllerDidBGDataUpdated(_ view: KMBackgroundController) {
  4406. var applyEnable = true
  4407. if let model = view.backgroundModel {
  4408. if model.type == .image {
  4409. if model.imagePath == nil {
  4410. applyEnable = false
  4411. }
  4412. }
  4413. } else {
  4414. applyEnable = false
  4415. }
  4416. editToolbarView?.applyEnable = applyEnable
  4417. editToolbarView?.reloadData()
  4418. }
  4419. }
  4420. //MARK: - KMHeaderFooterControllerDelegate 页眉页脚代理
  4421. extension KMMainViewController: KMHeaderFooterControllerDelegate {
  4422. func kmHeaderFooterControllerDidUpdateModeType(_ view: KMHeaderFooterController) {
  4423. editToolbarView?.editSubType = view.editSubType
  4424. }
  4425. func kmHeaderFooterControllerDidModelDataUpdated(_ view: KMHeaderFooterController) {
  4426. var applyEnable = true
  4427. if let model = view.headerFooterModel {
  4428. if model.topLeftString.count == 0 && model.topCenterString.count == 0 && model.topRightString.count == 0 &&
  4429. model.bottomLeftString.count == 0 && model.bottomCenterString.count == 0 && model.bottomRightString.count == 0 {
  4430. applyEnable = false
  4431. }
  4432. } else {
  4433. applyEnable = false
  4434. }
  4435. editToolbarView?.applyEnable = applyEnable
  4436. editToolbarView?.reloadData()
  4437. }
  4438. }
  4439. //MARK: - KMBatesControllerDelegate Bates贝茨码代理
  4440. extension KMMainViewController: KMBatesControllerDelegate {
  4441. func kmBatesControllerDidUpdateMode(_ view: KMBatesController) {
  4442. editToolbarView?.editSubType = view.editSubType
  4443. editToolbarView?.reloadData()
  4444. }
  4445. func kmBatesControllerDidModelDataUpdated(_ view: KMBatesController) {
  4446. var applyEnable = true
  4447. if let model = view.batesModel {
  4448. if model.topLeftString.count == 0 && model.topCenterString.count == 0 && model.topRightString.count == 0 &&
  4449. model.bottomLeftString.count == 0 && model.bottomCenterString.count == 0 && model.bottomRightString.count == 0 {
  4450. applyEnable = false
  4451. }
  4452. } else {
  4453. applyEnable = false
  4454. }
  4455. editToolbarView?.applyEnable = applyEnable
  4456. editToolbarView?.reloadData()
  4457. }
  4458. }
  4459. //MARK: - CPDFViewDelegate PDFView代理
  4460. extension KMMainViewController: CPDFViewDelegate,CPDFListViewDelegate {
  4461. func pdfViewDocumentDidLoaded(_ pdfView: CPDFView!) {
  4462. sideBarController?.reloadPageTurnerData()
  4463. documentLoadComplete()
  4464. }
  4465. func pdfViewCurrentPageDidChanged(_ pdfView: CPDFView!) {
  4466. sideBarController?.reloadPageTurnerData()
  4467. botaViewController?.currentPageDidChangedAction(listView: listView)
  4468. //分屏视图
  4469. reloadPDFPageNumberToolbar()
  4470. if viewManager.splitSyncScroll {
  4471. if splitPDFController?.inPDFFirst == false && splitPDFController?.outPDFFirst == false {
  4472. splitPDFController?.outPDFFirst = true
  4473. if let splitPDFView = splitPDFController?.pdfView, let document = splitPDFView.document {
  4474. var index = pdfView.currentPageIndex
  4475. if index > document.pageCount {
  4476. index = Int(splitPDFView.document.pageCount - 1)
  4477. }
  4478. splitPDFView.go(toPageIndex: index, animated: false)
  4479. }
  4480. NSObject.cancelPreviousPerformRequests(withTarget: self, selector: #selector(pdfUpdatedFinish), object: nil)
  4481. self.perform(#selector(pdfUpdatedFinish), with: nil, afterDelay: 0.35)
  4482. } else if splitPDFController?.outPDFFirst == true {
  4483. if let splitPDFView = splitPDFController?.pdfView, let document = splitPDFView.document {
  4484. var index = pdfView.currentPageIndex
  4485. if index > document.pageCount {
  4486. index = Int(splitPDFView.document.pageCount - 1)
  4487. }
  4488. splitPDFView.go(toPageIndex: index, animated: false)
  4489. }
  4490. NSObject.cancelPreviousPerformRequests(withTarget: self, selector: #selector(pdfUpdatedFinish), object: nil)
  4491. self.perform(#selector(pdfUpdatedFinish), with: nil, afterDelay: 0.35)
  4492. }
  4493. }
  4494. //水印
  4495. updateEditModeDocumentWhenPageChanged()
  4496. //
  4497. }
  4498. func pdfViewScaleDidChanged(_ pdfView: CPDFView!) {
  4499. pdfToolbarController?.reloadSelectZoomView()
  4500. reloadPDFPageNumberToolbar()
  4501. reloadPopUIWindow()
  4502. //分屏视图
  4503. if viewManager.splitSyncScroll {
  4504. if splitPDFController?.inPDFFirst == false && splitPDFController?.outPDFFirst == false {
  4505. splitPDFController?.outPDFFirst = true
  4506. NSObject.cancelPreviousPerformRequests(withTarget: self, selector: #selector(pdfUpdatedFinish), object: nil)
  4507. self.perform(#selector(pdfUpdatedFinish), with: nil, afterDelay: 0.35)
  4508. } else if splitPDFController?.outPDFFirst == true {
  4509. if let splitPDFView = splitPDFController?.pdfView {
  4510. splitPDFView.scaleFactor = pdfView.scaleFactor
  4511. }
  4512. NSObject.cancelPreviousPerformRequests(withTarget: self, selector: #selector(pdfUpdatedFinish), object: nil)
  4513. self.perform(#selector(pdfUpdatedFinish), with: nil, afterDelay: 0.35)
  4514. }
  4515. }
  4516. }
  4517. func pdfViewDidClick(onLink pdfView: CPDFView!, withURL url: String!) {
  4518. if let urlString = url, urlString == Store_Link {
  4519. //跳转订阅比较表
  4520. return
  4521. }
  4522. if url.hasPrefix("smb://") {
  4523. NSWorkspace.shared.openFile(url)
  4524. } else {
  4525. KMTools.openURL(urlString: url)
  4526. }
  4527. }
  4528. func pdfViewPerformURL(_ pdfView: CPDFView!, withContent content: String!) {
  4529. KMPrint("pdfViewPerformURL")
  4530. if content != nil {
  4531. NSWorkspace.shared.open(URL(string: content)!)
  4532. } else {
  4533. let alert = NSAlert()
  4534. alert.alertStyle = .critical
  4535. alert.informativeText = KMLocalizedString("The hyperlink is invalid.", comment: "")
  4536. alert.messageText = ""
  4537. alert.addButton(withTitle: KMLocalizedString("OK", comment: ""))
  4538. alert.runModal()
  4539. return
  4540. }
  4541. }
  4542. func pdfViewPerformPrint(_ pdfView: CPDFView!) {
  4543. KMPrint("pdfViewPerformPrint")
  4544. self.showPrintWindow()
  4545. }
  4546. func pdfViewPerformGo(toPage pdfView: CPDFView!) {
  4547. KMPrint("pdfViewPerformGo")
  4548. }
  4549. func pdfViewOpenPDF(_ pdfView: CPDFView!, forRemoteGoTo action: CPDFAction!) {
  4550. KMPrint("pdfViewOpenPDF")
  4551. }
  4552. func pdfViewPerformReset(_ pdfView: CPDFView!) {
  4553. KMPrint("pdfViewPerformReset")
  4554. pdfView.document?.resetForm()
  4555. }
  4556. func pdfViewEditingBlockDidChanged(_ pdfView: CPDFView!) {
  4557. KMPrint("pdfViewEditingBlockDidChanged")
  4558. }
  4559. func pdfViewAsBookBookmark() -> NSImage! {
  4560. return NSImage(named: "KMImageNameBookmarkIcon")!
  4561. }
  4562. //MARK: -PDFView内容编辑模块
  4563. func pdfViewEditingSelectionDidChanged(_ pdfView: CPDFView!) {
  4564. // 文本区块 选中文本已经变化
  4565. reloadPopUIWindow()
  4566. }
  4567. func pdfViewPDFSelectionAttributeDidChanged(_ pdfView: CPDFView!) {
  4568. reloadPopUIWindow()
  4569. }
  4570. func pdfViewEditingAreaDidChanged(_ pdfView: CPDFView!) {
  4571. //编辑模块变化
  4572. rightSideController?.reloadDataWithPDFView(pdfView: (pdfView as! CPDFListView))
  4573. if pdfView is CPDFListView {
  4574. (pdfView as! CPDFListView).isEditImage = false
  4575. }
  4576. if let areas = pdfView.editingAreas(), areas.count > 0 {
  4577. if viewManager.showRightSide == false && SettingsManager.sharedInstance.autoExpandPropertyPanel == true {
  4578. viewManager.showRightSide = true
  4579. self.refreshToolbarRightViewInfo()
  4580. }
  4581. } else {
  4582. if viewManager.subToolMode == .None {
  4583. if SettingsManager.sharedInstance.autoExpandPropertyPanel == true {
  4584. viewManager.showRightSide = false
  4585. }
  4586. self.refreshToolbarRightViewInfo()
  4587. }
  4588. }
  4589. reloadPopUIWindow()
  4590. }
  4591. func pdfViewEditingCropBoundsDidChanged(_ pdfView: CPDFView!, editing editArea: CPDFEditArea!) {
  4592. if self.listView.cropAreas == nil && editArea != nil && (editArea is CPDFEditImageArea){
  4593. self.listView.cropAreas = editArea as? CPDFEditImageArea
  4594. }
  4595. reloadPopUIWindow()
  4596. }
  4597. //编辑PDF 创建图片区域回调
  4598. func pdfViewEditingAddImageArea(_ pdfView: CPDFView!, add page: CPDFPage!, add rect: CGRect) {
  4599. if (pdfView as! CPDFListView).isEditImage {
  4600. return
  4601. }
  4602. if listView.editingAreas().count > 0 {
  4603. pdfView.updateEditing([])
  4604. return
  4605. }
  4606. let panel = NSOpenPanel()
  4607. panel.allowsMultipleSelection = false
  4608. panel.allowedFileTypes = ["png","jpg"]
  4609. panel.beginSheetModal(for: NSApp.mainWindow!) { response in
  4610. if response == .OK {
  4611. var filePath = panel.url?.path
  4612. let image = NSImage.init(contentsOf: panel.url!)
  4613. //图片自适应范围
  4614. if image != nil {
  4615. var imageRect = rect
  4616. let imageSize = image!.size
  4617. var previewSize = rect.size
  4618. var isChangeSize = false
  4619. if previewSize.width == 0 && previewSize.height == 0 {
  4620. previewSize = CGSize(width: 500, height: 500)
  4621. isChangeSize = true
  4622. }
  4623. var scale = min(previewSize.width / imageSize.width, previewSize.height / imageSize.height)
  4624. if scale < 1 { // 大于 500
  4625. } else {
  4626. let wh = max(imageSize.width, imageSize.height)
  4627. if wh >= 72 {
  4628. scale = min(scale, 1)
  4629. } else {
  4630. scale = min(72 / imageSize.width, 72 / imageSize.height)
  4631. }
  4632. }
  4633. let newSize = CGSize(width: imageSize.width * scale, height: imageSize.height * scale)
  4634. if isChangeSize {
  4635. imageRect.origin.x = imageRect.origin.x - newSize.width / 2
  4636. imageRect.origin.y = imageRect.origin.y - newSize.height / 2
  4637. } else {
  4638. imageRect.origin.x = imageRect.origin.x + imageRect.width / 2 - newSize.width / 2
  4639. imageRect.origin.y = imageRect.origin.y + imageRect.height / 2 - newSize.height / 2
  4640. }
  4641. imageRect.size = newSize
  4642. let limitWidth = 1920.0
  4643. if imageSize.width > limitWidth || imageSize.height > limitWidth {
  4644. filePath = KMImageOptimization.needCompressImageLosslessly(image: image!,
  4645. targetSize: CGSize(width: limitWidth, height: limitWidth),
  4646. maxSizeInBytes: 1024 * 1024 * 5,
  4647. targetCompression: 1.0)
  4648. }
  4649. //自适应page
  4650. let pageRect = self.listView.currentPage().bounds ?? .zero
  4651. if imageRect.width > pageRect.width ||
  4652. imageRect.height > pageRect.height {
  4653. let pageScale = min(pageRect.width / imageSize.width, pageRect.height / imageSize.height)
  4654. imageRect = CGRect(x: imageRect.origin.x,
  4655. y: imageRect.origin.y,
  4656. width: imageRect.width * pageScale,
  4657. height: imageRect.height * pageScale)
  4658. }
  4659. if imageRect.origin.x < 0 {
  4660. imageRect.origin.x = 5
  4661. }
  4662. if imageRect.origin.y < 0 {
  4663. imageRect.origin.y = 5
  4664. }
  4665. if imageRect.origin.x + imageRect.width > pageRect.width ||
  4666. imageRect.origin.y + imageRect.height > pageRect.height {
  4667. let offsetX = imageRect.origin.x + imageRect.width - pageRect.width
  4668. let offsetY = imageRect.origin.y + imageRect.height - pageRect.height
  4669. imageRect.origin.x = imageRect.origin.x - offsetX - 5
  4670. imageRect.origin.y = imageRect.origin.y - offsetY - 5
  4671. }
  4672. DispatchQueue.main.async {
  4673. self.listView.createImagePath(filePath, rect: imageRect, page: pdfView.currentPage())
  4674. }
  4675. }
  4676. }
  4677. }
  4678. }
  4679. func pdfViewEditingAddTextArea(_ pdfView: CPDFView!, add page: CPDFPage!, add rect: CGRect) {
  4680. let areas = self.listView.km_EditingAreas()
  4681. if let area = areas.last {
  4682. if let data = area as? CPDFEditTextArea {
  4683. if let str = data.editTextAreaString(), str.isEmpty {
  4684. self.listView.remove(with: [area])
  4685. } else {
  4686. self.listView.updateEditing([])
  4687. return
  4688. }
  4689. }
  4690. }
  4691. var newRect = rect
  4692. if rect.size.equalTo(.zero) {
  4693. newRect = CGRect(x: rect.origin.x, y: rect.origin.y - 12, width: 20, height: 12)
  4694. } else {
  4695. newRect = CGRect(x: rect.origin.x, y: rect.origin.y + rect.size.height - 12, width: rect.size.width, height: 12)
  4696. }
  4697. let fontSize = CPDFEditTextArea.defaultFontSize()
  4698. let fontColor = CPDFEditTextArea.defaultColor()
  4699. let fontAlign = CPDFEditTextArea.defaultFontAlignment()
  4700. NSColorPanel.shared.color = fontColor
  4701. let attri = CEditAttributes()
  4702. attri.cFont = CPDFFont(familyName: CPDFEditTextArea.defaultFontName(), fontStyle: CPDFEditTextArea.defaultFontStyle())
  4703. attri.fontColor = fontColor
  4704. attri.alignment = fontAlign
  4705. attri.fontSize = fontSize
  4706. attri.isBold = CPDFEditTextArea.defaultIsBold()
  4707. attri.isItalic = CPDFEditTextArea.defaultIsItality()
  4708. self.listView.createStringBounds(newRect, with: attri, page: page)
  4709. }
  4710. func pdfViewMobileEditingBegan(_ point: CGPoint, for pdfView: CPDFView!, forEditing editingAreas: [CPDFEditArea]!) {
  4711. rightSideController?.reloadEditingAreas()
  4712. toggleClosePopUIWindow()
  4713. }
  4714. func pdfViewMobileEditingMove(_ point: CGPoint, for pdfView: CPDFView!, forEditing editingAreas: [CPDFEditArea]!) {
  4715. rightSideController?.reloadEditingAreas()
  4716. toggleClosePopUIWindow()
  4717. }
  4718. func pdfViewMobileEditingEnd(_ point: CGPoint, for pdfView: CPDFView!, forEditing editingAreas: [CPDFEditArea]!) {
  4719. rightSideController?.reloadEditingAreas()
  4720. reloadPopUIWindow()
  4721. }
  4722. func pdfViewEditingSelectCharDidChanged(_ pdfView: CPDFView!) {
  4723. rightSideController?.reloadEditingAreas()
  4724. reloadPopUIWindow()
  4725. }
  4726. func pdfViewEditingExitCropMode(_ pdfView: CPDFView!, forEditing editingArea: CPDFEditImageArea!) {
  4727. rightSideController?.reloadEditingAreas()
  4728. toggleClosePopUIWindow()
  4729. }
  4730. func pdfViewEditingOperationDidChanged(_ pdfView: CPDFView!) {
  4731. let areas = self.listView.km_editingImageAreas()
  4732. if areas.count == 1 {
  4733. if let data = areas.first as? CPDFEditImageArea {
  4734. let updating = self.listView.editAreaBoundUpdating
  4735. if updating {
  4736. self.listView.editAreaBoundUpdating = false
  4737. }
  4738. }
  4739. }
  4740. }
  4741. func pdfViewEditingDoubleClick(_ pdfView: CPDFView!, imageArea editArea: CPDFEditArea!) {
  4742. if(editArea.isImageArea()) {
  4743. listView.cropAction()
  4744. rightSideController?.reloadEditingAreas()
  4745. }
  4746. }
  4747. //MARK: - PDFView键盘事件
  4748. func pdfListViewKeyDownIsContinue(_ pdfListView: CPDFListView!, theEvent: NSEvent!) -> Bool {
  4749. let command = theEvent.modifierFlags.contains(.command)
  4750. let control = theEvent.modifierFlags.contains(.control)
  4751. let shift = theEvent.modifierFlags.contains(.shift)
  4752. let option = theEvent.modifierFlags.contains(.option)
  4753. KMPrint(theEvent.keyCode)
  4754. if self.listView.isEditing() == true {
  4755. if control && theEvent.keyCode == 11 { // ctr + b
  4756. self.listView.setEditingTextarea_Bold()
  4757. rightSideController?.reloadEditingAreas()
  4758. return false
  4759. } else if control && theEvent.keyCode == 34 { // ctr +i
  4760. self.listView.setEditingTextarea_Italic()
  4761. rightSideController?.reloadEditingAreas()
  4762. return false
  4763. } else if theEvent.keyCode == 36 { // enter
  4764. if self.listView.isCropMode {
  4765. self.listView.cropComfirmAction()
  4766. rightSideController?.reloadEditingAreas()
  4767. return false
  4768. }
  4769. } else if theEvent.keyCode == 53 { // Cancel
  4770. if self.listView.isCropMode {
  4771. self.listView.cropCancelAction()
  4772. rightSideController?.reloadEditingAreas()
  4773. return false
  4774. }
  4775. }
  4776. }
  4777. if self.listView.toolMode == .COCRToolMode {
  4778. if theEvent.keyCode == 53 {
  4779. self.listView.selectionRect = NSZeroRect
  4780. self.listView.selectionPageIndex = UInt(NSNotFound)
  4781. self.closePopOperationWindow()
  4782. self.listView.setNeedsDisplayForVisiblePages()
  4783. return false
  4784. } else if theEvent.keyCode == 36 { // enter
  4785. self.convertSelectionRectOCR(rect: self.listView.currentSelectionRect())
  4786. return false
  4787. }
  4788. }
  4789. if (theEvent.keyCode == 11 && command) { // command + B [添加书签]
  4790. self.menuItemBookMarkClick_add(sender: NSMenuItem())
  4791. return false
  4792. } else if (command && control && theEvent.keyCode == 14) { // command + control + E [注释 橡皮擦]
  4793. return false
  4794. } else if (theEvent.keyCode == 123) { // 向左
  4795. if(self.listView.isEditing() && !self.listView.isSelecteditAreaNotEdit()) {
  4796. return false
  4797. } else {
  4798. if (self.pdfViewCanHorizontalScroll() == false && self.listView.canGoToPreviousPage()) {
  4799. self.listView.goToPreviousPage(nil)
  4800. return false
  4801. }
  4802. }
  4803. } else if (theEvent.keyCode == 126) { // 向上
  4804. if(self.listView.isEditing() && !self.listView.isSelecteditAreaNotEdit()) {
  4805. return false
  4806. } else {
  4807. if (self.listView.isContinousScroll()) {
  4808. return true
  4809. }
  4810. if (self.pdfViewCanVerticalScroll() == false && self.listView.canGoToPreviousPage()) {
  4811. self.listView.goToPreviousPage(nil)
  4812. return false
  4813. }
  4814. }
  4815. } else if (theEvent.keyCode == 124) { // 向右
  4816. if(self.listView.isEditing() && !self.listView.isSelecteditAreaNotEdit()) {
  4817. return false
  4818. } else {
  4819. if (self.pdfViewCanHorizontalScroll() == false && self.listView.canGoToNextPage()) {
  4820. self.listView.goToNextPage(nil)
  4821. return false
  4822. }
  4823. }
  4824. } else if (theEvent.keyCode == 125) { // 向下
  4825. if(self.listView.isEditing() && !self.listView.isSelecteditAreaNotEdit()) {
  4826. return false
  4827. } else {
  4828. if (self.listView.isContinousScroll()) {
  4829. return true
  4830. }
  4831. if (self.pdfViewCanVerticalScroll() == false && self.listView.canGoToNextPage()) {
  4832. self.listView.goToNextPage(nil)
  4833. return false
  4834. }
  4835. }
  4836. } else if (theEvent.keyCode == 36) {
  4837. if self.listView.shouAddEditAreaType() == .image || self.listView.shouAddEditAreaType() == .text {
  4838. if self.listView.isEditImage {
  4839. self.menuItemEditingClick_CropImage(sender: NSMenuItem())
  4840. }
  4841. }
  4842. } else if option && theEvent.keyCode == 18 {
  4843. //option + 1
  4844. updatePDFViewToolsType(.Select)
  4845. } else if option && theEvent.keyCode == 19 {
  4846. //option + 2
  4847. updatePDFViewToolsType(.Scroll)
  4848. } else if option && theEvent.keyCode == 20 {
  4849. //option + 3
  4850. updatePDFViewToolsType(.Content_Selection)
  4851. } else if option && theEvent.keyCode == 21 {
  4852. //option + 4
  4853. updatePDFViewToolsType(.Magnify)
  4854. } else if option && theEvent.keyCode == 23 {
  4855. //option + 5
  4856. updatePDFViewToolsType(.AreaZoom)
  4857. } else if theEvent.keyCode == 53 {
  4858. //ESC
  4859. self.exitFullScreen()
  4860. if viewManager.isPDFReadMode {
  4861. self.exitPDFReadMode()
  4862. }
  4863. self.leftSideViewCancelSelect()
  4864. }
  4865. return true
  4866. }
  4867. func pdfListViewMenuValidate(_ pdfListView: CPDFListView!, menuItem: NSMenuItem!, isTakesEffect: UnsafeMutablePointer<ObjCBool>!) -> Bool {
  4868. guard let action = menuItem.action else {
  4869. isTakesEffect.pointee = false
  4870. return false
  4871. }
  4872. isTakesEffect.pointee = false
  4873. return false
  4874. }
  4875. //MARK: - CPDFListViewDelegate
  4876. func pdfListViewChangedToolMode(_ pdfListView: CPDFListView!, for toolMode: CToolMode) {
  4877. reloadPopUIWindow()
  4878. }
  4879. func pdfListViewChangedAnnotationType(_ pdfListView: CPDFListView!, for annotationType: CAnnotationType) {
  4880. if(annotationType == .unkown) {
  4881. if viewManager.showRightSide == false {
  4882. toggleCloseRightSide()
  4883. }
  4884. if viewManager.subToolMode != .None {
  4885. viewManager.subToolMode = .None
  4886. pdfToolbarController?.cancelSelectedSecondToolbarItems(viewManager.toolMode)
  4887. pdfToolbarController?.refreshSecondToolbarItemsState()
  4888. }
  4889. cancelMeasureType()
  4890. } else if annotationType == .measureLine ||
  4891. annotationType == .measurePolyLine ||
  4892. annotationType == .measurePolyGon ||
  4893. annotationType == .measureSquare {
  4894. refreshMeasureInfo()
  4895. } else {
  4896. cancelMeasureType()
  4897. }
  4898. }
  4899. func pdfListViewChangeatioActiveAnnotations(_ pdfListView: CPDFListView!, forActiveAnnotations annotations: [CPDFAnnotation]!, isRightMenu: Bool) {
  4900. self.view.window?.makeFirstResponder(self.listView)
  4901. reloadPopUIWindow()
  4902. if isRightMenu {
  4903. } else if annotations.count > 0 {
  4904. if self.viewManager.isPDFReadMode {
  4905. toggleCloseRightSide()
  4906. } else {
  4907. let isMultiAnnotations = pdfListView.isMultiAnnotation(annotations)
  4908. if isMultiAnnotations == true, SettingsManager.sharedInstance.autoExpandPropertyPanel == true {
  4909. viewManager.showRightSide = false
  4910. } else {
  4911. if SettingsManager.sharedInstance.autoExpandPropertyPanel == true {
  4912. viewManager.showRightSide = true
  4913. }
  4914. }
  4915. refreshToolbarRightViewInfo()
  4916. }
  4917. } else if (annotations.count == 0){
  4918. if pdfListView.annotationType == .unkown {
  4919. if SettingsManager.sharedInstance.autoExpandPropertyPanel == true {
  4920. viewManager.showRightSide = false
  4921. }
  4922. } else {
  4923. if self.viewManager.isPDFReadMode {
  4924. viewManager.showRightSide = false
  4925. } else {
  4926. }
  4927. }
  4928. refreshToolbarRightViewInfo()
  4929. }
  4930. self.refreshMeasureInfo()
  4931. //
  4932. pdfToolbarController?.pdfViewActiveAnnotationsChanged()
  4933. }
  4934. func pdfListViewMenu(forEvent pdfListView: CPDFListView!, for theEvent: NSEvent!, click menu: AutoreleasingUnsafeMutablePointer<NSMenu?>!, isMoveSelectAnno: Bool) {
  4935. toggleClosePopUIWindow()
  4936. self.view.window?.orderFront(nil)
  4937. var pagePoint = CGPoint.zero
  4938. let point = self.view.convert(theEvent.locationInWindow, from: nil)
  4939. let isShowPopUI:Bool = !SettingsManager.sharedInstance.showQuickActionBar
  4940. if let page = pdfListView.pageAndPoint(&pagePoint, for: theEvent, nearest: false) {
  4941. if view.window?.interactionMode == .presentation {
  4942. let menuStruct = clickPresentationMenu(point: pagePoint)
  4943. groupListMenuGroup?.groupDelegate = self
  4944. groupListMenuGroup?.frame = CGRectMake(0, 0, 180, menuStruct.viewHeight)
  4945. groupListMenuGroup?.updateGroupInfo(menuStruct.menuitems)
  4946. groupListMenuGroup?.showWithPoint(CGPoint(x: point.x, y: point.y - menuStruct.viewHeight), relativeTo: nil)
  4947. } else {
  4948. var menuStringArr: [String] = []
  4949. let activeAnnotations = pdfListView.activeAnnotations as? [CPDFAnnotation]
  4950. if activeAnnotations?.count ?? 0 > 1 {
  4951. var isSameAnnotation = true
  4952. let firstAnnotation = activeAnnotations?.first
  4953. for i in 1..<(activeAnnotations?.count ?? 1) {
  4954. if firstAnnotation?.type != activeAnnotations?[i].type {
  4955. isSameAnnotation = false
  4956. break
  4957. }
  4958. }
  4959. if isSameAnnotation {
  4960. if firstAnnotation?.isKind(of: CPDFMarkupAnnotation.self) == true {
  4961. menuStringArr.append(PDFViewMenuIdentifier_Normal_CopyText)
  4962. menuStringArr.append(PDFViewMenuIdentifier_Normal_Delete)
  4963. menuStringArr.append(PDFViewMenuIdentifier_Space)
  4964. } else if firstAnnotation?.isKind(of: CPDFRedactAnnotation.self) == true {
  4965. menuStringArr.append(PDFViewMenuIdentifier_Normal_Delete)
  4966. menuStringArr.append(PDFViewMenuIdentifier_Space)
  4967. menuStringArr.append(PDFViewMenuIdentifier_Redact_Apply)
  4968. menuStringArr.append(PDFViewMenuIdentifier_Redact_Multipage)
  4969. } else {
  4970. menuStringArr.append(PDFViewMenuIdentifier_Normal_Copy)
  4971. menuStringArr.append(PDFViewMenuIdentifier_Normal_Cut)
  4972. menuStringArr.append(PDFViewMenuIdentifier_Normal_Delete)
  4973. menuStringArr.append(PDFViewMenuIdentifier_Space)
  4974. }
  4975. if(isShowPopUI){
  4976. menuStringArr.append(PDFViewMenuIdentifier_Normal_ShowPopUI)
  4977. menuStringArr.append(PDFViewMenuIdentifier_Space)
  4978. }
  4979. if firstAnnotation?.isKind(of: CPDFRedactAnnotation.self) == true {
  4980. } else {
  4981. menuStringArr.append(PDFViewMenuIdentifier_Normal_SortAnnotation)
  4982. }
  4983. if firstAnnotation?.isKind(of: CPDFLinkAnnotation.self) == true || firstAnnotation?.isKind(of: CPDFWidgetAnnotation.self) == true {
  4984. menuStringArr.append(PDFViewMenuIdentifier_Space)
  4985. menuStringArr.append(PDFViewMenuIdentifier_Normal_Aligning)
  4986. }
  4987. } else {
  4988. menuStringArr.append(PDFViewMenuIdentifier_Normal_Copy)
  4989. menuStringArr.append(PDFViewMenuIdentifier_Normal_Cut)
  4990. menuStringArr.append(PDFViewMenuIdentifier_Normal_Delete)
  4991. menuStringArr.append(PDFViewMenuIdentifier_Space)
  4992. menuStringArr.append(PDFViewMenuIdentifier_Normal_SortAnnotation)
  4993. if firstAnnotation?.isKind(of: CPDFWidgetAnnotation.self) == true {
  4994. menuStringArr.append(PDFViewMenuIdentifier_Normal_Aligning)
  4995. }
  4996. }
  4997. } else if activeAnnotations?.count == 1 {
  4998. if pdfListView.activeAnnotation.isKind(of: CPDFMarkupAnnotation.self) {
  4999. menuStringArr.append(PDFViewMenuIdentifier_Normal_CopyText)
  5000. menuStringArr.append(PDFViewMenuIdentifier_Normal_Delete)
  5001. if(isShowPopUI){
  5002. menuStringArr.append(PDFViewMenuIdentifier_Space)
  5003. menuStringArr.append(PDFViewMenuIdentifier_Normal_ShowPopUI)
  5004. }
  5005. menuStringArr.append(PDFViewMenuIdentifier_Space)
  5006. menuStringArr.append(PDFViewMenuIdentifier_Normal_SortAnnotation)
  5007. } else if pdfListView.activeAnnotation.isKind(of: CPDFRedactAnnotation.self) {
  5008. menuStringArr.append(PDFViewMenuIdentifier_Normal_Delete)
  5009. menuStringArr.append(PDFViewMenuIdentifier_Space)
  5010. menuStringArr.append(PDFViewMenuIdentifier_Redact_Apply)
  5011. menuStringArr.append(PDFViewMenuIdentifier_Redact_Multipage)
  5012. menuStringArr.append(PDFViewMenuIdentifier_Space)
  5013. menuStringArr.append(PDFViewMenuIdentifier_Normal_RedactProperties)
  5014. menuStringArr.append(PDFViewMenuIdentifier_Redact_Default)
  5015. } else if listView.activeAnnotation.isKind(of: CPDFLinkAnnotation.self) {
  5016. let link = listView.activeAnnotation as? CPDFLinkAnnotation
  5017. menuStringArr.append(PDFViewMenuIdentifier_Normal_Copy)
  5018. menuStringArr.append(PDFViewMenuIdentifier_Normal_Cut)
  5019. menuStringArr.append(PDFViewMenuIdentifier_Normal_Delete)
  5020. if(isShowPopUI){
  5021. menuStringArr.append(PDFViewMenuIdentifier_Space)
  5022. menuStringArr.append(PDFViewMenuIdentifier_Normal_ShowPopUI)
  5023. }
  5024. } else if pdfListView.activeAnnotation.isKind(of: CPDFWidgetAnnotation.self) {
  5025. menuStringArr.append(PDFViewMenuIdentifier_Normal_Copy)
  5026. menuStringArr.append(PDFViewMenuIdentifier_Normal_Cut)
  5027. menuStringArr.append(PDFViewMenuIdentifier_Normal_Delete)
  5028. menuStringArr.append(PDFViewMenuIdentifier_Space)
  5029. if(isShowPopUI){
  5030. menuStringArr.append(PDFViewMenuIdentifier_Normal_ShowPopUI)
  5031. menuStringArr.append(PDFViewMenuIdentifier_Space)
  5032. }
  5033. menuStringArr.append(PDFViewMenuIdentifier_Normal_SortAnnotation)
  5034. } else {
  5035. menuStringArr.append(PDFViewMenuIdentifier_Normal_Copy)
  5036. menuStringArr.append(PDFViewMenuIdentifier_Normal_Cut)
  5037. menuStringArr.append(PDFViewMenuIdentifier_Normal_Delete)
  5038. menuStringArr.append(PDFViewMenuIdentifier_Space)
  5039. if pdfListView.activeAnnotation.isKind(of: CPDFTextAnnotation.self) ||
  5040. pdfListView.activeAnnotation.isKind(of: CPDFFreeTextAnnotation.self) {
  5041. } else {
  5042. menuStringArr.append(PDFViewMenuIdentifier_Normal_Content)
  5043. menuStringArr.append(PDFViewMenuIdentifier_Space)
  5044. }
  5045. if(isShowPopUI){
  5046. menuStringArr.append(PDFViewMenuIdentifier_Normal_ShowPopUI)
  5047. menuStringArr.append(PDFViewMenuIdentifier_Space)
  5048. }
  5049. menuStringArr.append(PDFViewMenuIdentifier_Normal_SortAnnotation)
  5050. }
  5051. } else {
  5052. let currentSelection = pdfListView.currentSelection
  5053. if currentSelection != nil {
  5054. if currentSelection?.selectionType() == .text {
  5055. menuStringArr.append(PDFViewMenuIdentifier_Normal_AITool)
  5056. menuStringArr.append(PDFViewMenuIdentifier_Space)
  5057. menuStringArr.append(PDFViewMenuIdentifier_Normal_Copy)
  5058. if pdfListView.canPaste() {
  5059. menuStringArr.append(PDFViewMenuIdentifier_Normal_Past)
  5060. }
  5061. menuStringArr.append(PDFViewMenuIdentifier_Space)
  5062. menuStringArr.append(PDFViewMenuIdentifier_Normal_Hight)
  5063. menuStringArr.append(PDFViewMenuIdentifier_Normal_Underline)
  5064. menuStringArr.append(PDFViewMenuIdentifier_Normal_StrikeOut)
  5065. menuStringArr.append(PDFViewMenuIdentifier_Normal_Squiggly)
  5066. menuStringArr.append(PDFViewMenuIdentifier_Normal_Square)
  5067. menuStringArr.append(PDFViewMenuIdentifier_Normal_Circle)
  5068. menuStringArr.append(PDFViewMenuIdentifier_Space)
  5069. menuStringArr.append(PDFViewMenuIdentifier_Normal_AddOutLine)
  5070. menuStringArr.append(PDFViewMenuIdentifier_Normal_AddBook)
  5071. menuStringArr.append(PDFViewMenuIdentifier_Space)
  5072. menuStringArr.append(PDFViewMenuIdentifier_Normal_TTS)
  5073. menuStringArr.append(PDFViewMenuIdentifier_Normal_SearchText)
  5074. } else if currentSelection?.selectionType() == .image {
  5075. menuStringArr.append(PDFViewMenuIdentifier_Normal_Copy)
  5076. if pdfListView.canPaste() {
  5077. menuStringArr.append(PDFViewMenuIdentifier_Normal_Past)
  5078. }
  5079. menuStringArr.append(PDFViewMenuIdentifier_Space)
  5080. menuStringArr.append(PDFViewMenuIdentifier_Normal_Export)
  5081. menuStringArr.append(PDFViewMenuIdentifier_Space)
  5082. menuStringArr.append(PDFViewMenuIdentifier_Normal_Square)
  5083. menuStringArr.append(PDFViewMenuIdentifier_Normal_Circle)
  5084. }
  5085. } else {
  5086. if pdfListView.toolMode == .CFormToolMode {
  5087. if pdfListView.canPaste() {
  5088. menuStringArr.append(PDFViewMenuIdentifier_Normal_Past)
  5089. }
  5090. menuStringArr.append(PDFViewMenuIdentifier_Space)
  5091. menuStringArr.append(PDFViewMenuIdentifier_Normal_SelectAllForm)
  5092. menuStringArr.append(PDFViewMenuIdentifier_Space)
  5093. menuStringArr.append(PDFViewMenuIdentifier_Normal_HightForm)
  5094. menuStringArr.append(PDFViewMenuIdentifier_Normal_ShowFormName)
  5095. menuStringArr.append(PDFViewMenuIdentifier_Normal_RestForm)
  5096. menuStringArr.append(PDFViewMenuIdentifier_Space)
  5097. menuStringArr.append(PDFViewMenuIdentifier_Normal_AddBook)
  5098. menuStringArr.append(PDFViewMenuIdentifier_Space)
  5099. menuStringArr.append(PDFViewMenuIdentifier_Normal_ViewTools)
  5100. menuStringArr.append(PDFViewMenuIdentifier_Space)
  5101. menuStringArr.append(PDFViewMenuIdentifier_Normal_PageView)
  5102. menuStringArr.append(PDFViewMenuIdentifier_Space)
  5103. menuStringArr.append(PDFViewMenuIdentifier_Normal_Scale)
  5104. menuStringArr.append(PDFViewMenuIdentifier_Space)
  5105. menuStringArr.append(PDFViewMenuIdentifier_Normal_PageRotate)
  5106. menuStringArr.append(PDFViewMenuIdentifier_Space)
  5107. menuStringArr.append(PDFViewMenuIdentifier_Normal_PageNum)
  5108. menuStringArr.append(PDFViewMenuIdentifier_Space)
  5109. menuStringArr.append(PDFViewMenuIdentifier_Normal_Search)
  5110. menuStringArr.append(PDFViewMenuIdentifier_Normal_Print)
  5111. menuStringArr.append(PDFViewMenuIdentifier_Normal_Properties)
  5112. } else if pdfListView.toolMode == .CRedactToolMode {
  5113. menuStringArr.append(PDFViewMenuIdentifier_Normal_SelectAllText)
  5114. menuStringArr.append(PDFViewMenuIdentifier_Space)
  5115. menuStringArr.append(PDFViewMenuIdentifier_Normal_AddBook)
  5116. menuStringArr.append(PDFViewMenuIdentifier_Space)
  5117. menuStringArr.append(PDFViewMenuIdentifier_Normal_ViewTools)
  5118. menuStringArr.append(PDFViewMenuIdentifier_Space)
  5119. menuStringArr.append(PDFViewMenuIdentifier_Normal_PageView)
  5120. menuStringArr.append(PDFViewMenuIdentifier_Space)
  5121. menuStringArr.append(PDFViewMenuIdentifier_Normal_Scale)
  5122. menuStringArr.append(PDFViewMenuIdentifier_Space)
  5123. menuStringArr.append(PDFViewMenuIdentifier_Normal_PageRotate)
  5124. menuStringArr.append(PDFViewMenuIdentifier_Space)
  5125. menuStringArr.append(PDFViewMenuIdentifier_Normal_PageNum)
  5126. menuStringArr.append(PDFViewMenuIdentifier_Space)
  5127. menuStringArr.append(PDFViewMenuIdentifier_Normal_HightLink)
  5128. menuStringArr.append(PDFViewMenuIdentifier_Normal_HightForm)
  5129. menuStringArr.append(PDFViewMenuIdentifier_Normal_RestForm)
  5130. menuStringArr.append(PDFViewMenuIdentifier_Space)
  5131. menuStringArr.append(PDFViewMenuIdentifier_Normal_Search)
  5132. menuStringArr.append(PDFViewMenuIdentifier_Normal_Print)
  5133. menuStringArr.append(PDFViewMenuIdentifier_Normal_Properties)
  5134. } else {
  5135. if(listView.viewSplitMode != .disable) {
  5136. menuStringArr.append(PDFViewMenuIdentifier_Split_ViewMode)
  5137. menuStringArr.append(PDFViewMenuIdentifier_Split_Sync)
  5138. menuStringArr.append(PDFViewMenuIdentifier_Split_ShowBar)
  5139. menuStringArr.append(PDFViewMenuIdentifier_Space)
  5140. } else {
  5141. menuStringArr.append(PDFViewMenuIdentifier_Normal_AITool)
  5142. menuStringArr.append(PDFViewMenuIdentifier_Space)
  5143. if pdfListView == listView {
  5144. if pdfListView.canPaste() {
  5145. menuStringArr.append(PDFViewMenuIdentifier_Normal_Past)
  5146. }
  5147. menuStringArr.append(PDFViewMenuIdentifier_Normal_SelectAllText)
  5148. menuStringArr.append(PDFViewMenuIdentifier_Normal_SelectAllAnnotation)
  5149. menuStringArr.append(PDFViewMenuIdentifier_Space)
  5150. menuStringArr.append(PDFViewMenuIdentifier_Normal_ShowAnnotation)
  5151. menuStringArr.append(PDFViewMenuIdentifier_Space)
  5152. menuStringArr.append(PDFViewMenuIdentifier_Normal_AddBook)
  5153. menuStringArr.append(PDFViewMenuIdentifier_Space)
  5154. menuStringArr.append(PDFViewMenuIdentifier_Normal_ViewTools)
  5155. menuStringArr.append(PDFViewMenuIdentifier_Space)
  5156. }
  5157. }
  5158. menuStringArr.append(PDFViewMenuIdentifier_Normal_PageView)
  5159. if(listView.viewSplitMode != .disable) {
  5160. } else {
  5161. menuStringArr.append(PDFViewMenuIdentifier_Normal_ReadMode)
  5162. }
  5163. menuStringArr.append(PDFViewMenuIdentifier_Space)
  5164. menuStringArr.append(PDFViewMenuIdentifier_Normal_Scale)
  5165. menuStringArr.append(PDFViewMenuIdentifier_Space)
  5166. menuStringArr.append(PDFViewMenuIdentifier_Normal_PageRotate)
  5167. menuStringArr.append(PDFViewMenuIdentifier_Space)
  5168. menuStringArr.append(PDFViewMenuIdentifier_Normal_PageNum)
  5169. menuStringArr.append(PDFViewMenuIdentifier_Space)
  5170. menuStringArr.append(PDFViewMenuIdentifier_Normal_AutoScroll)
  5171. menuStringArr.append(PDFViewMenuIdentifier_Space)
  5172. menuStringArr.append(PDFViewMenuIdentifier_Normal_HightLink)
  5173. menuStringArr.append(PDFViewMenuIdentifier_Normal_HightForm)
  5174. menuStringArr.append(PDFViewMenuIdentifier_Normal_RestForm)
  5175. menuStringArr.append(PDFViewMenuIdentifier_Space)
  5176. menuStringArr.append(PDFViewMenuIdentifier_Normal_Search)
  5177. menuStringArr.append(PDFViewMenuIdentifier_Normal_Print)
  5178. menuStringArr.append(PDFViewMenuIdentifier_Normal_Properties)
  5179. }
  5180. }
  5181. }
  5182. let menuStruct = KMPDFMenuConfig.clickMenuUI(items: menuStringArr, theEvent: theEvent, listView: pdfListView)
  5183. groupListMenuGroup?.groupDelegate = self
  5184. groupListMenuGroup?.frame = CGRectMake(0, 0, 180, menuStruct.viewHeight)
  5185. groupListMenuGroup?.updateGroupInfo(menuStruct.menuitems)
  5186. groupListMenuGroup?.showWithPoint(CGPoint(x: point.x, y: point.y - menuStruct.viewHeight), relativeTo: nil, withWindow: self.view.window)
  5187. }
  5188. } else {
  5189. var menuStringArr: [String] = []
  5190. menuStringArr.append(PDFViewMenuIdentifier_Normal_PageView)
  5191. menuStringArr.append(PDFViewMenuIdentifier_Normal_ReadMode)
  5192. menuStringArr.append(PDFViewMenuIdentifier_Space)
  5193. menuStringArr.append(PDFViewMenuIdentifier_Normal_Scale)
  5194. menuStringArr.append(PDFViewMenuIdentifier_Space)
  5195. menuStringArr.append(PDFViewMenuIdentifier_Normal_HightLink)
  5196. menuStringArr.append(PDFViewMenuIdentifier_Normal_HightForm)
  5197. menuStringArr.append(PDFViewMenuIdentifier_Normal_RestForm)
  5198. let menuStruct = KMPDFMenuConfig.clickMenuUI(items: menuStringArr, theEvent: theEvent, listView: pdfListView)
  5199. groupListMenuGroup?.groupDelegate = self
  5200. groupListMenuGroup?.frame = CGRectMake(0, 0, 180, menuStruct.viewHeight)
  5201. groupListMenuGroup?.updateGroupInfo(menuStruct.menuitems)
  5202. groupListMenuGroup?.showWithPoint(CGPoint(x: point.x, y: point.y - menuStruct.viewHeight), relativeTo: nil, withWindow: self.view.window)
  5203. }
  5204. }
  5205. func pdfListViewMenuItemsEditing(at point: CGPoint, for page: CPDFPage!, menuItems: [NSMenuItem]!) -> [NSMenuItem]! {
  5206. toggleClosePopUIWindow()
  5207. var windowPoint = listView.convert(point, from: page)
  5208. let view: NSView? = nil
  5209. windowPoint = listView.convert(windowPoint, to: view)
  5210. if self.view.window?.interactionMode == .presentation {
  5211. let menuStruct = clickPresentationMenu(point: point)
  5212. groupListMenuGroup?.groupDelegate = self
  5213. groupListMenuGroup?.frame = CGRectMake(0, 0, 180, menuStruct.viewHeight)
  5214. groupListMenuGroup?.updateGroupInfo(menuStruct.menuitems)
  5215. groupListMenuGroup?.showWithPoint(CGPoint(x: windowPoint.x, y: windowPoint.y - menuStruct.viewHeight), relativeTo: nil)
  5216. } else {
  5217. let isShowPopUI:Bool = !SettingsManager.sharedInstance.showQuickActionBar
  5218. var menuStringArr: [String] = []
  5219. let editingAreas = listView.km_EditingAreas()
  5220. let firstEditingArea = editingAreas.first
  5221. if editingAreas.count > 1 {
  5222. var isSameEditingArea = true
  5223. if(firstEditingArea?.isTextArea() == true) {
  5224. for i in 1..<(editingAreas.count) {
  5225. if !editingAreas[i].isTextArea() {
  5226. isSameEditingArea = false
  5227. break
  5228. }
  5229. }
  5230. } else if (firstEditingArea?.isImageArea() == true) {
  5231. for i in 1..<(editingAreas.count) {
  5232. if !editingAreas[i].isImageArea() {
  5233. isSameEditingArea = false
  5234. break
  5235. }
  5236. }
  5237. }
  5238. if(isSameEditingArea) {
  5239. if (firstEditingArea?.isTextArea() == true) {
  5240. menuStringArr.append(PDFViewMenuIdentifier_Normal_Copy)
  5241. menuStringArr.append(PDFViewMenuIdentifier_Normal_Cut)
  5242. if listView.isSupportPastMatchStyle() {
  5243. menuStringArr.append(PDFViewMenuIdentifier_Edit_Paste)
  5244. }
  5245. if listView.isSupportPast() {
  5246. menuStringArr.append(PDFViewMenuIdentifier_Edit_NoStylePaste)
  5247. }
  5248. menuStringArr.append(PDFViewMenuIdentifier_Edit_SelectAll)
  5249. menuStringArr.append(PDFViewMenuIdentifier_Normal_Delete)
  5250. menuStringArr.append(PDFViewMenuIdentifier_Space)
  5251. menuStringArr.append(PDFViewMenuIdentifier_Edit_Font)
  5252. menuStringArr.append(PDFViewMenuIdentifier_Edit_FontName)
  5253. menuStringArr.append(PDFViewMenuIdentifier_Edit_FontAlight)
  5254. if(isShowPopUI){
  5255. menuStringArr.append(PDFViewMenuIdentifier_Space)
  5256. menuStringArr.append(PDFViewMenuIdentifier_Normal_ShowPopUI)
  5257. }
  5258. menuStringArr.append(PDFViewMenuIdentifier_Space)
  5259. menuStringArr.append(PDFViewMenuIdentifier_Normal_Aligning)
  5260. } else if (firstEditingArea?.isImageArea() == true) {
  5261. menuStringArr.append(PDFViewMenuIdentifier_Normal_Copy)
  5262. menuStringArr.append(PDFViewMenuIdentifier_Normal_Cut)
  5263. menuStringArr.append(PDFViewMenuIdentifier_Normal_Delete)
  5264. menuStringArr.append(PDFViewMenuIdentifier_Space)
  5265. menuStringArr.append(PDFViewMenuIdentifier_Edit_RotateLeft)
  5266. menuStringArr.append(PDFViewMenuIdentifier_Edit_RotateRight)
  5267. menuStringArr.append(PDFViewMenuIdentifier_Edit_HorizontalMirror)
  5268. menuStringArr.append(PDFViewMenuIdentifier_Edit_VerticalMirror)
  5269. menuStringArr.append(PDFViewMenuIdentifier_Space)
  5270. menuStringArr.append(PDFViewMenuIdentifier_Normal_Export)
  5271. if(isShowPopUI){
  5272. menuStringArr.append(PDFViewMenuIdentifier_Space)
  5273. menuStringArr.append(PDFViewMenuIdentifier_Normal_ShowPopUI)
  5274. }
  5275. menuStringArr.append(PDFViewMenuIdentifier_Space)
  5276. menuStringArr.append(PDFViewMenuIdentifier_Normal_Aligning)
  5277. }
  5278. } else {
  5279. menuStringArr.append(PDFViewMenuIdentifier_Normal_Copy)
  5280. menuStringArr.append(PDFViewMenuIdentifier_Normal_Cut)
  5281. menuStringArr.append(PDFViewMenuIdentifier_Normal_Delete)
  5282. menuStringArr.append(PDFViewMenuIdentifier_Space)
  5283. menuStringArr.append(PDFViewMenuIdentifier_Normal_Aligning)
  5284. }
  5285. } else if editingAreas.count == 1 {
  5286. if firstEditingArea?.isTextArea() == true {
  5287. if !listView.isSelecteditAreaNotEdit() { //光标输入状态
  5288. if listView.isSupportPast() {
  5289. menuStringArr.append(PDFViewMenuIdentifier_Edit_NoStylePaste)
  5290. }
  5291. menuStringArr.append(PDFViewMenuIdentifier_Edit_SelectAll)
  5292. menuStringArr.append(PDFViewMenuIdentifier_Space)
  5293. } else {
  5294. let editState = listView.editStatus()
  5295. if (editState == .editSelectText) {// 选择文本
  5296. menuStringArr.append(PDFViewMenuIdentifier_Normal_Copy)
  5297. menuStringArr.append(PDFViewMenuIdentifier_Normal_Cut)
  5298. if listView.isSupportPast() {
  5299. menuStringArr.append(PDFViewMenuIdentifier_Edit_NoStylePaste)
  5300. }
  5301. menuStringArr.append(PDFViewMenuIdentifier_Edit_SelectAll)
  5302. menuStringArr.append(PDFViewMenuIdentifier_Normal_Delete)
  5303. menuStringArr.append(PDFViewMenuIdentifier_Space)
  5304. } else {
  5305. menuStringArr.append(PDFViewMenuIdentifier_Normal_Copy)
  5306. menuStringArr.append(PDFViewMenuIdentifier_Normal_Cut)
  5307. if listView.isSupportPastMatchStyle() {
  5308. menuStringArr.append(PDFViewMenuIdentifier_Edit_Paste)
  5309. }
  5310. if listView.isSupportPast() {
  5311. menuStringArr.append(PDFViewMenuIdentifier_Edit_NoStylePaste)
  5312. }
  5313. menuStringArr.append(PDFViewMenuIdentifier_Edit_SelectAll)
  5314. menuStringArr.append(PDFViewMenuIdentifier_Normal_Delete)
  5315. menuStringArr.append(PDFViewMenuIdentifier_Space)
  5316. }
  5317. menuStringArr.append(PDFViewMenuIdentifier_Edit_Font)
  5318. menuStringArr.append(PDFViewMenuIdentifier_Edit_FontName)
  5319. menuStringArr.append(PDFViewMenuIdentifier_Edit_FontAlight)
  5320. if(isShowPopUI){
  5321. menuStringArr.append(PDFViewMenuIdentifier_Space)
  5322. menuStringArr.append(PDFViewMenuIdentifier_Normal_ShowPopUI)
  5323. }
  5324. }
  5325. } else if firstEditingArea?.isImageArea() == true {
  5326. menuStringArr.append(PDFViewMenuIdentifier_Normal_Copy)
  5327. menuStringArr.append(PDFViewMenuIdentifier_Normal_Cut)
  5328. menuStringArr.append(PDFViewMenuIdentifier_Normal_Delete)
  5329. menuStringArr.append(PDFViewMenuIdentifier_Space)
  5330. menuStringArr.append(PDFViewMenuIdentifier_Edit_RotateLeft)
  5331. menuStringArr.append(PDFViewMenuIdentifier_Edit_RotateRight)
  5332. menuStringArr.append(PDFViewMenuIdentifier_Edit_HorizontalMirror)
  5333. menuStringArr.append(PDFViewMenuIdentifier_Edit_VerticalMirror)
  5334. menuStringArr.append(PDFViewMenuIdentifier_Space)
  5335. menuStringArr.append(PDFViewMenuIdentifier_Edit_Crop)
  5336. menuStringArr.append(PDFViewMenuIdentifier_Edit_Replace)
  5337. menuStringArr.append(PDFViewMenuIdentifier_Normal_Export)
  5338. if(isShowPopUI){
  5339. menuStringArr.append(PDFViewMenuIdentifier_Space)
  5340. menuStringArr.append(PDFViewMenuIdentifier_Normal_ShowPopUI)
  5341. }
  5342. }
  5343. } else {
  5344. if(listView.isSupportPastMatchStyle()) {
  5345. menuStringArr.append(PDFViewMenuIdentifier_Edit_Paste)
  5346. }
  5347. if(listView.isSupportPast()) {
  5348. menuStringArr.append(PDFViewMenuIdentifier_Edit_NoStylePaste)
  5349. }
  5350. menuStringArr.append(PDFViewMenuIdentifier_Edit_SelectAll)
  5351. menuStringArr.append(PDFViewMenuIdentifier_Space)
  5352. menuStringArr.append(PDFViewMenuIdentifier_Edit_AddText)
  5353. menuStringArr.append(PDFViewMenuIdentifier_Edit_AddImage)
  5354. menuStringArr.append(PDFViewMenuIdentifier_Edit_AddLink)
  5355. menuStringArr.append(PDFViewMenuIdentifier_Space)
  5356. menuStringArr.append(PDFViewMenuIdentifier_Normal_AddBook)
  5357. menuStringArr.append(PDFViewMenuIdentifier_Space)
  5358. menuStringArr.append(PDFViewMenuIdentifier_Normal_ViewTools)
  5359. menuStringArr.append(PDFViewMenuIdentifier_Space)
  5360. menuStringArr.append(PDFViewMenuIdentifier_Normal_PageView)
  5361. menuStringArr.append(PDFViewMenuIdentifier_Space)
  5362. menuStringArr.append(PDFViewMenuIdentifier_Normal_Scale)
  5363. menuStringArr.append(PDFViewMenuIdentifier_Space)
  5364. menuStringArr.append(PDFViewMenuIdentifier_Normal_PageRotate)
  5365. menuStringArr.append(PDFViewMenuIdentifier_Space)
  5366. menuStringArr.append(PDFViewMenuIdentifier_Normal_PageNum)
  5367. menuStringArr.append(PDFViewMenuIdentifier_Space)
  5368. menuStringArr.append(PDFViewMenuIdentifier_Normal_Search)
  5369. menuStringArr.append(PDFViewMenuIdentifier_Normal_Print)
  5370. menuStringArr.append(PDFViewMenuIdentifier_Normal_Properties)
  5371. }
  5372. let menuStruct = KMPDFMenuConfig.clickMenuUI(items: menuStringArr, theEvent: nil, listView: listView)
  5373. groupListMenuGroup?.groupDelegate = self
  5374. groupListMenuGroup?.frame = CGRectMake(0, 0, 180, menuStruct.viewHeight)
  5375. groupListMenuGroup?.updateGroupInfo(menuStruct.menuitems)
  5376. groupListMenuGroup?.showWithPoint(CGPoint(x: windowPoint.x, y: windowPoint.y - menuStruct.viewHeight), relativeTo: nil)
  5377. }
  5378. return []
  5379. }
  5380. func pdfListViewMobileAnnotationBegan(_ point: CGPoint, for pdfListView: CPDFListView!, forActiveAnnotations annotations: [CPDFAnnotation]!) {
  5381. toggleClosePopUIWindow()
  5382. }
  5383. func pdfListViewMobileAnnotationMove(_ point: CGPoint, for pdfListView: CPDFListView!, forActiveAnnotations annotations: [CPDFAnnotation]!) {
  5384. toggleClosePopUIWindow()
  5385. }
  5386. func pdfListViewMobileAnnotationEnd(_ point: CGPoint, for pdfListView: CPDFListView!, forActiveAnnotations annotations: [CPDFAnnotation]!) {
  5387. reloadPopUIWindow()
  5388. }
  5389. func pdfListViewAddAnnotations(_ pdfListView: CPDFListView!, forAdd annotations: [CPDFAnnotation]!, in pdfPage: CPDFPage!) {
  5390. var pageIndexes = IndexSet()
  5391. pageIndexes.insert(Int(pdfPage.pageIndex()))
  5392. KMNThumbnailManager.reloadThumImage(document: self.listView.document, pageIndexs: pageIndexes)
  5393. botaViewController?.reloadData()
  5394. alertTipViewController.reloadFormAlertUI()
  5395. alertTipViewController.reloadDigitalAlertUI()
  5396. alertTipViewController.reloadAlertUIFrame()
  5397. }
  5398. func pdfListViewRemoveAnnotations(_ pdfListView: CPDFListView!, forRemove annotations: [CPDFAnnotation]!, in pdfPage: CPDFPage!) {
  5399. var pageIndexes = IndexSet()
  5400. pageIndexes.insert(Int(pdfPage.pageIndex()))
  5401. KMNThumbnailManager.reloadThumImage(document: self.listView.document, pageIndexs: pageIndexes)
  5402. botaViewController?.reloadData()
  5403. alertTipViewController.reloadFormAlertUI()
  5404. alertTipViewController.reloadAlertUIFrame()
  5405. }
  5406. func pdfListViewEditAnnotation(_ pdfListView: CPDFListView!, for anotation: CPDFAnnotation!) {
  5407. if anotation.isKind(of: CPDFSignatureWidgetAnnotation.self) {
  5408. if let signatureWidgetAnnotation = anotation as? CPDFSignatureWidgetAnnotation {
  5409. let signature = signatureWidgetAnnotation.signature()
  5410. if ((signature) != nil) {
  5411. popUpSignatureWidgetState(signature!, listView)
  5412. } else {
  5413. let widget = CPDFSignatureWidgetAnnotation.init(PDFListViewNoteWith: listView.document)
  5414. widget.bounds = NSMakeRect(-1000, -1000, 545, 178);
  5415. anotation.page.addAnnotation(widget)
  5416. let configWindowVC = DSignatureConfigWindowController.init(windowNibName: "DSignatureConfigWindowController")
  5417. configWindowVC.viewType = .fileList;
  5418. configWindowVC.appearanceWidget = widget;
  5419. configWindowVC.isCreatDS = false
  5420. configWindowVC.complentionHandle = {[weak self] isSign, dic, config, isLock in
  5421. widget.page.removeAnnotation(widget)
  5422. if isSign {
  5423. if (dic.object(forKey: SAVEFILEPATH_KEY) != nil) {
  5424. let p12Path = dic.object(forKey: SAVEFILEPATH_KEY) as! String
  5425. let password = dic.object(forKey: PASSWORD_KEY)
  5426. if p12Path.count > 0 {
  5427. self?.writeSignatureToWidget(signatureWidgetAnnotation, p12Path, password as! String, config, isLock)
  5428. }
  5429. }
  5430. } else {
  5431. if signatureWidgetAnnotation.isSignSignatureAdd() == true {
  5432. self?.listView.remove(anotation)
  5433. }
  5434. }
  5435. }
  5436. configWindowVC.actionBlock = {[weak self] controller, type in
  5437. if (type == .cancel) {
  5438. NSApplication.shared.stopModal()
  5439. controller.window?.orderOut(nil)
  5440. controller.window?.close()
  5441. widget.page.removeAnnotation(widget)
  5442. if signatureWidgetAnnotation.isSignSignatureAdd() == true {
  5443. self?.listView.remove(anotation)
  5444. } else {
  5445. self?.listView.setNeedsDisplayAnnotationViewFor(anotation.page)
  5446. }
  5447. } else if (type == .confirm) {
  5448. NSApplication.shared.stopModal()
  5449. controller.window?.orderOut(nil)
  5450. controller.window?.close()
  5451. }
  5452. }
  5453. configWindowVC.window?.center()
  5454. NSApplication.shared.runModal(for: configWindowVC.window!)
  5455. }
  5456. }
  5457. } else if anotation.isKind(of: CPDFRedactAnnotation.self) {
  5458. if let redactAnnotation = anotation as? CPDFRedactAnnotation {
  5459. let properties = KMRedactPropertiesWindowController()
  5460. properties.readactAnnotation = redactAnnotation
  5461. properties.own_beginSheetModal(for: self.view.window) { result in
  5462. }
  5463. properties.callback = { [weak self] annotation in
  5464. if let page = annotation?.page {
  5465. self?.listView.setNeedsDisplayAnnotationViewFor(page)
  5466. }
  5467. }
  5468. }
  5469. }
  5470. }
  5471. func pdfListViewSplitModeShowBar() -> Bool {
  5472. return viewManager.splitShowBottomBar
  5473. }
  5474. func pdfListViewEndEditMode(_ pdfListView: CPDFListView!) {
  5475. let document = listView.document
  5476. if(document != nil) {
  5477. for i in 0..<document!.pageCount {
  5478. let thumbnail = KMNThumbnail.init(document: document!, currentPageIndex: Int(i))
  5479. thumbnail.removeCacheImage()
  5480. }
  5481. }
  5482. botaViewController?.reloadData()
  5483. }
  5484. func pdfListViewAddEditAreaTypeChanged(_ pdfListView: CPDFListView!) {
  5485. if self.listView.shouAddEditAreaType() != .text && self.listView.shouAddEditAreaType() != .image {
  5486. if viewManager.subToolMode != .None {
  5487. viewManager.subToolMode = .None
  5488. pdfToolbarController?.cancelSelectedSecondToolbarItems(viewManager.toolMode)
  5489. pdfToolbarController?.refreshSecondToolbarItemsState()
  5490. }
  5491. }
  5492. }
  5493. //MARK: -Crop
  5494. func pdfListViewChangedSelectionOrMagnification(_ pdfListView: CPDFListView!) {
  5495. reloadPopUIWindow()
  5496. }
  5497. func pdfListViewDidSelectionEnd(_ pdfListView: CPDFListView!) {
  5498. if (!self.listView.isEqual(to: pdfListView)) {
  5499. return
  5500. }
  5501. if (self.listView.toolMode != .CSelectToolMode) {
  5502. return
  5503. }
  5504. reloadPopUIWindow()
  5505. }
  5506. func pdfListViewHaveDocumentAttribute() -> Bool {
  5507. if(!self.listView.document.allowsCopying) {
  5508. self.removeOwnerPassword()
  5509. return false
  5510. }
  5511. return true
  5512. }
  5513. func pdfListViewShowTipView() -> Bool {
  5514. let popWindow = KMNAnnotationPopToolbarWindow.shared
  5515. if popWindow.isVisible == true {
  5516. return true
  5517. }
  5518. return false
  5519. }
  5520. func pdfListViewAnnotationEditModeChange(_ pdfListView: CPDFListView!, for anotation: CPDFAnnotation!) {
  5521. reloadPopUIWindow()
  5522. }
  5523. func pdfListViewAnnotationChange(_ color: NSColor!, forActiveAnnotation annotation: CPDFAnnotation!) {
  5524. rightSideController?.reloadData()
  5525. NotificationCenter.default.post(name: toolbarImageColorChangedNotificationName, object: nil)
  5526. }
  5527. //MARK: -Measure
  5528. func pdfListViewAnnotationMeasureInfoChange(_ pdfListView: CPDFListView!, with annotation: CPDFAnnotation!) {
  5529. guard let data = annotation else {
  5530. if distanceMeasureInfoWindowController?.window?.isVisible == true {
  5531. distanceMeasureInfoWindowController?.clearData()
  5532. }
  5533. return
  5534. }
  5535. if let lineAnnotation = annotation as? CPDFLineAnnotation {
  5536. handleLineAnnotation(lineAnnotation)
  5537. } else if let polylineAnnotation = annotation as? CPDFPolylineAnnotation {
  5538. handlePolylineAnnotation(polylineAnnotation)
  5539. } else if let polygonAnnotation = annotation as? CPDFPolygonAnnotation {
  5540. handlePolygonAnnotation(polygonAnnotation)
  5541. }
  5542. }
  5543. func pdfListViewMeasureCancel(_ pdfListView: CPDFListView!) {
  5544. cancelMeasureType()
  5545. }
  5546. private func handleLineAnnotation(_ annotation: CPDFLineAnnotation) {
  5547. if perimeterMeasureInfoWindowController?.window?.isVisible == true {
  5548. perimeterMeasureInfoWindowController?.hideFloatingWindow()
  5549. distanceMeasureInfoWindowController?.showWindow(self)
  5550. } else if areaMeasureInfoWindowController?.window?.isVisible == true {
  5551. areaMeasureInfoWindowController?.hideFloatingWindow()
  5552. distanceMeasureInfoWindowController?.showWindow(self)
  5553. } else if distanceMeasureInfoWindowController?.window?.isVisible == false {
  5554. distanceMeasureInfoWindowController?.showWindow(self)
  5555. }
  5556. let measureInfo = annotation.measureInfo
  5557. let startPoint = annotation.startPoint
  5558. let endPoint = annotation.endPoint
  5559. let angle = atan2(endPoint.y - startPoint.y, endPoint.x - startPoint.x) * (180.0 / .pi)
  5560. distanceMeasureInfoWindowController?.angleLabel.stringValue = String(format: "%.2f°", abs(angle))
  5561. distanceMeasureInfoWindowController?.xLabel.stringValue = String(format: "%.0f", abs(endPoint.x - startPoint.x))
  5562. distanceMeasureInfoWindowController?.yLabel.stringValue = String(format: "%.0f", abs(endPoint.y - startPoint.y))
  5563. distanceMeasureInfoWindowController?.reloadData(with: measureInfo!)
  5564. }
  5565. private func handlePolylineAnnotation(_ annotation: CPDFPolylineAnnotation) {
  5566. if distanceMeasureInfoWindowController?.window?.isVisible == true {
  5567. distanceMeasureInfoWindowController?.hideFloatingWindow()
  5568. perimeterMeasureInfoWindowController?.showWindow(self)
  5569. } else if areaMeasureInfoWindowController?.window?.isVisible == true {
  5570. areaMeasureInfoWindowController?.hideFloatingWindow()
  5571. perimeterMeasureInfoWindowController?.showWindow(self)
  5572. } else if perimeterMeasureInfoWindowController?.window?.isVisible == false {
  5573. perimeterMeasureInfoWindowController?.showWindow(self)
  5574. }
  5575. let measureInfo = annotation.measureInfo
  5576. let savePoints = annotation.savePoints()
  5577. var angle: CGFloat = 0
  5578. if savePoints.count >= 3 {
  5579. let count = savePoints.count
  5580. let startPoint = savePoints[count - 3].pointValue
  5581. let midPoint = savePoints[count - 2].pointValue
  5582. let endPoint = savePoints.last!.pointValue
  5583. angle = angleBetweenPoints(startPoint, midPoint, endPoint)
  5584. }
  5585. angle = 180 - angle
  5586. perimeterMeasureInfoWindowController?.angleLabel.stringValue = String(format: "%.2f°", abs(angle))
  5587. perimeterMeasureInfoWindowController?.reloadData(with: measureInfo!)
  5588. }
  5589. private func handlePolygonAnnotation(_ annotation: CPDFPolygonAnnotation) {
  5590. if distanceMeasureInfoWindowController?.window?.isVisible == true {
  5591. distanceMeasureInfoWindowController?.hideFloatingWindow()
  5592. areaMeasureInfoWindowController?.showWindow(self)
  5593. } else if perimeterMeasureInfoWindowController?.window?.isVisible == true {
  5594. perimeterMeasureInfoWindowController?.hideFloatingWindow()
  5595. areaMeasureInfoWindowController?.showWindow(self)
  5596. } else if areaMeasureInfoWindowController?.window?.isVisible == false {
  5597. areaMeasureInfoWindowController?.showWindow(self)
  5598. }
  5599. let measureInfo = annotation.measureInfo
  5600. let savePoints = annotation.savePoints
  5601. var angle: CGFloat = 0
  5602. if savePoints.count >= 3 {
  5603. let count = savePoints.count
  5604. let startPoint = (savePoints[count - 3] as AnyObject).pointValue
  5605. let midPoint = (savePoints[count - 2] as AnyObject).pointValue
  5606. let endPoint = (savePoints.lastObject as AnyObject).pointValue
  5607. angle = angleBetweenPoints(startPoint!, midPoint!, endPoint!)
  5608. }
  5609. angle = 180 - angle
  5610. areaMeasureInfoWindowController?.angleLabel.stringValue = String(format: "%.2f°", abs(angle))
  5611. areaMeasureInfoWindowController?.reloadData(measureInfo!)
  5612. }
  5613. private func angleBetweenPoints(_ startPoint: CGPoint, _ midPoint: CGPoint, _ endPoint: CGPoint) -> CGFloat {
  5614. let vector1 = CGPoint(x: midPoint.x - startPoint.x, y: midPoint.y - startPoint.y)
  5615. let vector2 = CGPoint(x: endPoint.x - midPoint.x, y: endPoint.y - midPoint.y)
  5616. let dotProduct = vector1.x * vector2.x + vector1.y * vector2.y
  5617. let magnitude1 = sqrt(vector1.x * vector1.x + vector1.y * vector1.y)
  5618. let magnitude2 = sqrt(vector2.x * vector2.x + vector2.y * vector2.y)
  5619. return acos(dotProduct / (magnitude1 * magnitude2)) * (180.0 / .pi)
  5620. }
  5621. @objc func pdfUpdatedFinish() {
  5622. splitPDFController?.inPDFFirst = false
  5623. splitPDFController?.outPDFFirst = false
  5624. }
  5625. //MARK: - Notification
  5626. @objc private func pdfViewScrollViewDidScroll(_ noti: Notification) {
  5627. reloadPopUIWindow()
  5628. if listView.popOver?.isShown == true {
  5629. listView.popOver?.close()
  5630. }
  5631. }
  5632. func pageCountChangedNotification(_ sender: Notification) {
  5633. guard let document = sender.object as? CPDFDocument else {
  5634. return
  5635. }
  5636. botaViewController?.pageCountChangedAction(document: document)
  5637. }
  5638. func annotationsAttributeHasChange(_ sender: Notification) {
  5639. guard let dict = sender.object as? [String : Any] else {
  5640. return
  5641. }
  5642. if let anno = dict["object"] as? CPDFAnnotation {
  5643. let value = dict["keyPath"] as? String ?? ""
  5644. let didEnd = dict["didEnd"] as? Bool ?? false
  5645. if didEnd {
  5646. if value == CPDFAnnotationBoundsKey {
  5647. if anno is CPDFSquareAnnotation || anno is CPDFCircleAnnotation {
  5648. anno.contents = anno.page?.string(for: anno.bounds) ?? ""
  5649. }
  5650. }
  5651. if anno.km_isMeasure() && anno.contents == nil {
  5652. anno.contents = anno.string() ?? ""
  5653. }
  5654. var pageIndexes = IndexSet()
  5655. pageIndexes.insert(Int(anno.page.pageIndex()))
  5656. reloadIfThumData(pageIndexs: pageIndexes)
  5657. reloadPopUIWindow()
  5658. } else {
  5659. if value != CPDFAnnotationBoundsKey && value != CPDFAnnotationStartPointKey && value != CPDFAnnotationEndPointKey && value != CPDFAnnotationPathsKey { // 改变bounds(箭头、直线注释 开始点和结束点, 手绘注释的paths)的操作会卡顿,比如移动
  5660. var pageIndexes = IndexSet()
  5661. pageIndexes.insert(Int(anno.page.pageIndex()))
  5662. reloadIfThumData(pageIndexs: pageIndexes)
  5663. reloadPopUIWindow()
  5664. }
  5665. }
  5666. }
  5667. }
  5668. func reloadThumData(pageIndexs: IndexSet) {
  5669. NSObject.cancelPreviousPerformRequests(withTarget: self, selector: #selector(reloadIfThumData), object: pageIndexs)
  5670. DispatchQueue.main.asyncAfter(deadline: .now() + 0.3) {
  5671. self.reloadIfThumData(pageIndexs: pageIndexs)
  5672. }
  5673. }
  5674. func reloadIfThumData(pageIndexs: IndexSet) {
  5675. KMNThumbnailManager.reloadThumImage(document: self.listView.document, pageIndexs: pageIndexs)
  5676. botaViewController?.reloadData()
  5677. }
  5678. @objc fileprivate func signatureStateChangeNoti(_ sender: Notification) {
  5679. guard let objecListView = sender.object as? CPDFListView else {
  5680. return
  5681. }
  5682. if listView == objecListView {
  5683. reloadDigitalSigns()
  5684. alertTipViewController.reloadDigitalAlertUI()
  5685. alertTipViewController.reloadAlertUIFrame()
  5686. let signatureWidget = listView.editAnnotation
  5687. if let signatureWidgetAnnotation = signatureWidget as? CPDFSignatureWidgetAnnotation {
  5688. let signature = signatureWidgetAnnotation.signature()
  5689. if signature == nil {
  5690. return
  5691. }
  5692. signaturestateVC.signature = signature
  5693. signaturestateVC.reloadData()
  5694. }
  5695. }
  5696. }
  5697. }
  5698. //MARK: - KMNThumbnailBaseViewDelegate
  5699. extension KMMainViewController: KMNThumbnailBaseViewDelegate {
  5700. func clickThumbnailViewControlle(pageEditVC:KMNThumbnailBaseViewController?,currentIndex:Int) {
  5701. exitPageEditMode()
  5702. if listView.currentPageIndex != currentIndex {
  5703. listView.go(toPageIndex: currentIndex, animated: true)
  5704. }
  5705. viewManager.isPageEditMode = false
  5706. pdfToolbarController?.clickWithIdentify(KMPDFToolbar_PageEdit_Identifier)
  5707. }
  5708. func insertPDFThumbnailViewControlle(pageEditVC: KMNThumbnailBaseViewController?, pdfDocment: CPDFDocument?) {
  5709. if(pdfDocment != nil) {
  5710. insertDocuments.insert(pdfDocment!)
  5711. }
  5712. }
  5713. func changeIndexPathsThumbnailViewControlle(pageEditVC: KMNThumbnailBaseViewController?, selectionIndexPaths: Set<IndexPath>, selectionStrings: String) {
  5714. toolbarManager.page_pageInfo_Property.text = selectionStrings
  5715. if(toolbarManager.page_pageInfo_Property.creatable == false) {
  5716. toolbarManager.page_pageInfo_Property.creatable = true
  5717. }
  5718. pdfToolbarController?.refreshSecondToolbarItemsState()
  5719. }
  5720. func leftSideViewControllerThumbnailHaveChange(leftSideViewController: KMNLeftSideViewController) {
  5721. if(self.pageEditViewController?.view.superview == nil) { //当页面编辑不显示时,undo还会继续,所以需要刷新PDFView,如果页面编辑视图存在时,在退出页面编辑时一次性刷新
  5722. listView.layoutDocumentView()
  5723. botaViewController?.reloadData()
  5724. }
  5725. }
  5726. }
  5727. //MARK: - KMNLeftSideViewControllerDelegate
  5728. extension KMMainViewController: KMNLeftSideViewControllerDelegate {
  5729. func enterPageEditLeftSideViewController(leftSideViewController: KMNLeftSideViewController) {
  5730. if viewManager.isPageEditMode == false {
  5731. viewManager.isPageEditMode = true
  5732. if(pdfToolbarController != nil) {
  5733. kmPDFToolbarControllerDidToolbarItemClicked(pdfToolbarController!, KMPDFToolbar_PageEdit_Identifier)
  5734. pdfToolbarController?.resetSecondToolbar()
  5735. pageEditViewController?.selectionIndexPaths = leftSideViewController.thumnailViewController?.collectionView.selectionIndexPaths ?? []
  5736. }
  5737. }
  5738. }
  5739. func changeSelectePageLeftSideViewController(leftSideViewController: KMNLeftSideViewController, pageIndex: Int) {
  5740. if(listView.currentPageIndex != pageIndex) {
  5741. listView.go(toPageIndex: pageIndex, animated: true)
  5742. }
  5743. }
  5744. func addBookmarkForLeftC(controller: KMNLeftSideViewController, bookmark: CPDFBookmark?, info: [String : Any]?) {
  5745. if let result = info?["result"] as? Bool {
  5746. if result == false {
  5747. if let targetV = listView.superview {
  5748. _ = KMNCustomAlertView.alertView(message: KMLocalizedString("This page has been bookmarked"), type: .normal_custom, fromView: targetV, point:CGPointMake(targetV.frame.size.width/2, targetV.bounds.size.height-24))
  5749. }
  5750. }
  5751. }
  5752. }
  5753. func switchSearchPopWindow(controller: KMNLeftSideViewController) {
  5754. if(viewManager.pdfSideBarType == .search) {
  5755. toggleCloseLeftSide()
  5756. }
  5757. let handdler = controller.searchViewC.handdler
  5758. showSearchPopWindow(type: handdler.type, keyborad: handdler.searchKey, replaceText: handdler.replaceKey, results: handdler.searchResults)
  5759. }
  5760. func searchTypeDidChange(controller: KMNLeftSideViewController) {
  5761. let handdler = controller.searchViewC.handdler
  5762. if handdler.type == .replace {
  5763. if viewManager.toolMode != .Edit {
  5764. viewManager.toolMode = .Edit
  5765. updatePDFViewAnnotationMode()
  5766. }
  5767. }
  5768. }
  5769. }
  5770. //MARK: - ComponentGroupDelegate
  5771. extension KMMainViewController: ComponentGroupDelegate {
  5772. func componentGroupDidSelect(group: ComponentGroup?, menuItemProperty: ComponentMenuitemProperty?) {
  5773. if menuItemProperty?.identifier == PDFViewMenuIdentifier_PageNext {
  5774. if let objectListView = menuItemProperty?.representedObject as? CPDFListView {
  5775. if objectListView.canGoToNextPage() {
  5776. objectListView.goToNextPage(nil)
  5777. }
  5778. }
  5779. } else if (menuItemProperty?.identifier == PDFViewMenuIdentifier_PagePrevious) {
  5780. if let objectListView = menuItemProperty?.representedObject as? CPDFListView {
  5781. if objectListView.canGoToPreviousPage() {
  5782. objectListView.goToPreviousPage(nil)
  5783. }
  5784. }
  5785. } else if (menuItemProperty?.identifier == PDFViewMenuIdentifier_PageFirst) {
  5786. if let objectListView = menuItemProperty?.representedObject as? CPDFListView {
  5787. if objectListView.canGoToFirstPage() {
  5788. objectListView.goToFirstPage(nil)
  5789. }
  5790. }
  5791. } else if (menuItemProperty?.identifier == PDFViewMenuIdentifier_PageLast) {
  5792. if let objectListView = menuItemProperty?.representedObject as? CPDFListView {
  5793. if objectListView.canGoToLastPage() {
  5794. objectListView.goToLastPage(nil)
  5795. }
  5796. }
  5797. } else if (menuItemProperty?.identifier == PDFViewMenuIdentifier_Presentation_LaserPoint) {
  5798. listView.exitPresentationDrawMode()
  5799. } else if (menuItemProperty?.identifier == PDFViewMenuIdentifier_Presentation_Brush) {
  5800. listView.enterPresentationDrawMode()
  5801. } else if(menuItemProperty?.identifier == PDFViewMenuIdentifier_Presentation_Exit) {
  5802. self.exitFullScreen()
  5803. } else if menuItemProperty?.identifier == PDFViewMenuIdentifier_Normal_AIRewrite {
  5804. viewManager.pdfSideBarType = .aiTools
  5805. sideBarController?.reloadData()
  5806. if let sideVC = sideBarController {
  5807. kmPDFSideBarControllerDidSidebarTypeUpdated(sideVC)
  5808. }
  5809. botaViewController?.setCurrentPDFSelection(self.listView.currentSelection.string())
  5810. botaViewController?.chooseAIFunctionWithType(.reWriting)
  5811. } else if (menuItemProperty?.identifier == PDFViewMenuIdentifier_Normal_AIProofread) {
  5812. viewManager.pdfSideBarType = .aiTools
  5813. sideBarController?.reloadData()
  5814. if let sideVC = sideBarController {
  5815. kmPDFSideBarControllerDidSidebarTypeUpdated(sideVC)
  5816. }
  5817. botaViewController?.setCurrentPDFSelection(self.listView.currentSelection.string())
  5818. botaViewController?.chooseAIFunctionWithType(.proofreading)
  5819. } else if (menuItemProperty?.identifier == PDFViewMenuIdentifier_Normal_AITranslate) {
  5820. viewManager.pdfSideBarType = .aiTools
  5821. sideBarController?.reloadData()
  5822. if let sideVC = sideBarController {
  5823. kmPDFSideBarControllerDidSidebarTypeUpdated(sideVC)
  5824. }
  5825. botaViewController?.setCurrentPDFSelection(self.listView.currentSelection.string())
  5826. botaViewController?.chooseAIFunctionWithType(.translate)
  5827. } else if (menuItemProperty?.identifier == PDFViewMenuIdentifier_Normal_Past) {
  5828. let theEvent = menuItemProperty?.representedObject
  5829. if let currentEvent = theEvent as? NSEvent {
  5830. var pagePoint = CGPoint.zero
  5831. if let page = listView.pageAndPoint(&pagePoint, for: currentEvent, nearest: false) {
  5832. listView.menuPointPaste(pagePoint, page: page, isRightPaste: true)
  5833. }
  5834. }
  5835. } else if (menuItemProperty?.identifier == PDFViewMenuIdentifier_Normal_SelectAllText) {
  5836. if self.listView.toolMode == .CRedactToolMode {
  5837. if let dic = menuItemProperty?.representedObject as? NSDictionary {
  5838. let objectListView = dic["Object"] as? CPDFListView
  5839. let theEvent = dic["theEvent"] as? NSEvent
  5840. if(objectListView != nil && theEvent != nil) {
  5841. var pagePoint = CGPoint.zero
  5842. if let page = objectListView?.pageAndPoint(&pagePoint, for: theEvent, nearest: false) {
  5843. self.selectAllRedactAnnotation(currentPage: page)
  5844. }
  5845. }
  5846. }
  5847. } else {
  5848. listView.selectAll(nil)
  5849. }
  5850. } else if (menuItemProperty?.identifier == PDFViewMenuIdentifier_Normal_AddBook) {
  5851. menuItemBookMarkClick_add(sender: nil)
  5852. } else if(menuItemProperty?.identifier == PDFViewMenuIdentifier_Normal_TextTool) {
  5853. listView.toolMode = .CTextToolMode
  5854. listView.annotationType = .unkown
  5855. viewManager.viewToolsType = .Select
  5856. pdfToolbarController?.reloadToolsView()
  5857. } else if(menuItemProperty?.identifier == PDFViewMenuIdentifier_Normal_MoveTool) {
  5858. listView.toolMode = .CMoveToolMode
  5859. listView.annotationType = .unkown
  5860. viewManager.viewToolsType = .Scroll
  5861. pdfToolbarController?.reloadToolsView()
  5862. } else if(menuItemProperty?.identifier == PDFViewMenuIdentifier_Normal_SelectTool) {
  5863. listView.toolMode = .CSelectToolMode
  5864. listView.annotationType = .unkown
  5865. viewManager.viewToolsType = .Content_Selection
  5866. pdfToolbarController?.reloadToolsView()
  5867. } else if(menuItemProperty?.identifier == PDFViewMenuIdentifier_Normal_MagnifyTool) {
  5868. listView.toolMode = .CMagnifyToolMode
  5869. listView.annotationType = .unkown
  5870. viewManager.viewToolsType = .Magnify
  5871. pdfToolbarController?.reloadToolsView()
  5872. } else if(menuItemProperty?.identifier == PDFViewMenuIdentifier_Normal_SelectZoomTool) {
  5873. listView.toolMode = .CSelectZoomToolMode
  5874. listView.annotationType = .unkown
  5875. viewManager.viewToolsType = .AreaZoom
  5876. pdfToolbarController?.reloadToolsView()
  5877. } else if(menuItemProperty?.identifier == PDFViewMenuIdentifier_Normal_Single) {
  5878. if let objectListView = menuItemProperty?.representedObject as? CPDFListView {
  5879. objectListView.menuItemClick_SinglePage(nil)
  5880. }
  5881. } else if(menuItemProperty?.identifier == PDFViewMenuIdentifier_Normal_SingleContinuous) {
  5882. if let objectListView = menuItemProperty?.representedObject as? CPDFListView {
  5883. objectListView.menuItemClick_SinglePagesContinuous(nil)
  5884. }
  5885. } else if(menuItemProperty?.identifier == PDFViewMenuIdentifier_Normal_TwoPages) {
  5886. if let objectListView = menuItemProperty?.representedObject as? CPDFListView {
  5887. objectListView.menuItemClick_TwoPages(nil)
  5888. }
  5889. } else if(menuItemProperty?.identifier == PDFViewMenuIdentifier_Normal_TwoPagesContinuous) {
  5890. if let objectListView = menuItemProperty?.representedObject as? CPDFListView {
  5891. objectListView.menuItemClick_TwoPagesContinuous(nil)
  5892. }
  5893. } else if(menuItemProperty?.identifier == PDFViewMenuIdentifier_Normal_BookMode) {
  5894. if let objectListView = menuItemProperty?.representedObject as? CPDFListView {
  5895. objectListView.menuItemClick_BookMode(nil)
  5896. }
  5897. } else if(menuItemProperty?.identifier == PDFViewMenuIdentifier_Normal_ReadMode) {
  5898. viewManager.isPDFReadMode = !viewManager.isPDFReadMode
  5899. if viewManager.isPDFReadMode {
  5900. openPDFReadMode()
  5901. } else {
  5902. exitPDFReadMode()
  5903. }
  5904. } else if(menuItemProperty?.identifier == PDFViewMenuIdentifier_Normal_ScaleWidth) {
  5905. if let objectListView = menuItemProperty?.representedObject as? CPDFListView {
  5906. objectListView.autoScales = true
  5907. }
  5908. } else if(menuItemProperty?.identifier == PDFViewMenuIdentifier_Normal_ScalePage) {
  5909. if let objectListView = menuItemProperty?.representedObject as? CPDFListView {
  5910. let pageHeight = objectListView.currentPage()!.size.height
  5911. let pdfviewHeight = objectListView.bounds.size.height
  5912. objectListView.scaleFactor = pdfviewHeight/pageHeight
  5913. objectListView.autoScales = false
  5914. }
  5915. } else if(menuItemProperty?.identifier == PDFViewMenuIdentifier_Normal_ScaleOrg) {
  5916. if let objectListView = menuItemProperty?.representedObject as? CPDFListView {
  5917. if objectListView.scaleFactor != 1.0 {
  5918. objectListView.scaleFactor = 1.0
  5919. objectListView.autoScales = false
  5920. }
  5921. }
  5922. } else if(menuItemProperty?.identifier == PDFViewMenuIdentifier_Normal_ScaleZoomIn) {
  5923. if let objectListView = menuItemProperty?.representedObject as? CPDFListView {
  5924. var scale = objectListView.scaleFactor
  5925. switch scale {
  5926. case 0...0.25:
  5927. scale += 0.25
  5928. case 0.25...3:
  5929. scale += 0.25
  5930. case 3.1...10:
  5931. scale += 0.4
  5932. case 10.1...100:
  5933. scale += 1
  5934. default:
  5935. scale += 1
  5936. }
  5937. objectListView.scaleFactor = scale
  5938. }
  5939. } else if(menuItemProperty?.identifier == PDFViewMenuIdentifier_Normal_ScaleZoomOut) {
  5940. if let objectListView = menuItemProperty?.representedObject as? CPDFListView {
  5941. var scale = objectListView.scaleFactor
  5942. switch scale {
  5943. case 0...0.25:
  5944. scale = 0
  5945. case 0.25...3:
  5946. scale -= 0.25
  5947. case 3.1...10:
  5948. scale -= 0.4
  5949. case 10.1...100:
  5950. scale -= 1
  5951. default:
  5952. scale -= 1
  5953. }
  5954. objectListView.scaleFactor = scale
  5955. }
  5956. } else if(menuItemProperty?.identifier == PDFViewMenuIdentifier_Normal_RotateLeft) {
  5957. if let dic = menuItemProperty?.representedObject as? NSDictionary {
  5958. let objectListView = dic["Object"] as? CPDFListView
  5959. let theEvent = dic["theEvent"] as? NSEvent
  5960. if(objectListView != nil && theEvent != nil) {
  5961. var pagePoint = CGPoint.zero
  5962. if let page = objectListView?.pageAndPoint(&pagePoint, for: theEvent, nearest: false) {
  5963. rotateLeft(page: page, listView: objectListView)
  5964. }
  5965. }
  5966. }
  5967. } else if(menuItemProperty?.identifier == PDFViewMenuIdentifier_Normal_RotateRight) {
  5968. if let dic = menuItemProperty?.representedObject as? NSDictionary {
  5969. let objectListView = dic["Object"] as? CPDFListView
  5970. let theEvent = dic["theEvent"] as? NSEvent
  5971. if(objectListView != nil && theEvent != nil) {
  5972. var pagePoint = CGPoint.zero
  5973. if let page = objectListView?.pageAndPoint(&pagePoint, for: theEvent, nearest: false) {
  5974. rotateRight(page: page, listView: objectListView)
  5975. }
  5976. }
  5977. }
  5978. } else if(menuItemProperty?.identifier == PDFViewMenuIdentifier_Normal_EnterPageNum) {
  5979. gotoPage(nil)
  5980. } else if(menuItemProperty?.identifier == PDFViewMenuIdentifier_Normal_PageBack) {
  5981. if let objectListView = menuItemProperty?.representedObject as? CPDFListView {
  5982. if(objectListView.km_canGoForward() == true) {
  5983. objectListView.km_goForward(nil)
  5984. }
  5985. }
  5986. } else if(menuItemProperty?.identifier == PDFViewMenuIdentifier_Normal_PageForward) {
  5987. if let objectListView = menuItemProperty?.representedObject as? CPDFListView {
  5988. if(objectListView.km_canGoBack() == true) {
  5989. objectListView.km_goBack(nil)
  5990. }
  5991. }
  5992. } else if(menuItemProperty?.identifier == PDFViewMenuIdentifier_Normal_AutoScroll) {
  5993. toggleAutoFlow(nil)
  5994. } else if(menuItemProperty?.identifier == PDFViewMenuIdentifier_Normal_HightForm) {
  5995. highlightFormFiled(nil)
  5996. } else if(menuItemProperty?.identifier == PDFViewMenuIdentifier_Normal_HightLink) {
  5997. highlightLinks(nil)
  5998. } else if(menuItemProperty?.identifier == PDFViewMenuIdentifier_Normal_RestForm) {
  5999. resetForm(nil)
  6000. } else if(menuItemProperty?.identifier == PDFViewMenuIdentifier_Normal_Search) {
  6001. if botaViewController != nil {
  6002. switchSearchPopWindow(controller: botaViewController!)
  6003. }
  6004. } else if(menuItemProperty?.identifier == PDFViewMenuIdentifier_Normal_Print) {
  6005. menuItemAction_print(nil)
  6006. } else if(menuItemProperty?.identifier == PDFViewMenuIdentifier_Normal_Properties) {
  6007. menuItemAction_property(nil)
  6008. } else if(menuItemProperty?.identifier == PDFViewMenuIdentifier_Normal_Copy) {
  6009. if(listView.isEditing() == true) {
  6010. listView.copyEditAreaAction()
  6011. } else {
  6012. listView.copy(nil)
  6013. }
  6014. } else if(menuItemProperty?.identifier == PDFViewMenuIdentifier_Normal_Hight) {
  6015. if let currentSelect = listView.currentSelection {
  6016. if(currentSelect.selectionType() == .text) {
  6017. listView.addAnnotation(with: .highlight, selection: currentSelect, page: currentSelect.page, bounds: currentSelect.bounds)
  6018. listView.currentSelection = nil;
  6019. }
  6020. }
  6021. } else if(menuItemProperty?.identifier == PDFViewMenuIdentifier_Normal_Underline) {
  6022. if let currentSelect = listView.currentSelection {
  6023. if(currentSelect.selectionType() == .text) {
  6024. listView.addAnnotation(with: .underline, selection: currentSelect, page: currentSelect.page, bounds: currentSelect.bounds)
  6025. listView.currentSelection = nil;
  6026. }
  6027. }
  6028. } else if(menuItemProperty?.identifier == PDFViewMenuIdentifier_Normal_Squiggly) {
  6029. if let currentSelect = listView.currentSelection {
  6030. if(currentSelect.selectionType() == .text) {
  6031. listView.addAnnotation(with: .squiggly, selection: currentSelect, page: currentSelect.page, bounds: currentSelect.bounds)
  6032. listView.currentSelection = nil;
  6033. }
  6034. }
  6035. } else if(menuItemProperty?.identifier == PDFViewMenuIdentifier_Normal_StrikeOut) {
  6036. if let currentSelect = listView.currentSelection {
  6037. if(currentSelect.selectionType() == .text) {
  6038. listView.addAnnotation(with: .strikeOut, selection: currentSelect, page: currentSelect.page, bounds: currentSelect.bounds)
  6039. listView.currentSelection = nil;
  6040. }
  6041. }
  6042. } else if(menuItemProperty?.identifier == PDFViewMenuIdentifier_Normal_Square) {
  6043. if let currentSelect = listView.currentSelection {
  6044. listView.addAnnotation(with: .square, selection: currentSelect, page: currentSelect.page, bounds: currentSelect.bounds)
  6045. listView.currentSelection = nil;
  6046. }
  6047. } else if(menuItemProperty?.identifier == PDFViewMenuIdentifier_Normal_Circle) {
  6048. if let currentSelect = listView.currentSelection {
  6049. listView.addAnnotation(with: .circle, selection: currentSelect, page: currentSelect.page, bounds: listView.currentSelection.bounds)
  6050. listView.currentSelection = nil;
  6051. }
  6052. } else if(menuItemProperty?.identifier == PDFViewMenuIdentifier_Normal_AddOutLine) {
  6053. addOutLineItemAction()
  6054. } else if(menuItemProperty?.identifier == PDFViewMenuIdentifier_Normal_TTS) {
  6055. startSpeaking(nil)
  6056. } else if(menuItemProperty?.identifier == PDFViewMenuIdentifier_Normal_SearchText) {
  6057. searchBaiduAction()
  6058. } else if(menuItemProperty?.identifier == PDFViewMenuIdentifier_Normal_SelectAllForm) {
  6059. if let dic = menuItemProperty?.representedObject as? NSDictionary {
  6060. let objectListView = dic["Object"] as? CPDFListView
  6061. let theEvent = dic["theEvent"] as? NSEvent
  6062. if(objectListView != nil && theEvent != nil) {
  6063. var pagePoint = CGPoint.zero
  6064. if let page = objectListView?.pageAndPoint(&pagePoint, for: theEvent, nearest: false) {
  6065. selectAllFormAnnotation(currentPage: page)
  6066. listView.setNeedsDisplayAnnotationViewForVisiblePages()
  6067. }
  6068. }
  6069. }
  6070. } else if(menuItemProperty?.identifier == PDFViewMenuIdentifier_Normal_ShowFormName) {
  6071. if(listView.showFormFieldName == true) {
  6072. listView.showFormFieldName = false
  6073. } else {
  6074. listView.showFormFieldName = true
  6075. }
  6076. listView.setNeedsDisplayAnnotationViewForVisiblePages()
  6077. } else if(menuItemProperty?.identifier == PDFViewMenuIdentifier_Normal_SelectAllAnnotation) {
  6078. if let dic = menuItemProperty?.representedObject as? NSDictionary {
  6079. let objectListView = dic["Object"] as? CPDFListView
  6080. let theEvent = dic["theEvent"] as? NSEvent
  6081. if(objectListView != nil && theEvent != nil) {
  6082. var pagePoint = CGPoint.zero
  6083. if let page = objectListView?.pageAndPoint(&pagePoint, for: theEvent, nearest: false) {
  6084. selectAllNomerAnnotation(currentPage: page)
  6085. listView.setNeedsDisplayAnnotationViewForVisiblePages()
  6086. }
  6087. }
  6088. }
  6089. } else if(menuItemProperty?.identifier == PDFViewMenuIdentifier_Normal_ShowAnnotation) {
  6090. let isHiden = listView.hideNotes
  6091. listView.hideNotes = !isHiden
  6092. listView.setNeedsDisplayAnnotationViewForVisiblePages()
  6093. } else if(menuItemProperty?.identifier == PDFViewMenuIdentifier_Normal_CopyText) {
  6094. var copyText:String = ""
  6095. let annotations = listView.activeAnnotations
  6096. for i in 0 ..< (annotations?.count ?? 0){
  6097. if let an = annotations?[i] as? CPDFMarkupAnnotation {
  6098. let markupContent = an.markupContent()
  6099. if markupContent.isEmpty == false {
  6100. if copyText.isEmpty == true {
  6101. copyText = markupContent
  6102. } else {
  6103. copyText = copyText + "\n" + markupContent
  6104. }
  6105. }
  6106. }
  6107. }
  6108. let pboard = NSPasteboard.general
  6109. if copyText.isEmpty == false {
  6110. pboard.clearContents()
  6111. pboard.writeObjects([copyText as NSPasteboardWriting])
  6112. }
  6113. } else if(menuItemProperty?.identifier == PDFViewMenuIdentifier_Normal_Cut) {
  6114. if(listView.isEditing() == true) {
  6115. listView.cutEditAreaAction()
  6116. } else {
  6117. listView.cut(nil)
  6118. }
  6119. } else if(menuItemProperty?.identifier == PDFViewMenuIdentifier_Normal_Delete) {
  6120. if(listView.isEditing() == true) {
  6121. listView.remove(with: listView.km_EditingAreas())
  6122. } else {
  6123. listView.delete(nil)
  6124. }
  6125. } else if(menuItemProperty?.identifier == PDFViewMenuIdentifier_Normal_ShowPopUI) {
  6126. UserDefaults.standard.setValue(true, forKey: settingsShowQuickActionBarKey)
  6127. SettingsManager.sharedInstance.showQuickActionBar = true
  6128. reloadPopUIWindow()
  6129. } else if(menuItemProperty?.identifier == PDFViewMenuIdentifier_Normal_SortFirstAnnotation) {
  6130. let activeAnnotations = listView.activeAnnotations
  6131. for i in 0 ..< (activeAnnotations?.count ?? 0){
  6132. let object = activeAnnotations?[i]
  6133. if let an = object as? CPDFAnnotation {
  6134. listView.bringAnnotationFront(an, page: an.page)
  6135. }
  6136. }
  6137. listView.setNeedsDisplayAnnotationViewForVisiblePages()
  6138. } else if(menuItemProperty?.identifier == PDFViewMenuIdentifier_Normal_SortTopAnnotation) {
  6139. let activeAnnotations = listView.activeAnnotations
  6140. for i in 0 ..< (activeAnnotations?.count ?? 0){
  6141. let object = activeAnnotations?[i]
  6142. if let an = object as? CPDFAnnotation {
  6143. listView.bringAnnotationForward(an, page: an.page)
  6144. }
  6145. }
  6146. listView.setNeedsDisplayAnnotationViewForVisiblePages()
  6147. } else if(menuItemProperty?.identifier == PDFViewMenuIdentifier_Normal_SortBottomAnnotation) {
  6148. let activeAnnotations = listView.activeAnnotations
  6149. for i in 0 ..< (activeAnnotations?.count ?? 0){
  6150. let object = activeAnnotations?[i]
  6151. if let an = object as? CPDFAnnotation {
  6152. listView.sendAnnotationBackward(an, page: an.page)
  6153. }
  6154. }
  6155. listView.setNeedsDisplayAnnotationViewForVisiblePages()
  6156. } else if(menuItemProperty?.identifier == PDFViewMenuIdentifier_Normal_SortLastAnnotation) {
  6157. let activeAnnotations = listView.activeAnnotations
  6158. for i in 0 ..< (activeAnnotations?.count ?? 0){
  6159. let object = activeAnnotations?[i]
  6160. if let an = object as? CPDFAnnotation {
  6161. listView.sendAnnotationBack(an, page: an.page)
  6162. }
  6163. }
  6164. listView.setNeedsDisplayAnnotationViewForVisiblePages()
  6165. } else if(menuItemProperty?.identifier == PDFViewMenuIdentifier_Normal_Content) {
  6166. if let activeAnnotation = listView.activeAnnotation {
  6167. listView.edit(activeAnnotation)
  6168. }
  6169. } else if(menuItemProperty?.identifier == PDFViewMenuIdentifier_Redact_Apply) {
  6170. redactApplyAction()
  6171. } else if(menuItemProperty?.identifier == PDFViewMenuIdentifier_Redact_Multipage) {
  6172. if let redactAnnotation = listView.activeAnnotation as? CPDFRedactAnnotation {
  6173. redactMultipageAction(redactAnnotation: redactAnnotation)
  6174. }
  6175. } else if(menuItemProperty?.identifier == PDFViewMenuIdentifier_Redact_Default) {
  6176. if let redactAnnotation = listView.activeAnnotation as? CPDFRedactAnnotation {
  6177. setPropertiesDefault(annotation: redactAnnotation)
  6178. }
  6179. } else if(menuItemProperty?.identifier == PDFViewMenuIdentifier_Split_ViewSingleMode) {
  6180. listView.viewSplitMode = .disable
  6181. reloadPDFSplitInfo()
  6182. } else if(menuItemProperty?.identifier == PDFViewMenuIdentifier_Split_ViewVerticalMode) {
  6183. listView.viewSplitMode = .vertical
  6184. reloadPDFSplitInfo()
  6185. } else if(menuItemProperty?.identifier == PDFViewMenuIdentifier_Split_ViewHorizontalMode) {
  6186. listView.viewSplitMode = .horizontal
  6187. reloadPDFSplitInfo()
  6188. } else if(menuItemProperty?.identifier == PDFViewMenuIdentifier_Split_Sync) {
  6189. viewManager.splitSyncScroll = !viewManager.splitSyncScroll
  6190. } else if(menuItemProperty?.identifier == PDFViewMenuIdentifier_Split_ShowBar) {
  6191. viewManager.splitShowBottomBar = !viewManager.splitShowBottomBar
  6192. splitPDFController?.refreshToolbarState()
  6193. reloadPDFPageNumberToolbar()
  6194. } else if(menuItemProperty?.identifier == PDFViewMenuIdentifier_Normal_LeftAlight) {
  6195. if(listView.isEditing()) {
  6196. listView.changeEditingAreas(.left)
  6197. } else {
  6198. listView.change(listView.activeAnnotations as? [CPDFAnnotation], alignmentType: .left)
  6199. }
  6200. } else if(menuItemProperty?.identifier == PDFViewMenuIdentifier_Normal_VerticallyAlight) {
  6201. if(listView.isEditing()) {
  6202. listView.changeEditingAreas(.vertical)
  6203. } else {
  6204. listView.change(listView.activeAnnotations as? [CPDFAnnotation], alignmentType: .vertical)
  6205. }
  6206. } else if(menuItemProperty?.identifier == PDFViewMenuIdentifier_Normal_RightAlight) {
  6207. if(listView.isEditing()) {
  6208. listView.changeEditingAreas(.right)
  6209. } else {
  6210. listView.change(listView.activeAnnotations as? [CPDFAnnotation], alignmentType: .right)
  6211. }
  6212. } else if(menuItemProperty?.identifier == PDFViewMenuIdentifier_Normal_TopAlight) {
  6213. if(listView.isEditing()) {
  6214. listView.changeEditingAreas(.top)
  6215. } else {
  6216. listView.change(listView.activeAnnotations as? [CPDFAnnotation], alignmentType: .top)
  6217. }
  6218. } else if(menuItemProperty?.identifier == PDFViewMenuIdentifier_Normal_HorizontallyAlight) {
  6219. if(listView.isEditing()) {
  6220. listView.changeEditingAreas(.horizontally)
  6221. } else {
  6222. listView.change(listView.activeAnnotations as? [CPDFAnnotation], alignmentType: .horizontally)
  6223. }
  6224. } else if(menuItemProperty?.identifier == PDFViewMenuIdentifier_Normal_BottomAlight) {
  6225. if(listView.isEditing()) {
  6226. listView.changeEditingAreas(.bottom)
  6227. } else {
  6228. listView.change(listView.activeAnnotations as? [CPDFAnnotation], alignmentType: .bottom)
  6229. }
  6230. } else if(menuItemProperty?.identifier == PDFViewMenuIdentifier_Normal_DistributeHorizontally) {
  6231. if(listView.isEditing()) {
  6232. listView.changeEditingAreas(.disHorizontally)
  6233. } else {
  6234. listView.change(listView.activeAnnotations as? [CPDFAnnotation], alignmentType: .disHorizontally)
  6235. }
  6236. } else if(menuItemProperty?.identifier == PDFViewMenuIdentifier_Normal_DistributeVertically) {
  6237. if(listView.isEditing()) {
  6238. listView.changeEditingAreas(.disVertical)
  6239. } else {
  6240. listView.change(listView.activeAnnotations as? [CPDFAnnotation], alignmentType: .disVertical)
  6241. }
  6242. } else if(menuItemProperty?.identifier == PDFViewMenuIdentifier_Normal_ExportJPG) {
  6243. if(listView.isEditing() == true) {
  6244. listView.exportEditingImageAreasAction(format: "jpg")
  6245. } else {
  6246. if let currentSelection = listView.currentSelection {
  6247. if(currentSelection.selectionType() == .image) {
  6248. listView.exprotSelection(currentSelection, type: 1)
  6249. }
  6250. }
  6251. }
  6252. } else if(menuItemProperty?.identifier == PDFViewMenuIdentifier_Normal_ExportPNG) {
  6253. if(listView.isEditing() == true) {
  6254. listView.exportEditingImageAreasAction(format: "png")
  6255. } else {
  6256. if let currentSelection = listView.currentSelection {
  6257. if(currentSelection.selectionType() == .image) {
  6258. listView.exprotSelection(currentSelection, type: 0)
  6259. }
  6260. }
  6261. }
  6262. } else if(menuItemProperty?.identifier == PDFViewMenuIdentifier_Normal_ExportPDF) {
  6263. if(listView.isEditing() == true) {
  6264. listView.exportEditingImageAreasAction(format: "pdf")
  6265. } else {
  6266. if let currentSelection = listView.currentSelection {
  6267. if(currentSelection.selectionType() == .image) {
  6268. listView.exprotSelection(currentSelection, type: 2)
  6269. }
  6270. }
  6271. }
  6272. } else if(menuItemProperty?.identifier == PDFViewMenuIdentifier_Edit_Paste) {
  6273. listView.pasteEditAreaMatchStyleAction()
  6274. } else if(menuItemProperty?.identifier == PDFViewMenuIdentifier_Edit_NoStylePaste) {
  6275. listView.pasteEditAreaAction()
  6276. } else if(menuItemProperty?.identifier == PDFViewMenuIdentifier_Edit_SelectAll) {
  6277. if listView.km_EditingAreas().count <= 0 {
  6278. listView.selectAllAreaAction()
  6279. } else {
  6280. listView.selectAllAction(with: listView.km_EditingAreas().first)
  6281. }
  6282. } else if(menuItemProperty?.identifier == PDFViewMenuIdentifier_Edit_AddLink) {
  6283. pdfToolbarController?.clickWithIdentify(KMPDFToolbar_edit_link_Identifier)
  6284. } else if(menuItemProperty?.identifier == PDFViewMenuIdentifier_Edit_AddText) {
  6285. pdfToolbarController?.clickWithIdentify(KMPDFToolbar_edit_text_Identifier)
  6286. } else if(menuItemProperty?.identifier == PDFViewMenuIdentifier_Edit_AddImage) {
  6287. pdfToolbarController?.clickWithIdentify(KMPDFToolbar_edit_image_Identifier)
  6288. } else if(menuItemProperty?.identifier == PDFViewMenuIdentifier_Edit_FontBold) {
  6289. listView.setEditingTextarea_Bold()
  6290. } else if(menuItemProperty?.identifier == PDFViewMenuIdentifier_Edit_FontItalic) {
  6291. listView.setEditingTextarea_Italic()
  6292. } else if(menuItemProperty?.identifier == PDFViewMenuIdentifier_Edit_FontUnderline) {
  6293. listView.setEditingTextarea_Under()
  6294. } else if(menuItemProperty?.identifier == PDFViewMenuIdentifier_Edit_FontStrikeout) {
  6295. listView.setEditingTextarea_Strikeout()
  6296. } else if(menuItemProperty?.identifier == PDFViewMenuIdentifier_Edit_FontZoomIn) {
  6297. listView.zoomInEditTextFontSize()
  6298. } else if(menuItemProperty?.identifier == PDFViewMenuIdentifier_Edit_FontZoomOut) {
  6299. listView.zoomInEditTextFontSize()
  6300. } else if(menuItemProperty?.identifier == PDFViewMenuIdentifier_Edit_FontColor) {
  6301. let colorPanel = NSColorPanel.shared
  6302. colorPanel.setTarget(self)
  6303. colorPanel.setAction(#selector(editFontColorItemPanelAction(_:)))
  6304. colorPanel.orderFront(nil)
  6305. } else if(menuItemProperty?.identifier == PDFViewMenuIdentifier_Edit_FontH1Name) {
  6306. let model = KMEditPDFTextManager.manager.fetchUserDefaultData(type: .h1)
  6307. self.updateEditPDFTextFontModel(model)
  6308. } else if(menuItemProperty?.identifier == PDFViewMenuIdentifier_Edit_FontH2Name) {
  6309. let model = KMEditPDFTextManager.manager.fetchUserDefaultData(type: .h2)
  6310. self.updateEditPDFTextFontModel(model)
  6311. } else if(menuItemProperty?.identifier == PDFViewMenuIdentifier_Edit_FontH3Name) {
  6312. let model = KMEditPDFTextManager.manager.fetchUserDefaultData(type: .h3)
  6313. self.updateEditPDFTextFontModel(model)
  6314. } else if(menuItemProperty?.identifier == PDFViewMenuIdentifier_Edit_FontB1Name) {
  6315. let model = KMEditPDFTextManager.manager.fetchUserDefaultData(type: .b1)
  6316. self.updateEditPDFTextFontModel(model)
  6317. } else if(menuItemProperty?.identifier == PDFViewMenuIdentifier_Edit_FontB2Name) {
  6318. let model = KMEditPDFTextManager.manager.fetchUserDefaultData(type: .b2)
  6319. self.updateEditPDFTextFontModel(model)
  6320. } else if(menuItemProperty?.identifier == PDFViewMenuIdentifier_Edit_FontB3Name) {
  6321. let model = KMEditPDFTextManager.manager.fetchUserDefaultData(type: .b3)
  6322. self.updateEditPDFTextFontModel(model)
  6323. } else if(menuItemProperty?.identifier == PDFViewMenuIdentifier_Edit_FontLeftAlight) {
  6324. listView.setEditingTextarea_Alignment(align:.left)
  6325. } else if(menuItemProperty?.identifier == PDFViewMenuIdentifier_Edit_FontCenterAlight) {
  6326. listView.setEditingTextarea_Alignment(align:.center)
  6327. } else if(menuItemProperty?.identifier == PDFViewMenuIdentifier_Edit_FontRightAlight) {
  6328. listView.setEditingTextarea_Alignment(align:.right)
  6329. } else if(menuItemProperty?.identifier == PDFViewMenuIdentifier_Edit_FontJustAlight) {
  6330. listView.setEditingTextarea_Alignment(align:.justified)
  6331. } else if(menuItemProperty?.identifier == PDFViewMenuIdentifier_Edit_RotateLeft) {
  6332. listView.leftRotateAction()
  6333. rightSideController?.reloadEditingAreas()
  6334. } else if(menuItemProperty?.identifier == PDFViewMenuIdentifier_Edit_RotateRight) {
  6335. listView.rightRotateAction()
  6336. rightSideController?.reloadEditingAreas()
  6337. } else if(menuItemProperty?.identifier == PDFViewMenuIdentifier_Edit_HorizontalMirror) {
  6338. listView.reverseYAction()
  6339. rightSideController?.reloadEditingAreas()
  6340. } else if(menuItemProperty?.identifier == PDFViewMenuIdentifier_Edit_VerticalMirror) {
  6341. listView.reverseXAction()
  6342. rightSideController?.reloadEditingAreas()
  6343. } else if(menuItemProperty?.identifier == PDFViewMenuIdentifier_Edit_Crop) {
  6344. listView.cropAction()
  6345. rightSideController?.reloadEditingAreas()
  6346. } else if(menuItemProperty?.identifier == PDFViewMenuIdentifier_Edit_Replace) {
  6347. listView.replaceImageEdit()
  6348. rightSideController?.reloadEditingAreas()
  6349. } else if (menuItemProperty?.identifier == PDFViewMenuIdentifier_Normal_RedactProperties) {
  6350. if let redactAnnotation = listView.activeAnnotation as? CPDFRedactAnnotation{
  6351. showRedactProperty(readactAnnotation: redactAnnotation)
  6352. }
  6353. }
  6354. }
  6355. func componentGroupDidDismiss(group: ComponentGroup?) {
  6356. }
  6357. func updateEditPDFTextFontModel(_ model: KMEditPDFTextFontModel) {
  6358. let fontName = model.fontName
  6359. let fontStyle = model.fontStyle
  6360. let fontSize = model.fontSize
  6361. let bold = model.bold
  6362. let italic = model.italic
  6363. let alignment = model.alignment
  6364. let font = CPDFFont(familyName: fontName, fontStyle: fontStyle)
  6365. listView.setEditingTextarea_font(font: font)
  6366. listView.setEditingTextarea_FontSize(size: fontSize)
  6367. listView.setEditingTextarea(isBold: bold)
  6368. listView.setEditingTextarea(isItalic: italic)
  6369. listView.setEditingTextarea_Alignment(align: alignment)
  6370. }
  6371. }
  6372. // MARK: - KMSnapshotWindowControllerDelegate
  6373. extension KMMainViewController: KMSnapshotWindowControllerDelegate {
  6374. func snapshotControllerWillClose(_ controller: KMSnapshotWindowController) {
  6375. }
  6376. func snapshotController(_ controller: KMSnapshotWindowController, miniaturizedRect isMiniaturize: Bool) -> NSRect {
  6377. return CGRectZero
  6378. }
  6379. func snapshotControllerDidFinishSetup(_ controller: KMSnapshotWindowController) {
  6380. }
  6381. }
  6382. // MARK: - CPDFDocumentDelegate
  6383. extension KMMainViewController: CPDFDocumentDelegate {
  6384. func documentDidBeginDocumentFind(_ document: CPDFDocument!) {
  6385. }
  6386. func documentDidEndDocumentFind(_ document: CPDFDocument!) {
  6387. }
  6388. }
  6389. // MARK: - 测量代理CDistanceSettingWindowControllerDelegate
  6390. extension KMMainViewController : CDistanceSettingWindowControllerDelegate {
  6391. func distanceSettingWindowController(_ distanceSettingWindowController: CDistanceSettingWindowController, updateMeasureInfo measureInfo: CPDFMeasureInfo?) {
  6392. if measureInfo != nil {
  6393. if self.listView.activeAnnotations.count > 0 {
  6394. if self.listView.activeAnnotation.isKind(of: CPDFPolylineAnnotation.self) {
  6395. self.updateMeasureInfo((self.listView.activeAnnotation as! CPDFPolylineAnnotation).measureInfo, withNewMeasure: measureInfo)
  6396. } else if self.listView.activeAnnotation.isKind(of: CPDFPolygonAnnotation.self) {
  6397. self.updateMeasureInfo((self.listView.activeAnnotation as! CPDFPolygonAnnotation).measureInfo, withNewMeasure: measureInfo)
  6398. } else if let data = self.listView.activeAnnotation as? CPDFLineAnnotation, data.isMeasure {
  6399. self.updateMeasureInfo(data.measureInfo, withNewMeasure: measureInfo)
  6400. }
  6401. self.listView.setNeedsDisplayAnnotationViewFor(self.listView.activeAnnotation.page)
  6402. }
  6403. self.updateMeasureInfo(self.listView.distanceMeasureInfo, withNewMeasure: measureInfo)
  6404. self.updateMeasureInfo(self.listView.perimeterMeasureInfo, withNewMeasure: measureInfo)
  6405. self.updateMeasureInfo(self.listView.polygonAreaMeasureInfo, withNewMeasure: measureInfo)
  6406. self.updateMeasureInfo(self.listView.squareAreaMeasureInfo, withNewMeasure: measureInfo)
  6407. }
  6408. }
  6409. func updateMeasureInfo(_ measureInfo: CPDFMeasureInfo?, withNewMeasure newMeasure: CPDFMeasureInfo?) {
  6410. guard let measureInfo = measureInfo else { return }
  6411. guard let newMeasure = newMeasure else { return }
  6412. measureInfo.rulerBase = newMeasure.rulerBase
  6413. measureInfo.rulerTranslate = newMeasure.rulerTranslate
  6414. measureInfo.rulerBaseUnit = newMeasure.rulerBaseUnit
  6415. measureInfo.rulerTranslateUnit = newMeasure.rulerTranslateUnit
  6416. measureInfo.factor = newMeasure.factor
  6417. measureInfo.precision = newMeasure.precision
  6418. }
  6419. }
  6420. //MARK: - Redact密文
  6421. extension KMMainViewController {
  6422. func showRedactProperty(readactAnnotation: CPDFRedactAnnotation?) {
  6423. let properties = KMRedactPropertiesWindowController()
  6424. properties.readactAnnotation = readactAnnotation
  6425. properties.own_beginSheetModal(for: self.view.window) { result in
  6426. }
  6427. }
  6428. func redactApplyAction(needAlert: Bool = true) {
  6429. if needAlert {
  6430. DispatchQueue.main.async { [weak self] in
  6431. guard let self = self else {
  6432. return
  6433. }
  6434. if UserDefaults.standard.object(forKey: "kApplyRedactAlert") != nil {
  6435. self.listView.document.applyRedactions()
  6436. self.listView.layoutDocumentView()
  6437. return
  6438. }
  6439. let alert = NSAlert()
  6440. alert.alertStyle = .informational
  6441. alert.messageText = KMLocalizedString("This action will permanently remove the redacted information from this document.")
  6442. alert.informativeText = KMLocalizedString("""
  6443. After you save this document, you will not be able to retrieve the redacted information.
  6444. """)
  6445. alert.addButton(withTitle: KMLocalizedString("Apply"))
  6446. alert.addButton(withTitle: KMLocalizedString("Cancel"))
  6447. alert.showsSuppressionButton = true
  6448. let response = alert.runModal()
  6449. if response.rawValue == 1000 {
  6450. if alert.suppressionButton?.state == .on {
  6451. UserDefaults.standard.set("YES", forKey: "kApplyRedactAlert")
  6452. UserDefaults.standard.synchronize()
  6453. }
  6454. self.listView.document.applyRedactions()
  6455. self.listView.layoutDocumentView()
  6456. } else if response.rawValue == 1001 {
  6457. //取消
  6458. }
  6459. }
  6460. } else {
  6461. self.listView.document.applyRedactions()
  6462. self.listView.layoutDocumentView()
  6463. }
  6464. }
  6465. func redactMultipageAction(redactAnnotation:CPDFRedactAnnotation) {
  6466. let pagesWindowController = KMRedactSelectPagesWindowController(document: listView.document)
  6467. pagesWindowController.own_beginSheetModal(for: self.view.window) { result in
  6468. }
  6469. pagesWindowController.callback = { [weak self] pages in
  6470. if pages.count > 0 {
  6471. self?.listView.redactAddAnnotationPages(pages, redactAnnotation: redactAnnotation)
  6472. }
  6473. }
  6474. }
  6475. func setPropertiesDefault(annotation:CPDFRedactAnnotation) {
  6476. CPDFRedactAnnotation.update_defaultOutlineColor(annotation.borderColor())
  6477. CPDFRedactAnnotation.update_defaultFillColor(annotation.interiorColor())
  6478. CPDFRedactAnnotation.update_defaultTextColor(annotation.fontColor())
  6479. CPDFRedactAnnotation.update_defaultFontSize(annotation.fontSize)
  6480. CPDFRedactAnnotation.update_defaultFontAlignment(annotation.alignment())
  6481. CPDFRedactAnnotation.update_defaultOverlayText(annotation.overlayText())
  6482. }
  6483. func enterRedactAlert() {
  6484. if UserDefaults.standard.object(forKey: "kRedact") != nil {
  6485. return
  6486. }
  6487. let alert = NSAlert()
  6488. alert.alertStyle = .informational
  6489. alert.informativeText = KMLocalizedString("Redaction allows you to permanently mask and remove sensitive content.")
  6490. alert.messageText = KMLocalizedString("""
  6491. Redaction requires two steps:
  6492. 1. Mark for Redaction
  6493. 2. Apply Redactions
  6494. Note: Redactions are not applied permanently until you select Apply Redactions.
  6495. """)
  6496. alert.addButton(withTitle: KMLocalizedString("OK"))
  6497. alert.showsSuppressionButton = true
  6498. let response = alert.runModal()
  6499. if response.rawValue == 1000 {
  6500. if alert.suppressionButton?.state == .on {
  6501. UserDefaults.standard.set("YES", forKey: "kRedact")
  6502. UserDefaults.standard.synchronize()
  6503. }
  6504. }
  6505. }
  6506. }
  6507. //MARK: - extension
  6508. extension KMMainViewController {
  6509. func removeAllAnnotations() {
  6510. let alert = NSAlert()
  6511. alert.messageText = KMLocalizedString("This will permanently remove all annotations. Are you sure to continue?", comment: "")
  6512. alert.addButton(withTitle: KMLocalizedString("Yes", comment:""))
  6513. alert.addButton(withTitle: KMLocalizedString("No", comment:""))
  6514. if (alert.runModal() != .alertFirstButtonReturn) {
  6515. return
  6516. }
  6517. DispatchQueue.main.async {
  6518. self.removeAllAnnotationsStore.store(t: self.listView)
  6519. }
  6520. }
  6521. //MARK: - AI
  6522. func showAITypeChooseView(aiConfigType: AIConfigType) -> Void {
  6523. if (self.document != nil) {
  6524. AIChatInfoManager.defaultManager.currentFilePath = (self.document?.documentURL.path)!
  6525. } else {
  6526. AIChatInfoManager.defaultManager.currentFilePath = ""
  6527. }
  6528. let windowVC: AINewConfigWindowController = AINewConfigWindowController.currentWC()
  6529. windowVC.chooseCurFileHandle = {[unowned self] windowVC in
  6530. if AIChatInfoManager.defaultManager.currentFilePath.isEmpty == false {
  6531. let documentArray = NSDocumentController.shared.documents
  6532. var didFileEdit: Bool = false
  6533. var curDoc: KMMainDocument!
  6534. for document in documentArray {
  6535. if document.fileURL?.path == AIChatInfoManager.defaultManager.currentFilePath {
  6536. didFileEdit = document.isDocumentEdited
  6537. curDoc = document as! KMMainDocument
  6538. break
  6539. }
  6540. }
  6541. if didFileEdit {
  6542. let tempFileURL = FileManager.default.temporaryDirectory.appendingPathComponent(AIChatInfoManager.defaultManager.currentFilePath.lastPathComponent)
  6543. if FileManager.default.fileExists(atPath: tempFileURL.path) {
  6544. do {
  6545. try FileManager.default.removeItem(at: tempFileURL)
  6546. } catch {
  6547. }
  6548. }
  6549. if curDoc != nil {
  6550. curDoc.mainViewController?.SaveTempPDFDocumentToURLPath(tempPath: tempFileURL.path)
  6551. }
  6552. }
  6553. windowVC.window?.becomeMain()
  6554. }
  6555. }
  6556. if windowVC.window?.isVisible == true && windowVC.didSetOriginFrame == true {
  6557. } else {
  6558. var windowRect = windowVC.window?.frame
  6559. windowRect!.origin.x = NSMaxX(self.view.window!.frame) - (windowRect?.size.width)!
  6560. windowRect!.origin.y = NSMaxY(self.view.window!.frame) - (windowRect?.size.height)! - 64
  6561. windowVC.window?.setFrame(windowRect!, display: true)
  6562. windowVC.didSetOriginFrame = true
  6563. }
  6564. windowVC.eventLabel = "AITools_Tbr"
  6565. windowVC.showWindow(nil)
  6566. if (aiConfigType != .none) {
  6567. windowVC.eventLabel = "AITools_Start"
  6568. if self.listView.currentSelection?.string()?.isEmpty == false {
  6569. windowVC.setCurrentPDFSelection(self.listView.currentSelection.string())
  6570. }
  6571. windowVC.chooseAIFunctionWithType(aiConfigType)
  6572. }
  6573. }
  6574. @objc func aiTipIconViewShowStateChangeNoti() {
  6575. }
  6576. //MARK: - 引导
  6577. func loadFunctionGuide() -> Void {
  6578. DispatchQueue.main.asyncAfter(deadline: DispatchTime.now() + 1) {
  6579. if self.view.window != nil {
  6580. self.loadOpenFileFunctionGuide(.openFileNormal)
  6581. }
  6582. }
  6583. }
  6584. func loadOpenFileFunctionGuide(_ showType: KMGuideInfoType) -> Void {
  6585. if showType == .openFileNormal && KMGuideInfoWindowController.availableShow(.openFileNormal) {
  6586. self.guideInfoWindowController = KMGuideInfoWindowController.currentWC()
  6587. guard let guideWC = self.guideInfoWindowController else { return }
  6588. guideWC.type = .openFileNormal
  6589. // guideWC.openPanelRect = (self.view.window?.contentView?.convert(leftPanelItem.frame, from: leftPanelItem.superview)) ?? .zero
  6590. guideWC.window?.collectionBehavior = [.canJoinAllSpaces]
  6591. guideWC.normalGuideFinishHandle = { [weak self] windowVC in
  6592. }
  6593. guideWC.finishHandle = { [weak self] windowVC, type in
  6594. if type == .windowNewFinish ||
  6595. type == . windowDigitalFinish {
  6596. self?.checkFirstTrialController()
  6597. }
  6598. }
  6599. guideWC.openFileToggleHandle = { [weak self] windowVC, type in
  6600. self?.checkFirstTrialController()
  6601. }
  6602. var rect = self.view.window!.frame
  6603. rect.size.height -= 20
  6604. guideWC.window?.setFrame(rect, display: false)
  6605. guideWC.window?.minSize = rect.size
  6606. guideWC.window?.maxSize = rect.size
  6607. self.view.window?.addChildWindow(guideWC.window!, ordered: .above)
  6608. guideWC.show()
  6609. } else if showType == .digitalSignGuide && KMGuideInfoWindowController.availableShow(.digitalSignGuide) {
  6610. self.guideInfoWindowController = KMGuideInfoWindowController.currentWC()
  6611. guard let guideWC = self.guideInfoWindowController else { return }
  6612. guideWC.type = .digitalSignGuide
  6613. guideWC.window?.collectionBehavior = [.canJoinAllSpaces]
  6614. guideWC.finishHandle = { [weak self] windowVC, type in
  6615. self?.checkFirstTrialController()
  6616. }
  6617. var rect = self.view.window!.frame
  6618. rect.size.height -= 20
  6619. guideWC.window?.setFrame(rect, display: false)
  6620. guideWC.window?.minSize = rect.size
  6621. guideWC.window?.maxSize = rect.size
  6622. self.view.window?.addChildWindow(guideWC.window!, ordered: .above)
  6623. guideWC.show()
  6624. } else if showType == .pdfCompareGuide && KMGuideInfoWindowController.availableShow(.pdfCompareGuide) {
  6625. DispatchQueue.main.asyncAfter(deadline: DispatchTime.now() + 0.2) {
  6626. self.guideInfoWindowController = KMGuideInfoWindowController.currentWC()
  6627. guard let guideWC = self.guideInfoWindowController else { return }
  6628. guideWC.type = .pdfCompareGuide
  6629. guard let win = self.view.window else {
  6630. return
  6631. }
  6632. guideWC.finishHandle = { [weak self] winC, type in
  6633. if type == .windowNewFinish {
  6634. DispatchQueue.main.async {
  6635. self?.loadOpenFileFunctionGuide(.measureGuide)
  6636. }
  6637. return
  6638. }
  6639. }
  6640. guideWC.window?.collectionBehavior = [.canJoinAllSpaces]
  6641. var rect = self.view.window!.frame
  6642. rect.size.height -= 20
  6643. guideWC.window?.setFrame(rect, display: false)
  6644. guideWC.window?.minSize = rect.size
  6645. guideWC.window?.maxSize = rect.size
  6646. self.view.window?.addChildWindow(guideWC.window!, ordered: .above)
  6647. guideWC.show()
  6648. }
  6649. } else if showType == .measureGuide && KMGuideInfoWindowController.availableShow(.measureGuide) {
  6650. DispatchQueue.main.asyncAfter(deadline: DispatchTime.now() + 0.2) {
  6651. self.guideInfoWindowController = KMGuideInfoWindowController.currentWC()
  6652. guard let guideWC = self.guideInfoWindowController else { return }
  6653. guard let _ = self.view.window else {
  6654. return
  6655. }
  6656. guideWC.type = .measureGuide
  6657. guideWC.window?.collectionBehavior = [.canJoinAllSpaces]
  6658. var rect = self.view.window?.frame ?? .zero
  6659. rect.size.height -= 20
  6660. guideWC.window?.setFrame(rect, display: false)
  6661. guideWC.window?.minSize = rect.size
  6662. guideWC.window?.maxSize = rect.size
  6663. self.view.window?.addChildWindow(guideWC.window!, ordered: .above)
  6664. guideWC.show()
  6665. }
  6666. } else if showType == .convertGuide && KMGuideInfoWindowController.availableShow(.convertGuide) {
  6667. DispatchQueue.main.asyncAfter(deadline: DispatchTime.now() + 1) {
  6668. self.guideInfoWindowController = KMGuideInfoWindowController.currentWC()
  6669. guard let guideWC = self.guideInfoWindowController else { return }
  6670. guideWC.type = .convertGuide
  6671. guard let win = self.view.window else {
  6672. return
  6673. }
  6674. guideWC.purchaseHandle = { [weak self] windowVC in
  6675. #if VERSION_DMG
  6676. if IAPProductsManager.default().isAvailableAllFunction() {
  6677. if IAPProductsManager.default().isAvailableAdvancedPDFToOffice() {
  6678. //Convert:
  6679. } else {
  6680. let limitWC = KMPurchaseLimitWindowController.currentLimitWC()
  6681. limitWC.continueBlock = { windowController in
  6682. }
  6683. limitWC.window?.center()
  6684. limitWC.showWindow(nil)
  6685. }
  6686. } else {
  6687. KMPurchaseCompareWindowController.sharedInstance().showWindow(nil)
  6688. }
  6689. #else
  6690. if IAPProductsManager.default().isAvailableAllFunction() {
  6691. if IAPProductsManager.default().isAvailableAdvancedPDFToOffice() {
  6692. //Convert:
  6693. } else {
  6694. var vc = KMToolCompareWindowController(toolType: .Convert, selectNum: 1)
  6695. vc.showWindow(nil)
  6696. }
  6697. } else {
  6698. KMPurchaseCompareWindowController.sharedInstance().showWindow(nil)
  6699. }
  6700. #endif
  6701. }
  6702. guideWC.window?.collectionBehavior = [.canJoinAllSpaces]
  6703. var rect = self.view.window?.frame ?? .zero
  6704. rect.size.height -= 20
  6705. guideWC.window?.setFrame(rect, display: false)
  6706. guideWC.window?.minSize = rect.size
  6707. guideWC.window?.maxSize = rect.size
  6708. self.view.window?.addChildWindow(guideWC.window!, ordered: .above)
  6709. guideWC.show()
  6710. }
  6711. } else {
  6712. }
  6713. }
  6714. func checkFirstTrialController() -> Void {
  6715. #if VERSION_DMG
  6716. //打开文档后引导相关
  6717. if VerificationManager.default().status == .none {
  6718. let appVersion = Bundle.main.infoDictionary?["CFBundleShortVersionString"] as? String ?? ""
  6719. let lastVersion = UserDefaults.standard.object(forKey: "SKLastTrialVersionMainDocumentLaunchedKey") as? String ?? ""
  6720. if lastVersion.isEmpty || lastVersion != appVersion {
  6721. UserDefaults.standard.setValue(appVersion, forKey: "SKLastTrialVersionMainDocumentLaunchedKey")
  6722. UserDefaults.standard.synchronize()
  6723. KMPurchaseCompareWindowController.sharedInstance().showWindow(nil)
  6724. }
  6725. }
  6726. #endif
  6727. }
  6728. // MARK: - Private Methods
  6729. func isPDFPageCountExceedsLimit(filePath: String) -> Bool {
  6730. let url = URL(fileURLWithPath: filePath)
  6731. guard let document = PDFDocument(url: url) else {
  6732. return false
  6733. }
  6734. let pageCount = document.pageCount
  6735. return pageCount > 30
  6736. }
  6737. // MARK: - 保存文档
  6738. internal func needSaveDocument() -> Bool {
  6739. if (self.isPDFDocumentEdited) {
  6740. return self.isPDFDocumentEdited
  6741. }
  6742. if (self.needSave) {
  6743. return self.needSave
  6744. }
  6745. let document: KMMainDocument? = self.myDocument as? KMMainDocument
  6746. if (document?.isDocumentEdited == nil || document?.isDocumentEdited == false) {
  6747. return false
  6748. }
  6749. return true
  6750. }
  6751. internal func saveDocument(overlookDocumentIfEdited overlook: Bool = false) {
  6752. let document: KMMainDocument? = self.myDocument as? KMMainDocument
  6753. if (overlook) {
  6754. document?.save(nil)
  6755. return
  6756. }
  6757. if (self.isPDFDocumentEdited) {
  6758. self.needSave = false
  6759. document?.save(nil)
  6760. return
  6761. }
  6762. if (document?.isDocumentEdited == nil || document?.isDocumentEdited == false) {
  6763. return
  6764. }
  6765. document?.save(nil)
  6766. }
  6767. internal func asyncSaveDocument(overlookDocumentIfEdited overlook: Bool = false, callback:@escaping KMCommonBlock) {
  6768. let document: KMMainDocument? = self.myDocument as? KMMainDocument
  6769. if (overlook) {
  6770. DispatchQueue.main.async {
  6771. document?.save(nil)
  6772. callback()
  6773. }
  6774. return
  6775. }
  6776. if (self.isPDFDocumentEdited) {
  6777. self.needSave = false
  6778. DispatchQueue.main.async {
  6779. document?.save(nil)
  6780. callback()
  6781. }
  6782. return
  6783. }
  6784. if (document?.isDocumentEdited == nil || document?.isDocumentEdited == false) {
  6785. callback()
  6786. return
  6787. }
  6788. DispatchQueue.main.async {
  6789. document?.save(nil)
  6790. callback()
  6791. }
  6792. }
  6793. internal func saveDocumentWithProgressAlert(callback:@escaping KMCommonBlock) {
  6794. // 显示进度
  6795. AutoSaveManager.manager.isSaving = true
  6796. self.showProgressWindow(message: KMLocalizedString("Save", comment: "") + "PDF")
  6797. self.progressC?.maxValue = 3.0
  6798. self.progressC?.increment(by: 1.0)
  6799. // 保存文档
  6800. self.asyncSaveDocument { [weak self] params in
  6801. // 执行进度 [假进度]
  6802. self?.progressC?.increment(by: 1.0)
  6803. self?.progressC?.increment(by: 1.0)
  6804. DispatchQueue.main.asyncAfter(deadline: .now()+0.1) {
  6805. // 隐藏进度
  6806. self?.hiddenProgressWindow()
  6807. DispatchQueue.main.asyncAfter(deadline: .now()+1) {
  6808. AutoSaveManager.manager.isSaving = false
  6809. }
  6810. // 回调
  6811. callback()
  6812. }
  6813. }
  6814. }
  6815. func SaveTempPDFDocumentToURLPath(tempPath: String) {
  6816. self.document?.write(toFile: tempPath)
  6817. }
  6818. // MARK: - 定时保存
  6819. func addAutoSaveEvent() {
  6820. if (self.autoSaveTimer != nil) {
  6821. self.autoSaveTimer?.invalidate()
  6822. self.autoSaveTimer = nil
  6823. }
  6824. if self.document != nil, SettingsManager.sharedInstance.autoSaveFile == true {
  6825. self.autoSaveTimer = Timer.scheduledTimer(withTimeInterval: 1 * 60, repeats: true, block: { [weak self] timer in
  6826. self?.autoSaveTimerAction(timer)
  6827. })
  6828. }
  6829. self.checkAutoSaveInfo()
  6830. }
  6831. func checkAutoSaveInfo() {
  6832. guard let cnt = AutoSaveManager.manager.autoSavePaths?.count, cnt > 0 else {
  6833. return
  6834. }
  6835. if AutoSaveManager.manager.autoSaveAlertShow {
  6836. return
  6837. }
  6838. AutoSaveManager.manager.autoSaveDidEndAction = false
  6839. AutoSaveManager.manager.autoSaveAlertShow = true
  6840. blockSaveWindow.cancelHandle = { [weak self] windowController in
  6841. AutoSaveManager.manager.autoSaveDidEndAction = true
  6842. AutoSaveManager.manager.clearCache()
  6843. self?.km_quick_endSheet()
  6844. }
  6845. blockSaveWindow.confirmHandle = { [weak self] windowController in
  6846. self?.view.window?.endSheet(windowController.window!)
  6847. self?.saveAutoSaveInfo()
  6848. }
  6849. self.view.window?.beginSheet(blockSaveWindow.window!)
  6850. }
  6851. func saveAutoSaveInfo() {
  6852. let openPanel = NSOpenPanel()
  6853. openPanel.canChooseDirectories = true
  6854. openPanel.canChooseFiles = false
  6855. openPanel.allowsMultipleSelection = false
  6856. let win = NSApp.keyWindow != nil ? NSApp.keyWindow : self.view.window
  6857. openPanel.beginSheetModal(for: win!) { result in
  6858. if (result == .OK) {
  6859. let folderPath = openPanel.url?.path ?? openPanel.url?.absoluteString
  6860. for path in AutoSaveManager.manager.opendPaths ?? [] {
  6861. let _path = path as? String
  6862. var newPath = "\(folderPath ?? "")/\(_path?.lastPathComponent ?? "")"
  6863. newPath = self.getValidFilePath(newPath)
  6864. do {
  6865. try FileManager.default.moveItem(atPath: _path ?? "", toPath: newPath)
  6866. } catch {
  6867. NSWorkspace.shared.activateFileViewerSelecting([URL(fileURLWithPath: newPath)])
  6868. }
  6869. }
  6870. AutoSaveManager.manager.clearCache()
  6871. }
  6872. AutoSaveManager.manager.autoSaveDidEndAction = true
  6873. }
  6874. }
  6875. func autoSaveTimerAction(_ timer: Timer) {
  6876. if (self.document == nil || self.listView.document?.documentURL.path == nil) {
  6877. return
  6878. }
  6879. if AutoSaveManager.manager.autoSaveDidEndAction == false {
  6880. //防止提示弹窗出现后,未进行任何操作又进入自动保存的机制
  6881. return
  6882. }
  6883. if let data = self.document?.isLocked, data {
  6884. return
  6885. }
  6886. if SettingsManager.sharedInstance.autoSaveFile == false {
  6887. return
  6888. }
  6889. let documentArray = NSDocumentController.shared.documents
  6890. var didFileEdit = false
  6891. for doc in documentArray {
  6892. if doc.fileURL?.path == self.document?.documentURL.path {
  6893. didFileEdit = doc.isDocumentEdited
  6894. break
  6895. }
  6896. }
  6897. if (didFileEdit == false) {
  6898. return
  6899. }
  6900. AutoSaveManager.manager.isSaving = true
  6901. let savePath = AutoSaveManager.manager.autoSaveWithPath(self.listView.document?.documentURL.path ?? "")
  6902. if (!self.document!.isLocked) {
  6903. self.document?.write(to: URL(fileURLWithPath: savePath))
  6904. }
  6905. DispatchQueue.main.asyncAfter(deadline: .now() + 1.5) {
  6906. AutoSaveManager.manager.isSaving = false
  6907. }
  6908. }
  6909. func removeAutoSaveInfo() {
  6910. if self.autoSaveTimer != nil {
  6911. self.autoSaveTimer?.invalidate()
  6912. self.autoSaveTimer = nil
  6913. }
  6914. if AutoSaveManager.manager.autoSaveDidEndAction == false {
  6915. //防止提示弹窗出现后,未进行任何操作又进入自动保存的机制
  6916. return
  6917. }
  6918. if SettingsManager.sharedInstance.autoSaveFile == false {
  6919. return
  6920. }
  6921. if self.document == nil || self.listView.document?.documentURL.path == nil {
  6922. return
  6923. }
  6924. AutoSaveManager.manager.removeAutoSavePath(self.listView.document?.documentURL.path ?? "")
  6925. }
  6926. // MARK: - 选择缩放模式
  6927. @objc public func selectZoom(_ type: KMPDFZoomType) {
  6928. switch type {
  6929. case .width:
  6930. self.listView.autoScales = true
  6931. break
  6932. case .fit:
  6933. if let pageHeight = self.listView.currentPage()?.size.height, pageHeight > 0 {
  6934. let pdfviewHeight = self.listView.bounds.size.height
  6935. self.listView.scaleFactor = pdfviewHeight/pageHeight
  6936. self.listView.autoScales = false
  6937. }
  6938. break
  6939. case .actualSize:
  6940. if self.listView.scaleFactor != 1.0 {
  6941. self.listView.scaleFactor = 1.0
  6942. self.listView.autoScales = false
  6943. }
  6944. break
  6945. case .zoom_In:
  6946. self.doZoomIn(nil)
  6947. break
  6948. case .zoom_Out:
  6949. self.doZoomOut(nil)
  6950. break
  6951. }
  6952. }
  6953. func doZoomIn(_ sender: Any?) {
  6954. if (self.listView.canZoomIn) {
  6955. self.listView.zoomIn(nil)
  6956. }
  6957. }
  6958. func doZoomOut(_ sender: Any?) {
  6959. if (self.listView.canZoomOut) {
  6960. self.listView.zoomOut(nil)
  6961. }
  6962. }
  6963. // MARK: - Event 监听
  6964. private func addEventMonitor() {
  6965. if (self.eventMonitor != nil) {
  6966. self.removeEventMonitor()
  6967. }
  6968. self.eventMonitor = NSEvent.addLocalMonitorForEvents(matching: [.scrollWheel, .leftMouseDown, .leftMouseUp]) { [weak self] event in
  6969. if (event.type == .scrollWheel && event.modifierFlags.contains(.option)) { // Alt + 鼠标滚轮
  6970. self?.listView.magnifyWheel(event)
  6971. return nil
  6972. } else if event.type == .leftMouseDown {
  6973. let point = event.locationInView(self?.listView ?? NSView())
  6974. let presentationDrawView = self?.listView.presentationDrawView
  6975. if let data = self?.interactionMode, data == .presentation,CGRectContainsPoint(self?.listView.frame ?? .zero, point),presentationDrawView?.isHidden == true { // 幻灯片模式下
  6976. if point.x >= (self?.listView.frame.maxX ?? 0) / 2 {
  6977. let can = self?.listView.canGoToNextPage() ?? false
  6978. if can {
  6979. self?.listView.goToNextPage(nil)
  6980. }
  6981. } else {
  6982. let can = self?.listView.canGoToPreviousPage() ?? false
  6983. if can {
  6984. self?.listView.goToPreviousPage(nil)
  6985. }
  6986. }
  6987. return nil
  6988. }
  6989. }
  6990. return event
  6991. }
  6992. }
  6993. private func removeEventMonitor() {
  6994. if (self.eventMonitor != nil) {
  6995. KMPrint("已移除事件监听")
  6996. NSEvent.removeMonitor(self.eventMonitor as Any)
  6997. self.eventMonitor = nil
  6998. }
  6999. }
  7000. func addKeyEventMonitor() {
  7001. if (self.keyEventMonitor != nil) {
  7002. self.removeKeyEventMonitor()
  7003. }
  7004. keyEventMonitor = NSEvent.addLocalMonitorForEvents(matching: .keyDown) { [weak self] event in
  7005. if event.keyCode == 53 {
  7006. if self?.listView.annotationType == .freeText {
  7007. self?.listView.keyDown(with: event)
  7008. }
  7009. } else {
  7010. }
  7011. return event
  7012. }
  7013. }
  7014. func removeKeyEventMonitor() {
  7015. if (self.keyEventMonitor != nil) {
  7016. KMPrint("removeKeyEventMonitor 已移除事件监听")
  7017. NSEvent.removeMonitor(self.keyEventMonitor as Any)
  7018. self.keyEventMonitor = nil
  7019. }
  7020. }
  7021. //MARK: - Mouse Event
  7022. override func mouseMoved(with event: NSEvent) {
  7023. self.view.window?.mouseMoved(with: event)
  7024. }
  7025. override func keyDown(with event: NSEvent) {
  7026. listView.keyDown(with: event)
  7027. }
  7028. // MARK: - Tools
  7029. func pdfViewCanHorizontalScroll() -> Bool {
  7030. let scroll = self.listView.scroll()
  7031. if (scroll == nil) {
  7032. return false
  7033. }
  7034. return scroll?.horizontalScroller?.isHidden == nil ? false : !(scroll!.horizontalScroller!.isHidden)
  7035. }
  7036. func pdfViewCanVerticalScroll() -> Bool {
  7037. let scroll = self.listView.scroll()
  7038. if (scroll == nil) {
  7039. return false
  7040. }
  7041. return scroll?.verticalScroller?.isHidden == nil ? false : !(scroll!.verticalScroller!.isHidden)
  7042. }
  7043. // MARK: - Public Methods
  7044. // 清理数据 [eg. 通知]
  7045. public func clearData() {
  7046. KMThumbnailCache.shared.clearCache()
  7047. self.removeNotifications()
  7048. if (self.listView.spellingTag() > 0) {
  7049. NSSpellChecker.shared.closeSpellDocument(withTag: self.listView.spellingTag())
  7050. }
  7051. self.removeAutoSaveInfo()
  7052. self.myDocument = nil
  7053. if textFieldSheet.window?.isVisible == true {
  7054. textFieldSheet.close()
  7055. }
  7056. if NSColorPanel.shared.isVisible == true {
  7057. NSColorPanel.shared.close()
  7058. }
  7059. if KMInfoWindowController.shared.window?.isVisible == true {
  7060. KMInfoWindowController.shared.close()
  7061. }
  7062. }
  7063. public func clearSecureOptions() {
  7064. self._secureOptions = nil
  7065. self.documentAttribute = nil
  7066. }
  7067. public func clearRemoveSecureFlag() {
  7068. self._removeSecureFlag = false
  7069. }
  7070. public func recordIsPDFDocumentEdited() {
  7071. km_synchronized(self) {
  7072. self.model.isPDFDocumentEdited = true
  7073. if let _document = self.myDocument {
  7074. KMTools.setDocumentEditedState(document: _document)
  7075. }
  7076. }
  7077. }
  7078. public func clearIsPDFDocumentEdited() {
  7079. km_synchronized(self) {
  7080. self.model.isPDFDocumentEdited = false
  7081. }
  7082. }
  7083. func showSnapshots(setups: NSArray?) {
  7084. if self.listView.document != nil {
  7085. for setup in setups ?? [] {
  7086. let swc = KMSnapshotWindowController()
  7087. swc.delegate = self
  7088. swc.setPdfDocument(self.listView.document, setup: setup as? NSDictionary)
  7089. swc.setForceOnTop(self.interactionMode != .normal)
  7090. self.myDocument?.addWindowController(swc)
  7091. }
  7092. }
  7093. }
  7094. // MARK: - Noti Actions
  7095. internal func documentDidUnlockNotification(_ sender: Notification) {
  7096. if (self.listView.document != nil && self.listView.document.isEqual(to: sender.object)) {
  7097. if (self.myDocument == nil) {
  7098. return
  7099. }
  7100. if (self.listView.document.allowsPrinting && self.listView.document.allowsCopying) {
  7101. self.hiddenSecureLimitTip()
  7102. }
  7103. let isUnlockFromKeychain = (self.myDocument as? KMMainDocument)?.isUnlockFromKeychain ?? false
  7104. if (isUnlockFromKeychain || self.model.isSaveKeyChain == false) {
  7105. return
  7106. }
  7107. let type = SettingsManager.sharedInstance.keychainType
  7108. if (type == .never) {
  7109. return
  7110. }
  7111. if (type == .always) {
  7112. self.myDocument?.savePasswordInKeychain(self.listView.document.password, self.listView.document)
  7113. return
  7114. }
  7115. // 保存到钥匙串
  7116. let alert = NSAlert()
  7117. alert.messageText = KMLocalizedString("Remember Password?", comment: "")
  7118. alert.informativeText = KMLocalizedString("Do you want to save this password in your Keychain?", comment: "")
  7119. alert.addButton(withTitle: KMLocalizedString("Yes", comment: ""))
  7120. alert.addButton(withTitle: KMLocalizedString("No", comment: ""))
  7121. if (alert.runModal() == .alertFirstButtonReturn) { // 保存密码
  7122. self.myDocument?.savePasswordInKeychain(self.listView.document.password, self.listView.document)
  7123. return
  7124. }
  7125. }
  7126. }
  7127. internal func applicationWillTerminateNotification(_ sender: Notification) {
  7128. self.savePageNumberIfNeed()
  7129. self.saveDocument()
  7130. }
  7131. internal func pdfViewHighlightFormFiledUpdateNoti(_ sender: Notification) {
  7132. self.alertTipViewController.reloadFormAlertUI()
  7133. }
  7134. func rename(_ sender: NSNotification) -> Void {
  7135. if (self.view.window == nil || self.view.window!.isVisible == false) {
  7136. return
  7137. }
  7138. let tabController = sender.object as? CTTabController
  7139. if tabController?.title == self.document?.documentURL.deletingPathExtension().lastPathComponent {
  7140. if let doc = self.myDocument, doc.isDocumentEdited {
  7141. Task {
  7142. let resp = await KMAlertTool.runModel(message: NSLocalizedString("File Updated", comment: ""), buttons: [NSLocalizedString("Save", comment: ""), NSLocalizedString("Cancel", comment: "")])
  7143. if resp != .alertFirstButtonReturn { // 取消
  7144. return
  7145. }
  7146. doc.updateChangeCount(.changeCleared)
  7147. self.document?.write(to: doc.fileURL)
  7148. Task { @MainActor in
  7149. self._renameForSavePanel(tabController)
  7150. }
  7151. }
  7152. return
  7153. }
  7154. self._renameForSavePanel(tabController)
  7155. }
  7156. }
  7157. func savePdfAlertView() {
  7158. if AutoSaveManager.manager.isSaving || AutoSaveManager.manager.isSaveNoti{
  7159. return
  7160. }
  7161. AutoSaveManager.manager.isSaveNoti = true
  7162. var num = 0
  7163. if self.listView.document != nil{
  7164. num = Int(self.listView.document.pageCount)
  7165. }
  7166. if Thread.current.isMainThread {
  7167. self.beginProgressSheet(withMessage: NSLocalizedString("Saving PDF", comment: "") + "...", maxValue: UInt(num))
  7168. } else {
  7169. DispatchQueue.main.async {
  7170. self.beginProgressSheet(withMessage: NSLocalizedString("Saving PDF", comment: "") + "...", maxValue: UInt(num))
  7171. }
  7172. }
  7173. }
  7174. func savePdfFinishAlertView() {
  7175. if !AutoSaveManager.manager.isSaveNoti{
  7176. return
  7177. }
  7178. AutoSaveManager.manager.isSaveNoti = false
  7179. if Thread.current.isMainThread {
  7180. self.dismissProgressSheet()
  7181. } else {
  7182. DispatchQueue.main.async {
  7183. self.dismissProgressSheet()
  7184. }
  7185. }
  7186. }
  7187. private func _renameForSavePanel(_ tabC: CTTabController?) {
  7188. let outputSavePanel = NSSavePanel()
  7189. outputSavePanel.title = NSLocalizedString("Rename", comment: "")
  7190. outputSavePanel.allowedFileTypes = ["pdf"]
  7191. outputSavePanel.nameFieldStringValue = (self.document?.documentURL.lastPathComponent)!
  7192. outputSavePanel.directoryURL = self.document?.documentURL.deletingLastPathComponent()
  7193. let resp = outputSavePanel.runModal()
  7194. if resp == .OK {
  7195. let pdfDocument = CPDFDocument(url: self.document?.documentURL)
  7196. let fileURL = pdfDocument?.documentURL
  7197. let fileManager = FileManager.default
  7198. let newFileURL = fileURL!.deletingLastPathComponent().appendingPathComponent(outputSavePanel.url!.lastPathComponent)
  7199. var result = true
  7200. do {
  7201. try fileManager.moveItem(at: fileURL!, to: newFileURL)
  7202. } catch {
  7203. result = false
  7204. KMPrint("Error renaming file! Threw: \(error.localizedDescription)")
  7205. }
  7206. if (result) {
  7207. tabC?.title = outputSavePanel.url!.lastPathComponent
  7208. if let newPdfDocument = CPDFDocument(url: newFileURL) {
  7209. self.model.isSaveKeyChain = false
  7210. newPdfDocument.unlock(withPassword: self.document?.password)
  7211. if (newPdfDocument.pageCount > 0) {
  7212. self.setDocument = newPdfDocument
  7213. }
  7214. }
  7215. }
  7216. } else {
  7217. outputSavePanel.close()
  7218. }
  7219. }
  7220. func showInFinder(_ sender: Any) -> Void {
  7221. if sender is NSNotification {
  7222. let tabController = (sender as! NSNotification).object as? CTTabController
  7223. let path = self.document?.documentURL.deletingPathExtension().lastPathComponent
  7224. if tabController?.title == path {
  7225. if let file = self.myDocument?.fileURL {
  7226. if FileManager.default.fileExists(atPath: file.path) {
  7227. NSWorkspace.shared.activateFileViewerSelecting([file])
  7228. }
  7229. }
  7230. }
  7231. } else {
  7232. guard let url = self.myDocument?.fileURL else { return }
  7233. let file: URL = url
  7234. if FileManager.default.fileExists(atPath: file.path) {
  7235. NSWorkspace.shared.activateFileViewerSelecting([file])
  7236. }
  7237. }
  7238. }
  7239. }