weditor.pas 209 KB

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