weditor.pas 204 KB

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