weditor.pas 209 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786178717881789179017911792179317941795179617971798179918001801180218031804180518061807180818091810181118121813181418151816181718181819182018211822182318241825182618271828182918301831183218331834183518361837183818391840184118421843184418451846184718481849185018511852185318541855185618571858185918601861186218631864186518661867186818691870187118721873187418751876187718781879188018811882188318841885188618871888188918901891189218931894189518961897189818991900190119021903190419051906190719081909191019111912191319141915191619171918191919201921192219231924192519261927192819291930193119321933193419351936193719381939194019411942194319441945194619471948194919501951195219531954195519561957195819591960196119621963196419651966196719681969197019711972197319741975197619771978197919801981198219831984198519861987198819891990199119921993199419951996199719981999200020012002200320042005200620072008200920102011201220132014201520162017201820192020202120222023202420252026202720282029203020312032203320342035203620372038203920402041204220432044204520462047204820492050205120522053205420552056205720582059206020612062206320642065206620672068206920702071207220732074207520762077207820792080208120822083208420852086208720882089209020912092209320942095209620972098209921002101210221032104210521062107210821092110211121122113211421152116211721182119212021212122212321242125212621272128212921302131213221332134213521362137213821392140214121422143214421452146214721482149215021512152215321542155215621572158215921602161216221632164216521662167216821692170217121722173217421752176217721782179218021812182218321842185218621872188218921902191219221932194219521962197219821992200220122022203220422052206220722082209221022112212221322142215221622172218221922202221222222232224222522262227222822292230223122322233223422352236223722382239224022412242224322442245224622472248224922502251225222532254225522562257225822592260226122622263226422652266226722682269227022712272227322742275227622772278227922802281228222832284228522862287228822892290229122922293229422952296229722982299230023012302230323042305230623072308230923102311231223132314231523162317231823192320232123222323232423252326232723282329233023312332233323342335233623372338233923402341234223432344234523462347234823492350235123522353235423552356235723582359236023612362236323642365236623672368236923702371237223732374237523762377237823792380238123822383238423852386238723882389239023912392239323942395239623972398239924002401240224032404240524062407240824092410241124122413241424152416241724182419242024212422242324242425242624272428242924302431243224332434243524362437243824392440244124422443244424452446244724482449245024512452245324542455245624572458245924602461246224632464246524662467246824692470247124722473247424752476247724782479248024812482248324842485248624872488248924902491249224932494249524962497249824992500250125022503250425052506250725082509251025112512251325142515251625172518251925202521252225232524252525262527252825292530253125322533253425352536253725382539254025412542254325442545254625472548254925502551255225532554255525562557255825592560256125622563256425652566256725682569257025712572257325742575257625772578257925802581258225832584258525862587258825892590259125922593259425952596259725982599260026012602260326042605260626072608260926102611261226132614261526162617261826192620262126222623262426252626262726282629263026312632263326342635263626372638263926402641264226432644264526462647264826492650265126522653265426552656265726582659266026612662266326642665266626672668266926702671267226732674267526762677267826792680268126822683268426852686268726882689269026912692269326942695269626972698269927002701270227032704270527062707270827092710271127122713271427152716271727182719272027212722272327242725272627272728272927302731273227332734273527362737273827392740274127422743274427452746274727482749275027512752275327542755275627572758275927602761276227632764276527662767276827692770277127722773277427752776277727782779278027812782278327842785278627872788278927902791279227932794279527962797279827992800280128022803280428052806280728082809281028112812281328142815281628172818281928202821282228232824282528262827282828292830283128322833283428352836283728382839284028412842284328442845284628472848284928502851285228532854285528562857285828592860286128622863286428652866286728682869287028712872287328742875287628772878287928802881288228832884288528862887288828892890289128922893289428952896289728982899290029012902290329042905290629072908290929102911291229132914291529162917291829192920292129222923292429252926292729282929293029312932293329342935293629372938293929402941294229432944294529462947294829492950295129522953295429552956295729582959296029612962296329642965296629672968296929702971297229732974297529762977297829792980298129822983298429852986298729882989299029912992299329942995299629972998299930003001300230033004300530063007300830093010301130123013301430153016301730183019302030213022302330243025302630273028302930303031303230333034303530363037303830393040304130423043304430453046304730483049305030513052305330543055305630573058305930603061306230633064306530663067306830693070307130723073307430753076307730783079308030813082308330843085308630873088308930903091309230933094309530963097309830993100310131023103310431053106310731083109311031113112311331143115311631173118311931203121312231233124312531263127312831293130313131323133313431353136313731383139314031413142314331443145314631473148314931503151315231533154315531563157315831593160316131623163316431653166316731683169317031713172317331743175317631773178317931803181318231833184318531863187318831893190319131923193319431953196319731983199320032013202320332043205320632073208320932103211321232133214321532163217321832193220322132223223322432253226322732283229323032313232323332343235323632373238323932403241324232433244324532463247324832493250325132523253325432553256325732583259326032613262326332643265326632673268326932703271327232733274327532763277327832793280328132823283328432853286328732883289329032913292329332943295329632973298329933003301330233033304330533063307330833093310331133123313331433153316331733183319332033213322332333243325332633273328332933303331333233333334333533363337333833393340334133423343334433453346334733483349335033513352335333543355335633573358335933603361336233633364336533663367336833693370337133723373337433753376337733783379338033813382338333843385338633873388338933903391339233933394339533963397339833993400340134023403340434053406340734083409341034113412341334143415341634173418341934203421342234233424342534263427342834293430343134323433343434353436343734383439344034413442344334443445344634473448344934503451345234533454345534563457345834593460346134623463346434653466346734683469347034713472347334743475347634773478347934803481348234833484348534863487348834893490349134923493349434953496349734983499350035013502350335043505350635073508350935103511351235133514351535163517351835193520352135223523352435253526352735283529353035313532353335343535353635373538353935403541354235433544354535463547354835493550355135523553355435553556355735583559356035613562356335643565356635673568356935703571357235733574357535763577357835793580358135823583358435853586358735883589359035913592359335943595359635973598359936003601360236033604360536063607360836093610361136123613361436153616361736183619362036213622362336243625362636273628362936303631363236333634363536363637363836393640364136423643364436453646364736483649365036513652365336543655365636573658365936603661366236633664366536663667366836693670367136723673367436753676367736783679368036813682368336843685368636873688368936903691369236933694369536963697369836993700370137023703370437053706370737083709371037113712371337143715371637173718371937203721372237233724372537263727372837293730373137323733373437353736373737383739374037413742374337443745374637473748374937503751375237533754375537563757375837593760376137623763376437653766376737683769377037713772377337743775377637773778377937803781378237833784378537863787378837893790379137923793379437953796379737983799380038013802380338043805380638073808380938103811381238133814381538163817381838193820382138223823382438253826382738283829383038313832383338343835383638373838383938403841384238433844384538463847384838493850385138523853385438553856385738583859386038613862386338643865386638673868386938703871387238733874387538763877387838793880388138823883388438853886388738883889389038913892389338943895389638973898389939003901390239033904390539063907390839093910391139123913391439153916391739183919392039213922392339243925392639273928392939303931393239333934393539363937393839393940394139423943394439453946394739483949395039513952395339543955395639573958395939603961396239633964396539663967396839693970397139723973397439753976397739783979398039813982398339843985398639873988398939903991399239933994399539963997399839994000400140024003400440054006400740084009401040114012401340144015401640174018401940204021402240234024402540264027402840294030403140324033403440354036403740384039404040414042404340444045404640474048404940504051405240534054405540564057405840594060406140624063406440654066406740684069407040714072407340744075407640774078407940804081408240834084408540864087408840894090409140924093409440954096409740984099410041014102410341044105410641074108410941104111411241134114411541164117411841194120412141224123412441254126412741284129413041314132413341344135413641374138413941404141414241434144414541464147414841494150415141524153415441554156415741584159416041614162416341644165416641674168416941704171417241734174417541764177417841794180418141824183418441854186418741884189419041914192419341944195419641974198419942004201420242034204420542064207420842094210421142124213421442154216421742184219422042214222422342244225422642274228422942304231423242334234423542364237423842394240424142424243424442454246424742484249425042514252425342544255425642574258425942604261426242634264426542664267426842694270427142724273427442754276427742784279428042814282428342844285428642874288428942904291429242934294429542964297429842994300430143024303430443054306430743084309431043114312431343144315431643174318431943204321432243234324432543264327432843294330433143324333433443354336433743384339434043414342434343444345434643474348434943504351435243534354435543564357435843594360436143624363436443654366436743684369437043714372437343744375437643774378437943804381438243834384438543864387438843894390439143924393439443954396439743984399440044014402440344044405440644074408440944104411441244134414441544164417441844194420442144224423442444254426442744284429443044314432443344344435443644374438443944404441444244434444444544464447444844494450445144524453445444554456445744584459446044614462446344644465446644674468446944704471447244734474447544764477447844794480448144824483448444854486448744884489449044914492449344944495449644974498449945004501450245034504450545064507450845094510451145124513451445154516451745184519452045214522452345244525452645274528452945304531453245334534453545364537453845394540454145424543454445454546454745484549455045514552455345544555455645574558455945604561456245634564456545664567456845694570457145724573457445754576457745784579458045814582458345844585458645874588458945904591459245934594459545964597459845994600460146024603460446054606460746084609461046114612461346144615461646174618461946204621462246234624462546264627462846294630463146324633463446354636463746384639464046414642464346444645464646474648464946504651465246534654465546564657465846594660466146624663466446654666466746684669467046714672467346744675467646774678467946804681468246834684468546864687468846894690469146924693469446954696469746984699470047014702470347044705470647074708470947104711471247134714471547164717471847194720472147224723472447254726472747284729473047314732473347344735473647374738473947404741474247434744474547464747474847494750475147524753475447554756475747584759476047614762476347644765476647674768476947704771477247734774477547764777477847794780478147824783478447854786478747884789479047914792479347944795479647974798479948004801480248034804480548064807480848094810481148124813481448154816481748184819482048214822482348244825482648274828482948304831483248334834483548364837483848394840484148424843484448454846484748484849485048514852485348544855485648574858485948604861486248634864486548664867486848694870487148724873487448754876487748784879488048814882488348844885488648874888488948904891489248934894489548964897489848994900490149024903490449054906490749084909491049114912491349144915491649174918491949204921492249234924492549264927492849294930493149324933493449354936493749384939494049414942494349444945494649474948494949504951495249534954495549564957495849594960496149624963496449654966496749684969497049714972497349744975497649774978497949804981498249834984498549864987498849894990499149924993499449954996499749984999500050015002500350045005500650075008500950105011501250135014501550165017501850195020502150225023502450255026502750285029503050315032503350345035503650375038503950405041504250435044504550465047504850495050505150525053505450555056505750585059506050615062506350645065506650675068506950705071507250735074507550765077507850795080508150825083508450855086508750885089509050915092509350945095509650975098509951005101510251035104510551065107510851095110511151125113511451155116511751185119512051215122512351245125512651275128512951305131513251335134513551365137513851395140514151425143514451455146514751485149515051515152515351545155515651575158515951605161516251635164516551665167516851695170517151725173517451755176517751785179518051815182518351845185518651875188518951905191519251935194519551965197519851995200520152025203520452055206520752085209521052115212521352145215521652175218521952205221522252235224522552265227522852295230523152325233523452355236523752385239524052415242524352445245524652475248524952505251525252535254525552565257525852595260526152625263526452655266526752685269527052715272527352745275527652775278527952805281528252835284528552865287528852895290529152925293529452955296529752985299530053015302530353045305530653075308530953105311531253135314531553165317531853195320532153225323532453255326532753285329533053315332533353345335533653375338533953405341534253435344534553465347534853495350535153525353535453555356535753585359536053615362536353645365536653675368536953705371537253735374537553765377537853795380538153825383538453855386538753885389539053915392539353945395539653975398539954005401540254035404540554065407540854095410541154125413541454155416541754185419542054215422542354245425542654275428542954305431543254335434543554365437543854395440544154425443544454455446544754485449545054515452545354545455545654575458545954605461546254635464546554665467546854695470547154725473547454755476547754785479548054815482548354845485548654875488548954905491549254935494549554965497549854995500550155025503550455055506550755085509551055115512551355145515551655175518551955205521552255235524552555265527552855295530553155325533553455355536553755385539554055415542554355445545554655475548554955505551555255535554555555565557555855595560556155625563556455655566556755685569557055715572557355745575557655775578557955805581558255835584558555865587558855895590559155925593559455955596559755985599560056015602560356045605560656075608560956105611561256135614561556165617561856195620562156225623562456255626562756285629563056315632563356345635563656375638563956405641564256435644564556465647564856495650565156525653565456555656565756585659566056615662566356645665566656675668566956705671567256735674567556765677567856795680568156825683568456855686568756885689569056915692569356945695569656975698569957005701570257035704570557065707570857095710571157125713571457155716571757185719572057215722572357245725572657275728572957305731573257335734573557365737573857395740574157425743574457455746574757485749575057515752575357545755575657575758575957605761576257635764576557665767576857695770577157725773577457755776577757785779578057815782578357845785578657875788578957905791579257935794579557965797579857995800580158025803580458055806580758085809581058115812581358145815581658175818581958205821582258235824582558265827582858295830583158325833583458355836583758385839584058415842584358445845584658475848584958505851585258535854585558565857585858595860586158625863586458655866586758685869587058715872587358745875587658775878587958805881588258835884588558865887588858895890589158925893589458955896589758985899590059015902590359045905590659075908590959105911591259135914591559165917591859195920592159225923592459255926592759285929593059315932593359345935593659375938593959405941594259435944594559465947594859495950595159525953595459555956595759585959596059615962596359645965596659675968596959705971597259735974597559765977597859795980598159825983598459855986598759885989599059915992599359945995599659975998599960006001600260036004600560066007600860096010601160126013601460156016601760186019602060216022602360246025602660276028602960306031603260336034603560366037603860396040604160426043604460456046604760486049605060516052605360546055605660576058605960606061606260636064606560666067606860696070607160726073607460756076607760786079608060816082608360846085608660876088608960906091609260936094609560966097609860996100610161026103610461056106610761086109611061116112611361146115611661176118611961206121612261236124612561266127612861296130613161326133613461356136613761386139614061416142614361446145614661476148614961506151615261536154615561566157615861596160616161626163616461656166616761686169617061716172617361746175617661776178617961806181618261836184618561866187618861896190619161926193619461956196619761986199620062016202620362046205620662076208620962106211621262136214621562166217621862196220622162226223622462256226622762286229623062316232623362346235623662376238623962406241624262436244624562466247624862496250625162526253625462556256625762586259626062616262626362646265626662676268626962706271627262736274627562766277627862796280628162826283628462856286628762886289629062916292629362946295629662976298629963006301630263036304630563066307630863096310631163126313631463156316631763186319632063216322632363246325632663276328632963306331633263336334633563366337633863396340634163426343634463456346634763486349635063516352635363546355635663576358635963606361636263636364636563666367636863696370637163726373637463756376637763786379638063816382638363846385638663876388638963906391639263936394639563966397639863996400640164026403640464056406640764086409641064116412641364146415641664176418641964206421642264236424642564266427642864296430643164326433643464356436643764386439644064416442644364446445644664476448644964506451645264536454645564566457645864596460646164626463646464656466646764686469647064716472647364746475647664776478647964806481648264836484648564866487648864896490649164926493649464956496649764986499650065016502650365046505650665076508650965106511651265136514651565166517651865196520652165226523652465256526652765286529653065316532653365346535653665376538653965406541654265436544654565466547654865496550655165526553655465556556655765586559656065616562656365646565656665676568656965706571657265736574657565766577657865796580658165826583658465856586658765886589659065916592659365946595659665976598659966006601660266036604660566066607660866096610661166126613661466156616661766186619662066216622662366246625662666276628662966306631663266336634663566366637663866396640664166426643664466456646664766486649665066516652665366546655665666576658665966606661666266636664666566666667666866696670667166726673667466756676667766786679668066816682668366846685668666876688668966906691669266936694669566966697669866996700670167026703670467056706670767086709671067116712671367146715671667176718671967206721672267236724672567266727672867296730673167326733673467356736673767386739674067416742674367446745674667476748674967506751675267536754675567566757675867596760676167626763676467656766676767686769677067716772677367746775677667776778677967806781678267836784678567866787678867896790679167926793679467956796679767986799680068016802680368046805680668076808680968106811681268136814681568166817681868196820682168226823682468256826682768286829683068316832683368346835683668376838683968406841684268436844684568466847684868496850685168526853685468556856685768586859686068616862686368646865686668676868686968706871687268736874687568766877687868796880688168826883688468856886688768886889689068916892689368946895689668976898689969006901690269036904690569066907690869096910691169126913691469156916691769186919692069216922692369246925692669276928692969306931693269336934693569366937693869396940694169426943694469456946694769486949695069516952695369546955695669576958695969606961696269636964696569666967696869696970697169726973697469756976697769786979698069816982698369846985698669876988698969906991699269936994699569966997699869997000700170027003700470057006700770087009701070117012701370147015701670177018701970207021702270237024702570267027702870297030703170327033703470357036703770387039704070417042704370447045704670477048704970507051705270537054705570567057705870597060706170627063706470657066706770687069707070717072707370747075707670777078707970807081708270837084708570867087708870897090709170927093709470957096709770987099710071017102710371047105710671077108710971107111711271137114711571167117711871197120712171227123712471257126712771287129713071317132713371347135713671377138713971407141714271437144714571467147714871497150715171527153715471557156715771587159716071617162716371647165716671677168716971707171717271737174717571767177717871797180718171827183718471857186718771887189719071917192719371947195719671977198719972007201720272037204720572067207720872097210721172127213721472157216721772187219722072217222722372247225722672277228722972307231723272337234723572367237723872397240724172427243724472457246724772487249725072517252725372547255725672577258725972607261726272637264726572667267726872697270727172727273727472757276727772787279728072817282728372847285728672877288728972907291729272937294729572967297729872997300730173027303730473057306730773087309731073117312731373147315731673177318731973207321732273237324732573267327732873297330733173327333733473357336733773387339734073417342734373447345734673477348734973507351735273537354735573567357735873597360736173627363736473657366736773687369737073717372737373747375737673777378737973807381738273837384738573867387738873897390739173927393739473957396739773987399740074017402740374047405740674077408740974107411741274137414741574167417741874197420742174227423742474257426742774287429743074317432743374347435743674377438743974407441744274437444744574467447744874497450745174527453745474557456745774587459746074617462746374647465746674677468746974707471747274737474747574767477747874797480748174827483748474857486748774887489749074917492749374947495749674977498749975007501750275037504750575067507750875097510751175127513751475157516751775187519752075217522752375247525752675277528752975307531753275337534753575367537753875397540754175427543754475457546754775487549755075517552755375547555755675577558755975607561756275637564756575667567756875697570757175727573757475757576757775787579758075817582758375847585758675877588758975907591759275937594759575967597759875997600760176027603760476057606760776087609761076117612761376147615761676177618761976207621762276237624762576267627762876297630763176327633763476357636763776387639764076417642764376447645764676477648764976507651765276537654765576567657765876597660766176627663
  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. Video,MsgBox,Dialogs,App,StdDlg,Validate,
  703. {$ifdef WinClipSupported}
  704. Strings,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. { origin is reelative to screen for fvision }
  3556. cur.x:=cur.x+p^.origin.x;
  3557. cur.y:=cur.y+p^.origin.y;
  3558. while true do
  3559. begin
  3560. if (cur.x<0) or (cur.x>=p^.size.x) or
  3561. (cur.y<0) or (cur.y>=p^.size.y) then
  3562. break;
  3563. p2:=p;
  3564. G:=p^.owner;
  3565. if G=Nil then { top view }
  3566. begin
  3567. Video.SetCursorPos(cur.x,cur.y);
  3568. if (state and sfCursorIns)<>0 then
  3569. Video.SetCursorType(crBlock)
  3570. else
  3571. Video.SetCursorType(crUnderline);
  3572. exit;
  3573. end;
  3574. if (G^.state and sfVisible)=0 then
  3575. break;
  3576. p:=G^.Last;
  3577. if Check0 then
  3578. break;
  3579. end; { while }
  3580. end; { if }
  3581. Video.SetCursorType(crHidden);
  3582. end;
  3583. {$endif USE_FREEVISION}
  3584. function TCustomCodeEditor.Overwrite: boolean;
  3585. begin
  3586. Overwrite:=not IsFlagSet(efInsertMode);
  3587. end;
  3588. procedure TCustomCodeEditor.SetCodeCompleteWord(const S: string);
  3589. begin
  3590. if S<>'' then
  3591. SetCompleteState(csOffering)
  3592. else
  3593. SetCompleteState(csInactive);
  3594. end;
  3595. procedure TCustomCodeEditor.ClearCodeCompleteWord;
  3596. begin
  3597. SetCodeCompleteWord('');
  3598. SetCompleteState(csInactive);
  3599. end;
  3600. function TCustomCodeEditor.GetCompleteState: TCompleteState;
  3601. begin
  3602. { Abstract }
  3603. GetCompleteState:=csInactive;
  3604. end;
  3605. procedure TCustomCodeEditor.SetCompleteState(AState: TCompleteState);
  3606. begin
  3607. { Abstract }
  3608. end;
  3609. function TCustomCodeEditor.UpdateAttrs(FromLine: sw_integer; Attrs: byte): sw_integer;
  3610. begin
  3611. Abstract;
  3612. UpdateAttrs:=-1;
  3613. end;
  3614. function TCustomCodeEditor.UpdateAttrsRange(FromLine, ToLine: sw_integer; Attrs: byte): sw_integer;
  3615. begin
  3616. Abstract;
  3617. UpdateAttrsRange:=-1;
  3618. end;
  3619. procedure TCustomCodeEditor.AddAction(AAction: byte; AStartPos, AEndPos: TPoint; AText: string);
  3620. begin
  3621. { Abstract }
  3622. end;
  3623. procedure TCustomCodeEditor.AddGroupedAction(AAction : byte);
  3624. begin
  3625. { Abstract }
  3626. end;
  3627. procedure TCustomCodeEditor.CloseGroupedAction(AAction : byte);
  3628. begin
  3629. { Abstract }
  3630. end;
  3631. function TCustomCodeEditor.GetUndoActionCount: sw_integer;
  3632. begin
  3633. { Abstract }
  3634. GetUndoActionCount:=0;
  3635. end;
  3636. function TCustomCodeEditor.GetRedoActionCount: sw_integer;
  3637. begin
  3638. { Abstract }
  3639. GetRedoActionCount:=0;
  3640. end;
  3641. function TCustomCodeEditor.GetMaxFoldLevel: sw_integer;
  3642. var Max,L,I: sw_integer;
  3643. begin
  3644. Max:=0;
  3645. for I:=0 to GetFoldCount-1 do
  3646. begin
  3647. L:=GetFold(I)^.GetLevel;
  3648. if L>Max then Max:=L;
  3649. end;
  3650. GetMaxFoldLevel:=Max;
  3651. end;
  3652. function TCustomCodeEditor.GetFoldStringWidth: sw_integer;
  3653. begin
  3654. GetFoldStringWidth:=GetMaxFoldLevel;
  3655. end;
  3656. procedure TCustomCodeEditor.GetFoldStrings(EditorLine: sw_integer; var Prefix, Suffix: openstring);
  3657. var F: PFold;
  3658. C: char;
  3659. begin
  3660. Prefix:=CharStr(' ',GetFoldStringWidth); Suffix:='';
  3661. F:=GetLineFold(EditorLine);
  3662. if Assigned(F) then
  3663. begin
  3664. if F^.Collapsed_ then C:=#27 else C:=#26;
  3665. Prefix[1+F^.GetLevel]:=C;
  3666. if F^.Collapsed_ then
  3667. Suffix:='('+IntToStr(F^.GetLineCount)+')';
  3668. end;
  3669. end;
  3670. function TCustomCodeEditor.GetFoldCount: sw_integer;
  3671. begin
  3672. GetFoldCount:=0;
  3673. end;
  3674. function TCustomCodeEditor.GetFold(Index: sw_integer): PFold;
  3675. begin
  3676. GetFold:=nil;
  3677. end;
  3678. procedure TCustomCodeEditor.RegisterFold(AFold: PFold);
  3679. begin
  3680. Abstract;
  3681. end;
  3682. procedure TCustomCodeEditor.UnRegisterFold(AFold: PFold);
  3683. begin
  3684. Abstract;
  3685. end;
  3686. procedure TCustomCodeEditor.Indent;
  3687. var S, PreS: string;
  3688. Shift: integer;
  3689. begin
  3690. S:=GetLineText(CurPos.Y);
  3691. if CurPos.Y>0 then
  3692. PreS:=RTrim(GetLineText(CurPos.Y-1),not IsFlagSet(efUseTabCharacters))
  3693. else
  3694. PreS:='';
  3695. if CurPos.X>=length(PreS) then
  3696. Shift:=GetTabSize
  3697. else
  3698. begin
  3699. Shift:=1;
  3700. while (CurPos.X+Shift<length(PreS)) and (PreS[CurPos.X+Shift]<>' ') do
  3701. Inc(Shift);
  3702. end;
  3703. SetLineText(CurPos.Y,RExpand(copy(S,1,CurPos.X+1),CurPos.X+1)+CharStr(' ',Shift)+copy(S,CurPos.X+2,High(S)));
  3704. SetCurPtr(CurPos.X+Shift,CurPos.Y);
  3705. UpdateAttrs(CurPos.Y,attrAll);
  3706. DrawLines(CurPos.Y);
  3707. SetModified(true);
  3708. end;
  3709. procedure TCustomCodeEditor.CharLeft;
  3710. begin
  3711. if CurPos.X=0 then Exit;
  3712. SetCurPtr(CurPos.X-1,CurPos.Y);
  3713. end;
  3714. procedure TCustomCodeEditor.CharRight;
  3715. begin
  3716. if CurPos.X>=MaxLineLength then
  3717. Exit;
  3718. SetCurPtr(CurPos.X+1,CurPos.Y);
  3719. end;
  3720. procedure TCustomCodeEditor.WordLeft;
  3721. var X, Y: sw_integer;
  3722. Line: string;
  3723. GotIt,FoundNonSeparator: boolean;
  3724. begin
  3725. X:=CurPos.X;
  3726. Y:=CurPos.Y;
  3727. GotIt:=false;
  3728. FoundNonSeparator:=false;
  3729. while (Y>=0) do
  3730. begin
  3731. if Y=CurPos.Y then
  3732. begin
  3733. X:=length(GetDisplayText(Y));
  3734. if CurPos.X<X then
  3735. X:=CurPos.X; Dec(X);
  3736. if (X=-1) then
  3737. begin
  3738. Dec(Y);
  3739. if Y>=0 then
  3740. X:=length(GetDisplayText(Y));
  3741. Break;
  3742. end;
  3743. end
  3744. else
  3745. X:=length(GetDisplayText(Y))-1;
  3746. Line:=GetDisplayText(Y);
  3747. while (X>=0) and (GotIt=false) do
  3748. begin
  3749. if FoundNonSeparator then
  3750. begin
  3751. if IsWordSeparator(Line[X+1]) then
  3752. begin
  3753. Inc(X);
  3754. GotIt:=true;
  3755. Break;
  3756. end;
  3757. end
  3758. else
  3759. if not IsWordSeparator(Line[X+1]) then
  3760. FoundNonSeparator:=true;
  3761. Dec(X);
  3762. if (X=0) and (IsWordSeparator(Line[1])=false) then
  3763. begin
  3764. GotIt:=true;
  3765. Break;
  3766. end;
  3767. end;
  3768. if GotIt then
  3769. Break;
  3770. X:=0;
  3771. Dec(Y);
  3772. if Y>=0 then
  3773. begin
  3774. X:=length(GetDisplayText(Y));
  3775. Break;
  3776. end;
  3777. end;
  3778. if Y<0 then Y:=0; if X<0 then X:=0;
  3779. SetCurPtr(X,Y);
  3780. end;
  3781. procedure TCustomCodeEditor.WordRight;
  3782. var X, Y: sw_integer;
  3783. Line: string;
  3784. GotIt: boolean;
  3785. begin
  3786. X:=CurPos.X; Y:=CurPos.Y; GotIt:=false;
  3787. while (Y<GetLineCount) do
  3788. begin
  3789. if Y=CurPos.Y then
  3790. begin
  3791. X:=CurPos.X; Inc(X);
  3792. if (X>length(GetDisplayText(Y))-1) then
  3793. begin Inc(Y); X:=0; end;
  3794. end else X:=0;
  3795. Line:=GetDisplayText(Y);
  3796. while (X<=length(Line)+1) and (GotIt=false) and (Line<>'') do
  3797. begin
  3798. if X=length(Line)+1 then begin GotIt:=true; Dec(X); Break end;
  3799. if IsWordSeparator(Line[X]) then
  3800. begin
  3801. while (Y<GetLineCount) and
  3802. (X<=length(Line)) and (IsWordSeparator(Line[X])) do
  3803. begin
  3804. Inc(X);
  3805. if X>=length(Line) then
  3806. begin GotIt:=true; Dec(X); Break; end;
  3807. end;
  3808. if (GotIt=false) and (X<length(Line)) then
  3809. begin
  3810. Dec(X);
  3811. GotIt:=true;
  3812. Break;
  3813. end;
  3814. end;
  3815. Inc(X);
  3816. end;
  3817. if GotIt then Break;
  3818. X:=0;
  3819. Inc(Y);
  3820. if (Y<GetLineCount) then
  3821. begin
  3822. Line:=GetDisplayText(Y);
  3823. if (Line<>'') and (IsWordSeparator(Line[1])=false) then Break;
  3824. end;
  3825. end;
  3826. if Y=GetLineCount then Y:=GetLineCount-1;
  3827. SetCurPtr(X,Y);
  3828. end;
  3829. procedure TCustomCodeEditor.LineStart;
  3830. begin
  3831. SetCurPtr(0,CurPos.Y);
  3832. end;
  3833. procedure TCustomCodeEditor.LineEnd;
  3834. var
  3835. s : string;
  3836. i : longint;
  3837. begin
  3838. if CurPos.Y<GetLineCount then
  3839. begin
  3840. s:=GetDisplayText(CurPos.Y);
  3841. i:=length(s);
  3842. while (i>0) and (s[i]=' ') do
  3843. dec(i);
  3844. SetCurPtr(i,CurPos.Y);
  3845. end
  3846. else
  3847. SetCurPtr(0,CurPos.Y);
  3848. end;
  3849. function TCustomCodeEditor.NextVisibleLine(StartLine: sw_integer; Down: boolean): sw_integer;
  3850. var Count,NL: sw_integer;
  3851. begin
  3852. if Down then
  3853. begin
  3854. Count:=GetLineCount;
  3855. NL:=StartLine;
  3856. while (NL<Count-1) and not IsLineVisible(NL) do
  3857. Inc(NL);
  3858. if NL>=Count then
  3859. NL:=-1;
  3860. end
  3861. else
  3862. begin
  3863. NL:=StartLine;
  3864. while (NL>0) and not IsLineVisible(NL) do
  3865. Dec(NL);
  3866. end;
  3867. if not IsLineVisible(NL) then
  3868. NL:=-1;
  3869. NextVisibleLine:=NL;
  3870. end;
  3871. procedure TCustomCodeEditor.LineUp;
  3872. var NL: sw_integer;
  3873. begin
  3874. NL:=NextVisibleLine(CurPos.Y-1,false);
  3875. if NL<>-1 then
  3876. SetCurPtr(CurPos.X,NL);
  3877. end;
  3878. procedure TCustomCodeEditor.LineDown;
  3879. var NL: sw_integer;
  3880. begin
  3881. NL:=NextVisibleLine(CurPos.Y+1,true);
  3882. if NL<>-1 then
  3883. SetCurPtr(CurPos.X,NL);
  3884. end;
  3885. procedure TCustomCodeEditor.PageUp;
  3886. var NL: sw_integer;
  3887. begin
  3888. ScrollTo(Delta.X,Max(Delta.Y-Size.Y,0));
  3889. NL:=Max(CurPos.Y-(Size.Y),0);
  3890. if not IsLineVisible(NL) then
  3891. NL:=NextVisibleLine(NL,false);
  3892. if NL>=0 then
  3893. SetCurPtr(CurPos.X,Max(0,NL));
  3894. end;
  3895. procedure TCustomCodeEditor.PageDown;
  3896. var NL: sw_integer;
  3897. begin
  3898. ScrollTo(Delta.X,Min(Delta.Y+Size.Y,GetLineCount-1));
  3899. NL:=Min(CurPos.Y+(Size.Y{-1}),GetLineCount-1);
  3900. if not IsLineVisible(NL) then
  3901. NL:=NextVisibleLine(NL,true);
  3902. if NL>=0 then
  3903. SetCurPtr(CurPos.X,Min(GetLineCount-1,NL));
  3904. end;
  3905. procedure TCustomCodeEditor.TextStart;
  3906. begin
  3907. SetCurPtr(0,0);
  3908. end;
  3909. procedure TCustomCodeEditor.TextEnd;
  3910. var s : string;
  3911. i : longint;
  3912. begin
  3913. s:=GetDisplayText(GetLineCount-1);
  3914. i:=length(s);
  3915. while (i>0) and (s[i]=' ') do
  3916. dec(i);
  3917. SetCurPtr(i,GetLineCount-1);
  3918. end;
  3919. procedure TCustomCodeEditor.WindowStart;
  3920. begin
  3921. SetCurPtr(CurPos.X,Delta.Y);
  3922. end;
  3923. procedure TCustomCodeEditor.WindowEnd;
  3924. begin
  3925. SetCurPtr(CurPos.X,Delta.Y+Size.Y-1);
  3926. end;
  3927. procedure TCustomCodeEditor.JumpSelStart;
  3928. begin
  3929. if ValidBlock then
  3930. SetCurPtr(SelStart.X,SelStart.Y);
  3931. end;
  3932. procedure TCustomCodeEditor.JumpSelEnd;
  3933. begin
  3934. if ValidBlock then
  3935. SetCurPtr(SelEnd.X,SelEnd.Y);
  3936. end;
  3937. procedure TCustomCodeEditor.JumpMark(MarkIdx: integer);
  3938. begin
  3939. DontConsiderShiftState:=true;
  3940. if (MarkIdx<Low(Bookmarks)) or (MarkIdx>High(Bookmarks)) then
  3941. begin ErrorBox(FormatStrInt(msg_invalidmarkindex,MarkIdx),nil); Exit; end;
  3942. with Bookmarks[MarkIdx] do
  3943. if Valid=false then
  3944. InformationBox(FormatStrInt(msg_marknotset,MarkIdx),nil)
  3945. else
  3946. SetCurPtr(Pos.X,Pos.Y);
  3947. DontConsiderShiftState:=false;
  3948. end;
  3949. procedure TCustomCodeEditor.DefineMark(MarkIdx: integer);
  3950. begin
  3951. if (MarkIdx<Low(Bookmarks)) or (MarkIdx>High(Bookmarks)) then
  3952. begin
  3953. ErrorBox(FormatStrInt(msg_invalidmarkindex,MarkIdx),nil);
  3954. Exit;
  3955. end;
  3956. with Bookmarks[MarkIdx] do
  3957. begin
  3958. Pos:=CurPos;
  3959. Valid:=true;
  3960. end;
  3961. end;
  3962. procedure TCustomCodeEditor.JumpToLastCursorPos;
  3963. begin
  3964. NotImplemented;
  3965. end;
  3966. procedure TCustomCodeEditor.UpperCase;
  3967. var StartP,EndP: TPoint;
  3968. begin
  3969. if ValidBlock=false then Exit;
  3970. GetSelectionArea(StartP,EndP);
  3971. AddGroupedAction(eaUpperCase);
  3972. ChangeCaseArea(StartP,EndP,caToUpperCase);
  3973. CloseGroupedAction(eaUpperCase);
  3974. end;
  3975. procedure TCustomCodeEditor.LowerCase;
  3976. var StartP,EndP: TPoint;
  3977. begin
  3978. if ValidBlock=false then Exit;
  3979. GetSelectionArea(StartP,EndP);
  3980. AddGroupedAction(eaLowerCase);
  3981. ChangeCaseArea(StartP,EndP,caToLowerCase);
  3982. CloseGroupedAction(eaLowerCase);
  3983. end;
  3984. procedure TCustomCodeEditor.ToggleCase;
  3985. var StartP,EndP: TPoint;
  3986. begin
  3987. if ValidBlock=false then Exit;
  3988. GetSelectionArea(StartP,EndP);
  3989. AddGroupedAction(eaToggleCase);
  3990. ChangeCaseArea(StartP,EndP,caToggleCase);
  3991. CloseGroupedAction(eaToggleCase);
  3992. end;
  3993. procedure TCustomCodeEditor.WordLowerCase;
  3994. var StartP,EndP: TPoint;
  3995. begin
  3996. if GetCurrentWordArea(StartP,EndP)=false then Exit;
  3997. AddGroupedAction(eaLowerCase);
  3998. ChangeCaseArea(StartP,EndP,caToLowerCase);
  3999. CloseGroupedAction(eaLowerCase);
  4000. end;
  4001. procedure TCustomCodeEditor.WordUpperCase;
  4002. var StartP,EndP: TPoint;
  4003. begin
  4004. if GetCurrentWordArea(StartP,EndP)=false then Exit;
  4005. AddGroupedAction(eaUpperCase);
  4006. ChangeCaseArea(StartP,EndP,caToUpperCase);
  4007. CloseGroupedAction(eaUpperCase);
  4008. end;
  4009. procedure TCustomCodeEditor.CreateFoldFromBlock;
  4010. var StartY,EndY: sw_integer;
  4011. begin
  4012. if not IsFlagSet(efFolds) then Exit;
  4013. if not ValidBlock then Exit;
  4014. StartY:=SelStart.Y; EndY:=SelEnd.Y;
  4015. if SelEnd.X=0 then Dec(EndY);
  4016. if CreateFold(StartY,EndY,false)=false then
  4017. ErrorBox(msg_foldboundsarenotvalid,nil);
  4018. end;
  4019. procedure TCustomCodeEditor.ToggleFold;
  4020. var F: PFold;
  4021. begin
  4022. if not IsFlagSet(efFolds) then Exit;
  4023. F:=GetLineFold(CurPos.Y);
  4024. if Assigned(F) then
  4025. F^.Collapse(not F^.Collapsed_);
  4026. end;
  4027. procedure TCustomCodeEditor.ExpandFold;
  4028. var F: PFold;
  4029. begin
  4030. if not IsFlagSet(efFolds) then Exit;
  4031. F:=GetLineFold(CurPos.Y);
  4032. if Assigned(F) then
  4033. F^.Collapse(false);
  4034. end;
  4035. procedure TCustomCodeEditor.CollapseFold;
  4036. var F: PFold;
  4037. begin
  4038. if not IsFlagSet(efFolds) then Exit;
  4039. F:=GetLineFold(CurPos.Y);
  4040. if Assigned(F) then
  4041. F^.Collapse(true);
  4042. end;
  4043. procedure TCustomCodeEditor.ChangeCaseArea(StartP,EndP: TPoint; CaseAction: TCaseAction);
  4044. var Y,X: sw_integer;
  4045. X1,X2: sw_integer;
  4046. S: string;
  4047. C: char;
  4048. StartPos : TPoint;
  4049. HoldUndo : boolean;
  4050. begin
  4051. Lock;
  4052. HoldUndo:=GetStoreUndo;
  4053. SetStoreUndo(false);
  4054. for Y:=StartP.Y to EndP.Y do
  4055. begin
  4056. S:=GetDisplayText(Y);
  4057. { Pierre, please implement undo here! Gabor }
  4058. X1:=0; X2:=length(S)-1;
  4059. if Y=StartP.Y then X1:=StartP.X;
  4060. if Y=EndP.Y then X2:=EndP.X;
  4061. SetStoreUndo(HoldUndo);
  4062. StartPos.X:=X1;
  4063. StartPos.Y:=Y;
  4064. { the only drawback is that we keep
  4065. the original text even if Toggle where
  4066. it is not really necessary PM }
  4067. Addaction(eaOverwriteText,StartPos,StartPos,Copy(S,X1+1,X2-X1+1));
  4068. SetStoreUndo(false);
  4069. for X:=X1 to X2 do
  4070. begin
  4071. C:=S[X+1];
  4072. case CaseAction of
  4073. caToLowerCase : C:=LowCase(C);
  4074. caToUpperCase : C:=UpCase(C);
  4075. caToggleCase : if C in['a'..'z'] then
  4076. C:=Upcase(C)
  4077. else
  4078. C:=LowCase(C);
  4079. end;
  4080. S[X+1]:=C;
  4081. end;
  4082. SetDisplayText(Y,S);
  4083. end;
  4084. UpdateAttrsRange(StartP.Y,EndP.Y,attrAll);
  4085. DrawLines(CurPos.Y);
  4086. SetModified(true);
  4087. Addaction(eaMoveCursor,StartPos,CurPos,'');
  4088. SetStoreUndo(HoldUndo);
  4089. UnLock;
  4090. end;
  4091. procedure TCustomCodeEditor.PushInfo(Const st : string);
  4092. begin
  4093. { Dummies }
  4094. end;
  4095. procedure TCustomCodeEditor.PopInfo;
  4096. begin
  4097. { Dummies }
  4098. end;
  4099. procedure TCustomCodeEditor.InsertOptions;
  4100. begin
  4101. { Abstract }
  4102. NotImplemented;
  4103. end;
  4104. function TCustomCodeEditor.GetLineFold(EditorLine: sw_integer): PFold;
  4105. var L: PCustomLine;
  4106. LI: PEditorLineInfo;
  4107. F: PFold;
  4108. begin
  4109. F:=nil;
  4110. if IsFlagSet(efFolds) then
  4111. if (0<=EditorLine) and (EditorLine<GetLineCount) then
  4112. begin
  4113. L:=GetLine(EditorLine);
  4114. if Assigned(L) then
  4115. LI:=L^.GetEditorInfo(@Self)
  4116. else
  4117. LI:=nil;
  4118. if Assigned(LI) then
  4119. F:=LI^.Fold;
  4120. end;
  4121. GetLineFold:=F;
  4122. end;
  4123. function TCustomCodeEditor.IsLineVisible(EditorLine: sw_integer): boolean;
  4124. var V: boolean;
  4125. F,PrevF: PFold;
  4126. FoldHeadline: boolean;
  4127. begin
  4128. V:=true;
  4129. if IsFlagSet(efFolds) then
  4130. begin
  4131. F:=GetLineFold(EditorLine);
  4132. if Assigned(F) then
  4133. begin
  4134. PrevF:=GetLineFold(EditorLine-1);
  4135. FoldHeadline:=false;
  4136. if (PrevF<>F) and ((PrevF=nil) or (not PrevF^.IsParent(F))) then
  4137. FoldHeadline:=true;
  4138. if FoldHeadline then
  4139. begin
  4140. if Assigned(F^.ParentFold) and (F^.ParentFold^.IsCollapsed) then
  4141. V:=false;
  4142. end
  4143. else
  4144. if F^.IsCollapsed then
  4145. V:=false;
  4146. end;
  4147. end;
  4148. IsLineVisible:=V;
  4149. end;
  4150. function TCustomCodeEditor.ViewToEditorLine(ViewLine: sw_integer): sw_integer;
  4151. var I,Line,Count: sw_integer;
  4152. begin
  4153. if not IsFlagSet(efFolds) then
  4154. Line:=ViewLine
  4155. else
  4156. begin
  4157. Count:=GetLineCount;
  4158. I:=0; Line:=-1;
  4159. while (Line<ViewLine) and (I<Count) do
  4160. begin
  4161. if IsLineVisible(I) then
  4162. Inc(Line);
  4163. Inc(I);
  4164. end;
  4165. if Line<>ViewLine then
  4166. Line:=-1
  4167. else
  4168. Line:=I-1;
  4169. end;
  4170. ViewToEditorLine:=Line;
  4171. end;
  4172. function TCustomCodeEditor.EditorToViewLine(EditorLine: sw_integer): sw_integer;
  4173. var I,Line: sw_integer;
  4174. F: PFold;
  4175. begin
  4176. if not IsFlagSet(efFolds) then
  4177. Line:=EditorLine
  4178. else
  4179. begin
  4180. Line:=-1;
  4181. for I:=0 to EditorLine do
  4182. if IsLineVisible(I) then
  4183. Inc(Line);
  4184. end;
  4185. EditorToViewLine:=Line;
  4186. end;
  4187. procedure TCustomCodeEditor.ViewToEditorPoint(P: TPoint; var NP: TPoint);
  4188. begin
  4189. NP.X:=P.X-GetReservedColCount;
  4190. NP.Y:=ViewToEditorLine(P.Y);
  4191. end;
  4192. procedure TCustomCodeEditor.EditorToViewPoint(P: TPoint; var NP: TPoint);
  4193. begin
  4194. NP.X:=P.X+GetReservedColCount;
  4195. NP.Y:=EditorToViewLine(P.Y);
  4196. end;
  4197. procedure TCustomCodeEditor.FindMatchingDelimiter(ScanForward: boolean);
  4198. const OpenSymbols : string[6] = '[{(<''"';
  4199. CloseSymbols : string[6] = ']})>''"';
  4200. var SymIdx: integer;
  4201. LineText,LineAttr: string;
  4202. CurChar: char;
  4203. X,Y: sw_integer;
  4204. LineCount: sw_integer;
  4205. JumpPos: TPoint;
  4206. BracketLevel: integer;
  4207. begin
  4208. JumpPos.X:=-1; JumpPos.Y:=-1;
  4209. LineText:=GetDisplayText(CurPos.Y);
  4210. LineText:=copy(LineText,CurPos.X+1,1);
  4211. if LineText='' then Exit;
  4212. CurChar:=LineText[1];
  4213. Y:=CurPos.Y; X:=CurPos.X; LineCount:=0;
  4214. BracketLevel:=1;
  4215. if ScanForward then
  4216. begin
  4217. SymIdx:=Pos(CurChar,OpenSymbols);
  4218. if SymIdx=0 then Exit;
  4219. repeat
  4220. Inc(LineCount);
  4221. GetDisplayTextFormat(Y,LineText,LineAttr);
  4222. if LineCount<>1 then X:=-1;
  4223. repeat
  4224. Inc(X);
  4225. if X<length(LineText) then
  4226. if copy(LineAttr,X+1,1)<>chr(attrComment) then
  4227. if (LineText[X+1]=CloseSymbols[SymIdx]) and (BracketLevel=1) then
  4228. begin
  4229. JumpPos.X:=X; JumpPos.Y:=Y;
  4230. end
  4231. else
  4232. if LineText[X+1]=OpenSymbols[SymIdx] then
  4233. Inc(BracketLevel)
  4234. else
  4235. if LineText[X+1]=CloseSymbols[SymIdx] then
  4236. if BracketLevel>1 then
  4237. Dec(BracketLevel);
  4238. until (X>=length(LineText)) or (JumpPos.X<>-1);
  4239. Inc(Y);
  4240. until (Y>=GetLineCount) or (JumpPos.X<>-1);
  4241. end
  4242. else
  4243. begin
  4244. SymIdx:=Pos(CurChar,CloseSymbols);
  4245. if SymIdx=0 then Exit;
  4246. repeat
  4247. Inc(LineCount);
  4248. GetDisplayTextFormat(Y,LineText,LineAttr);
  4249. if LineCount<>1 then X:=length(LineText);
  4250. repeat
  4251. Dec(X);
  4252. if X>0 then
  4253. if copy(LineAttr,X+1,1)<>chr(attrComment) then
  4254. if (LineText[X+1]=OpenSymbols[SymIdx]) and (BracketLevel=1) then
  4255. begin
  4256. JumpPos.X:=X; JumpPos.Y:=Y;
  4257. end
  4258. else
  4259. if LineText[X+1]=CloseSymbols[SymIdx] then
  4260. Inc(BracketLevel)
  4261. else
  4262. if LineText[X+1]=OpenSymbols[SymIdx] then
  4263. if BracketLevel>1 then
  4264. Dec(BracketLevel);
  4265. until (X<0) or (JumpPos.X<>-1);
  4266. Dec(Y);
  4267. until (Y<0) or (JumpPos.X<>-1);
  4268. end;
  4269. if JumpPos.X<>-1 then
  4270. begin
  4271. SetCurPtr(JumpPos.X,JumpPos.Y);
  4272. TrackCursor(true);
  4273. end;
  4274. end;
  4275. function TCustomCodeEditor.InsertNewLine: Sw_integer;
  4276. var i,Ind: Sw_integer;
  4277. S,IndentStr: string;
  4278. procedure CalcIndent(LineOver: Sw_integer);
  4279. begin
  4280. if (LineOver<0) or (LineOver>GetLineCount) or ((GetFlags and efNoIndent)<>0) then
  4281. Ind:=0 else
  4282. begin
  4283. repeat
  4284. IndentStr:=GetDisplayText(LineOver);
  4285. Dec(LineOver);
  4286. until (LineOver<0) or (IndentStr<>'');
  4287. Ind:=0;
  4288. while (Ind<length(IndentStr)) and (IndentStr[Ind+1]=' ') do
  4289. Inc(Ind);
  4290. end;
  4291. IndentStr:=CharStr(' ',Ind);
  4292. end;
  4293. var {SelBack: sw_integer;}
  4294. SCP: TPoint;
  4295. HoldUndo : Boolean;
  4296. L,NewL: PCustomLine;
  4297. EI,NewEI: PEditorLineInfo;
  4298. begin
  4299. if IsReadOnly then begin InsertNewLine:=-1; Exit; end;
  4300. Lock;
  4301. SCP:=CurPos;
  4302. HoldUndo:=GetStoreUndo;
  4303. SetStoreUndo(false);
  4304. if CurPos.Y<GetLineCount then S:=GetLineText(CurPos.Y) else S:='';
  4305. if Overwrite=false then
  4306. begin
  4307. if CurPos.Y<GetLineCount then
  4308. begin
  4309. L:=GetLine(CurPos.Y);
  4310. if not assigned(L) then
  4311. EI:=nil
  4312. else
  4313. EI:=L^.GetEditorInfo(@Self);
  4314. end
  4315. else
  4316. EI:=nil;
  4317. { SelBack:=0;}
  4318. if GetLineCount>0 then
  4319. begin
  4320. S:=GetDisplayText(CurPos.Y);
  4321. { SelBack:=length(S)-SelEnd.X;}
  4322. SetDisplayText(CurPos.Y,RTrim(S,not IsFlagSet(efUseTabCharacters)));
  4323. end;
  4324. SetDisplayText(CurPos.Y,copy(S,1,CurPos.X-1+1));
  4325. CalcIndent(CurPos.Y);
  4326. S:=copy(S,CurPos.X+1,High(S));
  4327. i:=1;
  4328. while (i<=length(s)) and (i<=length(IndentStr)) and (s[i]=' ') do
  4329. inc(i);
  4330. if i>1 then
  4331. Delete(IndentStr,1,i-1);
  4332. NewL:=InsertLine(CurPos.Y+1,IndentStr+S);
  4333. LimitsChanged;
  4334. (* if PointOfs(SelStart)<>PointOfs(SelEnd) then { !!! check it - it's buggy !!! }
  4335. begin SelEnd.Y:=CurPos.Y+1; SelEnd.X:=length(GetLineText(CurPos.Y+1))-SelBack; end;*)
  4336. UpdateAttrs(CurPos.Y,attrAll);
  4337. SetCurPtr(Ind,CurPos.Y+1);
  4338. NewEI:=NewL^.GetEditorInfo(@Self);
  4339. if Assigned(EI) and Assigned(NewEI) then
  4340. begin
  4341. NewEI^.SetFold(EI^.Fold);
  4342. if Assigned(EI^.Fold) then
  4343. if EI^.Fold^.IsCollapsed then
  4344. EI^.Fold^.Collapse(false);
  4345. end;
  4346. SetStoreUndo(HoldUndo);
  4347. Addaction(eaInsertLine,SCP,CurPos,IndentStr);
  4348. SetStoreUndo(false);
  4349. AdjustSelection(CurPos.X-SCP.X,CurPos.Y-SCP.Y);
  4350. end else
  4351. begin
  4352. CalcIndent(CurPos.Y);
  4353. if CurPos.Y=GetLineCount-1 then
  4354. begin
  4355. AddLine(IndentStr);
  4356. AdjustSelection(0,1);
  4357. LimitsChanged;
  4358. SetStoreUndo(HoldUndo);
  4359. UpdateAttrs(CurPos.Y,attrAll);
  4360. SetCurPtr(Ind,CurPos.Y+1);
  4361. Addaction(eaInsertLine,SCP,CurPos,IndentStr);
  4362. SetStoreUndo(false);
  4363. end
  4364. else
  4365. begin
  4366. UpdateAttrs(CurPos.Y,attrAll);
  4367. SetStoreUndo(HoldUndo);
  4368. SetCurPtr(Ind,CurPos.Y+1);
  4369. SetStoreUndo(false);
  4370. end;
  4371. end;
  4372. DrawLines(CurPos.Y);
  4373. SetStoreUndo(HoldUndo);
  4374. SetModified(true);
  4375. Unlock;
  4376. end;
  4377. procedure TCustomCodeEditor.BreakLine;
  4378. begin
  4379. NotImplemented; Exit;
  4380. end;
  4381. procedure TCustomCodeEditor.BackSpace;
  4382. var S,PreS: string;
  4383. OI,CI,CP,Y,TX: Sw_integer;
  4384. SCP,SC1 : TPoint;
  4385. HoldUndo : Boolean;
  4386. begin
  4387. if IsReadOnly then Exit;
  4388. Lock;
  4389. SCP:=CurPos;
  4390. HoldUndo:=GetStoreUndo;
  4391. SetStoreUndo(false);
  4392. if CurPos.X=0 then
  4393. begin
  4394. if CurPos.Y>0 then
  4395. begin
  4396. S:=GetLineText(CurPos.Y-1);
  4397. SetLineText(CurPos.Y-1,S+GetLineText(CurPos.Y));
  4398. SC1.X:=Length(S);SC1.Y:=CurPOS.Y-1;
  4399. SetStoreUndo(HoldUndo);
  4400. AddAction(eaDeleteLine,SCP,SC1,GetLineText(CurPos.Y));
  4401. SetStoreUndo(false);
  4402. DeleteLine(CurPos.Y);
  4403. LimitsChanged;
  4404. SetCurPtr(length(S),CurPos.Y-1);
  4405. end;
  4406. end
  4407. else
  4408. begin
  4409. CP:=CurPos.X-1;
  4410. S:=GetLineText(CurPos.Y);
  4411. CI:=LinePosToCharIdx(CurPos.Y,CP);
  4412. if (s[ci]=TAB) and (CharIdxToLinePos(Curpos.y,ci)=cp) then
  4413. CP:=CharIdxToLinePos(CurPos.Y,CI-1)+1;
  4414. if IsFlagSet(efBackspaceUnindents) then
  4415. begin
  4416. S:=GetDisplayText(CurPos.Y);
  4417. if Trim(copy(S,1,CP+1))='' then
  4418. begin
  4419. Y:=CurPos.Y;
  4420. while (Y>0) do
  4421. begin
  4422. Dec(Y);
  4423. PreS:=GetDisplayText(Y);
  4424. if Trim(copy(PreS,1,CP+1))<>'' then Break;
  4425. end;
  4426. if Y<0 then PreS:='';
  4427. TX:=0;
  4428. while (TX<length(PreS)) and (PreS[TX+1]=' ') do
  4429. Inc(TX);
  4430. if TX<CP then CP:=TX;
  4431. end;
  4432. end;
  4433. S:=GetLineText(CurPos.Y);
  4434. OI:=LinePosToCharIdx(CurPos.Y,CurPos.X);
  4435. CI:=LinePosToCharIdx(CurPos.Y,CP);
  4436. SetLineText(CurPos.Y,copy(S,1,CI-1)+copy(S,OI,High(S)));
  4437. SetCurPtr(CP,CurPos.Y);
  4438. SetStoreUndo(HoldUndo);
  4439. Addaction(eaDeleteText,SCP,CurPos,Copy(S,CI,OI-CI));
  4440. SetStoreUndo(false);
  4441. end;
  4442. UpdateAttrs(CurPos.Y,attrAll);
  4443. AdjustSelection(CurPos.X-SCP.X,CurPos.Y-SCP.Y);
  4444. DrawLines(CurPos.Y);
  4445. SetStoreUndo(HoldUndo);
  4446. SetModified(true);
  4447. Unlock;
  4448. end;
  4449. procedure TCustomCodeEditor.DelChar;
  4450. var S: string;
  4451. SDX,SDY,CI : sw_integer;
  4452. HoldUndo : boolean;
  4453. SCP : TPoint;
  4454. begin
  4455. if IsReadOnly then Exit;
  4456. Lock;
  4457. HoldUndo:=GetStoreUndo;
  4458. SetStoreUndo(false);
  4459. S:=GetLineText(CurPos.Y);
  4460. if CurPos.X>=length(S) then
  4461. begin
  4462. if CurPos.Y<GetLineCount-1 then
  4463. begin
  4464. SetLineText(CurPos.Y,S+CharStr(' ',CurPOS.X-Length(S))+GetLineText(CurPos.Y+1));
  4465. SetStoreUndo(HoldUndo);
  4466. SCP.X:=0;SCP.Y:=CurPos.Y+1;
  4467. AddGroupedAction(eaDelChar);
  4468. AddAction(eaMoveCursor,CurPos,SCP,'');
  4469. AddAction(eaDeleteLine,SCP,CurPos,GetLineText(CurPos.Y+1));
  4470. CloseGroupedAction(eaDelChar);
  4471. SetStoreUndo(false);
  4472. DeleteLine(CurPos.Y+1);
  4473. LimitsChanged;
  4474. SDX:=0; SDY:=-1;
  4475. end;
  4476. end
  4477. else
  4478. begin
  4479. { Problem if S[CurPos.X+1]=TAB !! PM }
  4480. CI:=LinePosToCharIdx(CurPos.Y,CurPos.X);
  4481. if S[CI]=TAB then
  4482. begin
  4483. { we want to remove the tab if we are at the first place
  4484. of the tab, but the following test was true for the last position
  4485. in tab
  4486. if CharIdxToLinePos(Curpos.y,ci)=Curpos.x then }
  4487. if CharIdxToLinePos(Curpos.y,ci-1)=Curpos.x-1 then
  4488. Delete(S,Ci,1)
  4489. else
  4490. S:=Copy(S,1,CI-1)+CharStr(' ',GetTabSize-1)+Copy(S,CI+1,High(S));
  4491. SetStoreUndo(HoldUndo);
  4492. Addaction(eaDeleteText,CurPos,CurPos,#9);
  4493. SetStoreUndo(false);
  4494. end
  4495. else
  4496. begin
  4497. SetStoreUndo(HoldUndo);
  4498. Addaction(eaDeleteText,CurPos,CurPos,S[CI]);
  4499. SetStoreUndo(false);
  4500. Delete(S,CI,1);
  4501. end;
  4502. SetLineText(CurPos.Y,S);
  4503. SDX:=-1; SDY:=0;
  4504. end;
  4505. SetCurPtr(CurPos.X,CurPos.Y);
  4506. UpdateAttrs(CurPos.Y,attrAll);
  4507. AdjustSelection(SDX,SDY);
  4508. DrawLines(CurPos.Y);
  4509. SetStoreUndo(HoldUndo);
  4510. SetModified(true);
  4511. Unlock;
  4512. end;
  4513. procedure TCustomCodeEditor.DelWord;
  4514. var
  4515. SP,EP : TPoint;
  4516. SelSize : sw_integer;
  4517. begin
  4518. if IsReadOnly then Exit;
  4519. Lock;
  4520. SP:=SelStart;
  4521. EP:=SelEnd;
  4522. SetSelection(SelStart,SelStart);
  4523. SelectWord;
  4524. SelSize:=SelEnd.X-SelStart.X;
  4525. DelSelect;
  4526. SetSelection(SP,EP);
  4527. AdjustSelectionPos(CurPos.X,CurPos.Y,-SelSize,0);
  4528. if SelSize>0 then
  4529. SetModified(true);
  4530. Unlock;
  4531. end;
  4532. procedure TCustomCodeEditor.DelToEndOfWord;
  4533. var
  4534. SP,EP : TPoint;
  4535. S : String;
  4536. SelSize : sw_integer;
  4537. begin
  4538. if IsReadOnly then Exit;
  4539. Lock;
  4540. SP:=SelStart;
  4541. EP:=SelEnd;
  4542. SetSelection(SelStart,SelStart);
  4543. SelectWord;
  4544. S:=GetDisplayText(CurPos.Y);
  4545. if ((SelStart.X=SelEnd.X) and (SelStart.Y=SelEnd.Y)) then
  4546. begin
  4547. if (Length(S) <= CurPos.X) then
  4548. begin
  4549. SetSelection(SP,EP);
  4550. DelChar;
  4551. Unlock;
  4552. exit;
  4553. end
  4554. else
  4555. begin
  4556. SelEnd.X:=CurPos.X+1;
  4557. SelEnd.Y:=CurPos.Y;
  4558. end;
  4559. end;
  4560. while (length(S)>= SelEnd.X+1) and
  4561. ((S[SelEnd.X+1]=' ') or (S[SelEnd.X+1]=TAB)) do
  4562. inc(SelEnd.X);
  4563. SetSelection(CurPos,SelEnd);
  4564. SelSize:=SelEnd.X-SelStart.X;
  4565. DelSelect;
  4566. SetSelection(SP,EP);
  4567. AdjustSelectionPos(CurPos.X,CurPos.Y,-SelSize,0);
  4568. if SelSize>0 then
  4569. SetModified(true);
  4570. Unlock;
  4571. end;
  4572. procedure TCustomCodeEditor.DelStart;
  4573. var S: string;
  4574. begin
  4575. if IsReadOnly then Exit;
  4576. Lock;
  4577. S:=GetLineText(CurPos.Y);
  4578. if (S<>'') and (CurPos.X<>0) then
  4579. begin
  4580. SetLineText(CurPos.Y,copy(S,LinePosToCharIdx(CurPos.Y,CurPos.X),High(S)));
  4581. SetCurPtr(0,CurPos.Y);
  4582. UpdateAttrs(CurPos.Y,attrAll);
  4583. DrawLines(CurPos.Y);
  4584. SetModified(true);
  4585. end;
  4586. Unlock;
  4587. end;
  4588. procedure TCustomCodeEditor.DelEnd;
  4589. var S: string;
  4590. begin
  4591. if IsReadOnly then Exit;
  4592. Lock;
  4593. S:=GetLineText(CurPos.Y);
  4594. if (S<>'') and (CurPos.X<>length(S)) then
  4595. begin
  4596. SetLineText(CurPos.Y,copy(S,1,LinePosToCharIdx(CurPos.Y,CurPos.X)-1));
  4597. SetCurPtr(CurPos.X,CurPos.Y);
  4598. UpdateAttrs(CurPos.Y,attrAll);
  4599. DrawLines(CurPos.Y);
  4600. SetModified(true);
  4601. end;
  4602. Unlock;
  4603. end;
  4604. procedure TCustomCodeEditor.DelLine;
  4605. var
  4606. HoldUndo : boolean;
  4607. SP : TPoint;
  4608. S : String;
  4609. begin
  4610. if IsReadOnly then Exit;
  4611. Lock;
  4612. if GetLineCount>0 then
  4613. begin
  4614. SP:=CurPos;
  4615. S:=GetLineText(CurPos.Y);
  4616. HoldUndo:=GetStoreUndo;
  4617. SetStoreUndo(false);
  4618. DeleteLine(CurPos.Y);
  4619. LimitsChanged;
  4620. AdjustSelection(0,-1);
  4621. SetCurPtr(0,CurPos.Y);
  4622. UpdateAttrs(Max(0,CurPos.Y-1),attrAll);
  4623. DrawLines(CurPos.Y);
  4624. SetStoreUndo(HoldUndo);
  4625. AddAction(eaDeleteLine,SP,CurPos,S);
  4626. SetModified(true);
  4627. end;
  4628. Unlock;
  4629. end;
  4630. procedure TCustomCodeEditor.InsMode;
  4631. begin
  4632. SetInsertMode(Overwrite);
  4633. end;
  4634. function TCustomCodeEditor.GetCurrentWordArea(var StartP,EndP: TPoint): boolean;
  4635. const WordChars = ['A'..'Z','a'..'z','0'..'9','_'];
  4636. var P : TPoint;
  4637. S : String;
  4638. StartPos,EndPos : byte;
  4639. OK: boolean;
  4640. begin
  4641. P:=CurPos;
  4642. S:=GetLineText(P.Y);
  4643. StartPos:=P.X+1;
  4644. EndPos:=StartPos;
  4645. OK:=(S[StartPos] in WordChars);
  4646. if OK then
  4647. begin
  4648. While (StartPos>0) and (S[StartPos-1] in WordChars) do
  4649. Dec(StartPos);
  4650. While (EndPos<Length(S)) and (S[EndPos+1] in WordChars) do
  4651. Inc(EndPos);
  4652. StartP.X:=StartPos-1; StartP.Y:=CurPos.Y;
  4653. EndP.X:=EndPos-1; EndP.Y:=CurPos.Y;
  4654. end;
  4655. GetCurrentWordArea:=OK;
  4656. end;
  4657. function TCustomCodeEditor.GetCurrentWord : string;
  4658. var S: string;
  4659. StartP,EndP: TPoint;
  4660. begin
  4661. if GetCurrentWordArea(StartP,EndP)=false then
  4662. S:=''
  4663. else
  4664. begin
  4665. S:=GetLineText(StartP.Y);
  4666. S:=copy(S,StartP.X+1,EndP.X-StartP.X+1);
  4667. end;
  4668. GetCurrentWord:=S;
  4669. end;
  4670. procedure TCustomCodeEditor.StartSelect;
  4671. var P1,P2: TPoint;
  4672. begin
  4673. if ValidBlock=false then
  4674. begin
  4675. { SetSelection(SelStart,Limit);}
  4676. P1:=CurPos; P1.X:=0; P2:=CurPos; {P2.X:=length(GetLineText(P2.Y))+1;}
  4677. SetSelection(P1,P2);
  4678. end
  4679. else
  4680. SetSelection(CurPos,SelEnd);
  4681. if PointOfs(SelEnd)<PointOfs(SelStart) then
  4682. SetSelection(SelStart,SelStart);
  4683. CheckSels;
  4684. DrawView;
  4685. end;
  4686. procedure TCustomCodeEditor.EndSelect;
  4687. var P: TPoint;
  4688. LS: sw_integer;
  4689. begin
  4690. P:=CurPos;
  4691. { P.X:=Min(SelEnd.X,length(GetLineText(SelEnd.Y)));}
  4692. LS:=length(GetLineText(SelEnd.Y));
  4693. if LS<P.X then P.X:=LS;
  4694. CheckSels;
  4695. SetSelection(SelStart,P);
  4696. DrawView;
  4697. end;
  4698. procedure TCustomCodeEditor.DelSelect;
  4699. var LineDelta, LineCount, CurLine: Sw_integer;
  4700. StartX,EndX,LastX: Sw_integer;
  4701. S: string;
  4702. SPos : TPoint;
  4703. begin
  4704. if IsReadOnly or (ValidBlock=false) then Exit;
  4705. Lock;
  4706. AddGroupedAction(eaDelBlock);
  4707. LineCount:=(SelEnd.Y-SelStart.Y)+1;
  4708. LineDelta:=0; LastX:=CurPos.X;
  4709. CurLine:=SelStart.Y;
  4710. { single line : easy }
  4711. if LineCount=1 then
  4712. begin
  4713. S:=GetDisplayText(CurLine);
  4714. StartX:=SelStart.X;
  4715. EndX:=SelEnd.X;
  4716. SetDisplayText(CurLine,RExpand(copy(S,1,StartX),StartX)
  4717. +copy(S,EndX+1,High(S)));
  4718. if GetStoreUndo then
  4719. begin
  4720. SPos.X:=StartX;
  4721. SPos.Y:=CurLine;
  4722. AddAction(eaDeleteText,SPos,SPos,Copy(S,StartX+1,EndX-StartX));
  4723. end;
  4724. Inc(CurLine);
  4725. LastX:=SelStart.X;
  4726. end
  4727. { several lines : a bit less easy }
  4728. else
  4729. begin
  4730. S:=GetDisplayText(CurLine);
  4731. StartX:=SelStart.X;
  4732. EndX:=SelEnd.X;
  4733. SetDisplayText(CurLine,RExpand(copy(S,1,StartX),StartX)
  4734. +copy(GetDisplayText(CurLine+LineCount-1),EndX+1,High(S)));
  4735. if GetStoreUndo then
  4736. begin
  4737. SPos.X:=StartX;
  4738. SPos.Y:=CurLine;
  4739. AddAction(eaDeleteText,SPos,SPos,Copy(S,StartX+1,High(S)));
  4740. S:=GetDisplayText(CurLine+LineCount-1);
  4741. end;
  4742. Inc(CurLine);
  4743. Inc(LineDelta);
  4744. LastX:=SelStart.X;
  4745. while (LineDelta<LineCount) do
  4746. begin
  4747. { delete the complete line }
  4748. DeleteLine(CurLine);
  4749. Inc(LineDelta);
  4750. end;
  4751. if GetStoreUndo then
  4752. begin
  4753. AddAction(eaInsertText,SPos,SPos,Copy(S,EndX+1,High(S)));
  4754. end;
  4755. end;
  4756. HideSelect;
  4757. SetCurPtr(LastX,CurLine-1);
  4758. UpdateAttrs(CurPos.Y,attrAll);
  4759. DrawLines(CurPos.Y);
  4760. SetModified(true);
  4761. CloseGroupedAction(eaDelBlock);
  4762. UnLock;
  4763. end;
  4764. procedure TCustomCodeEditor.HideSelect;
  4765. begin
  4766. SetSelection(CurPos,CurPos);
  4767. DrawLines(Delta.Y);
  4768. end;
  4769. procedure TCustomCodeEditor.CopyBlock;
  4770. var Temp: PCodeEditor;
  4771. R: TRect;
  4772. begin
  4773. if IsReadOnly or (ValidBlock=false) then Exit;
  4774. Lock;
  4775. GetExtent(R);
  4776. AddGroupedAction(eaCopyBlock);
  4777. New(Temp, Init(R, nil, nil, nil,nil));
  4778. Temp^.InsertFrom(@Self);
  4779. (* Temp^.SelectAll(true);
  4780. { this selects one line too much because
  4781. we have a empty line at creation to avoid
  4782. negative line problems so we need to decrease SelEnd.Y }
  4783. Dec(Temp^.SelEnd.Y);*)
  4784. InsertFrom(Temp);
  4785. Dispose(Temp, Done);
  4786. CloseGroupedAction(eaCopyBlock);
  4787. UnLock;
  4788. end;
  4789. procedure TCustomCodeEditor.MoveBlock;
  4790. var Temp: PCodeEditor;
  4791. R: TRect;
  4792. OldPos: TPoint;
  4793. begin
  4794. if IsReadOnly then Exit;
  4795. if (SelStart.X=SelEnd.X) and (SelStart.Y=SelEnd.Y) then Exit;
  4796. Lock;
  4797. AddGroupedAction(eaMoveBlock);
  4798. GetExtent(R);
  4799. New(Temp, Init(R, nil, nil, nil,nil));
  4800. Temp^.InsertFrom(@Self);
  4801. OldPos:=CurPos;
  4802. if CurPos.Y>SelStart.Y then
  4803. Dec(OldPos.Y,Temp^.GetLineCount-1);
  4804. DelSelect;
  4805. SetCurPtr(OldPos.X,OldPos.Y);
  4806. InsertFrom(Temp);
  4807. Dispose(Temp, Done);
  4808. CloseGroupedAction(eaMoveBlock);
  4809. UnLock;
  4810. end;
  4811. procedure TCustomCodeEditor.IndentBlock;
  4812. var
  4813. ey,i,indlen : Sw_integer;
  4814. S,Ind : String;
  4815. Pos : Tpoint;
  4816. begin
  4817. if IsReadOnly then Exit;
  4818. if (SelStart.X=SelEnd.X) and (SelStart.Y=SelEnd.Y) then Exit;
  4819. Lock;
  4820. AddGroupedAction(eaIndentBlock);
  4821. ey:=selend.y;
  4822. if selend.x=0 then
  4823. dec(ey);
  4824. S:='';
  4825. { If AutoIndent try to align first line to
  4826. last line before selection }
  4827. { DISABLED created problems PM
  4828. if IsFlagSet(efAutoIndent) and (SelStart.Y>0) then
  4829. begin
  4830. i:=SelStart.Y-1;
  4831. while (S='') and (i>=0) do
  4832. begin
  4833. S:=GetDisplayText(i);
  4834. dec(i);
  4835. end;
  4836. if (S='') or (S[1]<>' ') then
  4837. Ind:=' '
  4838. else
  4839. begin
  4840. i:=1;
  4841. while (i<=Length(S)) and (S[i]=' ') do
  4842. inc(i);
  4843. indlen:=i;
  4844. S:=GetDisplayText(SelStart.Y);
  4845. i:=1;
  4846. while (i<=Length(S)) and (S[i]=' ') do
  4847. inc(i);
  4848. indlen:=indlen-i;
  4849. if indlen<=0 then
  4850. indlen:=1;
  4851. Ind:=CharStr(' ',indlen);
  4852. end;
  4853. end
  4854. else
  4855. Ind:=' ';}
  4856. Ind:=CharStr(' ',GetIndentSize);
  4857. for i:=selstart.y to ey do
  4858. begin
  4859. S:=GetLineText(i);
  4860. SetLineText(i,Ind+S);
  4861. Pos.X:=0;Pos.Y:=i;
  4862. AddAction(eaInsertText,Pos,Pos,Ind);
  4863. end;
  4864. SetCurPtr(CurPos.X,CurPos.Y);
  4865. { must be added manually here PM }
  4866. AddAction(eaMoveCursor,Pos,CurPos,'');
  4867. UpdateAttrsRange(SelStart.Y,SelEnd.Y,attrAll);
  4868. DrawLines(CurPos.Y);
  4869. SetModified(true);
  4870. CloseGroupedAction(eaIndentBlock);
  4871. UnLock;
  4872. end;
  4873. procedure TCustomCodeEditor.UnindentBlock;
  4874. var
  4875. ey,i,j,k,indlen : Sw_integer;
  4876. S : String;
  4877. Pos : TPoint;
  4878. begin
  4879. if IsReadOnly then Exit;
  4880. if (SelStart.X=SelEnd.X) and (SelStart.Y=SelEnd.Y) then Exit;
  4881. Lock;
  4882. AddGroupedAction(eaUnindentBlock);
  4883. ey:=selend.y;
  4884. if selend.x=0 then
  4885. dec(ey);
  4886. { If AutoIndent try to align first line to
  4887. last line before selection }
  4888. { Disabled created problems
  4889. if IsFlagSet(efAutoIndent) and (SelStart.Y>0) then
  4890. begin
  4891. S:=GetDisplayText(SelStart.Y);
  4892. i:=1;
  4893. while (i<=Length(S)) and (S[i]=' ') do
  4894. inc(i);
  4895. indlen:=i-1;
  4896. i:=SelStart.Y-1;
  4897. S:='';
  4898. while (S='') and (i>=0) do
  4899. begin
  4900. if Trim(Copy(GetDisplayText(i),1,indlen))='' then
  4901. S:=''
  4902. else
  4903. S:=GetDisplayText(i);
  4904. dec(i);
  4905. end;
  4906. if (S='') then
  4907. Indlen:=1
  4908. else
  4909. begin
  4910. i:=1;
  4911. while (i<=Length(S)) and (S[i]=' ') do
  4912. inc(i);
  4913. indlen:=indlen-i+1;
  4914. if indlen<=0 then
  4915. indlen:=1;
  4916. end;
  4917. end
  4918. else
  4919. Indlen:=1;}
  4920. Indlen:=GetIndentSize;
  4921. for i:=selstart.y to ey do
  4922. begin
  4923. S:=GetLineText(i);
  4924. k:=0;
  4925. for j:=1 to indlen do
  4926. if (length(s)>1) and (S[1]=' ') then
  4927. begin
  4928. Delete(s,1,1);
  4929. inc(k);
  4930. end;
  4931. SetLineText(i,S);
  4932. if k>0 then
  4933. begin
  4934. Pos.Y:=i;
  4935. Pos.X:=0;
  4936. AddAction(eaDeleteText,Pos,Pos,CharStr(' ',k));
  4937. end;
  4938. end;
  4939. SetCurPtr(CurPos.X,CurPos.Y);
  4940. UpdateAttrsRange(SelStart.Y,SelEnd.Y,attrAll);
  4941. DrawLines(CurPos.Y);
  4942. SetModified(true);
  4943. CloseGroupedAction(eaUnindentBlock);
  4944. UnLock;
  4945. end;
  4946. procedure TCustomCodeEditor.SelectWord;
  4947. const WordChars = ['A'..'Z','a'..'z','0'..'9','_'];
  4948. var S : String;
  4949. StartPos,EndPos : byte;
  4950. A,B: TPoint;
  4951. begin
  4952. A:=CurPos;
  4953. B:=CurPos;
  4954. S:=GetDisplayText(A.Y);
  4955. StartPos:=A.X+1;
  4956. EndPos:=StartPos;
  4957. if not (S[StartPos] in WordChars) then
  4958. exit
  4959. else
  4960. begin
  4961. While (StartPos>0) and (S[StartPos-1] in WordChars) do
  4962. Dec(StartPos);
  4963. While (EndPos<Length(S)) and (S[EndPos+1] in WordChars) do
  4964. Inc(EndPos);
  4965. A.X:=StartPos-1;
  4966. B.X:=EndPos;
  4967. SetSelection(A,B);
  4968. end;
  4969. end;
  4970. procedure TCustomCodeEditor.SelectLine;
  4971. var A,B: TPoint;
  4972. begin
  4973. if CurPos.Y<GetLineCount then
  4974. begin
  4975. A.Y:=CurPos.Y; A.X:=0;
  4976. B.Y:=CurPos.Y+1; B.X:=0;
  4977. SetSelection(A,B);
  4978. end;
  4979. end;
  4980. procedure TCustomCodeEditor.WriteBlock;
  4981. var FileName: string;
  4982. S: PBufStream;
  4983. begin
  4984. if ValidBlock=false then Exit;
  4985. FileName:='';
  4986. if EditorDialog(edWriteBlock, @FileName) <> cmCancel then
  4987. begin
  4988. FileName := FExpand(FileName);
  4989. New(S, Init(FileName, stCreate, 4096));
  4990. if (S=nil) or (S^.Status<>stOK) then
  4991. EditorDialog(edCreateError,@FileName)
  4992. else
  4993. if SaveAreaToStream(S,SelStart,SelEnd)=false then
  4994. EditorDialog(edWriteError,@FileName);
  4995. if Assigned(S) then Dispose(S, Done);
  4996. end;
  4997. end;
  4998. procedure TCustomCodeEditor.ReadBlock;
  4999. var FileName: string;
  5000. S: PBufStream;
  5001. E: PCodeEditor;
  5002. R: TRect;
  5003. begin
  5004. if IsReadOnly then Exit;
  5005. FileName:='';
  5006. if EditorDialog(edReadBlock, @FileName) <> cmCancel then
  5007. begin
  5008. FileName := FExpand(FileName);
  5009. New(S, Init(FileName, stOpenRead, 4096));
  5010. if (S=nil) or (S^.Status<>stOK) then
  5011. EditorDialog(edReadError,@FileName)
  5012. else
  5013. begin
  5014. R.Assign(0,0,0,0);
  5015. New(E, Init(R,nil,nil,nil,nil));
  5016. AddGroupedAction(eaReadBlock);
  5017. if E^.LoadFromStream(S)=false then
  5018. EditorDialog(edReadError,@FileName)
  5019. else
  5020. begin
  5021. E^.SelectAll(true);
  5022. Self.InsertFrom(E);
  5023. end;
  5024. CloseGroupedAction(eaReadBlock);
  5025. Dispose(E, Done);
  5026. end;
  5027. if Assigned(S) then Dispose(S, Done);
  5028. end;
  5029. end;
  5030. procedure TCustomCodeEditor.PrintBlock;
  5031. begin
  5032. NotImplemented; Exit;
  5033. end;
  5034. function TCustomCodeEditor.SelectCodeTemplate(var ShortCut: string): boolean;
  5035. begin
  5036. { Abstract }
  5037. SelectCodeTemplate:=false;
  5038. end;
  5039. procedure TCustomCodeEditor.ExpandCodeTemplate;
  5040. var Line,ShortCutInEditor,ShortCut: string;
  5041. X,Y,I,LineIndent: sw_integer;
  5042. CodeLines: PUnsortedStringCollection;
  5043. CanJump,Expanded: boolean;
  5044. CP: TPoint;
  5045. begin
  5046. {
  5047. The usage of editing primitives in this routine make it pretty slow, but
  5048. its speed is still acceptable and they make the implementation of Undo
  5049. much easier... - Gabor
  5050. }
  5051. if IsReadOnly then Exit;
  5052. Lock;
  5053. CP.X:=-1; CP.Y:=-1; Expanded:=false;
  5054. Line:=GetDisplayText(CurPos.Y);
  5055. X:=CurPos.X; ShortCut:='';
  5056. if X<=length(Line) then
  5057. while (X>0) and (Line[X] in (NumberChars+AlphaChars)) do
  5058. begin
  5059. ShortCut:=Line[X]+ShortCut;
  5060. Dec(X);
  5061. end;
  5062. ShortCutInEditor:=ShortCut;
  5063. New(CodeLines, Init(10,10));
  5064. if (ShortCut='') or (not TranslateCodeTemplate(ShortCut,CodeLines)) then
  5065. if SelectCodeTemplate(ShortCut) then
  5066. TranslateCodeTemplate(ShortCut,CodeLines);
  5067. if CodeLines^.Count>0 then
  5068. begin
  5069. LineIndent:=X;
  5070. SetCurPtr(X,CurPos.Y);
  5071. for I:=1 to length(ShortCutInEditor) do
  5072. DelChar;
  5073. for Y:=0 to CodeLines^.Count-1 do
  5074. begin
  5075. Line:=CodeLines^.At(Y)^;
  5076. CanJump:=false;
  5077. if (Y>0) then
  5078. begin
  5079. CanJump:=Trim(GetLineText(CurPos.Y))='';
  5080. if CanJump=false then
  5081. begin
  5082. (* for X:=1 to LineIndent do { indent template lines to align }
  5083. AddChar(' '); { them to the first line }*)
  5084. InsertText(CharStr(' ',LineIndent));
  5085. end
  5086. else
  5087. SetCurPtr(CurPos.X+LineIndent,CurPos.Y);
  5088. end;
  5089. I:=Pos(CodeTemplateCursorChar,Line);
  5090. if I>0 then
  5091. begin
  5092. Delete(Line,I,1);
  5093. CP.X:=CurPos.X+I-1;
  5094. CP.Y:=CurPos.Y;
  5095. end;
  5096. InsertText(Line);
  5097. if Y<CodeLines^.Count-1 then
  5098. begin
  5099. InsertNewLine; { line break }
  5100. if CanJump=false then
  5101. begin
  5102. while CurPos.X>0 do { unindent }
  5103. begin
  5104. SetCurPtr(CurPos.X-1,CurPos.Y);
  5105. DelChar;
  5106. end;
  5107. end
  5108. else
  5109. SetCurPtr(0,CurPos.Y);
  5110. end;
  5111. end;
  5112. Expanded:=true;
  5113. end;
  5114. Dispose(CodeLines, Done);
  5115. if (CP.X<>-1) and (CP.Y<>-1) then
  5116. SetCurPtr(CP.X,CP.Y);
  5117. UnLock;
  5118. end;
  5119. procedure TCustomCodeEditor.AddChar(C: char);
  5120. const OpenBrackets : string[10] = '[({';
  5121. CloseBrackets : string[10] = '])}';
  5122. var S,SC,TabS: string;
  5123. BI: byte;
  5124. CI,TabStart,LocTabSize : Sw_integer;
  5125. SP: TPoint;
  5126. HoldUndo : boolean;
  5127. begin
  5128. if IsReadOnly then Exit;
  5129. Lock;
  5130. SP:=CurPos;
  5131. HoldUndo:=GetStoreUndo;
  5132. SetStoreUndo(false);
  5133. if (C<>TAB) or IsFlagSet(efUseTabCharacters) then
  5134. SC:=C
  5135. else
  5136. begin
  5137. LocTabSize:=GetTabSize - (CurPos.X mod GetTabSize);
  5138. if (CurPos.Y<=1) or not IsFlagSet(efAutoIndent) then
  5139. SC:=CharStr(' ',LocTabSize)
  5140. else
  5141. begin
  5142. S:=GetLineText(CurPos.Y-1);
  5143. BI:=CurPos.X+1;
  5144. while (BI<=Length(S)) and (S[BI]=' ') do
  5145. inc(BI);
  5146. if (BI=CurPos.X+1) or (BI>Length(S)) then
  5147. SC:=CharStr(' ',LocTabSize)
  5148. else
  5149. SC:=CharStr(' ',BI-CurPos.X-1);
  5150. end;
  5151. end;
  5152. S:=GetLineText(CurPos.Y);
  5153. if CharIdxToLinePos(CurPos.Y,length(S))<CurPos.X then
  5154. begin
  5155. S:=S+CharStr(' ',CurPos.X-CharIdxToLinePos(CurPos.Y,length(S)){-1});
  5156. SetLineText(CurPos.Y,S);
  5157. end;
  5158. CI:=LinePosToCharIdx(CurPos.Y,CurPos.X);
  5159. if (CI>0) and (S[CI]=TAB) and not IsFlagSet(efUseTabCharacters) then
  5160. begin
  5161. if CI=1 then
  5162. TabStart:=0
  5163. else
  5164. TabStart:=CharIdxToLinePos(CurPos.Y,CI-1)+1;
  5165. if SC=Tab then TabS:=Tab else
  5166. TabS:=CharStr(' ',CurPos.X-TabStart);
  5167. SetLineText(CurPos.Y,copy(S,1,CI-1)+TabS+SC+copy(S,CI+1,High(S)));
  5168. SetCurPtr(CharIdxToLinePos(CurPos.Y,CI+length(TabS)+length(SC)),CurPos.Y);
  5169. end
  5170. else
  5171. begin
  5172. if Overwrite and (CI<=length(S)) then
  5173. begin
  5174. SetLineText(CurPos.Y,copy(S,1,CI-1)+SC+copy(S,CI+length(SC),High(S)));
  5175. end
  5176. else
  5177. SetLineText(CurPos.Y,copy(S,1,CI-1)+SC+copy(S,CI,High(S)));
  5178. SetCurPtr(CharIdxToLinePos(CurPos.Y,CI+length(SC)),CurPos.Y);
  5179. end;
  5180. { must be before CloseBrackets !! }
  5181. SetStoreUndo(HoldUndo);
  5182. if Overwrite then
  5183. Addaction(eaOverwriteText,SP,CurPos,Copy(S,CI,length(SC)))
  5184. else
  5185. Addaction(eaInsertText,SP,CurPos,SC);
  5186. SetStoreUndo(false);
  5187. if IsFlagSet(efAutoBrackets) then
  5188. begin
  5189. BI:=Pos(C,OpenBrackets);
  5190. if (BI>0) then
  5191. begin
  5192. SetStoreUndo(HoldUndo);
  5193. AddChar(CloseBrackets[BI]);
  5194. SetStoreUndo(false);
  5195. SetCurPtr(CurPos.X-1,CurPos.Y);
  5196. end;
  5197. end;
  5198. UpdateAttrs(CurPos.Y,attrAll);
  5199. if GetInsertMode then
  5200. AdjustSelection(CurPos.X-SP.X,CurPos.Y-SP.Y);
  5201. DrawLines(CurPos.Y);
  5202. SetStoreUndo(HoldUndo);
  5203. SetModified(true);
  5204. UnLock;
  5205. end;
  5206. {$ifdef WinClipSupported}
  5207. function TCustomCodeEditor.ClipPasteWin: Boolean;
  5208. var OK: boolean;
  5209. l,i : longint;
  5210. p,p10,p2,p13 : pchar;
  5211. s : string;
  5212. BPos,EPos,StorePos : TPoint;
  5213. first : boolean;
  5214. begin
  5215. Lock;
  5216. OK:=WinClipboardSupported;
  5217. if OK then
  5218. begin
  5219. first:=true;
  5220. StorePos:=CurPos;
  5221. i:=CurPos.Y;
  5222. l:=GetTextWinClipboardSize;
  5223. if l=0 then
  5224. OK:=false
  5225. else
  5226. OK:=GetTextWinClipBoardData(p,l);
  5227. if OK then
  5228. begin
  5229. if l>500 then
  5230. PushInfo(msg_readingwinclipboard);
  5231. AddGroupedAction(eaPasteWin);
  5232. p2:=p;
  5233. p13:=strpos(p,#13);
  5234. p10:=strpos(p,#10);
  5235. while assigned(p10) do
  5236. begin
  5237. if p13+1=p10 then
  5238. p13[0]:=#0
  5239. else
  5240. p10[0]:=#0;
  5241. s:=strpas(p2);
  5242. if first then
  5243. begin
  5244. { we need to cut the line in two
  5245. if not at end of line PM }
  5246. InsertNewLine;
  5247. SetCurPtr(StorePos.X,StorePos.Y);
  5248. InsertText(s);
  5249. first:=false;
  5250. end
  5251. else
  5252. begin
  5253. Inc(i);
  5254. InsertLine(i,s);
  5255. BPos.X:=0;BPos.Y:=i;
  5256. EPOS.X:=Length(s);EPos.Y:=i;
  5257. AddAction(eaInsertLine,BPos,EPos,GetDisplayText(i));
  5258. end;
  5259. if p13+1=p10 then
  5260. p13[0]:=#13
  5261. else
  5262. p10[0]:=#10;
  5263. p2:=@p10[1];
  5264. p13:=strpos(p2,#13);
  5265. p10:=strpos(p2,#10);
  5266. end;
  5267. if strlen(p2)>0 then
  5268. begin
  5269. s:=strpas(p2);
  5270. if not first then
  5271. SetCurPtr(0,i+1);
  5272. InsertText(s);
  5273. end;
  5274. SetCurPtr(StorePos.X,StorePos.Y);
  5275. SetModified(true);
  5276. UpdateAttrs(StorePos.Y,attrAll);
  5277. CloseGroupedAction(eaPasteWin);
  5278. Update;
  5279. if l>500 then
  5280. PopInfo;
  5281. { we must free the allocated memory }
  5282. freemem(p,l);
  5283. DrawView;
  5284. end;
  5285. end;
  5286. ClipPasteWin:=OK;
  5287. UnLock;
  5288. end;
  5289. function TCustomCodeEditor.ClipCopyWin: Boolean;
  5290. var OK,ShowInfo: boolean;
  5291. p,p2 : pchar;
  5292. s : string;
  5293. i,str_begin,str_end,NumLines,PcLength : longint;
  5294. begin
  5295. NumLines:=SelEnd.Y-SelStart.Y;
  5296. if (NumLines>0) or (SelEnd.X>SelStart.X) then
  5297. Inc(NumLines);
  5298. if NumLines=0 then
  5299. exit;
  5300. Lock;
  5301. ShowInfo:=SelEnd.Y-SelStart.Y>50;
  5302. if ShowInfo then
  5303. PushInfo(msg_copyingwinclipboard);
  5304. { First calculate needed size }
  5305. { for newlines first + 1 for terminal #0 }
  5306. PcLength:=Length(EOL)*(NumLines-1)+1;
  5307. { overestimated but can not be that big PM }
  5308. for i:=SelStart.Y to SelEnd.Y do
  5309. PCLength:=PCLength+Length(GetLineText(i));
  5310. getmem(p,PCLength);
  5311. i:=SelStart.Y;
  5312. s:=GetLineText(i);
  5313. str_begin:=LinePosToCharIdx(i,SelStart.X);
  5314. if SelEnd.Y>SelStart.Y then
  5315. str_end:=High(S)
  5316. else
  5317. str_end:=LinePosToCharIdx(i,SelEnd.X)-1;
  5318. s:=copy(s,str_begin,str_end-str_begin+1);
  5319. strpcopy(p,s);
  5320. p2:=strend(p);
  5321. inc(i);
  5322. while i<SelEnd.Y do
  5323. begin
  5324. strpcopy(p2,EOL+GetLineText(i));
  5325. p2:=strend(p2);
  5326. Inc(i);
  5327. end;
  5328. if SelEnd.Y>SelStart.Y then
  5329. begin
  5330. s:=copy(GetLineText(i),1,LinePosToCharIdx(i,SelEnd.X)-1);
  5331. strpcopy(p2,EOL+s);
  5332. end;
  5333. OK:=WinClipboardSupported;
  5334. if OK then
  5335. begin
  5336. OK:=SetTextWinClipBoardData(p,strlen(p));
  5337. end;
  5338. ClipCopyWin:=OK;
  5339. if ShowInfo then
  5340. PopInfo;
  5341. Freemem(p,PCLength);
  5342. UnLock;
  5343. end;
  5344. {$endif WinClipSupported}
  5345. function TCustomCodeEditor.ClipCopy: Boolean;
  5346. var OK,ShowInfo: boolean;
  5347. begin
  5348. Lock;
  5349. {AddGroupedAction(eaCopy);
  5350. can we undo a copy ??
  5351. maybe as an Undo Paste in Clipboard !! }
  5352. OK:=Clipboard<>nil;
  5353. if OK then
  5354. ShowInfo:=SelEnd.Y-SelStart.Y>50
  5355. else
  5356. ShowInfo:=false;
  5357. if ShowInfo then
  5358. PushInfo(msg_copyingclipboard);
  5359. if OK then OK:=Clipboard^.InsertFrom(@Self);
  5360. if ShowInfo then
  5361. PopInfo;
  5362. ClipCopy:=OK;
  5363. UnLock;
  5364. end;
  5365. procedure TCustomCodeEditor.ClipCut;
  5366. var
  5367. ShowInfo : boolean;
  5368. begin
  5369. if IsReadOnly then Exit;
  5370. Lock;
  5371. AddGroupedAction(eaCut);
  5372. DontConsiderShiftState:=true;
  5373. if Clipboard<>nil then
  5374. begin
  5375. ShowInfo:=SelEnd.Y-SelStart.Y>50;
  5376. if ShowInfo then
  5377. PushInfo(msg_cutting);
  5378. if Clipboard^.InsertFrom(@Self) then
  5379. begin
  5380. if not IsClipBoard then
  5381. DelSelect;
  5382. SetModified(true);
  5383. end;
  5384. if ShowInfo then
  5385. PopInfo;
  5386. end;
  5387. CloseGroupedAction(eaCut);
  5388. UnLock;
  5389. DontConsiderShiftState:=false;
  5390. end;
  5391. procedure TCustomCodeEditor.ClipPaste;
  5392. var
  5393. ShowInfo : boolean;
  5394. begin
  5395. if IsReadOnly then Exit;
  5396. DontConsiderShiftState:=true;
  5397. Lock;
  5398. AddGroupedAction(eaPaste);
  5399. if Clipboard<>nil then
  5400. begin
  5401. ShowInfo:=Clipboard^.SelEnd.Y-Clipboard^.SelStart.Y>50;
  5402. if ShowInfo then
  5403. PushInfo(msg_pastingclipboard);
  5404. InsertFrom(Clipboard);
  5405. if ShowInfo then
  5406. PopInfo;
  5407. SetModified(true);
  5408. end;
  5409. CloseGroupedAction(eaPaste);
  5410. UnLock;
  5411. DontConsiderShiftState:=false;
  5412. end;
  5413. procedure TCustomCodeEditor.Undo;
  5414. begin
  5415. NotImplemented; Exit;
  5416. end;
  5417. procedure TCustomCodeEditor.Redo;
  5418. begin
  5419. NotImplemented; Exit;
  5420. end;
  5421. procedure TCustomCodeEditor.GotoLine;
  5422. var
  5423. GotoRec: TGotoLineDialogRec;
  5424. begin
  5425. with GotoRec do
  5426. begin
  5427. LineNo:='1';
  5428. Lines:=GetLineCount;
  5429. if EditorDialog(edGotoLine, @GotoRec) <> cmCancel then
  5430. begin
  5431. Lock;
  5432. SetCurPtr(0,StrToInt(LineNo)-1);
  5433. TrackCursor(true);
  5434. UnLock;
  5435. end;
  5436. end;
  5437. end;
  5438. procedure TCustomCodeEditor.Find;
  5439. var
  5440. FindRec: TFindDialogRec;
  5441. DoConf: boolean;
  5442. begin
  5443. with FindRec do
  5444. begin
  5445. Find := FindStr;
  5446. if GetCurrentWord<>'' then
  5447. Find:=GetCurrentWord;
  5448. {$ifdef TEST_REGEXP}
  5449. Options := ((FindFlags and ffmOptionsFind) shr ffsOptions) or
  5450. ((FindFlags and ffUseRegExp) shr ffsUseRegExpFind);
  5451. {$else not TEST_REGEXP}
  5452. Options := (FindFlags and ffmOptions) shr ffsOptions;
  5453. {$endif TEST_REGEXP}
  5454. Direction := (FindFlags and ffmDirection) shr ffsDirection;
  5455. Scope := (FindFlags and ffmScope) shr ffsScope;
  5456. Origin := (FindFlags and ffmOrigin) shr ffsOrigin;
  5457. DoConf:= (FindFlags and ffPromptOnReplace)<>0;
  5458. FindReplaceEditor:=@self;
  5459. if EditorDialog(edFind, @FindRec) <> cmCancel then
  5460. begin
  5461. FindStr := Find;
  5462. {$ifdef TEST_REGEXP}
  5463. FindFlags := ((Options and ffmOptionsFind) shl ffsOptions) or (Direction shl ffsDirection) or
  5464. ((Options and ffmUseRegExpFind) shl ffsUseRegExpFind) or
  5465. (Scope shl ffsScope) or (Origin shl ffsOrigin);
  5466. {$else : not TEST_REGEXP}
  5467. FindFlags := ((Options and ffmOptions) shl ffsOptions) or (Direction shl ffsDirection) or
  5468. (Scope shl ffsScope) or (Origin shl ffsOrigin);
  5469. {$endif TEST_REGEXP}
  5470. FindFlags := FindFlags and not ffDoReplace;
  5471. if DoConf then
  5472. FindFlags := (FindFlags or ffPromptOnReplace);
  5473. SearchRunCount:=0;
  5474. if FindStr<>'' then
  5475. DoSearchReplace
  5476. else
  5477. EditorDialog(edSearchFailed,nil);
  5478. end;
  5479. FindReplaceEditor:=nil;
  5480. end;
  5481. end;
  5482. procedure TCustomCodeEditor.Replace;
  5483. var
  5484. ReplaceRec: TReplaceDialogRec;
  5485. Re: word;
  5486. begin
  5487. if IsReadOnly then Exit;
  5488. with ReplaceRec do
  5489. begin
  5490. Find := FindStr;
  5491. if GetCurrentWord<>'' then
  5492. Find:=GetCurrentWord;
  5493. Replace := ReplaceStr;
  5494. {$ifdef TEST_REGEXP}
  5495. Options := (FindFlags and ffmOptions) shr ffsOptions or
  5496. (FindFlags and ffUseRegExp) shr ffsUseRegExpReplace;
  5497. {$else not TEST_REGEXP}
  5498. Options := (FindFlags and ffmOptions) shr ffsOptions;
  5499. {$endif TEST_REGEXP}
  5500. Direction := (FindFlags and ffmDirection) shr ffsDirection;
  5501. Scope := (FindFlags and ffmScope) shr ffsScope;
  5502. Origin := (FindFlags and ffmOrigin) shr ffsOrigin;
  5503. FindReplaceEditor:=@self;
  5504. Re:=EditorDialog(edReplace, @ReplaceRec);
  5505. FindReplaceEditor:=nil;
  5506. if Re <> cmCancel then
  5507. begin
  5508. FindStr := Find;
  5509. ReplaceStr := Replace;
  5510. FindFlags := (Options shl ffsOptions) or (Direction shl ffsDirection) or
  5511. {$ifdef TEST_REGEXP}
  5512. ((Options and ffmUseRegExpReplace) shl ffsUseRegExpReplace) or
  5513. {$endif TEST_REGEXP}
  5514. (Scope shl ffsScope) or (Origin shl ffsOrigin);
  5515. FindFlags := FindFlags or ffDoReplace;
  5516. if Re = cmYes then
  5517. FindFlags := FindFlags or ffReplaceAll;
  5518. SearchRunCount:=0;
  5519. if FindStr<>'' then
  5520. DoSearchReplace
  5521. else
  5522. EditorDialog(edSearchFailed,nil);
  5523. end;
  5524. end;
  5525. end;
  5526. procedure TCustomCodeEditor.DoSearchReplace;
  5527. var S: string;
  5528. DX,DY,P,Y,X: sw_integer;
  5529. Count: sw_integer;
  5530. Found,CanExit: boolean;
  5531. SForward,DoReplace,DoReplaceAll: boolean;
  5532. {$ifdef TEST_REGEXP}
  5533. UseRegExp : boolean;
  5534. RegExpEngine : TRegExprEngine;
  5535. RegExpFlags : tregexprflags;
  5536. regexpindex,regexplen : longint;
  5537. findstrpchar : pchar;
  5538. {$endif TEST_REGEXP}
  5539. LeftOK,RightOK: boolean;
  5540. FoundCount: sw_integer;
  5541. A,B: TPoint;
  5542. AreaStart,AreaEnd: TPoint;
  5543. CanReplace,Confirm: boolean;
  5544. Re: word;
  5545. IFindStr : string;
  5546. BT : BTable;
  5547. function ContainsText(const SubS:string;var S: string; Start: Sw_word): Sw_integer;
  5548. var
  5549. P: Sw_Integer;
  5550. begin
  5551. if Start<=0 then
  5552. P:=0
  5553. else
  5554. begin
  5555. if SForward then
  5556. begin
  5557. if Start>length(s) then
  5558. P:=0
  5559. else if FindFlags and ffCaseSensitive<>0 then
  5560. P:=BMFScan(S[Start],length(s)+1-Start,FindStr,Bt)+1
  5561. else
  5562. P:=BMFIScan(S[Start],length(s)+1-Start,IFindStr,Bt)+1;
  5563. if P>0 then
  5564. Inc(P,Start-1);
  5565. end
  5566. else
  5567. begin
  5568. if start>length(s) then
  5569. start:=length(s);
  5570. if FindFlags and ffCaseSensitive<>0 then
  5571. P:=BMBScan(S[1],Start,FindStr,Bt)+1
  5572. else
  5573. P:=BMBIScan(S[1],Start,IFindStr,Bt)+1;
  5574. end;
  5575. end;
  5576. ContainsText:=P;
  5577. end;
  5578. function InArea(X,Y: sw_integer): boolean;
  5579. begin
  5580. InArea:=((AreaStart.Y=Y) and (AreaStart.X<=X)) or
  5581. ((AreaStart.Y<Y) and (Y<AreaEnd.Y)) or
  5582. ((AreaEnd.Y=Y) and (X<=AreaEnd.X));
  5583. end;
  5584. var CurDY: sw_integer;
  5585. begin
  5586. if FindStr='' then
  5587. begin
  5588. Find;
  5589. { Find will call DoFindReplace at end again
  5590. so we need to exit directly now PM }
  5591. exit;
  5592. end;
  5593. Inc(SearchRunCount);
  5594. SForward:=(FindFlags and ffmDirection)=ffForward;
  5595. DoReplace:=(FindFlags and ffDoReplace)<>0;
  5596. Confirm:=(FindFlags and ffPromptOnReplace)<>0;
  5597. DoReplaceAll:=(FindFlags and ffReplaceAll)<>0;
  5598. {$ifdef TEST_REGEXP}
  5599. UseRegExp:=(FindFlags and ffUseRegExp)<>0;
  5600. if UseRegExp then
  5601. begin
  5602. if FindFlags and ffCaseSensitive<>0 then
  5603. RegExpFlags:=[ref_caseinsensitive]
  5604. else
  5605. RegExpFlags:=[];
  5606. getmem(findstrpchar,length(findstr)+1);
  5607. strpcopy(findstrpchar,findstr);
  5608. RegExpEngine:=GenerateRegExprEngine(findstrpchar,RegExpFlags);
  5609. strdispose(findstrpchar);
  5610. end;
  5611. {$endif TEST_REGEXP}
  5612. Count:=GetLineCount;
  5613. FoundCount:=0;
  5614. { Empty file ? }
  5615. if Count=0 then
  5616. begin
  5617. EditorDialog(edSearchFailed,nil);
  5618. exit;
  5619. end;
  5620. if SForward then
  5621. DY:=1
  5622. else
  5623. DY:=-1;
  5624. DX:=DY;
  5625. if FindStr<>'' then
  5626. PushInfo('Looking for "'+FindStr+'"');
  5627. if (FindFlags and ffmScope)=ffGlobal then
  5628. begin
  5629. AreaStart.X:=0;
  5630. AreaStart.Y:=0;
  5631. AreaEnd.X:=length(GetDisplayText(Count-1));
  5632. AreaEnd.Y:=Count-1;
  5633. end
  5634. else
  5635. begin
  5636. AreaStart:=SelStart;
  5637. AreaEnd:=SelEnd;
  5638. end;
  5639. X:=CurPos.X-DX;
  5640. Y:=CurPos.Y;;
  5641. if SearchRunCount=1 then
  5642. if (FindFlags and ffmOrigin)=ffEntireScope then
  5643. if SForward then
  5644. begin
  5645. X:=AreaStart.X-1;
  5646. Y:=AreaStart.Y;
  5647. end
  5648. else
  5649. begin
  5650. X:=AreaEnd.X+1;
  5651. Y:=AreaEnd.Y;
  5652. end;
  5653. if FindFlags and ffCaseSensitive<>0 then
  5654. begin
  5655. if SForward then
  5656. BMFMakeTable(FindStr,bt)
  5657. else
  5658. BMBMakeTable(FindStr,bt);
  5659. end
  5660. else
  5661. begin
  5662. IFindStr:=Upper(FindStr);
  5663. if SForward then
  5664. BMFMakeTable(IFindStr,bt)
  5665. else
  5666. BMBMakeTable(IFindStr,bt);
  5667. end;
  5668. inc(X,DX);
  5669. CanExit:=false;
  5670. if (DoReplace=false) or ((Confirm=false) and (Owner<>nil)) then
  5671. Owner^.Lock;
  5672. if InArea(X,Y) then
  5673. repeat
  5674. CurDY:=DY;
  5675. S:=GetDisplayText(Y);
  5676. {$ifdef TEST_REGEXP}
  5677. if UseRegExp then
  5678. begin
  5679. getmem(findstrpchar,length(Copy(S,X+1,high(S)))+1);
  5680. strpcopy(findstrpchar,Copy(S,X+1,high(S)));
  5681. { If start of line is required do check other positions PM }
  5682. if (FindStr[1]='^') and (X<>0) then
  5683. Found:=false
  5684. else
  5685. Found:=RegExprPos(RegExpEngine,findstrpchar,regexpindex,regexplen);
  5686. strdispose(findstrpchar);
  5687. P:=regexpindex+X+1;
  5688. end
  5689. else
  5690. {$endif TEST_REGEXP}
  5691. begin
  5692. P:=ContainsText(FindStr,S,X+1);
  5693. Found:=P<>0;
  5694. end;
  5695. if Found then
  5696. begin
  5697. A.X:=P-1;
  5698. A.Y:=Y;
  5699. B.Y:=Y;
  5700. {$ifdef TEST_REGEXP}
  5701. if UseRegExp then
  5702. B.X:=A.X+regexplen
  5703. else
  5704. {$endif TEST_REGEXP}
  5705. B.X:=A.X+length(FindStr);
  5706. end;
  5707. Found:=Found and InArea(A.X,A.Y);
  5708. if Found and ((FindFlags and ffWholeWordsOnly)<>0) then
  5709. begin
  5710. LeftOK:=(A.X<=0) or (not( (S[A.X] in AlphaChars) or (S[A.X] in NumberChars) ));
  5711. RightOK:=(B.X>=length(S)) or (not( (S[B.X+1] in AlphaChars) or (S[B.X+1] in NumberChars) ));
  5712. Found:=LeftOK and RightOK;
  5713. if Found=false then
  5714. begin
  5715. CurDY:=0;
  5716. X:=B.X+1;
  5717. end;
  5718. end;
  5719. if Found then
  5720. Inc(FoundCount);
  5721. if Found then
  5722. begin
  5723. Lock;
  5724. if SForward then
  5725. SetCurPtr(B.X,B.Y)
  5726. else
  5727. SetCurPtr(A.X,A.Y);
  5728. TrackCursor(true);
  5729. SetHighlight(A,B);
  5730. UnLock;
  5731. CurDY:=0;
  5732. if (DoReplace=false) then
  5733. begin
  5734. CanExit:=true;
  5735. If SForward then
  5736. begin
  5737. X:=B.X;
  5738. Y:=B.Y;
  5739. end
  5740. else
  5741. begin
  5742. X:=A.X;
  5743. Y:=A.Y;
  5744. end;
  5745. end
  5746. else
  5747. begin
  5748. if Confirm=false then CanReplace:=true else
  5749. begin
  5750. Re:=EditorDialog(edReplacePrompt,@CurPos);
  5751. case Re of
  5752. cmYes :
  5753. CanReplace:=true;
  5754. cmNo :
  5755. CanReplace:=false;
  5756. else {cmCancel}
  5757. begin
  5758. CanReplace:=false;
  5759. CanExit:=true;
  5760. end;
  5761. end;
  5762. end;
  5763. if CanReplace then
  5764. begin
  5765. Lock;
  5766. SetSelection(A,B);
  5767. DelSelect;
  5768. InsertText(ReplaceStr);
  5769. if SForward then
  5770. begin
  5771. X:=CurPos.X;
  5772. Y:=CurPos.Y;
  5773. end
  5774. else
  5775. begin
  5776. X:=A.X;
  5777. Y:=A.Y;
  5778. end;
  5779. UnLock;
  5780. end
  5781. else
  5782. begin
  5783. If SForward then
  5784. begin
  5785. X:=B.X;
  5786. Y:=B.Y;
  5787. end
  5788. else
  5789. begin
  5790. X:=A.X;
  5791. Y:=A.Y;
  5792. end;
  5793. end;
  5794. if (DoReplaceAll=false) then
  5795. CanExit:=true;
  5796. end;
  5797. end;
  5798. if (CanExit=false) and (CurDY<>0) then
  5799. begin
  5800. inc(Y,CurDY);
  5801. if SForward then
  5802. X:=0
  5803. else
  5804. X:=254;
  5805. CanExit:=(Y>=Count) or (Y<0);
  5806. end;
  5807. if not CanExit then
  5808. CanExit:=not InArea(X,Y);
  5809. until CanExit;
  5810. if (FoundCount=0) or (DoReplace) then
  5811. SetHighlight(CurPos,CurPos);
  5812. if (DoReplace=false) or ((Confirm=false) and (Owner<>nil)) then
  5813. Owner^.UnLock;
  5814. {if (DoReplace=false) or (Confirm=false) then
  5815. UnLock;}
  5816. if (FoundCount=0) then
  5817. EditorDialog(edSearchFailed,nil);
  5818. if FindStr<>'' then
  5819. PopInfo;
  5820. {$ifdef TEST_REGEXP}
  5821. if UseRegExp then
  5822. DestroyRegExprEngine(RegExpEngine);
  5823. {$endif TEST_REGEXP}
  5824. if (FindFlags and ffmScope)=ffSelectedText then
  5825. { restore selection PM }
  5826. begin
  5827. SetSelection(AreaStart,AreaEnd);
  5828. end;
  5829. end;
  5830. function TCustomCodeEditor.GetInsertMode: boolean;
  5831. begin
  5832. GetInsertMode:=(GetFlags and efInsertMode)<>0;
  5833. end;
  5834. procedure TCustomCodeEditor.SetInsertMode(InsertMode: boolean);
  5835. begin
  5836. if InsertMode then
  5837. SetFlags(GetFlags or efInsertMode)
  5838. else
  5839. SetFlags(GetFlags and (not efInsertMode));
  5840. DrawCursor;
  5841. end;
  5842. { there is a problem with ShiftDel here
  5843. because GetShitState tells to extend the
  5844. selection which gives wrong results (PM) }
  5845. function TCustomCodeEditor.ShouldExtend: boolean;
  5846. var ShiftInEvent: boolean;
  5847. begin
  5848. ShiftInEvent:=false;
  5849. if Assigned(CurEvent) then
  5850. if CurEvent^.What=evKeyDown then
  5851. ShiftInEvent:=((CurEvent^.KeyShift and kbShift)<>0);
  5852. ShouldExtend:=ShiftInEvent and
  5853. not DontConsiderShiftState;
  5854. end;
  5855. procedure TCustomCodeEditor.SetCurPtr(X,Y: sw_integer);
  5856. var OldPos{,OldSEnd,OldSStart}: TPoint;
  5857. Extended: boolean;
  5858. F: PFold;
  5859. begin
  5860. Lock;
  5861. X:=Max(0,Min(MaxLineLength+1,X));
  5862. Y:=Max(0,Min(GetLineCount-1,Y));
  5863. OldPos:=CurPos;
  5864. { OldSEnd:=SelEnd;
  5865. OldSStart:=SelStart;}
  5866. CurPos.X:=X;
  5867. CurPos.Y:=Y;
  5868. TrackCursor(false);
  5869. if not IsLineVisible(CurPos.Y) then
  5870. begin
  5871. F:=GetLineFold(CurPos.Y);
  5872. if Assigned(F) then
  5873. F^.Collapse(false);
  5874. end;
  5875. if (NoSelect=false) and (ShouldExtend) then
  5876. begin
  5877. CheckSels;
  5878. Extended:=false;
  5879. if PointOfs(OldPos)=PointOfs(SelStart) then
  5880. begin SetSelection(CurPos,SelEnd); Extended:=true; end;
  5881. CheckSels;
  5882. if Extended=false then
  5883. if PointOfs(OldPos)=PointOfs(SelEnd) then
  5884. begin
  5885. if ValidBlock=false then
  5886. SetSelection(CurPos,CurPos);
  5887. SetSelection(SelStart,CurPos); Extended:=true;
  5888. end;
  5889. CheckSels;
  5890. if (Extended=false) then
  5891. if PointOfs(OldPos)<=PointOfs(CurPos)
  5892. then begin SetSelection(OldPos,CurPos); Extended:=true; end
  5893. else begin SetSelection(CurPos,OldPos); Extended:=true; end;
  5894. DrawView;
  5895. end else
  5896. if not IsFlagSet(efPersistentBlocks) then
  5897. begin HideSelect; DrawView; end;
  5898. { if PointOfs(SelStart)=PointOfs(SelEnd) then
  5899. SetSelection(CurPos,CurPos);}
  5900. if (GetFlags and (efHighlightColumn+efHighlightRow))<>0 then
  5901. DrawView;
  5902. if ((CurPos.X<>OldPos.X) or (CurPos.Y<>OldPos.Y)) and
  5903. ((Highlight.A.X<>HighLight.B.X) or (Highlight.A.Y<>HighLight.B.Y)) then
  5904. HideHighlight;
  5905. if (OldPos.Y<>CurPos.Y) and (0<=OldPos.Y) and (OldPos.Y<GetLineCount) then
  5906. SetLineText(OldPos.Y,RTrim(GetLineText(OldPos.Y),not IsFlagSet(efUseTabCharacters)));
  5907. if ((CurPos.X<>OldPos.X) or (CurPos.Y<>OldPos.Y)) and (GetErrorMessage<>'') then
  5908. SetErrorMessage('');
  5909. { if ((CurPos.X<>OldPos.X) or (CurPos.Y<>OldPos.Y)) and (HighlightRow<>-1) then
  5910. SetHighlightRow(-1);}
  5911. if ((CurPos.X<>OldPos.X) or (CurPos.Y<>OldPos.Y)) then
  5912. AddAction(eaMoveCursor,OldPos,CurPos,'');
  5913. if ((CurPos.X<>OldPos.X) or (CurPos.Y<>OldPos.Y)) then
  5914. PositionChanged;{UpdateIndicator;}
  5915. UnLock;
  5916. end;
  5917. procedure TCustomCodeEditor.CheckSels;
  5918. begin
  5919. if (SelStart.Y>SelEnd.Y) or
  5920. ( (SelStart.Y=SelEnd.Y) and (SelStart.X>SelEnd.X) ) then
  5921. SetSelection(SelEnd,SelStart);
  5922. end;
  5923. procedure TCustomCodeEditor.CodeCompleteApply;
  5924. var S: string;
  5925. I: integer;
  5926. begin
  5927. Lock;
  5928. { here should be some kind or "mark" or "break" inserted in the Undo
  5929. information, so activating it "undoes" only the completition first and
  5930. doesn't delete the complete word at once... - Gabor }
  5931. S:=GetCodeCompleteFrag;
  5932. SetCurPtr(CurPos.X-length(S),CurPos.Y);
  5933. for I:=1 to length(S) do
  5934. DelChar;
  5935. S:=GetCodeCompleteWord;
  5936. for I:=1 to length(S) do
  5937. AddChar(S[I]);
  5938. UnLock;
  5939. SetCompleteState(csInactive);
  5940. end;
  5941. procedure TCustomCodeEditor.CodeCompleteCancel;
  5942. begin
  5943. SetCompleteState(csDenied);
  5944. end;
  5945. procedure TCustomCodeEditor.CodeCompleteCheck;
  5946. var Line: string;
  5947. X: sw_integer;
  5948. CurWord,NewWord: string;
  5949. begin
  5950. SetCodeCompleteFrag('');
  5951. if (not IsFlagSet(efCodeComplete)) or (IsReadOnly=true) then Exit;
  5952. Lock;
  5953. Line:=GetDisplayText(CurPos.Y);
  5954. X:=CurPos.X; CurWord:='';
  5955. if X<=length(Line) then
  5956. while (X>0) and (Line[X] in (NumberChars+AlphaChars)) do
  5957. begin
  5958. CurWord:=Line[X]+CurWord;
  5959. Dec(X);
  5960. end;
  5961. if (length(CurWord)>=CodeCompleteMinLen) and CompleteCodeWord(CurWord,NewWord) then
  5962. begin
  5963. SetCodeCompleteFrag(CurWord);
  5964. SetCodeCompleteWord(NewWord);
  5965. end
  5966. else
  5967. ClearCodeCompleteWord;
  5968. UnLock;
  5969. end;
  5970. function TCustomCodeEditor.GetCodeCompleteFrag: string;
  5971. begin
  5972. { Abstract }
  5973. GetCodeCompleteFrag:='';
  5974. end;
  5975. procedure TCustomCodeEditor.SetCodeCompleteFrag(const S: string);
  5976. begin
  5977. { Abstract }
  5978. end;
  5979. procedure TCustomCodeEditor.DrawLines(FirstLine: sw_integer);
  5980. begin
  5981. if FirstLine>=(Delta.Y+Size.Y) then Exit; { falls outside of the screen }
  5982. DrawView;
  5983. end;
  5984. procedure TCustomCodeEditor.HideHighlight;
  5985. begin
  5986. SetHighlight(CurPos,CurPos);
  5987. end;
  5988. procedure TCustomCodeEditor.GetSelectionArea(var StartP,EndP: TPoint);
  5989. begin
  5990. StartP:=SelStart; EndP:=SelEnd;
  5991. if EndP.X=0 then
  5992. begin
  5993. Dec(EndP.Y);
  5994. EndP.X:=length(GetDisplayText(EndP.Y))-1;
  5995. end
  5996. else
  5997. Dec(EndP.X);
  5998. end;
  5999. function TCustomCodeEditor.ValidBlock: boolean;
  6000. begin
  6001. ValidBlock:=(SelStart.X<>SelEnd.X) or (SelStart.Y<>SelEnd.Y);
  6002. end;
  6003. procedure TCustomCodeEditor.SetSelection(A, B: TPoint);
  6004. var WV: boolean;
  6005. OS,OE: TPoint;
  6006. begin
  6007. WV:=ValidBlock;
  6008. OS:=SelStart; OE:=SelEnd;
  6009. SelStart:=A; SelEnd:=B;
  6010. if (WV=false) and (ValidBlock=false) then { do nothing } else
  6011. if (OS.X<>SelStart.X) or (OS.Y<>SelStart.Y) or
  6012. (OE.X<>SelEnd.X) or (OE.Y<>SelEnd.Y) then
  6013. SelectionChanged;
  6014. end;
  6015. procedure TCustomCodeEditor.SetHighlight(A, B: TPoint);
  6016. begin
  6017. Highlight.A:=A; Highlight.B:=B;
  6018. HighlightChanged;
  6019. end;
  6020. {procedure TCustomCodeEditor.SetHighlightRow(Row: sw_integer);
  6021. begin
  6022. HighlightRow:=Row;
  6023. DrawView;
  6024. end;}
  6025. {procedure TCodeEditor.SetDebuggerRow(Row: sw_integer);
  6026. begin
  6027. DebuggerRow:=Row;
  6028. DrawView;
  6029. end;}
  6030. procedure TCustomCodeEditor.SelectAll(Enable: boolean);
  6031. var A,B: TPoint;
  6032. begin
  6033. if (Enable=false) or (GetLineCount=0) then
  6034. begin A:=CurPos; B:=CurPos end
  6035. else
  6036. begin
  6037. A.X:=0; A.Y:=0;
  6038. { B.Y:=GetLineCount-1;
  6039. B.X:=length(GetLineText(B.Y));}
  6040. B.Y:=GetLineCount; B.X:=0;
  6041. end;
  6042. SetSelection(A,B);
  6043. DrawView;
  6044. end;
  6045. procedure TCustomCodeEditor.SelectionChanged;
  6046. var Enable,CanPaste: boolean;
  6047. begin
  6048. if GetLineCount=0 then
  6049. begin
  6050. SelStart.X:=0; SelStart.Y:=0; SelEnd:=SelStart;
  6051. end
  6052. else
  6053. if SelEnd.Y>GetLineCount-1 then
  6054. if (SelEnd.Y<>GetLineCount) or (SelEnd.X<>0) then
  6055. begin
  6056. SelEnd.Y:=GetLineCount-1;
  6057. SelEnd.X:=length(GetDisplayText(SelEnd.Y));
  6058. end;
  6059. Enable:=((SelStart.X<>SelEnd.X) or (SelStart.Y<>SelEnd.Y)) and (Clipboard<>nil);
  6060. SetCmdState(ToClipCmds,Enable and (Clipboard<>@Self));
  6061. SetCmdState(NulClipCmds,Enable);
  6062. CanPaste:=(Clipboard<>nil) and ((Clipboard^.SelStart.X<>Clipboard^.SelEnd.X) or
  6063. (Clipboard^.SelStart.Y<>Clipboard^.SelEnd.Y));
  6064. SetCmdState(FromClipCmds,CanPaste and (Clipboard<>@Self));
  6065. {$ifdef WinClipSupported}
  6066. SetCmdState(FromWinClipCmds,GetTextWinClipboardSize>0);
  6067. {$endif WinClipSupported}
  6068. SetCmdState(UndoCmd,(GetUndoActionCount>0));
  6069. SetCmdState(RedoCmd,(GetRedoActionCount>0));
  6070. Message(Application,evBroadcast,cmCommandSetChanged,nil);
  6071. DrawView;
  6072. end;
  6073. procedure TCustomCodeEditor.HighlightChanged;
  6074. begin
  6075. DrawView;
  6076. end;
  6077. procedure TCustomCodeEditor.SetState(AState: Word; Enable: Boolean);
  6078. procedure ShowSBar(SBar: PScrollBar);
  6079. begin
  6080. if Assigned(SBar) and (SBar^.GetState(sfVisible)=false) then
  6081. SBar^.Show;
  6082. end;
  6083. begin
  6084. inherited SetState(AState,Enable);
  6085. if AlwaysShowScrollBars then
  6086. begin
  6087. ShowSBar(HScrollBar);
  6088. ShowSBar(VScrollBar);
  6089. end;
  6090. if (AState and (sfActive+sfSelected+sfFocused))<>0 then
  6091. begin
  6092. SelectionChanged;
  6093. if ((State and sfFocused)=0) and (GetCompleteState=csOffering) then
  6094. ClearCodeCompleteWord;
  6095. end;
  6096. end;
  6097. function TCustomCodeEditor.GetPalette: PPalette;
  6098. const P: string[length(CEditor)] = CEditor;
  6099. begin
  6100. GetPalette:=@P;
  6101. end;
  6102. function TCustomCodeEditorCore.LoadFromStream(Editor: PCustomCodeEditor; Stream: PStream): boolean;
  6103. var S: string;
  6104. AllLinesComplete,LineComplete,hasCR,OK: boolean;
  6105. begin
  6106. DeleteAllLines;
  6107. ChangedLine:=-1;
  6108. AllLinesComplete:=true;
  6109. OK:=(Stream^.Status=stOK);
  6110. if eofstream(Stream) then
  6111. AddLine('')
  6112. else
  6113. begin
  6114. while OK and (eofstream(Stream)=false) and (GetLineCount<MaxLineCount) do
  6115. begin
  6116. ReadlnFromStream(Stream,S,LineComplete,hasCR);
  6117. AllLinesComplete:=AllLinesComplete and LineComplete;
  6118. OK:=OK and (Stream^.Status=stOK);
  6119. if OK then AddLine(S);
  6120. if not LineComplete and (ChangedLine=-1) then
  6121. ChangedLine:=GetLineCount;
  6122. end;
  6123. { Do not remove the final newline if it exists PM }
  6124. if hasCR then
  6125. AddLine('');
  6126. end;
  6127. LimitsChanged;
  6128. if not AllLinesComplete then
  6129. SetModified(true);
  6130. if (GetLineCount=MaxLineCount) and not eofstream(stream) then
  6131. EditorDialog(edTooManyLines,nil);
  6132. LoadFromStream:=OK;
  6133. end;
  6134. function TCustomCodeEditorCore.SaveAreaToStream(Editor: PCustomCodeEditor; Stream: PStream; StartP,EndP: TPoint): boolean;
  6135. var S: string;
  6136. OK: boolean;
  6137. Line: Sw_integer;
  6138. begin
  6139. if EndP.X=0 then
  6140. begin
  6141. if EndP.Y>0 then
  6142. begin
  6143. EndP.X:=length(GetDisplayText(EndP.Y));
  6144. end
  6145. else
  6146. EndP.X:=0;
  6147. end
  6148. else
  6149. Dec(EndP.X);
  6150. OK:=(Stream^.Status=stOK); Line:=StartP.Y;
  6151. while OK and (Line<=EndP.Y) and (Line<GetLineCount) do
  6152. begin
  6153. S:=GetLineText(Line);
  6154. { Remove all traling spaces PM }
  6155. if not Editor^.IsFlagSet(efKeepTrailingSpaces) then
  6156. While (Length(S)>0) and (S[Length(S)]=' ') do
  6157. Dec(S[0]);
  6158. { if FlagSet(efUseTabCharacters) then
  6159. S:=CompressUsingTabs(S,TabSize);
  6160. }
  6161. if Line=EndP.Y then S:=copy(S,1,LinePosToCharIdx(Line,EndP.X));
  6162. if Line=StartP.Y then S:=copy(S,LinePosToCharIdx(Line,StartP.X),High(S));
  6163. Stream^.Write(S[1],length(S));
  6164. if Line<EndP.Y then
  6165. Stream^.Write(EOL[1],length(EOL));
  6166. Inc(Line);
  6167. OK:=OK and (Stream^.Status=stOK);
  6168. end;
  6169. SaveAreaToStream:=OK;
  6170. end;
  6171. constructor TEditorAction.init(act:byte; StartP,EndP:TPoint;Txt:String);
  6172. begin
  6173. Action:=act;
  6174. StartPos:=StartP;
  6175. EndPos:=EndP;
  6176. Text:=NewStr(txt);
  6177. ActionCount:=0;
  6178. IsGrouped:=false;
  6179. end;
  6180. constructor TEditorAction.init_group(act:byte);
  6181. begin
  6182. Action:=act;
  6183. ActionCount:=0;
  6184. IsGrouped:=true;
  6185. end;
  6186. function TEditorAction.Is_grouped_action : boolean;
  6187. begin
  6188. Is_grouped_action:=IsGrouped;
  6189. end;
  6190. destructor TEditorAction.done;
  6191. begin
  6192. DisposeStr(Text);
  6193. end;
  6194. function TEditorActionCollection.At(Idx : sw_integer) : PEditorAction;
  6195. begin
  6196. At:=PEditorAction(Inherited At(Idx));
  6197. end;
  6198. procedure TEditorInputLine.HandleEvent(var Event : TEvent);
  6199. var
  6200. s : string;
  6201. i : longint;
  6202. begin
  6203. If (Event.What=evKeyDown) and
  6204. (Event.KeyCode=kbRight) and
  6205. (CurPos = Length(Data^)) and
  6206. Assigned(FindReplaceEditor) then
  6207. Begin
  6208. s:=FindReplaceEditor^.GetDisplayText(FindReplaceEditor^.CurPos.Y);
  6209. s:=Copy(s,FindReplaceEditor^.CurPos.X + 1 -length(Data^),high(s));
  6210. i:=pos(Data^,s);
  6211. if i>0 then
  6212. begin
  6213. s:=Data^+s[i+length(Data^)];
  6214. If not assigned(validator) or
  6215. Validator^.IsValidInput(s,False) then
  6216. Begin
  6217. Event.CharCode:=s[length(s)];
  6218. Event.Scancode:=0;
  6219. Inherited HandleEvent(Event);
  6220. End;
  6221. end;
  6222. End
  6223. else
  6224. Inherited HandleEvent(Event);
  6225. end;
  6226. function CreateFindDialog: PDialog;
  6227. var R,R1,R2: TRect;
  6228. D: PDialog;
  6229. IL1: PEditorInputLine;
  6230. Control : PView;
  6231. CB1: PCheckBoxes;
  6232. RB1,RB2,RB3: PRadioButtons;
  6233. begin
  6234. R.Assign(0,0,56,15);
  6235. New(D, Init(R, dialog_find));
  6236. with D^ do
  6237. begin
  6238. Options:=Options or ofCentered;
  6239. GetExtent(R); R.Grow(-3,-2);
  6240. R1.Copy(R); R1.B.X:=17; R1.B.Y:=R1.A.Y+1;
  6241. R2.Copy(R); R2.B.X:=R2.B.X-3;R2.A.X:=17; R2.B.Y:=R2.A.Y+1;
  6242. New(IL1, Init(R2, FindStrSize));
  6243. IL1^.Data^:=FindStr;
  6244. Insert(IL1);
  6245. Insert(New(PLabel, Init(R1, label_find_texttofind, IL1)));
  6246. R1.Assign(R2.B.X, R2.A.Y, R2.B.X+3, R2.B.Y);
  6247. Control := New(PHistory, Init(R1, IL1, TextFindId));
  6248. Insert(Control);
  6249. 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;
  6250. R2.Copy(R1); R2.Move(0,1);
  6251. R2.B.Y:=R2.A.Y+{$ifdef TEST_REGEXP}3{$else}2{$endif};
  6252. New(CB1, Init(R2,
  6253. NewSItem(label_find_casesensitive,
  6254. NewSItem(label_find_wholewordsonly,
  6255. {$ifdef TEST_REGEXP}
  6256. NewSItem(label_find_useregexp,
  6257. {$endif TEST_REGEXP}
  6258. nil)))){$ifdef TEST_REGEXP}){$endif TEST_REGEXP};
  6259. Insert(CB1);
  6260. Insert(New(PLabel, Init(R1, label_find_options, CB1)));
  6261. 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;
  6262. R2.Copy(R1); R2.Move(0,1); R2.B.Y:=R2.A.Y+2;
  6263. New(RB1, Init(R2,
  6264. NewSItem(label_find_forward,
  6265. NewSItem(label_find_backward,
  6266. nil))));
  6267. Insert(RB1);
  6268. Insert(New(PLabel, Init(R1, label_find_direction, RB1)));
  6269. 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;
  6270. R2.Copy(R1); R2.Move(0,1); R2.B.Y:=R2.A.Y+2;
  6271. New(RB2, Init(R2,
  6272. NewSItem(label_find_global,
  6273. NewSItem(label_find_selectedtext,
  6274. nil))));
  6275. Insert(RB2);
  6276. Insert(New(PLabel, Init(R1, label_find_scope, RB2)));
  6277. 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;
  6278. R2.Copy(R1); R2.Move(0,1); R2.B.Y:=R2.A.Y+2;
  6279. New(RB3, Init(R2,
  6280. NewSItem(label_find_fromcursor,
  6281. NewSItem(label_find_entirescope,
  6282. nil))));
  6283. Insert(RB3);
  6284. Insert(New(PLabel, Init(R1, label_find_origin, RB3)));
  6285. GetExtent(R); R.Grow(-13,-1); R.A.Y:=R.B.Y-2; R.B.X:=R.A.X+10;
  6286. Insert(New(PButton, Init(R, btn_OK, cmOK, bfDefault)));
  6287. R.Move(19,0);
  6288. Insert(New(PButton, Init(R, btn_Cancel, cmCancel, bfNormal)));
  6289. end;
  6290. IL1^.Select;
  6291. CreateFindDialog := D;
  6292. end;
  6293. function CreateReplaceDialog: PDialog;
  6294. var R,R1,R2: TRect;
  6295. D: PDialog;
  6296. Control : PView;
  6297. IL1,IL2: PInputLine;
  6298. CB1: PCheckBoxes;
  6299. RB1,RB2,RB3: PRadioButtons;
  6300. begin
  6301. R.Assign(0,0,56,18);
  6302. New(D, Init(R, dialog_replace));
  6303. with D^ do
  6304. begin
  6305. Options:=Options or ofCentered;
  6306. GetExtent(R); R.Grow(-3,-2);
  6307. R1.Copy(R); R1.B.X:=17; R1.B.Y:=R1.A.Y+1;
  6308. R2.Copy(R); R2.B.X:=R2.B.X-3;R2.A.X:=17; R2.B.Y:=R2.A.Y+1;
  6309. New(IL1, Init(R2, FindStrSize));
  6310. IL1^.Data^:=FindStr;
  6311. Insert(IL1);
  6312. Insert(New(PLabel, Init(R1, label_replace_texttofind, IL1)));
  6313. R1.Assign(R2.B.X, R2.A.Y, R2.B.X+3, R2.B.Y);
  6314. Control := New(PHistory, Init(R1, IL1, TextFindId));
  6315. Insert(Control);
  6316. R1.Copy(R); R1.Move(0,2); R1.B.X:=17; R1.B.Y:=R1.A.Y+1;
  6317. R2.Copy(R); R2.Move(0,2);R2.B.X:=R2.B.X-3;
  6318. R2.A.X:=17; R2.B.Y:=R2.A.Y+1;
  6319. New(IL2, Init(R2, FindStrSize));
  6320. IL2^.Data^:=ReplaceStr;
  6321. Insert(IL2);
  6322. Insert(New(PLabel, Init(R1, label_replace_newtext, IL2)));
  6323. R1.Assign(R2.B.X, R2.A.Y, R2.B.X+3, R2.B.Y);
  6324. Control := New(PHistory, Init(R1, IL2, TextReplaceId));
  6325. Insert(Control);
  6326. 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;
  6327. R2.Copy(R1); R2.Move(0,1);
  6328. R2.B.Y:=R2.A.Y+{$ifdef TEST_REGEXP}4{$else}3{$endif};
  6329. New(CB1, Init(R2,
  6330. NewSItem(label_replace_casesensitive,
  6331. NewSItem(label_replace_wholewordsonly,
  6332. NewSItem(label_replace_promptonreplace,
  6333. {$ifdef TEST_REGEXP}
  6334. NewSItem(label_find_useregexp,
  6335. {$endif TEST_REGEXP}
  6336. nil))))){$ifdef TEST_REGEXP}){$endif TEST_REGEXP};
  6337. Insert(CB1);
  6338. Insert(New(PLabel, Init(R1, label_replace_options, CB1)));
  6339. 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;
  6340. R2.Copy(R1); R2.Move(0,1); R2.B.Y:=R2.A.Y+2;
  6341. New(RB1, Init(R2,
  6342. NewSItem(label_replace_forward,
  6343. NewSItem(label_replace_backward,
  6344. nil))));
  6345. Insert(RB1);
  6346. Insert(New(PLabel, Init(R1, label_replace_direction, RB1)));
  6347. 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;
  6348. R2.Copy(R1); R2.Move(0,1); R2.B.Y:=R2.A.Y+2;
  6349. New(RB2, Init(R2,
  6350. NewSItem(label_replace_global,
  6351. NewSItem(label_replace_selectedtext,
  6352. nil))));
  6353. Insert(RB2);
  6354. Insert(New(PLabel, Init(R1, label_replace_scope, RB2)));
  6355. 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;
  6356. R2.Copy(R1); R2.Move(0,1); R2.B.Y:=R2.A.Y+2;
  6357. New(RB3, Init(R2,
  6358. NewSItem(label_replace_fromcursor,
  6359. NewSItem(label_replace_entirescope,
  6360. nil))));
  6361. Insert(RB3);
  6362. Insert(New(PLabel, Init(R1, label_replace_origin, RB3)));
  6363. GetExtent(R); R.Grow(-13,-1); R.A.Y:=R.B.Y-2; R.B.X:=R.A.X+10; R.Move(-10,0);
  6364. Insert(New(PButton, Init(R, btn_OK, cmOK, bfDefault)));
  6365. R.Move(11,0); R.B.X:=R.A.X+14;
  6366. Insert(New(PButton, Init(R, btn_replace_changeall, cmYes, bfNormal)));
  6367. R.Move(15,0); R.B.X:=R.A.X+10;
  6368. Insert(New(PButton, Init(R, btn_Cancel, cmCancel, bfNormal)));
  6369. end;
  6370. IL1^.Select;
  6371. CreateReplaceDialog := D;
  6372. end;
  6373. function CreateGotoLineDialog(Info: pointer): PDialog;
  6374. var D: PDialog;
  6375. R,R1,R2: TRect;
  6376. Control : PView;
  6377. IL: PInputLine;
  6378. begin
  6379. R.Assign(0,0,40,7);
  6380. New(D, Init(R, dialog_gotoline));
  6381. with D^ do
  6382. begin
  6383. Options:=Options or ofCentered;
  6384. GetExtent(R); R.Grow(-3,-2); R.B.Y:=R.A.Y+1;
  6385. R1.Copy(R); R1.B.X:=27; R2.Copy(R);
  6386. R2.B.X:=R2.B.X-3;R2.A.X:=27;
  6387. New(IL, Init(R2,5));
  6388. with TGotoLineDialogRec(Info^) do
  6389. IL^.SetValidator(New(PRangeValidator, Init(1, Lines)));
  6390. Insert(IL);
  6391. Insert(New(PLabel, Init(R1, label_gotoline_linenumber, IL)));
  6392. R1.Assign(R2.B.X, R2.A.Y, R2.B.X+3, R2.B.Y);
  6393. Control := New(PHistory, Init(R1, IL, GotoId));
  6394. Insert(Control);
  6395. GetExtent(R); R.Grow(-8,-1); R.A.Y:=R.B.Y-2; R.B.X:=R.A.X+10;
  6396. Insert(New(PButton, Init(R, btn_OK, cmOK, bfDefault)));
  6397. R.Move(15,0);
  6398. Insert(New(PButton, Init(R, btn_Cancel, cmCancel, bfNormal)));
  6399. end;
  6400. IL^.Select;
  6401. CreateGotoLineDialog:=D;
  6402. end;
  6403. function StdEditorDialog(Dialog: Integer; Info: Pointer): Word;
  6404. var
  6405. R: TRect;
  6406. T: TPoint;
  6407. Re: word;
  6408. Name: string;
  6409. DriveNumber : byte;
  6410. StoreDir,StoreDir2 : DirStr;
  6411. Title,DefExt: string;
  6412. AskOW: boolean;
  6413. begin
  6414. case Dialog of
  6415. edOutOfMemory:
  6416. StdEditorDialog := AdvMessageBox(msg_notenoughmemoryforthisoperation,
  6417. nil, mfInsertInApp+ mfError + mfOkButton);
  6418. edReadError:
  6419. StdEditorDialog := AdvMessageBox(msg_errorreadingfile,
  6420. @Info, mfInsertInApp+ mfError + mfOkButton);
  6421. edWriteError:
  6422. StdEditorDialog := AdvMessageBox(msg_errorwritingfile,
  6423. @Info, mfInsertInApp+ mfError + mfOkButton);
  6424. edSaveError:
  6425. StdEditorDialog := AdvMessageBox(msg_errorsavingfile,
  6426. @Info, mfInsertInApp+ mfError + mfOkButton);
  6427. edCreateError:
  6428. StdEditorDialog := AdvMessageBox(msg_errorcreatingfile,
  6429. @Info, mfInsertInApp+ mfError + mfOkButton);
  6430. edSaveModify:
  6431. StdEditorDialog := AdvMessageBox(msg_filehasbeenmodifiedsave,
  6432. @Info, mfInsertInApp+ mfInformation + mfYesNoCancel);
  6433. edSaveUntitled:
  6434. StdEditorDialog := AdvMessageBox(msg_saveuntitledfile,
  6435. nil, mfInsertInApp+ mfInformation + mfYesNoCancel);
  6436. edChangedOnloading:
  6437. StdEditorDialog := AdvMessageBox(msg_filehadtoolonglines,
  6438. Info, mfInsertInApp+ mfOKButton + mfInformation);
  6439. edFileOnDiskChanged:
  6440. StdEditorDialog := AdvMessageBox(msg_filewasmodified,
  6441. @info, mfInsertInApp+ mfInformation + mfYesNoCancel);
  6442. edReloadDiskmodifiedFile:
  6443. StdEditorDialog := AdvMessageBox(msg_reloaddiskmodifiedfile,
  6444. @info, mfInsertInApp+ mfInformation + mfYesNoCancel);
  6445. edReloadDiskAndIDEModifiedFile:
  6446. StdEditorDialog := AdvMessageBox(msg_reloaddiskandidemodifiedfile,
  6447. @info, mfInsertInApp+ mfInformation + mfYesNoCancel);
  6448. edSaveAs,edWriteBlock,edReadBlock:
  6449. begin
  6450. Name:=PString(Info)^;
  6451. GetDir(0,StoreDir);
  6452. DriveNumber:=0;
  6453. if (Length(FileDir)>1) and (FileDir[2]=':') then
  6454. begin
  6455. { does not assume that lowercase are greater then uppercase ! }
  6456. if (FileDir[1]>='a') and (FileDir[1]<='z') then
  6457. DriveNumber:=Ord(FileDir[1])-ord('a')+1
  6458. else
  6459. DriveNumber:=Ord(FileDir[1])-ord('A')+1;
  6460. GetDir(DriveNumber,StoreDir2);
  6461. {$ifndef FPC}
  6462. ChDir(Copy(FileDir,1,2));
  6463. { this sets InOutRes in win32 PM }
  6464. { is this bad? What about an EatIO? Gabor }
  6465. {$endif not FPC}
  6466. end;
  6467. if FileDir<>'' then
  6468. ChDir(TrimEndSlash(FileDir));
  6469. case Dialog of
  6470. edSaveAs :
  6471. begin
  6472. Title:=dialog_savefileas;
  6473. DefExt:='*'+DefaultSaveExt;
  6474. end;
  6475. edWriteBlock :
  6476. begin
  6477. Title:=dialog_writeblocktofile;
  6478. DefExt:='*.*';
  6479. end;
  6480. edReadBlock :
  6481. begin
  6482. Title:=dialog_readblockfromfile;
  6483. DefExt:='*.*';
  6484. end;
  6485. else begin Title:='???'; DefExt:=''; end;
  6486. end;
  6487. Re:=Application^.ExecuteDialog(New(PFileDialog, Init(DefExt,
  6488. Title, label_name, fdOkButton, FileId)), @Name);
  6489. case Dialog of
  6490. edSaveAs :
  6491. begin
  6492. if ExtOf(Name)='' then
  6493. Name:=Name+DefaultSaveExt;
  6494. AskOW:=(Name<>PString(Info)^);
  6495. end;
  6496. edWriteBlock :
  6497. begin
  6498. if ExtOf(Name)='' then
  6499. Name:=Name+DefaultSaveExt;
  6500. AskOW:=true;
  6501. end;
  6502. edReadBlock : AskOW:=false;
  6503. else AskOW:=true;
  6504. end;
  6505. if (Re<>cmCancel) and AskOW then
  6506. begin
  6507. FileDir:=DirOf(FExpand(Name));
  6508. if ExistsFile(Name) then
  6509. if EditorDialog(edReplaceFile,@Name)<>cmYes then
  6510. Re:=cmCancel;
  6511. end;
  6512. if DriveNumber<>0 then
  6513. ChDir(StoreDir2);
  6514. {$ifndef FPC}
  6515. if (Length(StoreDir)>1) and (StoreDir[2]=':') then
  6516. ChDir(Copy(StoreDir,1,2));
  6517. {$endif not FPC}
  6518. if StoreDir<>'' then
  6519. ChDir(TrimEndSlash(StoreDir));
  6520. if Re<>cmCancel then
  6521. PString(Info)^:=Name;
  6522. StdEditorDialog := Re;
  6523. end;
  6524. edGotoLine:
  6525. StdEditorDialog :=
  6526. Application^.ExecuteDialog(CreateGotoLineDialog(Info), Info);
  6527. edFind:
  6528. StdEditorDialog :=
  6529. Application^.ExecuteDialog(CreateFindDialog, Info);
  6530. edSearchFailed:
  6531. StdEditorDialog := AdvMessageBox(msg_searchstringnotfound,
  6532. nil, mfInsertInApp+ mfError + mfOkButton);
  6533. edReplace:
  6534. StdEditorDialog :=
  6535. Application^.ExecuteDialog(CreateReplaceDialog, Info);
  6536. edReplacePrompt:
  6537. begin
  6538. { Avoid placing the dialog on the same line as the cursor }
  6539. R.Assign(0, 1, 40, 8);
  6540. R.Move((Desktop^.Size.X - R.B.X) div 2, 0);
  6541. Desktop^.MakeGlobal(R.B, T);
  6542. Inc(T.Y);
  6543. if PPoint(Info)^.Y <= T.Y then
  6544. R.Move(0, Desktop^.Size.Y - R.B.Y - 2);
  6545. StdEditorDialog := AdvMessageBoxRect(R, msg_replacethisoccourence,
  6546. nil, mfInsertInApp+ mfYesNoCancel + mfInformation);
  6547. end;
  6548. edReplaceFile :
  6549. StdEditorDialog :=
  6550. AdvMessageBox(msg_fileexistsoverwrite,@Info,mfInsertInApp+mfConfirmation+
  6551. mfYesButton+mfNoButton);
  6552. end;
  6553. end;
  6554. procedure RegisterWEditor;
  6555. begin
  6556. {$ifndef NOOBJREG}
  6557. {$endif}
  6558. end;
  6559. END.
  6560. {
  6561. $Log$
  6562. Revision 1.14 2001-10-02 16:35:04 pierre
  6563. * get correct curosr position for fvision
  6564. Revision 1.13 2001/10/01 09:08:21 pierre
  6565. * fix hexadecimal number highlighting
  6566. Revision 1.12 2001/09/27 16:30:16 pierre
  6567. * fix Hexadecimal number highlighting
  6568. Revision 1.11 2001/09/25 22:45:09 pierre
  6569. * fix recognition of directives broken by last patch
  6570. Revision 1.10 2001/09/25 11:59:20 pierre
  6571. * fix comment highlight bugs from bug 1617
  6572. Revision 1.9 2001/09/17 22:54:09 pierre
  6573. + Line completion for Find/Replace dialogs
  6574. Revision 1.8 2001/09/17 21:30:26 pierre
  6575. * fix a bug in Find/Replace dialog about RegExp
  6576. Revision 1.7 2001/09/14 23:47:09 pierre
  6577. + more regexp, options now in Find/Replace dialogs
  6578. Revision 1.6 2001/09/13 16:11:34 pierre
  6579. + test code for regexpr use in find dialog
  6580. Revision 1.5 2001/09/12 09:31:42 pierre
  6581. * fix bug 1579
  6582. Revision 1.4 2001/09/04 22:58:58 pierre
  6583. * fix highlight for 'i:=1to'
  6584. Revision 1.3 2001/08/12 00:06:49 pierre
  6585. * better clipboard handling for files with tabs
  6586. Revision 1.2 2001/08/05 02:01:48 peter
  6587. * FVISION define to compile with fvision units
  6588. Revision 1.1 2001/08/04 11:30:25 peter
  6589. * ide works now with both compiler versions
  6590. Revision 1.1.2.37 2001/08/03 11:43:58 pierre
  6591. * Show Find Dialog if Ctrl-L is pressed but FindStr is empty
  6592. Revision 1.1.2.36 2001/06/07 16:41:13 jonas
  6593. * updated for stricter checking of @ for procvars
  6594. Revision 1.1.2.35 2001/05/09 15:39:42 pierre
  6595. * fix a problem for shortened files
  6596. Revision 1.1.2.34 2001/04/03 23:27:12 pierre
  6597. * make Ctrl-T BP compatible
  6598. Revision 1.1.2.33 2001/03/20 00:20:43 pierre
  6599. * fix some memory leaks + several small enhancements
  6600. Revision 1.1.2.32 2001/03/13 16:19:16 pierre
  6601. + syntax highligh in disassembly window
  6602. Revision 1.1.2.31 2001/03/12 17:34:57 pierre
  6603. + Disassembly window started
  6604. Revision 1.1.2.30 2001/03/06 22:04:53 pierre
  6605. * Avoid cursor updates when editor window is locked
  6606. Revision 1.1.2.29 2001/02/19 10:40:52 pierre
  6607. * Check for changed files after Running tool or shell
  6608. Revision 1.1.2.28 2001/02/05 12:58:26 pierre
  6609. * fix several Undo bugs
  6610. Revision 1.1.2.27 2001/01/14 22:11:23 peter
  6611. * fixed missing unlock that broke the helpwindow after compiling
  6612. a program
  6613. Revision 1.1.2.26 2001/01/07 22:33:20 peter
  6614. * fixed search in empty editor
  6615. Revision 1.1.2.25 2000/12/30 22:48:57 peter
  6616. * fixed delete and backspace with tabs, but tabsupport is still
  6617. not correct in other places
  6618. Revision 1.1.2.24 2000/12/14 08:37:51 pierre
  6619. * avoid unnecessary int64 calculation
  6620. Revision 1.1.2.23 2000/11/29 18:28:53 pierre
  6621. + add save to file capability for list boxes
  6622. Revision 1.1.2.22 2000/11/27 12:06:50 pierre
  6623. New bunch of Gabor fixes
  6624. Revision 1.1.2.21 2000/11/23 16:32:16 pierre
  6625. * avoid flickering for GotoLine
  6626. Revision 1.1.2.20 2000/11/22 17:13:00 pierre
  6627. * bug in DelToEndOfWord fixed
  6628. Revision 1.1.2.19 2000/11/22 16:09:43 pierre
  6629. * Ctrl-T now deletes from cursor to end of word
  6630. Revision 1.1.2.18 2000/11/21 16:10:41 pierre
  6631. * avoid selection extension for JumpMark
  6632. Revision 1.1.2.17 2000/11/14 23:41:32 pierre
  6633. * fix for bug 1234
  6634. Revision 1.1.2.16 2000/11/14 09:08:50 marco
  6635. * First batch IDE renamefest
  6636. Revision 1.1.2.15 2000/11/13 16:55:09 pierre
  6637. * multi space indent disabled
  6638. Revision 1.1.2.14 2000/11/06 17:19:58 pierre
  6639. * avoid eating of last carriage return
  6640. Revision 1.1.2.13 2000/11/03 15:49:26 pierre
  6641. * more Undo fixes
  6642. Revision 1.1.2.12 2000/11/03 13:31:33 pierre
  6643. + more Undo stuff and smarter indent/unindent
  6644. Revision 1.1.2.11 2000/10/31 08:12:45 pierre
  6645. * fix for bug 1161
  6646. Revision 1.1.2.10 2000/10/31 07:50:02 pierre
  6647. + efNoIndent to avoid any indentation
  6648. Revision 1.1.2.9 2000/10/26 00:02:40 pierre
  6649. * Undo improovments
  6650. Revision 1.1.2.8 2000/10/24 23:06:30 pierre
  6651. * some Undo/redo fixes
  6652. Revision 1.1.2.7 2000/10/20 13:40:34 pierre
  6653. * avoid crash if paste win clipboard on empty editor
  6654. Revision 1.1.2.6 2000/09/19 19:54:09 pierre
  6655. * fix for bug 1141 by Gabor
  6656. Revision 1.1.2.5 2000/09/18 13:20:55 pierre
  6657. New bunch of Gabor changes
  6658. Revision 1.1.2.4 2000/08/15 03:40:54 peter
  6659. [*] no more fatal exits when the IDE can't find the error file (containing
  6660. the redirected assembler/linker output) after compilation
  6661. [*] hidden windows are now added always at the end of the Window List
  6662. [*] TINIFile parsed entries encapsulated in string delimiters incorrectly
  6663. [*] selection was incorrectly adjusted when typing in overwrite mode
  6664. [*] the line wasn't expanded when it's end was reached in overw. mode
  6665. [*] the IDE now tries to locate source files also in the user specified
  6666. unit dirs (for ex. as a response to 'Open at cursor' (Ctrl+Enter) )
  6667. [*] 'Open at cursor' is now aware of the extension (if specified)
  6668. Revision 1.1.2.3 2000/07/20 11:02:16 michael
  6669. + Fixes from gabor. See fixes.txt
  6670. Revision 1.1.2.2 2000/07/18 05:50:22 michael
  6671. + Merged Gabors fixes
  6672. Revision 1.1.2.1 2000/07/15 21:30:06 pierre
  6673. * Do not consider ASM inside a string as a assembler statement start
  6674. * Add .pas extension to edWriteBlock if no extension is choosen
  6675. Revision 1.1 2000/07/13 09:48:37 michael
  6676. + Initial import
  6677. Revision 1.95 2000/06/22 09:07:13 pierre
  6678. * Gabor changes: see fixes.txt
  6679. Revision 1.94 2000/06/16 21:17:39 pierre
  6680. + TCustoCodeEditorCore.GetChangedLine
  6681. Revision 1.93 2000/06/16 08:50:43 pierre
  6682. + new bunch of Gabor's changes
  6683. Revision 1.92 2000/06/15 20:29:45 pierre
  6684. * avoid RTE 211 on Ctrl K W
  6685. Revision 1.91 2000/05/29 10:44:58 pierre
  6686. + New bunch of Gabor's changes: see fixes.txt
  6687. Revision 1.90 2000/05/17 11:58:26 pierre
  6688. * remove openbrace because of multiple comment level problem
  6689. Revision 1.89 2000/05/17 09:44:46 pierre
  6690. * fix the $ifdef inside a comment problem
  6691. Revision 1.88 2000/04/25 08:42:34 pierre
  6692. * New Gabor changes : see fixes.txt
  6693. Revision 1.87 2000/04/18 11:42:38 pierre
  6694. lot of Gabor changes : see fixes.txt
  6695. Revision 1.86 2000/03/23 21:36:19 pierre
  6696. * get correct position in indicator again
  6697. Revision 1.85 2000/03/21 23:17:47 pierre
  6698. + Gabor patch to add support for multiple windows
  6699. of same file
  6700. weditor has been splitted into weditor and wcedit units
  6701. Revision 1.84 2000/03/20 19:19:44 pierre
  6702. * LFN support in streams
  6703. Revision 1.83 2000/03/14 13:38:03 pierre
  6704. * max number of line changed and warning added
  6705. Revision 1.82 2000/03/02 22:33:36 pierre
  6706. * Grep improoved
  6707. Revision 1.81 2000/02/09 12:56:54 pierre
  6708. * fix for DelChar past end of line
  6709. Revision 1.80 2000/02/07 12:11:15 pierre
  6710. Gabors changes
  6711. Revision 1.79 2000/02/05 14:50:59 florian
  6712. * applied fix from Gabor regarding the limited line length of the clipboard
  6713. Revision 1.78 2000/01/28 22:20:04 pierre
  6714. * Test_partial_syntax released
  6715. Revision 1.77 2000/01/27 22:30:38 florian
  6716. * start of FPU window
  6717. * current executed line color has a higher priority then a breakpoint now
  6718. Revision 1.76 2000/01/25 00:12:23 pierre
  6719. * fix for Backspace Undo
  6720. Revision 1.75 2000/01/14 15:36:42 pierre
  6721. + GetShortFileName used for tcodeeditor file opening
  6722. Revision 1.74 2000/01/10 23:20:04 pierre
  6723. * problem with Paste solved
  6724. Revision 1.73 2000/01/10 13:25:46 pierre
  6725. + first partial syntax test
  6726. Revision 1.72 2000/01/07 00:19:30 pierre
  6727. * forgot CommentLineType check to see if we need to update format
  6728. on next line
  6729. * some changes for TEST_PARTIAL_SYNTAX still does notwork :(
  6730. Revision 1.71 2000/01/06 17:47:26 pierre
  6731. * avoid to resyntax whole source in unnecessary cases
  6732. Revision 1.70 2000/01/05 17:35:50 pierre
  6733. + Warning box if a line is cut at reading of file
  6734. this is done to avoid loosing completely long lines
  6735. * several TAB related changes
  6736. in particular do not remove or recombine TABs in makefiles
  6737. * fixes for ^KR and ^KW (the was an extra LF at end of
  6738. written block of disk and an error for starting X position
  6739. in SaveAreaToStream)
  6740. Revision 1.69 2000/01/05 00:37:34 pierre
  6741. * ^KC fix
  6742. * better Tab handling
  6743. Revision 1.68 2000/01/04 12:33:08 pierre
  6744. * reinserted version 1.66 lost changes
  6745. + CtrlT Undo works now !
  6746. Revision 1.67 2000/01/03 11:38:35 michael
  6747. Changes from Gabor
  6748. Revision 1.65 1999/12/08 16:02:46 pierre
  6749. * fix for bugs 746,748 and 750
  6750. Revision 1.64 1999/12/01 17:25:00 pierre
  6751. + check if file on disk was changed since load before overwriting
  6752. Revision 1.63 1999/11/22 17:34:08 pierre
  6753. * fix for form bug 634
  6754. Revision 1.62 1999/11/18 13:42:06 pierre
  6755. * Some more Undo stuff
  6756. Revision 1.61 1999/11/10 00:45:30 pierre
  6757. + groupd action started, not yet working
  6758. Revision 1.60 1999/11/05 13:49:13 pierre
  6759. * WinPaste depends on avalaible Clipboard data
  6760. Revision 1.59 1999/11/03 09:39:23 peter
  6761. * fixed uppercase filenames
  6762. * savetostream did twice a -1 on the linecount, so the lastline of a
  6763. file wasn't saved correctly
  6764. Revision 1.58 1999/10/28 15:14:22 pierre
  6765. * get it to compile with debug conditional
  6766. Revision 1.56 1999/10/27 13:32:58 pierre
  6767. * some more Undo Fixes
  6768. Revision 1.55 1999/10/27 10:46:19 pierre
  6769. * More Undo/Redo stuff
  6770. Revision 1.54 1999/10/25 16:49:05 pierre
  6771. + Undo/Redo by Visa Harvey (great thanks) inserted
  6772. (with some modifications)
  6773. Moves work correctly
  6774. Text insertion/deletion are still buggy !
  6775. * LinePosToCharIndex and reverse function changed to get more
  6776. sensible results, dependant code adapted
  6777. * several bug fixes
  6778. Revision 1.53 1999/10/14 10:21:48 pierre
  6779. * more tabs related problems fiwes
  6780. Revision 1.52 1999/10/12 23:35:18 pierre
  6781. + DelStart and SelectWord implemented
  6782. * AddChar(tab) now reacts correctly if efAutoIndent is set
  6783. Revision 1.51 1999/10/08 15:24:50 pierre
  6784. * InsertFrom bug (end of line wasdiscarded)
  6785. Revision 1.50 1999/09/28 23:44:13 pierre
  6786. * text insertion in middle of line was buggy
  6787. Revision 1.49 1999/09/23 16:33:30 pierre
  6788. * ^B^A now prints out the ascii 1 char
  6789. * In SearchReplace Several occurence of a pattern in the same line
  6790. should now be found correctly
  6791. Revision 1.48 1999/09/22 16:16:26 pierre
  6792. + added HistLists for several dialogs
  6793. Revision 1.47 1999/09/21 17:08:59 pierre
  6794. + Windows clipboard for win32
  6795. Revision 1.46 1999/09/13 16:24:44 peter
  6796. + clock
  6797. * backspace unident like tp7
  6798. Revision 1.45 1999/09/09 12:05:33 pierre
  6799. + Copy/Paste to Windows Clipboard
  6800. + efLeaveTrailingSpaces added to editor flags
  6801. (if not set then spaces at the end of a line are
  6802. removed on writing the file)
  6803. Revision 1.44 1999/08/27 15:07:44 pierre
  6804. + cmResetDebuggerRow
  6805. Revision 1.43 1999/08/24 22:04:35 pierre
  6806. + TCodeEditor.SetDebuggerRow
  6807. works like SetHighlightRow but is only disposed by a SetDebuggerRow(-1)
  6808. so the current stop point in debugging is not lost if
  6809. we move the cursor
  6810. Revision 1.42 1999/08/22 22:20:30 pierre
  6811. * selection extension bug removed, via oldEvent pointer in TCodeEditor.HandleEvent
  6812. Revision 1.41 1999/08/16 18:25:28 peter
  6813. * Adjusting the selection when the editor didn't contain any line.
  6814. * Reserved word recognition redesigned, but this didn't affect the overall
  6815. syntax highlight speed remarkably (at least not on my Amd-K6/350).
  6816. The syntax scanner loop is a bit slow but the main problem is the
  6817. recognition of special symbols. Switching off symbol processing boosts
  6818. the performance up to ca. 200%...
  6819. * The editor didn't allow copying (for ex to clipboard) of a single character
  6820. * 'File|Save as' caused permanently run-time error 3. Not any more now...
  6821. * Compiler Messages window (actually the whole desktop) did not act on any
  6822. keypress when compilation failed and thus the window remained visible
  6823. + Message windows are now closed upon pressing Esc
  6824. + At 'Run' the IDE checks whether any sources are modified, and recompiles
  6825. only when neccessary
  6826. + BlockRead and BlockWrite (Ctrl+K+R/W) implemented in TCodeEditor
  6827. + LineSelect (Ctrl+K+L) implemented
  6828. * The IDE had problems closing help windows before saving the desktop
  6829. Revision 1.40 1999/08/03 20:22:42 peter
  6830. + TTab acts now on Ctrl+Tab and Ctrl+Shift+Tab...
  6831. + Desktop saving should work now
  6832. - History saved
  6833. - Clipboard content saved
  6834. - Desktop saved
  6835. - Symbol info saved
  6836. * syntax-highlight bug fixed, which compared special keywords case sensitive
  6837. (for ex. 'asm' caused asm-highlighting, while 'ASM' didn't)
  6838. * with 'whole words only' set, the editor didn't found occourences of the
  6839. searched text, if the text appeared previously in the same line, but didn't
  6840. satisfied the 'whole-word' condition
  6841. * ^QB jumped to (SelStart.X,SelEnd.X) instead of (SelStart.X,SelStart.Y)
  6842. (ie. the beginning of the selection)
  6843. * when started typing in a new line, but not at the start (X=0) of it,
  6844. the editor inserted the text one character more to left as it should...
  6845. * TCodeEditor.HideSelection (Ctrl-K+H) didn't update the screen
  6846. * Shift shouldn't cause so much trouble in TCodeEditor now...
  6847. * Syntax highlight had problems recognizing a special symbol if it was
  6848. prefixed by another symbol character in the source text
  6849. * Auto-save also occours at Dos shell, Tool execution, etc. now...
  6850. Revision 1.39 1999/07/28 23:11:26 peter
  6851. * fixes from gabor
  6852. Revision 1.38 1999/07/12 13:14:24 pierre
  6853. * LineEnd bug corrected, now goes end of text even if selected
  6854. + Until Return for debugger
  6855. + Code for Quit inside GDB Window
  6856. Revision 1.37 1999/06/29 22:50:16 peter
  6857. * more fixes from gabor
  6858. Revision 1.36 1999/06/29 08:51:34 pierre
  6859. * lockflag problems fixed
  6860. Revision 1.35 1999/06/28 19:32:32 peter
  6861. * fixes from gabor
  6862. Revision 1.34 1999/06/28 15:58:07 pierre
  6863. * ShiftDel problem solved
  6864. Revision 1.33 1999/06/25 00:31:51 pierre
  6865. + FileDir remembers the last directory for Open and Save
  6866. Revision 1.32 1999/06/21 23:36:12 pierre
  6867. * Size for Cluster is word (TP compatibility)
  6868. Revision 1.31 1999/05/22 13:44:35 peter
  6869. * fixed couple of bugs
  6870. Revision 1.30 1999/04/15 08:58:10 peter
  6871. * syntax highlight fixes
  6872. * browser updates
  6873. Revision 1.29 1999/04/07 21:55:59 peter
  6874. + object support for browser
  6875. * html help fixes
  6876. * more desktop saving things
  6877. * NODEBUG directive to exclude debugger
  6878. Revision 1.28 1999/03/23 15:11:39 peter
  6879. * desktop saving things
  6880. * vesa mode
  6881. * preferences dialog
  6882. Revision 1.27 1999/03/08 14:58:17 peter
  6883. + prompt with dialogs for tools
  6884. Revision 1.26 1999/03/07 22:58:57 pierre
  6885. * FindRec needs longint for CheckBoxes
  6886. Revision 1.25 1999/03/05 17:39:39 pierre
  6887. * Actions item freeing
  6888. Revision 1.24 1999/03/03 16:45:07 pierre
  6889. * Actions were not dispose in TCodeEditor.Done
  6890. Revision 1.23 1999/03/01 15:42:10 peter
  6891. + Added dummy entries for functions not yet implemented
  6892. * MenuBar didn't update itself automatically on command-set changes
  6893. * Fixed Debugging/Profiling options dialog
  6894. * TCodeEditor converts spaces to tabs at save only if efUseTabChars is set
  6895. * efBackSpaceUnindents works correctly
  6896. + 'Messages' window implemented
  6897. + Added '$CAP MSG()' and '$CAP EDIT' to available tool-macros
  6898. + Added TP message-filter support (for ex. you can call GREP thru
  6899. GREP2MSG and view the result in the messages window - just like in TP)
  6900. * A 'var' was missing from the param-list of THelpFacility.TopicSearch,
  6901. so topic search didn't work...
  6902. * In FPHELP.PAS there were still context-variables defined as word instead
  6903. of THelpCtx
  6904. * StdStatusKeys() was missing from the statusdef for help windows
  6905. + Topic-title for index-table can be specified when adding a HTML-files
  6906. Revision 1.22 1999/02/22 02:15:25 peter
  6907. + default extension for save in the editor
  6908. + Separate Text to Find for the grep dialog
  6909. * fixed redir crash with tp7
  6910. Revision 1.21 1999/02/20 15:18:33 peter
  6911. + ctrl-c capture with confirm dialog
  6912. + ascii table in the tools menu
  6913. + heapviewer
  6914. * empty file fixed
  6915. * fixed callback routines in fpdebug to have far for tp7
  6916. Revision 1.20 1999/02/18 17:27:57 pierre
  6917. * find/replace dialogs need packed records !!
  6918. Revision 1.19 1999/02/18 13:44:36 peter
  6919. * search fixed
  6920. + backward search
  6921. * help fixes
  6922. * browser updates
  6923. Revision 1.18 1999/02/15 15:12:25 pierre
  6924. + TLine remembers Comment type
  6925. Revision 1.17 1999/02/15 09:32:58 pierre
  6926. * single line comment // fix : comments intermix still wrong !!
  6927. Revision 1.16 1999/02/11 19:07:26 pierre
  6928. * GDBWindow redesigned :
  6929. normal editor apart from
  6930. that any kbEnter will send the line (for begin to cursor)
  6931. to GDB command !
  6932. GDBWindow opened in Debugger Menu
  6933. still buggy :
  6934. -echo should not be present if at end of text
  6935. -GDBWindow becomes First after each step (I don't know why !)
  6936. Revision 1.15 1999/02/09 09:29:59 pierre
  6937. * avoid invisible characters in CombineColors
  6938. Revision 1.14 1999/02/05 13:51:45 peter
  6939. * unit name of FPSwitches -> FPSwitch which is easier to use
  6940. * some fixes for tp7 compiling
  6941. Revision 1.13 1999/02/05 13:22:43 pierre
  6942. * bug that caused crash for empty files
  6943. Revision 1.12 1999/02/05 12:04:56 pierre
  6944. + 'loose' centering for debugger
  6945. Revision 1.11 1999/02/04 17:19:26 peter
  6946. * linux fixes
  6947. Revision 1.10 1999/02/04 10:13:00 pierre
  6948. + GetCurrentWord (used in Find/Replace)
  6949. + DefUseTabsPattern (pattern forcing tabs to be kept)
  6950. used for all makefiles !!
  6951. Revision 1.9 1999/01/29 10:34:33 peter
  6952. + needobjdir,needlibdir
  6953. Revision 1.8 1999/01/21 11:54:31 peter
  6954. + tools menu
  6955. + speedsearch in symbolbrowser
  6956. * working run command
  6957. Revision 1.7 1999/01/14 21:41:17 peter
  6958. * use * as modified indicator
  6959. * fixed syntax highlighting
  6960. Revision 1.6 1999/01/12 14:29:44 peter
  6961. + Implemented still missing 'switch' entries in Options menu
  6962. + Pressing Ctrl-B sets ASCII mode in editor, after which keypresses (even
  6963. ones with ASCII < 32 ; entered with Alt+<###>) are interpreted always as
  6964. ASCII chars and inserted directly in the text.
  6965. + Added symbol browser
  6966. * splitted fp.pas to fpide.pas
  6967. Revision 1.5 1999/01/07 15:02:40 peter
  6968. * better tab support
  6969. Revision 1.4 1999/01/04 11:49:55 peter
  6970. * 'Use tab characters' now works correctly
  6971. + Syntax highlight now acts on File|Save As...
  6972. + Added a new class to syntax highlight: 'hex numbers'.
  6973. * There was something very wrong with the palette managment. Now fixed.
  6974. + Added output directory (-FE<xxx>) support to 'Directories' dialog...
  6975. * Fixed some possible bugs in Running/Compiling, and the compilation/run
  6976. process revised
  6977. Revision 1.2 1998/12/28 15:47:55 peter
  6978. + Added user screen support, display & window
  6979. + Implemented Editor,Mouse Options dialog
  6980. + Added location of .INI and .CFG file
  6981. + Option (INI) file managment implemented (see bottom of Options Menu)
  6982. + Switches updated
  6983. + Run program
  6984. Revision 1.4 1998/12/27 12:01:23 gabor
  6985. * efXXXX constants revised for BP compatibility
  6986. * fixed column and row highlighting (needs to rewrite default palette in the INI)
  6987. Revision 1.3 1998/12/22 10:39:54 peter
  6988. + options are now written/read
  6989. + find and replace routines
  6990. }