weditor.pas 210 KB

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