weditor.pas 208 KB

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