weditor.pas 170 KB

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