KMMainViewController.swift 357 KB

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