weditor.pas 211 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724172517261727172817291730173117321733173417351736173717381739174017411742174317441745174617471748174917501751175217531754175517561757175817591760176117621763176417651766176717681769177017711772177317741775177617771778177917801781178217831784178517861787178817891790179117921793179417951796179717981799180018011802180318041805180618071808180918101811181218131814181518161817181818191820182118221823182418251826182718281829183018311832183318341835183618371838183918401841184218431844184518461847184818491850185118521853185418551856185718581859186018611862186318641865186618671868186918701871187218731874187518761877187818791880188118821883188418851886188718881889189018911892189318941895189618971898189919001901190219031904190519061907190819091910191119121913191419151916191719181919192019211922192319241925192619271928192919301931193219331934193519361937193819391940194119421943194419451946194719481949195019511952195319541955195619571958195919601961196219631964196519661967196819691970197119721973197419751976197719781979198019811982198319841985198619871988198919901991199219931994199519961997199819992000200120022003200420052006200720082009201020112012201320142015201620172018201920202021202220232024202520262027202820292030203120322033203420352036203720382039204020412042204320442045204620472048204920502051205220532054205520562057205820592060206120622063206420652066206720682069207020712072207320742075207620772078207920802081208220832084208520862087208820892090209120922093209420952096209720982099210021012102210321042105210621072108210921102111211221132114211521162117211821192120212121222123212421252126212721282129213021312132213321342135213621372138213921402141214221432144214521462147214821492150215121522153215421552156215721582159216021612162216321642165216621672168216921702171217221732174217521762177217821792180218121822183218421852186218721882189219021912192219321942195219621972198219922002201220222032204220522062207220822092210221122122213221422152216221722182219222022212222222322242225222622272228222922302231223222332234223522362237223822392240224122422243224422452246224722482249225022512252225322542255225622572258225922602261226222632264226522662267226822692270227122722273227422752276227722782279228022812282228322842285228622872288228922902291229222932294229522962297229822992300230123022303230423052306230723082309231023112312231323142315231623172318231923202321232223232324232523262327232823292330233123322333233423352336233723382339234023412342234323442345234623472348234923502351235223532354235523562357235823592360236123622363236423652366236723682369237023712372237323742375237623772378237923802381238223832384238523862387238823892390239123922393239423952396239723982399240024012402240324042405240624072408240924102411241224132414241524162417241824192420242124222423242424252426242724282429243024312432243324342435243624372438243924402441244224432444244524462447244824492450245124522453245424552456245724582459246024612462246324642465246624672468246924702471247224732474247524762477247824792480248124822483248424852486248724882489249024912492249324942495249624972498249925002501250225032504250525062507250825092510251125122513251425152516251725182519252025212522252325242525252625272528252925302531253225332534253525362537253825392540254125422543254425452546254725482549255025512552255325542555255625572558255925602561256225632564256525662567256825692570257125722573257425752576257725782579258025812582258325842585258625872588258925902591259225932594259525962597259825992600260126022603260426052606260726082609261026112612261326142615261626172618261926202621262226232624262526262627262826292630263126322633263426352636263726382639264026412642264326442645264626472648264926502651265226532654265526562657265826592660266126622663266426652666266726682669267026712672267326742675267626772678267926802681268226832684268526862687268826892690269126922693269426952696269726982699270027012702270327042705270627072708270927102711271227132714271527162717271827192720272127222723272427252726272727282729273027312732273327342735273627372738273927402741274227432744274527462747274827492750275127522753275427552756275727582759276027612762276327642765276627672768276927702771277227732774277527762777277827792780278127822783278427852786278727882789279027912792279327942795279627972798279928002801280228032804280528062807280828092810281128122813281428152816281728182819282028212822282328242825282628272828282928302831283228332834283528362837283828392840284128422843284428452846284728482849285028512852285328542855285628572858285928602861286228632864286528662867286828692870287128722873287428752876287728782879288028812882288328842885288628872888288928902891289228932894289528962897289828992900290129022903290429052906290729082909291029112912291329142915291629172918291929202921292229232924292529262927292829292930293129322933293429352936293729382939294029412942294329442945294629472948294929502951295229532954295529562957295829592960296129622963296429652966296729682969297029712972297329742975297629772978297929802981298229832984298529862987298829892990299129922993299429952996299729982999300030013002300330043005300630073008300930103011301230133014301530163017301830193020302130223023302430253026302730283029303030313032303330343035303630373038303930403041304230433044304530463047304830493050305130523053305430553056305730583059306030613062306330643065306630673068306930703071307230733074307530763077307830793080308130823083308430853086308730883089309030913092309330943095309630973098309931003101310231033104310531063107310831093110311131123113311431153116311731183119312031213122312331243125312631273128312931303131313231333134313531363137313831393140314131423143314431453146314731483149315031513152315331543155315631573158315931603161316231633164316531663167316831693170317131723173317431753176317731783179318031813182318331843185318631873188318931903191319231933194319531963197319831993200320132023203320432053206320732083209321032113212321332143215321632173218321932203221322232233224322532263227322832293230323132323233323432353236323732383239324032413242324332443245324632473248324932503251325232533254325532563257325832593260326132623263326432653266326732683269327032713272327332743275327632773278327932803281328232833284328532863287328832893290329132923293329432953296329732983299330033013302330333043305330633073308330933103311331233133314331533163317331833193320332133223323332433253326332733283329333033313332333333343335333633373338333933403341334233433344334533463347334833493350335133523353335433553356335733583359336033613362336333643365336633673368336933703371337233733374337533763377337833793380338133823383338433853386338733883389339033913392339333943395339633973398339934003401340234033404340534063407340834093410341134123413341434153416341734183419342034213422342334243425342634273428342934303431343234333434343534363437343834393440344134423443344434453446344734483449345034513452345334543455345634573458345934603461346234633464346534663467346834693470347134723473347434753476347734783479348034813482348334843485348634873488348934903491349234933494349534963497349834993500350135023503350435053506350735083509351035113512351335143515351635173518351935203521352235233524352535263527352835293530353135323533353435353536353735383539354035413542354335443545354635473548354935503551355235533554355535563557355835593560356135623563356435653566356735683569357035713572357335743575357635773578357935803581358235833584358535863587358835893590359135923593359435953596359735983599360036013602360336043605360636073608360936103611361236133614361536163617361836193620362136223623362436253626362736283629363036313632363336343635363636373638363936403641364236433644364536463647364836493650365136523653365436553656365736583659366036613662366336643665366636673668366936703671367236733674367536763677367836793680368136823683368436853686368736883689369036913692369336943695369636973698369937003701370237033704370537063707370837093710371137123713371437153716371737183719372037213722372337243725372637273728372937303731373237333734373537363737373837393740374137423743374437453746374737483749375037513752375337543755375637573758375937603761376237633764376537663767376837693770377137723773377437753776377737783779378037813782378337843785378637873788378937903791379237933794379537963797379837993800380138023803380438053806380738083809381038113812381338143815381638173818381938203821382238233824382538263827382838293830383138323833383438353836383738383839384038413842384338443845384638473848384938503851385238533854385538563857385838593860386138623863386438653866386738683869387038713872387338743875387638773878387938803881388238833884388538863887388838893890389138923893389438953896389738983899390039013902390339043905390639073908390939103911391239133914391539163917391839193920392139223923392439253926392739283929393039313932393339343935393639373938393939403941394239433944394539463947394839493950395139523953395439553956395739583959396039613962396339643965396639673968396939703971397239733974397539763977397839793980398139823983398439853986398739883989399039913992399339943995399639973998399940004001400240034004400540064007400840094010401140124013401440154016401740184019402040214022402340244025402640274028402940304031403240334034403540364037403840394040404140424043404440454046404740484049405040514052405340544055405640574058405940604061406240634064406540664067406840694070407140724073407440754076407740784079408040814082408340844085408640874088408940904091409240934094409540964097409840994100410141024103410441054106410741084109411041114112411341144115411641174118411941204121412241234124412541264127412841294130413141324133413441354136413741384139414041414142414341444145414641474148414941504151415241534154415541564157415841594160416141624163416441654166416741684169417041714172417341744175417641774178417941804181418241834184418541864187418841894190419141924193419441954196419741984199420042014202420342044205420642074208420942104211421242134214421542164217421842194220422142224223422442254226422742284229423042314232423342344235423642374238423942404241424242434244424542464247424842494250425142524253425442554256425742584259426042614262426342644265426642674268426942704271427242734274427542764277427842794280428142824283428442854286428742884289429042914292429342944295429642974298429943004301430243034304430543064307430843094310431143124313431443154316431743184319432043214322432343244325432643274328432943304331433243334334433543364337433843394340434143424343434443454346434743484349435043514352435343544355435643574358435943604361436243634364436543664367436843694370437143724373437443754376437743784379438043814382438343844385438643874388438943904391439243934394439543964397439843994400440144024403440444054406440744084409441044114412441344144415441644174418441944204421442244234424442544264427442844294430443144324433443444354436443744384439444044414442444344444445444644474448444944504451445244534454445544564457445844594460446144624463446444654466446744684469447044714472447344744475447644774478447944804481448244834484448544864487448844894490449144924493449444954496449744984499450045014502450345044505450645074508450945104511451245134514451545164517451845194520452145224523452445254526452745284529453045314532453345344535453645374538453945404541454245434544454545464547454845494550455145524553455445554556455745584559456045614562456345644565456645674568456945704571457245734574457545764577457845794580458145824583458445854586458745884589459045914592459345944595459645974598459946004601460246034604460546064607460846094610461146124613461446154616461746184619462046214622462346244625462646274628462946304631463246334634463546364637463846394640464146424643464446454646464746484649465046514652465346544655465646574658465946604661466246634664466546664667466846694670467146724673467446754676467746784679468046814682468346844685468646874688468946904691469246934694469546964697469846994700470147024703470447054706470747084709471047114712471347144715471647174718471947204721472247234724472547264727472847294730473147324733473447354736473747384739474047414742474347444745474647474748474947504751475247534754475547564757475847594760476147624763476447654766476747684769477047714772477347744775477647774778477947804781478247834784478547864787478847894790479147924793479447954796479747984799480048014802480348044805480648074808480948104811481248134814481548164817481848194820482148224823482448254826482748284829483048314832483348344835483648374838483948404841484248434844484548464847484848494850485148524853485448554856485748584859486048614862486348644865486648674868486948704871487248734874487548764877487848794880488148824883488448854886488748884889489048914892489348944895489648974898489949004901490249034904490549064907490849094910491149124913491449154916491749184919492049214922492349244925492649274928492949304931493249334934493549364937493849394940494149424943494449454946494749484949495049514952495349544955495649574958495949604961496249634964496549664967496849694970497149724973497449754976497749784979498049814982498349844985498649874988498949904991499249934994499549964997499849995000500150025003500450055006500750085009501050115012501350145015501650175018501950205021502250235024502550265027502850295030503150325033503450355036503750385039504050415042504350445045504650475048504950505051505250535054505550565057505850595060506150625063506450655066506750685069507050715072507350745075507650775078507950805081508250835084508550865087508850895090509150925093509450955096509750985099510051015102510351045105510651075108510951105111511251135114511551165117511851195120512151225123512451255126512751285129513051315132513351345135513651375138513951405141514251435144514551465147514851495150515151525153515451555156515751585159516051615162516351645165516651675168516951705171517251735174517551765177517851795180518151825183518451855186518751885189519051915192519351945195519651975198519952005201520252035204520552065207520852095210521152125213521452155216521752185219522052215222522352245225522652275228522952305231523252335234523552365237523852395240524152425243524452455246524752485249525052515252525352545255525652575258525952605261526252635264526552665267526852695270527152725273527452755276527752785279528052815282528352845285528652875288528952905291529252935294529552965297529852995300530153025303530453055306530753085309531053115312531353145315531653175318531953205321532253235324532553265327532853295330533153325333533453355336533753385339534053415342534353445345534653475348534953505351535253535354535553565357535853595360536153625363536453655366536753685369537053715372537353745375537653775378537953805381538253835384538553865387538853895390539153925393539453955396539753985399540054015402540354045405540654075408540954105411541254135414541554165417541854195420542154225423542454255426542754285429543054315432543354345435543654375438543954405441544254435444544554465447544854495450545154525453545454555456545754585459546054615462546354645465546654675468546954705471547254735474547554765477547854795480548154825483548454855486548754885489549054915492549354945495549654975498549955005501550255035504550555065507550855095510551155125513551455155516551755185519552055215522552355245525552655275528552955305531553255335534553555365537553855395540554155425543554455455546554755485549555055515552555355545555555655575558555955605561556255635564556555665567556855695570557155725573557455755576557755785579558055815582558355845585558655875588558955905591559255935594559555965597559855995600560156025603560456055606560756085609561056115612561356145615561656175618561956205621562256235624562556265627562856295630563156325633563456355636563756385639564056415642564356445645564656475648564956505651565256535654565556565657565856595660566156625663566456655666566756685669567056715672567356745675567656775678567956805681568256835684568556865687568856895690569156925693569456955696569756985699570057015702570357045705570657075708570957105711571257135714571557165717571857195720572157225723572457255726572757285729573057315732573357345735573657375738573957405741574257435744574557465747574857495750575157525753575457555756575757585759576057615762576357645765576657675768576957705771577257735774577557765777577857795780578157825783578457855786578757885789579057915792579357945795579657975798579958005801580258035804580558065807580858095810581158125813581458155816581758185819582058215822582358245825582658275828582958305831583258335834583558365837583858395840584158425843584458455846584758485849585058515852585358545855585658575858585958605861586258635864586558665867586858695870587158725873587458755876587758785879588058815882588358845885588658875888588958905891589258935894589558965897589858995900590159025903590459055906590759085909591059115912591359145915591659175918591959205921592259235924592559265927592859295930593159325933593459355936593759385939594059415942594359445945594659475948594959505951595259535954595559565957595859595960596159625963596459655966596759685969597059715972597359745975597659775978597959805981598259835984598559865987598859895990599159925993599459955996599759985999600060016002600360046005600660076008600960106011601260136014601560166017601860196020602160226023602460256026602760286029603060316032603360346035603660376038603960406041604260436044604560466047604860496050605160526053605460556056605760586059606060616062606360646065606660676068606960706071607260736074607560766077607860796080608160826083608460856086608760886089609060916092609360946095609660976098609961006101610261036104610561066107610861096110611161126113611461156116611761186119612061216122612361246125612661276128612961306131613261336134613561366137613861396140614161426143614461456146614761486149615061516152615361546155615661576158615961606161616261636164616561666167616861696170617161726173617461756176617761786179618061816182618361846185618661876188618961906191619261936194619561966197619861996200620162026203620462056206620762086209621062116212621362146215621662176218621962206221622262236224622562266227622862296230623162326233623462356236623762386239624062416242624362446245624662476248624962506251625262536254625562566257625862596260626162626263626462656266626762686269627062716272627362746275627662776278627962806281628262836284628562866287628862896290629162926293629462956296629762986299630063016302630363046305630663076308630963106311631263136314631563166317631863196320632163226323632463256326632763286329633063316332633363346335633663376338633963406341634263436344634563466347634863496350635163526353635463556356635763586359636063616362636363646365636663676368636963706371637263736374637563766377637863796380638163826383638463856386638763886389639063916392639363946395639663976398639964006401640264036404640564066407640864096410641164126413641464156416641764186419642064216422642364246425642664276428642964306431643264336434643564366437643864396440644164426443644464456446644764486449645064516452645364546455645664576458645964606461646264636464646564666467646864696470647164726473647464756476647764786479648064816482648364846485648664876488648964906491649264936494649564966497649864996500650165026503650465056506650765086509651065116512651365146515651665176518651965206521652265236524652565266527652865296530653165326533653465356536653765386539654065416542654365446545654665476548654965506551655265536554655565566557655865596560656165626563656465656566656765686569657065716572657365746575657665776578657965806581658265836584658565866587658865896590659165926593659465956596659765986599660066016602660366046605660666076608660966106611661266136614661566166617661866196620662166226623662466256626662766286629663066316632663366346635663666376638663966406641664266436644664566466647664866496650665166526653665466556656665766586659666066616662666366646665666666676668666966706671667266736674667566766677667866796680668166826683668466856686668766886689669066916692669366946695669666976698669967006701670267036704670567066707670867096710671167126713671467156716671767186719672067216722672367246725672667276728672967306731673267336734673567366737673867396740674167426743674467456746674767486749675067516752675367546755675667576758675967606761676267636764676567666767676867696770677167726773677467756776677767786779678067816782678367846785678667876788678967906791679267936794679567966797679867996800680168026803680468056806680768086809681068116812681368146815681668176818681968206821682268236824682568266827682868296830683168326833683468356836683768386839684068416842684368446845684668476848684968506851685268536854685568566857685868596860686168626863686468656866686768686869687068716872687368746875687668776878687968806881688268836884688568866887688868896890689168926893689468956896689768986899690069016902690369046905690669076908690969106911691269136914691569166917691869196920692169226923692469256926692769286929693069316932693369346935693669376938693969406941694269436944694569466947694869496950695169526953695469556956695769586959696069616962696369646965696669676968696969706971697269736974697569766977697869796980698169826983698469856986698769886989699069916992699369946995699669976998699970007001700270037004700570067007700870097010701170127013701470157016701770187019702070217022702370247025702670277028702970307031703270337034703570367037703870397040704170427043704470457046704770487049705070517052705370547055705670577058705970607061706270637064706570667067706870697070707170727073707470757076707770787079708070817082708370847085708670877088708970907091709270937094709570967097709870997100710171027103710471057106710771087109711071117112711371147115711671177118711971207121712271237124712571267127712871297130713171327133713471357136713771387139714071417142714371447145714671477148714971507151715271537154715571567157715871597160716171627163716471657166716771687169717071717172717371747175717671777178717971807181718271837184718571867187718871897190719171927193719471957196719771987199720072017202720372047205720672077208720972107211721272137214721572167217721872197220722172227223722472257226722772287229723072317232723372347235723672377238723972407241724272437244724572467247724872497250725172527253725472557256725772587259726072617262726372647265726672677268726972707271727272737274727572767277727872797280728172827283728472857286728772887289729072917292729372947295729672977298729973007301730273037304730573067307730873097310731173127313731473157316731773187319732073217322732373247325732673277328732973307331733273337334733573367337733873397340734173427343734473457346734773487349735073517352735373547355735673577358735973607361736273637364736573667367736873697370737173727373737473757376737773787379738073817382738373847385738673877388738973907391739273937394739573967397739873997400740174027403740474057406740774087409741074117412741374147415741674177418741974207421742274237424742574267427742874297430743174327433743474357436743774387439744074417442744374447445744674477448744974507451745274537454745574567457745874597460746174627463746474657466746774687469747074717472747374747475747674777478747974807481748274837484748574867487748874897490749174927493749474957496749774987499750075017502750375047505750675077508750975107511751275137514751575167517751875197520752175227523752475257526752775287529753075317532753375347535753675377538753975407541754275437544754575467547754875497550755175527553755475557556755775587559756075617562756375647565756675677568756975707571757275737574757575767577757875797580758175827583758475857586758775887589759075917592759375947595759675977598759976007601760276037604760576067607760876097610761176127613761476157616761776187619762076217622762376247625762676277628762976307631763276337634763576367637763876397640764176427643764476457646764776487649765076517652765376547655765676577658765976607661766276637664766576667667766876697670767176727673767476757676767776787679768076817682768376847685768676877688768976907691769276937694769576967697769876997700770177027703
  1. {
  2. This file is part of the Free Pascal Integrated Development Environment
  3. Copyright (c) 1998 by Berczi Gabor
  4. Code editor template objects
  5. See the file COPYING.FPC, included in this distribution,
  6. for details about the copyright.
  7. This program is distributed in the hope that it will be useful,
  8. but WITHOUT ANY WARRANTY; without even the implied warranty of
  9. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
  10. **********************************************************************}
  11. {$I globdir.inc}
  12. {$ifdef TP}{$L-}{$endif}
  13. unit WEditor;
  14. interface
  15. {tes}
  16. uses
  17. Dos,Objects,Drivers,Views,Menus,
  18. {$ifdef FVISION}
  19. FVConsts,
  20. {$else}
  21. Commands,
  22. {$endif}
  23. WUtils;
  24. const
  25. cmFileNameChanged = 51234;
  26. cmASCIIChar = 51235;
  27. cmClearLineHighlights = 51236;
  28. cmSaveCancelled = 51237;
  29. cmBreakLine = 51238;
  30. cmSelStart = 51239;
  31. cmSelEnd = 51240;
  32. cmLastCursorPos = 51241;
  33. cmIndentBlock = 51242;
  34. cmUnIndentBlock = 51243;
  35. cmSelectLine = 51244;
  36. cmWriteBlock = 51245;
  37. cmReadBlock = 51246;
  38. cmPrintBlock = 51247;
  39. cmResetDebuggerRow = 51248;
  40. cmAddChar = 51249;
  41. cmExpandCodeTemplate = 51250;
  42. cmUpperCase = 51251;
  43. cmLowerCase = 51252;
  44. cmWindowStart = 51253;
  45. cmWindowEnd = 51254;
  46. cmFindMatchingDelimiter= 51255;
  47. cmFindMatchingDelimiterBack=51256;
  48. cmActivateMenu = 51257;
  49. cmWordLowerCase = 51258;
  50. cmWordUpperCase = 51259;
  51. cmOpenAtCursor = 51260;
  52. cmBrowseAtCursor = 51261;
  53. cmInsertOptions = 51262;
  54. cmToggleCase = 51263;
  55. cmCreateFold = 51264;
  56. cmToggleFold = 51265;
  57. cmCollapseFold = 51266;
  58. cmExpandFold = 51267;
  59. cmDelToEndOfWord = 51268;
  60. EditorTextBufSize = {$ifdef FPC}32768{$else} 4096{$endif};
  61. MaxLineLength = 255;
  62. MaxLineCount = {$ifdef FPC}2000000{$else}16380{$endif};
  63. CodeCompleteMinLen = 4; { minimum length of text to try to complete }
  64. CodeTemplateCursorChar = '|'; { char to signal cursor pos in templates }
  65. efBackupFiles = $00000001;
  66. efInsertMode = $00000002;
  67. efAutoIndent = $00000004;
  68. efUseTabCharacters = $00000008;
  69. efBackSpaceUnindents = $00000010;
  70. efPersistentBlocks = $00000020;
  71. efSyntaxHighlight = $00000040;
  72. efBlockInsCursor = $00000080;
  73. efVerticalBlocks = $00000100;
  74. efHighlightColumn = $00000200;
  75. efHighlightRow = $00000400;
  76. efAutoBrackets = $00000800;
  77. efExpandAllTabs = $00001000;
  78. efKeepTrailingSpaces = $00002000;
  79. efCodeComplete = $00004000;
  80. efFolds = $00008000;
  81. efNoIndent = $00010000;
  82. efKeepLineAttr = $00020000;
  83. efStoreContent = $80000000;
  84. attrAsm = 1;
  85. attrComment = 2;
  86. attrForceFull = 128;
  87. attrAll = attrAsm+attrComment;
  88. edOutOfMemory = 0;
  89. edReadError = 1;
  90. edWriteError = 2;
  91. edCreateError = 3;
  92. edSaveModify = 4;
  93. edSaveUntitled = 5;
  94. edSaveAs = 6;
  95. edFind = 7;
  96. edSearchFailed = 8;
  97. edReplace = 9;
  98. edReplacePrompt = 10;
  99. edTooManyLines = 11;
  100. edGotoLine = 12;
  101. edReplaceFile = 13;
  102. edWriteBlock = 14;
  103. edReadBlock = 15;
  104. edFileOnDiskChanged = 16;
  105. edChangedOnloading = 17;
  106. edSaveError = 18;
  107. edReloadDiskmodifiedFile = 19;
  108. edReloadDiskAndIDEModifiedFile = 20;
  109. ffmOptions = $0007; ffsOptions = 0;
  110. ffmDirection = $0008; ffsDirection = 3;
  111. ffmScope = $0010; ffsScope = 4;
  112. ffmOrigin = $0020; ffsOrigin = 5;
  113. ffDoReplace = $0040;
  114. ffReplaceAll = $0080;
  115. ffCaseSensitive = $0001;
  116. ffWholeWordsOnly = $0002;
  117. ffPromptOnReplace = $0004;
  118. ffForward = $0000;
  119. ffBackward = $0008;
  120. ffGlobal = $0000;
  121. ffSelectedText = $0010;
  122. ffFromCursor = $0000;
  123. ffEntireScope = $0020;
  124. {$ifdef TEST_REGEXP}
  125. ffUseRegExp = $0100;
  126. ffmUseRegExpFind = $0004;
  127. ffmOptionsFind = $0003;
  128. ffsUseRegExpFind = 8 - 2;
  129. ffmUseRegExpReplace = $0008;
  130. ffsUseRegExpReplace = 8 - 3;
  131. {$endif TEST_REGEXP}
  132. coTextColor = 0;
  133. coWhiteSpaceColor = 1;
  134. coCommentColor = 2;
  135. coReservedWordColor = 3;
  136. coIdentifierColor = 4;
  137. coStringColor = 5;
  138. coNumberColor = 6;
  139. coAssemblerColor = 7;
  140. coSymbolColor = 8;
  141. coDirectiveColor = 9;
  142. coHexNumberColor = 10;
  143. coTabColor = 11;
  144. coAsmReservedColor = 12;
  145. coBreakColor = 13;
  146. coFirstColor = 0;
  147. coLastColor = coBreakColor;
  148. lfBreakpoint = $0001;
  149. lfHighlightRow = $0002;
  150. lfDebuggerRow = $0004;
  151. lfSpecialRow = $0008;
  152. eaMoveCursor = 1;
  153. eaInsertLine = 2;
  154. eaInsertText = 3;
  155. eaDeleteLine = 4;
  156. eaDeleteText = 5;
  157. eaSelectionChanged = 6;
  158. eaCut = 7;
  159. eaPaste = 8;
  160. eaPasteWin = 9;
  161. eaDelChar = 10;
  162. eaClear = 11;
  163. eaCopyBlock = 12;
  164. eaMoveBlock = 13;
  165. eaDelBlock = 14;
  166. eaReadBlock = 15;
  167. eaIndentBlock = 16;
  168. eaUnindentBlock = 17;
  169. eaOverwriteText = 18;
  170. eaUpperCase = 19;
  171. eaLowerCase = 20;
  172. eaToggleCase = 21;
  173. eaDummy = 22;
  174. LastAction = eaDummy;
  175. ActionString : array [0..LastAction-1] of string[13] =
  176. ('','Move','InsLine','InsText','DelLine','DelText',
  177. 'SelChange','Cut','Paste','PasteWin','DelChar','Clear',
  178. 'CopyBlock','MoveBlock','DelBlock',
  179. 'ReadBlock','IndentBlock','UnindentBlock','Overwrite',
  180. 'UpperCase','LowerCase','ToggleCase');
  181. CIndicator = #2#3#1;
  182. CEditor = #33#34#35#36#37#38#39#40#41#42#43#44#45#46#47#48#49#50;
  183. TAB = #9;
  184. FindStrSize = 79;
  185. type
  186. PCustomCodeEditor = ^TCustomCodeEditor;
  187. PEditorLineInfo = ^TEditorLineInfo;
  188. PFoldCollection = ^TFoldCollection;
  189. PFold = ^TFold;
  190. TFold = object(TObject)
  191. constructor Init(AEditor: PCustomCodeEditor; AParentFold: PFold; ACollapsed: boolean);
  192. procedure AddReference(P: PObject);
  193. procedure RemoveReference(P: PObject);
  194. procedure AddLineReference(Line: PEditorLineInfo);
  195. procedure RemoveLineReference(Line: PEditorLineInfo);
  196. procedure AddChildReference(Fold: PFold);
  197. procedure RemoveChildReference(Fold: PFold);
  198. function CanDispose: boolean;
  199. function IsCollapsed: boolean;
  200. function IsParent(AFold: PFold): boolean;
  201. function GetLineCount: sw_integer;
  202. procedure Collapse(ACollapse: boolean);
  203. procedure Changed;
  204. function GetLevel: sw_integer;
  205. destructor Done; virtual;
  206. public
  207. ParentFold: PFold;
  208. Collapsed_: boolean;
  209. ReferenceCount: sw_integer;
  210. Editor: PCustomCodeEditor;
  211. LineCount_: sw_integer;
  212. Childs: PFoldCollection;
  213. end;
  214. TFoldCollection = object(TCollection)
  215. function At(Index: sw_Integer): PFold;
  216. end;
  217. TEditorLineInfo = object(TObject)
  218. Editor: PCustomCodeEditor;
  219. Format : PString;
  220. BeginsWithAsm,
  221. EndsWithAsm : boolean;
  222. BeginsWithComment,
  223. EndsInSingleLineComment,
  224. EndsWithComment : boolean;
  225. BeginsWithDirective,
  226. EndsWithDirective : boolean;
  227. BeginCommentType,EndCommentType : byte;
  228. Fold: PFold;
  229. constructor Init(AEditor: PCustomCodeEditor);
  230. destructor Done; virtual;
  231. function GetFormat: string;
  232. procedure SetFormat(const AFormat: string);
  233. procedure SetFold(AFold: PFold);
  234. { Syntax information is now generated separately for each editor instance.
  235. This is not neccessary for a one-language IDE, but this unit contains
  236. a _generic_ editor object, which should be (and is) as flexible as
  237. possible.
  238. The overhead caused by generating the same syntax info for ex.
  239. twice isn't so much... - Gabor }
  240. end;
  241. PEditorLineInfoCollection = ^TEditorLineInfoCollection;
  242. TEditorLineInfoCollection = object(TCollection)
  243. function At(Index: sw_Integer): PEditorLineInfo;
  244. end;
  245. PCustomLine = ^TCustomLine;
  246. TCustomLine = object(TObject)
  247. constructor Init(const AText: string; AFlags: longint);
  248. {a}function GetText: string; virtual;
  249. {a}procedure SetText(const AText: string); virtual;
  250. {a}function GetEditorInfo(Editor: PCustomCodeEditor): PEditorLineInfo; virtual;
  251. {a}function GetFlags: longint; virtual;
  252. {a}procedure SetFlags(AFlags: longint); virtual;
  253. function IsFlagSet(AFlag: longint): boolean;
  254. procedure SetFlagState(AFlag: longint; ASet: boolean);
  255. destructor Done; virtual;
  256. public { internal use only! }
  257. {a}procedure AddEditorInfo(Index: sw_integer; AEditor: PCustomCodeEditor); virtual;
  258. {a}procedure RemoveEditorInfo(AEditor: PCustomCodeEditor); virtual;
  259. end;
  260. PLineCollection = ^TLineCollection;
  261. TLineCollection = object(TCollection)
  262. function At(Index: sw_Integer): PCustomLine;
  263. end;
  264. PEditorAction = ^TEditorAction;
  265. TEditorAction = object(TObject)
  266. StartPos : TPoint;
  267. EndPos : TPoint;
  268. Text : PString;
  269. ActionCount : longint;
  270. Flags : longint;
  271. Action : byte;
  272. IsGrouped : boolean;
  273. TimeStamp : longint; { this is needed to keep track of line number &
  274. position changes (for ex. for symbol browser)
  275. the line&pos references (eg. symbol info) should
  276. also contain such a timestamp. this will enable
  277. to determine which changes have been made since
  278. storage of the information and thus calculate
  279. the (probably) changed line & position information,
  280. so, we can still jump to the right position in the
  281. editor even when it is heavily modified - Gabor }
  282. constructor init(act:byte; StartP,EndP:TPoint;Txt:String;AFlags : longint);
  283. constructor init_group(act:byte);
  284. function is_grouped_action : boolean;
  285. destructor done; virtual;
  286. end;
  287. PEditorActionCollection = ^TEditorActionCollection;
  288. TEditorActionCollection = object(TCollection)
  289. CurrentGroupedAction : PEditorAction;
  290. GroupLevel : longint;
  291. function At(Idx : sw_integer) : PEditorAction;
  292. end;
  293. TSpecSymbolClass =
  294. (ssCommentPrefix,ssCommentSingleLinePrefix,ssCommentSuffix,ssStringPrefix,ssStringSuffix,
  295. ssDirectivePrefix,ssDirectiveSuffix,ssAsmPrefix,ssAsmSuffix);
  296. TEditorBookMark = record
  297. Valid : boolean;
  298. Pos : TPoint;
  299. end;
  300. TCompleteState = (csInactive,csOffering,csDenied);
  301. PEditorBinding = ^TEditorBinding;
  302. PEditorBindingCollection = ^TEditorBindingCollection;
  303. TEditorBindingCollection = object(TCollection)
  304. function At(Index: sw_Integer): PEditorBinding;
  305. end;
  306. TEditorBinding = object(TObject)
  307. Editor : PCustomCodeEditor;
  308. constructor Init(AEditor: PCustomCodeEditor);
  309. destructor Done; virtual;
  310. end;
  311. PCustomCodeEditorCore = ^TCustomCodeEditorCore;
  312. TCustomCodeEditorCore = object(TObject)
  313. {$ifdef TP}public{$else}protected{$endif}
  314. Bindings : PEditorBindingCollection;
  315. LockFlag : sw_integer;
  316. ChangedLine : sw_integer;
  317. ContentsChangedCalled : boolean;
  318. LimitsChangedCalled : boolean;
  319. ModifiedChangedCalled : boolean;
  320. TabSizeChangedCalled : boolean;
  321. StoreUndoChangedCalled : boolean;
  322. {$ifdef TEST_PARTIAL_SYNTAX}
  323. LastSyntaxedLine : sw_integer;
  324. SyntaxComplete : boolean;
  325. {$endif TEST_PARTIAL_SYNTAX}
  326. public
  327. constructor Init;
  328. procedure BindEditor(AEditor: PCustomCodeEditor);
  329. procedure UnBindEditor(AEditor: PCustomCodeEditor);
  330. function IsEditorBound(AEditor: PCustomCodeEditor): boolean;
  331. function GetBindingCount: sw_integer;
  332. function GetBindingIndex(AEditor: PCustomCodeEditor): sw_integer;
  333. function SearchBinding(AEditor: PCustomCodeEditor): PEditorBinding;
  334. function CanDispose: boolean;
  335. destructor Done; virtual;
  336. public
  337. {a}function GetModified: boolean; virtual;
  338. function GetChangedLine: sw_integer;
  339. {a}procedure SetModified(AModified: boolean); virtual;
  340. {a}function GetStoreUndo: boolean; virtual;
  341. {a}procedure SetStoreUndo(AStore: boolean); virtual;
  342. {a}function GetSyntaxCompleted: boolean; virtual;
  343. {a}procedure SetSyntaxCompleted(SC: boolean); virtual;
  344. {a}function GetTabSize: integer; virtual;
  345. {a}procedure SetTabSize(ATabSize: integer); virtual;
  346. {a}function GetIndentSize: integer; virtual;
  347. {a}procedure SetIndentSize(AIndentSize: integer); virtual;
  348. function IsClipboard: Boolean;
  349. public
  350. { Notifications }
  351. procedure BindingsChanged;
  352. procedure ContentsChanged;
  353. procedure LimitsChanged;
  354. procedure ModifiedChanged;
  355. procedure TabSizeChanged;
  356. procedure StoreUndoChanged;
  357. {a}procedure DoContentsChanged; virtual;
  358. {a}procedure DoLimitsChanged; virtual;
  359. {a}procedure DoModifiedChanged; virtual;
  360. {a}procedure DoTabSizeChanged; virtual;
  361. {a}procedure DoStoreUndoChanged; virtual;
  362. {a}procedure DoSyntaxStateChanged; virtual;
  363. function GetLastVisibleLine : sw_integer;
  364. public
  365. { Storage }
  366. function LoadFromStream(Editor: PCustomCodeEditor; Stream: PStream): boolean; virtual;
  367. function SaveToStream(Editor: PCustomCodeEditor; Stream: PStream): boolean; virtual;
  368. function SaveAreaToStream(Editor: PCustomCodeEditor; Stream: PStream; StartP,EndP: TPoint): boolean; virtual;
  369. {$ifdef TP}public{$else}protected{$endif}
  370. { Text & info storage abstraction }
  371. {a}procedure ISetLineFlagState(Binding: PEditorBinding; LineNo: sw_integer; Flag: longint; ASet: boolean); virtual;
  372. {a}procedure IGetDisplayTextFormat(Binding: PEditorBinding; LineNo: sw_integer;var DT,DF:string); virtual;
  373. {a}function IGetLineFormat(Binding: PEditorBinding; LineNo: sw_integer): string; virtual;
  374. {a}procedure ISetLineFormat(Binding: PEditorBinding; LineNo: sw_integer;const S: string); virtual;
  375. public
  376. { Text & info storage abstraction }
  377. function CharIdxToLinePos(Line,CharIdx: sw_integer): sw_integer;
  378. function LinePosToCharIdx(Line,X: sw_integer): sw_integer;
  379. {a}function GetLineCount: sw_integer; virtual;
  380. {a}function GetLine(LineNo: sw_integer): PCustomLine; virtual;
  381. {a}function GetLineText(LineNo: sw_integer): string; virtual;
  382. {a}procedure SetDisplayText(I: sw_integer;const S: string); virtual;
  383. {a}function GetDisplayText(I: sw_integer): string; virtual;
  384. {a}procedure SetLineText(I: sw_integer;const S: string); virtual;
  385. procedure GetDisplayTextFormat(Editor: PCustomCodeEditor; I: sw_integer;var DT,DF:string); virtual;
  386. function GetLineFormat(Editor: PCustomCodeEditor; I: sw_integer): string; virtual;
  387. procedure SetLineFormat(Editor: PCustomCodeEditor; I: sw_integer;const S: string); virtual;
  388. {a}procedure DeleteAllLines; virtual;
  389. {a}procedure DeleteLine(I: sw_integer); virtual;
  390. {a}function InsertLine(LineNo: sw_integer; const S: string): PCustomLine; virtual;
  391. {a}procedure AddLine(const S: string); virtual;
  392. {a}procedure GetContent(ALines: PUnsortedStringCollection); virtual;
  393. {a}procedure SetContent(ALines: PUnsortedStringCollection); virtual;
  394. public
  395. procedure Lock(AEditor: PCustomCodeEditor);
  396. procedure UnLock(AEditor: PCustomCodeEditor);
  397. function Locked: boolean;
  398. public
  399. { Syntax highlight }
  400. function UpdateAttrs(FromLine: sw_integer; Attrs: byte): sw_integer; virtual;
  401. function UpdateAttrsRange(FromLine, ToLine: sw_integer; Attrs: byte): sw_integer; virtual;
  402. function DoUpdateAttrs(Editor: PCustomCodeEditor; FromLine: sw_integer; Attrs: byte): sw_integer; virtual;
  403. function DoUpdateAttrsRange(Editor: PCustomCodeEditor; FromLine, ToLine: sw_integer;
  404. Attrs: byte): sw_integer; virtual;
  405. public
  406. { Undo info storage }
  407. {a}procedure AddAction(AAction: byte; AStartPos, AEndPos: TPoint; AText: string;AFlags : longint); virtual;
  408. {a}procedure AddGroupedAction(AAction : byte); virtual;
  409. {a}procedure CloseGroupedAction(AAction : byte); virtual;
  410. {a}function GetUndoActionCount: sw_integer; virtual;
  411. {a}function GetRedoActionCount: sw_integer; virtual;
  412. procedure UpdateUndoRedo(cm : word; action : byte);virtual;
  413. end;
  414. TCaseAction = (caToLowerCase,caToUpperCase,caToggleCase);
  415. TCustomCodeEditor = object(TScroller)
  416. SelStart : TPoint;
  417. SelEnd : TPoint;
  418. Highlight : TRect;
  419. CurPos : TPoint;
  420. ELockFlag : integer;
  421. NoSelect : Boolean;
  422. AlwaysShowScrollBars: boolean;
  423. public
  424. { constructor Load(var S: TStream);
  425. procedure Store(var S: TStream);}
  426. procedure ConvertEvent(var Event: TEvent); virtual;
  427. procedure HandleEvent(var Event: TEvent); virtual;
  428. procedure SetState(AState: Word; Enable: Boolean); virtual;
  429. procedure LocalMenu(P: TPoint); virtual;
  430. function GetLocalMenu: PMenu; virtual;
  431. function GetCommandTarget: PView; virtual;
  432. function CreateLocalMenuView(var Bounds: TRect; M: PMenu): PMenuPopup; virtual;
  433. function GetPalette: PPalette; virtual;
  434. public
  435. procedure Draw; virtual;
  436. procedure DrawCursor; virtual;
  437. {$ifdef USE_FREEVISION}
  438. { this is the only way I found to avoid
  439. having the cursor being updated if lock is on PM }
  440. procedure ResetCursor; virtual;
  441. {$endif USE_FREEVISION}
  442. procedure DrawIndicator; virtual;
  443. public
  444. {a}function GetFlags: longint; virtual;
  445. {a}procedure SetFlags(AFlags: longint); virtual;
  446. {a}function GetModified: boolean; virtual;
  447. {a}procedure SetModified(AModified: boolean); virtual;
  448. {a}function GetStoreUndo: boolean; virtual;
  449. {a}procedure SetStoreUndo(AStore: boolean); virtual;
  450. {a}function GetSyntaxCompleted: boolean; virtual;
  451. {a}procedure SetSyntaxCompleted(SC: boolean); virtual;
  452. {a}function GetLastSyntaxedLine: sw_integer; virtual;
  453. {a}procedure SetLastSyntaxedLine(ALine: sw_integer); virtual;
  454. function IsFlagSet(AFlag: longint): boolean;
  455. function GetReservedColCount: sw_integer; virtual;
  456. {a}function GetTabSize: integer; virtual;
  457. {a}procedure SetTabSize(ATabSize: integer); virtual;
  458. {a}function GetIndentSize: integer; virtual;
  459. {a}procedure SetIndentSize(AIndentSize: integer); virtual;
  460. {a}function IsReadOnly: boolean; virtual;
  461. {a}function IsClipboard: Boolean; virtual;
  462. {a}function GetInsertMode: boolean; virtual;
  463. {a}procedure SetInsertMode(InsertMode: boolean); virtual;
  464. procedure SetCurPtr(X,Y: sw_integer); virtual;
  465. procedure GetSelectionArea(var StartP,EndP: TPoint); virtual;
  466. procedure SetSelection(A, B: TPoint); virtual;
  467. procedure SetHighlight(A, B: TPoint); virtual;
  468. procedure ChangeCaseArea(StartP,EndP: TPoint; CaseAction: TCaseAction); virtual;
  469. procedure SetLineFlagState(LineNo: sw_integer; Flags: longint; ASet: boolean);
  470. procedure SetLineFlagExclusive(Flags: longint; LineNo: sw_integer);
  471. procedure Update; virtual;
  472. procedure ScrollTo(X, Y: sw_Integer);
  473. procedure TrackCursor(Center: boolean); virtual;
  474. procedure Lock; virtual;
  475. procedure UnLock; virtual;
  476. public
  477. { Text & info storage abstraction }
  478. {a}function GetLineCount: sw_integer; virtual;
  479. {a}function GetLine(LineNo: sw_integer): PCustomLine; virtual;
  480. {a}function CharIdxToLinePos(Line,CharIdx: sw_integer): sw_integer; virtual;
  481. {a}function LinePosToCharIdx(Line,X: sw_integer): sw_integer; virtual;
  482. {a}function GetLineText(I: sw_integer): string; virtual;
  483. {a}procedure SetDisplayText(I: sw_integer;const S: string); virtual;
  484. {a}function GetDisplayText(I: sw_integer): string; virtual;
  485. {a}procedure SetLineText(I: sw_integer;const S: string); virtual;
  486. {a}procedure GetDisplayTextFormat(I: sw_integer;var DT,DF:string); virtual;
  487. {a}function GetLineFormat(I: sw_integer): string; virtual;
  488. {a}procedure SetLineFormat(I: sw_integer;const S: string); virtual;
  489. {a}procedure DeleteAllLines; virtual;
  490. {a}procedure DeleteLine(I: sw_integer); virtual;
  491. {a}function InsertLine(LineNo: sw_integer; const S: string): PCustomLine; virtual;
  492. {a}procedure AddLine(const S: string); virtual;
  493. {a}function GetErrorMessage: string; virtual;
  494. {a}procedure SetErrorMessage(const S: string); virtual;
  495. {a}procedure AdjustSelection(DeltaX, DeltaY: sw_integer);
  496. {a}procedure AdjustSelectionPos(CurPosX, CurPosY: sw_integer; DeltaX, DeltaY: sw_integer);
  497. {a}procedure GetContent(ALines: PUnsortedStringCollection); virtual;
  498. {a}procedure SetContent(ALines: PUnsortedStringCollection); virtual;
  499. {a}function LoadFromStream(Stream: PStream): boolean; virtual;
  500. {a}function SaveToStream(Stream: PStream): boolean; virtual;
  501. {a}function SaveAreaToStream(Stream: PStream; StartP,EndP: TPoint): boolean;virtual;
  502. function LoadFromFile(const AFileName: string): boolean; virtual;
  503. function SaveToFile(const AFileName: string): boolean; virtual;
  504. public
  505. {a}function InsertFrom(Editor: PCustomCodeEditor): Boolean; virtual;
  506. {a}function InsertText(const S: string): Boolean; virtual;
  507. public
  508. procedure FlagsChanged(OldFlags: longint); virtual;
  509. {a}procedure BindingsChanged; virtual;
  510. procedure ContentsChanged; virtual;
  511. procedure LimitsChanged; virtual;
  512. procedure ModifiedChanged; virtual;
  513. procedure PositionChanged; virtual;
  514. procedure TabSizeChanged; virtual;
  515. procedure SyntaxStateChanged; virtual;
  516. procedure StoreUndoChanged; virtual;
  517. procedure SelectionChanged; virtual;
  518. procedure HighlightChanged; virtual;
  519. {a}procedure DoLimitsChanged; virtual;
  520. public
  521. { Syntax highlight support }
  522. {a}function GetSpecSymbolCount(SpecClass: TSpecSymbolClass): integer; virtual;
  523. {a}function GetSpecSymbol(SpecClass: TSpecSymbolClass; Index: integer): string; virtual;
  524. {a}function IsReservedWord(const S: string): boolean; virtual;
  525. {a}function IsAsmReservedWord(const S: string): boolean; virtual;
  526. public
  527. { CodeTemplate support }
  528. {a}function TranslateCodeTemplate(const Shortcut: string; ALines: PUnsortedStringCollection): boolean; virtual;
  529. function SelectCodeTemplate(var ShortCut: string): boolean; virtual;
  530. { CodeComplete support }
  531. {a}function CompleteCodeWord(const WordS: string; var Text: string): boolean; virtual;
  532. {a}function GetCodeCompleteWord: string; virtual;
  533. {a}procedure SetCodeCompleteWord(const S: string); virtual;
  534. {a}function GetCodeCompleteFrag: string; virtual;
  535. {a}procedure SetCodeCompleteFrag(const S: string); virtual;
  536. function GetCompleteState: TCompleteState; virtual;
  537. procedure SetCompleteState(AState: TCompleteState); virtual;
  538. procedure ClearCodeCompleteWord; virtual;
  539. { Fold support }
  540. function GetMaxFoldLevel: sw_integer; virtual;
  541. function GetFoldStringWidth: sw_integer; virtual;
  542. procedure GetFoldStrings(EditorLine: sw_integer; var Prefix, Suffix: openstring); virtual;
  543. {a}function GetFoldCount: sw_integer; virtual;
  544. {a}function GetFold(Index: sw_integer): PFold; virtual;
  545. {a}procedure RegisterFold(AFold: PFold); virtual;
  546. {a}procedure UnRegisterFold(AFold: PFold); virtual;
  547. function ViewToEditorLine(ViewLine: sw_integer): sw_integer;
  548. function EditorToViewLine(EditorLine: sw_integer): sw_integer;
  549. procedure ViewToEditorPoint(P: TPoint; var NP: TPoint);
  550. procedure EditorToViewPoint(P: TPoint; var NP: TPoint);
  551. { Fold support }
  552. function CreateFold(StartY,EndY: sw_integer; Collapsed: boolean): boolean; virtual;
  553. procedure FoldChanged(Fold: PFold); virtual;
  554. procedure RemoveAllFolds; virtual;
  555. public
  556. { Syntax highlight }
  557. {a}function UpdateAttrs(FromLine: sw_integer; Attrs: byte): sw_integer; virtual;
  558. {a}function UpdateAttrsRange(FromLine, ToLine: sw_integer; Attrs: byte): sw_integer; virtual;
  559. public
  560. { Undo info storage }
  561. {a}procedure AddAction(AAction: byte; AStartPos, AEndPos: TPoint; AText: string;AFlags : longint); virtual;
  562. {a}procedure AddGroupedAction(AAction : byte); virtual;
  563. {a}procedure CloseGroupedAction(AAction : byte); virtual;
  564. {a}function GetUndoActionCount: sw_integer; virtual;
  565. {a}function GetRedoActionCount: sw_integer; virtual;
  566. {$ifdef TP}public{$else}protected{$endif}
  567. LastLocalCmd: word;
  568. KeyState : Integer;
  569. Bookmarks : array[0..9] of TEditorBookmark;
  570. DrawCalled,
  571. DrawCursorCalled: boolean;
  572. CurEvent : PEvent;
  573. procedure DrawLines(FirstLine: sw_integer);
  574. function Overwrite: boolean;
  575. function IsModal: boolean;
  576. procedure CheckSels;
  577. procedure CodeCompleteCheck;
  578. procedure CodeCompleteApply;
  579. procedure CodeCompleteCancel;
  580. procedure UpdateUndoRedo(cm : word; action : byte);
  581. procedure HideHighlight;
  582. function ShouldExtend: boolean;
  583. function ValidBlock: boolean;
  584. function GetLineFold(EditorLine: sw_integer): PFold;
  585. function IsLineVisible(EditorLine: sw_integer): boolean; virtual;
  586. function NextVisibleLine(StartLine: sw_integer; Down: boolean): sw_integer;
  587. procedure PushInfo(Const st : string);virtual;
  588. procedure PopInfo;virtual;
  589. public
  590. { Editor primitives }
  591. procedure SelectAll(Enable: boolean); virtual;
  592. public
  593. { Editor commands }
  594. SearchRunCount: integer;
  595. InASCIIMode: boolean;
  596. procedure Indent; virtual;
  597. procedure CharLeft; virtual;
  598. procedure CharRight; virtual;
  599. procedure WordLeft; virtual;
  600. procedure WordRight; virtual;
  601. procedure LineStart; virtual;
  602. procedure LineEnd; virtual;
  603. procedure LineUp; virtual;
  604. procedure LineDown; virtual;
  605. procedure PageUp; virtual;
  606. procedure PageDown; virtual;
  607. procedure TextStart; virtual;
  608. procedure TextEnd; virtual;
  609. procedure WindowStart; virtual;
  610. procedure WindowEnd; virtual;
  611. procedure JumpSelStart; virtual;
  612. procedure JumpSelEnd; virtual;
  613. procedure JumpMark(MarkIdx: integer); virtual;
  614. procedure DefineMark(MarkIdx: integer); virtual;
  615. procedure JumpToLastCursorPos; virtual;
  616. procedure FindMatchingDelimiter(ScanForward: boolean); virtual;
  617. procedure CreateFoldFromBlock; virtual;
  618. procedure ToggleFold; virtual;
  619. procedure CollapseFold; virtual;
  620. procedure ExpandFold; virtual;
  621. procedure UpperCase; virtual;
  622. procedure LowerCase; virtual;
  623. procedure WordLowerCase; virtual;
  624. procedure WordUpperCase; virtual;
  625. procedure InsertOptions; virtual;
  626. procedure ToggleCase; virtual;
  627. function InsertNewLine: Sw_integer; virtual;
  628. procedure BreakLine; virtual;
  629. procedure BackSpace; virtual;
  630. procedure DelChar; virtual;
  631. procedure DelWord; virtual;
  632. procedure DelToEndOfWord; virtual;
  633. procedure DelStart; virtual;
  634. procedure DelEnd; virtual;
  635. procedure DelLine; virtual;
  636. procedure InsMode; virtual;
  637. procedure StartSelect; virtual;
  638. procedure EndSelect; virtual;
  639. procedure DelSelect; virtual;
  640. procedure HideSelect; virtual;
  641. procedure CopyBlock; virtual;
  642. procedure MoveBlock; virtual;
  643. procedure IndentBlock; virtual;
  644. procedure UnindentBlock; virtual;
  645. procedure SelectWord; virtual;
  646. procedure SelectLine; virtual;
  647. procedure WriteBlock; virtual;
  648. procedure ReadBlock; virtual;
  649. procedure PrintBlock; virtual;
  650. procedure ExpandCodeTemplate; virtual;
  651. procedure AddChar(C: char); virtual;
  652. {$ifdef WinClipSupported}
  653. function ClipCopyWin: Boolean; virtual;
  654. function ClipPasteWin: Boolean; virtual;
  655. {$endif WinClipSupported}
  656. function ClipCopy: Boolean; virtual;
  657. procedure ClipCut; virtual;
  658. procedure ClipPaste; virtual;
  659. function GetCurrentWord : string;
  660. function GetCurrentWordArea(var StartP,EndP: TPoint): boolean;
  661. procedure Undo; virtual;
  662. procedure Redo; virtual;
  663. procedure Find; virtual;
  664. procedure Replace; virtual;
  665. procedure DoSearchReplace; virtual;
  666. procedure GotoLine; virtual;
  667. end;
  668. TCodeEditorDialog = function(Dialog: Integer; Info: Pointer): Word;
  669. const
  670. cmCopyWin = 240;
  671. cmPasteWin = 241;
  672. { used for ShiftDel and ShiftIns to avoid
  673. GetShiftState to be considered for extending
  674. selection (PM) }
  675. DontConsiderShiftState: boolean = false;
  676. ToClipCmds : TCommandSet = ([cmCut,cmCopy,cmCopyWin]);
  677. FromClipCmds : TCommandSet = ([cmPaste]);
  678. FromWinClipCmds : TCommandSet = ([cmPasteWin]);
  679. NulClipCmds : TCommandSet = ([cmClear]);
  680. UndoCmd : TCommandSet = ([cmUndo]);
  681. RedoCmd : TCommandSet = ([cmRedo]);
  682. function ExtractTabs(S: string; TabSize: Sw_integer): string;
  683. function StdEditorDialog(Dialog: Integer; Info: Pointer): word;
  684. const
  685. DefaultSaveExt : string[12] = '.pas';
  686. FileDir : DirStr = '';
  687. EditorDialog : TCodeEditorDialog = {$ifdef fpc}@{$endif}StdEditorDialog;
  688. Clipboard : PCustomCodeEditor = nil;
  689. FindStr : String[FindStrSize] = '';
  690. ReplaceStr : String[FindStrSize] = '';
  691. FindReplaceEditor : PCustomCodeEditor = nil;
  692. FindFlags : word = ffPromptOnReplace;
  693. WhiteSpaceChars : set of char = [#0,#32,#255];
  694. TabChars : set of char = [#9];
  695. HashChars : set of char = ['#'];
  696. AlphaChars : set of char = ['A'..'Z','a'..'z','_'];
  697. NumberChars : set of char = ['0'..'9'];
  698. HexNumberChars : set of char = ['0'..'9','A'..'F','a'..'f'];
  699. RealNumberChars : set of char = ['E','e','.'{,'+','-'}];
  700. procedure RegisterWEditor;
  701. implementation
  702. uses
  703. Strings,Video,MsgBox,Dialogs,App,StdDlg,Validate,
  704. {$ifdef WinClipSupported}
  705. WinClip,
  706. {$endif WinClipSupported}
  707. {$ifdef TEST_REGEXP}
  708. regexpr,
  709. {$endif TEST_REGEXP}
  710. WConsts,WViews,WCEdit;
  711. type
  712. {$ifdef FVISION}
  713. RecordWord = sw_word;
  714. {$else not FVISION}
  715. RecordWord = word;
  716. {$endif not FVISION}
  717. TFindDialogRec = packed record
  718. Find : String[FindStrSize];
  719. Options : RecordWord{longint};
  720. { checkboxes need 32 bits PM }
  721. { reverted to word in dialogs.TCluster for TP compatibility (PM) }
  722. { anyhow its complete nonsense : you can only have 16 fields
  723. but use a longint to store it !! }
  724. Direction: RecordWord;{ and tcluster has word size }
  725. Scope : RecordWord;
  726. Origin : RecordWord;
  727. end;
  728. TReplaceDialogRec = packed record
  729. Find : String[FindStrSize];
  730. Replace : String[FindStrSize];
  731. Options : RecordWord{longint};
  732. Direction: RecordWord;
  733. Scope : RecordWord;
  734. Origin : RecordWord;
  735. end;
  736. TEditorInputLine = object(TInputLine)
  737. Procedure HandleEvent(var Event : TEvent);virtual;
  738. end;
  739. PEditorInputLine = ^TEditorInputLine;
  740. TGotoLineDialogRec = packed record
  741. LineNo : string[5];
  742. Lines : sw_integer;
  743. end;
  744. const
  745. kbShift = kbLeftShift+kbRightShift;
  746. const
  747. FirstKeyCount = 46;
  748. FirstKeys: array[0..FirstKeyCount * 2] of Word = (FirstKeyCount,
  749. Ord(^A), cmWordLeft, Ord(^B), cmJumpLine, Ord(^C), cmPageDown,
  750. Ord(^D), cmCharRight, Ord(^E), cmLineUp,
  751. Ord(^F), cmWordRight, Ord(^G), cmDelChar,
  752. Ord(^H), cmBackSpace, Ord(^J), cmExpandCodeTemplate,
  753. Ord(^K), $FF02, Ord(^L), cmSearchAgain,
  754. Ord(^M), cmNewLine, Ord(^N), cmBreakLine,
  755. Ord(^O), $FF03,
  756. Ord(^P), cmASCIIChar, Ord(^Q), $FF01,
  757. Ord(^R), cmPageUp, Ord(^S), cmCharLeft,
  758. Ord(^T), cmDelToEndOfWord, Ord(^U), cmUndo,
  759. Ord(^V), cmInsMode, Ord(^X), cmLineDown,
  760. Ord(^Y), cmDelLine, kbLeft, cmCharLeft,
  761. kbRight, cmCharRight, kbCtrlLeft, cmWordLeft,
  762. kbCtrlRight, cmWordRight, kbHome, cmLineStart,
  763. kbCtrlHome, cmWindowStart, kbCtrlEnd, cmWindowEnd,
  764. kbEnd, cmLineEnd, kbUp, cmLineUp,
  765. kbDown, cmLineDown, kbPgUp, cmPageUp,
  766. kbPgDn, cmPageDown, kbCtrlPgUp, cmTextStart,
  767. kbCtrlPgDn, cmTextEnd, kbIns, cmInsMode,
  768. kbDel, cmDelChar, kbShiftIns, cmPaste,
  769. kbShiftDel, cmCut, kbCtrlIns, cmCopy,
  770. kbCtrlDel, cmClear,
  771. kbCtrlGrayMul, cmToggleFold, kbCtrlGrayMinus, cmCollapseFold, kbCtrlGrayPlus, cmExpandFold);
  772. QuickKeyCount = 29;
  773. QuickKeys: array[0..QuickKeyCount * 2] of Word = (QuickKeyCount,
  774. Ord('A'), cmReplace, Ord('C'), cmTextEnd,
  775. Ord('D'), cmLineEnd, Ord('F'), cmFind,
  776. Ord('H'), cmDelStart, Ord('R'), cmTextStart,
  777. Ord('S'), cmLineStart, Ord('Y'), cmDelEnd,
  778. Ord('G'), cmJumpLine, Ord('A'), cmReplace,
  779. Ord('B'), cmSelStart, Ord('K'), cmSelEnd,
  780. Ord('P'), cmLastCursorPos,
  781. Ord('E'), cmWindowStart, Ord('T'), cmWindowStart,
  782. Ord('U'), cmWindowEnd, Ord('X'), cmWindowEnd,
  783. Ord('['), cmFindMatchingDelimiter, Ord(']'), cmFindMatchingDelimiterBack,
  784. Ord('0'), cmJumpMark0, Ord('1'), cmJumpMark1, Ord('2'), cmJumpMark2,
  785. Ord('3'), cmJumpMark3, Ord('4'), cmJumpMark4, Ord('5'), cmJumpMark5,
  786. Ord('6'), cmJumpMark6, Ord('7'), cmJumpMark7, Ord('8'), cmJumpMark8,
  787. Ord('9'), cmJumpMark9);
  788. BlockKeyCount = 30;
  789. BlockKeys: array[0..BlockKeyCount * 2] of Word = (BlockKeyCount,
  790. Ord('B'), cmStartSelect, Ord('C'), cmCopyBlock,
  791. Ord('H'), cmHideSelect, Ord('K'), cmEndSelect,
  792. Ord('Y'), cmDelSelect, Ord('V'), cmMoveBlock,
  793. Ord('I'), cmIndentBlock, Ord('U'), cmUnindentBlock,
  794. Ord('T'), cmSelectWord, Ord('L'), cmSelectLine,
  795. Ord('W'), cmWriteBlock, Ord('R'), cmReadBlock,
  796. Ord('P'), cmPrintBlock,
  797. Ord('N'), cmUpperCase, Ord('O'), cmLowerCase,
  798. Ord('D'), cmActivateMenu,
  799. Ord('E'), cmWordLowerCase, Ord('F'), cmWordUpperCase,
  800. Ord('S'), cmSave, Ord('A'), cmCreateFold,
  801. Ord('0'), cmSetMark0, Ord('1'), cmSetMark1, Ord('2'), cmSetMark2,
  802. Ord('3'), cmSetMark3, Ord('4'), cmSetMark4, Ord('5'), cmSetMark5,
  803. Ord('6'), cmSetMark6, Ord('7'), cmSetMark7, Ord('8'), cmSetMark8,
  804. Ord('9'), cmSetMark9);
  805. MiscKeyCount = 6;
  806. MiscKeys: array[0..MiscKeyCount * 2] of Word = (MiscKeyCount,
  807. Ord('A'), cmOpenAtCursor, Ord('B'), cmBrowseAtCursor,
  808. Ord('G'), cmJumpLine, Ord('O'), cmInsertOptions,
  809. Ord('U'), cmToggleCase, Ord('L'), cmSelectLine);
  810. KeyMap: array[0..3] of Pointer = (@FirstKeys, @QuickKeys, @BlockKeys, @MiscKeys);
  811. function ScanKeyMap(KeyMap: Pointer; KeyCode: Word): Word;
  812. type
  813. pword = ^word;
  814. var
  815. p : pword;
  816. count : sw_word;
  817. begin
  818. p:=keymap;
  819. count:=p^;
  820. inc(p);
  821. while (count>0) do
  822. begin
  823. if (lo(p^)=lo(keycode)) and
  824. ((hi(p^)=0) or (hi(p^)=hi(keycode))) then
  825. begin
  826. inc(p);
  827. scankeymap:=p^;
  828. Exit;
  829. end;
  830. inc(p,2);
  831. dec(count);
  832. end;
  833. scankeymap:=0;
  834. end;
  835. function IsWordSeparator(C: char): boolean;
  836. begin
  837. IsWordSeparator:=C in[' ',#0,#255,':','=','''','"','.',',','/',';','$','#','(',')','<','>','^','*','+','-','?','&','[',']'];
  838. end;
  839. {function IsSpace(C: char): boolean;
  840. begin
  841. IsSpace:=C in[' ',#0,#255];
  842. end;}
  843. function LTrim(S: string): string;
  844. begin
  845. while (length(S)>0) and (S[1] in [#0,TAB,#32]) do
  846. Delete(S,1,1);
  847. LTrim:=S;
  848. end;
  849. { TAB are not same as spaces if UseTabs is set PM }
  850. function RTrim(S: string;cut_tabs : boolean): string;
  851. begin
  852. while (length(S)>0) and
  853. ((S[length(S)] in [#0,#32]) or
  854. ((S[Length(S)]=TAB) and cut_tabs)) do
  855. Delete(S,length(S),1);
  856. RTrim:=S;
  857. end;
  858. function Trim(S: string): string;
  859. begin
  860. Trim:=RTrim(LTrim(S),true);
  861. end;
  862. function EatIO: integer;
  863. begin
  864. EatIO:=IOResult;
  865. end;
  866. function ExistsFile(const FileName: string): boolean;
  867. var f: file;
  868. Exists: boolean;
  869. begin
  870. if FileName='' then Exists:=false else
  871. begin
  872. {$I-}
  873. Assign(f,FileName);
  874. Reset(f,1);
  875. Exists:=EatIO=0;
  876. Close(f);
  877. EatIO;
  878. {$I+}
  879. end;
  880. ExistsFile:=Exists;
  881. end;
  882. function StrToInt(const S: string): longint;
  883. var L: longint;
  884. C: integer;
  885. begin
  886. Val(S,L,C); if C<>0 then L:=-1;
  887. StrToInt:=L;
  888. end;
  889. function RExpand(const S: string; MinLen: byte): string;
  890. begin
  891. if length(S)<MinLen then
  892. RExpand:=S+CharStr(' ',MinLen-length(S))
  893. else
  894. RExpand:=S;
  895. end;
  896. function upper(const s : string) : string;
  897. var
  898. i : Sw_word;
  899. begin
  900. for i:=1 to length(s) do
  901. if s[i] in ['a'..'z'] then
  902. upper[i]:=char(byte(s[i])-32)
  903. else
  904. upper[i]:=s[i];
  905. upper[0]:=s[0];
  906. end;
  907. type TPosOfs = {$ifdef TP}longint{$endif}{$ifdef FPC}comp{$endif};
  908. function PosToOfs(const X,Y: sw_integer): TPosOfs;
  909. type TPosRec = record LoI, HiI: sw_integer; end;
  910. var C: TPosRec;
  911. begin
  912. C.LoI:=X; C.HiI:=Y;
  913. PosToOfs:=TPosOfs(C);
  914. end;
  915. function PosToOfsP(const P: TPoint): TPosOfs;
  916. begin
  917. PosToOfsP:=PosToOfs(P.X,P.Y);
  918. end;
  919. function PointOfs(P: TPoint): TPosOfs;
  920. begin
  921. PointOfs:={longint(P.Y)*MaxLineLength+P.X}PosToOfsP(P);
  922. end;
  923. function ExtractTabs(S: string; TabSize: Sw_integer): string;
  924. var
  925. P,PAdd: Sw_integer;
  926. begin
  927. p:=0;
  928. while p<length(s) do
  929. begin
  930. inc(p);
  931. if s[p]=TAB then
  932. begin
  933. PAdd:=TabSize-((p-1) mod TabSize);
  934. s:=copy(S,1,P-1)+CharStr(' ',PAdd)+copy(S,P+1,High(s));
  935. inc(P,PAdd-1);
  936. end;
  937. end;
  938. ExtractTabs:=S;
  939. end;
  940. {function CompressUsingTabs(S: string; TabSize: byte): string;
  941. var TabS: string;
  942. P: byte;
  943. begin
  944. TabS:=CharStr(' ',TabSize);
  945. repeat
  946. P:=Pos(TabS,S);
  947. if P>0 then
  948. S:=copy(S,1,P-1)+TAB+copy(S,P+TabSize,High(S));
  949. until P=0;
  950. CompressUsingTabs:=S;
  951. end;}
  952. {*****************************************************************************
  953. Forward/Backward Scanning
  954. *****************************************************************************}
  955. Const
  956. {$ifndef FPC}
  957. MaxBufLength = $7f00;
  958. NotFoundValue = -1;
  959. {$else}
  960. MaxBufLength = $7fffff00;
  961. NotFoundValue = -1;
  962. {$endif}
  963. Type
  964. Btable = Array[0..255] of Byte;
  965. Procedure BMFMakeTable(const s:string; Var t : Btable);
  966. Var
  967. x : sw_integer;
  968. begin
  969. FillChar(t,sizeof(t),length(s));
  970. For x := length(s) downto 1 do
  971. if (t[ord(s[x])] = length(s)) then
  972. t[ord(s[x])] := length(s) - x;
  973. end;
  974. function BMFScan(var Block; Size: Sw_Word;const Str: String;const bt:BTable): Sw_Integer;
  975. Var
  976. buffer : Array[0..MaxBufLength-1] of Byte Absolute block;
  977. s2 : String;
  978. len,
  979. numb : Sw_Word;
  980. found : Boolean;
  981. begin
  982. len:=length(str);
  983. if len>size then
  984. begin
  985. BMFScan := NotFoundValue;
  986. exit;
  987. end;
  988. s2[0]:=chr(len); { sets the length to that of the search String }
  989. found:=False;
  990. numb:=pred(len);
  991. While (not found) and (numb<size) do
  992. begin
  993. { partial match }
  994. if buffer[numb] = ord(str[len]) then
  995. begin
  996. { less partial! }
  997. if buffer[numb-pred(len)] = ord(str[1]) then
  998. begin
  999. move(buffer[numb-pred(len)],s2[1],len);
  1000. if (str=s2) then
  1001. begin
  1002. found:=true;
  1003. break;
  1004. end;
  1005. end;
  1006. inc(numb);
  1007. end
  1008. else
  1009. inc(numb,Bt[buffer[numb]]);
  1010. end;
  1011. if not found then
  1012. BMFScan := NotFoundValue
  1013. else
  1014. BMFScan := numb - pred(len);
  1015. end;
  1016. function BMFIScan(var Block; Size: Sw_Word;const Str: String;const bt:BTable): Sw_Integer;
  1017. Var
  1018. buffer : Array[0..MaxBufLength-1] of Char Absolute block;
  1019. len,
  1020. numb,
  1021. x : Sw_Word;
  1022. found : Boolean;
  1023. p : pchar;
  1024. c : char;
  1025. begin
  1026. len:=length(str);
  1027. if (len=0) or (len>size) then
  1028. begin
  1029. BMFIScan := NotFoundValue;
  1030. exit;
  1031. end;
  1032. found:=False;
  1033. numb:=pred(len);
  1034. While (not found) and (numb<size) do
  1035. begin
  1036. { partial match }
  1037. c:=buffer[numb];
  1038. if c in ['a'..'z'] then
  1039. c:=chr(ord(c)-32);
  1040. if (c=str[len]) then
  1041. begin
  1042. { less partial! }
  1043. p:=@buffer[numb-pred(len)];
  1044. x:=1;
  1045. while (x<=len) do
  1046. begin
  1047. if not(((p^ in ['a'..'z']) and (chr(ord(p^)-32)=str[x])) or
  1048. (p^=str[x])) then
  1049. break;
  1050. inc(p);
  1051. inc(x);
  1052. end;
  1053. if (x>len) then
  1054. begin
  1055. found:=true;
  1056. break;
  1057. end;
  1058. inc(numb);
  1059. end
  1060. else
  1061. inc(numb,Bt[ord(c)]);
  1062. end;
  1063. if not found then
  1064. BMFIScan := NotFoundValue
  1065. else
  1066. BMFIScan := numb - pred(len);
  1067. end;
  1068. Procedure BMBMakeTable(const s:string; Var t : Btable);
  1069. Var
  1070. x : sw_integer;
  1071. begin
  1072. FillChar(t,sizeof(t),length(s));
  1073. For x := 1 to length(s)do
  1074. if (t[ord(s[x])] = length(s)) then
  1075. t[ord(s[x])] := x-1;
  1076. end;
  1077. function BMBScan(var Block; Size: Sw_Word;const Str: String;const bt:BTable): Sw_Integer;
  1078. Var
  1079. buffer : Array[0..MaxBufLength-1] of Byte Absolute block;
  1080. s2 : String;
  1081. len,
  1082. numb : Sw_integer;
  1083. found : Boolean;
  1084. begin
  1085. len:=length(str);
  1086. if len>size then
  1087. begin
  1088. BMBScan := NotFoundValue;
  1089. exit;
  1090. end;
  1091. s2[0]:=chr(len); { sets the length to that of the search String }
  1092. found:=False;
  1093. numb:=size-pred(len);
  1094. While (not found) and (numb>0) do
  1095. begin
  1096. { partial match }
  1097. if buffer[numb] = ord(str[1]) then
  1098. begin
  1099. { less partial! }
  1100. if buffer[numb+pred(len)] = ord(str[len]) then
  1101. begin
  1102. move(buffer[numb],s2[1],len);
  1103. if (str=s2) then
  1104. begin
  1105. found:=true;
  1106. break;
  1107. end;
  1108. end;
  1109. dec(numb);
  1110. end
  1111. else
  1112. dec(numb,Bt[buffer[numb]]);
  1113. end;
  1114. if not found then
  1115. BMBScan := NotFoundValue
  1116. else
  1117. BMBScan := numb;
  1118. end;
  1119. function BMBIScan(var Block; Size: Sw_Word;const Str: String;const bt:BTable): Sw_Integer;
  1120. Var
  1121. buffer : Array[0..MaxBufLength-1] of Char Absolute block;
  1122. len,
  1123. numb,
  1124. x : Sw_integer;
  1125. found : Boolean;
  1126. p : pchar;
  1127. c : char;
  1128. begin
  1129. len:=length(str);
  1130. if (len=0) or (len>size) then
  1131. begin
  1132. BMBIScan := NotFoundValue;
  1133. exit;
  1134. end;
  1135. found:=False;
  1136. numb:=size-len;
  1137. While (not found) and (numb>0) do
  1138. begin
  1139. { partial match }
  1140. c:=buffer[numb];
  1141. if c in ['a'..'z'] then
  1142. c:=chr(ord(c)-32);
  1143. if (c=str[1]) then
  1144. begin
  1145. { less partial! }
  1146. p:=@buffer[numb];
  1147. x:=1;
  1148. while (x<=len) do
  1149. begin
  1150. if not(((p^ in ['a'..'z']) and (chr(ord(p^)-32)=str[x])) or
  1151. (p^=str[x])) then
  1152. break;
  1153. inc(p);
  1154. inc(x);
  1155. end;
  1156. if (x>len) then
  1157. begin
  1158. found:=true;
  1159. break;
  1160. end;
  1161. dec(numb);
  1162. end
  1163. else
  1164. dec(numb,Bt[ord(c)]);
  1165. end;
  1166. if not found then
  1167. BMBIScan := NotFoundValue
  1168. else
  1169. BMBIScan := numb;
  1170. end;
  1171. {*****************************************************************************
  1172. PLine,TLineCollection
  1173. *****************************************************************************}
  1174. constructor TCustomLine.Init(const AText: string; AFlags: longint);
  1175. begin
  1176. inherited Init;
  1177. SetText(AText);
  1178. end;
  1179. function TCustomLine.GetText: string;
  1180. begin
  1181. Abstract; GetText:='';
  1182. end;
  1183. procedure TCustomLine.SetText(const AText: string);
  1184. begin
  1185. Abstract;
  1186. end;
  1187. function TCustomLine.GetEditorInfo(Editor: PCustomCodeEditor): PEditorLineInfo;
  1188. begin
  1189. Abstract;
  1190. GetEditorInfo:=nil;
  1191. end;
  1192. function TCustomLine.GetFlags: longint;
  1193. begin
  1194. Abstract;
  1195. GetFlags:=0;
  1196. end;
  1197. procedure TCustomLine.SetFlags(AFlags: longint);
  1198. begin
  1199. Abstract;
  1200. end;
  1201. function TCustomLine.IsFlagSet(AFlag: longint): boolean;
  1202. begin
  1203. IsFlagSet:=(GetFlags and AFlag)=AFlag;
  1204. end;
  1205. procedure TCustomLine.SetFlagState(AFlag: longint; ASet: boolean);
  1206. var N,O: longint;
  1207. begin
  1208. O:=GetFlags; N:=O;
  1209. if ASet then
  1210. N:=N or AFlag
  1211. else
  1212. N:=N and (not AFlag);
  1213. if N<>O then
  1214. SetFlags(N);
  1215. end;
  1216. procedure TCustomLine.AddEditorInfo(Index: sw_integer; AEditor: PCustomCodeEditor);
  1217. begin
  1218. { Abstract }
  1219. end;
  1220. procedure TCustomLine.RemoveEditorInfo(AEditor: PCustomCodeEditor);
  1221. begin
  1222. { Abstract }
  1223. end;
  1224. destructor TCustomLine.Done;
  1225. begin
  1226. inherited Done;
  1227. end;
  1228. function TLineCollection.At(Index: sw_Integer): PCustomLine;
  1229. begin
  1230. At:=inherited At(Index);
  1231. end;
  1232. constructor TFold.Init(AEditor: PCustomCodeEditor; AParentFold: PFold; ACollapsed: boolean);
  1233. begin
  1234. inherited Init;
  1235. New(Childs, Init(10,10));
  1236. Editor:=AEditor;
  1237. ParentFold:=AParentFold;
  1238. if Assigned(ParentFold) then
  1239. ParentFold^.AddChildReference(@Self);
  1240. Collapsed_:=ACollapsed;
  1241. if Assigned(AEditor) then
  1242. Editor^.RegisterFold(@Self);
  1243. end;
  1244. procedure TFold.AddReference(P: PObject);
  1245. begin
  1246. Inc(ReferenceCount);
  1247. end;
  1248. procedure TFold.RemoveReference(P: PObject);
  1249. begin
  1250. Dec(ReferenceCount);
  1251. if CanDispose then
  1252. Free;
  1253. end;
  1254. procedure TFold.AddLineReference(Line: PEditorLineInfo);
  1255. begin
  1256. Inc(LineCount_);
  1257. AddReference(Line);
  1258. end;
  1259. procedure TFold.RemoveLineReference(Line: PEditorLineInfo);
  1260. begin
  1261. Dec(LineCount_);
  1262. RemoveReference(Line);
  1263. end;
  1264. procedure TFold.AddChildReference(Fold: PFold);
  1265. begin
  1266. Childs^.Insert(Fold);
  1267. AddReference(Fold);
  1268. end;
  1269. procedure TFold.RemoveChildReference(Fold: PFold);
  1270. begin
  1271. Childs^.Delete(Fold);
  1272. RemoveReference(Fold);
  1273. end;
  1274. function TFold.CanDispose: boolean;
  1275. begin
  1276. CanDispose:=ReferenceCount<=0;
  1277. end;
  1278. function TFold.IsCollapsed: boolean;
  1279. var C: boolean;
  1280. begin
  1281. C:=Collapsed_;
  1282. if Assigned(ParentFold) then C:=C or ParentFold^.IsCollapsed;
  1283. IsCollapsed:=C;
  1284. end;
  1285. function TFold.IsParent(AFold: PFold): boolean;
  1286. var P: boolean;
  1287. begin
  1288. P:=(ParentFold=AFold);
  1289. if Assigned(ParentFold) then P:=P or ParentFold^.IsParent(AFold);
  1290. IsParent:=P;
  1291. end;
  1292. function TFold.GetLineCount: sw_integer;
  1293. var Count: sw_integer;
  1294. procedure AddIt(P: PFold); {$ifndef FPC}far;{$endif}
  1295. begin
  1296. Inc(Count,P^.GetLineCount);
  1297. end;
  1298. begin
  1299. Count:=LineCount_;
  1300. if assigned(Childs) then Childs^.ForEach(@AddIt);
  1301. GetLineCount:=Count;
  1302. end;
  1303. procedure TFold.Collapse(ACollapse: boolean);
  1304. begin
  1305. if ACollapse<>Collapsed_ then
  1306. begin
  1307. Collapsed_:=ACollapse;
  1308. if (not Collapsed_) and Assigned(ParentFold) then
  1309. ParentFold^.Collapse(false);
  1310. Changed;
  1311. end;
  1312. end;
  1313. procedure TFold.Changed;
  1314. begin
  1315. if Assigned(Editor) then
  1316. Editor^.FoldChanged(@Self);
  1317. end;
  1318. function TFold.GetLevel: sw_integer;
  1319. var Level: sw_integer;
  1320. begin
  1321. Level:=0;
  1322. if Assigned(ParentFold) then
  1323. Inc(Level,1+ParentFold^.GetLevel);
  1324. GetLevel:=Level;
  1325. end;
  1326. destructor TFold.Done;
  1327. begin
  1328. if Assigned(ParentFold) then
  1329. ParentFold^.RemoveChildReference(@Self);
  1330. if Assigned(Editor) then
  1331. Editor^.UnRegisterFold(@Self);
  1332. Childs^.DeleteAll; Dispose(Childs, Done);
  1333. inherited Done;
  1334. end;
  1335. function TFoldCollection.At(Index: sw_Integer): PFold;
  1336. begin
  1337. At:=inherited At(Index);
  1338. end;
  1339. constructor TEditorLineInfo.Init(AEditor: PCustomCodeEditor);
  1340. begin
  1341. inherited Init;
  1342. Editor:=AEditor;
  1343. end;
  1344. function TEditorLineInfo.GetFormat: string;
  1345. begin
  1346. GetFormat:=GetStr(Format);
  1347. end;
  1348. procedure TEditorLineInfo.SetFormat(const AFormat: string);
  1349. begin
  1350. SetStr(Format,AFormat);
  1351. end;
  1352. procedure TEditorLineInfo.SetFold(AFold: PFold);
  1353. begin
  1354. if Assigned(Fold) then
  1355. Fold^.RemoveLineReference(@Self);
  1356. Fold:=AFold;
  1357. if Assigned(Fold) then
  1358. Fold^.AddLineReference(@Self);
  1359. end;
  1360. destructor TEditorLineInfo.Done;
  1361. begin
  1362. if Format<>nil then DisposeStr(Format); Format:=nil;
  1363. SetFold(nil);
  1364. inherited Done;
  1365. end;
  1366. function TEditorLineInfoCollection.At(Index: sw_Integer): PEditorLineInfo;
  1367. begin
  1368. At:=inherited At(Index);
  1369. end;
  1370. function TEditorBindingCollection.At(Index: sw_Integer): PEditorBinding;
  1371. begin
  1372. At:=inherited At(Index);
  1373. end;
  1374. constructor TEditorBinding.Init(AEditor: PCustomCodeEditor);
  1375. begin
  1376. inherited Init;
  1377. Editor:=AEditor;
  1378. end;
  1379. destructor TEditorBinding.Done;
  1380. begin
  1381. inherited Done;
  1382. end;
  1383. constructor TCustomCodeEditorCore.Init;
  1384. begin
  1385. inherited Init;
  1386. New(Bindings, Init(10,10));
  1387. end;
  1388. procedure TCustomCodeEditorCore.BindEditor(AEditor: PCustomCodeEditor);
  1389. var B: PEditorBinding;
  1390. Count,I,Idx: sw_integer;
  1391. L: PCustomLine;
  1392. begin
  1393. if Assigned(AEditor)=false then Exit;
  1394. New(B, Init(AEditor));
  1395. Bindings^.Insert(B);
  1396. Idx:=Bindings^.IndexOf(B);
  1397. Count:=GetLineCount;
  1398. for I:=0 to Count-1 do
  1399. begin
  1400. L:=GetLine(I);
  1401. if Assigned(L) then
  1402. L^.AddEditorInfo(Idx,AEditor);
  1403. end;
  1404. BindingsChanged;
  1405. end;
  1406. procedure TCustomCodeEditorCore.UnBindEditor(AEditor: PCustomCodeEditor);
  1407. var B: PEditorBinding;
  1408. Count,I: sw_integer;
  1409. L: PCustomLine;
  1410. begin
  1411. B:=SearchBinding(AEditor);
  1412. if Assigned(B) then
  1413. begin
  1414. Count:=GetLineCount;
  1415. for I:=0 to Count-1 do
  1416. begin
  1417. L:=GetLine(I);
  1418. if Assigned(L) then
  1419. L^.RemoveEditorInfo(AEditor);
  1420. end;
  1421. Bindings^.Free(B);
  1422. BindingsChanged;
  1423. end;
  1424. end;
  1425. function TCustomCodeEditorCore.IsEditorBound(AEditor: PCustomCodeEditor): boolean;
  1426. begin
  1427. IsEditorBound:=SearchBinding(AEditor)<>nil;
  1428. end;
  1429. function TCustomCodeEditorCore.GetBindingCount: sw_integer;
  1430. begin
  1431. GetBindingCount:=Bindings^.Count;
  1432. end;
  1433. function TCustomCodeEditorCore.GetBindingIndex(AEditor: PCustomCodeEditor): sw_integer;
  1434. var B: PEditorBinding;
  1435. begin
  1436. B:=SearchBinding(AEditor);
  1437. GetBindingIndex:=Bindings^.IndexOf(B);
  1438. end;
  1439. function TCustomCodeEditorCore.SearchBinding(AEditor: PCustomCodeEditor): PEditorBinding;
  1440. function SearchEditor(P: PEditorBinding): boolean; {$ifndef FPC}far;{$endif}
  1441. begin
  1442. SearchEditor:=P^.Editor=AEditor;
  1443. end;
  1444. begin
  1445. SearchBinding:=Bindings^.FirstThat(@SearchEditor);
  1446. end;
  1447. function TCustomCodeEditorCore.CanDispose: boolean;
  1448. begin
  1449. CanDispose:=Assigned(Bindings) and (Bindings^.Count=0);
  1450. end;
  1451. function TCustomCodeEditorCore.GetModified: boolean;
  1452. begin
  1453. Abstract;
  1454. GetModified:=true;
  1455. end;
  1456. function TCustomCodeEditorCore.GetChangedLine: sw_integer;
  1457. begin
  1458. GetChangedLine:=ChangedLine;
  1459. end;
  1460. procedure TCustomCodeEditorCore.SetModified(AModified: boolean);
  1461. begin
  1462. Abstract;
  1463. end;
  1464. function TCustomCodeEditorCore.GetStoreUndo: boolean;
  1465. begin
  1466. Abstract;
  1467. GetStoreUndo:=false;
  1468. end;
  1469. procedure TCustomCodeEditorCore.SetStoreUndo(AStore: boolean);
  1470. begin
  1471. Abstract;
  1472. end;
  1473. function TCustomCodeEditorCore.GetSyntaxCompleted: boolean;
  1474. begin
  1475. Abstract;
  1476. GetSyntaxCompleted:=true;
  1477. end;
  1478. procedure TCustomCodeEditorCore.SetSyntaxCompleted(SC : boolean);
  1479. begin
  1480. Abstract;
  1481. end;
  1482. function TCustomCodeEditorCore.IsClipboard: Boolean;
  1483. function IsClip(P: PEditorBinding): boolean; {$ifndef FPC}far;{$endif}
  1484. begin
  1485. IsClip:=(P^.Editor=Clipboard);
  1486. end;
  1487. begin
  1488. IsClipBoard:=Bindings^.FirstThat(@IsClip)<>nil;
  1489. end;
  1490. function TCustomCodeEditorCore.GetTabSize: integer;
  1491. begin
  1492. Abstract;
  1493. GetTabSize:=0;
  1494. end;
  1495. procedure TCustomCodeEditorCore.SetTabSize(ATabSize: integer);
  1496. begin
  1497. Abstract;
  1498. end;
  1499. function TCustomCodeEditorCore.GetIndentSize: integer;
  1500. begin
  1501. Abstract;
  1502. GetIndentSize:=0;
  1503. end;
  1504. procedure TCustomCodeEditorCore.SetIndentSize(AIndentSize: integer);
  1505. begin
  1506. Abstract;
  1507. end;
  1508. procedure TCustomCodeEditorCore.LimitsChanged;
  1509. begin
  1510. if Locked then
  1511. LimitsChangedCalled:=true
  1512. else
  1513. DoLimitsChanged;
  1514. end;
  1515. procedure TCustomCodeEditorCore.ContentsChanged;
  1516. begin
  1517. if Locked then
  1518. ContentsChangedCalled:=true
  1519. else
  1520. DoContentsChanged;
  1521. end;
  1522. procedure TCustomCodeEditorCore.ModifiedChanged;
  1523. begin
  1524. if Locked then
  1525. ModifiedChangedCalled:=true
  1526. else
  1527. DoModifiedChanged;
  1528. end;
  1529. procedure TCustomCodeEditorCore.TabSizeChanged;
  1530. begin
  1531. if Locked then
  1532. TabSizeChangedCalled:=true
  1533. else
  1534. DoTabSizeChanged;
  1535. end;
  1536. procedure TCustomCodeEditorCore.StoreUndoChanged;
  1537. begin
  1538. if Locked then
  1539. StoreUndoChangedCalled:=true
  1540. else
  1541. DoStoreUndoChanged;
  1542. end;
  1543. procedure TCustomCodeEditorCore.BindingsChanged;
  1544. procedure CallIt(P: PEditorBinding); {$ifndef FPC}far;{$endif}
  1545. begin
  1546. P^.Editor^.BindingsChanged;
  1547. end;
  1548. begin
  1549. Bindings^.ForEach(@CallIt);
  1550. end;
  1551. procedure TCustomCodeEditorCore.DoLimitsChanged;
  1552. procedure CallIt(P: PEditorBinding); {$ifndef FPC}far;{$endif}
  1553. begin
  1554. P^.Editor^.DoLimitsChanged;
  1555. end;
  1556. begin
  1557. Bindings^.ForEach(@CallIt);
  1558. end;
  1559. procedure TCustomCodeEditorCore.DoContentsChanged;
  1560. procedure CallIt(P: PEditorBinding); {$ifndef FPC}far;{$endif}
  1561. begin
  1562. P^.Editor^.ContentsChanged;
  1563. end;
  1564. begin
  1565. Bindings^.ForEach(@CallIt);
  1566. end;
  1567. procedure TCustomCodeEditorCore.DoModifiedChanged;
  1568. procedure CallIt(P: PEditorBinding); {$ifndef FPC}far;{$endif}
  1569. begin
  1570. P^.Editor^.ModifiedChanged;
  1571. end;
  1572. begin
  1573. Bindings^.ForEach(@CallIt);
  1574. end;
  1575. procedure TCustomCodeEditorCore.DoTabSizeChanged;
  1576. procedure CallIt(P: PEditorBinding); {$ifndef FPC}far;{$endif}
  1577. begin
  1578. P^.Editor^.TabSizeChanged;
  1579. end;
  1580. begin
  1581. Bindings^.ForEach(@CallIt);
  1582. end;
  1583. procedure TCustomCodeEditorCore.UpdateUndoRedo(cm : word; action : byte);
  1584. procedure CallIt(P: PEditorBinding); {$ifndef FPC}far;{$endif}
  1585. begin
  1586. if (P^.Editor^.State and sfActive)<>0 then
  1587. begin
  1588. P^.Editor^.UpdateUndoRedo(cm,action);
  1589. if cm=cmUndo then
  1590. begin
  1591. P^.Editor^.SetCmdState(UndoCmd,true);
  1592. P^.Editor^.SetCmdState(RedoCmd,false);
  1593. Message(Application,evBroadcast,cmCommandSetChanged,nil);
  1594. end;
  1595. end;
  1596. end;
  1597. begin
  1598. Bindings^.ForEach(@CallIt);
  1599. end;
  1600. procedure TCustomCodeEditorCore.DoStoreUndoChanged;
  1601. procedure CallIt(P: PEditorBinding); {$ifndef FPC}far;{$endif}
  1602. begin
  1603. P^.Editor^.StoreUndoChanged;
  1604. end;
  1605. begin
  1606. Bindings^.ForEach(@CallIt);
  1607. end;
  1608. procedure TCustomCodeEditorCore.DoSyntaxStateChanged;
  1609. procedure CallIt(P: PEditorBinding); {$ifndef FPC}far;{$endif}
  1610. begin
  1611. P^.Editor^.SyntaxStateChanged;
  1612. end;
  1613. begin
  1614. Bindings^.ForEach(@CallIt);
  1615. end;
  1616. function TCustomCodeEditorCore.GetLastVisibleLine : sw_integer;
  1617. var
  1618. y : sw_integer;
  1619. procedure CallIt(P: PEditorBinding); {$ifndef FPC}far;{$endif}
  1620. begin
  1621. if y < P^.Editor^.Delta.Y+P^.Editor^.Size.Y then
  1622. y:=P^.Editor^.Delta.Y+P^.Editor^.Size.Y;
  1623. end;
  1624. begin
  1625. y:=0;
  1626. Bindings^.ForEach(@CallIt);
  1627. GetLastVisibleLine:=y;
  1628. end;
  1629. function TCustomCodeEditorCore.SaveToStream(Editor: PCustomCodeEditor; Stream: PStream): boolean;
  1630. var A,B: TPoint;
  1631. begin
  1632. A.Y:=0; A.X:=0;
  1633. B.Y:=GetLineCount-1;
  1634. if GetLineCount>0 then
  1635. B.X:=length(GetDisplayText(B.Y))
  1636. else
  1637. B.X:=0;
  1638. SaveToStream:=SaveAreaToStream(Editor,Stream,A,B);
  1639. end;
  1640. procedure TCustomCodeEditorCore.ISetLineFlagState(Binding: PEditorBinding; LineNo: sw_integer; Flag: longint; ASet: boolean);
  1641. begin
  1642. Abstract;
  1643. end;
  1644. procedure TCustomCodeEditorCore.IGetDisplayTextFormat(Binding: PEditorBinding; LineNo: sw_integer;var DT,DF:string);
  1645. begin
  1646. Abstract;
  1647. end;
  1648. function TCustomCodeEditorCore.IGetLineFormat(Binding: PEditorBinding; LineNo: sw_integer): string;
  1649. begin
  1650. Abstract;
  1651. IGetLineFormat:='';
  1652. end;
  1653. procedure TCustomCodeEditorCore.ISetLineFormat(Binding: PEditorBinding; LineNo: sw_integer;const S: string);
  1654. begin
  1655. Abstract;
  1656. end;
  1657. function TCustomCodeEditorCore.CharIdxToLinePos(Line,CharIdx: sw_integer): sw_integer;
  1658. var S: string;
  1659. TabSize,CP,RX,NextInc: sw_integer;
  1660. begin
  1661. S:=GetLineText(Line);
  1662. (* this would fasten the code
  1663. but UseTabCharacters is set for Editor not for EditorCore
  1664. objects,which is dangerous anyway and should be changed ... PM
  1665. if not IsFlagSet(efUseTabCharacters) then
  1666. begin
  1667. if CharIdx<=Length(S) then
  1668. CharIdxToLinePos:=CharIdx-1
  1669. else
  1670. CharIdxToLinePos:=Length(S)-1;
  1671. exit;
  1672. end; *)
  1673. TabSize:=GetTabSize;
  1674. CP:=1; RX:=0;
  1675. NextInc:=0;
  1676. while {(CP<=length(S)) and }(CP<=CharIdx) do
  1677. begin
  1678. if NextInc>0 then
  1679. Inc(RX,NextInc);
  1680. if (CP<=length(S)) and (S[CP]=TAB) then
  1681. NextInc:=TabSize-(RX mod TabSize) -1
  1682. else
  1683. NextInc:=0;
  1684. Inc(RX);
  1685. Inc(CP);
  1686. end;
  1687. CharIdxToLinePos:=RX-1;
  1688. end;
  1689. function TCustomCodeEditorCore.LinePosToCharIdx(Line,X: sw_integer): sw_integer;
  1690. var S: string;
  1691. TabSize,CP,RX: sw_integer;
  1692. begin
  1693. TabSize:=GetTabSize;
  1694. S:=GetLineText(Line);
  1695. (*
  1696. if not IsFlagSet(efUseTabCharacters) then
  1697. begin
  1698. if S='' then
  1699. CP:=0
  1700. else if (Line<Length(S)) then
  1701. LinePosToCharIdx:=Line+1
  1702. else
  1703. LinePosToCharIdx:=Length(S);
  1704. exit;
  1705. end; *)
  1706. if S='' then
  1707. CP:=0
  1708. else
  1709. begin
  1710. CP:=0; RX:=0;
  1711. while (RX<=X) and (CP<=length(S)) do
  1712. begin
  1713. Inc(CP);
  1714. if S[CP]=TAB then
  1715. Inc(RX,TabSize-(RX mod TabSize))
  1716. else
  1717. Inc(RX);
  1718. end;
  1719. end;
  1720. LinePosToCharIdx:=CP;
  1721. end;
  1722. function TCustomCodeEditorCore.GetLineCount: sw_integer;
  1723. begin
  1724. Abstract;
  1725. GetLineCount:=0;
  1726. end;
  1727. function TCustomCodeEditorCore.GetLine(LineNo: sw_integer): PCustomLine;
  1728. begin
  1729. Abstract;
  1730. GetLine:=nil;
  1731. end;
  1732. function TCustomCodeEditorCore.GetLineText(LineNo: sw_integer): string;
  1733. begin
  1734. Abstract;
  1735. GetLineText:='';
  1736. end;
  1737. procedure TCustomCodeEditorCore.SetDisplayText(I: sw_integer;const S: string);
  1738. begin
  1739. Abstract;
  1740. end;
  1741. function TCustomCodeEditorCore.GetDisplayText(I: sw_integer): string;
  1742. begin
  1743. Abstract;
  1744. GetDisplayText:='';
  1745. end;
  1746. procedure TCustomCodeEditorCore.SetLineText(I: sw_integer;const S: string);
  1747. begin
  1748. Abstract;
  1749. end;
  1750. procedure TCustomCodeEditorCore.GetDisplayTextFormat(Editor: PCustomCodeEditor; I: sw_integer;var DT,DF:string);
  1751. begin
  1752. IGetDisplayTextFormat(SearchBinding(Editor),I,DT,DF);
  1753. end;
  1754. function TCustomCodeEditorCore.GetLineFormat(Editor: PCustomCodeEditor; I: sw_integer): string;
  1755. begin
  1756. GetLineFormat:=IGetLineFormat(SearchBinding(Editor),I);
  1757. end;
  1758. procedure TCustomCodeEditorCore.SetLineFormat(Editor: PCustomCodeEditor; I: sw_integer; const S: string);
  1759. begin
  1760. ISetLineFormat(SearchBinding(Editor),I,S);
  1761. end;
  1762. procedure TCustomCodeEditorCore.DeleteAllLines;
  1763. begin
  1764. Abstract;
  1765. end;
  1766. procedure TCustomCodeEditorCore.DeleteLine(I: sw_integer);
  1767. begin
  1768. Abstract;
  1769. end;
  1770. function TCustomCodeEditorCore.InsertLine(LineNo: sw_integer; const S: string): PCustomLine;
  1771. begin
  1772. Abstract;
  1773. InsertLine:=nil; { eliminate compiler warning }
  1774. end;
  1775. procedure TCustomCodeEditorCore.AddLine(const S: string);
  1776. begin
  1777. Abstract;
  1778. end;
  1779. procedure TCustomCodeEditorCore.GetContent(ALines: PUnsortedStringCollection);
  1780. begin
  1781. Abstract;
  1782. end;
  1783. procedure TCustomCodeEditorCore.SetContent(ALines: PUnsortedStringCollection);
  1784. begin
  1785. Abstract;
  1786. end;
  1787. function TCustomCodeEditorCore.Locked: boolean;
  1788. begin
  1789. Locked:=LockFlag>0;
  1790. end;
  1791. procedure TCustomCodeEditorCore.Lock(AEditor: PCustomCodeEditor);
  1792. begin
  1793. Inc(LockFlag);
  1794. end;
  1795. procedure TCustomCodeEditorCore.UnLock(AEditor: PCustomCodeEditor);
  1796. begin
  1797. {$ifdef DEBUG}
  1798. if LockFlag=0 then
  1799. Bug('negative lockflag',nil)
  1800. else
  1801. {$endif DEBUG}
  1802. Dec(LockFlag);
  1803. if (LockFlag>0) then
  1804. Exit;
  1805. if LimitsChangedCalled then
  1806. begin
  1807. DoLimitsChanged;
  1808. LimitsChangedCalled:=false;
  1809. end;
  1810. if ModifiedChangedCalled then
  1811. begin
  1812. DoModifiedChanged;
  1813. ModifiedChangedCalled:=false;
  1814. end;
  1815. if TabSizeChangedCalled then
  1816. begin
  1817. DoTabSizeChanged;
  1818. TabSizeChangedCalled:=false;
  1819. end;
  1820. if StoreUndoChangedCalled then
  1821. begin
  1822. DoStoreUndoChanged;
  1823. StoreUndoChangedCalled:=false;
  1824. end;
  1825. if ContentsChangedCalled then
  1826. begin
  1827. DoContentsChanged;
  1828. ContentsChangedCalled:=false;
  1829. end;
  1830. end;
  1831. function TCustomCodeEditorCore.UpdateAttrs(FromLine: sw_integer; Attrs: byte): sw_integer;
  1832. var MinLine: sw_integer;
  1833. procedure CallIt(P: PEditorBinding); {$ifndef FPC}far;{$endif}
  1834. var I: sw_integer;
  1835. begin
  1836. I:=DoUpdateAttrs(P^.Editor,FromLine,Attrs);
  1837. if (I<MinLine) or (MinLine=-1) then MinLine:=I;
  1838. end;
  1839. begin
  1840. MinLine:=-1;
  1841. Bindings^.ForEach(@CallIt);
  1842. UpdateAttrs:=MinLine;
  1843. end;
  1844. function TCustomCodeEditorCore.UpdateAttrsRange(FromLine, ToLine: sw_integer; Attrs: byte): sw_integer;
  1845. var MinLine: sw_integer;
  1846. procedure CallIt(P: PEditorBinding); {$ifndef FPC}far;{$endif}
  1847. var I: sw_integer;
  1848. begin
  1849. I:=DoUpdateAttrsRange(P^.Editor,FromLine,ToLine,Attrs);
  1850. if (I<MinLine) or (MinLine=-1) then MinLine:=I;
  1851. end;
  1852. begin
  1853. MinLine:=-1;
  1854. Bindings^.ForEach(@CallIt);
  1855. UpdateAttrsRange:=MinLine;
  1856. end;
  1857. function TCustomCodeEditorCore.DoUpdateAttrs(Editor: PCustomCodeEditor; FromLine: sw_integer; Attrs: byte): sw_integer;
  1858. type
  1859. TCharClass = (ccWhiteSpace,ccTab,ccAlpha,
  1860. ccNumber,ccHexNumber,ccRealNumber,
  1861. ccHash,ccSymbol);
  1862. var
  1863. SymbolIndex: Sw_integer;
  1864. CurrentCommentType : Byte;
  1865. FirstCC,LastCC: TCharClass;
  1866. InAsm,InComment,InSingleLineComment,InDirective,InString: boolean;
  1867. X,ClassStart: Sw_integer;
  1868. SymbolConcat: string;
  1869. LineText,Format: string;
  1870. function MatchSymbol(const What, S: string): boolean;
  1871. var Match: boolean;
  1872. begin
  1873. Match:=false;
  1874. if length(What)>=length(S) then
  1875. if copy(What,1+length(What)-length(S),length(S))=S then
  1876. Match:=true;
  1877. MatchSymbol:=Match;
  1878. end;
  1879. var MatchedSymbol: boolean;
  1880. MatchingSymbol: string;
  1881. type TPartialType = (pmNone,pmLeft,pmRight,pmAny);
  1882. function MatchesAnySpecSymbol(What: string; SClass: TSpecSymbolClass; PartialMatch: TPartialType;
  1883. CaseInsensitive: boolean): boolean;
  1884. var S: string;
  1885. I: Sw_integer;
  1886. Match,Found: boolean;
  1887. begin
  1888. Found:=false;
  1889. if CaseInsensitive then
  1890. What:=UpcaseStr(What);
  1891. if What<>'' then
  1892. for I:=1 to Editor^.GetSpecSymbolCount(SClass) do
  1893. begin
  1894. SymbolIndex:=I;
  1895. S:=Editor^.GetSpecSymbol(SClass,I-1);
  1896. if (length(What)<length(S)) or
  1897. ((PartialMatch=pmNone) and (length(S)<>length(What)))
  1898. then
  1899. Match:=false
  1900. else
  1901. begin
  1902. if CaseInsensitive then
  1903. S:=UpcaseStr(S);
  1904. case PartialMatch of
  1905. pmNone : Match:=What=S;
  1906. pmRight:
  1907. Match:=copy(What,length(What)-length(S)+1,length(S))=S;
  1908. else Match:=MatchSymbol(What,S);
  1909. end;
  1910. end;
  1911. if Match then
  1912. begin
  1913. MatchingSymbol:=S; Found:=true; Break;
  1914. end;
  1915. end;
  1916. MatchedSymbol:=MatchedSymbol or Found;
  1917. MatchesAnySpecSymbol:=Found;
  1918. end;
  1919. function IsCommentPrefix: boolean;
  1920. begin
  1921. IsCommentPrefix:=MatchesAnySpecSymbol(SymbolConcat,ssCommentPrefix,pmLeft,false);
  1922. end;
  1923. function IsSingleLineCommentPrefix: boolean;
  1924. begin
  1925. IsSingleLineCommentPrefix:=MatchesAnySpecSymbol(SymbolConcat,ssCommentSingleLinePrefix,pmLeft,false);
  1926. end;
  1927. function IsCommentSuffix: boolean;
  1928. begin
  1929. IsCommentSuffix:=(MatchesAnySpecSymbol(SymbolConcat,ssCommentSuffix,pmRight,false))
  1930. and (CurrentCommentType=SymbolIndex);
  1931. end;
  1932. function IsStringPrefix: boolean;
  1933. begin
  1934. IsStringPrefix:=MatchesAnySpecSymbol(SymbolConcat,ssStringPrefix,pmLeft,false);
  1935. end;
  1936. function IsStringSuffix: boolean;
  1937. begin
  1938. IsStringSuffix:=MatchesAnySpecSymbol(SymbolConcat,ssStringSuffix,pmRight,false);
  1939. end;
  1940. function IsDirectivePrefix: boolean;
  1941. begin
  1942. IsDirectivePrefix:=MatchesAnySpecSymbol(SymbolConcat,ssDirectivePrefix,pmLeft,false);
  1943. end;
  1944. function IsDirectiveSuffix: boolean;
  1945. begin
  1946. IsDirectiveSuffix:=MatchesAnySpecSymbol(SymbolConcat,ssDirectiveSuffix,pmRight,false);
  1947. end;
  1948. function IsAsmPrefix(const WordS: string): boolean;
  1949. var
  1950. StoredMatchedSymbol : boolean;
  1951. begin
  1952. StoredMatchedSymbol:=MatchedSymbol;
  1953. IsAsmPrefix:=MatchesAnySpecSymbol(WordS,ssAsmPrefix,pmNone,true);
  1954. MatchedSymbol:=StoredMatchedSymbol;
  1955. end;
  1956. function IsAsmSuffix(const WordS: string): boolean;
  1957. var
  1958. StoredMatchedSymbol : boolean;
  1959. begin
  1960. StoredMatchedSymbol:=MatchedSymbol;
  1961. IsAsmSuffix:=MatchesAnySpecSymbol(WordS,ssAsmSuffix,pmNone,true);
  1962. MatchedSymbol:=StoredMatchedSymbol;
  1963. end;
  1964. function GetCharClass(C: char): TCharClass;
  1965. var CC: TCharClass;
  1966. begin
  1967. if C in WhiteSpaceChars then CC:=ccWhiteSpace else
  1968. if C in TabChars then CC:=ccTab else
  1969. if C in HashChars then CC:=ccHash else
  1970. if (LastCC=ccHexNumber) and (C in HexNumberChars) then CC:=ccHexNumber else
  1971. if C in NumberChars then CC:=ccNumber else
  1972. if (LastCC=ccNumber) and (C in RealNumberChars) then
  1973. begin
  1974. if (C='.') then
  1975. begin
  1976. if (LineText[X+1]='.') then
  1977. cc:=ccSymbol
  1978. else
  1979. cc:=ccRealNumber;
  1980. end
  1981. else {'E','e'}
  1982. begin
  1983. if (LineText[X+1]in ['+','-','0'..'9']) then
  1984. cc:=ccRealNumber
  1985. else
  1986. cc:=ccAlpha
  1987. end;
  1988. end else
  1989. if C in AlphaChars then CC:=ccAlpha else
  1990. CC:=ccSymbol;
  1991. GetCharClass:=CC;
  1992. end;
  1993. procedure FormatWord(SClass: TCharClass; StartX:Sw_integer;EndX: Sw_integer);
  1994. var
  1995. C: byte;
  1996. WordS: string;
  1997. begin
  1998. C:=0;
  1999. WordS:=copy(LineText,StartX,EndX-StartX+1);
  2000. if IsAsmSuffix(WordS) and (InAsm=true) and (InComment=false) and
  2001. (InString=false) and (InDirective=false) then InAsm:=false;
  2002. if InDirective then C:=coDirectiveColor else
  2003. if InComment then C:=coCommentColor else
  2004. if InString then C:=coStringColor else
  2005. if InAsm then
  2006. begin
  2007. if (SClass=ccAlpha) and Editor^.IsAsmReservedWord(WordS) then
  2008. C:=coReservedWordColor
  2009. else
  2010. C:=coAssemblerColor;
  2011. end
  2012. else
  2013. case SClass of
  2014. ccWhiteSpace :
  2015. C:=coWhiteSpaceColor;
  2016. ccTab :
  2017. C:=coTabColor;
  2018. ccHexNumber:
  2019. C:=coHexNumberColor;
  2020. ccNumber,
  2021. ccRealNumber :
  2022. C:=coNumberColor;
  2023. ccHash :
  2024. C:=coStringColor;
  2025. ccSymbol :
  2026. C:=coSymbolColor;
  2027. ccAlpha :
  2028. begin
  2029. if Editor^.IsReservedWord(WordS) then
  2030. C:=coReservedWordColor
  2031. else
  2032. C:=coIdentifierColor;
  2033. end;
  2034. end;
  2035. if EndX+1>=StartX then
  2036. FillChar(Format[StartX],EndX+1-StartX,C);
  2037. if IsAsmPrefix(WordS) and (InString=false) and
  2038. (InAsm=false) and (InComment=false) and (InDirective=false) then
  2039. InAsm:=true;
  2040. end;
  2041. procedure ProcessChar(C: char);
  2042. var CC: TCharClass;
  2043. EX: Sw_integer;
  2044. begin
  2045. CC:=GetCharClass(C);
  2046. if ClassStart=X then
  2047. FirstCC:=CC;
  2048. if ( (CC<>LastCC) and
  2049. (
  2050. ((FirstCC=ccNumber) and (CC<>ccRealNumber) {and (CC<>ccNumber)}) or
  2051. (((CC<>ccAlpha) or (LastCC<>ccNumber) ) and
  2052. ( (CC<>ccNumber) or (LastCC<>ccAlpha) ) and
  2053. ( (CC<>ccNumber) or (LastCC<>ccHash) ) and
  2054. ( (CC<>ccRealNumber) or (LastCC<>ccNumber))
  2055. ))) or
  2056. (X>length(LineText)) or (CC=ccSymbol) then
  2057. begin
  2058. MatchedSymbol:=false;
  2059. EX:=X-1;
  2060. if (CC=ccSymbol) then
  2061. begin
  2062. if length(SymbolConcat)>=High(SymbolConcat) then
  2063. Delete(SymbolConcat,1,1);
  2064. SymbolConcat:=SymbolConcat+C;
  2065. if IsCommentSuffix and (InComment) then
  2066. Inc(EX) else
  2067. if IsStringSuffix and (InString) then
  2068. Inc(EX) else
  2069. if IsDirectiveSuffix and (InDirective) then
  2070. Inc(EX);
  2071. end;
  2072. if CC=ccRealNumber then
  2073. Inc(EX);
  2074. if (C='$') and (MatchedSymbol=false) and (IsDirectivePrefix=false) then
  2075. CC:=ccHexNumber;
  2076. if CC<>ccSymbol then SymbolConcat:='';
  2077. FormatWord(LastCC,ClassStart,EX);
  2078. ClassStart:=EX+1;
  2079. if ClassStart=X then
  2080. FirstCC:=CC;
  2081. case CC of
  2082. ccAlpha : ;
  2083. ccNumber :
  2084. if (LastCC<>ccAlpha) then;
  2085. ccSymbol :
  2086. if IsDirectivePrefix and (InComment=true) and (CurrentCommentType=1) and
  2087. (InDirective=false) then
  2088. begin InDirective:=true; InComment:=false; Dec(ClassStart,length(MatchingSymbol)-1); end else
  2089. if IsDirectiveSuffix and (InComment=false) and (InDirective=true) then
  2090. InDirective:=false else
  2091. if IsCommentPrefix and (InComment=false) and (InString=false) then
  2092. begin
  2093. InComment:=true;
  2094. CurrentCommentType:=SymbolIndex;
  2095. InSingleLineComment:=IsSingleLineCommentPrefix;
  2096. {InString:=false; }
  2097. Dec(ClassStart,length(MatchingSymbol)-1);
  2098. { Remove (* from SymbolConcat to avoid problem with (*) PM }
  2099. { fixes part of bug 1617 }
  2100. { but removed proper directive prefix detection ... }
  2101. if MatchingSymbol[length(MatchingSymbol)]=Editor^.GetSpecSymbol(ssCommentSuffix,SymbolIndex)[1] then
  2102. Delete(SymbolConcat,1,length(MatchingSymbol));
  2103. end
  2104. else
  2105. if IsCommentSuffix and (InComment) then
  2106. begin InComment:=false; InString:=false; end else
  2107. if IsStringPrefix and (InComment=false) and (InString=false) then
  2108. begin InString:=true; Dec(ClassStart,length(MatchingSymbol)-1); end else
  2109. if IsStringSuffix and (InComment=false) and (InString=true) then
  2110. InString:=false;
  2111. end;
  2112. if MatchedSymbol and (InComment=false) then
  2113. SymbolConcat:='';
  2114. LastCC:=CC;
  2115. end;
  2116. end;
  2117. var CurLine: Sw_integer;
  2118. Line,NextLine,PrevLine{,OldLine}: PCustomLine;
  2119. PrevLI,LI,NextLI: PEditorLineInfo;
  2120. begin
  2121. if (not Editor^.IsFlagSet(efSyntaxHighlight)) or (FromLine>=GetLineCount) then
  2122. begin
  2123. SetLineFormat(Editor,FromLine,'');
  2124. DoUpdateAttrs:=GetLineCount;
  2125. {$ifdef TEST_PARTIAL_SYNTAX}
  2126. LastSyntaxedLine:=GetLineCount;
  2127. if not SyntaxComplete then
  2128. begin
  2129. SyntaxComplete:=true;
  2130. DoSyntaxStateChanged;
  2131. end;
  2132. (* { no Idle necessary }
  2133. EventMask:=EventMask and not evIdle;*)
  2134. {$endif TEST_PARTIAL_SYNTAX}
  2135. Editor^.SyntaxStateChanged;
  2136. Exit;
  2137. end;
  2138. {$ifdef TEST_PARTIAL_SYNTAX}
  2139. If Editor^.IsFlagSet(efSyntaxHighlight) and (LastSyntaxedLine<FromLine)
  2140. and (FromLine<GetLineCount) then
  2141. CurLine:=LastSyntaxedLine
  2142. else
  2143. {$endif TEST_PARTIAL_SYNTAX}
  2144. CurLine:=FromLine;
  2145. if CurLine>0 then
  2146. PrevLine:=GetLine(CurLine-1)
  2147. else
  2148. PrevLine:=nil;
  2149. repeat
  2150. Line:=GetLine(CurLine);
  2151. if Assigned(PrevLine) then PrevLI:=PrevLine^.GetEditorInfo(Editor) else PrevLI:=nil;
  2152. if Assigned(Line) then LI:=Line^.GetEditorInfo(Editor) else LI:=nil;
  2153. InSingleLineComment:=false;
  2154. if PrevLI<>nil then
  2155. begin
  2156. InAsm:=PrevLI^.EndsWithAsm;
  2157. InComment:=PrevLI^.EndsWithComment and not PrevLI^.EndsInSingleLineComment;
  2158. CurrentCommentType:=PrevLI^.EndCommentType;
  2159. InDirective:=PrevLI^.EndsWithDirective;
  2160. end
  2161. else
  2162. begin
  2163. InAsm:=false;
  2164. InComment:=false;
  2165. CurrentCommentType:=0;
  2166. InDirective:=false;
  2167. end;
  2168. { OldLine:=Line;}
  2169. if (not Editor^.IsFlagSet(efKeepLineAttr)) then
  2170. begin
  2171. LI^.BeginsWithAsm:=InAsm;
  2172. LI^.BeginsWithComment:=InComment;
  2173. LI^.BeginsWithDirective:=InDirective;
  2174. LI^.BeginCommentType:=CurrentCommentType;
  2175. end
  2176. else
  2177. begin
  2178. InAsm:=LI^.BeginsWithAsm;
  2179. InComment:=LI^.BeginsWithComment;
  2180. InDirective:=LI^.BeginsWithDirective;
  2181. CurrentCommentType:=LI^.BeginCommentType;
  2182. end;
  2183. LineText:=GetLineText(CurLine);
  2184. Format:=CharStr(chr(coTextColor),length(LineText));
  2185. LastCC:=ccWhiteSpace;
  2186. ClassStart:=1;
  2187. SymbolConcat:='';
  2188. InString:=false;
  2189. if LineText<>'' then
  2190. begin
  2191. for X:=1 to length(LineText) do
  2192. ProcessChar(LineText[X]);
  2193. Inc(X);
  2194. ProcessChar(' ');
  2195. end;
  2196. SetLineFormat(Editor,CurLine,Format);
  2197. LI^.EndsWithAsm:=InAsm;
  2198. LI^.EndsWithComment:=InComment;
  2199. LI^.EndsInSingleLineComment:=InSingleLineComment;
  2200. LI^.EndCommentType:=CurrentCommentType;
  2201. LI^.EndsWithDirective:=InDirective;
  2202. Inc(CurLine);
  2203. if CurLine>=GetLineCount then
  2204. Break;
  2205. NextLine:=GetLine(CurLine);
  2206. if Assigned(NextLine) then NextLI:=NextLine^.GetEditorInfo(Editor) else NextLI:=nil;
  2207. if ((Attrs and attrForceFull)=0) then
  2208. if (* Why should we go
  2209. (InAsm=false) and (NextLI^.BeginsWithAsm=false) and
  2210. (InComment=false) and (NextLI^.BeginsWithComment=false) and
  2211. (InDirective=false) and (NextLI^.BeginsWithDirective=false) and
  2212. { OldLine = Line so this is nonsense}
  2213. (PrevLI^.EndsWithComment=LI^.EndsWithComment) and
  2214. (PrevLI^.EndsWithAsm=LI^.EndsWithAsm) and
  2215. (PrevLI^.EndsWithDirective=LI^.EndsWithDirective) and *)
  2216. {$ifdef TEST_PARTIAL_SYNTAX}
  2217. (CurLine>FromLine) and
  2218. {$endif TEST_PARTIAL_SYNTAX}
  2219. (NextLI^.BeginsWithAsm=LI^.EndsWithAsm) and
  2220. (NextLI^.BeginsWithComment=LI^.EndsWithComment) and
  2221. (NextLI^.BeginsWithDirective=LI^.EndsWithDirective) and
  2222. (NextLI^.BeginCommentType=LI^.EndCommentType) and
  2223. (NextLI^.Format<>nil) then
  2224. Break;
  2225. {$ifdef TEST_PARTIAL_SYNTAX}
  2226. if (CurLine<GetLineCount) and
  2227. (CurLine>FromLine) and
  2228. ((Attrs and attrForceFull)=0) and
  2229. (CurLine>GetLastVisibleLine) then
  2230. begin
  2231. If SyntaxComplete then
  2232. begin
  2233. SyntaxComplete:=false;
  2234. DoSyntaxStateChanged;
  2235. end;
  2236. LastSyntaxedLine:=CurLine-1;
  2237. break;
  2238. end;
  2239. {$endif TEST_PARTIAL_SYNTAX}
  2240. PrevLine:=Line;
  2241. until false;
  2242. DoUpdateAttrs:=CurLine;
  2243. {$ifdef TEST_PARTIAL_SYNTAX}
  2244. If LastSyntaxedLine<CurLine-1 then
  2245. LastSyntaxedLine:=CurLine-1;
  2246. if CurLine=GetLineCount then
  2247. begin
  2248. SyntaxComplete:=true;
  2249. DoSyntaxStateChanged;
  2250. end;
  2251. {$endif TEST_PARTIAL_SYNTAX}
  2252. end;
  2253. function TCustomCodeEditorCore.DoUpdateAttrsRange(Editor: PCustomCodeEditor; FromLine, ToLine: sw_integer;
  2254. Attrs: byte): sw_integer;
  2255. var Line: Sw_integer;
  2256. begin
  2257. Lock(Editor);
  2258. Line:=FromLine;
  2259. repeat
  2260. Line:=DoUpdateAttrs(Editor,Line,Attrs);
  2261. until (Line>=GetLineCount) or (Line>ToLine);
  2262. DoUpdateAttrsRange:=Line;
  2263. Unlock(Editor);
  2264. end;
  2265. procedure TCustomCodeEditorCore.AddAction(AAction: byte; AStartPos, AEndPos: TPoint; AText: string;AFlags : longint);
  2266. begin
  2267. Abstract;
  2268. end;
  2269. procedure TCustomCodeEditorCore.AddGroupedAction(AAction : byte);
  2270. begin
  2271. Abstract;
  2272. end;
  2273. procedure TCustomCodeEditorCore.CloseGroupedAction(AAction : byte);
  2274. begin
  2275. Abstract;
  2276. end;
  2277. function TCustomCodeEditorCore.GetUndoActionCount: sw_integer;
  2278. begin
  2279. Abstract;
  2280. GetUndoActionCount:=0;
  2281. end;
  2282. function TCustomCodeEditorCore.GetRedoActionCount: sw_integer;
  2283. begin
  2284. Abstract;
  2285. GetRedoActionCount:=0;
  2286. end;
  2287. destructor TCustomCodeEditorCore.Done;
  2288. begin
  2289. {$ifdef DEBUG}
  2290. if Bindings^.Count>0 then
  2291. ErrorBox('Internal error: there are still '+IntToStr(Bindings^.Count)+' editors '+
  2292. 'registered at TCodeEditorCode.Done!!!',nil);
  2293. {$endif}
  2294. if Assigned(Bindings) then Dispose(Bindings, Done); Bindings:=nil;
  2295. inherited Done;
  2296. end;
  2297. procedure TCustomCodeEditor.Lock;
  2298. begin
  2299. Inc(ELockFlag);
  2300. {$ifdef FVISION}
  2301. LockScreenUpdate;
  2302. {$endif FVISION}
  2303. end;
  2304. procedure TCustomCodeEditor.UnLock;
  2305. begin
  2306. {$ifdef DEBUG}
  2307. if Elockflag=0 then
  2308. Bug('negative lockflag',nil)
  2309. else
  2310. {$endif DEBUG}
  2311. {$ifdef FVISION}
  2312. UnlockScreenUpdate;
  2313. {$endif FVISION}
  2314. Dec(ELockFlag);
  2315. if (ELockFlag>0) then
  2316. Exit;
  2317. if DrawCalled then
  2318. DrawView;
  2319. If DrawCursorCalled then
  2320. Begin
  2321. DrawCursor;
  2322. DrawCursorCalled:=false;
  2323. End;
  2324. end;
  2325. procedure TCustomCodeEditor.DrawIndicator;
  2326. begin
  2327. { Abstract }
  2328. end;
  2329. procedure TCustomCodeEditor.AdjustSelectionPos(CurPosX, CurPosY: sw_integer; DeltaX, DeltaY: sw_integer);
  2330. var CP: TPoint;
  2331. begin
  2332. if ValidBlock=false then Exit;
  2333. CP.X:=CurPosX; CP.Y:=CurPosY;
  2334. if (PosToOfsP(SelStart)<=PosToOfsP(CP)) and (PosToOfsP(CP)<PosToOfsP(SelEnd)) then
  2335. begin
  2336. { CurPos is IN selection }
  2337. Inc(SelEnd.Y,DeltaY);
  2338. if (CP.Y=SelEnd.Y) and
  2339. ((SelStart.Y<>SelEnd.Y) or (SelStart.X<=CP.X)) and
  2340. (CP.X<=SelEnd.X) then
  2341. Inc(SelEnd.X,DeltaX);
  2342. SelectionChanged;
  2343. end
  2344. else
  2345. if (PosToOfsP(CP)<=PosToOfsP(SelStart)) then
  2346. begin
  2347. { CurPos is BEFORE selection }
  2348. if (CP.Y=SelStart.Y) and (CP.Y=SelEnd.Y) and (DeltaY<0) then
  2349. begin
  2350. SelStart:=CurPos; SelEnd:=CurPos;
  2351. end
  2352. else
  2353. if (CP.Y=SelStart.Y) then
  2354. begin
  2355. if CP.X<SelStart.X then
  2356. Inc(SelStart.X,DeltaX);
  2357. end;
  2358. { else}
  2359. begin
  2360. Inc(SelStart.Y,DeltaY);
  2361. Inc(SelEnd.Y,DeltaY);
  2362. end;
  2363. if SelEnd.Y=CurPos.Y then Inc(SelEnd.X,DeltaX);
  2364. SelectionChanged;
  2365. end
  2366. else
  2367. begin
  2368. { CurPos is AFTER selection }
  2369. { actually we don't have to do anything here }
  2370. end;
  2371. end;
  2372. function TCustomCodeEditor.GetFlags: longint;
  2373. begin
  2374. { Abstract }
  2375. GetFlags:=0;
  2376. end;
  2377. procedure TCustomCodeEditor.SetFlags(AFlags: longint);
  2378. begin
  2379. { Abstract }
  2380. end;
  2381. function TCustomCodeEditor.GetModified: boolean;
  2382. begin
  2383. { Abstract }
  2384. GetModified:=true;
  2385. end;
  2386. procedure TCustomCodeEditor.SetModified(AModified: boolean);
  2387. begin
  2388. { Abstract }
  2389. end;
  2390. function TCustomCodeEditor.GetStoreUndo: boolean;
  2391. begin
  2392. { Abstract }
  2393. GetStoreUndo:=false;
  2394. end;
  2395. procedure TCustomCodeEditor.SetStoreUndo(AStore: boolean);
  2396. begin
  2397. { Abstract }
  2398. end;
  2399. function TCustomCodeEditor.GetSyntaxCompleted: boolean;
  2400. begin
  2401. { Abstract }
  2402. GetSyntaxCompleted:=true;
  2403. end;
  2404. procedure TCustomCodeEditor.SetSyntaxCompleted(SC : boolean);
  2405. begin
  2406. { Abstract }
  2407. end;
  2408. function TCustomCodeEditor.GetLastSyntaxedLine: sw_integer;
  2409. begin
  2410. Abstract;
  2411. GetLastSyntaxedLine:=0;
  2412. end;
  2413. procedure TCustomCodeEditor.SetLastSyntaxedLine(ALine: sw_integer);
  2414. begin
  2415. Abstract;
  2416. end;
  2417. function TCustomCodeEditor.IsFlagSet(AFlag: longint): boolean;
  2418. begin
  2419. IsFlagSet:=(GetFlags and AFlag)=AFlag;
  2420. end;
  2421. function TCustomCodeEditor.GetTabSize: integer;
  2422. begin
  2423. { Abstract }
  2424. GetTabSize:=5;
  2425. end;
  2426. procedure TCustomCodeEditor.SetTabSize(ATabSize: integer);
  2427. begin
  2428. { Abstract }
  2429. end;
  2430. function TCustomCodeEditor.GetIndentSize: integer;
  2431. begin
  2432. { Abstract }
  2433. GetIndentSize:=1;
  2434. end;
  2435. procedure TCustomCodeEditor.SetIndentSize(AIndentSize: integer);
  2436. begin
  2437. { Abstract }
  2438. end;
  2439. function TCustomCodeEditor.IsReadOnly: boolean;
  2440. begin
  2441. { Abstract }
  2442. IsReadOnly:=false;
  2443. end;
  2444. function TCustomCodeEditor.IsClipboard: Boolean;
  2445. begin
  2446. { Abstract }
  2447. IsClipboard:=false;
  2448. end;
  2449. function TCustomCodeEditor.GetLineCount: sw_integer;
  2450. begin
  2451. Abstract;
  2452. GetLineCount:=0;
  2453. end;
  2454. function TCustomCodeEditor.GetLine(LineNo: sw_integer): PCustomLine;
  2455. begin
  2456. Abstract;
  2457. GetLine:=nil;
  2458. end;
  2459. function TCustomCodeEditor.CharIdxToLinePos(Line,CharIdx: sw_integer): sw_integer;
  2460. begin
  2461. Abstract;
  2462. CharIdxToLinePos:=0;
  2463. end;
  2464. function TCustomCodeEditor.LinePosToCharIdx(Line,X: sw_integer): sw_integer;
  2465. begin
  2466. Abstract;
  2467. LinePosToCharIdx:=0;
  2468. end;
  2469. function TCustomCodeEditor.GetLineText(I: sw_integer): string;
  2470. begin
  2471. Abstract;
  2472. GetLineText:='';
  2473. end;
  2474. procedure TCustomCodeEditor.SetDisplayText(I: sw_integer;const S: string);
  2475. begin
  2476. Abstract;
  2477. end;
  2478. function TCustomCodeEditor.GetDisplayText(I: sw_integer): string;
  2479. begin
  2480. Abstract;
  2481. GetDisplayText:='';
  2482. end;
  2483. procedure TCustomCodeEditor.SetLineText(I: sw_integer;const S: string);
  2484. begin
  2485. Abstract;
  2486. end;
  2487. procedure TCustomCodeEditor.GetDisplayTextFormat(I: sw_integer;var DT,DF:string);
  2488. begin
  2489. Abstract;
  2490. end;
  2491. function TCustomCodeEditor.GetLineFormat(I: sw_integer): string;
  2492. begin
  2493. { Abstract }
  2494. GetLineFormat:='';
  2495. end;
  2496. procedure TCustomCodeEditor.SetLineFormat(I: sw_integer;const S: string);
  2497. begin
  2498. { Abstract }
  2499. end;
  2500. procedure TCustomCodeEditor.DeleteAllLines;
  2501. begin
  2502. Abstract;
  2503. end;
  2504. procedure TCustomCodeEditor.DeleteLine(I: sw_integer);
  2505. begin
  2506. Abstract;
  2507. end;
  2508. function TCustomCodeEditor.InsertLine(LineNo: sw_integer; const S: string): PCustomLine;
  2509. begin
  2510. Abstract;
  2511. InsertLine:=nil; { eliminate compiler warning }
  2512. end;
  2513. procedure TCustomCodeEditor.AddLine(const S: string);
  2514. begin
  2515. Abstract;
  2516. end;
  2517. function TCustomCodeEditor.GetErrorMessage: string;
  2518. begin
  2519. Abstract;
  2520. GetErrorMessage:='';
  2521. end;
  2522. procedure TCustomCodeEditor.SetErrorMessage(const S: string);
  2523. begin
  2524. Abstract;
  2525. end;
  2526. procedure TCustomCodeEditor.GetContent(ALines: PUnsortedStringCollection);
  2527. begin
  2528. Abstract;
  2529. end;
  2530. procedure TCustomCodeEditor.SetContent(ALines: PUnsortedStringCollection);
  2531. begin
  2532. Abstract;
  2533. end;
  2534. function TCustomCodeEditor.LoadFromStream(Stream: PStream): boolean;
  2535. begin
  2536. Abstract;
  2537. LoadFromStream:=false;
  2538. end;
  2539. function TCustomCodeEditor.SaveToStream(Stream: PStream): boolean;
  2540. var A,B: TPoint;
  2541. begin
  2542. A.Y:=0; A.X:=0;
  2543. B.Y:=GetLineCount-1;
  2544. if GetLineCount>0 then
  2545. B.X:=length(GetDisplayText(B.Y))
  2546. else
  2547. B.X:=0;
  2548. SaveToStream:=SaveAreaToStream(Stream,A,B);
  2549. end;
  2550. function TCustomCodeEditor.SaveAreaToStream(Stream: PStream; StartP,EndP: TPoint): boolean;
  2551. begin
  2552. Abstract;
  2553. SaveAreaToStream:=false;
  2554. end;
  2555. function TCustomCodeEditor.LoadFromFile(const AFileName: string): boolean;
  2556. var S: PBufStream;
  2557. OK: boolean;
  2558. begin
  2559. New(S, Init(AFileName,stOpenRead,EditorTextBufSize));
  2560. OK:=Assigned(S);
  2561. {$ifdef TEST_PARTIAL_SYNTAX}
  2562. SetSyntaxCompleted(false);
  2563. { Idle necessary }
  2564. EventMask:=EventMask or evIdle;
  2565. {$endif TEST_PARTIAL_SYNTAX}
  2566. if OK then OK:=LoadFromStream(S);
  2567. if Assigned(S) then Dispose(S, Done);
  2568. LoadFromFile:=OK;
  2569. end;
  2570. function TCustomCodeEditor.SaveToFile(const AFileName: string): boolean;
  2571. var OK: boolean;
  2572. S: PBufStream;
  2573. begin
  2574. New(S, Init(AFileName,stCreate,EditorTextBufSize));
  2575. OK:=Assigned(S) and (S^.Status=stOK);
  2576. if OK then OK:=SaveToStream(S);
  2577. if Assigned(S) then Dispose(S, Done);
  2578. SaveToFile:=OK;
  2579. end;
  2580. function TCustomCodeEditor.InsertFrom(Editor: PCustomCodeEditor): Boolean;
  2581. var OK: boolean;
  2582. CP,RX,RSX,LineDelta,LineCount: Sw_integer;
  2583. StartPos,DestPos,BPos,EPos: TPoint;
  2584. LineStartX,LineEndX: Sw_integer;
  2585. TabSize,CharIdxStart,CharIdxEnd: Sw_integer;
  2586. S,DS,BeforeS,OrigS,AfterS: string;
  2587. VerticalBlock: boolean;
  2588. SEnd: TPoint;
  2589. begin
  2590. if Editor^.IsFlagSet(efVerticalBlocks) then
  2591. begin
  2592. NotImplemented;
  2593. Exit;
  2594. end;
  2595. Lock;
  2596. { every data in the clipboard gets a new line }
  2597. if (Clipboard=@Self) and (CurPos.X>0) then
  2598. InsertNewLine;
  2599. OK:=(Editor^.SelStart.X<>Editor^.SelEnd.X) or (Editor^.SelStart.Y<>Editor^.SelEnd.Y);
  2600. if OK then
  2601. begin
  2602. StartPos:=CurPos; DestPos:=CurPos;
  2603. EPos:=CurPos;
  2604. VerticalBlock:=Editor^.IsFlagSet(efVerticalBlocks);
  2605. LineDelta:=0; LineCount:=(Editor^.SelEnd.Y-Editor^.SelStart.Y)+1;
  2606. OK:=GetLineCount<MaxLineCount;
  2607. OrigS:=GetLineText(DestPos.Y);
  2608. BeforeS:=Copy(OrigS,1,LinePosToCharIdx(DestPos.Y,DestPos.X-1));
  2609. { we might need to add some spaces here,
  2610. but how many ? }
  2611. TabSize:=GetTabSize;
  2612. CP:=1; RX:=0;
  2613. while (CP<=length(BeforeS)) do
  2614. begin
  2615. if (BeforeS[CP]=TAB) then
  2616. Inc(RX,TabSize-(RX mod TabSize))
  2617. else
  2618. Inc(RX);
  2619. Inc(CP);
  2620. end;
  2621. BeforeS:=BeforeS+CharStr(' ',DestPos.X-RX);
  2622. AfterS:=Copy(OrigS,LinePosToCharIdx(DestPos.Y,DestPos.X),High(OrigS));
  2623. BPos:=CurPos;
  2624. while OK and (LineDelta<LineCount) do
  2625. begin
  2626. if (LineDelta>0) and (VerticalBlock=false) then
  2627. begin
  2628. InsertLine(DestPos.Y,'');
  2629. EPOS.X:=0;EPos.Y:=DestPos.Y;
  2630. AddAction(eaInsertLine,BPos,EPos,'',GetFlags);
  2631. LimitsChanged;
  2632. end;
  2633. If LineDelta>0 then
  2634. BeforeS:='';
  2635. if (LineDelta=0) or VerticalBlock then
  2636. LineStartX:=Editor^.SelStart.X
  2637. else
  2638. LineStartX:=0;
  2639. if (LineDelta=LineCount-1) or VerticalBlock then
  2640. LineEndX:=Editor^.SelEnd.X-1
  2641. else
  2642. LineEndX:=High(S);
  2643. CharIdxStart:=Editor^.LinePosToCharIdx(Editor^.SelStart.Y+LineDelta,LineStartX);
  2644. CharIdxEnd:=Editor^.LinePosToCharIdx(Editor^.SelStart.Y+LineDelta,LineEndX);
  2645. if LineEndX<LineStartX then
  2646. S:=''
  2647. else if VerticalBlock then
  2648. S:=RExpand(copy(Editor^.GetLineText(Editor^.SelStart.Y+LineDelta),CharIdxStart,CharIdxEnd-CharIdxStart+1),
  2649. Min(CharIdxEnd-CharIdxStart+1,High(S)))
  2650. else
  2651. S:=copy(Editor^.GetLineText(Editor^.SelStart.Y+LineDelta),CharIdxStart,CharIdxEnd-CharIdxStart+1);
  2652. if VerticalBlock=false then
  2653. begin
  2654. DS:=BeforeS+S;
  2655. CP:=1; RX:=0;
  2656. RSX :=0;
  2657. while (CP<=length(DS)) do
  2658. begin
  2659. if (DS[CP]=TAB) then
  2660. Inc(RX,TabSize-(RX mod TabSize))
  2661. else
  2662. Inc(RX);
  2663. if CP=length(BeforeS) then
  2664. RSX:=RX;
  2665. Inc(CP);
  2666. end;
  2667. if LineDelta=LineCount-1 then
  2668. begin
  2669. SetLineText(DestPos.Y,DS+AfterS);
  2670. BPos.X:=DestPos.X;BPos.Y:=DestPos.Y;
  2671. EPOS.X:=DestPos.X+RX-RSX;EPos.Y:=DestPos.Y;
  2672. AddAction(eaInsertText,BPos,EPos,S,GetFlags);
  2673. end
  2674. else
  2675. begin
  2676. SetLineText(DestPos.Y,DS);
  2677. BPos.X:=DestPos.X;BPos.Y:=DestPos.Y;
  2678. EPOS.X:=DestPos.X+RX-RSX;EPos.Y:=DestPos.Y;
  2679. AddAction(eaInsertText,BPos,EPos,S,GetFlags);
  2680. end;
  2681. BPos.X:=EPos.X;
  2682. if LineDelta=LineCount-1 then
  2683. begin
  2684. SEnd.Y:=DestPos.Y;
  2685. SEnd.X:=DestPos.X+RX-RSX;
  2686. end
  2687. else
  2688. begin
  2689. Inc(DestPos.Y);
  2690. DestPos.X:=0;
  2691. end;
  2692. end
  2693. else { if VerticalBlock=false then .. else }
  2694. begin
  2695. { this is not yet implemented !! PM }
  2696. S:=RExpand(S,LineEndX-LineStartX+1);
  2697. end;
  2698. Inc(LineDelta);
  2699. OK:=GetLineCount<MaxLineCount;
  2700. end;
  2701. if OK=false then EditorDialog(edTooManyLines,nil);
  2702. { mainly to force eaMove insertion }
  2703. if not IsClipboard then
  2704. SetCurPtr(EPos.X,EPos.Y);
  2705. SetCurPtr(StartPos.X,StartPos.Y);
  2706. UpdateAttrs(StartPos.Y,attrAll);
  2707. SetModified(true);
  2708. LimitsChanged;
  2709. SetSelection(CurPos,SEnd);
  2710. if IsClipboard then
  2711. begin
  2712. Inc(DestPos.X,length(S));
  2713. SetCurPtr(DestPos.X,DestPos.Y);
  2714. end;
  2715. DrawView;
  2716. end;
  2717. UnLock;
  2718. InsertFrom:=OK;
  2719. end;
  2720. function TCustomCodeEditor.InsertText(const S: string): Boolean;
  2721. var I: sw_integer;
  2722. OldPos: TPoint;
  2723. HoldUndo : boolean;
  2724. begin
  2725. Lock;
  2726. OldPos:=CurPos;
  2727. HoldUndo:=GetStoreUndo;
  2728. SetStoreUndo(false);
  2729. for I:=1 to length(S) do
  2730. AddChar(S[I]);
  2731. InsertText:=true;
  2732. SetStoreUndo(HoldUndo);
  2733. AddAction(eaInsertText,OldPos,CurPos,S,GetFlags);
  2734. UnLock;
  2735. end;
  2736. procedure TCustomCodeEditor.ModifiedChanged;
  2737. begin
  2738. { Abstract }
  2739. end;
  2740. procedure TCustomCodeEditor.PositionChanged;
  2741. begin
  2742. { Abstract }
  2743. end;
  2744. procedure TCustomCodeEditor.TabSizeChanged;
  2745. begin
  2746. { Abstract }
  2747. end;
  2748. procedure TCustomCodeEditor.SyntaxStateChanged;
  2749. begin
  2750. { Abstract }
  2751. end;
  2752. procedure TCustomCodeEditor.StoreUndoChanged;
  2753. begin
  2754. { Abstract }
  2755. end;
  2756. function TCustomCodeEditor.GetSpecSymbolCount(SpecClass: TSpecSymbolClass): integer;
  2757. begin
  2758. { Abstract }
  2759. GetSpecSymbolCount:=0;
  2760. end;
  2761. function TCustomCodeEditor.GetSpecSymbol(SpecClass: TSpecSymbolClass; Index: integer): string;
  2762. begin
  2763. Abstract;
  2764. GetSpecSymbol:='';
  2765. end;
  2766. function TCustomCodeEditor.IsReservedWord(const S: string): boolean;
  2767. begin
  2768. { Abstract }
  2769. IsReservedWord:=false;
  2770. end;
  2771. function TCustomCodeEditor.IsAsmReservedWord(const S: string): boolean;
  2772. begin
  2773. { Abstract }
  2774. IsAsmReservedWord:=false;
  2775. end;
  2776. function TCustomCodeEditor.TranslateCodeTemplate(const Shortcut: string; ALines: PUnsortedStringCollection): boolean;
  2777. begin
  2778. { Abstract }
  2779. TranslateCodeTemplate:=false;
  2780. end;
  2781. function TCustomCodeEditor.CompleteCodeWord(const WordS: string; var Text: string): boolean;
  2782. begin
  2783. { Abstract }
  2784. Text:='';
  2785. CompleteCodeWord:=false;
  2786. end;
  2787. function TCustomCodeEditor.GetCodeCompleteWord: string;
  2788. begin
  2789. { Abstract }
  2790. GetCodeCompleteWord:='';
  2791. end;
  2792. function TCustomCodeEditor.CreateFold(StartY,EndY: sw_integer; Collapsed: boolean): boolean;
  2793. var F,ParentF: PFold;
  2794. L: PCustomLine;
  2795. EI: PEditorLineInfo;
  2796. Y: sw_integer;
  2797. OK: boolean;
  2798. begin
  2799. OK:=true;
  2800. Lock;
  2801. for Y:=StartY to EndY do
  2802. begin
  2803. L:=GetLine(Y);
  2804. if assigned(L) then
  2805. EI:=L^.GetEditorInfo(@Self)
  2806. else
  2807. begin
  2808. CreateFold:=False;
  2809. exit;
  2810. end;
  2811. if Y=StartY then
  2812. ParentF:=EI^.Fold
  2813. else
  2814. OK:=OK and (EI^.Fold=ParentF);
  2815. if not OK then
  2816. Break;
  2817. end;
  2818. if OK then
  2819. begin
  2820. New(F, Init(@Self,ParentF,Collapsed));
  2821. for Y:=StartY to EndY do
  2822. GetLine(Y)^.GetEditorInfo(@Self)^.SetFold(F);
  2823. DrawView;
  2824. end;
  2825. UnLock;
  2826. CreateFold:=OK;
  2827. end;
  2828. procedure TCustomCodeEditor.FoldChanged(Fold: PFold);
  2829. var F: PFold;
  2830. I: sw_integer;
  2831. begin
  2832. for I:=0 to GetFoldCount-1 do
  2833. begin
  2834. F:=GetFold(I);
  2835. if F^.ParentFold=Fold then
  2836. FoldChanged(F);
  2837. end;
  2838. if Fold^.IsCollapsed then
  2839. begin
  2840. F:=GetLineFold(CurPos.Y); I:=CurPos.Y;
  2841. if F=Fold then
  2842. begin
  2843. while GetLineFold(I-1)=Fold do
  2844. Dec(I);
  2845. if I<>CurPos.Y then
  2846. SetCurPtr(CurPos.X,I);
  2847. end;
  2848. end;
  2849. DrawView;
  2850. end;
  2851. procedure TCustomCodeEditor.RemoveAllFolds;
  2852. var I: sw_integer;
  2853. L: PCustomLine;
  2854. begin
  2855. for I:=0 to GetLineCount-1 do
  2856. begin
  2857. L:=GetLine(I);
  2858. if not assigned(L) then exit;
  2859. with L^ do
  2860. with GetEditorInfo(@Self)^ do
  2861. SetFold(nil);
  2862. end;
  2863. DrawView;
  2864. end;
  2865. procedure TCustomCodeEditor.AdjustSelection(DeltaX, DeltaY: sw_integer);
  2866. begin
  2867. AdjustSelectionPos(CurPos.X,CurPos.Y,DeltaX,DeltaY);
  2868. end;
  2869. procedure TCustomCodeEditor.TrackCursor(Center: boolean);
  2870. var D,CP: TPoint;
  2871. begin
  2872. D:=Delta;
  2873. EditorToViewPoint(D,D); EditorToViewPoint(CurPos,CP);
  2874. if CP.Y<Delta.Y then D.Y:=CP.Y else
  2875. if CP.Y>Delta.Y+Size.Y-1 then D.Y:=CP.Y-Size.Y+1;
  2876. if CP.X<Delta.X then D.X:=CP.X else
  2877. if CP.X>Delta.X+Size.X-1 then D.X:=CP.X-Size.X+1;
  2878. if {((Delta.X<>D.X) or (Delta.Y<>D.Y)) and }Center then
  2879. begin
  2880. { loose centering for debugger PM }
  2881. while (CP.Y-D.Y)<(Size.Y div 3) do Dec(D.Y);
  2882. while (CP.Y-D.Y)>2*(Size.Y div 3) do Inc(D.Y);
  2883. end;
  2884. ViewToEditorPoint(D,D);
  2885. if (Delta.X<>D.X) or (Delta.Y<>D.Y) then
  2886. ScrollTo(D.X,D.Y);
  2887. DrawCursor;
  2888. end;
  2889. procedure TCustomCodeEditor.ScrollTo(X, Y: sw_Integer);
  2890. begin
  2891. inherited ScrollTo(X,Y);
  2892. if (HScrollBar=nil) or (VScrollBar=nil) then
  2893. begin Delta.X:=X; Delta.Y:=Y; end;
  2894. DrawView;
  2895. end;
  2896. function TCustomCodeEditor.IsModal: boolean;
  2897. var IsM: boolean;
  2898. begin
  2899. IsM:=GetState(sfModal);
  2900. if Assigned(Owner) then
  2901. IsM:=IsM or Owner^.GetState(sfModal);
  2902. IsModal:=IsM;
  2903. end;
  2904. procedure TCustomCodeEditor.FlagsChanged(OldFlags: longint);
  2905. var I: sw_integer;
  2906. begin
  2907. Lock;
  2908. if ((OldFlags xor GetFlags) and efCodeComplete)<>0 then
  2909. ClearCodeCompleteWord;
  2910. SetInsertMode(IsFlagSet(efInsertMode));
  2911. if ((OldFlags xor GetFlags) and efFolds)<>0 then
  2912. if not IsFlagSet(efFolds) then
  2913. RemoveAllFolds;
  2914. if IsFlagSet(efSyntaxHighlight) then
  2915. UpdateAttrs(0,attrAll) else
  2916. for I:=0 to GetLineCount-1 do
  2917. SetLineFormat(I,'');
  2918. DrawView;
  2919. UnLock;
  2920. end;
  2921. procedure TCustomCodeEditor.LimitsChanged;
  2922. begin
  2923. Abstract;
  2924. end;
  2925. procedure TCustomCodeEditor.DoLimitsChanged;
  2926. begin
  2927. SetLimit(MaxLineLength+1,EditorToViewLine(GetLineCount));
  2928. end;
  2929. procedure TCustomCodeEditor.BindingsChanged;
  2930. begin
  2931. { Abstract }
  2932. end;
  2933. procedure TCustomCodeEditor.ContentsChanged;
  2934. begin
  2935. DrawView;
  2936. end;
  2937. procedure TCustomCodeEditor.ConvertEvent(var Event: TEvent);
  2938. var
  2939. Key: Word;
  2940. begin
  2941. if Event.What = evKeyDown then
  2942. begin
  2943. if (Event.KeyShift and kbShift <> 0) and
  2944. (Event.ScanCode >= $47) and (Event.ScanCode <= $51) then
  2945. Event.CharCode := #0;
  2946. Key := Event.KeyCode;
  2947. if KeyState <> 0 then
  2948. begin
  2949. if (Lo(Key) >= $01) and (Lo(Key) <= $1A) then Inc(Key, $40);
  2950. if (Lo(Key) >= $61) and (Lo(Key) <= $7A) then Dec(Key, $20);
  2951. end;
  2952. Key := ScanKeyMap(KeyMap[KeyState], Key);
  2953. if (KeyState<>0) and (Key=0) then
  2954. ClearEvent(Event); { eat second key if unrecognized after ^Q or ^K }
  2955. KeyState := 0;
  2956. if Key <> 0 then
  2957. if Hi(Key) = $FF then
  2958. begin
  2959. KeyState := Lo(Key);
  2960. ClearEvent(Event);
  2961. end
  2962. else
  2963. begin
  2964. Event.What := evCommand;
  2965. Event.Command := Key;
  2966. end;
  2967. end;
  2968. end;
  2969. procedure TCustomCodeEditor.SetLineFlagState(LineNo: sw_integer; Flags: longint; ASet: boolean);
  2970. var L: PCustomLine;
  2971. begin
  2972. { Avoid crashes if file was shorten for instance }
  2973. if LineNo>=GetLineCount then
  2974. exit;
  2975. L:=GetLine(LineNo);
  2976. if Assigned(L) then
  2977. with L^ do
  2978. if ASet then
  2979. SetFlags(GetFlags or Flags)
  2980. else
  2981. SetFlags(GetFlags and not Flags);
  2982. end;
  2983. procedure TCustomCodeEditor.SetLineFlagExclusive(Flags: longint; LineNo: sw_integer);
  2984. var I,Count: sw_integer;
  2985. L: PCustomLine;
  2986. begin
  2987. Lock;
  2988. Count:=GetLineCount;
  2989. for I:=0 to Count-1 do
  2990. begin
  2991. L:=GetLine(I);
  2992. if not assigned(L) then break;
  2993. if I=LineNo then
  2994. L^.SetFlags(L^.GetFlags or Flags)
  2995. else
  2996. L^.SetFlags(L^.GetFlags and (not Flags));
  2997. end;
  2998. UnLock;
  2999. end;
  3000. procedure TCustomCodeEditor.HandleEvent(var Event: TEvent);
  3001. var DontClear : boolean;
  3002. procedure CheckScrollBar(P: PScrollBar; var D: Sw_Integer);
  3003. begin
  3004. if (Event.InfoPtr = P) and (P^.Value <> D) then
  3005. begin
  3006. D := P^.Value;
  3007. DrawView;
  3008. end;
  3009. end;
  3010. procedure GetMousePos(var P: TPoint);
  3011. begin
  3012. MakeLocal(Event.Where,P);
  3013. Inc(P.X,Delta.X); Inc(P.Y,Delta.Y);
  3014. Dec(P.X,GetReservedColCount);
  3015. if P.X<0 then P.X:=0;
  3016. if P.Y<0 then P.Y:=0;
  3017. end;
  3018. type TCCAction = (ccCheck,ccClear,ccDontCare);
  3019. var
  3020. StartP,P: TPoint;
  3021. E: TEvent;
  3022. OldEvent : PEvent;
  3023. CCAction: TCCAction;
  3024. begin
  3025. CCAction:=ccClear;
  3026. E:=Event;
  3027. OldEvent:=CurEvent;
  3028. if (E.What and (evMouse or evKeyboard))<>0 then
  3029. CurEvent:=@E;
  3030. if (InASCIIMode=false) or (Event.What<>evKeyDown) then
  3031. if (Event.What<>evKeyDown) or (Event.KeyCode<>kbEnter) or (IsReadOnly=false) then
  3032. if (Event.What<>evKeyDown) or
  3033. ((Event.KeyCode<>kbEnter) and (Event.KeyCode<>kbEsc)) or
  3034. (GetCompleteState<>csOffering) then
  3035. ConvertEvent(Event);
  3036. case Event.What of
  3037. evMouseDown :
  3038. if MouseInView(Event.Where) then
  3039. if (Event.Buttons=mbRightButton) then
  3040. begin
  3041. MakeLocal(Event.Where,P); Inc(P.X); Inc(P.Y);
  3042. LocalMenu(P);
  3043. ClearEvent(Event);
  3044. end else
  3045. if Event.Buttons=mbLeftButton then
  3046. begin
  3047. GetMousePos(P);
  3048. StartP:=P;
  3049. SetCurPtr(P.X,P.Y);
  3050. repeat
  3051. GetMousePos(P);
  3052. if PointOfs(P)<PointOfs(StartP)
  3053. then SetSelection(P,StartP)
  3054. else SetSelection(StartP,P);
  3055. SetCurPtr(P.X,P.Y);
  3056. DrawView;
  3057. until not MouseEvent(Event, evMouseMove+evMouseAuto);
  3058. DrawView;
  3059. end;
  3060. evKeyDown :
  3061. begin
  3062. { Scancode is almost never zero PM }
  3063. { this is supposed to enable entering of ASCII chars below 32,
  3064. which are normally interpreted as control chars. So, when you enter
  3065. Alt+24 (on the numeric pad) then this will normally move the cursor
  3066. one line down, but if you do it in ASCII mode (also after Ctrl+B)
  3067. then this will insert the ASCII #24 char (upper arrow) in the
  3068. source code. - Gabor }
  3069. if InASCIIMode {and (Event.CharCode<>0)} then
  3070. begin
  3071. AddChar(Event.CharCode);
  3072. if (GetCompleteState<>csDenied) or (Event.CharCode=#32) then
  3073. CCAction:=ccCheck
  3074. else
  3075. CCAction:=ccClear;
  3076. end
  3077. else
  3078. begin
  3079. DontClear:=false;
  3080. case Event.KeyCode of
  3081. kbAltF10 :
  3082. Message(@Self,evCommand,cmLocalMenu,@Self);
  3083. kbEnter :
  3084. if IsReadOnly then
  3085. DontClear:=true else
  3086. if GetCompleteState=csOffering then
  3087. CodeCompleteApply
  3088. else
  3089. Message(@Self,evCommand,cmNewLine,nil);
  3090. kbEsc :
  3091. if GetCompleteState=csOffering then
  3092. CodeCompleteCancel else
  3093. if IsModal then
  3094. DontClear:=true;
  3095. else
  3096. case Event.CharCode of
  3097. #9,#32..#255 :
  3098. if (Event.CharCode=#9) and IsModal then
  3099. DontClear:=true
  3100. else
  3101. begin
  3102. NoSelect:=true;
  3103. AddChar(Event.CharCode);
  3104. NoSelect:=false;
  3105. if (GetCompleteState<>csDenied) or (Event.CharCode=#32) then
  3106. CCAction:=ccCheck
  3107. else
  3108. CCAction:=ccClear;
  3109. end;
  3110. else
  3111. DontClear:=true;
  3112. end; { case Event.CharCode .. }
  3113. end; { case Event.KeyCode .. }
  3114. if not DontClear then
  3115. ClearEvent(Event);
  3116. end;
  3117. InASCIIMode:=false;
  3118. end;
  3119. evCommand :
  3120. begin
  3121. DontClear:=false;
  3122. case Event.Command of
  3123. cmASCIIChar : InASCIIMode:=not InASCIIMode;
  3124. cmAddChar : AddChar(chr(longint(Event.InfoPtr)));
  3125. cmCharLeft : CharLeft;
  3126. cmCharRight : CharRight;
  3127. cmWordLeft : WordLeft;
  3128. cmWordRight : WordRight;
  3129. cmLineStart : LineStart;
  3130. cmLineEnd : LineEnd;
  3131. cmLineUp : LineUp;
  3132. cmLineDown : LineDown;
  3133. cmPageUp : PageUp;
  3134. cmPageDown : PageDown;
  3135. cmTextStart : TextStart;
  3136. cmTextEnd : TextEnd;
  3137. cmWindowStart : WindowStart;
  3138. cmWindowEnd : WindowEnd;
  3139. cmNewLine : begin
  3140. InsertNewLine;
  3141. TrackCursor(false);
  3142. end;
  3143. cmBreakLine : BreakLine;
  3144. cmBackSpace : BackSpace;
  3145. cmDelChar : DelChar;
  3146. cmDelWord : DelWord;
  3147. cmDelToEndOfWord : DelToEndOfWord;
  3148. cmDelStart : DelStart;
  3149. cmDelEnd : DelEnd;
  3150. cmDelLine : DelLine;
  3151. cmInsMode : InsMode;
  3152. cmStartSelect : StartSelect;
  3153. cmHideSelect : HideSelect;
  3154. cmUpdateTitle : ;
  3155. cmEndSelect : EndSelect;
  3156. cmDelSelect : DelSelect;
  3157. cmCopyBlock : CopyBlock;
  3158. cmMoveBlock : MoveBlock;
  3159. cmIndentBlock : IndentBlock;
  3160. cmUnindentBlock : UnindentBlock;
  3161. cmSelStart : JumpSelStart;
  3162. cmSelEnd : JumpSelEnd;
  3163. cmLastCursorPos : JumpToLastCursorPos;
  3164. cmFindMatchingDelimiter : FindMatchingDelimiter(true);
  3165. cmFindMatchingDelimiterBack : FindMatchingDelimiter(false);
  3166. cmUpperCase : UpperCase;
  3167. cmLowerCase : LowerCase;
  3168. cmWordLowerCase : WordLowerCase;
  3169. cmWordUpperCase : WordUpperCase;
  3170. cmInsertOptions : InsertOptions;
  3171. cmToggleCase : ToggleCase;
  3172. cmCreateFold : CreateFoldFromBlock;
  3173. cmToggleFold : ToggleFold;
  3174. cmExpandFold : ExpandFold;
  3175. cmCollapseFold : CollapseFold;
  3176. cmJumpMark0..cmJumpMark9 : JumpMark(Event.Command-cmJumpMark0);
  3177. cmSetMark0..cmSetMark9 : DefineMark(Event.Command-cmSetMark0);
  3178. cmSelectWord : SelectWord;
  3179. cmSelectLine : SelectLine;
  3180. cmWriteBlock : WriteBlock;
  3181. cmReadBlock : ReadBlock;
  3182. cmPrintBlock : PrintBlock;
  3183. { ------ }
  3184. cmFind : Find;
  3185. cmReplace : Replace;
  3186. cmSearchAgain : DoSearchReplace;
  3187. cmJumpLine : GotoLine;
  3188. { ------ }
  3189. cmCut : ClipCut;
  3190. cmCopy : ClipCopy;
  3191. cmPaste : ClipPaste;
  3192. {$ifdef WinClipSupported}
  3193. cmCopyWin : ClipCopyWin;
  3194. cmPasteWin : ClipPasteWin;
  3195. {$endif WinClipSupported}
  3196. cmUndo : Undo;
  3197. cmRedo : Redo;
  3198. cmClear : DelSelect;
  3199. cmExpandCodeTemplate: ExpandCodeTemplate;
  3200. cmLocalMenu :
  3201. begin
  3202. P:=CurPos; Inc(P.X); Inc(P.Y);
  3203. LocalMenu(P);
  3204. end;
  3205. cmActivateMenu :
  3206. Message(Application,evCommand,cmMenu,nil);
  3207. else
  3208. begin
  3209. DontClear:=true;
  3210. CCAction:=ccDontCare;
  3211. end;
  3212. end;
  3213. if DontClear=false then
  3214. ClearEvent(Event);
  3215. end;
  3216. {$ifdef TEST_PARTIAL_SYNTAX}
  3217. evIdle :
  3218. begin
  3219. CCAction:=ccDontCare;
  3220. { Complete syntax by 20 lines increment }
  3221. { could already be quite lengthy on slow systems }
  3222. if not GetSyntaxCompleted then
  3223. UpdateAttrsRange(GetLastSyntaxedLine,GetLastSyntaxedLine+20,AttrAll);
  3224. end;
  3225. {$endif TEST_PARTIAL_SYNTAX}
  3226. evBroadcast :
  3227. begin
  3228. CCAction:=ccDontCare;
  3229. case Event.Command of
  3230. cmUpdate :
  3231. Update;
  3232. cmClearLineHighlights :
  3233. SetLineFlagExclusive(lfHighlightRow,-1);
  3234. cmResetDebuggerRow :
  3235. SetLineFlagExclusive(lfDebuggerRow,-1);
  3236. cmScrollBarChanged:
  3237. if (Event.InfoPtr = HScrollBar) or
  3238. (Event.InfoPtr = VScrollBar) then
  3239. begin
  3240. CheckScrollBar(HScrollBar, Delta.X);
  3241. CheckScrollBar(VScrollBar, Delta.Y);
  3242. end;
  3243. end;
  3244. end;
  3245. else CCAction:=ccDontCare;
  3246. end;
  3247. inherited HandleEvent(Event);
  3248. CurEvent:=OldEvent;
  3249. case CCAction of
  3250. ccCheck : CodeCompleteCheck;
  3251. ccClear : ClearCodeCompleteWord;
  3252. end;
  3253. end;
  3254. procedure TCustomCodeEditor.UpdateUndoRedo(cm : word; action : byte);
  3255. var UndoMenu : PMenuItem;
  3256. begin
  3257. UndoMenu:=PAdvancedMenuBar(MenuBar)^.GetMenuItem(cm);
  3258. if assigned(UndoMenu) then
  3259. begin
  3260. If assigned(UndoMenu^.Param) then
  3261. DisposeStr(UndoMenu^.Param);
  3262. if action<lastaction then
  3263. UndoMenu^.Param:=NewStr(ActionString[action]);
  3264. end;
  3265. end;
  3266. procedure TCustomCodeEditor.Update;
  3267. begin
  3268. Lock;
  3269. LimitsChanged;
  3270. SelectionChanged;
  3271. HighlightChanged;
  3272. UnLock;
  3273. end;
  3274. function TCustomCodeEditor.GetLocalMenu: PMenu;
  3275. begin
  3276. GetLocalMenu:=nil;
  3277. end;
  3278. function TCustomCodeEditor.GetCommandTarget: PView;
  3279. begin
  3280. GetCommandTarget:=@Self;
  3281. end;
  3282. function TCustomCodeEditor.CreateLocalMenuView(var Bounds: TRect; M: PMenu): PMenuPopup;
  3283. var MV: PMenuPopup;
  3284. begin
  3285. New(MV, Init(Bounds, M));
  3286. CreateLocalMenuView:=MV;
  3287. end;
  3288. procedure TCustomCodeEditor.LocalMenu(P: TPoint);
  3289. var M: PMenu;
  3290. MV: PMenuPopUp;
  3291. R: TRect;
  3292. Re: word;
  3293. begin
  3294. M:=GetLocalMenu;
  3295. if M=nil then Exit;
  3296. if LastLocalCmd<>0 then
  3297. M^.Default:=SearchMenuItem(M,LastLocalCmd);
  3298. Desktop^.GetExtent(R);
  3299. MakeGlobal(P,R.A); {Desktop^.MakeLocal(R.A,R.A);}
  3300. MV:=CreateLocalMenuView(R,M);
  3301. Re:=Application^.ExecView(MV);
  3302. if M^.Default=nil then LastLocalCmd:=0
  3303. else LastLocalCmd:=M^.Default^.Command;
  3304. Dispose(MV, Done);
  3305. if Re<>0 then
  3306. Message(GetCommandTarget,evCommand,Re,@Self);
  3307. end;
  3308. function TCustomCodeEditor.GetReservedColCount: sw_integer;
  3309. var LSX: sw_integer;
  3310. begin
  3311. if IsFlagSet(efFolds) then LSX:=GetFoldStringWidth else LSX:=0;
  3312. GetReservedColCount:=LSX;
  3313. end;
  3314. procedure TCustomCodeEditor.Draw;
  3315. function GetEIFold(EI: PEditorLineInfo): PFold;
  3316. begin
  3317. if Assigned(EI) then GetEIFold:=EI^.Fold else GetEIFold:=nil;
  3318. end;
  3319. var SelectColor,
  3320. HighlightColColor,
  3321. HighlightRowColor,
  3322. ErrorMessageColor : word;
  3323. B: TDrawBuffer;
  3324. I,X,Y,AX,AY,MaxX,LSX: sw_integer;
  3325. PX: TPoint;
  3326. LineCount: sw_integer;
  3327. Line,PrevLine: PCustomLine;
  3328. LineText,Format: string;
  3329. isBreak : boolean;
  3330. C: char;
  3331. FreeFormat: array[0..MaxLineLength] of boolean;
  3332. Color: word;
  3333. ColorTab: array[coFirstColor..coLastColor] of word;
  3334. ErrorLine: integer;
  3335. ErrorMsg: string[MaxViewWidth];
  3336. function CombineColors(Orig,Modifier: byte): byte;
  3337. var Color: byte;
  3338. begin
  3339. if (Modifier and $0f)=0 then
  3340. Color:=(Orig and $0f) or (Modifier and $f0)
  3341. else
  3342. Color:=(Orig and $f0) or (Modifier and $0f);
  3343. { do not allow invisible }
  3344. { use white as foreground in this case }
  3345. if (Color and $f) = ((Color div $10) and $7) then
  3346. Color:=(Color and $F0) or $F;
  3347. CombineColors:=Color;
  3348. end;
  3349. var PrevEI,EI: PEditorLineInfo;
  3350. FoldPrefix,FoldSuffix: string;
  3351. { SkipLine: boolean;}
  3352. { FoldStartLine: sw_integer;}
  3353. begin
  3354. if ELockFlag>0 then
  3355. begin
  3356. DrawCalled:=true;
  3357. Exit;
  3358. end;
  3359. DrawCalled:=false;
  3360. ErrorMsg:=copy(GetErrorMessage,1,MaxViewWidth);
  3361. if ErrorMsg='' then ErrorLine:=-1 else
  3362. if (CurPos.Y-Delta.Y)<(Size.Y div 2) then ErrorLine:=Size.Y-1
  3363. else ErrorLine:=0;
  3364. LineCount:=GetLineCount;
  3365. ColorTab[coTextColor]:=GetColor(1);
  3366. ColorTab[coWhiteSpaceColor]:=GetColor(2);
  3367. ColorTab[coCommentColor]:=GetColor(3);
  3368. ColorTab[coReservedWordColor]:=GetColor(4);
  3369. ColorTab[coIdentifierColor]:=GetColor(5);
  3370. ColorTab[coStringColor]:=GetColor(6);
  3371. ColorTab[coNumberColor]:=GetColor(7);
  3372. ColorTab[coAssemblerColor]:=GetColor(8);
  3373. ColorTab[coSymbolColor]:=GetColor(9);
  3374. ColorTab[coDirectiveColor]:=GetColor(13);
  3375. ColorTab[coHexNumberColor]:=GetColor(14);
  3376. ColorTab[coTabColor]:=GetColor(15);
  3377. { break same as error }
  3378. ColorTab[coBreakColor]:=GetColor(16);
  3379. ColorTab[coAsmReservedColor]:=GetColor(17);
  3380. SelectColor:=GetColor(10);
  3381. HighlightColColor:=GetColor(11);
  3382. HighlightRowColor:=GetColor(12);
  3383. ErrorMessageColor:=GetColor(16);
  3384. {$ifdef TEST_PARTIAL_SYNTAX}
  3385. If (not GetSyntaxCompleted) and (GetLastSyntaxedLine<Delta.Y+Size.Y) then
  3386. UpdateAttrsRange(GetLastSyntaxedLine,Delta.Y+Size.Y,AttrAll);
  3387. {$endif TEST_PARTIAL_SYNTAX}
  3388. LSX:=GetReservedColCount;
  3389. PrevLine:=nil; PrevEI:=nil; {FoldStartLine:=-1;}
  3390. Y:=0; AY:=Delta.Y;
  3391. for Y:=0 to Size.Y-1 do
  3392. begin
  3393. if Y=ErrorLine then
  3394. begin
  3395. MoveChar(B,' ',ErrorMessageColor,Size.X);
  3396. MoveStr(B,ErrorMsg,ErrorMessageColor);
  3397. WriteLine(0,Y,Size.X,1,B);
  3398. end
  3399. else
  3400. begin
  3401. AY:=ViewToEditorLine(Delta.Y+Y);
  3402. if (0<=AY) and (AY<LineCount) then
  3403. begin
  3404. Line:=GetLine(AY);
  3405. if assigned(Line) then
  3406. begin
  3407. IsBreak:=Line^.IsFlagSet(lfBreakpoint);
  3408. EI:=Line^.GetEditorInfo(@Self);
  3409. end
  3410. else
  3411. begin
  3412. IsBreak:=false;
  3413. EI:=nil;
  3414. end;
  3415. end
  3416. else
  3417. begin
  3418. Line:=nil;
  3419. IsBreak:=false;
  3420. EI:=nil;
  3421. end;
  3422. begin
  3423. Color:=ColorTab[coTextColor];
  3424. FillChar(FreeFormat,SizeOf(FreeFormat),1);
  3425. MoveChar(B,' ',Color,Size.X);
  3426. GetDisplayTextFormat(AY,LineText,Format);
  3427. { if FlagSet(efSyntaxHighlight) then MaxX:=length(LineText)+1
  3428. else }MaxX:=Size.X+Delta.X;
  3429. for X:=1 to Min(MaxX,High(LineText)) do
  3430. begin
  3431. AX:=Delta.X+X-1;
  3432. if X<=length(LineText) then C:=LineText[X] else C:=' ';
  3433. PX.X:=AX-Delta.X; PX.Y:=AY;
  3434. if (Highlight.A.X<>Highlight.B.X) or (Highlight.A.Y<>Highlight.B.Y) then
  3435. { there's a highlight }
  3436. begin
  3437. if (PointOfs(Highlight.A)<=PointOfs(PX)) and (PointOfs(PX)<PointOfs(Highlight.B)) then
  3438. begin
  3439. Color:=SelectColor;
  3440. FreeFormat[X]:=false;
  3441. end;
  3442. end
  3443. else
  3444. { no highlight }
  3445. begin
  3446. if IsFlagSet(efVerticalBlocks) then
  3447. begin
  3448. if (SelStart.X<=AX) and (AX<=SelEnd.X) and
  3449. (SelStart.Y<=AY) and (AY<=SelEnd.Y) then
  3450. begin
  3451. Color:=SelectColor; FreeFormat[X]:=false;
  3452. end;
  3453. end
  3454. else
  3455. if PointOfs(SelStart)<>PointOfs(SelEnd) then
  3456. if (PointOfs(SelStart)<=PointOfs(PX)) and (PointOfs(PX)<PointOfs(SelEnd)) then
  3457. begin
  3458. Color:=SelectColor; FreeFormat[X]:=false;
  3459. end;
  3460. end; { no highlight }
  3461. if FreeFormat[X] then
  3462. if X<=length(Format) then
  3463. {Color:=ColorTab[ord(Format[X])] else Color:=ColorTab[coTextColor];
  3464. this give BoundsCheckError with -Cr quite often PM }
  3465. Color:=ColorTab[ord(Format[X]) mod (coLastColor + 1)] else Color:=ColorTab[coTextColor];
  3466. if IsFlagSet(efHighlightRow) and
  3467. (PX.Y=CurPos.Y) then
  3468. begin
  3469. Color:=CombineColors(Color,HighlightRowColor);
  3470. FreeFormat[X]:=false;
  3471. end;
  3472. if IsFlagSet(efHighlightColumn) and (PX.X=CurPos.X) then
  3473. begin
  3474. Color:=CombineColors(Color,HighlightColColor);
  3475. FreeFormat[X]:=false;
  3476. end;
  3477. if Assigned(Line) and Line^.IsFlagSet(lfHighlightRow) then
  3478. begin
  3479. Color:=CombineColors(Color,HighlightRowColor);
  3480. FreeFormat[X]:=false;
  3481. end;
  3482. if isbreak then
  3483. begin
  3484. Color:=ColorTab[coBreakColor];
  3485. FreeFormat[X]:=false;
  3486. end;
  3487. if Assigned(Line) and Line^.isFlagSet(lfDebuggerRow) then
  3488. begin
  3489. Color:=CombineColors(Color,HighlightRowColor);
  3490. FreeFormat[X]:=false;
  3491. end;
  3492. if (0<=LSX+X-1-Delta.X) and (LSX+X-1-Delta.X<MaxViewWidth) then
  3493. MoveChar(B[LSX+X-1-Delta.X],C,Color,1);
  3494. end; { for X:=1 to ... }
  3495. if IsFlagSet(efFolds) then
  3496. begin
  3497. GetFoldStrings(AY,FoldPrefix,FoldSuffix);
  3498. MoveStr(B[0],FoldPrefix,ColorTab[coTextColor]);
  3499. if FoldSuffix<>'' then
  3500. MoveStr(B[Size.X-1-length(FoldSuffix)],FoldSuffix,ColorTab[coTextColor]);
  3501. end;
  3502. WriteLine(0,Y,Size.X,1,B);
  3503. end; { if not SkipLine ... }
  3504. end; { not errorline }
  3505. PrevEI:=EI; PrevLine:=Line;
  3506. end; { while (Y<Size.Y) ... }
  3507. DrawCursor;
  3508. end;
  3509. procedure TCustomCodeEditor.DrawCursor;
  3510. var LSX: sw_integer;
  3511. begin
  3512. if Elockflag>0 then
  3513. DrawCursorCalled:=true
  3514. else
  3515. begin
  3516. SetCursor(GetReservedColCount+CurPos.X-Delta.X,EditorToViewLine(CurPos.Y)-Delta.Y);
  3517. SetState(sfCursorIns,Overwrite);
  3518. end;
  3519. end;
  3520. {$ifdef USE_FREEVISION}
  3521. procedure TCustomCodeEditor.ResetCursor;
  3522. const
  3523. sfV_CV_F:word = sfVisible + sfCursorVis + sfFocused;
  3524. var
  3525. p,p2 : PView;
  3526. G : PGroup;
  3527. cur : TPoint;
  3528. function Check0:boolean;
  3529. var
  3530. res : byte;
  3531. begin
  3532. res:=0;
  3533. while res=0 do
  3534. begin
  3535. p:=p^.next;
  3536. if p=p2 then
  3537. begin
  3538. p:=P^.owner;
  3539. res:=1
  3540. end
  3541. else
  3542. if ((p^.state and sfVisible)<>0) and
  3543. (cur.x>=p^.origin.x) and
  3544. (cur.x<p^.size.x+p^.origin.x) and
  3545. (cur.y>=p^.origin.y) and
  3546. (cur.y<p^.size.y+p^.origin.y) then
  3547. res:=2;
  3548. end;
  3549. Check0:=res=2;
  3550. end;
  3551. begin
  3552. if Elockflag>0 then
  3553. begin
  3554. DrawCursorCalled:=true;
  3555. exit;
  3556. end
  3557. {$ifdef FVISION}
  3558. else inherited ResetCursor;
  3559. {$else not FVISION}
  3560. else if (state and sfV_CV_F) = sfV_CV_F then
  3561. begin
  3562. p:=@Self;
  3563. cur:=cursor;
  3564. while true do
  3565. begin
  3566. if (cur.x<0) or (cur.x>=p^.size.x) or
  3567. (cur.y<0) or (cur.y>=p^.size.y) then
  3568. break;
  3569. p2:=p;
  3570. cur.x:=cur.x+p^.origin.x;
  3571. cur.y:=cur.y+p^.origin.y;
  3572. G:=p^.owner;
  3573. if G=Nil then { top view }
  3574. begin
  3575. Video.SetCursorPos(cur.x,cur.y);
  3576. if (state and sfCursorIns)<>0 then
  3577. Video.SetCursorType(crBlock)
  3578. else
  3579. Video.SetCursorType(crUnderline);
  3580. exit;
  3581. end;
  3582. if (G^.state and sfVisible)=0 then
  3583. break;
  3584. p:=G^.Last;
  3585. if Check0 then
  3586. break;
  3587. end; { while }
  3588. end; { if }
  3589. Video.SetCursorType(crHidden);
  3590. {$endif not FVISION}
  3591. end;
  3592. {$endif USE_FREEVISION}
  3593. function TCustomCodeEditor.Overwrite: boolean;
  3594. begin
  3595. Overwrite:=not IsFlagSet(efInsertMode);
  3596. end;
  3597. procedure TCustomCodeEditor.SetCodeCompleteWord(const S: string);
  3598. begin
  3599. if S<>'' then
  3600. SetCompleteState(csOffering)
  3601. else
  3602. SetCompleteState(csInactive);
  3603. end;
  3604. procedure TCustomCodeEditor.ClearCodeCompleteWord;
  3605. begin
  3606. SetCodeCompleteWord('');
  3607. SetCompleteState(csInactive);
  3608. end;
  3609. function TCustomCodeEditor.GetCompleteState: TCompleteState;
  3610. begin
  3611. { Abstract }
  3612. GetCompleteState:=csInactive;
  3613. end;
  3614. procedure TCustomCodeEditor.SetCompleteState(AState: TCompleteState);
  3615. begin
  3616. { Abstract }
  3617. end;
  3618. function TCustomCodeEditor.UpdateAttrs(FromLine: sw_integer; Attrs: byte): sw_integer;
  3619. begin
  3620. Abstract;
  3621. UpdateAttrs:=-1;
  3622. end;
  3623. function TCustomCodeEditor.UpdateAttrsRange(FromLine, ToLine: sw_integer; Attrs: byte): sw_integer;
  3624. begin
  3625. Abstract;
  3626. UpdateAttrsRange:=-1;
  3627. end;
  3628. procedure TCustomCodeEditor.AddAction(AAction: byte; AStartPos, AEndPos: TPoint; AText: string;AFlags : longint);
  3629. begin
  3630. { Abstract }
  3631. end;
  3632. procedure TCustomCodeEditor.AddGroupedAction(AAction : byte);
  3633. begin
  3634. { Abstract }
  3635. end;
  3636. procedure TCustomCodeEditor.CloseGroupedAction(AAction : byte);
  3637. begin
  3638. { Abstract }
  3639. end;
  3640. function TCustomCodeEditor.GetUndoActionCount: sw_integer;
  3641. begin
  3642. { Abstract }
  3643. GetUndoActionCount:=0;
  3644. end;
  3645. function TCustomCodeEditor.GetRedoActionCount: sw_integer;
  3646. begin
  3647. { Abstract }
  3648. GetRedoActionCount:=0;
  3649. end;
  3650. function TCustomCodeEditor.GetMaxFoldLevel: sw_integer;
  3651. var Max,L,I: sw_integer;
  3652. begin
  3653. Max:=0;
  3654. for I:=0 to GetFoldCount-1 do
  3655. begin
  3656. L:=GetFold(I)^.GetLevel;
  3657. if L>Max then Max:=L;
  3658. end;
  3659. GetMaxFoldLevel:=Max;
  3660. end;
  3661. function TCustomCodeEditor.GetFoldStringWidth: sw_integer;
  3662. begin
  3663. GetFoldStringWidth:=GetMaxFoldLevel;
  3664. end;
  3665. procedure TCustomCodeEditor.GetFoldStrings(EditorLine: sw_integer; var Prefix, Suffix: openstring);
  3666. var F: PFold;
  3667. C: char;
  3668. begin
  3669. Prefix:=CharStr(' ',GetFoldStringWidth); Suffix:='';
  3670. F:=GetLineFold(EditorLine);
  3671. if Assigned(F) then
  3672. begin
  3673. if F^.Collapsed_ then C:=#27 else C:=#26;
  3674. Prefix[1+F^.GetLevel]:=C;
  3675. if F^.Collapsed_ then
  3676. Suffix:='('+IntToStr(F^.GetLineCount)+')';
  3677. end;
  3678. end;
  3679. function TCustomCodeEditor.GetFoldCount: sw_integer;
  3680. begin
  3681. GetFoldCount:=0;
  3682. end;
  3683. function TCustomCodeEditor.GetFold(Index: sw_integer): PFold;
  3684. begin
  3685. GetFold:=nil;
  3686. end;
  3687. procedure TCustomCodeEditor.RegisterFold(AFold: PFold);
  3688. begin
  3689. Abstract;
  3690. end;
  3691. procedure TCustomCodeEditor.UnRegisterFold(AFold: PFold);
  3692. begin
  3693. Abstract;
  3694. end;
  3695. procedure TCustomCodeEditor.Indent;
  3696. var S, PreS: string;
  3697. Shift: integer;
  3698. begin
  3699. S:=GetLineText(CurPos.Y);
  3700. if CurPos.Y>0 then
  3701. PreS:=RTrim(GetLineText(CurPos.Y-1),not IsFlagSet(efUseTabCharacters))
  3702. else
  3703. PreS:='';
  3704. if CurPos.X>=length(PreS) then
  3705. Shift:=GetTabSize
  3706. else
  3707. begin
  3708. Shift:=1;
  3709. while (CurPos.X+Shift<length(PreS)) and (PreS[CurPos.X+Shift]<>' ') do
  3710. Inc(Shift);
  3711. end;
  3712. SetLineText(CurPos.Y,RExpand(copy(S,1,CurPos.X+1),CurPos.X+1)+CharStr(' ',Shift)+copy(S,CurPos.X+2,High(S)));
  3713. SetCurPtr(CurPos.X+Shift,CurPos.Y);
  3714. UpdateAttrs(CurPos.Y,attrAll);
  3715. DrawLines(CurPos.Y);
  3716. SetModified(true);
  3717. end;
  3718. procedure TCustomCodeEditor.CharLeft;
  3719. begin
  3720. if CurPos.X=0 then Exit;
  3721. SetCurPtr(CurPos.X-1,CurPos.Y);
  3722. end;
  3723. procedure TCustomCodeEditor.CharRight;
  3724. begin
  3725. if CurPos.X>=MaxLineLength then
  3726. Exit;
  3727. SetCurPtr(CurPos.X+1,CurPos.Y);
  3728. end;
  3729. procedure TCustomCodeEditor.WordLeft;
  3730. var X, Y: sw_integer;
  3731. Line: string;
  3732. GotIt,FoundNonSeparator: boolean;
  3733. begin
  3734. X:=CurPos.X;
  3735. Y:=CurPos.Y;
  3736. GotIt:=false;
  3737. FoundNonSeparator:=false;
  3738. while (Y>=0) do
  3739. begin
  3740. if Y=CurPos.Y then
  3741. begin
  3742. X:=length(GetDisplayText(Y));
  3743. if CurPos.X<X then
  3744. X:=CurPos.X; Dec(X);
  3745. if (X=-1) then
  3746. begin
  3747. Dec(Y);
  3748. if Y>=0 then
  3749. X:=length(GetDisplayText(Y));
  3750. Break;
  3751. end;
  3752. end
  3753. else
  3754. X:=length(GetDisplayText(Y))-1;
  3755. Line:=GetDisplayText(Y);
  3756. while (X>=0) and (GotIt=false) do
  3757. begin
  3758. if FoundNonSeparator then
  3759. begin
  3760. if IsWordSeparator(Line[X+1]) then
  3761. begin
  3762. Inc(X);
  3763. GotIt:=true;
  3764. Break;
  3765. end;
  3766. end
  3767. else
  3768. if not IsWordSeparator(Line[X+1]) then
  3769. FoundNonSeparator:=true;
  3770. Dec(X);
  3771. if (X=0) and (IsWordSeparator(Line[1])=false) then
  3772. begin
  3773. GotIt:=true;
  3774. Break;
  3775. end;
  3776. end;
  3777. if GotIt then
  3778. Break;
  3779. X:=0;
  3780. Dec(Y);
  3781. if Y>=0 then
  3782. begin
  3783. X:=length(GetDisplayText(Y));
  3784. Break;
  3785. end;
  3786. end;
  3787. if Y<0 then Y:=0; if X<0 then X:=0;
  3788. SetCurPtr(X,Y);
  3789. end;
  3790. procedure TCustomCodeEditor.WordRight;
  3791. var X, Y: sw_integer;
  3792. Line: string;
  3793. GotIt: boolean;
  3794. begin
  3795. X:=CurPos.X; Y:=CurPos.Y; GotIt:=false;
  3796. while (Y<GetLineCount) do
  3797. begin
  3798. if Y=CurPos.Y then
  3799. begin
  3800. X:=CurPos.X; Inc(X);
  3801. if (X>length(GetDisplayText(Y))-1) then
  3802. begin Inc(Y); X:=0; end;
  3803. end else X:=0;
  3804. Line:=GetDisplayText(Y);
  3805. while (X<=length(Line)+1) and (GotIt=false) and (Line<>'') do
  3806. begin
  3807. if X=length(Line)+1 then begin GotIt:=true; Dec(X); Break end;
  3808. if IsWordSeparator(Line[X]) then
  3809. begin
  3810. while (Y<GetLineCount) and
  3811. (X<=length(Line)) and (IsWordSeparator(Line[X])) do
  3812. begin
  3813. Inc(X);
  3814. if X>=length(Line) then
  3815. begin GotIt:=true; Dec(X); Break; end;
  3816. end;
  3817. if (GotIt=false) and (X<length(Line)) then
  3818. begin
  3819. Dec(X);
  3820. GotIt:=true;
  3821. Break;
  3822. end;
  3823. end;
  3824. Inc(X);
  3825. end;
  3826. if GotIt then Break;
  3827. X:=0;
  3828. Inc(Y);
  3829. if (Y<GetLineCount) then
  3830. begin
  3831. Line:=GetDisplayText(Y);
  3832. if (Line<>'') and (IsWordSeparator(Line[1])=false) then Break;
  3833. end;
  3834. end;
  3835. if Y=GetLineCount then Y:=GetLineCount-1;
  3836. SetCurPtr(X,Y);
  3837. end;
  3838. procedure TCustomCodeEditor.LineStart;
  3839. begin
  3840. SetCurPtr(0,CurPos.Y);
  3841. end;
  3842. procedure TCustomCodeEditor.LineEnd;
  3843. var
  3844. s : string;
  3845. i : longint;
  3846. begin
  3847. if CurPos.Y<GetLineCount then
  3848. begin
  3849. s:=GetDisplayText(CurPos.Y);
  3850. i:=length(s);
  3851. while (i>0) and (s[i]=' ') do
  3852. dec(i);
  3853. SetCurPtr(i,CurPos.Y);
  3854. end
  3855. else
  3856. SetCurPtr(0,CurPos.Y);
  3857. end;
  3858. function TCustomCodeEditor.NextVisibleLine(StartLine: sw_integer; Down: boolean): sw_integer;
  3859. var Count,NL: sw_integer;
  3860. begin
  3861. if Down then
  3862. begin
  3863. Count:=GetLineCount;
  3864. NL:=StartLine;
  3865. while (NL<Count-1) and not IsLineVisible(NL) do
  3866. Inc(NL);
  3867. if NL>=Count then
  3868. NL:=-1;
  3869. end
  3870. else
  3871. begin
  3872. NL:=StartLine;
  3873. while (NL>0) and not IsLineVisible(NL) do
  3874. Dec(NL);
  3875. end;
  3876. if not IsLineVisible(NL) then
  3877. NL:=-1;
  3878. NextVisibleLine:=NL;
  3879. end;
  3880. procedure TCustomCodeEditor.LineUp;
  3881. var NL: sw_integer;
  3882. begin
  3883. NL:=NextVisibleLine(CurPos.Y-1,false);
  3884. if NL<>-1 then
  3885. SetCurPtr(CurPos.X,NL);
  3886. end;
  3887. procedure TCustomCodeEditor.LineDown;
  3888. var NL: sw_integer;
  3889. begin
  3890. NL:=NextVisibleLine(CurPos.Y+1,true);
  3891. if NL<>-1 then
  3892. SetCurPtr(CurPos.X,NL);
  3893. end;
  3894. procedure TCustomCodeEditor.PageUp;
  3895. var NL: sw_integer;
  3896. begin
  3897. ScrollTo(Delta.X,Max(Delta.Y-Size.Y,0));
  3898. NL:=Max(CurPos.Y-(Size.Y),0);
  3899. if not IsLineVisible(NL) then
  3900. NL:=NextVisibleLine(NL,false);
  3901. if NL>=0 then
  3902. SetCurPtr(CurPos.X,Max(0,NL));
  3903. end;
  3904. procedure TCustomCodeEditor.PageDown;
  3905. var NL: sw_integer;
  3906. begin
  3907. ScrollTo(Delta.X,Min(Delta.Y+Size.Y,GetLineCount-1));
  3908. NL:=Min(CurPos.Y+(Size.Y{-1}),GetLineCount-1);
  3909. if not IsLineVisible(NL) then
  3910. NL:=NextVisibleLine(NL,true);
  3911. if NL>=0 then
  3912. SetCurPtr(CurPos.X,Min(GetLineCount-1,NL));
  3913. end;
  3914. procedure TCustomCodeEditor.TextStart;
  3915. begin
  3916. SetCurPtr(0,0);
  3917. end;
  3918. procedure TCustomCodeEditor.TextEnd;
  3919. var s : string;
  3920. i : longint;
  3921. begin
  3922. s:=GetDisplayText(GetLineCount-1);
  3923. i:=length(s);
  3924. while (i>0) and (s[i]=' ') do
  3925. dec(i);
  3926. SetCurPtr(i,GetLineCount-1);
  3927. end;
  3928. procedure TCustomCodeEditor.WindowStart;
  3929. begin
  3930. SetCurPtr(CurPos.X,Delta.Y);
  3931. end;
  3932. procedure TCustomCodeEditor.WindowEnd;
  3933. begin
  3934. SetCurPtr(CurPos.X,Delta.Y+Size.Y-1);
  3935. end;
  3936. procedure TCustomCodeEditor.JumpSelStart;
  3937. begin
  3938. if ValidBlock then
  3939. SetCurPtr(SelStart.X,SelStart.Y);
  3940. end;
  3941. procedure TCustomCodeEditor.JumpSelEnd;
  3942. begin
  3943. if ValidBlock then
  3944. SetCurPtr(SelEnd.X,SelEnd.Y);
  3945. end;
  3946. procedure TCustomCodeEditor.JumpMark(MarkIdx: integer);
  3947. begin
  3948. DontConsiderShiftState:=true;
  3949. if (MarkIdx<Low(Bookmarks)) or (MarkIdx>High(Bookmarks)) then
  3950. begin ErrorBox(FormatStrInt(msg_invalidmarkindex,MarkIdx),nil); Exit; end;
  3951. with Bookmarks[MarkIdx] do
  3952. if Valid=false then
  3953. InformationBox(FormatStrInt(msg_marknotset,MarkIdx),nil)
  3954. else
  3955. SetCurPtr(Pos.X,Pos.Y);
  3956. DontConsiderShiftState:=false;
  3957. end;
  3958. procedure TCustomCodeEditor.DefineMark(MarkIdx: integer);
  3959. begin
  3960. if (MarkIdx<Low(Bookmarks)) or (MarkIdx>High(Bookmarks)) then
  3961. begin
  3962. ErrorBox(FormatStrInt(msg_invalidmarkindex,MarkIdx),nil);
  3963. Exit;
  3964. end;
  3965. with Bookmarks[MarkIdx] do
  3966. begin
  3967. Pos:=CurPos;
  3968. Valid:=true;
  3969. end;
  3970. end;
  3971. procedure TCustomCodeEditor.JumpToLastCursorPos;
  3972. begin
  3973. NotImplemented;
  3974. end;
  3975. procedure TCustomCodeEditor.UpperCase;
  3976. var StartP,EndP: TPoint;
  3977. begin
  3978. if ValidBlock=false then Exit;
  3979. GetSelectionArea(StartP,EndP);
  3980. AddGroupedAction(eaUpperCase);
  3981. ChangeCaseArea(StartP,EndP,caToUpperCase);
  3982. CloseGroupedAction(eaUpperCase);
  3983. end;
  3984. procedure TCustomCodeEditor.LowerCase;
  3985. var StartP,EndP: TPoint;
  3986. begin
  3987. if ValidBlock=false then Exit;
  3988. GetSelectionArea(StartP,EndP);
  3989. AddGroupedAction(eaLowerCase);
  3990. ChangeCaseArea(StartP,EndP,caToLowerCase);
  3991. CloseGroupedAction(eaLowerCase);
  3992. end;
  3993. procedure TCustomCodeEditor.ToggleCase;
  3994. var StartP,EndP: TPoint;
  3995. begin
  3996. if ValidBlock=false then Exit;
  3997. GetSelectionArea(StartP,EndP);
  3998. AddGroupedAction(eaToggleCase);
  3999. ChangeCaseArea(StartP,EndP,caToggleCase);
  4000. CloseGroupedAction(eaToggleCase);
  4001. end;
  4002. procedure TCustomCodeEditor.WordLowerCase;
  4003. var StartP,EndP: TPoint;
  4004. begin
  4005. if GetCurrentWordArea(StartP,EndP)=false then Exit;
  4006. AddGroupedAction(eaLowerCase);
  4007. ChangeCaseArea(StartP,EndP,caToLowerCase);
  4008. CloseGroupedAction(eaLowerCase);
  4009. end;
  4010. procedure TCustomCodeEditor.WordUpperCase;
  4011. var StartP,EndP: TPoint;
  4012. begin
  4013. if GetCurrentWordArea(StartP,EndP)=false then Exit;
  4014. AddGroupedAction(eaUpperCase);
  4015. ChangeCaseArea(StartP,EndP,caToUpperCase);
  4016. CloseGroupedAction(eaUpperCase);
  4017. end;
  4018. procedure TCustomCodeEditor.CreateFoldFromBlock;
  4019. var StartY,EndY: sw_integer;
  4020. begin
  4021. if not IsFlagSet(efFolds) then Exit;
  4022. if not ValidBlock then Exit;
  4023. StartY:=SelStart.Y; EndY:=SelEnd.Y;
  4024. if SelEnd.X=0 then Dec(EndY);
  4025. if CreateFold(StartY,EndY,false)=false then
  4026. ErrorBox(msg_foldboundsarenotvalid,nil);
  4027. end;
  4028. procedure TCustomCodeEditor.ToggleFold;
  4029. var F: PFold;
  4030. begin
  4031. if not IsFlagSet(efFolds) then Exit;
  4032. F:=GetLineFold(CurPos.Y);
  4033. if Assigned(F) then
  4034. F^.Collapse(not F^.Collapsed_);
  4035. end;
  4036. procedure TCustomCodeEditor.ExpandFold;
  4037. var F: PFold;
  4038. begin
  4039. if not IsFlagSet(efFolds) then Exit;
  4040. F:=GetLineFold(CurPos.Y);
  4041. if Assigned(F) then
  4042. F^.Collapse(false);
  4043. end;
  4044. procedure TCustomCodeEditor.CollapseFold;
  4045. var F: PFold;
  4046. begin
  4047. if not IsFlagSet(efFolds) then Exit;
  4048. F:=GetLineFold(CurPos.Y);
  4049. if Assigned(F) then
  4050. F^.Collapse(true);
  4051. end;
  4052. procedure TCustomCodeEditor.ChangeCaseArea(StartP,EndP: TPoint; CaseAction: TCaseAction);
  4053. var Y,X: sw_integer;
  4054. X1,X2: sw_integer;
  4055. S: string;
  4056. C: char;
  4057. StartPos : TPoint;
  4058. HoldUndo : boolean;
  4059. begin
  4060. Lock;
  4061. HoldUndo:=GetStoreUndo;
  4062. SetStoreUndo(false);
  4063. for Y:=StartP.Y to EndP.Y do
  4064. begin
  4065. S:=GetDisplayText(Y);
  4066. { Pierre, please implement undo here! Gabor }
  4067. X1:=0; X2:=length(S)-1;
  4068. if Y=StartP.Y then X1:=StartP.X;
  4069. if Y=EndP.Y then X2:=EndP.X;
  4070. SetStoreUndo(HoldUndo);
  4071. StartPos.X:=X1;
  4072. StartPos.Y:=Y;
  4073. { the only drawback is that we keep
  4074. the original text even if Toggle where
  4075. it is not really necessary PM }
  4076. Addaction(eaOverwriteText,StartPos,StartPos,Copy(S,X1+1,X2-X1+1),GetFlags);
  4077. SetStoreUndo(false);
  4078. for X:=X1 to X2 do
  4079. begin
  4080. C:=S[X+1];
  4081. case CaseAction of
  4082. caToLowerCase : C:=LowCase(C);
  4083. caToUpperCase : C:=UpCase(C);
  4084. caToggleCase : if C in['a'..'z'] then
  4085. C:=Upcase(C)
  4086. else
  4087. C:=LowCase(C);
  4088. end;
  4089. S[X+1]:=C;
  4090. end;
  4091. SetDisplayText(Y,S);
  4092. end;
  4093. UpdateAttrsRange(StartP.Y,EndP.Y,attrAll);
  4094. DrawLines(CurPos.Y);
  4095. SetModified(true);
  4096. Addaction(eaMoveCursor,StartPos,CurPos,'',GetFlags);
  4097. SetStoreUndo(HoldUndo);
  4098. UnLock;
  4099. end;
  4100. procedure TCustomCodeEditor.PushInfo(Const st : string);
  4101. begin
  4102. { Dummies }
  4103. end;
  4104. procedure TCustomCodeEditor.PopInfo;
  4105. begin
  4106. { Dummies }
  4107. end;
  4108. procedure TCustomCodeEditor.InsertOptions;
  4109. begin
  4110. { Abstract }
  4111. NotImplemented;
  4112. end;
  4113. function TCustomCodeEditor.GetLineFold(EditorLine: sw_integer): PFold;
  4114. var L: PCustomLine;
  4115. LI: PEditorLineInfo;
  4116. F: PFold;
  4117. begin
  4118. F:=nil;
  4119. if IsFlagSet(efFolds) then
  4120. if (0<=EditorLine) and (EditorLine<GetLineCount) then
  4121. begin
  4122. L:=GetLine(EditorLine);
  4123. if Assigned(L) then
  4124. LI:=L^.GetEditorInfo(@Self)
  4125. else
  4126. LI:=nil;
  4127. if Assigned(LI) then
  4128. F:=LI^.Fold;
  4129. end;
  4130. GetLineFold:=F;
  4131. end;
  4132. function TCustomCodeEditor.IsLineVisible(EditorLine: sw_integer): boolean;
  4133. var V: boolean;
  4134. F,PrevF: PFold;
  4135. FoldHeadline: boolean;
  4136. begin
  4137. V:=true;
  4138. if IsFlagSet(efFolds) then
  4139. begin
  4140. F:=GetLineFold(EditorLine);
  4141. if Assigned(F) then
  4142. begin
  4143. PrevF:=GetLineFold(EditorLine-1);
  4144. FoldHeadline:=false;
  4145. if (PrevF<>F) and ((PrevF=nil) or (not PrevF^.IsParent(F))) then
  4146. FoldHeadline:=true;
  4147. if FoldHeadline then
  4148. begin
  4149. if Assigned(F^.ParentFold) and (F^.ParentFold^.IsCollapsed) then
  4150. V:=false;
  4151. end
  4152. else
  4153. if F^.IsCollapsed then
  4154. V:=false;
  4155. end;
  4156. end;
  4157. IsLineVisible:=V;
  4158. end;
  4159. function TCustomCodeEditor.ViewToEditorLine(ViewLine: sw_integer): sw_integer;
  4160. var I,Line,Count: sw_integer;
  4161. begin
  4162. if not IsFlagSet(efFolds) then
  4163. Line:=ViewLine
  4164. else
  4165. begin
  4166. Count:=GetLineCount;
  4167. I:=0; Line:=-1;
  4168. while (Line<ViewLine) and (I<Count) do
  4169. begin
  4170. if IsLineVisible(I) then
  4171. Inc(Line);
  4172. Inc(I);
  4173. end;
  4174. if Line<>ViewLine then
  4175. Line:=-1
  4176. else
  4177. Line:=I-1;
  4178. end;
  4179. ViewToEditorLine:=Line;
  4180. end;
  4181. function TCustomCodeEditor.EditorToViewLine(EditorLine: sw_integer): sw_integer;
  4182. var I,Line: sw_integer;
  4183. F: PFold;
  4184. begin
  4185. if not IsFlagSet(efFolds) then
  4186. Line:=EditorLine
  4187. else
  4188. begin
  4189. Line:=-1;
  4190. for I:=0 to EditorLine do
  4191. if IsLineVisible(I) then
  4192. Inc(Line);
  4193. end;
  4194. EditorToViewLine:=Line;
  4195. end;
  4196. procedure TCustomCodeEditor.ViewToEditorPoint(P: TPoint; var NP: TPoint);
  4197. begin
  4198. NP.X:=P.X-GetReservedColCount;
  4199. NP.Y:=ViewToEditorLine(P.Y);
  4200. end;
  4201. procedure TCustomCodeEditor.EditorToViewPoint(P: TPoint; var NP: TPoint);
  4202. begin
  4203. NP.X:=P.X+GetReservedColCount;
  4204. NP.Y:=EditorToViewLine(P.Y);
  4205. end;
  4206. procedure TCustomCodeEditor.FindMatchingDelimiter(ScanForward: boolean);
  4207. const OpenSymbols : string[6] = '[{(<''"';
  4208. CloseSymbols : string[6] = ']})>''"';
  4209. var SymIdx: integer;
  4210. LineText,LineAttr: string;
  4211. CurChar: char;
  4212. X,Y: sw_integer;
  4213. LineCount: sw_integer;
  4214. JumpPos: TPoint;
  4215. BracketLevel: integer;
  4216. begin
  4217. JumpPos.X:=-1; JumpPos.Y:=-1;
  4218. LineText:=GetDisplayText(CurPos.Y);
  4219. LineText:=copy(LineText,CurPos.X+1,1);
  4220. if LineText='' then Exit;
  4221. CurChar:=LineText[1];
  4222. Y:=CurPos.Y; X:=CurPos.X; LineCount:=0;
  4223. BracketLevel:=1;
  4224. if ScanForward then
  4225. begin
  4226. SymIdx:=Pos(CurChar,OpenSymbols);
  4227. if SymIdx=0 then Exit;
  4228. repeat
  4229. Inc(LineCount);
  4230. GetDisplayTextFormat(Y,LineText,LineAttr);
  4231. if LineCount<>1 then X:=-1;
  4232. repeat
  4233. Inc(X);
  4234. if X<length(LineText) then
  4235. if copy(LineAttr,X+1,1)<>chr(attrComment) then
  4236. if (LineText[X+1]=CloseSymbols[SymIdx]) and (BracketLevel=1) then
  4237. begin
  4238. JumpPos.X:=X; JumpPos.Y:=Y;
  4239. end
  4240. else
  4241. if LineText[X+1]=OpenSymbols[SymIdx] then
  4242. Inc(BracketLevel)
  4243. else
  4244. if LineText[X+1]=CloseSymbols[SymIdx] then
  4245. if BracketLevel>1 then
  4246. Dec(BracketLevel);
  4247. until (X>=length(LineText)) or (JumpPos.X<>-1);
  4248. Inc(Y);
  4249. until (Y>=GetLineCount) or (JumpPos.X<>-1);
  4250. end
  4251. else
  4252. begin
  4253. SymIdx:=Pos(CurChar,CloseSymbols);
  4254. if SymIdx=0 then Exit;
  4255. repeat
  4256. Inc(LineCount);
  4257. GetDisplayTextFormat(Y,LineText,LineAttr);
  4258. if LineCount<>1 then X:=length(LineText);
  4259. repeat
  4260. Dec(X);
  4261. if X>0 then
  4262. if copy(LineAttr,X+1,1)<>chr(attrComment) then
  4263. if (LineText[X+1]=OpenSymbols[SymIdx]) and (BracketLevel=1) then
  4264. begin
  4265. JumpPos.X:=X; JumpPos.Y:=Y;
  4266. end
  4267. else
  4268. if LineText[X+1]=CloseSymbols[SymIdx] then
  4269. Inc(BracketLevel)
  4270. else
  4271. if LineText[X+1]=OpenSymbols[SymIdx] then
  4272. if BracketLevel>1 then
  4273. Dec(BracketLevel);
  4274. until (X<0) or (JumpPos.X<>-1);
  4275. Dec(Y);
  4276. until (Y<0) or (JumpPos.X<>-1);
  4277. end;
  4278. if JumpPos.X<>-1 then
  4279. begin
  4280. SetCurPtr(JumpPos.X,JumpPos.Y);
  4281. TrackCursor(true);
  4282. end;
  4283. end;
  4284. function TCustomCodeEditor.InsertNewLine: Sw_integer;
  4285. var i,Ind: Sw_integer;
  4286. S,IndentStr: string;
  4287. procedure CalcIndent(LineOver: Sw_integer);
  4288. begin
  4289. if (LineOver<0) or (LineOver>GetLineCount) or ((GetFlags and efNoIndent)<>0) then
  4290. Ind:=0 else
  4291. begin
  4292. repeat
  4293. IndentStr:=GetDisplayText(LineOver);
  4294. Dec(LineOver);
  4295. until (LineOver<0) or (IndentStr<>'');
  4296. Ind:=0;
  4297. while (Ind<length(IndentStr)) and (IndentStr[Ind+1]=' ') do
  4298. Inc(Ind);
  4299. end;
  4300. IndentStr:=CharStr(' ',Ind);
  4301. end;
  4302. var {SelBack: sw_integer;}
  4303. SCP: TPoint;
  4304. CI : sw_integer;
  4305. HoldUndo : Boolean;
  4306. L,NewL: PCustomLine;
  4307. EI,NewEI: PEditorLineInfo;
  4308. begin
  4309. if IsReadOnly then begin InsertNewLine:=-1; Exit; end;
  4310. Lock;
  4311. SCP:=CurPos;
  4312. HoldUndo:=GetStoreUndo;
  4313. SetStoreUndo(false);
  4314. if CurPos.Y<GetLineCount then S:=GetLineText(CurPos.Y) else S:='';
  4315. if Overwrite=false then
  4316. begin
  4317. if CurPos.Y<GetLineCount then
  4318. begin
  4319. L:=GetLine(CurPos.Y);
  4320. if not assigned(L) then
  4321. EI:=nil
  4322. else
  4323. EI:=L^.GetEditorInfo(@Self);
  4324. end
  4325. else
  4326. EI:=nil;
  4327. { SelBack:=0;}
  4328. CI:=LinePosToCharIdx(CurPos.Y,CurPos.X);
  4329. if GetLineCount>0 then
  4330. begin
  4331. S:=GetLineText(CurPos.Y);
  4332. { SelBack:=length(S)-SelEnd.X;}
  4333. SetLineText(CurPos.Y,RTrim(S,not IsFlagSet(efUseTabCharacters)));
  4334. end;
  4335. SetLineText(CurPos.Y,copy(S,1,CI-1));
  4336. CalcIndent(CurPos.Y);
  4337. S:=copy(S,CI,High(S));
  4338. i:=1;
  4339. while (i<=length(s)) and (i<=length(IndentStr)) and (s[i]=' ') do
  4340. inc(i);
  4341. if i>1 then
  4342. Delete(IndentStr,1,i-1);
  4343. NewL:=InsertLine(CurPos.Y+1,IndentStr+S);
  4344. LimitsChanged;
  4345. (* if PointOfs(SelStart)<>PointOfs(SelEnd) then { !!! check it - it's buggy !!! }
  4346. begin SelEnd.Y:=CurPos.Y+1; SelEnd.X:=length(GetLineText(CurPos.Y+1))-SelBack; end;*)
  4347. UpdateAttrs(CurPos.Y,attrAll);
  4348. SetCurPtr(Ind,CurPos.Y+1);
  4349. NewEI:=NewL^.GetEditorInfo(@Self);
  4350. if Assigned(EI) and Assigned(NewEI) then
  4351. begin
  4352. NewEI^.SetFold(EI^.Fold);
  4353. if Assigned(EI^.Fold) then
  4354. if EI^.Fold^.IsCollapsed then
  4355. EI^.Fold^.Collapse(false);
  4356. end;
  4357. SetStoreUndo(HoldUndo);
  4358. { obsolete IndentStr is taken care of by the Flags PM }
  4359. Addaction(eaInsertLine,SCP,CurPos,CharStr(' ',i-1){IndentStr},GetFlags);
  4360. SetStoreUndo(false);
  4361. AdjustSelection(CurPos.X-SCP.X,CurPos.Y-SCP.Y);
  4362. end else
  4363. begin
  4364. CalcIndent(CurPos.Y);
  4365. if CurPos.Y=GetLineCount-1 then
  4366. begin
  4367. AddLine(IndentStr);
  4368. AdjustSelection(0,1);
  4369. LimitsChanged;
  4370. SetStoreUndo(HoldUndo);
  4371. UpdateAttrs(CurPos.Y,attrAll);
  4372. SetCurPtr(Ind,CurPos.Y+1);
  4373. { obsolete IndentStr is taken care of by the Flags PM }
  4374. Addaction(eaInsertLine,SCP,CurPos,''{IndentStr},GetFlags);
  4375. SetStoreUndo(false);
  4376. end
  4377. else
  4378. begin
  4379. UpdateAttrs(CurPos.Y,attrAll);
  4380. SetStoreUndo(HoldUndo);
  4381. SetCurPtr(Ind,CurPos.Y+1);
  4382. AddAction(eaMoveCursor,SCP,CurPos,'',GetFlags);
  4383. SetStoreUndo(false);
  4384. end;
  4385. end;
  4386. DrawLines(CurPos.Y);
  4387. SetStoreUndo(HoldUndo);
  4388. SetModified(true);
  4389. Unlock;
  4390. end;
  4391. procedure TCustomCodeEditor.BreakLine;
  4392. begin
  4393. NotImplemented; Exit;
  4394. end;
  4395. procedure TCustomCodeEditor.BackSpace;
  4396. var S,PreS: string;
  4397. OI,CI,CP,Y,TX: Sw_integer;
  4398. SCP,SC1 : TPoint;
  4399. HoldUndo : Boolean;
  4400. begin
  4401. if IsReadOnly then Exit;
  4402. Lock;
  4403. SCP:=CurPos;
  4404. HoldUndo:=GetStoreUndo;
  4405. SetStoreUndo(false);
  4406. if CurPos.X=0 then
  4407. begin
  4408. if CurPos.Y>0 then
  4409. begin
  4410. S:=GetLineText(CurPos.Y-1);
  4411. SetLineText(CurPos.Y-1,S+GetLineText(CurPos.Y));
  4412. SC1.X:=Length(S);SC1.Y:=CurPOS.Y-1;
  4413. SetStoreUndo(HoldUndo);
  4414. AddAction(eaDeleteLine,SCP,SC1,GetLineText(CurPos.Y),GetFlags);
  4415. SetStoreUndo(false);
  4416. DeleteLine(CurPos.Y);
  4417. LimitsChanged;
  4418. SetCurPtr(length(S),CurPos.Y-1);
  4419. end;
  4420. end
  4421. else
  4422. begin
  4423. CP:=CurPos.X-1;
  4424. S:=GetLineText(CurPos.Y);
  4425. CI:=LinePosToCharIdx(CurPos.Y,CP);
  4426. if (s[ci]=TAB) and (CharIdxToLinePos(Curpos.y,ci)=cp) then
  4427. CP:=CharIdxToLinePos(CurPos.Y,CI-1)+1;
  4428. if IsFlagSet(efBackspaceUnindents) then
  4429. begin
  4430. S:=GetDisplayText(CurPos.Y);
  4431. if Trim(copy(S,1,CP+1))='' then
  4432. begin
  4433. Y:=CurPos.Y;
  4434. while (Y>0) do
  4435. begin
  4436. Dec(Y);
  4437. PreS:=GetDisplayText(Y);
  4438. if Trim(copy(PreS,1,CP+1))<>'' then Break;
  4439. end;
  4440. if Y<0 then PreS:='';
  4441. TX:=0;
  4442. while (TX<length(PreS)) and (PreS[TX+1]=' ') do
  4443. Inc(TX);
  4444. if TX<CP then CP:=TX;
  4445. end;
  4446. end;
  4447. S:=GetLineText(CurPos.Y);
  4448. OI:=LinePosToCharIdx(CurPos.Y,CurPos.X);
  4449. CI:=LinePosToCharIdx(CurPos.Y,CP);
  4450. SetLineText(CurPos.Y,copy(S,1,CI-1)+copy(S,OI,High(S)));
  4451. SetCurPtr(CP,CurPos.Y);
  4452. SetStoreUndo(HoldUndo);
  4453. Addaction(eaDeleteText,SCP,CurPos,Copy(S,CI,OI-CI),GetFlags);
  4454. SetStoreUndo(false);
  4455. end;
  4456. UpdateAttrs(CurPos.Y,attrAll);
  4457. AdjustSelection(CurPos.X-SCP.X,CurPos.Y-SCP.Y);
  4458. DrawLines(CurPos.Y);
  4459. SetStoreUndo(HoldUndo);
  4460. SetModified(true);
  4461. Unlock;
  4462. end;
  4463. procedure TCustomCodeEditor.DelChar;
  4464. var S: string;
  4465. SDX,SDY,CI : sw_integer;
  4466. HoldUndo : boolean;
  4467. SCP : TPoint;
  4468. begin
  4469. if IsReadOnly then Exit;
  4470. Lock;
  4471. HoldUndo:=GetStoreUndo;
  4472. SetStoreUndo(false);
  4473. S:=GetLineText(CurPos.Y);
  4474. CI:=LinePosToCharIdx(CurPos.Y,CurPos.X);
  4475. if CI>length(S) then
  4476. begin
  4477. if CurPos.Y<GetLineCount-1 then
  4478. begin
  4479. SetLineText(CurPos.Y,S+CharStr(' ',CurPOS.X-Length(S))+GetLineText(CurPos.Y+1));
  4480. SetStoreUndo(HoldUndo);
  4481. SCP.X:=0;SCP.Y:=CurPos.Y+1;
  4482. AddGroupedAction(eaDelChar);
  4483. AddAction(eaMoveCursor,CurPos,SCP,'',GetFlags);
  4484. AddAction(eaDeleteLine,SCP,CurPos,GetLineText(CurPos.Y+1),GetFlags);
  4485. CloseGroupedAction(eaDelChar);
  4486. SetStoreUndo(false);
  4487. DeleteLine(CurPos.Y+1);
  4488. LimitsChanged;
  4489. SDX:=0; SDY:=-1;
  4490. end;
  4491. end
  4492. else
  4493. begin
  4494. { Problem if S[CurPos.X+1]=TAB !! PM }
  4495. if S[CI]=TAB then
  4496. begin
  4497. { we want to remove the tab if we are at the first place
  4498. of the tab, but the following test was true for the last position
  4499. in tab
  4500. if CharIdxToLinePos(Curpos.y,ci)=Curpos.x then }
  4501. if CharIdxToLinePos(Curpos.y,ci-1)=Curpos.x-1 then
  4502. Delete(S,Ci,1)
  4503. else
  4504. S:=Copy(S,1,CI-1)+CharStr(' ',GetTabSize-1)+Copy(S,CI+1,High(S));
  4505. SetStoreUndo(HoldUndo);
  4506. Addaction(eaDeleteText,CurPos,CurPos,#9,GetFlags);
  4507. SetStoreUndo(false);
  4508. end
  4509. else
  4510. begin
  4511. SetStoreUndo(HoldUndo);
  4512. Addaction(eaDeleteText,CurPos,CurPos,S[CI],GetFlags);
  4513. SetStoreUndo(false);
  4514. Delete(S,CI,1);
  4515. end;
  4516. SetLineText(CurPos.Y,S);
  4517. SDX:=-1; SDY:=0;
  4518. end;
  4519. SetCurPtr(CurPos.X,CurPos.Y);
  4520. UpdateAttrs(CurPos.Y,attrAll);
  4521. AdjustSelection(SDX,SDY);
  4522. DrawLines(CurPos.Y);
  4523. SetStoreUndo(HoldUndo);
  4524. SetModified(true);
  4525. Unlock;
  4526. end;
  4527. procedure TCustomCodeEditor.DelWord;
  4528. var
  4529. SP,EP : TPoint;
  4530. SelSize : sw_integer;
  4531. begin
  4532. if IsReadOnly then Exit;
  4533. Lock;
  4534. SP:=SelStart;
  4535. EP:=SelEnd;
  4536. SetSelection(SelStart,SelStart);
  4537. SelectWord;
  4538. SelSize:=SelEnd.X-SelStart.X;
  4539. DelSelect;
  4540. SetSelection(SP,EP);
  4541. AdjustSelectionPos(CurPos.X,CurPos.Y,-SelSize,0);
  4542. if SelSize>0 then
  4543. SetModified(true);
  4544. Unlock;
  4545. end;
  4546. procedure TCustomCodeEditor.DelToEndOfWord;
  4547. var
  4548. SP,EP : TPoint;
  4549. S : String;
  4550. SelSize : sw_integer;
  4551. begin
  4552. if IsReadOnly then Exit;
  4553. Lock;
  4554. SP:=SelStart;
  4555. EP:=SelEnd;
  4556. SetSelection(SelStart,SelStart);
  4557. SelectWord;
  4558. S:=GetDisplayText(CurPos.Y);
  4559. if ((SelStart.X=SelEnd.X) and (SelStart.Y=SelEnd.Y)) then
  4560. begin
  4561. if (Length(S) <= CurPos.X) then
  4562. begin
  4563. SetSelection(SP,EP);
  4564. DelChar;
  4565. Unlock;
  4566. exit;
  4567. end
  4568. else
  4569. begin
  4570. SelEnd.X:=CurPos.X+1;
  4571. SelEnd.Y:=CurPos.Y;
  4572. end;
  4573. end;
  4574. while (length(S)>= SelEnd.X+1) and
  4575. ((S[SelEnd.X+1]=' ') or (S[SelEnd.X+1]=TAB)) do
  4576. inc(SelEnd.X);
  4577. SetSelection(CurPos,SelEnd);
  4578. SelSize:=SelEnd.X-SelStart.X;
  4579. DelSelect;
  4580. SetSelection(SP,EP);
  4581. AdjustSelectionPos(CurPos.X,CurPos.Y,-SelSize,0);
  4582. if SelSize>0 then
  4583. SetModified(true);
  4584. Unlock;
  4585. end;
  4586. procedure TCustomCodeEditor.DelStart;
  4587. var S: string;
  4588. begin
  4589. if IsReadOnly then Exit;
  4590. Lock;
  4591. S:=GetLineText(CurPos.Y);
  4592. if (S<>'') and (CurPos.X<>0) then
  4593. begin
  4594. SetLineText(CurPos.Y,copy(S,LinePosToCharIdx(CurPos.Y,CurPos.X),High(S)));
  4595. SetCurPtr(0,CurPos.Y);
  4596. UpdateAttrs(CurPos.Y,attrAll);
  4597. DrawLines(CurPos.Y);
  4598. SetModified(true);
  4599. end;
  4600. Unlock;
  4601. end;
  4602. procedure TCustomCodeEditor.DelEnd;
  4603. var S: string;
  4604. begin
  4605. if IsReadOnly then Exit;
  4606. Lock;
  4607. S:=GetLineText(CurPos.Y);
  4608. if (S<>'') and (CurPos.X<>length(S)) then
  4609. begin
  4610. SetLineText(CurPos.Y,copy(S,1,LinePosToCharIdx(CurPos.Y,CurPos.X)-1));
  4611. SetCurPtr(CurPos.X,CurPos.Y);
  4612. UpdateAttrs(CurPos.Y,attrAll);
  4613. DrawLines(CurPos.Y);
  4614. SetModified(true);
  4615. end;
  4616. Unlock;
  4617. end;
  4618. procedure TCustomCodeEditor.DelLine;
  4619. var
  4620. HoldUndo : boolean;
  4621. SP : TPoint;
  4622. S : String;
  4623. begin
  4624. if IsReadOnly then Exit;
  4625. Lock;
  4626. if GetLineCount>0 then
  4627. begin
  4628. SP:=CurPos;
  4629. S:=GetLineText(CurPos.Y);
  4630. HoldUndo:=GetStoreUndo;
  4631. SetStoreUndo(false);
  4632. DeleteLine(CurPos.Y);
  4633. LimitsChanged;
  4634. AdjustSelection(0,-1);
  4635. SetCurPtr(0,CurPos.Y);
  4636. UpdateAttrs(Max(0,CurPos.Y-1),attrAll);
  4637. DrawLines(CurPos.Y);
  4638. SetStoreUndo(HoldUndo);
  4639. AddAction(eaDeleteLine,SP,CurPos,S,GetFlags);
  4640. SetModified(true);
  4641. end;
  4642. Unlock;
  4643. end;
  4644. procedure TCustomCodeEditor.InsMode;
  4645. begin
  4646. SetInsertMode(Overwrite);
  4647. end;
  4648. function TCustomCodeEditor.GetCurrentWordArea(var StartP,EndP: TPoint): boolean;
  4649. const WordChars = ['A'..'Z','a'..'z','0'..'9','_'];
  4650. var P : TPoint;
  4651. S : String;
  4652. StartPos,EndPos : byte;
  4653. OK: boolean;
  4654. begin
  4655. P:=CurPos;
  4656. S:=GetLineText(P.Y);
  4657. StartPos:=P.X+1;
  4658. EndPos:=StartPos;
  4659. OK:=(S[StartPos] in WordChars);
  4660. if OK then
  4661. begin
  4662. While (StartPos>0) and (S[StartPos-1] in WordChars) do
  4663. Dec(StartPos);
  4664. While (EndPos<Length(S)) and (S[EndPos+1] in WordChars) do
  4665. Inc(EndPos);
  4666. StartP.X:=StartPos-1; StartP.Y:=CurPos.Y;
  4667. EndP.X:=EndPos-1; EndP.Y:=CurPos.Y;
  4668. end;
  4669. GetCurrentWordArea:=OK;
  4670. end;
  4671. function TCustomCodeEditor.GetCurrentWord : string;
  4672. var S: string;
  4673. StartP,EndP: TPoint;
  4674. begin
  4675. if GetCurrentWordArea(StartP,EndP)=false then
  4676. S:=''
  4677. else
  4678. begin
  4679. S:=GetLineText(StartP.Y);
  4680. S:=copy(S,StartP.X+1,EndP.X-StartP.X+1);
  4681. end;
  4682. GetCurrentWord:=S;
  4683. end;
  4684. procedure TCustomCodeEditor.StartSelect;
  4685. var P1,P2: TPoint;
  4686. begin
  4687. if ValidBlock=false then
  4688. begin
  4689. { SetSelection(SelStart,Limit);}
  4690. P1:=CurPos; P1.X:=0; P2:=CurPos; {P2.X:=length(GetLineText(P2.Y))+1;}
  4691. SetSelection(P1,P2);
  4692. end
  4693. else
  4694. SetSelection(CurPos,SelEnd);
  4695. if PointOfs(SelEnd)<PointOfs(SelStart) then
  4696. SetSelection(SelStart,SelStart);
  4697. CheckSels;
  4698. DrawView;
  4699. end;
  4700. procedure TCustomCodeEditor.EndSelect;
  4701. var P: TPoint;
  4702. LS: sw_integer;
  4703. begin
  4704. P:=CurPos;
  4705. { P.X:=Min(SelEnd.X,length(GetLineText(SelEnd.Y)));}
  4706. LS:=length(GetLineText(SelEnd.Y));
  4707. if LS<P.X then P.X:=LS;
  4708. CheckSels;
  4709. SetSelection(SelStart,P);
  4710. DrawView;
  4711. end;
  4712. procedure TCustomCodeEditor.DelSelect;
  4713. var LineDelta, LineCount, CurLine: Sw_integer;
  4714. StartX,EndX,LastX: Sw_integer;
  4715. S: string;
  4716. SPos : TPoint;
  4717. begin
  4718. if IsReadOnly or (ValidBlock=false) then Exit;
  4719. Lock;
  4720. AddGroupedAction(eaDelBlock);
  4721. LineCount:=(SelEnd.Y-SelStart.Y)+1;
  4722. LineDelta:=0; LastX:=CurPos.X;
  4723. CurLine:=SelStart.Y;
  4724. { single line : easy }
  4725. if LineCount=1 then
  4726. begin
  4727. S:=GetDisplayText(CurLine);
  4728. StartX:=SelStart.X;
  4729. EndX:=SelEnd.X;
  4730. SetDisplayText(CurLine,RExpand(copy(S,1,StartX),StartX)
  4731. +copy(S,EndX+1,High(S)));
  4732. if GetStoreUndo then
  4733. begin
  4734. SPos.X:=StartX;
  4735. SPos.Y:=CurLine;
  4736. AddAction(eaDeleteText,SPos,SPos,Copy(S,StartX+1,EndX-StartX),GetFlags);
  4737. end;
  4738. Inc(CurLine);
  4739. LastX:=SelStart.X;
  4740. end
  4741. { several lines : a bit less easy }
  4742. else
  4743. begin
  4744. S:=GetDisplayText(CurLine);
  4745. StartX:=SelStart.X;
  4746. EndX:=SelEnd.X;
  4747. SetDisplayText(CurLine,RExpand(copy(S,1,StartX),StartX)
  4748. +copy(GetDisplayText(CurLine+LineCount-1),EndX+1,High(S)));
  4749. if GetStoreUndo then
  4750. begin
  4751. SPos.X:=StartX;
  4752. SPos.Y:=CurLine;
  4753. AddAction(eaDeleteText,SPos,SPos,Copy(S,StartX+1,High(S)),GetFlags);
  4754. S:=GetDisplayText(CurLine+LineCount-1);
  4755. end;
  4756. Inc(CurLine);
  4757. Inc(LineDelta);
  4758. LastX:=SelStart.X;
  4759. while (LineDelta<LineCount) do
  4760. begin
  4761. { delete the complete line }
  4762. DeleteLine(CurLine);
  4763. Inc(LineDelta);
  4764. end;
  4765. if GetStoreUndo then
  4766. begin
  4767. AddAction(eaInsertText,SPos,SPos,Copy(S,EndX+1,High(S)),GetFlags);
  4768. end;
  4769. end;
  4770. HideSelect;
  4771. SetCurPtr(LastX,CurLine-1);
  4772. UpdateAttrs(CurPos.Y,attrAll);
  4773. DrawLines(CurPos.Y);
  4774. SetModified(true);
  4775. CloseGroupedAction(eaDelBlock);
  4776. UnLock;
  4777. end;
  4778. procedure TCustomCodeEditor.HideSelect;
  4779. begin
  4780. SetSelection(CurPos,CurPos);
  4781. DrawLines(Delta.Y);
  4782. end;
  4783. procedure TCustomCodeEditor.CopyBlock;
  4784. var Temp: PCodeEditor;
  4785. R: TRect;
  4786. begin
  4787. if IsReadOnly or (ValidBlock=false) then Exit;
  4788. Lock;
  4789. GetExtent(R);
  4790. AddGroupedAction(eaCopyBlock);
  4791. New(Temp, Init(R, nil, nil, nil,nil));
  4792. Temp^.InsertFrom(@Self);
  4793. (* Temp^.SelectAll(true);
  4794. { this selects one line too much because
  4795. we have a empty line at creation to avoid
  4796. negative line problems so we need to decrease SelEnd.Y }
  4797. Dec(Temp^.SelEnd.Y);*)
  4798. InsertFrom(Temp);
  4799. Dispose(Temp, Done);
  4800. CloseGroupedAction(eaCopyBlock);
  4801. UnLock;
  4802. end;
  4803. procedure TCustomCodeEditor.MoveBlock;
  4804. var Temp: PCodeEditor;
  4805. R: TRect;
  4806. OldPos: TPoint;
  4807. begin
  4808. if IsReadOnly then Exit;
  4809. if (SelStart.X=SelEnd.X) and (SelStart.Y=SelEnd.Y) then Exit;
  4810. Lock;
  4811. AddGroupedAction(eaMoveBlock);
  4812. GetExtent(R);
  4813. New(Temp, Init(R, nil, nil, nil,nil));
  4814. Temp^.InsertFrom(@Self);
  4815. OldPos:=CurPos;
  4816. if CurPos.Y>SelStart.Y then
  4817. Dec(OldPos.Y,Temp^.GetLineCount-1);
  4818. DelSelect;
  4819. SetCurPtr(OldPos.X,OldPos.Y);
  4820. InsertFrom(Temp);
  4821. Dispose(Temp, Done);
  4822. CloseGroupedAction(eaMoveBlock);
  4823. UnLock;
  4824. end;
  4825. procedure TCustomCodeEditor.IndentBlock;
  4826. var
  4827. ey,i,indlen : Sw_integer;
  4828. S,Ind : String;
  4829. Pos : Tpoint;
  4830. begin
  4831. if IsReadOnly then Exit;
  4832. if (SelStart.X=SelEnd.X) and (SelStart.Y=SelEnd.Y) then Exit;
  4833. Lock;
  4834. AddGroupedAction(eaIndentBlock);
  4835. ey:=selend.y;
  4836. if selend.x=0 then
  4837. dec(ey);
  4838. S:='';
  4839. { If AutoIndent try to align first line to
  4840. last line before selection }
  4841. { DISABLED created problems PM
  4842. if IsFlagSet(efAutoIndent) and (SelStart.Y>0) then
  4843. begin
  4844. i:=SelStart.Y-1;
  4845. while (S='') and (i>=0) do
  4846. begin
  4847. S:=GetDisplayText(i);
  4848. dec(i);
  4849. end;
  4850. if (S='') or (S[1]<>' ') then
  4851. Ind:=' '
  4852. else
  4853. begin
  4854. i:=1;
  4855. while (i<=Length(S)) and (S[i]=' ') do
  4856. inc(i);
  4857. indlen:=i;
  4858. S:=GetDisplayText(SelStart.Y);
  4859. i:=1;
  4860. while (i<=Length(S)) and (S[i]=' ') do
  4861. inc(i);
  4862. indlen:=indlen-i;
  4863. if indlen<=0 then
  4864. indlen:=1;
  4865. Ind:=CharStr(' ',indlen);
  4866. end;
  4867. end
  4868. else
  4869. Ind:=' ';}
  4870. Ind:=CharStr(' ',GetIndentSize);
  4871. for i:=selstart.y to ey do
  4872. begin
  4873. S:=GetLineText(i);
  4874. SetLineText(i,Ind+S);
  4875. Pos.X:=0;Pos.Y:=i;
  4876. AddAction(eaInsertText,Pos,Pos,Ind,GetFlags);
  4877. end;
  4878. SetCurPtr(CurPos.X,CurPos.Y);
  4879. { must be added manually here PM }
  4880. AddAction(eaMoveCursor,Pos,CurPos,'',GetFlags);
  4881. UpdateAttrsRange(SelStart.Y,SelEnd.Y,attrAll);
  4882. DrawLines(CurPos.Y);
  4883. SetModified(true);
  4884. CloseGroupedAction(eaIndentBlock);
  4885. UnLock;
  4886. end;
  4887. procedure TCustomCodeEditor.UnindentBlock;
  4888. var
  4889. ey,i,j,k,indlen : Sw_integer;
  4890. S : String;
  4891. Pos : TPoint;
  4892. begin
  4893. if IsReadOnly then Exit;
  4894. if (SelStart.X=SelEnd.X) and (SelStart.Y=SelEnd.Y) then Exit;
  4895. Lock;
  4896. AddGroupedAction(eaUnindentBlock);
  4897. ey:=selend.y;
  4898. if selend.x=0 then
  4899. dec(ey);
  4900. { If AutoIndent try to align first line to
  4901. last line before selection }
  4902. { Disabled created problems
  4903. if IsFlagSet(efAutoIndent) and (SelStart.Y>0) then
  4904. begin
  4905. S:=GetDisplayText(SelStart.Y);
  4906. i:=1;
  4907. while (i<=Length(S)) and (S[i]=' ') do
  4908. inc(i);
  4909. indlen:=i-1;
  4910. i:=SelStart.Y-1;
  4911. S:='';
  4912. while (S='') and (i>=0) do
  4913. begin
  4914. if Trim(Copy(GetDisplayText(i),1,indlen))='' then
  4915. S:=''
  4916. else
  4917. S:=GetDisplayText(i);
  4918. dec(i);
  4919. end;
  4920. if (S='') then
  4921. Indlen:=1
  4922. else
  4923. begin
  4924. i:=1;
  4925. while (i<=Length(S)) and (S[i]=' ') do
  4926. inc(i);
  4927. indlen:=indlen-i+1;
  4928. if indlen<=0 then
  4929. indlen:=1;
  4930. end;
  4931. end
  4932. else
  4933. Indlen:=1;}
  4934. Indlen:=GetIndentSize;
  4935. for i:=selstart.y to ey do
  4936. begin
  4937. S:=GetLineText(i);
  4938. k:=0;
  4939. for j:=1 to indlen do
  4940. if (length(s)>1) and (S[1]=' ') then
  4941. begin
  4942. Delete(s,1,1);
  4943. inc(k);
  4944. end;
  4945. SetLineText(i,S);
  4946. if k>0 then
  4947. begin
  4948. Pos.Y:=i;
  4949. Pos.X:=0;
  4950. AddAction(eaDeleteText,Pos,Pos,CharStr(' ',k),GetFlags);
  4951. end;
  4952. end;
  4953. SetCurPtr(CurPos.X,CurPos.Y);
  4954. UpdateAttrsRange(SelStart.Y,SelEnd.Y,attrAll);
  4955. DrawLines(CurPos.Y);
  4956. SetModified(true);
  4957. CloseGroupedAction(eaUnindentBlock);
  4958. UnLock;
  4959. end;
  4960. procedure TCustomCodeEditor.SelectWord;
  4961. const WordChars = ['A'..'Z','a'..'z','0'..'9','_'];
  4962. var S : String;
  4963. StartPos,EndPos : byte;
  4964. A,B: TPoint;
  4965. begin
  4966. A:=CurPos;
  4967. B:=CurPos;
  4968. S:=GetDisplayText(A.Y);
  4969. StartPos:=A.X+1;
  4970. EndPos:=StartPos;
  4971. if not (S[StartPos] in WordChars) then
  4972. exit
  4973. else
  4974. begin
  4975. While (StartPos>0) and (S[StartPos-1] in WordChars) do
  4976. Dec(StartPos);
  4977. While (EndPos<Length(S)) and (S[EndPos+1] in WordChars) do
  4978. Inc(EndPos);
  4979. A.X:=StartPos-1;
  4980. B.X:=EndPos;
  4981. SetSelection(A,B);
  4982. end;
  4983. end;
  4984. procedure TCustomCodeEditor.SelectLine;
  4985. var A,B: TPoint;
  4986. begin
  4987. if CurPos.Y<GetLineCount then
  4988. begin
  4989. A.Y:=CurPos.Y; A.X:=0;
  4990. B.Y:=CurPos.Y+1; B.X:=0;
  4991. SetSelection(A,B);
  4992. end;
  4993. end;
  4994. procedure TCustomCodeEditor.WriteBlock;
  4995. var FileName: string;
  4996. S: PBufStream;
  4997. begin
  4998. if ValidBlock=false then Exit;
  4999. FileName:='';
  5000. if EditorDialog(edWriteBlock, @FileName) <> cmCancel then
  5001. begin
  5002. FileName := FExpand(FileName);
  5003. New(S, Init(FileName, stCreate, 4096));
  5004. if (S=nil) or (S^.Status<>stOK) then
  5005. EditorDialog(edCreateError,@FileName)
  5006. else
  5007. if SaveAreaToStream(S,SelStart,SelEnd)=false then
  5008. EditorDialog(edWriteError,@FileName);
  5009. if Assigned(S) then Dispose(S, Done);
  5010. end;
  5011. end;
  5012. procedure TCustomCodeEditor.ReadBlock;
  5013. var FileName: string;
  5014. S: PBufStream;
  5015. E: PCodeEditor;
  5016. R: TRect;
  5017. begin
  5018. if IsReadOnly then Exit;
  5019. FileName:='';
  5020. if EditorDialog(edReadBlock, @FileName) <> cmCancel then
  5021. begin
  5022. FileName := FExpand(FileName);
  5023. New(S, Init(FileName, stOpenRead, 4096));
  5024. if (S=nil) or (S^.Status<>stOK) then
  5025. EditorDialog(edReadError,@FileName)
  5026. else
  5027. begin
  5028. R.Assign(0,0,0,0);
  5029. New(E, Init(R,nil,nil,nil,nil));
  5030. AddGroupedAction(eaReadBlock);
  5031. if E^.LoadFromStream(S)=false then
  5032. EditorDialog(edReadError,@FileName)
  5033. else
  5034. begin
  5035. E^.SelectAll(true);
  5036. Self.InsertFrom(E);
  5037. end;
  5038. CloseGroupedAction(eaReadBlock);
  5039. Dispose(E, Done);
  5040. end;
  5041. if Assigned(S) then Dispose(S, Done);
  5042. end;
  5043. end;
  5044. procedure TCustomCodeEditor.PrintBlock;
  5045. begin
  5046. NotImplemented; Exit;
  5047. end;
  5048. function TCustomCodeEditor.SelectCodeTemplate(var ShortCut: string): boolean;
  5049. begin
  5050. { Abstract }
  5051. SelectCodeTemplate:=false;
  5052. end;
  5053. procedure TCustomCodeEditor.ExpandCodeTemplate;
  5054. var Line,ShortCutInEditor,ShortCut: string;
  5055. X,Y,I,LineIndent: sw_integer;
  5056. CodeLines: PUnsortedStringCollection;
  5057. CanJump,Expanded: boolean;
  5058. CP: TPoint;
  5059. begin
  5060. {
  5061. The usage of editing primitives in this routine make it pretty slow, but
  5062. its speed is still acceptable and they make the implementation of Undo
  5063. much easier... - Gabor
  5064. }
  5065. if IsReadOnly then Exit;
  5066. Lock;
  5067. CP.X:=-1; CP.Y:=-1; Expanded:=false;
  5068. Line:=GetDisplayText(CurPos.Y);
  5069. X:=CurPos.X; ShortCut:='';
  5070. if X<=length(Line) then
  5071. while (X>0) and (Line[X] in (NumberChars+AlphaChars)) do
  5072. begin
  5073. ShortCut:=Line[X]+ShortCut;
  5074. Dec(X);
  5075. end;
  5076. ShortCutInEditor:=ShortCut;
  5077. New(CodeLines, Init(10,10));
  5078. if (ShortCut='') or (not TranslateCodeTemplate(ShortCut,CodeLines)) then
  5079. if SelectCodeTemplate(ShortCut) then
  5080. TranslateCodeTemplate(ShortCut,CodeLines);
  5081. if CodeLines^.Count>0 then
  5082. begin
  5083. LineIndent:=X;
  5084. SetCurPtr(X,CurPos.Y);
  5085. for I:=1 to length(ShortCutInEditor) do
  5086. DelChar;
  5087. for Y:=0 to CodeLines^.Count-1 do
  5088. begin
  5089. Line:=CodeLines^.At(Y)^;
  5090. CanJump:=false;
  5091. if (Y>0) then
  5092. begin
  5093. CanJump:=Trim(GetLineText(CurPos.Y))='';
  5094. if CanJump=false then
  5095. begin
  5096. (* for X:=1 to LineIndent do { indent template lines to align }
  5097. AddChar(' '); { them to the first line }*)
  5098. InsertText(CharStr(' ',LineIndent));
  5099. end
  5100. else
  5101. SetCurPtr(CurPos.X+LineIndent,CurPos.Y);
  5102. end;
  5103. I:=Pos(CodeTemplateCursorChar,Line);
  5104. if I>0 then
  5105. begin
  5106. Delete(Line,I,1);
  5107. CP.X:=CurPos.X+I-1;
  5108. CP.Y:=CurPos.Y;
  5109. end;
  5110. InsertText(Line);
  5111. if Y<CodeLines^.Count-1 then
  5112. begin
  5113. InsertNewLine; { line break }
  5114. if CanJump=false then
  5115. begin
  5116. while CurPos.X>0 do { unindent }
  5117. begin
  5118. SetCurPtr(CurPos.X-1,CurPos.Y);
  5119. DelChar;
  5120. end;
  5121. end
  5122. else
  5123. SetCurPtr(0,CurPos.Y);
  5124. end;
  5125. end;
  5126. Expanded:=true;
  5127. end;
  5128. Dispose(CodeLines, Done);
  5129. if (CP.X<>-1) and (CP.Y<>-1) then
  5130. SetCurPtr(CP.X,CP.Y);
  5131. UnLock;
  5132. end;
  5133. procedure TCustomCodeEditor.AddChar(C: char);
  5134. const OpenBrackets : string[10] = '[({';
  5135. CloseBrackets : string[10] = '])}';
  5136. var S,SC,TabS: string;
  5137. BI: byte;
  5138. CI,TabStart,LocTabSize : Sw_integer;
  5139. SP: TPoint;
  5140. HoldUndo : boolean;
  5141. begin
  5142. if IsReadOnly then Exit;
  5143. Lock;
  5144. SP:=CurPos;
  5145. HoldUndo:=GetStoreUndo;
  5146. SetStoreUndo(false);
  5147. if (C<>TAB) or IsFlagSet(efUseTabCharacters) then
  5148. SC:=C
  5149. else
  5150. begin
  5151. LocTabSize:=GetTabSize - (CurPos.X mod GetTabSize);
  5152. if (CurPos.Y<=1) or not IsFlagSet(efAutoIndent) then
  5153. SC:=CharStr(' ',LocTabSize)
  5154. else
  5155. begin
  5156. S:=GetLineText(CurPos.Y-1);
  5157. BI:=CurPos.X+1;
  5158. while (BI<=Length(S)) and (S[BI]=' ') do
  5159. inc(BI);
  5160. if (BI=CurPos.X+1) or (BI>Length(S)) then
  5161. SC:=CharStr(' ',LocTabSize)
  5162. else
  5163. SC:=CharStr(' ',BI-CurPos.X-1);
  5164. end;
  5165. end;
  5166. S:=GetLineText(CurPos.Y);
  5167. if CharIdxToLinePos(CurPos.Y,length(S))<CurPos.X then
  5168. begin
  5169. S:=S+CharStr(' ',CurPos.X-CharIdxToLinePos(CurPos.Y,length(S)){-1});
  5170. SetLineText(CurPos.Y,S);
  5171. end;
  5172. CI:=LinePosToCharIdx(CurPos.Y,CurPos.X);
  5173. if (CI>0) and (S[CI]=TAB) and not IsFlagSet(efUseTabCharacters) then
  5174. begin
  5175. if CI=1 then
  5176. TabStart:=0
  5177. else
  5178. TabStart:=CharIdxToLinePos(CurPos.Y,CI-1)+1;
  5179. if SC=Tab then TabS:=Tab else
  5180. TabS:=CharStr(' ',CurPos.X-TabStart);
  5181. SetLineText(CurPos.Y,copy(S,1,CI-1)+TabS+SC+copy(S,CI+1,High(S)));
  5182. SetCurPtr(CharIdxToLinePos(CurPos.Y,CI+length(TabS)+length(SC)),CurPos.Y);
  5183. end
  5184. else
  5185. begin
  5186. if Overwrite and (CI<=length(S)) then
  5187. begin
  5188. SetLineText(CurPos.Y,copy(S,1,CI-1)+SC+copy(S,CI+length(SC),High(S)));
  5189. end
  5190. else
  5191. SetLineText(CurPos.Y,copy(S,1,CI-1)+SC+copy(S,CI,High(S)));
  5192. SetCurPtr(CharIdxToLinePos(CurPos.Y,CI+length(SC)),CurPos.Y);
  5193. end;
  5194. { must be before CloseBrackets !! }
  5195. SetStoreUndo(HoldUndo);
  5196. if Overwrite then
  5197. Addaction(eaOverwriteText,SP,CurPos,Copy(S,CI,length(SC)),GetFlags)
  5198. else
  5199. Addaction(eaInsertText,SP,CurPos,SC,GetFlags);
  5200. SetStoreUndo(false);
  5201. if IsFlagSet(efAutoBrackets) then
  5202. begin
  5203. BI:=Pos(C,OpenBrackets);
  5204. if (BI>0) then
  5205. begin
  5206. SetStoreUndo(HoldUndo);
  5207. AddChar(CloseBrackets[BI]);
  5208. SetStoreUndo(false);
  5209. SetCurPtr(CurPos.X-1,CurPos.Y);
  5210. end;
  5211. end;
  5212. UpdateAttrs(CurPos.Y,attrAll);
  5213. if GetInsertMode then
  5214. AdjustSelection(CurPos.X-SP.X,CurPos.Y-SP.Y);
  5215. DrawLines(CurPos.Y);
  5216. SetStoreUndo(HoldUndo);
  5217. SetModified(true);
  5218. UnLock;
  5219. end;
  5220. {$ifdef WinClipSupported}
  5221. function TCustomCodeEditor.ClipPasteWin: Boolean;
  5222. var OK: boolean;
  5223. l,i : longint;
  5224. p,p10,p2,p13 : pchar;
  5225. s : string;
  5226. BPos,EPos,StorePos : TPoint;
  5227. first : boolean;
  5228. begin
  5229. Lock;
  5230. OK:=WinClipboardSupported;
  5231. if OK then
  5232. begin
  5233. first:=true;
  5234. StorePos:=CurPos;
  5235. i:=CurPos.Y;
  5236. l:=GetTextWinClipboardSize;
  5237. if l=0 then
  5238. OK:=false
  5239. else
  5240. OK:=GetTextWinClipBoardData(p,l);
  5241. if OK then
  5242. begin
  5243. if l>500 then
  5244. PushInfo(msg_readingwinclipboard);
  5245. AddGroupedAction(eaPasteWin);
  5246. p2:=p;
  5247. p13:=strpos(p,#13);
  5248. p10:=strpos(p,#10);
  5249. while assigned(p10) do
  5250. begin
  5251. if p13+1=p10 then
  5252. p13[0]:=#0
  5253. else
  5254. p10[0]:=#0;
  5255. s:=strpas(p2);
  5256. if first then
  5257. begin
  5258. { we need to cut the line in two
  5259. if not at end of line PM }
  5260. InsertNewLine;
  5261. SetCurPtr(StorePos.X,StorePos.Y);
  5262. InsertText(s);
  5263. first:=false;
  5264. end
  5265. else
  5266. begin
  5267. Inc(i);
  5268. InsertLine(i,s);
  5269. BPos.X:=0;BPos.Y:=i;
  5270. EPOS.X:=Length(s);EPos.Y:=i;
  5271. AddAction(eaInsertLine,BPos,EPos,GetDisplayText(i),GetFlags);
  5272. end;
  5273. if p13+1=p10 then
  5274. p13[0]:=#13
  5275. else
  5276. p10[0]:=#10;
  5277. p2:=@p10[1];
  5278. p13:=strpos(p2,#13);
  5279. p10:=strpos(p2,#10);
  5280. end;
  5281. if strlen(p2)>0 then
  5282. begin
  5283. s:=strpas(p2);
  5284. if not first then
  5285. SetCurPtr(0,i+1);
  5286. InsertText(s);
  5287. end;
  5288. SetCurPtr(StorePos.X,StorePos.Y);
  5289. SetModified(true);
  5290. UpdateAttrs(StorePos.Y,attrAll);
  5291. CloseGroupedAction(eaPasteWin);
  5292. Update;
  5293. if l>500 then
  5294. PopInfo;
  5295. { we must free the allocated memory }
  5296. freemem(p,l);
  5297. DrawView;
  5298. end;
  5299. end;
  5300. ClipPasteWin:=OK;
  5301. UnLock;
  5302. end;
  5303. function TCustomCodeEditor.ClipCopyWin: Boolean;
  5304. var OK,ShowInfo: boolean;
  5305. p,p2 : pchar;
  5306. s : string;
  5307. i,str_begin,str_end,NumLines,PcLength : longint;
  5308. begin
  5309. NumLines:=SelEnd.Y-SelStart.Y;
  5310. if (NumLines>0) or (SelEnd.X>SelStart.X) then
  5311. Inc(NumLines);
  5312. if NumLines=0 then
  5313. exit;
  5314. Lock;
  5315. ShowInfo:=SelEnd.Y-SelStart.Y>50;
  5316. if ShowInfo then
  5317. PushInfo(msg_copyingwinclipboard);
  5318. { First calculate needed size }
  5319. { for newlines first + 1 for terminal #0 }
  5320. PcLength:=Length(EOL)*(NumLines-1)+1;
  5321. { overestimated but can not be that big PM }
  5322. for i:=SelStart.Y to SelEnd.Y do
  5323. PCLength:=PCLength+Length(GetLineText(i));
  5324. getmem(p,PCLength);
  5325. i:=SelStart.Y;
  5326. s:=GetLineText(i);
  5327. str_begin:=LinePosToCharIdx(i,SelStart.X);
  5328. if SelEnd.Y>SelStart.Y then
  5329. str_end:=High(S)
  5330. else
  5331. str_end:=LinePosToCharIdx(i,SelEnd.X)-1;
  5332. s:=copy(s,str_begin,str_end-str_begin+1);
  5333. strpcopy(p,s);
  5334. p2:=strend(p);
  5335. inc(i);
  5336. while i<SelEnd.Y do
  5337. begin
  5338. strpcopy(p2,EOL+GetLineText(i));
  5339. p2:=strend(p2);
  5340. Inc(i);
  5341. end;
  5342. if SelEnd.Y>SelStart.Y then
  5343. begin
  5344. s:=copy(GetLineText(i),1,LinePosToCharIdx(i,SelEnd.X)-1);
  5345. strpcopy(p2,EOL+s);
  5346. end;
  5347. OK:=WinClipboardSupported;
  5348. if OK then
  5349. begin
  5350. OK:=SetTextWinClipBoardData(p,strlen(p));
  5351. end;
  5352. ClipCopyWin:=OK;
  5353. if ShowInfo then
  5354. PopInfo;
  5355. Freemem(p,PCLength);
  5356. UnLock;
  5357. end;
  5358. {$endif WinClipSupported}
  5359. function TCustomCodeEditor.ClipCopy: Boolean;
  5360. var OK,ShowInfo: boolean;
  5361. begin
  5362. Lock;
  5363. {AddGroupedAction(eaCopy);
  5364. can we undo a copy ??
  5365. maybe as an Undo Paste in Clipboard !! }
  5366. OK:=Clipboard<>nil;
  5367. if OK then
  5368. ShowInfo:=SelEnd.Y-SelStart.Y>50
  5369. else
  5370. ShowInfo:=false;
  5371. if ShowInfo then
  5372. PushInfo(msg_copyingclipboard);
  5373. if OK then OK:=Clipboard^.InsertFrom(@Self);
  5374. if ShowInfo then
  5375. PopInfo;
  5376. ClipCopy:=OK;
  5377. UnLock;
  5378. end;
  5379. procedure TCustomCodeEditor.ClipCut;
  5380. var
  5381. ShowInfo : boolean;
  5382. begin
  5383. if IsReadOnly then Exit;
  5384. Lock;
  5385. AddGroupedAction(eaCut);
  5386. DontConsiderShiftState:=true;
  5387. if Clipboard<>nil then
  5388. begin
  5389. ShowInfo:=SelEnd.Y-SelStart.Y>50;
  5390. if ShowInfo then
  5391. PushInfo(msg_cutting);
  5392. if Clipboard^.InsertFrom(@Self) then
  5393. begin
  5394. if not IsClipBoard then
  5395. DelSelect;
  5396. SetModified(true);
  5397. end;
  5398. if ShowInfo then
  5399. PopInfo;
  5400. end;
  5401. CloseGroupedAction(eaCut);
  5402. UnLock;
  5403. DontConsiderShiftState:=false;
  5404. end;
  5405. procedure TCustomCodeEditor.ClipPaste;
  5406. var
  5407. ShowInfo : boolean;
  5408. begin
  5409. if IsReadOnly then Exit;
  5410. DontConsiderShiftState:=true;
  5411. Lock;
  5412. AddGroupedAction(eaPaste);
  5413. if Clipboard<>nil then
  5414. begin
  5415. ShowInfo:=Clipboard^.SelEnd.Y-Clipboard^.SelStart.Y>50;
  5416. if ShowInfo then
  5417. PushInfo(msg_pastingclipboard);
  5418. InsertFrom(Clipboard);
  5419. if ShowInfo then
  5420. PopInfo;
  5421. SetModified(true);
  5422. end;
  5423. CloseGroupedAction(eaPaste);
  5424. UnLock;
  5425. DontConsiderShiftState:=false;
  5426. end;
  5427. procedure TCustomCodeEditor.Undo;
  5428. begin
  5429. NotImplemented; Exit;
  5430. end;
  5431. procedure TCustomCodeEditor.Redo;
  5432. begin
  5433. NotImplemented; Exit;
  5434. end;
  5435. procedure TCustomCodeEditor.GotoLine;
  5436. var
  5437. GotoRec: TGotoLineDialogRec;
  5438. begin
  5439. with GotoRec do
  5440. begin
  5441. LineNo:='1';
  5442. Lines:=GetLineCount;
  5443. if EditorDialog(edGotoLine, @GotoRec) <> cmCancel then
  5444. begin
  5445. Lock;
  5446. SetCurPtr(0,StrToInt(LineNo)-1);
  5447. TrackCursor(true);
  5448. UnLock;
  5449. end;
  5450. end;
  5451. end;
  5452. procedure TCustomCodeEditor.Find;
  5453. var
  5454. FindRec: TFindDialogRec;
  5455. DoConf: boolean;
  5456. begin
  5457. with FindRec do
  5458. begin
  5459. Find := FindStr;
  5460. if GetCurrentWord<>'' then
  5461. Find:=GetCurrentWord;
  5462. {$ifdef TEST_REGEXP}
  5463. Options := ((FindFlags and ffmOptionsFind) shr ffsOptions) or
  5464. ((FindFlags and ffUseRegExp) shr ffsUseRegExpFind);
  5465. {$else not TEST_REGEXP}
  5466. Options := (FindFlags and ffmOptions) shr ffsOptions;
  5467. {$endif TEST_REGEXP}
  5468. Direction := (FindFlags and ffmDirection) shr ffsDirection;
  5469. Scope := (FindFlags and ffmScope) shr ffsScope;
  5470. Origin := (FindFlags and ffmOrigin) shr ffsOrigin;
  5471. DoConf:= (FindFlags and ffPromptOnReplace)<>0;
  5472. FindReplaceEditor:=@self;
  5473. if EditorDialog(edFind, @FindRec) <> cmCancel then
  5474. begin
  5475. FindStr := Find;
  5476. {$ifdef TEST_REGEXP}
  5477. FindFlags := ((Options and ffmOptionsFind) shl ffsOptions) or (Direction shl ffsDirection) or
  5478. ((Options and ffmUseRegExpFind) shl ffsUseRegExpFind) or
  5479. (Scope shl ffsScope) or (Origin shl ffsOrigin);
  5480. {$else : not TEST_REGEXP}
  5481. FindFlags := ((Options and ffmOptions) shl ffsOptions) or (Direction shl ffsDirection) or
  5482. (Scope shl ffsScope) or (Origin shl ffsOrigin);
  5483. {$endif TEST_REGEXP}
  5484. FindFlags := FindFlags and not ffDoReplace;
  5485. if DoConf then
  5486. FindFlags := (FindFlags or ffPromptOnReplace);
  5487. SearchRunCount:=0;
  5488. if FindStr<>'' then
  5489. DoSearchReplace
  5490. else
  5491. EditorDialog(edSearchFailed,nil);
  5492. end;
  5493. FindReplaceEditor:=nil;
  5494. end;
  5495. end;
  5496. procedure TCustomCodeEditor.Replace;
  5497. var
  5498. ReplaceRec: TReplaceDialogRec;
  5499. Re: word;
  5500. begin
  5501. if IsReadOnly then Exit;
  5502. with ReplaceRec do
  5503. begin
  5504. Find := FindStr;
  5505. if GetCurrentWord<>'' then
  5506. Find:=GetCurrentWord;
  5507. Replace := ReplaceStr;
  5508. {$ifdef TEST_REGEXP}
  5509. Options := (FindFlags and ffmOptions) shr ffsOptions or
  5510. (FindFlags and ffUseRegExp) shr ffsUseRegExpReplace;
  5511. {$else not TEST_REGEXP}
  5512. Options := (FindFlags and ffmOptions) shr ffsOptions;
  5513. {$endif TEST_REGEXP}
  5514. Direction := (FindFlags and ffmDirection) shr ffsDirection;
  5515. Scope := (FindFlags and ffmScope) shr ffsScope;
  5516. Origin := (FindFlags and ffmOrigin) shr ffsOrigin;
  5517. FindReplaceEditor:=@self;
  5518. Re:=EditorDialog(edReplace, @ReplaceRec);
  5519. FindReplaceEditor:=nil;
  5520. if Re <> cmCancel then
  5521. begin
  5522. FindStr := Find;
  5523. ReplaceStr := Replace;
  5524. FindFlags := (Options shl ffsOptions) or (Direction shl ffsDirection) or
  5525. {$ifdef TEST_REGEXP}
  5526. ((Options and ffmUseRegExpReplace) shl ffsUseRegExpReplace) or
  5527. {$endif TEST_REGEXP}
  5528. (Scope shl ffsScope) or (Origin shl ffsOrigin);
  5529. FindFlags := FindFlags or ffDoReplace;
  5530. if Re = cmYes then
  5531. FindFlags := FindFlags or ffReplaceAll;
  5532. SearchRunCount:=0;
  5533. if FindStr<>'' then
  5534. DoSearchReplace
  5535. else
  5536. EditorDialog(edSearchFailed,nil);
  5537. end;
  5538. end;
  5539. end;
  5540. procedure TCustomCodeEditor.DoSearchReplace;
  5541. var S: string;
  5542. DX,DY,P,Y,X: sw_integer;
  5543. Count: sw_integer;
  5544. Found,CanExit: boolean;
  5545. SForward,DoReplace,DoReplaceAll: boolean;
  5546. {$ifdef TEST_REGEXP}
  5547. UseRegExp : boolean;
  5548. RegExpEngine : TRegExprEngine;
  5549. RegExpFlags : tregexprflags;
  5550. regexpindex,regexplen : longint;
  5551. findstrpchar : pchar;
  5552. {$endif TEST_REGEXP}
  5553. LeftOK,RightOK: boolean;
  5554. FoundCount: sw_integer;
  5555. A,B: TPoint;
  5556. AreaStart,AreaEnd: TPoint;
  5557. CanReplace,Confirm: boolean;
  5558. Re: word;
  5559. IFindStr : string;
  5560. BT : BTable;
  5561. function ContainsText(const SubS:string;var S: string; Start: Sw_word): Sw_integer;
  5562. var
  5563. P: Sw_Integer;
  5564. begin
  5565. if Start<=0 then
  5566. P:=0
  5567. else
  5568. begin
  5569. if SForward then
  5570. begin
  5571. if Start>length(s) then
  5572. P:=0
  5573. else if FindFlags and ffCaseSensitive<>0 then
  5574. P:=BMFScan(S[Start],length(s)+1-Start,FindStr,Bt)+1
  5575. else
  5576. P:=BMFIScan(S[Start],length(s)+1-Start,IFindStr,Bt)+1;
  5577. if P>0 then
  5578. Inc(P,Start-1);
  5579. end
  5580. else
  5581. begin
  5582. if start>length(s) then
  5583. start:=length(s);
  5584. if FindFlags and ffCaseSensitive<>0 then
  5585. P:=BMBScan(S[1],Start,FindStr,Bt)+1
  5586. else
  5587. P:=BMBIScan(S[1],Start,IFindStr,Bt)+1;
  5588. end;
  5589. end;
  5590. ContainsText:=P;
  5591. end;
  5592. function InArea(X,Y: sw_integer): boolean;
  5593. begin
  5594. InArea:=((AreaStart.Y=Y) and (AreaStart.X<=X)) or
  5595. ((AreaStart.Y<Y) and (Y<AreaEnd.Y)) or
  5596. ((AreaEnd.Y=Y) and (X<=AreaEnd.X));
  5597. end;
  5598. var CurDY: sw_integer;
  5599. begin
  5600. if FindStr='' then
  5601. begin
  5602. Find;
  5603. { Find will call DoFindReplace at end again
  5604. so we need to exit directly now PM }
  5605. exit;
  5606. end;
  5607. Inc(SearchRunCount);
  5608. SForward:=(FindFlags and ffmDirection)=ffForward;
  5609. DoReplace:=(FindFlags and ffDoReplace)<>0;
  5610. Confirm:=(FindFlags and ffPromptOnReplace)<>0;
  5611. DoReplaceAll:=(FindFlags and ffReplaceAll)<>0;
  5612. {$ifdef TEST_REGEXP}
  5613. UseRegExp:=(FindFlags and ffUseRegExp)<>0;
  5614. if UseRegExp then
  5615. begin
  5616. if FindFlags and ffCaseSensitive<>0 then
  5617. RegExpFlags:=[ref_caseinsensitive]
  5618. else
  5619. RegExpFlags:=[];
  5620. getmem(findstrpchar,length(findstr)+1);
  5621. strpcopy(findstrpchar,findstr);
  5622. RegExpEngine:=GenerateRegExprEngine(findstrpchar,RegExpFlags);
  5623. strdispose(findstrpchar);
  5624. end;
  5625. {$endif TEST_REGEXP}
  5626. Count:=GetLineCount;
  5627. FoundCount:=0;
  5628. { Empty file ? }
  5629. if Count=0 then
  5630. begin
  5631. EditorDialog(edSearchFailed,nil);
  5632. exit;
  5633. end;
  5634. if SForward then
  5635. DY:=1
  5636. else
  5637. DY:=-1;
  5638. DX:=DY;
  5639. if FindStr<>'' then
  5640. PushInfo('Looking for "'+FindStr+'"');
  5641. if (FindFlags and ffmScope)=ffGlobal then
  5642. begin
  5643. AreaStart.X:=0;
  5644. AreaStart.Y:=0;
  5645. AreaEnd.X:=length(GetDisplayText(Count-1));
  5646. AreaEnd.Y:=Count-1;
  5647. end
  5648. else
  5649. begin
  5650. AreaStart:=SelStart;
  5651. AreaEnd:=SelEnd;
  5652. end;
  5653. X:=CurPos.X-DX;
  5654. Y:=CurPos.Y;;
  5655. if SearchRunCount=1 then
  5656. if (FindFlags and ffmOrigin)=ffEntireScope then
  5657. if SForward then
  5658. begin
  5659. X:=AreaStart.X-1;
  5660. Y:=AreaStart.Y;
  5661. end
  5662. else
  5663. begin
  5664. X:=AreaEnd.X+1;
  5665. Y:=AreaEnd.Y;
  5666. end;
  5667. if FindFlags and ffCaseSensitive<>0 then
  5668. begin
  5669. if SForward then
  5670. BMFMakeTable(FindStr,bt)
  5671. else
  5672. BMBMakeTable(FindStr,bt);
  5673. end
  5674. else
  5675. begin
  5676. IFindStr:=Upper(FindStr);
  5677. if SForward then
  5678. BMFMakeTable(IFindStr,bt)
  5679. else
  5680. BMBMakeTable(IFindStr,bt);
  5681. end;
  5682. inc(X,DX);
  5683. CanExit:=false;
  5684. if (DoReplace=false) or ((Confirm=false) and (Owner<>nil)) then
  5685. Owner^.Lock;
  5686. if InArea(X,Y) then
  5687. repeat
  5688. CurDY:=DY;
  5689. S:=GetDisplayText(Y);
  5690. {$ifdef TEST_REGEXP}
  5691. if UseRegExp then
  5692. begin
  5693. getmem(findstrpchar,length(Copy(S,X+1,high(S)))+1);
  5694. strpcopy(findstrpchar,Copy(S,X+1,high(S)));
  5695. { If start of line is required do check other positions PM }
  5696. if (FindStr[1]='^') and (X<>0) then
  5697. Found:=false
  5698. else
  5699. Found:=RegExprPos(RegExpEngine,findstrpchar,regexpindex,regexplen);
  5700. strdispose(findstrpchar);
  5701. P:=regexpindex+X+1;
  5702. end
  5703. else
  5704. {$endif TEST_REGEXP}
  5705. begin
  5706. P:=ContainsText(FindStr,S,X+1);
  5707. Found:=P<>0;
  5708. end;
  5709. if Found then
  5710. begin
  5711. A.X:=P-1;
  5712. A.Y:=Y;
  5713. B.Y:=Y;
  5714. {$ifdef TEST_REGEXP}
  5715. if UseRegExp then
  5716. B.X:=A.X+regexplen
  5717. else
  5718. {$endif TEST_REGEXP}
  5719. B.X:=A.X+length(FindStr);
  5720. end;
  5721. Found:=Found and InArea(A.X,A.Y);
  5722. if Found and ((FindFlags and ffWholeWordsOnly)<>0) then
  5723. begin
  5724. LeftOK:=(A.X<=0) or (not( (S[A.X] in AlphaChars) or (S[A.X] in NumberChars) ));
  5725. RightOK:=(B.X>=length(S)) or (not( (S[B.X+1] in AlphaChars) or (S[B.X+1] in NumberChars) ));
  5726. Found:=LeftOK and RightOK;
  5727. if Found=false then
  5728. begin
  5729. CurDY:=0;
  5730. X:=B.X+1;
  5731. end;
  5732. end;
  5733. if Found then
  5734. Inc(FoundCount);
  5735. if Found then
  5736. begin
  5737. Lock;
  5738. if SForward then
  5739. SetCurPtr(B.X,B.Y)
  5740. else
  5741. SetCurPtr(A.X,A.Y);
  5742. TrackCursor(true);
  5743. SetHighlight(A,B);
  5744. UnLock;
  5745. CurDY:=0;
  5746. if (DoReplace=false) then
  5747. begin
  5748. CanExit:=true;
  5749. If SForward then
  5750. begin
  5751. X:=B.X;
  5752. Y:=B.Y;
  5753. end
  5754. else
  5755. begin
  5756. X:=A.X;
  5757. Y:=A.Y;
  5758. end;
  5759. end
  5760. else
  5761. begin
  5762. if Confirm=false then CanReplace:=true else
  5763. begin
  5764. Re:=EditorDialog(edReplacePrompt,@CurPos);
  5765. case Re of
  5766. cmYes :
  5767. CanReplace:=true;
  5768. cmNo :
  5769. CanReplace:=false;
  5770. else {cmCancel}
  5771. begin
  5772. CanReplace:=false;
  5773. CanExit:=true;
  5774. end;
  5775. end;
  5776. end;
  5777. if CanReplace then
  5778. begin
  5779. Lock;
  5780. SetSelection(A,B);
  5781. DelSelect;
  5782. InsertText(ReplaceStr);
  5783. if SForward then
  5784. begin
  5785. X:=CurPos.X;
  5786. Y:=CurPos.Y;
  5787. end
  5788. else
  5789. begin
  5790. X:=A.X;
  5791. Y:=A.Y;
  5792. end;
  5793. UnLock;
  5794. end
  5795. else
  5796. begin
  5797. If SForward then
  5798. begin
  5799. X:=B.X;
  5800. Y:=B.Y;
  5801. end
  5802. else
  5803. begin
  5804. X:=A.X;
  5805. Y:=A.Y;
  5806. end;
  5807. end;
  5808. if (DoReplaceAll=false) then
  5809. CanExit:=true;
  5810. end;
  5811. end;
  5812. if (CanExit=false) and (CurDY<>0) then
  5813. begin
  5814. inc(Y,CurDY);
  5815. if SForward then
  5816. X:=0
  5817. else
  5818. X:=254;
  5819. CanExit:=(Y>=Count) or (Y<0);
  5820. end;
  5821. if not CanExit then
  5822. CanExit:=not InArea(X,Y);
  5823. until CanExit;
  5824. if (FoundCount=0) or (DoReplace) then
  5825. SetHighlight(CurPos,CurPos);
  5826. if (DoReplace=false) or ((Confirm=false) and (Owner<>nil)) then
  5827. Owner^.UnLock;
  5828. {if (DoReplace=false) or (Confirm=false) then
  5829. UnLock;}
  5830. if (FoundCount=0) then
  5831. EditorDialog(edSearchFailed,nil);
  5832. if FindStr<>'' then
  5833. PopInfo;
  5834. {$ifdef TEST_REGEXP}
  5835. if UseRegExp then
  5836. DestroyRegExprEngine(RegExpEngine);
  5837. {$endif TEST_REGEXP}
  5838. if (FindFlags and ffmScope)=ffSelectedText then
  5839. { restore selection PM }
  5840. begin
  5841. SetSelection(AreaStart,AreaEnd);
  5842. end;
  5843. end;
  5844. function TCustomCodeEditor.GetInsertMode: boolean;
  5845. begin
  5846. GetInsertMode:=(GetFlags and efInsertMode)<>0;
  5847. end;
  5848. procedure TCustomCodeEditor.SetInsertMode(InsertMode: boolean);
  5849. begin
  5850. if InsertMode then
  5851. SetFlags(GetFlags or efInsertMode)
  5852. else
  5853. SetFlags(GetFlags and (not efInsertMode));
  5854. DrawCursor;
  5855. end;
  5856. { there is a problem with ShiftDel here
  5857. because GetShitState tells to extend the
  5858. selection which gives wrong results (PM) }
  5859. function TCustomCodeEditor.ShouldExtend: boolean;
  5860. var ShiftInEvent: boolean;
  5861. begin
  5862. ShiftInEvent:=false;
  5863. if Assigned(CurEvent) then
  5864. if CurEvent^.What=evKeyDown then
  5865. ShiftInEvent:=((CurEvent^.KeyShift and kbShift)<>0);
  5866. ShouldExtend:=ShiftInEvent and
  5867. not DontConsiderShiftState;
  5868. end;
  5869. procedure TCustomCodeEditor.SetCurPtr(X,Y: sw_integer);
  5870. var OldPos{,OldSEnd,OldSStart}: TPoint;
  5871. Extended: boolean;
  5872. F: PFold;
  5873. begin
  5874. Lock;
  5875. X:=Max(0,Min(MaxLineLength+1,X));
  5876. Y:=Max(0,Min(GetLineCount-1,Y));
  5877. OldPos:=CurPos;
  5878. { OldSEnd:=SelEnd;
  5879. OldSStart:=SelStart;}
  5880. CurPos.X:=X;
  5881. CurPos.Y:=Y;
  5882. TrackCursor(false);
  5883. if not IsLineVisible(CurPos.Y) then
  5884. begin
  5885. F:=GetLineFold(CurPos.Y);
  5886. if Assigned(F) then
  5887. F^.Collapse(false);
  5888. end;
  5889. if (NoSelect=false) and (ShouldExtend) then
  5890. begin
  5891. CheckSels;
  5892. Extended:=false;
  5893. if PointOfs(OldPos)=PointOfs(SelStart) then
  5894. begin SetSelection(CurPos,SelEnd); Extended:=true; end;
  5895. CheckSels;
  5896. if Extended=false then
  5897. if PointOfs(OldPos)=PointOfs(SelEnd) then
  5898. begin
  5899. if ValidBlock=false then
  5900. SetSelection(CurPos,CurPos);
  5901. SetSelection(SelStart,CurPos); Extended:=true;
  5902. end;
  5903. CheckSels;
  5904. if (Extended=false) then
  5905. if PointOfs(OldPos)<=PointOfs(CurPos)
  5906. then begin SetSelection(OldPos,CurPos); Extended:=true; end
  5907. else begin SetSelection(CurPos,OldPos); Extended:=true; end;
  5908. DrawView;
  5909. end else
  5910. if not IsFlagSet(efPersistentBlocks) then
  5911. begin HideSelect; DrawView; end;
  5912. { if PointOfs(SelStart)=PointOfs(SelEnd) then
  5913. SetSelection(CurPos,CurPos);}
  5914. if (GetFlags and (efHighlightColumn+efHighlightRow))<>0 then
  5915. DrawView;
  5916. if ((CurPos.X<>OldPos.X) or (CurPos.Y<>OldPos.Y)) and
  5917. ((Highlight.A.X<>HighLight.B.X) or (Highlight.A.Y<>HighLight.B.Y)) then
  5918. HideHighlight;
  5919. if (OldPos.Y<>CurPos.Y) and (0<=OldPos.Y) and (OldPos.Y<GetLineCount) then
  5920. SetLineText(OldPos.Y,RTrim(GetLineText(OldPos.Y),not IsFlagSet(efUseTabCharacters)));
  5921. if ((CurPos.X<>OldPos.X) or (CurPos.Y<>OldPos.Y)) and (GetErrorMessage<>'') then
  5922. SetErrorMessage('');
  5923. { if ((CurPos.X<>OldPos.X) or (CurPos.Y<>OldPos.Y)) and (HighlightRow<>-1) then
  5924. SetHighlightRow(-1);}
  5925. if ((CurPos.X<>OldPos.X) or (CurPos.Y<>OldPos.Y)) then
  5926. AddAction(eaMoveCursor,OldPos,CurPos,'',GetFlags);
  5927. if ((CurPos.X<>OldPos.X) or (CurPos.Y<>OldPos.Y)) then
  5928. PositionChanged;{UpdateIndicator;}
  5929. UnLock;
  5930. end;
  5931. procedure TCustomCodeEditor.CheckSels;
  5932. begin
  5933. if (SelStart.Y>SelEnd.Y) or
  5934. ( (SelStart.Y=SelEnd.Y) and (SelStart.X>SelEnd.X) ) then
  5935. SetSelection(SelEnd,SelStart);
  5936. end;
  5937. procedure TCustomCodeEditor.CodeCompleteApply;
  5938. var S: string;
  5939. I: integer;
  5940. begin
  5941. Lock;
  5942. { here should be some kind or "mark" or "break" inserted in the Undo
  5943. information, so activating it "undoes" only the completition first and
  5944. doesn't delete the complete word at once... - Gabor }
  5945. S:=GetCodeCompleteFrag;
  5946. SetCurPtr(CurPos.X-length(S),CurPos.Y);
  5947. for I:=1 to length(S) do
  5948. DelChar;
  5949. S:=GetCodeCompleteWord;
  5950. for I:=1 to length(S) do
  5951. AddChar(S[I]);
  5952. UnLock;
  5953. SetCompleteState(csInactive);
  5954. end;
  5955. procedure TCustomCodeEditor.CodeCompleteCancel;
  5956. begin
  5957. SetCompleteState(csDenied);
  5958. end;
  5959. procedure TCustomCodeEditor.CodeCompleteCheck;
  5960. var Line: string;
  5961. X: sw_integer;
  5962. CurWord,NewWord: string;
  5963. begin
  5964. SetCodeCompleteFrag('');
  5965. if (not IsFlagSet(efCodeComplete)) or (IsReadOnly=true) then Exit;
  5966. Lock;
  5967. Line:=GetDisplayText(CurPos.Y);
  5968. X:=CurPos.X; CurWord:='';
  5969. if X<=length(Line) then
  5970. while (X>0) and (Line[X] in (NumberChars+AlphaChars)) do
  5971. begin
  5972. CurWord:=Line[X]+CurWord;
  5973. Dec(X);
  5974. end;
  5975. if (length(CurWord)>=CodeCompleteMinLen) and CompleteCodeWord(CurWord,NewWord) then
  5976. begin
  5977. SetCodeCompleteFrag(CurWord);
  5978. SetCodeCompleteWord(NewWord);
  5979. end
  5980. else
  5981. ClearCodeCompleteWord;
  5982. UnLock;
  5983. end;
  5984. function TCustomCodeEditor.GetCodeCompleteFrag: string;
  5985. begin
  5986. { Abstract }
  5987. GetCodeCompleteFrag:='';
  5988. end;
  5989. procedure TCustomCodeEditor.SetCodeCompleteFrag(const S: string);
  5990. begin
  5991. { Abstract }
  5992. end;
  5993. procedure TCustomCodeEditor.DrawLines(FirstLine: sw_integer);
  5994. begin
  5995. if FirstLine>=(Delta.Y+Size.Y) then Exit; { falls outside of the screen }
  5996. DrawView;
  5997. end;
  5998. procedure TCustomCodeEditor.HideHighlight;
  5999. begin
  6000. SetHighlight(CurPos,CurPos);
  6001. end;
  6002. procedure TCustomCodeEditor.GetSelectionArea(var StartP,EndP: TPoint);
  6003. begin
  6004. StartP:=SelStart; EndP:=SelEnd;
  6005. if EndP.X=0 then
  6006. begin
  6007. Dec(EndP.Y);
  6008. EndP.X:=length(GetDisplayText(EndP.Y))-1;
  6009. end
  6010. else
  6011. Dec(EndP.X);
  6012. end;
  6013. function TCustomCodeEditor.ValidBlock: boolean;
  6014. begin
  6015. ValidBlock:=(SelStart.X<>SelEnd.X) or (SelStart.Y<>SelEnd.Y);
  6016. end;
  6017. procedure TCustomCodeEditor.SetSelection(A, B: TPoint);
  6018. var WV: boolean;
  6019. OS,OE: TPoint;
  6020. begin
  6021. WV:=ValidBlock;
  6022. OS:=SelStart; OE:=SelEnd;
  6023. SelStart:=A; SelEnd:=B;
  6024. if (WV=false) and (ValidBlock=false) then { do nothing } else
  6025. if (OS.X<>SelStart.X) or (OS.Y<>SelStart.Y) or
  6026. (OE.X<>SelEnd.X) or (OE.Y<>SelEnd.Y) then
  6027. SelectionChanged;
  6028. end;
  6029. procedure TCustomCodeEditor.SetHighlight(A, B: TPoint);
  6030. begin
  6031. Highlight.A:=A; Highlight.B:=B;
  6032. HighlightChanged;
  6033. end;
  6034. {procedure TCustomCodeEditor.SetHighlightRow(Row: sw_integer);
  6035. begin
  6036. HighlightRow:=Row;
  6037. DrawView;
  6038. end;}
  6039. {procedure TCodeEditor.SetDebuggerRow(Row: sw_integer);
  6040. begin
  6041. DebuggerRow:=Row;
  6042. DrawView;
  6043. end;}
  6044. procedure TCustomCodeEditor.SelectAll(Enable: boolean);
  6045. var A,B: TPoint;
  6046. begin
  6047. if (Enable=false) or (GetLineCount=0) then
  6048. begin A:=CurPos; B:=CurPos end
  6049. else
  6050. begin
  6051. A.X:=0; A.Y:=0;
  6052. { B.Y:=GetLineCount-1;
  6053. B.X:=length(GetLineText(B.Y));}
  6054. B.Y:=GetLineCount; B.X:=0;
  6055. end;
  6056. SetSelection(A,B);
  6057. DrawView;
  6058. end;
  6059. procedure TCustomCodeEditor.SelectionChanged;
  6060. var Enable,CanPaste: boolean;
  6061. begin
  6062. if GetLineCount=0 then
  6063. begin
  6064. SelStart.X:=0; SelStart.Y:=0; SelEnd:=SelStart;
  6065. end
  6066. else
  6067. if SelEnd.Y>GetLineCount-1 then
  6068. if (SelEnd.Y<>GetLineCount) or (SelEnd.X<>0) then
  6069. begin
  6070. SelEnd.Y:=GetLineCount-1;
  6071. SelEnd.X:=length(GetDisplayText(SelEnd.Y));
  6072. end;
  6073. Enable:=((SelStart.X<>SelEnd.X) or (SelStart.Y<>SelEnd.Y)) and (Clipboard<>nil);
  6074. SetCmdState(ToClipCmds,Enable and (Clipboard<>@Self));
  6075. SetCmdState(NulClipCmds,Enable);
  6076. CanPaste:=(Clipboard<>nil) and ((Clipboard^.SelStart.X<>Clipboard^.SelEnd.X) or
  6077. (Clipboard^.SelStart.Y<>Clipboard^.SelEnd.Y));
  6078. SetCmdState(FromClipCmds,CanPaste and (Clipboard<>@Self));
  6079. {$ifdef WinClipSupported}
  6080. SetCmdState(FromWinClipCmds,GetTextWinClipboardSize>0);
  6081. {$endif WinClipSupported}
  6082. SetCmdState(UndoCmd,(GetUndoActionCount>0));
  6083. SetCmdState(RedoCmd,(GetRedoActionCount>0));
  6084. Message(Application,evBroadcast,cmCommandSetChanged,nil);
  6085. DrawView;
  6086. end;
  6087. procedure TCustomCodeEditor.HighlightChanged;
  6088. begin
  6089. DrawView;
  6090. end;
  6091. procedure TCustomCodeEditor.SetState(AState: Word; Enable: Boolean);
  6092. procedure ShowSBar(SBar: PScrollBar);
  6093. begin
  6094. if Assigned(SBar) and (SBar^.GetState(sfVisible)=false) then
  6095. SBar^.Show;
  6096. end;
  6097. begin
  6098. inherited SetState(AState,Enable);
  6099. if AlwaysShowScrollBars then
  6100. begin
  6101. ShowSBar(HScrollBar);
  6102. ShowSBar(VScrollBar);
  6103. end;
  6104. if (AState and (sfActive+sfSelected+sfFocused))<>0 then
  6105. begin
  6106. SelectionChanged;
  6107. if ((State and sfFocused)=0) and (GetCompleteState=csOffering) then
  6108. ClearCodeCompleteWord;
  6109. end;
  6110. end;
  6111. function TCustomCodeEditor.GetPalette: PPalette;
  6112. const P: string[length(CEditor)] = CEditor;
  6113. begin
  6114. GetPalette:=@P;
  6115. end;
  6116. function TCustomCodeEditorCore.LoadFromStream(Editor: PCustomCodeEditor; Stream: PStream): boolean;
  6117. var S: string;
  6118. AllLinesComplete,LineComplete,hasCR,OK: boolean;
  6119. begin
  6120. DeleteAllLines;
  6121. ChangedLine:=-1;
  6122. AllLinesComplete:=true;
  6123. OK:=(Stream^.Status=stOK);
  6124. if eofstream(Stream) then
  6125. AddLine('')
  6126. else
  6127. begin
  6128. while OK and (eofstream(Stream)=false) and (GetLineCount<MaxLineCount) do
  6129. begin
  6130. ReadlnFromStream(Stream,S,LineComplete,hasCR);
  6131. AllLinesComplete:=AllLinesComplete and LineComplete;
  6132. OK:=OK and (Stream^.Status=stOK);
  6133. if OK then AddLine(S);
  6134. if not LineComplete and (ChangedLine=-1) then
  6135. ChangedLine:=GetLineCount;
  6136. end;
  6137. { Do not remove the final newline if it exists PM }
  6138. if hasCR then
  6139. AddLine('');
  6140. end;
  6141. LimitsChanged;
  6142. if not AllLinesComplete then
  6143. SetModified(true);
  6144. if (GetLineCount=MaxLineCount) and not eofstream(stream) then
  6145. EditorDialog(edTooManyLines,nil);
  6146. LoadFromStream:=OK;
  6147. end;
  6148. function TCustomCodeEditorCore.SaveAreaToStream(Editor: PCustomCodeEditor; Stream: PStream; StartP,EndP: TPoint): boolean;
  6149. var S: string;
  6150. OK: boolean;
  6151. Line: Sw_integer;
  6152. begin
  6153. if EndP.X=0 then
  6154. begin
  6155. if EndP.Y>0 then
  6156. begin
  6157. EndP.X:=length(GetDisplayText(EndP.Y));
  6158. end
  6159. else
  6160. EndP.X:=0;
  6161. end
  6162. else
  6163. Dec(EndP.X);
  6164. OK:=(Stream^.Status=stOK); Line:=StartP.Y;
  6165. while OK and (Line<=EndP.Y) and (Line<GetLineCount) do
  6166. begin
  6167. S:=GetLineText(Line);
  6168. { Remove all traling spaces PM }
  6169. if not Editor^.IsFlagSet(efKeepTrailingSpaces) then
  6170. While (Length(S)>0) and (S[Length(S)]=' ') do
  6171. Dec(S[0]);
  6172. { if FlagSet(efUseTabCharacters) then
  6173. S:=CompressUsingTabs(S,TabSize);
  6174. }
  6175. if Line=EndP.Y then S:=copy(S,1,LinePosToCharIdx(Line,EndP.X));
  6176. if Line=StartP.Y then S:=copy(S,LinePosToCharIdx(Line,StartP.X),High(S));
  6177. Stream^.Write(S[1],length(S));
  6178. if Line<EndP.Y then
  6179. Stream^.Write(EOL[1],length(EOL));
  6180. Inc(Line);
  6181. OK:=OK and (Stream^.Status=stOK);
  6182. end;
  6183. SaveAreaToStream:=OK;
  6184. end;
  6185. constructor TEditorAction.init(act:byte; StartP,EndP:TPoint;Txt:String;AFlags : longint);
  6186. begin
  6187. Action:=act;
  6188. StartPos:=StartP;
  6189. EndPos:=EndP;
  6190. Text:=NewStr(txt);
  6191. ActionCount:=0;
  6192. Flags:=AFlags;
  6193. IsGrouped:=false;
  6194. end;
  6195. constructor TEditorAction.init_group(act:byte);
  6196. begin
  6197. Action:=act;
  6198. ActionCount:=0;
  6199. Flags:=0;
  6200. IsGrouped:=true;
  6201. end;
  6202. function TEditorAction.Is_grouped_action : boolean;
  6203. begin
  6204. Is_grouped_action:=IsGrouped;
  6205. end;
  6206. destructor TEditorAction.done;
  6207. begin
  6208. DisposeStr(Text);
  6209. end;
  6210. function TEditorActionCollection.At(Idx : sw_integer) : PEditorAction;
  6211. begin
  6212. At:=PEditorAction(Inherited At(Idx));
  6213. end;
  6214. procedure TEditorInputLine.HandleEvent(var Event : TEvent);
  6215. var
  6216. s : string;
  6217. i : longint;
  6218. begin
  6219. If (Event.What=evKeyDown) and
  6220. (Event.KeyCode=kbRight) and
  6221. (CurPos = Length(Data^)) and
  6222. Assigned(FindReplaceEditor) then
  6223. Begin
  6224. s:=FindReplaceEditor^.GetDisplayText(FindReplaceEditor^.CurPos.Y);
  6225. s:=Copy(s,FindReplaceEditor^.CurPos.X + 1 -length(Data^),high(s));
  6226. i:=pos(Data^,s);
  6227. if i>0 then
  6228. begin
  6229. s:=Data^+s[i+length(Data^)];
  6230. If not assigned(validator) or
  6231. Validator^.IsValidInput(s,False) then
  6232. Begin
  6233. Event.CharCode:=s[length(s)];
  6234. Event.Scancode:=0;
  6235. Inherited HandleEvent(Event);
  6236. End;
  6237. end;
  6238. End
  6239. else
  6240. Inherited HandleEvent(Event);
  6241. end;
  6242. function CreateFindDialog: PDialog;
  6243. var R,R1,R2: TRect;
  6244. D: PDialog;
  6245. IL1: PEditorInputLine;
  6246. Control : PView;
  6247. CB1: PCheckBoxes;
  6248. RB1,RB2,RB3: PRadioButtons;
  6249. begin
  6250. R.Assign(0,0,56,15);
  6251. New(D, Init(R, dialog_find));
  6252. with D^ do
  6253. begin
  6254. Options:=Options or ofCentered;
  6255. GetExtent(R); R.Grow(-3,-2);
  6256. R1.Copy(R); R1.B.X:=17; R1.B.Y:=R1.A.Y+1;
  6257. R2.Copy(R); R2.B.X:=R2.B.X-3;R2.A.X:=17; R2.B.Y:=R2.A.Y+1;
  6258. New(IL1, Init(R2, FindStrSize));
  6259. IL1^.Data^:=FindStr;
  6260. Insert(IL1);
  6261. Insert(New(PLabel, Init(R1, label_find_texttofind, IL1)));
  6262. R1.Assign(R2.B.X, R2.A.Y, R2.B.X+3, R2.B.Y);
  6263. Control := New(PHistory, Init(R1, IL1, TextFindId));
  6264. Insert(Control);
  6265. R1.Copy(R); Inc(R1.A.Y,2); R1.B.Y:=R1.A.Y+1; R1.B.X:=R1.A.X+(R1.B.X-R1.A.X) div 2-1;
  6266. R2.Copy(R1); R2.Move(0,1);
  6267. R2.B.Y:=R2.A.Y+{$ifdef TEST_REGEXP}3{$else}2{$endif};
  6268. New(CB1, Init(R2,
  6269. NewSItem(label_find_casesensitive,
  6270. NewSItem(label_find_wholewordsonly,
  6271. {$ifdef TEST_REGEXP}
  6272. NewSItem(label_find_useregexp,
  6273. {$endif TEST_REGEXP}
  6274. nil)))){$ifdef TEST_REGEXP}){$endif TEST_REGEXP};
  6275. Insert(CB1);
  6276. Insert(New(PLabel, Init(R1, label_find_options, CB1)));
  6277. R1.Copy(R); Inc(R1.A.Y,2); R1.B.Y:=R1.A.Y+1; R1.A.X:=R1.B.X-(R1.B.X-R1.A.X) div 2+1;
  6278. R2.Copy(R1); R2.Move(0,1); R2.B.Y:=R2.A.Y+2;
  6279. New(RB1, Init(R2,
  6280. NewSItem(label_find_forward,
  6281. NewSItem(label_find_backward,
  6282. nil))));
  6283. Insert(RB1);
  6284. Insert(New(PLabel, Init(R1, label_find_direction, RB1)));
  6285. R1.Copy(R); Inc(R1.A.Y,6); R1.B.Y:=R1.A.Y+1; R1.B.X:=R1.A.X+(R1.B.X-R1.A.X) div 2-1;
  6286. R2.Copy(R1); R2.Move(0,1); R2.B.Y:=R2.A.Y+2;
  6287. New(RB2, Init(R2,
  6288. NewSItem(label_find_global,
  6289. NewSItem(label_find_selectedtext,
  6290. nil))));
  6291. Insert(RB2);
  6292. Insert(New(PLabel, Init(R1, label_find_scope, RB2)));
  6293. R1.Copy(R); Inc(R1.A.Y,6); R1.B.Y:=R1.A.Y+1; R1.A.X:=R1.B.X-(R1.B.X-R1.A.X) div 2+1;
  6294. R2.Copy(R1); R2.Move(0,1); R2.B.Y:=R2.A.Y+2;
  6295. New(RB3, Init(R2,
  6296. NewSItem(label_find_fromcursor,
  6297. NewSItem(label_find_entirescope,
  6298. nil))));
  6299. Insert(RB3);
  6300. Insert(New(PLabel, Init(R1, label_find_origin, RB3)));
  6301. GetExtent(R); R.Grow(-13,-1); R.A.Y:=R.B.Y-2; R.B.X:=R.A.X+10;
  6302. Insert(New(PButton, Init(R, btn_OK, cmOK, bfDefault)));
  6303. R.Move(19,0);
  6304. Insert(New(PButton, Init(R, btn_Cancel, cmCancel, bfNormal)));
  6305. end;
  6306. IL1^.Select;
  6307. CreateFindDialog := D;
  6308. end;
  6309. function CreateReplaceDialog: PDialog;
  6310. var R,R1,R2: TRect;
  6311. D: PDialog;
  6312. Control : PView;
  6313. IL1,IL2: PInputLine;
  6314. CB1: PCheckBoxes;
  6315. RB1,RB2,RB3: PRadioButtons;
  6316. begin
  6317. R.Assign(0,0,56,18);
  6318. New(D, Init(R, dialog_replace));
  6319. with D^ do
  6320. begin
  6321. Options:=Options or ofCentered;
  6322. GetExtent(R); R.Grow(-3,-2);
  6323. R1.Copy(R); R1.B.X:=17; R1.B.Y:=R1.A.Y+1;
  6324. R2.Copy(R); R2.B.X:=R2.B.X-3;R2.A.X:=17; R2.B.Y:=R2.A.Y+1;
  6325. New(IL1, Init(R2, FindStrSize));
  6326. IL1^.Data^:=FindStr;
  6327. Insert(IL1);
  6328. Insert(New(PLabel, Init(R1, label_replace_texttofind, IL1)));
  6329. R1.Assign(R2.B.X, R2.A.Y, R2.B.X+3, R2.B.Y);
  6330. Control := New(PHistory, Init(R1, IL1, TextFindId));
  6331. Insert(Control);
  6332. R1.Copy(R); R1.Move(0,2); R1.B.X:=17; R1.B.Y:=R1.A.Y+1;
  6333. R2.Copy(R); R2.Move(0,2);R2.B.X:=R2.B.X-3;
  6334. R2.A.X:=17; R2.B.Y:=R2.A.Y+1;
  6335. New(IL2, Init(R2, FindStrSize));
  6336. IL2^.Data^:=ReplaceStr;
  6337. Insert(IL2);
  6338. Insert(New(PLabel, Init(R1, label_replace_newtext, IL2)));
  6339. R1.Assign(R2.B.X, R2.A.Y, R2.B.X+3, R2.B.Y);
  6340. Control := New(PHistory, Init(R1, IL2, TextReplaceId));
  6341. Insert(Control);
  6342. R1.Copy(R); Inc(R1.A.Y,4); R1.B.Y:=R1.A.Y+1; R1.B.X:=R1.A.X+(R1.B.X-R1.A.X) div 2-1;
  6343. R2.Copy(R1); R2.Move(0,1);
  6344. R2.B.Y:=R2.A.Y+{$ifdef TEST_REGEXP}4{$else}3{$endif};
  6345. New(CB1, Init(R2,
  6346. NewSItem(label_replace_casesensitive,
  6347. NewSItem(label_replace_wholewordsonly,
  6348. NewSItem(label_replace_promptonreplace,
  6349. {$ifdef TEST_REGEXP}
  6350. NewSItem(label_find_useregexp,
  6351. {$endif TEST_REGEXP}
  6352. nil))))){$ifdef TEST_REGEXP}){$endif TEST_REGEXP};
  6353. Insert(CB1);
  6354. Insert(New(PLabel, Init(R1, label_replace_options, CB1)));
  6355. R1.Copy(R); Inc(R1.A.Y,4); R1.B.Y:=R1.A.Y+1; R1.A.X:=R1.B.X-(R1.B.X-R1.A.X) div 2+1;
  6356. R2.Copy(R1); R2.Move(0,1); R2.B.Y:=R2.A.Y+2;
  6357. New(RB1, Init(R2,
  6358. NewSItem(label_replace_forward,
  6359. NewSItem(label_replace_backward,
  6360. nil))));
  6361. Insert(RB1);
  6362. Insert(New(PLabel, Init(R1, label_replace_direction, RB1)));
  6363. R1.Copy(R); Inc(R1.A.Y,9); R1.B.Y:=R1.A.Y+1; R1.B.X:=R1.A.X+(R1.B.X-R1.A.X) div 2-1;
  6364. R2.Copy(R1); R2.Move(0,1); R2.B.Y:=R2.A.Y+2;
  6365. New(RB2, Init(R2,
  6366. NewSItem(label_replace_global,
  6367. NewSItem(label_replace_selectedtext,
  6368. nil))));
  6369. Insert(RB2);
  6370. Insert(New(PLabel, Init(R1, label_replace_scope, RB2)));
  6371. R1.Copy(R); Inc(R1.A.Y,9); R1.B.Y:=R1.A.Y+1; R1.A.X:=R1.B.X-(R1.B.X-R1.A.X) div 2+1;
  6372. R2.Copy(R1); R2.Move(0,1); R2.B.Y:=R2.A.Y+2;
  6373. New(RB3, Init(R2,
  6374. NewSItem(label_replace_fromcursor,
  6375. NewSItem(label_replace_entirescope,
  6376. nil))));
  6377. Insert(RB3);
  6378. Insert(New(PLabel, Init(R1, label_replace_origin, RB3)));
  6379. GetExtent(R); R.Grow(-13,-1); R.A.Y:=R.B.Y-2; R.B.X:=R.A.X+10; R.Move(-10,0);
  6380. Insert(New(PButton, Init(R, btn_OK, cmOK, bfDefault)));
  6381. R.Move(11,0); R.B.X:=R.A.X+14;
  6382. Insert(New(PButton, Init(R, btn_replace_changeall, cmYes, bfNormal)));
  6383. R.Move(15,0); R.B.X:=R.A.X+10;
  6384. Insert(New(PButton, Init(R, btn_Cancel, cmCancel, bfNormal)));
  6385. end;
  6386. IL1^.Select;
  6387. CreateReplaceDialog := D;
  6388. end;
  6389. function CreateGotoLineDialog(Info: pointer): PDialog;
  6390. var D: PDialog;
  6391. R,R1,R2: TRect;
  6392. Control : PView;
  6393. IL: PInputLine;
  6394. begin
  6395. R.Assign(0,0,40,7);
  6396. New(D, Init(R, dialog_gotoline));
  6397. with D^ do
  6398. begin
  6399. Options:=Options or ofCentered;
  6400. GetExtent(R); R.Grow(-3,-2); R.B.Y:=R.A.Y+1;
  6401. R1.Copy(R); R1.B.X:=27; R2.Copy(R);
  6402. R2.B.X:=R2.B.X-3;R2.A.X:=27;
  6403. New(IL, Init(R2,5));
  6404. with TGotoLineDialogRec(Info^) do
  6405. IL^.SetValidator(New(PRangeValidator, Init(1, Lines)));
  6406. Insert(IL);
  6407. Insert(New(PLabel, Init(R1, label_gotoline_linenumber, IL)));
  6408. R1.Assign(R2.B.X, R2.A.Y, R2.B.X+3, R2.B.Y);
  6409. Control := New(PHistory, Init(R1, IL, GotoId));
  6410. Insert(Control);
  6411. GetExtent(R); R.Grow(-8,-1); R.A.Y:=R.B.Y-2; R.B.X:=R.A.X+10;
  6412. Insert(New(PButton, Init(R, btn_OK, cmOK, bfDefault)));
  6413. R.Move(15,0);
  6414. Insert(New(PButton, Init(R, btn_Cancel, cmCancel, bfNormal)));
  6415. end;
  6416. IL^.Select;
  6417. CreateGotoLineDialog:=D;
  6418. end;
  6419. function StdEditorDialog(Dialog: Integer; Info: Pointer): Word;
  6420. var
  6421. R: TRect;
  6422. T: TPoint;
  6423. Re: word;
  6424. Name: string;
  6425. DriveNumber : byte;
  6426. StoreDir,StoreDir2 : DirStr;
  6427. Title,DefExt: string;
  6428. AskOW: boolean;
  6429. begin
  6430. case Dialog of
  6431. edOutOfMemory:
  6432. StdEditorDialog := AdvMessageBox(msg_notenoughmemoryforthisoperation,
  6433. nil, mfInsertInApp+ mfError + mfOkButton);
  6434. edReadError:
  6435. StdEditorDialog := AdvMessageBox(msg_errorreadingfile,
  6436. @Info, mfInsertInApp+ mfError + mfOkButton);
  6437. edWriteError:
  6438. StdEditorDialog := AdvMessageBox(msg_errorwritingfile,
  6439. @Info, mfInsertInApp+ mfError + mfOkButton);
  6440. edSaveError:
  6441. StdEditorDialog := AdvMessageBox(msg_errorsavingfile,
  6442. @Info, mfInsertInApp+ mfError + mfOkButton);
  6443. edCreateError:
  6444. StdEditorDialog := AdvMessageBox(msg_errorcreatingfile,
  6445. @Info, mfInsertInApp+ mfError + mfOkButton);
  6446. edSaveModify:
  6447. StdEditorDialog := AdvMessageBox(msg_filehasbeenmodifiedsave,
  6448. @Info, mfInsertInApp+ mfInformation + mfYesNoCancel);
  6449. edSaveUntitled:
  6450. StdEditorDialog := AdvMessageBox(msg_saveuntitledfile,
  6451. nil, mfInsertInApp+ mfInformation + mfYesNoCancel);
  6452. edChangedOnloading:
  6453. StdEditorDialog := AdvMessageBox(msg_filehadtoolonglines,
  6454. Info, mfInsertInApp+ mfOKButton + mfInformation);
  6455. edFileOnDiskChanged:
  6456. StdEditorDialog := AdvMessageBox(msg_filewasmodified,
  6457. @info, mfInsertInApp+ mfInformation + mfYesNoCancel);
  6458. edReloadDiskmodifiedFile:
  6459. StdEditorDialog := AdvMessageBox(msg_reloaddiskmodifiedfile,
  6460. @info, mfInsertInApp+ mfInformation + mfYesNoCancel);
  6461. edReloadDiskAndIDEModifiedFile:
  6462. StdEditorDialog := AdvMessageBox(msg_reloaddiskandidemodifiedfile,
  6463. @info, mfInsertInApp+ mfInformation + mfYesNoCancel);
  6464. edSaveAs,edWriteBlock,edReadBlock:
  6465. begin
  6466. Name:=PString(Info)^;
  6467. GetDir(0,StoreDir);
  6468. DriveNumber:=0;
  6469. if (Length(FileDir)>1) and (FileDir[2]=':') then
  6470. begin
  6471. { does not assume that lowercase are greater then uppercase ! }
  6472. if (FileDir[1]>='a') and (FileDir[1]<='z') then
  6473. DriveNumber:=Ord(FileDir[1])-ord('a')+1
  6474. else
  6475. DriveNumber:=Ord(FileDir[1])-ord('A')+1;
  6476. GetDir(DriveNumber,StoreDir2);
  6477. {$ifndef FPC}
  6478. ChDir(Copy(FileDir,1,2));
  6479. { this sets InOutRes in win32 PM }
  6480. { is this bad? What about an EatIO? Gabor }
  6481. {$endif not FPC}
  6482. end;
  6483. if FileDir<>'' then
  6484. ChDir(TrimEndSlash(FileDir));
  6485. case Dialog of
  6486. edSaveAs :
  6487. begin
  6488. Title:=dialog_savefileas;
  6489. DefExt:='*'+DefaultSaveExt;
  6490. end;
  6491. edWriteBlock :
  6492. begin
  6493. Title:=dialog_writeblocktofile;
  6494. DefExt:='*.*';
  6495. end;
  6496. edReadBlock :
  6497. begin
  6498. Title:=dialog_readblockfromfile;
  6499. DefExt:='*.*';
  6500. end;
  6501. else begin Title:='???'; DefExt:=''; end;
  6502. end;
  6503. Re:=Application^.ExecuteDialog(New(PFileDialog, Init(DefExt,
  6504. Title, label_name, fdOkButton, FileId)), @Name);
  6505. case Dialog of
  6506. edSaveAs :
  6507. begin
  6508. if ExtOf(Name)='' then
  6509. Name:=Name+DefaultSaveExt;
  6510. AskOW:=(Name<>PString(Info)^);
  6511. end;
  6512. edWriteBlock :
  6513. begin
  6514. if ExtOf(Name)='' then
  6515. Name:=Name+DefaultSaveExt;
  6516. AskOW:=true;
  6517. end;
  6518. edReadBlock : AskOW:=false;
  6519. else AskOW:=true;
  6520. end;
  6521. if (Re<>cmCancel) and AskOW then
  6522. begin
  6523. FileDir:=DirOf(FExpand(Name));
  6524. if ExistsFile(Name) then
  6525. if EditorDialog(edReplaceFile,@Name)<>cmYes then
  6526. Re:=cmCancel;
  6527. end;
  6528. if DriveNumber<>0 then
  6529. ChDir(StoreDir2);
  6530. {$ifndef FPC}
  6531. if (Length(StoreDir)>1) and (StoreDir[2]=':') then
  6532. ChDir(Copy(StoreDir,1,2));
  6533. {$endif not FPC}
  6534. if StoreDir<>'' then
  6535. ChDir(TrimEndSlash(StoreDir));
  6536. if Re<>cmCancel then
  6537. PString(Info)^:=Name;
  6538. StdEditorDialog := Re;
  6539. end;
  6540. edGotoLine:
  6541. StdEditorDialog :=
  6542. Application^.ExecuteDialog(CreateGotoLineDialog(Info), Info);
  6543. edFind:
  6544. StdEditorDialog :=
  6545. Application^.ExecuteDialog(CreateFindDialog, Info);
  6546. edSearchFailed:
  6547. StdEditorDialog := AdvMessageBox(msg_searchstringnotfound,
  6548. nil, mfInsertInApp+ mfError + mfOkButton);
  6549. edReplace:
  6550. StdEditorDialog :=
  6551. Application^.ExecuteDialog(CreateReplaceDialog, Info);
  6552. edReplacePrompt:
  6553. begin
  6554. { Avoid placing the dialog on the same line as the cursor }
  6555. R.Assign(0, 1, 40, 8);
  6556. R.Move((Desktop^.Size.X - R.B.X) div 2, 0);
  6557. Desktop^.MakeGlobal(R.B, T);
  6558. Inc(T.Y);
  6559. if PPoint(Info)^.Y <= T.Y then
  6560. R.Move(0, Desktop^.Size.Y - R.B.Y - 2);
  6561. StdEditorDialog := AdvMessageBoxRect(R, msg_replacethisoccourence,
  6562. nil, mfInsertInApp+ mfYesNoCancel + mfInformation);
  6563. end;
  6564. edReplaceFile :
  6565. StdEditorDialog :=
  6566. AdvMessageBox(msg_fileexistsoverwrite,@Info,mfInsertInApp+mfConfirmation+
  6567. mfYesButton+mfNoButton);
  6568. end;
  6569. end;
  6570. procedure RegisterWEditor;
  6571. begin
  6572. {$ifndef NOOBJREG}
  6573. {$endif}
  6574. end;
  6575. END.
  6576. {
  6577. $Log$
  6578. Revision 1.22 2002-06-13 14:50:35 pierre
  6579. * try to improove tabs handling in DelChar and InsertLine methods
  6580. Revision 1.21 2002/06/06 07:04:00 pierre
  6581. * use inherited ResetCursor for fvision lib
  6582. Revision 1.20 2002/05/31 12:33:49 pierre
  6583. * fix fvision dialog problem due to DataSize differences
  6584. Revision 1.19 2002/05/30 22:01:12 pierre
  6585. * fix ResetCursor for fvision
  6586. Revision 1.18 2002/04/16 08:27:01 pierre
  6587. * fix for bug report 1869
  6588. Revision 1.17 2002/01/25 14:15:35 pierre
  6589. * fix bug 1774
  6590. Revision 1.16 2001/11/07 00:18:00 pierre
  6591. * avoid problem to compile ide with debug for linux
  6592. Revision 1.15 2001/10/02 22:43:22 pierre
  6593. * correct last commit, FVISION conditional means the new fvision dir instead of fvnew
  6594. Revision 1.14 2001/10/02 16:35:04 pierre
  6595. * get correct curosr position for fvision
  6596. Revision 1.13 2001/10/01 09:08:21 pierre
  6597. * fix hexadecimal number highlighting
  6598. Revision 1.12 2001/09/27 16:30:16 pierre
  6599. * fix Hexadecimal number highlighting
  6600. Revision 1.11 2001/09/25 22:45:09 pierre
  6601. * fix recognition of directives broken by last patch
  6602. Revision 1.10 2001/09/25 11:59:20 pierre
  6603. * fix comment highlight bugs from bug 1617
  6604. Revision 1.9 2001/09/17 22:54:09 pierre
  6605. + Line completion for Find/Replace dialogs
  6606. Revision 1.8 2001/09/17 21:30:26 pierre
  6607. * fix a bug in Find/Replace dialog about RegExp
  6608. Revision 1.7 2001/09/14 23:47:09 pierre
  6609. + more regexp, options now in Find/Replace dialogs
  6610. Revision 1.6 2001/09/13 16:11:34 pierre
  6611. + test code for regexpr use in find dialog
  6612. Revision 1.5 2001/09/12 09:31:42 pierre
  6613. * fix bug 1579
  6614. Revision 1.4 2001/09/04 22:58:58 pierre
  6615. * fix highlight for 'i:=1to'
  6616. Revision 1.3 2001/08/12 00:06:49 pierre
  6617. * better clipboard handling for files with tabs
  6618. Revision 1.2 2001/08/05 02:01:48 peter
  6619. * FVISION define to compile with fvision units
  6620. Revision 1.1 2001/08/04 11:30:25 peter
  6621. * ide works now with both compiler versions
  6622. Revision 1.1.2.37 2001/08/03 11:43:58 pierre
  6623. * Show Find Dialog if Ctrl-L is pressed but FindStr is empty
  6624. Revision 1.1.2.36 2001/06/07 16:41:13 jonas
  6625. * updated for stricter checking of @ for procvars
  6626. Revision 1.1.2.35 2001/05/09 15:39:42 pierre
  6627. * fix a problem for shortened files
  6628. Revision 1.1.2.34 2001/04/03 23:27:12 pierre
  6629. * make Ctrl-T BP compatible
  6630. Revision 1.1.2.33 2001/03/20 00:20:43 pierre
  6631. * fix some memory leaks + several small enhancements
  6632. Revision 1.1.2.32 2001/03/13 16:19:16 pierre
  6633. + syntax highligh in disassembly window
  6634. Revision 1.1.2.31 2001/03/12 17:34:57 pierre
  6635. + Disassembly window started
  6636. Revision 1.1.2.30 2001/03/06 22:04:53 pierre
  6637. * Avoid cursor updates when editor window is locked
  6638. Revision 1.1.2.29 2001/02/19 10:40:52 pierre
  6639. * Check for changed files after Running tool or shell
  6640. Revision 1.1.2.28 2001/02/05 12:58:26 pierre
  6641. * fix several Undo bugs
  6642. Revision 1.1.2.27 2001/01/14 22:11:23 peter
  6643. * fixed missing unlock that broke the helpwindow after compiling
  6644. a program
  6645. Revision 1.1.2.26 2001/01/07 22:33:20 peter
  6646. * fixed search in empty editor
  6647. Revision 1.1.2.25 2000/12/30 22:48:57 peter
  6648. * fixed delete and backspace with tabs, but tabsupport is still
  6649. not correct in other places
  6650. Revision 1.1.2.24 2000/12/14 08:37:51 pierre
  6651. * avoid unnecessary int64 calculation
  6652. Revision 1.1.2.23 2000/11/29 18:28:53 pierre
  6653. + add save to file capability for list boxes
  6654. Revision 1.1.2.22 2000/11/27 12:06:50 pierre
  6655. New bunch of Gabor fixes
  6656. Revision 1.1.2.21 2000/11/23 16:32:16 pierre
  6657. * avoid flickering for GotoLine
  6658. Revision 1.1.2.20 2000/11/22 17:13:00 pierre
  6659. * bug in DelToEndOfWord fixed
  6660. Revision 1.1.2.19 2000/11/22 16:09:43 pierre
  6661. * Ctrl-T now deletes from cursor to end of word
  6662. Revision 1.1.2.18 2000/11/21 16:10:41 pierre
  6663. * avoid selection extension for JumpMark
  6664. Revision 1.1.2.17 2000/11/14 23:41:32 pierre
  6665. * fix for bug 1234
  6666. Revision 1.1.2.16 2000/11/14 09:08:50 marco
  6667. * First batch IDE renamefest
  6668. Revision 1.1.2.15 2000/11/13 16:55:09 pierre
  6669. * multi space indent disabled
  6670. Revision 1.1.2.14 2000/11/06 17:19:58 pierre
  6671. * avoid eating of last carriage return
  6672. Revision 1.1.2.13 2000/11/03 15:49:26 pierre
  6673. * more Undo fixes
  6674. Revision 1.1.2.12 2000/11/03 13:31:33 pierre
  6675. + more Undo stuff and smarter indent/unindent
  6676. Revision 1.1.2.11 2000/10/31 08:12:45 pierre
  6677. * fix for bug 1161
  6678. Revision 1.1.2.10 2000/10/31 07:50:02 pierre
  6679. + efNoIndent to avoid any indentation
  6680. Revision 1.1.2.9 2000/10/26 00:02:40 pierre
  6681. * Undo improovments
  6682. Revision 1.1.2.8 2000/10/24 23:06:30 pierre
  6683. * some Undo/redo fixes
  6684. Revision 1.1.2.7 2000/10/20 13:40:34 pierre
  6685. * avoid crash if paste win clipboard on empty editor
  6686. Revision 1.1.2.6 2000/09/19 19:54:09 pierre
  6687. * fix for bug 1141 by Gabor
  6688. Revision 1.1.2.5 2000/09/18 13:20:55 pierre
  6689. New bunch of Gabor changes
  6690. Revision 1.1.2.4 2000/08/15 03:40:54 peter
  6691. [*] no more fatal exits when the IDE can't find the error file (containing
  6692. the redirected assembler/linker output) after compilation
  6693. [*] hidden windows are now added always at the end of the Window List
  6694. [*] TINIFile parsed entries encapsulated in string delimiters incorrectly
  6695. [*] selection was incorrectly adjusted when typing in overwrite mode
  6696. [*] the line wasn't expanded when it's end was reached in overw. mode
  6697. [*] the IDE now tries to locate source files also in the user specified
  6698. unit dirs (for ex. as a response to 'Open at cursor' (Ctrl+Enter) )
  6699. [*] 'Open at cursor' is now aware of the extension (if specified)
  6700. Revision 1.1.2.3 2000/07/20 11:02:16 michael
  6701. + Fixes from gabor. See fixes.txt
  6702. Revision 1.1.2.2 2000/07/18 05:50:22 michael
  6703. + Merged Gabors fixes
  6704. Revision 1.1.2.1 2000/07/15 21:30:06 pierre
  6705. * Do not consider ASM inside a string as a assembler statement start
  6706. * Add .pas extension to edWriteBlock if no extension is choosen
  6707. Revision 1.1 2000/07/13 09:48:37 michael
  6708. + Initial import
  6709. Revision 1.95 2000/06/22 09:07:13 pierre
  6710. * Gabor changes: see fixes.txt
  6711. Revision 1.94 2000/06/16 21:17:39 pierre
  6712. + TCustoCodeEditorCore.GetChangedLine
  6713. Revision 1.93 2000/06/16 08:50:43 pierre
  6714. + new bunch of Gabor's changes
  6715. Revision 1.92 2000/06/15 20:29:45 pierre
  6716. * avoid RTE 211 on Ctrl K W
  6717. Revision 1.91 2000/05/29 10:44:58 pierre
  6718. + New bunch of Gabor's changes: see fixes.txt
  6719. Revision 1.90 2000/05/17 11:58:26 pierre
  6720. * remove openbrace because of multiple comment level problem
  6721. Revision 1.89 2000/05/17 09:44:46 pierre
  6722. * fix the $ifdef inside a comment problem
  6723. Revision 1.88 2000/04/25 08:42:34 pierre
  6724. * New Gabor changes : see fixes.txt
  6725. Revision 1.87 2000/04/18 11:42:38 pierre
  6726. lot of Gabor changes : see fixes.txt
  6727. Revision 1.86 2000/03/23 21:36:19 pierre
  6728. * get correct position in indicator again
  6729. Revision 1.85 2000/03/21 23:17:47 pierre
  6730. + Gabor patch to add support for multiple windows
  6731. of same file
  6732. weditor has been splitted into weditor and wcedit units
  6733. Revision 1.84 2000/03/20 19:19:44 pierre
  6734. * LFN support in streams
  6735. Revision 1.83 2000/03/14 13:38:03 pierre
  6736. * max number of line changed and warning added
  6737. Revision 1.82 2000/03/02 22:33:36 pierre
  6738. * Grep improoved
  6739. Revision 1.81 2000/02/09 12:56:54 pierre
  6740. * fix for DelChar past end of line
  6741. Revision 1.80 2000/02/07 12:11:15 pierre
  6742. Gabors changes
  6743. Revision 1.79 2000/02/05 14:50:59 florian
  6744. * applied fix from Gabor regarding the limited line length of the clipboard
  6745. Revision 1.78 2000/01/28 22:20:04 pierre
  6746. * Test_partial_syntax released
  6747. Revision 1.77 2000/01/27 22:30:38 florian
  6748. * start of FPU window
  6749. * current executed line color has a higher priority then a breakpoint now
  6750. Revision 1.76 2000/01/25 00:12:23 pierre
  6751. * fix for Backspace Undo
  6752. Revision 1.75 2000/01/14 15:36:42 pierre
  6753. + GetShortFileName used for tcodeeditor file opening
  6754. Revision 1.74 2000/01/10 23:20:04 pierre
  6755. * problem with Paste solved
  6756. Revision 1.73 2000/01/10 13:25:46 pierre
  6757. + first partial syntax test
  6758. Revision 1.72 2000/01/07 00:19:30 pierre
  6759. * forgot CommentLineType check to see if we need to update format
  6760. on next line
  6761. * some changes for TEST_PARTIAL_SYNTAX still does notwork :(
  6762. Revision 1.71 2000/01/06 17:47:26 pierre
  6763. * avoid to resyntax whole source in unnecessary cases
  6764. Revision 1.70 2000/01/05 17:35:50 pierre
  6765. + Warning box if a line is cut at reading of file
  6766. this is done to avoid loosing completely long lines
  6767. * several TAB related changes
  6768. in particular do not remove or recombine TABs in makefiles
  6769. * fixes for ^KR and ^KW (the was an extra LF at end of
  6770. written block of disk and an error for starting X position
  6771. in SaveAreaToStream)
  6772. Revision 1.69 2000/01/05 00:37:34 pierre
  6773. * ^KC fix
  6774. * better Tab handling
  6775. Revision 1.68 2000/01/04 12:33:08 pierre
  6776. * reinserted version 1.66 lost changes
  6777. + CtrlT Undo works now !
  6778. Revision 1.67 2000/01/03 11:38:35 michael
  6779. Changes from Gabor
  6780. Revision 1.65 1999/12/08 16:02:46 pierre
  6781. * fix for bugs 746,748 and 750
  6782. Revision 1.64 1999/12/01 17:25:00 pierre
  6783. + check if file on disk was changed since load before overwriting
  6784. Revision 1.63 1999/11/22 17:34:08 pierre
  6785. * fix for form bug 634
  6786. Revision 1.62 1999/11/18 13:42:06 pierre
  6787. * Some more Undo stuff
  6788. Revision 1.61 1999/11/10 00:45:30 pierre
  6789. + groupd action started, not yet working
  6790. Revision 1.60 1999/11/05 13:49:13 pierre
  6791. * WinPaste depends on avalaible Clipboard data
  6792. Revision 1.59 1999/11/03 09:39:23 peter
  6793. * fixed uppercase filenames
  6794. * savetostream did twice a -1 on the linecount, so the lastline of a
  6795. file wasn't saved correctly
  6796. Revision 1.58 1999/10/28 15:14:22 pierre
  6797. * get it to compile with debug conditional
  6798. Revision 1.56 1999/10/27 13:32:58 pierre
  6799. * some more Undo Fixes
  6800. Revision 1.55 1999/10/27 10:46:19 pierre
  6801. * More Undo/Redo stuff
  6802. Revision 1.54 1999/10/25 16:49:05 pierre
  6803. + Undo/Redo by Visa Harvey (great thanks) inserted
  6804. (with some modifications)
  6805. Moves work correctly
  6806. Text insertion/deletion are still buggy !
  6807. * LinePosToCharIndex and reverse function changed to get more
  6808. sensible results, dependant code adapted
  6809. * several bug fixes
  6810. Revision 1.53 1999/10/14 10:21:48 pierre
  6811. * more tabs related problems fiwes
  6812. Revision 1.52 1999/10/12 23:35:18 pierre
  6813. + DelStart and SelectWord implemented
  6814. * AddChar(tab) now reacts correctly if efAutoIndent is set
  6815. Revision 1.51 1999/10/08 15:24:50 pierre
  6816. * InsertFrom bug (end of line wasdiscarded)
  6817. Revision 1.50 1999/09/28 23:44:13 pierre
  6818. * text insertion in middle of line was buggy
  6819. Revision 1.49 1999/09/23 16:33:30 pierre
  6820. * ^B^A now prints out the ascii 1 char
  6821. * In SearchReplace Several occurence of a pattern in the same line
  6822. should now be found correctly
  6823. Revision 1.48 1999/09/22 16:16:26 pierre
  6824. + added HistLists for several dialogs
  6825. Revision 1.47 1999/09/21 17:08:59 pierre
  6826. + Windows clipboard for win32
  6827. Revision 1.46 1999/09/13 16:24:44 peter
  6828. + clock
  6829. * backspace unident like tp7
  6830. Revision 1.45 1999/09/09 12:05:33 pierre
  6831. + Copy/Paste to Windows Clipboard
  6832. + efLeaveTrailingSpaces added to editor flags
  6833. (if not set then spaces at the end of a line are
  6834. removed on writing the file)
  6835. Revision 1.44 1999/08/27 15:07:44 pierre
  6836. + cmResetDebuggerRow
  6837. Revision 1.43 1999/08/24 22:04:35 pierre
  6838. + TCodeEditor.SetDebuggerRow
  6839. works like SetHighlightRow but is only disposed by a SetDebuggerRow(-1)
  6840. so the current stop point in debugging is not lost if
  6841. we move the cursor
  6842. Revision 1.42 1999/08/22 22:20:30 pierre
  6843. * selection extension bug removed, via oldEvent pointer in TCodeEditor.HandleEvent
  6844. Revision 1.41 1999/08/16 18:25:28 peter
  6845. * Adjusting the selection when the editor didn't contain any line.
  6846. * Reserved word recognition redesigned, but this didn't affect the overall
  6847. syntax highlight speed remarkably (at least not on my Amd-K6/350).
  6848. The syntax scanner loop is a bit slow but the main problem is the
  6849. recognition of special symbols. Switching off symbol processing boosts
  6850. the performance up to ca. 200%...
  6851. * The editor didn't allow copying (for ex to clipboard) of a single character
  6852. * 'File|Save as' caused permanently run-time error 3. Not any more now...
  6853. * Compiler Messages window (actually the whole desktop) did not act on any
  6854. keypress when compilation failed and thus the window remained visible
  6855. + Message windows are now closed upon pressing Esc
  6856. + At 'Run' the IDE checks whether any sources are modified, and recompiles
  6857. only when neccessary
  6858. + BlockRead and BlockWrite (Ctrl+K+R/W) implemented in TCodeEditor
  6859. + LineSelect (Ctrl+K+L) implemented
  6860. * The IDE had problems closing help windows before saving the desktop
  6861. Revision 1.40 1999/08/03 20:22:42 peter
  6862. + TTab acts now on Ctrl+Tab and Ctrl+Shift+Tab...
  6863. + Desktop saving should work now
  6864. - History saved
  6865. - Clipboard content saved
  6866. - Desktop saved
  6867. - Symbol info saved
  6868. * syntax-highlight bug fixed, which compared special keywords case sensitive
  6869. (for ex. 'asm' caused asm-highlighting, while 'ASM' didn't)
  6870. * with 'whole words only' set, the editor didn't found occourences of the
  6871. searched text, if the text appeared previously in the same line, but didn't
  6872. satisfied the 'whole-word' condition
  6873. * ^QB jumped to (SelStart.X,SelEnd.X) instead of (SelStart.X,SelStart.Y)
  6874. (ie. the beginning of the selection)
  6875. * when started typing in a new line, but not at the start (X=0) of it,
  6876. the editor inserted the text one character more to left as it should...
  6877. * TCodeEditor.HideSelection (Ctrl-K+H) didn't update the screen
  6878. * Shift shouldn't cause so much trouble in TCodeEditor now...
  6879. * Syntax highlight had problems recognizing a special symbol if it was
  6880. prefixed by another symbol character in the source text
  6881. * Auto-save also occours at Dos shell, Tool execution, etc. now...
  6882. Revision 1.39 1999/07/28 23:11:26 peter
  6883. * fixes from gabor
  6884. Revision 1.38 1999/07/12 13:14:24 pierre
  6885. * LineEnd bug corrected, now goes end of text even if selected
  6886. + Until Return for debugger
  6887. + Code for Quit inside GDB Window
  6888. Revision 1.37 1999/06/29 22:50:16 peter
  6889. * more fixes from gabor
  6890. Revision 1.36 1999/06/29 08:51:34 pierre
  6891. * lockflag problems fixed
  6892. Revision 1.35 1999/06/28 19:32:32 peter
  6893. * fixes from gabor
  6894. Revision 1.34 1999/06/28 15:58:07 pierre
  6895. * ShiftDel problem solved
  6896. Revision 1.33 1999/06/25 00:31:51 pierre
  6897. + FileDir remembers the last directory for Open and Save
  6898. Revision 1.32 1999/06/21 23:36:12 pierre
  6899. * Size for Cluster is word (TP compatibility)
  6900. Revision 1.31 1999/05/22 13:44:35 peter
  6901. * fixed couple of bugs
  6902. Revision 1.30 1999/04/15 08:58:10 peter
  6903. * syntax highlight fixes
  6904. * browser updates
  6905. Revision 1.29 1999/04/07 21:55:59 peter
  6906. + object support for browser
  6907. * html help fixes
  6908. * more desktop saving things
  6909. * NODEBUG directive to exclude debugger
  6910. Revision 1.28 1999/03/23 15:11:39 peter
  6911. * desktop saving things
  6912. * vesa mode
  6913. * preferences dialog
  6914. Revision 1.27 1999/03/08 14:58:17 peter
  6915. + prompt with dialogs for tools
  6916. Revision 1.26 1999/03/07 22:58:57 pierre
  6917. * FindRec needs longint for CheckBoxes
  6918. Revision 1.25 1999/03/05 17:39:39 pierre
  6919. * Actions item freeing
  6920. Revision 1.24 1999/03/03 16:45:07 pierre
  6921. * Actions were not dispose in TCodeEditor.Done
  6922. Revision 1.23 1999/03/01 15:42:10 peter
  6923. + Added dummy entries for functions not yet implemented
  6924. * MenuBar didn't update itself automatically on command-set changes
  6925. * Fixed Debugging/Profiling options dialog
  6926. * TCodeEditor converts spaces to tabs at save only if efUseTabChars is set
  6927. * efBackSpaceUnindents works correctly
  6928. + 'Messages' window implemented
  6929. + Added '$CAP MSG()' and '$CAP EDIT' to available tool-macros
  6930. + Added TP message-filter support (for ex. you can call GREP thru
  6931. GREP2MSG and view the result in the messages window - just like in TP)
  6932. * A 'var' was missing from the param-list of THelpFacility.TopicSearch,
  6933. so topic search didn't work...
  6934. * In FPHELP.PAS there were still context-variables defined as word instead
  6935. of THelpCtx
  6936. * StdStatusKeys() was missing from the statusdef for help windows
  6937. + Topic-title for index-table can be specified when adding a HTML-files
  6938. Revision 1.22 1999/02/22 02:15:25 peter
  6939. + default extension for save in the editor
  6940. + Separate Text to Find for the grep dialog
  6941. * fixed redir crash with tp7
  6942. Revision 1.21 1999/02/20 15:18:33 peter
  6943. + ctrl-c capture with confirm dialog
  6944. + ascii table in the tools menu
  6945. + heapviewer
  6946. * empty file fixed
  6947. * fixed callback routines in fpdebug to have far for tp7
  6948. Revision 1.20 1999/02/18 17:27:57 pierre
  6949. * find/replace dialogs need packed records !!
  6950. Revision 1.19 1999/02/18 13:44:36 peter
  6951. * search fixed
  6952. + backward search
  6953. * help fixes
  6954. * browser updates
  6955. Revision 1.18 1999/02/15 15:12:25 pierre
  6956. + TLine remembers Comment type
  6957. Revision 1.17 1999/02/15 09:32:58 pierre
  6958. * single line comment // fix : comments intermix still wrong !!
  6959. Revision 1.16 1999/02/11 19:07:26 pierre
  6960. * GDBWindow redesigned :
  6961. normal editor apart from
  6962. that any kbEnter will send the line (for begin to cursor)
  6963. to GDB command !
  6964. GDBWindow opened in Debugger Menu
  6965. still buggy :
  6966. -echo should not be present if at end of text
  6967. -GDBWindow becomes First after each step (I don't know why !)
  6968. Revision 1.15 1999/02/09 09:29:59 pierre
  6969. * avoid invisible characters in CombineColors
  6970. Revision 1.14 1999/02/05 13:51:45 peter
  6971. * unit name of FPSwitches -> FPSwitch which is easier to use
  6972. * some fixes for tp7 compiling
  6973. Revision 1.13 1999/02/05 13:22:43 pierre
  6974. * bug that caused crash for empty files
  6975. Revision 1.12 1999/02/05 12:04:56 pierre
  6976. + 'loose' centering for debugger
  6977. Revision 1.11 1999/02/04 17:19:26 peter
  6978. * linux fixes
  6979. Revision 1.10 1999/02/04 10:13:00 pierre
  6980. + GetCurrentWord (used in Find/Replace)
  6981. + DefUseTabsPattern (pattern forcing tabs to be kept)
  6982. used for all makefiles !!
  6983. Revision 1.9 1999/01/29 10:34:33 peter
  6984. + needobjdir,needlibdir
  6985. Revision 1.8 1999/01/21 11:54:31 peter
  6986. + tools menu
  6987. + speedsearch in symbolbrowser
  6988. * working run command
  6989. Revision 1.7 1999/01/14 21:41:17 peter
  6990. * use * as modified indicator
  6991. * fixed syntax highlighting
  6992. Revision 1.6 1999/01/12 14:29:44 peter
  6993. + Implemented still missing 'switch' entries in Options menu
  6994. + Pressing Ctrl-B sets ASCII mode in editor, after which keypresses (even
  6995. ones with ASCII < 32 ; entered with Alt+<###>) are interpreted always as
  6996. ASCII chars and inserted directly in the text.
  6997. + Added symbol browser
  6998. * splitted fp.pas to fpide.pas
  6999. Revision 1.5 1999/01/07 15:02:40 peter
  7000. * better tab support
  7001. Revision 1.4 1999/01/04 11:49:55 peter
  7002. * 'Use tab characters' now works correctly
  7003. + Syntax highlight now acts on File|Save As...
  7004. + Added a new class to syntax highlight: 'hex numbers'.
  7005. * There was something very wrong with the palette managment. Now fixed.
  7006. + Added output directory (-FE<xxx>) support to 'Directories' dialog...
  7007. * Fixed some possible bugs in Running/Compiling, and the compilation/run
  7008. process revised
  7009. Revision 1.2 1998/12/28 15:47:55 peter
  7010. + Added user screen support, display & window
  7011. + Implemented Editor,Mouse Options dialog
  7012. + Added location of .INI and .CFG file
  7013. + Option (INI) file managment implemented (see bottom of Options Menu)
  7014. + Switches updated
  7015. + Run program
  7016. Revision 1.4 1998/12/27 12:01:23 gabor
  7017. * efXXXX constants revised for BP compatibility
  7018. * fixed column and row highlighting (needs to rewrite default palette in the INI)
  7019. Revision 1.3 1998/12/22 10:39:54 peter
  7020. + options are now written/read
  7021. + find and replace routines
  7022. }