maxide.bmx 216 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830183118321833183418351836183718381839184018411842184318441845184618471848184918501851185218531854185518561857185818591860186118621863186418651866186718681869187018711872187318741875187618771878187918801881188218831884188518861887188818891890189118921893189418951896189718981899190019011902190319041905190619071908190919101911191219131914191519161917191819191920192119221923192419251926192719281929193019311932193319341935193619371938193919401941194219431944194519461947194819491950195119521953195419551956195719581959196019611962196319641965196619671968196919701971197219731974197519761977197819791980198119821983198419851986198719881989199019911992199319941995199619971998199920002001200220032004200520062007200820092010201120122013201420152016201720182019202020212022202320242025202620272028202920302031203220332034203520362037203820392040204120422043204420452046204720482049205020512052205320542055205620572058205920602061206220632064206520662067206820692070207120722073207420752076207720782079208020812082208320842085208620872088208920902091209220932094209520962097209820992100210121022103210421052106210721082109211021112112211321142115211621172118211921202121212221232124212521262127212821292130213121322133213421352136213721382139214021412142214321442145214621472148214921502151215221532154215521562157215821592160216121622163216421652166216721682169217021712172217321742175217621772178217921802181218221832184218521862187218821892190219121922193219421952196219721982199220022012202220322042205220622072208220922102211221222132214221522162217221822192220222122222223222422252226222722282229223022312232223322342235223622372238223922402241224222432244224522462247224822492250225122522253225422552256225722582259226022612262226322642265226622672268226922702271227222732274227522762277227822792280228122822283228422852286228722882289229022912292229322942295229622972298229923002301230223032304230523062307230823092310231123122313231423152316231723182319232023212322232323242325232623272328232923302331233223332334233523362337233823392340234123422343234423452346234723482349235023512352235323542355235623572358235923602361236223632364236523662367236823692370237123722373237423752376237723782379238023812382238323842385238623872388238923902391239223932394239523962397239823992400240124022403240424052406240724082409241024112412241324142415241624172418241924202421242224232424242524262427242824292430243124322433243424352436243724382439244024412442244324442445244624472448244924502451245224532454245524562457245824592460246124622463246424652466246724682469247024712472247324742475247624772478247924802481248224832484248524862487248824892490249124922493249424952496249724982499250025012502250325042505250625072508250925102511251225132514251525162517251825192520252125222523252425252526252725282529253025312532253325342535253625372538253925402541254225432544254525462547254825492550255125522553255425552556255725582559256025612562256325642565256625672568256925702571257225732574257525762577257825792580258125822583258425852586258725882589259025912592259325942595259625972598259926002601260226032604260526062607260826092610261126122613261426152616261726182619262026212622262326242625262626272628262926302631263226332634263526362637263826392640264126422643264426452646264726482649265026512652265326542655265626572658265926602661266226632664266526662667266826692670267126722673267426752676267726782679268026812682268326842685268626872688268926902691269226932694269526962697269826992700270127022703270427052706270727082709271027112712271327142715271627172718271927202721272227232724272527262727272827292730273127322733273427352736273727382739274027412742274327442745274627472748274927502751275227532754275527562757275827592760276127622763276427652766276727682769277027712772277327742775277627772778277927802781278227832784278527862787278827892790279127922793279427952796279727982799280028012802280328042805280628072808280928102811281228132814281528162817281828192820282128222823282428252826282728282829283028312832283328342835283628372838283928402841284228432844284528462847284828492850285128522853285428552856285728582859286028612862286328642865286628672868286928702871287228732874287528762877287828792880288128822883288428852886288728882889289028912892289328942895289628972898289929002901290229032904290529062907290829092910291129122913291429152916291729182919292029212922292329242925292629272928292929302931293229332934293529362937293829392940294129422943294429452946294729482949295029512952295329542955295629572958295929602961296229632964296529662967296829692970297129722973297429752976297729782979298029812982298329842985298629872988298929902991299229932994299529962997299829993000300130023003300430053006300730083009301030113012301330143015301630173018301930203021302230233024302530263027302830293030303130323033303430353036303730383039304030413042304330443045304630473048304930503051305230533054305530563057305830593060306130623063306430653066306730683069307030713072307330743075307630773078307930803081308230833084308530863087308830893090309130923093309430953096309730983099310031013102310331043105310631073108310931103111311231133114311531163117311831193120312131223123312431253126312731283129313031313132313331343135313631373138313931403141314231433144314531463147314831493150315131523153315431553156315731583159316031613162316331643165316631673168316931703171317231733174317531763177317831793180318131823183318431853186318731883189319031913192319331943195319631973198319932003201320232033204320532063207320832093210321132123213321432153216321732183219322032213222322332243225322632273228322932303231323232333234323532363237323832393240324132423243324432453246324732483249325032513252325332543255325632573258325932603261326232633264326532663267326832693270327132723273327432753276327732783279328032813282328332843285328632873288328932903291329232933294329532963297329832993300330133023303330433053306330733083309331033113312331333143315331633173318331933203321332233233324332533263327332833293330333133323333333433353336333733383339334033413342334333443345334633473348334933503351335233533354335533563357335833593360336133623363336433653366336733683369337033713372337333743375337633773378337933803381338233833384338533863387338833893390339133923393339433953396339733983399340034013402340334043405340634073408340934103411341234133414341534163417341834193420342134223423342434253426342734283429343034313432343334343435343634373438343934403441344234433444344534463447344834493450345134523453345434553456345734583459346034613462346334643465346634673468346934703471347234733474347534763477347834793480348134823483348434853486348734883489349034913492349334943495349634973498349935003501350235033504350535063507350835093510351135123513351435153516351735183519352035213522352335243525352635273528352935303531353235333534353535363537353835393540354135423543354435453546354735483549355035513552355335543555355635573558355935603561356235633564356535663567356835693570357135723573357435753576357735783579358035813582358335843585358635873588358935903591359235933594359535963597359835993600360136023603360436053606360736083609361036113612361336143615361636173618361936203621362236233624362536263627362836293630363136323633363436353636363736383639364036413642364336443645364636473648364936503651365236533654365536563657365836593660366136623663366436653666366736683669367036713672367336743675367636773678367936803681368236833684368536863687368836893690369136923693369436953696369736983699370037013702370337043705370637073708370937103711371237133714371537163717371837193720372137223723372437253726372737283729373037313732373337343735373637373738373937403741374237433744374537463747374837493750375137523753375437553756375737583759376037613762376337643765376637673768376937703771377237733774377537763777377837793780378137823783378437853786378737883789379037913792379337943795379637973798379938003801380238033804380538063807380838093810381138123813381438153816381738183819382038213822382338243825382638273828382938303831383238333834383538363837383838393840384138423843384438453846384738483849385038513852385338543855385638573858385938603861386238633864386538663867386838693870387138723873387438753876387738783879388038813882388338843885388638873888388938903891389238933894389538963897389838993900390139023903390439053906390739083909391039113912391339143915391639173918391939203921392239233924392539263927392839293930393139323933393439353936393739383939394039413942394339443945394639473948394939503951395239533954395539563957395839593960396139623963396439653966396739683969397039713972397339743975397639773978397939803981398239833984398539863987398839893990399139923993399439953996399739983999400040014002400340044005400640074008400940104011401240134014401540164017401840194020402140224023402440254026402740284029403040314032403340344035403640374038403940404041404240434044404540464047404840494050405140524053405440554056405740584059406040614062406340644065406640674068406940704071407240734074407540764077407840794080408140824083408440854086408740884089409040914092409340944095409640974098409941004101410241034104410541064107410841094110411141124113411441154116411741184119412041214122412341244125412641274128412941304131413241334134413541364137413841394140414141424143414441454146414741484149415041514152415341544155415641574158415941604161416241634164416541664167416841694170417141724173417441754176417741784179418041814182418341844185418641874188418941904191419241934194419541964197419841994200420142024203420442054206420742084209421042114212421342144215421642174218421942204221422242234224422542264227422842294230423142324233423442354236423742384239424042414242424342444245424642474248424942504251425242534254425542564257425842594260426142624263426442654266426742684269427042714272427342744275427642774278427942804281428242834284428542864287428842894290429142924293429442954296429742984299430043014302430343044305430643074308430943104311431243134314431543164317431843194320432143224323432443254326432743284329433043314332433343344335433643374338433943404341434243434344434543464347434843494350435143524353435443554356435743584359436043614362436343644365436643674368436943704371437243734374437543764377437843794380438143824383438443854386438743884389439043914392439343944395439643974398439944004401440244034404440544064407440844094410441144124413441444154416441744184419442044214422442344244425442644274428442944304431443244334434443544364437443844394440444144424443444444454446444744484449445044514452445344544455445644574458445944604461446244634464446544664467446844694470447144724473447444754476447744784479448044814482448344844485448644874488448944904491449244934494449544964497449844994500450145024503450445054506450745084509451045114512451345144515451645174518451945204521452245234524452545264527452845294530453145324533453445354536453745384539454045414542454345444545454645474548454945504551455245534554455545564557455845594560456145624563456445654566456745684569457045714572457345744575457645774578457945804581458245834584458545864587458845894590459145924593459445954596459745984599460046014602460346044605460646074608460946104611461246134614461546164617461846194620462146224623462446254626462746284629463046314632463346344635463646374638463946404641464246434644464546464647464846494650465146524653465446554656465746584659466046614662466346644665466646674668466946704671467246734674467546764677467846794680468146824683468446854686468746884689469046914692469346944695469646974698469947004701470247034704470547064707470847094710471147124713471447154716471747184719472047214722472347244725472647274728472947304731473247334734473547364737473847394740474147424743474447454746474747484749475047514752475347544755475647574758475947604761476247634764476547664767476847694770477147724773477447754776477747784779478047814782478347844785478647874788478947904791479247934794479547964797479847994800480148024803480448054806480748084809481048114812481348144815481648174818481948204821482248234824482548264827482848294830483148324833483448354836483748384839484048414842484348444845484648474848484948504851485248534854485548564857485848594860486148624863486448654866486748684869487048714872487348744875487648774878487948804881488248834884488548864887488848894890489148924893489448954896489748984899490049014902490349044905490649074908490949104911491249134914491549164917491849194920492149224923492449254926492749284929493049314932493349344935493649374938493949404941494249434944494549464947494849494950495149524953495449554956495749584959496049614962496349644965496649674968496949704971497249734974497549764977497849794980498149824983498449854986498749884989499049914992499349944995499649974998499950005001500250035004500550065007500850095010501150125013501450155016501750185019502050215022502350245025502650275028502950305031503250335034503550365037503850395040504150425043504450455046504750485049505050515052505350545055505650575058505950605061506250635064506550665067506850695070507150725073507450755076507750785079508050815082508350845085508650875088508950905091509250935094509550965097509850995100510151025103510451055106510751085109511051115112511351145115511651175118511951205121512251235124512551265127512851295130513151325133513451355136513751385139514051415142514351445145514651475148514951505151515251535154515551565157515851595160516151625163516451655166516751685169517051715172517351745175517651775178517951805181518251835184518551865187518851895190519151925193519451955196519751985199520052015202520352045205520652075208520952105211521252135214521552165217521852195220522152225223522452255226522752285229523052315232523352345235523652375238523952405241524252435244524552465247524852495250525152525253525452555256525752585259526052615262526352645265526652675268526952705271527252735274527552765277527852795280528152825283528452855286528752885289529052915292529352945295529652975298529953005301530253035304530553065307530853095310531153125313531453155316531753185319532053215322532353245325532653275328532953305331533253335334533553365337533853395340534153425343534453455346534753485349535053515352535353545355535653575358535953605361536253635364536553665367536853695370537153725373537453755376537753785379538053815382538353845385538653875388538953905391539253935394539553965397539853995400540154025403540454055406540754085409541054115412541354145415541654175418541954205421542254235424542554265427542854295430543154325433543454355436543754385439544054415442544354445445544654475448544954505451545254535454545554565457545854595460546154625463546454655466546754685469547054715472547354745475547654775478547954805481548254835484548554865487548854895490549154925493549454955496549754985499550055015502550355045505550655075508550955105511551255135514551555165517551855195520552155225523552455255526552755285529553055315532553355345535553655375538553955405541554255435544554555465547554855495550555155525553555455555556555755585559556055615562556355645565556655675568556955705571557255735574557555765577557855795580558155825583558455855586558755885589559055915592559355945595559655975598559956005601560256035604560556065607560856095610561156125613561456155616561756185619562056215622562356245625562656275628562956305631563256335634563556365637563856395640564156425643564456455646564756485649565056515652565356545655565656575658565956605661566256635664566556665667566856695670567156725673567456755676567756785679568056815682568356845685568656875688568956905691569256935694569556965697569856995700570157025703570457055706570757085709571057115712571357145715571657175718571957205721572257235724572557265727572857295730573157325733573457355736573757385739574057415742574357445745574657475748574957505751575257535754575557565757575857595760576157625763576457655766576757685769577057715772577357745775577657775778577957805781578257835784578557865787578857895790579157925793579457955796579757985799580058015802580358045805580658075808580958105811581258135814581558165817581858195820582158225823582458255826582758285829583058315832583358345835583658375838583958405841584258435844584558465847584858495850585158525853585458555856585758585859586058615862586358645865586658675868586958705871587258735874587558765877587858795880588158825883588458855886588758885889589058915892589358945895589658975898589959005901590259035904590559065907590859095910591159125913591459155916591759185919592059215922592359245925592659275928592959305931593259335934593559365937593859395940594159425943594459455946594759485949595059515952595359545955595659575958595959605961596259635964596559665967596859695970597159725973597459755976597759785979598059815982598359845985598659875988598959905991599259935994599559965997599859996000600160026003600460056006600760086009601060116012601360146015601660176018601960206021602260236024602560266027602860296030603160326033603460356036603760386039604060416042604360446045604660476048604960506051605260536054605560566057605860596060606160626063606460656066606760686069607060716072607360746075607660776078607960806081608260836084608560866087608860896090609160926093609460956096609760986099610061016102610361046105610661076108610961106111611261136114611561166117611861196120612161226123612461256126612761286129613061316132613361346135613661376138613961406141614261436144614561466147614861496150615161526153615461556156615761586159616061616162616361646165616661676168616961706171617261736174617561766177617861796180618161826183618461856186618761886189619061916192619361946195619661976198619962006201620262036204620562066207620862096210621162126213621462156216621762186219622062216222622362246225622662276228622962306231623262336234623562366237623862396240624162426243624462456246624762486249625062516252625362546255625662576258625962606261626262636264626562666267626862696270627162726273627462756276627762786279628062816282628362846285628662876288628962906291629262936294629562966297629862996300630163026303630463056306630763086309631063116312631363146315631663176318631963206321632263236324632563266327632863296330633163326333633463356336633763386339634063416342634363446345634663476348634963506351635263536354635563566357635863596360636163626363636463656366636763686369637063716372637363746375637663776378637963806381638263836384638563866387638863896390639163926393639463956396639763986399640064016402640364046405640664076408640964106411641264136414641564166417641864196420642164226423642464256426642764286429643064316432643364346435643664376438643964406441644264436444644564466447644864496450645164526453645464556456645764586459646064616462646364646465646664676468646964706471647264736474647564766477647864796480648164826483648464856486648764886489649064916492649364946495649664976498649965006501650265036504650565066507650865096510651165126513651465156516651765186519652065216522652365246525652665276528652965306531653265336534653565366537653865396540654165426543654465456546654765486549655065516552655365546555655665576558655965606561656265636564656565666567656865696570657165726573657465756576657765786579658065816582658365846585658665876588658965906591659265936594659565966597659865996600660166026603660466056606660766086609661066116612661366146615661666176618661966206621662266236624662566266627662866296630663166326633663466356636663766386639664066416642664366446645664666476648664966506651665266536654665566566657665866596660666166626663666466656666666766686669667066716672667366746675667666776678667966806681668266836684668566866687668866896690669166926693669466956696669766986699670067016702670367046705670667076708670967106711671267136714671567166717671867196720672167226723672467256726672767286729673067316732673367346735673667376738673967406741674267436744674567466747674867496750675167526753675467556756675767586759676067616762676367646765676667676768676967706771677267736774677567766777677867796780678167826783678467856786678767886789679067916792679367946795679667976798679968006801680268036804680568066807680868096810681168126813681468156816681768186819682068216822682368246825682668276828682968306831683268336834683568366837683868396840684168426843684468456846684768486849685068516852685368546855685668576858685968606861686268636864686568666867686868696870687168726873687468756876687768786879688068816882688368846885688668876888688968906891689268936894689568966897689868996900690169026903690469056906690769086909691069116912691369146915691669176918691969206921692269236924692569266927692869296930693169326933693469356936693769386939694069416942694369446945694669476948694969506951695269536954695569566957695869596960696169626963696469656966696769686969697069716972697369746975697669776978697969806981698269836984698569866987698869896990699169926993699469956996699769986999700070017002700370047005700670077008700970107011701270137014701570167017701870197020702170227023702470257026702770287029703070317032703370347035703670377038703970407041704270437044704570467047704870497050705170527053705470557056705770587059706070617062706370647065706670677068706970707071707270737074707570767077707870797080708170827083708470857086708770887089709070917092709370947095709670977098709971007101710271037104710571067107710871097110711171127113711471157116711771187119712071217122712371247125712671277128712971307131713271337134713571367137713871397140714171427143714471457146714771487149715071517152715371547155715671577158715971607161716271637164716571667167716871697170717171727173717471757176717771787179718071817182718371847185718671877188718971907191719271937194719571967197719871997200720172027203720472057206720772087209721072117212721372147215721672177218721972207221722272237224722572267227722872297230723172327233723472357236723772387239724072417242724372447245724672477248724972507251725272537254725572567257725872597260726172627263726472657266726772687269727072717272727372747275727672777278727972807281728272837284728572867287728872897290729172927293729472957296729772987299730073017302730373047305730673077308730973107311731273137314731573167317731873197320732173227323732473257326732773287329733073317332733373347335733673377338733973407341734273437344734573467347734873497350735173527353735473557356735773587359736073617362736373647365736673677368736973707371737273737374737573767377737873797380738173827383738473857386738773887389739073917392739373947395739673977398739974007401740274037404740574067407740874097410741174127413741474157416741774187419742074217422742374247425742674277428742974307431743274337434743574367437743874397440744174427443744474457446744774487449745074517452745374547455745674577458745974607461746274637464746574667467746874697470747174727473747474757476747774787479748074817482748374847485748674877488748974907491749274937494749574967497749874997500750175027503750475057506750775087509751075117512751375147515751675177518751975207521752275237524752575267527752875297530753175327533753475357536753775387539754075417542754375447545754675477548754975507551755275537554755575567557755875597560756175627563756475657566756775687569757075717572757375747575757675777578757975807581758275837584758575867587758875897590759175927593759475957596759775987599760076017602760376047605760676077608760976107611761276137614761576167617761876197620762176227623762476257626762776287629763076317632763376347635763676377638763976407641764276437644764576467647764876497650765176527653765476557656765776587659766076617662766376647665766676677668766976707671767276737674767576767677767876797680768176827683768476857686768776887689769076917692769376947695769676977698769977007701770277037704770577067707770877097710771177127713771477157716771777187719772077217722772377247725772677277728772977307731773277337734773577367737773877397740774177427743774477457746774777487749775077517752775377547755775677577758775977607761776277637764776577667767776877697770777177727773777477757776777777787779778077817782778377847785778677877788778977907791779277937794779577967797779877997800780178027803780478057806780778087809781078117812781378147815781678177818781978207821782278237824782578267827782878297830783178327833783478357836783778387839784078417842784378447845784678477848784978507851785278537854785578567857785878597860786178627863786478657866786778687869787078717872787378747875787678777878787978807881788278837884788578867887788878897890789178927893789478957896789778987899790079017902790379047905790679077908790979107911791279137914791579167917791879197920792179227923792479257926792779287929793079317932793379347935793679377938793979407941794279437944
  1. ' maxide.bmx
  2. ' BlitzMax native integrated development environment
  3. ' Copyright (c) 2005-2014 Simon Armstrong, Blitz Research Limited
  4. ' Copyright (c) 2015-2019 Bruce A Henderson
  5. ' Permission is hereby granted, free of charge, to any person obtaining a copy
  6. ' of this software and associated documentation files (the "Software"), to deal
  7. ' in the Software without restriction, including without limitation the rights
  8. ' to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
  9. ' copies of the Software, and to permit persons to whom the Software is
  10. ' furnished to do so, subject to the following conditions:
  11. '
  12. ' The above copyright notice and this permission notice shall be included in
  13. ' all copies or substantial portions of the Software.
  14. '
  15. ' THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  16. ' IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  17. ' FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
  18. ' AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
  19. ' LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
  20. ' OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
  21. ' THE SOFTWARE.
  22. Strict
  23. Framework brl.standardio
  24. ?macos
  25. Import MaxGUI.CocoaMaxGui
  26. ?win32
  27. Import MaxGUI.Win32MaxGUIEx
  28. Import MaxGUI.maxguitextareascintilla
  29. ?linux
  30. Import MaxGUI.gtk3maxgui
  31. Import MaxGUI.gtk3webkitgtk
  32. Import MaxGUI.maxguitextareascintilla
  33. ?
  34. Import MaxGUI.ProxyGadgets
  35. Import brl.eventqueue
  36. Import brl.filesystem
  37. Import brl.system
  38. Import brl.ramstream
  39. Import pub.freeprocess
  40. Import brl.pngloader
  41. Import brl.timer
  42. ?bmxng
  43. Import brl.timerdefault
  44. ?
  45. Import brl.maxutil
  46. Import brl.stringbuilder
  47. Incbin "bmxlogo.png"
  48. Incbin "toolbar.png"
  49. Incbin "toolbar_48.png"
  50. Incbin "toolbar_64.png"
  51. Incbin "splash.png"
  52. Incbin "default.language.ini"
  53. Const DEFAULT_LANGUAGEPATH$ = "incbin::default.language.ini"
  54. ?Linux
  55. Incbin "window_icon.png"
  56. ?
  57. Const IDE_NAME$="MaxIDE"
  58. Const IDE_VERSION$="1.54 [ng]"
  59. Const TIMER_FREQUENCY=15
  60. AppTitle = IDE_NAME + " " + IDE_VERSION
  61. ?Win32
  62. Extern
  63. Global _bbusew 'secret 'NT' flag
  64. End Extern
  65. If Not _bbusew
  66. Notify ("This program is not compatible with Windows 95/98/ME.~n~n", True)
  67. End
  68. EndIf
  69. ?
  70. Global BCC_VERSION$="{unknown}" 'not valid until codeplay opened
  71. Const EOL$="~n"
  72. Const FileTypes$="bmx,bbdoc,txt,ini,doc,plist,bb,cpp,c,cc,m,cxx,s,glsl,hlsl,lua,py,h,hpp,html,htm,css,js,bat,sh,mm,as,java,bbx,cx"
  73. Const FileTypeFilters$="Code Files:"+FileTypes$+";All Files:*"
  74. Const HOMEPAGE$="/docs/html/index.html"
  75. ?MacOS
  76. Const LABELOFFSET=2
  77. ?Win32
  78. Const LABELOFFSET=4
  79. ?Linux
  80. Const LABELOFFSET=0
  81. ?
  82. Const MENUNEW=1
  83. Const MENUOPEN=2
  84. Const MENUCLOSE=3
  85. Const MENUSAVE=4
  86. Const MENUSAVEAS=5
  87. Const MENUSAVEALL=6
  88. Const MENUPRINT=7
  89. Const MENUQUIT=8
  90. Const MENUUNDO=9
  91. Const MENUREDO=10
  92. Const MENUCUT=11
  93. Const MENUCOPY=12
  94. Const MENUPASTE=13
  95. Const MENUSELECTALL=14
  96. Const MENUGOTO=15
  97. Const MENUINDENT=16
  98. Const MENUOUTDENT=17
  99. Const MENUFIND=18
  100. Const MENUFINDNEXT=19
  101. Const MENUREPLACE=20
  102. Const MENUNEXT=21
  103. Const MENUPREV=22
  104. Const MENUBUILD=23
  105. Const MENURUN=24
  106. Const MENUSTEP=25
  107. Const MENUSTEPIN=26
  108. Const MENUSTEPOUT=27
  109. Const MENUSTOP=28
  110. Const MENULOCKBUILD=29
  111. Const MENUUNLOCKBUILD=30
  112. Const MENUBUILDMODULES=31
  113. Const MENUBUILDALLMODULES=32
  114. Const MENUQUICKENABLED=33
  115. Const MENUDEBUGENABLED=34
  116. 'Const MENUGUIENABLED=35
  117. Const MENUCOMMANDLINE=36
  118. Const MENUIMPORTBB=38
  119. Const MENUFINDINFILES=39
  120. Const MENUPROJECTMANAGER=40
  121. Const MENUSHOWCONSOLE=41
  122. Const MENUOPTIONS=42
  123. Const MENUHOME=43
  124. Const MENUBACK=44
  125. Const MENUFORWARD=45
  126. Const MENUQUICKHELP=46
  127. Const MENUABOUT=47
  128. Const MENUNEWVIEW=48
  129. Const MENUDOCMODS=49
  130. Const MENUTRIGGERDOCMODS=50
  131. Const MENUTRIGGERSYNCDOCS=51
  132. Const MENUCLOSEALL=53
  133. Const MENUREFRESH=54
  134. Const MENUBROWSE=55
  135. Const MENUSHELL=56
  136. Const MENUPROPS=57
  137. Const MENUUPDATE=58
  138. Const MENUCOMMIT=59
  139. Const MENUCLOSEOTHERS=60
  140. Const MENUTHREADEDENABLED=61
  141. Const MENUVERBOSEENABLED=62
  142. Const MENUQUICKSCANENABLED=63
  143. Const MENUUNIVERSALENABLED=64
  144. Const MENUWARNOVERENABLED=65
  145. Const MENUGDBDEBUGENABLED=66
  146. Const MENUREQUIREOVERRIDEENABLED=67
  147. Const MENUOVERRIDEERRORSENABLED=68
  148. Const MENUAPPOPTIONS=70
  149. Const MENUCONSOLEENABLED=71
  150. Const MENUGUIENABLED=72
  151. Const MENUMAKELIBENABLED=73
  152. Const MENUPLATFORM=80
  153. Const MENUWIN32ENABLED=81
  154. Const MENULINUXENABLED=82
  155. Const MENUMACOSXENABLED=83
  156. Const MENURASPBERRYPIENABLED=84
  157. Const MENUANDROIDENABLED=85
  158. Const MENUEMSCRIPTENENABLED=86
  159. Const MENUIOSENABLED=87
  160. Const MENUNXENABLED=88
  161. Const MENUARCHITECTURE=90
  162. Const MENUX86ENABLED=91
  163. Const MENUX64ENABLED=92
  164. Const MENUPPCENABLED=93
  165. Const MENUARMENABLED=94
  166. Const MENUARMEABIV5ENABLED=95
  167. Const MENUARMEABIV7AENABLED=96
  168. Const MENUARM64V8AENABLED=97
  169. Const MENUJSENABLED=98
  170. Const MENUARMV7ENABLED=99
  171. Const MENUARM64ENABLED=100
  172. Const MENUGOTOBUILD=110
  173. Const MENUMISC=140
  174. Const MENUUPXENABLED=141
  175. Const MENUAPPSTUB=160
  176. Const MENURECENT=256
  177. Const TB_NEW=0
  178. Const TB_OPEN=1
  179. Const TB_CLOSE=2
  180. Const TB_SAVE=3
  181. 'spacer=4
  182. Const TB_CUT=5
  183. Const TB_COPY=6
  184. Const TB_PASTE=7
  185. Const TB_FIND=8
  186. 'spacer=9
  187. Const TB_BUILD=10
  188. Const TB_BUILDRUN=11
  189. Const TB_STEP=12
  190. Const TB_STEPIN=13
  191. Const TB_STEPOUT=14
  192. Const TB_STOP=15
  193. 'spacer=16
  194. Const TB_HOME=17
  195. Const TB_BACK=18
  196. Const TB_FORWARDS=19
  197. 'spacer=20
  198. Const TB_LOCKOPEN=21
  199. Const TB_LOCKGOTO=22
  200. 'toggle state elements:
  201. Const TB_CONTINUE=23
  202. Const TB_LOCKCLOSED=24
  203. Const TAB$=Chr(9)
  204. Const QUOTES$=Chr(34)
  205. Global TEMPCOUNT
  206. Global codeplay:TCodePlay
  207. Global defaultLanguage:TMaxGUILanguage = LoadLanguage( DEFAULT_LANGUAGEPATH )
  208. SetLocalizationLanguage( defaultLanguage )
  209. SetLocalizationMode( LOCALIZATION_ON|LOCALIZATION_OVERRIDE )
  210. codeplay=New TCodePlay
  211. codeplay.Initialize
  212. While codeplay.running
  213. codeplay.poll
  214. Wend
  215. End
  216. Function Quote$(a$) 'add quotes to arg if spaces found
  217. Local p
  218. If Not a.length Return
  219. If a[0]=34 Return a 'already quoted
  220. p=a.find(" ")
  221. If p=-1 Return a 'no spaces
  222. Return Chr(34)+a+Chr(34)
  223. End Function
  224. Type TToken
  225. Field token$
  226. Field help$
  227. Field ref$
  228. Method Create:TToken(t$,h$,r$)
  229. token=t
  230. help=h
  231. ref=r
  232. Return Self
  233. End Method
  234. End Type
  235. Type TQuickHelp
  236. Field map:TMap=New TMap 'key=lower(token) value=token:TToken
  237. Field tokens:String
  238. Method AddCommand:TQuickHelp(t$,l$,a$)
  239. map.Insert t.ToLower(),New TToken.Create(t$,l$,a$)
  240. End Method
  241. Method Token$(cmd$)
  242. Local t:TToken = TToken(map.ValueForKey(cmd.toLower()))
  243. If t Return t.token
  244. End Method
  245. Method Help$(cmd$)
  246. Local t:TToken = TToken(map.ValueForKey(cmd.toLower()))
  247. If t Return t.help
  248. End Method
  249. Method Link$(cmd$)
  250. Local t:TToken = TToken(map.ValueForKey(cmd.toLower()))
  251. If t Return t.ref
  252. End Method
  253. Function LoadCommandsTxt:TQuickHelp(bmxpath$)
  254. Local Text$
  255. Local qh:TQuickHelp
  256. Local i:Int,c,p,q
  257. Local token$,help$,anchor$
  258. Try
  259. Text=CacheAndLoadText(bmxpath+"/docs/html/Modules/commands.txt")
  260. Catch exception:Object
  261. Return Null
  262. EndTry
  263. If Not Text Return Null
  264. qh=New TQuickHelp
  265. Local sb:TStringBuilder = New TStringBuilder
  266. For Local l$ = EachIn Text.Split("~n")
  267. For i=0 Until l.length
  268. c=l[i]
  269. If c=Asc("_") Continue
  270. If c>=Asc("0") And c<=Asc("9") Continue
  271. If c>=Asc("a") And c<=Asc("z") Continue
  272. If c>=Asc("A") And c<=Asc("Z") Continue
  273. Exit
  274. Next
  275. token$=l[..i]
  276. help$=""
  277. anchor$=""
  278. q=l.findlast("|")
  279. If q>=0
  280. help=l[..q]
  281. anchor=l[q+1..]
  282. EndIf
  283. qh.AddCommand token,help,anchor
  284. If sb.Length() > 0 Then
  285. sb.Append(" ")
  286. End If
  287. sb.Append(token)
  288. Next
  289. qh.tokens = sb.ToString().ToLower()
  290. Return qh
  291. End Function
  292. End Type
  293. Const TOOLSHOW=1
  294. Const TOOLREFRESH=2
  295. Const TOOLNEW=3
  296. Const TOOLOPEN=4
  297. Const TOOLCLOSE=5
  298. Const TOOLSAVE=6
  299. Const TOOLHELP=7
  300. Const TOOLUNDO=8
  301. Const TOOLREDO=9
  302. Const TOOLCUT=10
  303. Const TOOLCOPY=11
  304. Const TOOLPASTE=12
  305. Const TOOLQUICKSAVE=13
  306. Const TOOLSAVEAS=14
  307. Const TOOLGOTO=15
  308. Const TOOLFIND=16
  309. Const TOOLFINDNEXT=17
  310. Const TOOLREPLACE=18
  311. Const TOOLBUILD=19
  312. Const TOOLRUN=20
  313. Const TOOLLOCK=21
  314. Const TOOLUNLOCK=22
  315. Const TOOLSELECT=23
  316. Const TOOLSELECTALL=24
  317. Const TOOLINDENT=25
  318. Const TOOLOUTDENT=26
  319. Const TOOLACTIVATE=27
  320. Const TOOLNAVIGATE=28
  321. Const TOOLNEWVIEW=29
  322. Const TOOLMENU=30
  323. Const TOOLPRINT=31
  324. Const TOOLERROR=32
  325. Const TOOLOUTPUT=32
  326. Type TTool
  327. Method Invoke(command,argument:Object=Null)
  328. End Method
  329. End Type
  330. Type TRequester
  331. Const STYLE_OK% = 1, STYLE_CANCEL% = 2
  332. Const STYLE_DIVIDER% = 4, STYLE_STATUS% = 8
  333. Const STYLE_RESIZABLE% = 16, STYLE_STDBORDER% = 32
  334. Const STYLE_MODAL% = 64
  335. Field host:TCodePlay
  336. Field window:TGadget,ok:TGadget,cancel:TGadget,divider:TGadget
  337. Field centered, modal
  338. Method initrequester(owner:TCodeplay,label$,w=260,h=60,flags=STYLE_OK|STYLE_CANCEL|STYLE_DIVIDER,oktext$="{{btn_ok}}")
  339. Local buttonPadding:Int = 7
  340. host=owner
  341. If (flags&STYLE_MODAL) Then flags:|STYLE_STDBORDER
  342. If (flags & (STYLE_CANCEL|STYLE_OK)) Then h:+ScaledSize(32);If (flags&STYLE_DIVIDER) Then h:+ScaledSize(12)
  343. Local windowflags% = WINDOW_TITLEBAR|WINDOW_HIDDEN|WINDOW_CLIENTCOORDS
  344. If (flags & STYLE_STATUS) Then windowflags:|WINDOW_STATUS
  345. If (flags & STYLE_RESIZABLE) Then windowflags:|WINDOW_RESIZABLE
  346. If Not (flags & STYLE_STDBORDER) Then windowflags:|WINDOW_TOOL
  347. window=CreateWindow(label,0,0,w,h,host.window,windowflags)
  348. If (flags & STYLE_RESIZABLE) Then
  349. If (flags & STYLE_STDBORDER) Then SetMaxWindowSize(window,ClientWidth(Desktop()),ClientHeight(Desktop()))
  350. SetMinWindowSize(window,w,h)
  351. EndIf
  352. If (flags & STYLE_OK) Then
  353. ok=CreateButton(oktext,ClientWidth(window)-ScaledSize(95+buttonPadding),ClientHeight(window)-ScaledSize(32),ScaledSize(95),ScaledSize(26),window,BUTTON_OK)
  354. SetGadgetLayout(ok,EDGE_CENTERED,EDGE_ALIGNED,EDGE_CENTERED,EDGE_ALIGNED)
  355. If (flags & STYLE_CANCEL) Then
  356. cancel=CreateButton("{{btn_cancel}}",ScaledSize(buttonPadding),ClientHeight(window)-ScaledSize(32),ScaledSize(95),ScaledSize(26),window,BUTTON_CANCEL)
  357. SetGadgetLayout(cancel,EDGE_ALIGNED,EDGE_CENTERED,EDGE_CENTERED,EDGE_ALIGNED)
  358. EndIf
  359. Else
  360. If (flags & STYLE_CANCEL) Then
  361. cancel=CreateButton("{{btn_close}}",ClientWidth(window)-ScaledSize(95+buttonPadding),ClientHeight(window)-ScaledSize(32),ScaledSize(95),ScaledSize(26),window,BUTTON_CANCEL)
  362. SetGadgetLayout(cancel,EDGE_CENTERED,EDGE_ALIGNED,EDGE_CENTERED,EDGE_ALIGNED)
  363. EndIf
  364. EndIf
  365. If (flags & STYLE_DIVIDER) And (flags & (STYLE_OK|STYLE_CANCEL)) Then
  366. divider = CreateLabel( "", ScaledSize(buttonPadding), ClientHeight(window)-ScaledSize(42), ClientWidth(window)-ScaledSize(12), ScaledSize(4), window, LABEL_SEPARATOR )
  367. SetGadgetLayout(divider,EDGE_ALIGNED,EDGE_ALIGNED,EDGE_CENTERED,EDGE_ALIGNED)
  368. EndIf
  369. If (flags & STYLE_MODAL) Then modal = True Else modal = False
  370. End Method
  371. Method Show()
  372. Local x,y,w,h,win:TGadget
  373. If Not centered
  374. win=host.window
  375. w=GadgetWidth(window)
  376. h=GadgetHeight(window)
  377. x=GadgetX(win)+(GadgetWidth(win)-w)/2
  378. y=GadgetY(win)+(GadgetHeight(win)-h)/2
  379. SetGadgetShape window,x,y,w,h
  380. centered=True
  381. EndIf
  382. host.HookRequester Self
  383. ShowGadget window
  384. ActivateGadget window
  385. PollSystem
  386. End Method
  387. Method Hide()
  388. EnableGadget host.window
  389. HideGadget window
  390. host.UnhookRequester Self
  391. host.SelectPanel host.currentpanel
  392. End Method
  393. Method IsModal()
  394. Return modal
  395. EndMethod
  396. Method Poll()
  397. End Method
  398. End Type
  399. Rem
  400. Type TProgressRequester Extends TRequester
  401. Field message$,value
  402. Field showing
  403. Field label:TGadget
  404. Field progbar:TGadget
  405. Method Show() 'returns false if cancelled
  406. showing=True
  407. Super.Show
  408. End Method
  409. Method Hide()
  410. showing=False
  411. Super.Hide()
  412. End Method
  413. Method Open(title$)
  414. SetGadgetText window,title
  415. Show
  416. End Method
  417. Method Update(msg$,val)
  418. If msg$<>message
  419. message=msg
  420. If label FreeGadget label
  421. label=CreateLabel(message,8,8,260,20,window)
  422. EndIf
  423. If showing And (val&$fc)<>(value&$fc) 'only update every 4 percent
  424. UpdateProgBar( progbar,val/100.0 )
  425. PollSystem
  426. EndIf
  427. value=val
  428. End Method
  429. Function Create:TProgressRequester(host:TCodePlay)
  430. Local progress:TProgressRequester
  431. progress=New TProgressRequester
  432. progress.initrequester(host,"{{progress_window_title}}",280,128,STYLE_CANCEL)
  433. progress.progbar=CreateProgBar( 8,32,260,20,progress.window )
  434. Return progress
  435. End Function
  436. End Type
  437. EndRem
  438. Type TPanelRequester Extends TRequester
  439. Field tabber:TGadget
  440. Field panels:TGadget[]
  441. Field index
  442. Method InitPanelRequester(owner:TCodeplay,label$,w=280,h=128)
  443. InitRequester owner,label,w,h,STYLE_OK|STYLE_CANCEL|STYLE_STDBORDER|STYLE_MODAL
  444. tabber=CreateTabber(ScaledSize(6),ScaledSize(6),w-ScaledSize(12),h-ScaledSize(12),window)
  445. SetGadgetLayout tabber,EDGE_ALIGNED,EDGE_ALIGNED,EDGE_ALIGNED,EDGE_ALIGNED
  446. End Method
  447. Method SetPanelIndex(i)
  448. HideGadget panels[index]
  449. index=i
  450. ShowGadget panels[index]
  451. SelectGadgetItem tabber,index
  452. End Method
  453. Method SetPanel(panel:TGadget)
  454. Local i
  455. For Local p:TGadget = EachIn panels
  456. If p=panel SetPanelIndex i;Exit
  457. i:+1
  458. Next
  459. End Method
  460. Method AddPanel:TGadget(name$)
  461. Local panel:TGadget
  462. panel=CreatePanel(0,0,ClientWidth(tabber),ClientHeight(tabber),tabber)
  463. SetGadgetLayout panel,EDGE_ALIGNED,EDGE_ALIGNED,EDGE_ALIGNED,EDGE_ALIGNED
  464. HideGadget panel
  465. AddGadgetItem tabber,name,GADGETITEM_LOCALIZED
  466. panels=panels[..panels.length+1]
  467. panels[panels.length-1]=panel
  468. Return panel
  469. End Method
  470. Method RemovePanel(panel)
  471. End Method
  472. End Type
  473. Type TAboutRequester Extends TRequester
  474. Global pixLogo:TPixmap
  475. Field pnlLogo:TGadget, lblTitle:TGadget, lblSubtitle:TGadget
  476. Field lblLeftAligned:TGadget[], lblRightAligned:TGadget[]
  477. Field hypBlitz:TGadget
  478. Method PopulateText()
  479. Local strHeadings$[], strValues$[]
  480. strHeadings:+["{{about_label_bccver}}:"]
  481. strValues:+[BCC_VERSION]
  482. strHeadings:+["{{about_label_bmkver}}:"]
  483. strValues:+[GetBMK()]
  484. strHeadings:+[""]
  485. strValues:+[""]
  486. strHeadings:+["{{about_label_bmxpath}}:"]
  487. ?Win32
  488. strValues:+[BlitzMaxPath().Replace("/","\")]
  489. ?Not Win32
  490. strValues:+[BlitzMaxPath()]
  491. ?
  492. ?Win32
  493. strHeadings:+["{{about_label_mingwpath}}:"]
  494. ' check For Local mingw32 dir First
  495. Local path:String = MinGWPath()
  496. If path Then
  497. strValues:+[path.Replace("/", "\")]
  498. Else
  499. strValues:+[LocalizeString("{{about_error_unavailable}}")]
  500. EndIf
  501. ?
  502. strHeadings:+[""]
  503. strValues:+[""]
  504. ?Not MacOS
  505. strHeadings:+["{{about_label_fasmver}}:"]
  506. strValues:+[GetFASM()]
  507. ?
  508. strHeadings:+["{{about_label_gccver}}:"]
  509. strValues:+[GetGCC()]
  510. strHeadings:+["{{about_label_gplusplusver}}:"]
  511. strValues:+[GetGpp()]
  512. strHeadings:+["{{about_label_upxver}}:"]
  513. strValues:+[GetUPX()]
  514. PopulateColumns( strHeadings, strValues )
  515. EndMethod
  516. Function GetProcessOutput$(cmd$, flags$ = "")
  517. Local version$
  518. ?Win32
  519. cmd:+".exe"
  520. ?
  521. cmd=Quote(cmd)
  522. If flags Then cmd:+" "+flags
  523. Local process:TProcess = CreateProcess(cmd,HIDECONSOLE)
  524. If process
  525. Local bytes:Byte[]
  526. Local tmpTimeout:Int = MilliSecs() + 500
  527. Repeat
  528. Delay 10
  529. bytes=process.pipe.ReadPipe()
  530. If bytes
  531. version:+String.FromBytes(bytes,bytes.length)
  532. EndIf
  533. Until (Not process.status()) Or (MilliSecs() > tmpTimeout)
  534. process.Close()
  535. Return version.Trim().Replace("~r","")
  536. EndIf
  537. Return LocalizeString("{{about_error_unavailable}}")
  538. EndFunction
  539. Method GetFASM$()
  540. ?Not MacOS
  541. Local tmpSections$[] = GetProcessOutput(BlitzMaxPath()+"/bin/fasm").Split("~n")[0].Split(" ")
  542. Return tmpSections[tmpSections.length-1]
  543. ?
  544. EndMethod
  545. Method GetBMK$()
  546. Local tmpSections$[] = GetProcessOutput(BlitzMaxPath()+"/bin/bmk", "-v").Split("~n")
  547. Return tmpSections[tmpSections.length-1]
  548. EndMethod
  549. Method GetGCC$()
  550. ?Win32
  551. Local gccPath:String = MinGWPath()
  552. If Not gccPath Then Return LocalizeString("{{about_error_notapplicable}}")
  553. gccPath :+ "/bin/gcc"
  554. gccPath = gccPath.Replace("/", "\")
  555. ? Not win32
  556. Local gccPath:String = "gcc"
  557. ?
  558. Return GetProcessOutput(gccPath, "-dumpversion").Split("~n")[0]
  559. EndMethod
  560. Method GetGpp$()
  561. ?Win32
  562. Local gppPath:String = MinGWPath()
  563. If Not gppPath Then Return LocalizeString("{{about_error_notapplicable}}")
  564. gppPath:+ "/bin/g++"
  565. gppPath = gppPath.Replace("/", "\")
  566. ? Not win32
  567. Local gppPath:String = "g++"
  568. ?
  569. Return GetProcessOutput(gppPath, "-dumpversion").Split("~n")[0]
  570. EndMethod
  571. Method GetUPX$()
  572. Local upxPath:String = BlitzMaxPath() + "/bin/upx"
  573. Local ext:String
  574. ?Win32
  575. ext = ".exe"
  576. upxPath = upxPath.Replace("/", "\")
  577. ?
  578. If FileType(upxPath + ext) = FILETYPE_FILE
  579. Return GetProcessOutput(upxPath, "-V").Split("~n")[0]
  580. Else
  581. Return LocalizeString("{{about_error_notapplicable}}")
  582. EndIf
  583. EndMethod
  584. Method PopulateColumns( strHeadings$[], strValues$[] )
  585. strHeadings = strHeadings[..lblLeftAligned.length]
  586. strValues = strValues[..lblRightAligned.length]
  587. For Local i:Int = 0 Until lblLeftAligned.length
  588. LocalizeGadget( lblLeftAligned[i], strHeadings[i] )
  589. Next
  590. For Local i:Int = 0 Until lblRightAligned.length
  591. SetGadgetText( lblRightAligned[i], strValues[i] )
  592. SetGadgetToolTip( lblRightAligned[i], strValues[i] )
  593. Next
  594. EndMethod
  595. Method Show()
  596. PopulateText()
  597. Super.Show()
  598. EndMethod
  599. Method Poll()
  600. Select EventSource()
  601. Case window
  602. If EventID()=EVENT_WINDOWCLOSE
  603. Hide()
  604. EndIf
  605. Case cancel
  606. If EventID()=EVENT_GADGETACTION
  607. Hide()
  608. EndIf
  609. Default
  610. Return 0
  611. End Select
  612. Return 1
  613. End Method
  614. Function Create:TAboutRequester(host:TCodePlay)
  615. Local abt:TAboutRequester = New TAboutRequester
  616. abt.initrequester(host,"{{about_window_title}}",ScaledSize(460),ScaledSize(299),STYLE_CANCEL|STYLE_DIVIDER|STYLE_MODAL)
  617. Local win:TGadget = abt.window, w = ClientWidth(abt.window)-ScaledSize(12), h = ClientHeight(abt.window)
  618. abt.pnlLogo = CreatePanel(w-ScaledSize(64-6),0,ScaledSize(64),ScaledSize(64),win)
  619. SetGadgetLayout abt.pnlLogo, EDGE_CENTERED, EDGE_ALIGNED, EDGE_ALIGNED, EDGE_CENTERED
  620. 'abt.pnlLogo = CreatePanel(0,0,64,64,win)
  621. 'SetGadgetLayout abt.pnlLogo, EDGE_ALIGNED, EDGE_CENTERED, EDGE_ALIGNED, EDGE_CENTERED
  622. If Not pixLogo Then pixLogo = LoadPixmapPNG("incbin::bmxlogo.png")
  623. SetGadgetPixmap abt.pnlLogo, pixLogo, PANELPIXMAP_CENTER
  624. Local y = 12
  625. Local arch:String
  626. ?x86
  627. arch = "x86"
  628. ?x64
  629. arch = "x64"
  630. ?arm
  631. arch = "ARM"
  632. ?
  633. abt.lblTitle = CreateLabel(IDE_NAME + " " + IDE_VERSION + " (" + arch + ")",ScaledSize(6),ScaledSize(y),w,ScaledSize(22),win,LABEL_LEFT)
  634. SetGadgetFont abt.lblTitle, LookupGuiFont( GUIFONT_SYSTEM, 12, FONT_BOLD )
  635. SetGadgetLayout abt.lblTitle, EDGE_ALIGNED, EDGE_ALIGNED, EDGE_ALIGNED, EDGE_CENTERED
  636. y:+23
  637. abt.lblSubtitle = CreateLabel("{{about_label_subtitle}}",ScaledSize(6),ScaledSize(y),w,ScaledSize(22),win,LABEL_LEFT)
  638. SetGadgetFont abt.lblSubtitle, LookupGuiFont( GUIFONT_SYSTEM, 10, FONT_ITALIC )
  639. SetGadgetLayout abt.lblSubtitle, EDGE_ALIGNED, EDGE_ALIGNED, EDGE_ALIGNED, EDGE_CENTERED
  640. y = 64
  641. SetGadgetLayout( CreateLabel("",ScaledSize(6),ScaledSize(y),w,ScaledSize(4),win,LABEL_SEPARATOR), EDGE_ALIGNED, EDGE_ALIGNED, EDGE_ALIGNED, EDGE_CENTERED )
  642. y:+(4+6)
  643. Local tmpGadget:TGadget
  644. For y = y Until (299-21) Step 22
  645. tmpGadget = CreateLabel("",ScaledSize(6),ScaledSize(y),ScaledSize(135),ScaledSize(22),win,LABEL_LEFT)
  646. SetGadgetLayout( tmpGadget, EDGE_ALIGNED, EDGE_RELATIVE, EDGE_ALIGNED, EDGE_CENTERED )
  647. abt.lblLeftAligned:+[tmpGadget]
  648. tmpGadget = CreateLabel("",ScaledSize(135+6),ScaledSize(y),w-ScaledSize(175),ScaledSize(22),win,LABEL_LEFT)
  649. SetGadgetLayout( tmpGadget, EDGE_RELATIVE, EDGE_ALIGNED, EDGE_ALIGNED, EDGE_CENTERED )
  650. DelocalizeGadget tmpGadget
  651. abt.lblRightAligned:+[tmpGadget]
  652. Next
  653. abt.hypBlitz = CreateHyperlink("https://blitzmax.org",ScaledSize(6),(h-ScaledSize(28)),ScaledSize(200),ScaledSize(26),win,LABEL_LEFT)
  654. SetGadgetLayout abt.hypBlitz, EDGE_ALIGNED, EDGE_ALIGNED, EDGE_CENTERED, EDGE_ALIGNED
  655. Return abt
  656. EndFunction
  657. Function Spacer( height:Int, inpout:Int Var )
  658. inpout:+height+ScaledSize(6)
  659. Return height
  660. EndFunction
  661. EndType
  662. Type TCmdLineRequester Extends TRequester
  663. Field label:TGadget,textfield:TGadget
  664. Method Poll()
  665. Select EventSource()
  666. Case window
  667. If EventID()=EVENT_WINDOWCLOSE
  668. Hide
  669. EndIf
  670. Case ok
  671. If EventID()=EVENT_GADGETACTION
  672. host.SetCommandLine TextFieldText(textfield)
  673. Hide
  674. EndIf
  675. Case cancel
  676. If EventID()=EVENT_GADGETACTION
  677. SetGadgetText textfield,host.GetCommandLine()
  678. Hide
  679. EndIf
  680. Default
  681. Return 0
  682. End Select
  683. Return 1
  684. End Method
  685. Method Show()
  686. SetGadgetText textfield,host.GetCommandLine()
  687. Super.Show()
  688. ActivateGadget textfield
  689. End Method
  690. Function Create:TCmdLineRequester(host:TCodePlay)
  691. Local cmd:TCmdLineRequester = New TCmdLineRequester
  692. cmd.initrequester(host,"{{cmdline_window_title}}",ScaledSize(260),ScaledSize(60),STYLE_OK|STYLE_CANCEL|STYLE_DIVIDER|STYLE_MODAL)
  693. cmd.label=CreateLabel("{{cmdline_label_cmdline}}:",ScaledSize(6),ScaledSize(8),ScaledSize(260),ScaledSize(20),cmd.window)
  694. cmd.textfield=CreateTextField(ScaledSize(6),ScaledSize(30),ClientWidth(cmd.window)-ScaledSize(12),ScaledSize(21),cmd.window)
  695. Return cmd
  696. End Function
  697. End Type
  698. Type TGotoRequester Extends TRequester
  699. Field linenumber:TGadget
  700. Method Show()
  701. Super.Show()
  702. ActivateGadget linenumber
  703. End Method
  704. Method Poll()
  705. Local line,data,Text$
  706. Select EventSource()
  707. Case linenumber
  708. If EventID() = EVENT_GADGETACTION
  709. Text = GadgetText(linenumber)
  710. If Text And (Int(Text) <> Text) Then SetGadgetText linenumber, Int(Text)
  711. EndIf
  712. Case window
  713. If EventID()=EVENT_WINDOWCLOSE
  714. Hide
  715. EndIf
  716. Case ok
  717. line=Int(GadgetText(linenumber))
  718. Hide
  719. host.activepanel.Invoke TOOLGOTO,String(line)
  720. Case cancel
  721. Hide
  722. Default
  723. Return 0
  724. End Select
  725. Return 1
  726. End Method
  727. Function Create:TGotoRequester(host:TCodePlay)
  728. Local seek:TGotoRequester = New TGotoRequester
  729. seek.initrequester(host,"{{goto_window_title}}",ScaledSize(260),ScaledSize(66),STYLE_OK|STYLE_CANCEL|STYLE_DIVIDER|STYLE_MODAL,"{{goto_btn_goto}}")
  730. CreateLabel("{{goto_label_linenum}}:",ScaledSize(6),ScaledSize(8+4),ScaledSize(114),ScaledSize(20),seek.window)
  731. seek.linenumber=CreateTextField(ScaledSize(150),ScaledSize(8),ClientWidth(seek.window)-ScaledSize(150+6),ScaledSize(21),seek.window)
  732. SetGadgetFilter( seek.linenumber, IntegerFilter )
  733. Return seek
  734. End Function
  735. Function IntegerFilter:Int( event:TEvent, context:Object )
  736. Select event.id
  737. Case EVENT_KEYCHAR
  738. If event.data >= Asc("0") And event.data <= Asc("9") Return True
  739. If event.data = 8 Or event.data = 127 Or event.data = 13 Return True
  740. Return False
  741. Case EVENT_KEYDOWN
  742. Return True
  743. EndSelect
  744. EndFunction
  745. End Type
  746. Type TColor
  747. Field red,green,blue
  748. Method Set(rgb)
  749. red=(rgb Shr 16)&$FF
  750. green=(rgb Shr 8)&$FF
  751. blue=rgb&$FF
  752. End Method
  753. Method ToString$()
  754. Return ""+red+","+green+","+blue
  755. End Method
  756. Method FromString(s$)
  757. Local p=s.Find(",")+1
  758. If Not p Return
  759. Local q=s.Find(",",p)+1
  760. If Not q Return
  761. red=Int(s[..p-1])
  762. green=Int(s[p..q-1])
  763. blue=Int(s[q..])
  764. End Method
  765. Method Request()
  766. If RequestColor(red,green,blue)
  767. red=RequestedRed()
  768. green=RequestedGreen()
  769. blue=RequestedBlue()
  770. Return True
  771. EndIf
  772. End Method
  773. End Type
  774. Type TTextStyle
  775. Field label:TGadget,panel:TGadget,combo:TGadget
  776. Field underline:TGadget, color:TColor
  777. Field flags
  778. Method Set(rgb,bolditalic)
  779. color.set(rgb)
  780. flags=bolditalic
  781. End Method
  782. Method Format(textarea:TGadget,pos,length,emphasise:Int = False)
  783. Local tmpFlags:Int = flags
  784. If emphasise Then tmpFlags:|TEXTFORMAT_BOLD
  785. FormatTextAreaText textarea,color.red,color.green,color.blue,tmpFlags,pos,length
  786. End Method
  787. Method ToString$()
  788. Return ""+color.red+","+color.green+","+color.blue+","+flags
  789. End Method
  790. Method FromString(s$)
  791. Local p,q,r
  792. p=s.Find(",")+1;If Not p Return
  793. q=s.Find(",",p)+1;If Not q Return
  794. r=s.Find(",",q)+1;If Not r Return
  795. color.red=Int(s[..p-1])
  796. color.green=Int(s[p..q-1])
  797. color.blue=Int(s[q..r-1])
  798. flags=Int(s[r..])
  799. End Method
  800. Method Poll()
  801. Select EventSource()
  802. Case panel
  803. If EventID()=EVENT_MOUSEDOWN
  804. Return color.Request()
  805. EndIf
  806. Case combo
  807. flags=(flags&~3)|SelectedGadgetItem(combo)
  808. Return True
  809. Case underline
  810. If EventData() Then flags:|TEXTFORMAT_UNDERLINE Else flags:&~TEXTFORMAT_UNDERLINE
  811. Return True
  812. End Select
  813. End Method
  814. Method Refresh()
  815. SetPanelColor panel,color.red,color.green,color.blue
  816. SelectGadgetItem combo,flags&3
  817. SetButtonState(underline,(flags&TEXTFORMAT_UNDERLINE <> 0))
  818. End Method
  819. Function Create:TTextStyle(name$,xpos,ypos,window:TGadget)
  820. Local s:TTextStyle
  821. s=New TTextStyle
  822. s.color=New TColor
  823. s.label=CreateLabel(name,xpos,ypos+ScaledSize(4),ScaledSize(90),ScaledSize(24),window)
  824. s.panel=CreatePanel(xpos+ScaledSize(114),ypos,ScaledSize(24),ScaledSize(24),window,PANEL_BORDER|PANEL_ACTIVE)
  825. SetPanelColor s.panel,255,255,0
  826. s.combo=CreateComboBox(xpos+ScaledSize(142),ypos,ScaledSize(96),ScaledSize(24),window)
  827. s.underline=CreateButton("{{txtstyle_underline}}",xpos+ScaledSize(270),ypos,ClientWidth(window)-(xpos+ScaledSize(220)),ScaledSize(24),window,BUTTON_CHECKBOX)
  828. AddGadgetItem s.combo,"{{txtstyle_normal}}",GADGETITEM_LOCALIZED
  829. AddGadgetItem s.combo,"{{txtstyle_bold}}",GADGETITEM_LOCALIZED
  830. AddGadgetItem s.combo,"{{txtstyle_italic}}",GADGETITEM_LOCALIZED
  831. AddGadgetItem s.combo,"{{txtstyle_bolditalic}}",GADGETITEM_LOCALIZED
  832. Return s
  833. End Function
  834. End Type
  835. Type TCaretStyle
  836. Field label:TGadget, panel:TGadget, combo:TGadget
  837. Field caretLinePanel:TGadget, caretLineVisibleToggle:TGadget
  838. Field color:TColor
  839. Field caretLineColor:TColor
  840. Field caretLineVisible:Int
  841. Field caretLineAlpha:Int = 30
  842. Field width:Int = 1
  843. Method Set(rgb:Int, width:Int, caretLineRGB:Int, caretLineVisible:Int)
  844. color.set(rgb)
  845. caretLineColor.set(caretLineRGB)
  846. Self.width=width
  847. Self.caretLineVisible = caretLineVisible
  848. End Method
  849. Method ToString$()
  850. Return ""+color.red+","+color.green+","+color.blue+","+width+","+caretLineColor.red+","+caretLineColor.green+","+caretLineColor.blue+","+caretLineVisible
  851. End Method
  852. Method FromString(s$)
  853. Local parts:String[] = s.split(",")
  854. If parts.length < 4 Then Return
  855. color.red = Int(parts[0])
  856. color.green = Int(parts[1])
  857. color.blue = Int(parts[2])
  858. width = Min(3, Max(1,Int(parts[3])))
  859. If parts.length >= 8
  860. caretLineColor.red = Int(parts[4])
  861. caretLineColor.green = Int(parts[5])
  862. caretLineColor.blue = Int(parts[6])
  863. caretLineVisible = Int(parts[7])
  864. EndIf
  865. End Method
  866. Method Poll()
  867. Select EventSource()
  868. Case panel
  869. If EventID()=EVENT_MOUSEDOWN
  870. Return color.Request()
  871. EndIf
  872. Case caretLinePanel
  873. If EventID() = EVENT_MOUSEDOWN
  874. Return caretLineColor.Request()
  875. EndIf
  876. Case combo
  877. width=SelectedGadgetItem(combo) + 1
  878. Return True
  879. Case caretLineVisibleToggle
  880. If EventData()
  881. caretLineVisible = True
  882. Else
  883. caretLineVisible = False
  884. EndIf
  885. Return True
  886. End Select
  887. End Method
  888. Method Refresh()
  889. SetPanelColor panel,color.red,color.green,color.blue
  890. SetPanelColor caretLinePanel, caretLineColor.red, caretLineColor.green, caretLineColor.blue
  891. SelectGadgetItem combo,width - 1
  892. SetButtonState(caretLineVisibleToggle, caretLineVisible)
  893. End Method
  894. Function Create:TCaretStyle(name$,xpos,ypos,window:TGadget)
  895. Local s:TCaretStyle
  896. s = New TCaretStyle
  897. s.color = New TColor
  898. s.caretLineColor = New TColor
  899. s.label=CreateLabel(name,xpos,ypos+ScaledSize(4),ScaledSize(90),ScaledSize(24),window)
  900. s.panel=CreatePanel(xpos+ScaledSize(114),ypos,ScaledSize(24),ScaledSize(24),window,PANEL_BORDER|PANEL_ACTIVE)
  901. SetPanelColor s.panel,255,255,0
  902. s.combo=CreateComboBox(xpos+ScaledSize(142),ypos,ScaledSize(96),ScaledSize(24),window)
  903. AddGadgetItem s.combo,"{{caretstyle_width_1}}",GADGETITEM_LOCALIZED
  904. AddGadgetItem s.combo,"{{caretstyle_width_2}}",GADGETITEM_LOCALIZED
  905. AddGadgetItem s.combo,"{{caretstyle_width_3}}",GADGETITEM_LOCALIZED
  906. s.caretLinePanel = CreatePanel(xpos+ScaledSize(242),ypos,ScaledSize(24),ScaledSize(24),window,PANEL_BORDER|PANEL_ACTIVE)
  907. SetPanelColor(s.caretLinePanel, 255, 255, 0)
  908. s.caretLineVisibleToggle = CreateButton("{{caretline_visible}}",xpos+ScaledSize(270),ypos,ClientWidth(window)-(xpos+ScaledSize(220)),ScaledSize(24),window,BUTTON_CHECKBOX)
  909. Return s
  910. End Function
  911. End Type
  912. Type TLineNumberStyle
  913. Field label:TGadget,fgPanel:TGadget,bgPanel:TGadget
  914. Field fg:TColor, bg:TColor
  915. Field enabled:TGadget
  916. Field flags:Int
  917. Method Set(fg, bg, flags:Int)
  918. Self.fg.set(fg)
  919. Self.bg.set(bg)
  920. Self.flags = flags
  921. End Method
  922. Method ToString$()
  923. Return ""+fg.red+","+fg.green+","+fg.blue+","+bg.red+","+bg.green+","+bg.blue+","+flags
  924. End Method
  925. Function GetArg:String(a:String Var)
  926. Local p:Int = a.Find(",")
  927. If p=-1 Then p=a.length
  928. Local r:String = a[..p]
  929. a=a[p+1..]
  930. Return r
  931. End Function
  932. Method FromString(s:String)
  933. fg.red=Int(GetArg(s))
  934. fg.green=Int(GetArg(s))
  935. fg.blue=Int(GetArg(s))
  936. bg.red=Int(GetArg(s))
  937. bg.green=Int(GetArg(s))
  938. bg.blue=Int(GetArg(s))
  939. flags=Int(GetArg(s))
  940. End Method
  941. Method Poll()
  942. Select EventSource()
  943. Case fgPanel
  944. If EventID()=EVENT_MOUSEDOWN
  945. Return fg.Request()
  946. EndIf
  947. Case bgPanel
  948. If EventID()=EVENT_MOUSEDOWN
  949. Return bg.Request()
  950. EndIf
  951. Case enabled
  952. If EventData() Then flags = True Else flags = False
  953. Return True
  954. End Select
  955. End Method
  956. Method Refresh()
  957. SetPanelColor fgPanel,fg.red,fg.green,fg.blue
  958. SetPanelColor bgPanel,bg.red,bg.green,bg.blue
  959. SetButtonState enabled, flags
  960. End Method
  961. Function Create:TLineNumberStyle(name$,xpos,ypos,window:TGadget)
  962. Local s:TLineNumberStyle
  963. s=New TLineNumberStyle
  964. s.fg=New TColor
  965. s.bg=New TColor
  966. s.label=CreateLabel(name,xpos,ypos+ScaledSize(4),ScaledSize(90),ScaledSize(24),window)
  967. s.fgPanel=CreatePanel(xpos+ScaledSize(114),ypos,ScaledSize(24),ScaledSize(24),window,PANEL_BORDER|PANEL_ACTIVE)
  968. SetPanelColor s.fgPanel,255,255,0
  969. s.bgPanel=CreatePanel(xpos+ScaledSize(142),ypos,ScaledSize(24),ScaledSize(24),window,PANEL_BORDER|PANEL_ACTIVE)
  970. SetPanelColor s.bgPanel,255,255,0
  971. s.enabled=CreateButton("{{linenumberstyle_enabled}}",xpos+ScaledSize(270),ypos,ClientWidth(window)-(xpos+ScaledSize(220)),ScaledSize(24),window,BUTTON_CHECKBOX)
  972. Return s
  973. End Function
  974. End Type
  975. Type TGadgetStyle
  976. Global fntLibrary:TGUIFont[] = [TGuiFont(Null), LookupGuiFont(GUIFONT_SYSTEM), LookupGuiFont(GUIFONT_MONOSPACED), ..
  977. LookupGuiFont(GUIFONT_SANSSERIF), LookupGuiFont(GUIFONT_SERIF), ..
  978. LookupGuiFont(GUIFONT_SCRIPT) ]
  979. Field label:TGadget,fpanel:TGadget,bpanel:TGadget,fcombo:TGadget,fbutton:TGadget
  980. Field font_name$, font_size:Double
  981. Field fg:TColor, bg:TColor
  982. Field font_type = GUIFONT_SYSTEM, font:TGUIFont = fntLibrary[font_type]
  983. Method Apply(gadget:TGadget)
  984. SetGadgetFont gadget,font
  985. SetGadgetColor gadget,bg.red,bg.green,bg.blue,True
  986. SetGadgetColor gadget,fg.red,fg.green,fg.blue,False
  987. End Method
  988. Method Set(fg_rgb,bg_rgb,ftype,fname$="",fsize=0)
  989. fg.set(fg_rgb)
  990. bg.set(bg_rgb)
  991. If Not fntLibrary[ftype] Then
  992. font_name=fname
  993. font_size=fsize
  994. Else
  995. font_name=FontName(fntLibrary[ftype])
  996. font_size=FontSize(fntLibrary[ftype])
  997. EndIf
  998. font_type=ftype
  999. End Method
  1000. Method ToString$()
  1001. Return font_name+","+String(font_size).Replace(",",".")+","+fg.ToString()+","+bg.ToString()+","+font_type
  1002. End Method
  1003. Function GetArg$(a$ Var)
  1004. Local p = a.Find(",")
  1005. If p=-1 Then p=a.length
  1006. Local r$ = a$[..p]
  1007. a$=a$[p+1..]
  1008. Return r$
  1009. End Function
  1010. Method FromString(s$)
  1011. font_name=GetArg(s$)
  1012. font_size=Double(GetArg(s$))
  1013. fg.red=Int(GetArg(s$))
  1014. fg.green=Int(GetArg(s$))
  1015. fg.blue=Int(GetArg(s$))
  1016. bg.red=Int(GetArg(s$))
  1017. bg.green=Int(GetArg(s$))
  1018. bg.blue=Int(GetArg(s$))
  1019. font_type=Int(GetArg(s$))
  1020. If fntLibrary[font_type] Then
  1021. font_name=FontName(fntLibrary[font_type])
  1022. font_size=FontSize(fntLibrary[font_type])
  1023. EndIf
  1024. End Method
  1025. Method Poll()
  1026. Local f:TGUIFont
  1027. Select EventSource()
  1028. Case fpanel
  1029. If EventID()=EVENT_MOUSEDOWN
  1030. Return fg.Request()
  1031. EndIf
  1032. Case bpanel
  1033. If EventID()=EVENT_MOUSEDOWN
  1034. Return bg.Request()
  1035. EndIf
  1036. Case fcombo, fbutton
  1037. If EventSource() = fcombo Then
  1038. If Not (EventData() < 0) Then
  1039. font_type = EventData()
  1040. f = fntLibrary[font_type]
  1041. EndIf
  1042. Else
  1043. font_type = 0
  1044. SelectGadgetItem fcombo, font_type
  1045. EndIf
  1046. If Not f Then f=RequestFont(font)
  1047. If f
  1048. font_name=FontName(f)
  1049. font_size=FontSize(f)
  1050. Return True
  1051. EndIf
  1052. End Select
  1053. End Method
  1054. Method Refresh()
  1055. font=fntLibrary[font_type]
  1056. If Not font Then font=LoadGuiFont(font_name,font_size)
  1057. SetPanelColor fpanel,fg.red,fg.green,fg.blue
  1058. SetPanelColor bpanel,bg.red,bg.green,bg.blue
  1059. SelectGadgetItem fcombo, font_type
  1060. Local tmpFloatText$[] = String(font_size).Split(".")
  1061. If tmpFloatText.length > 1 Then tmpFloatText[1] = tmpFloatText[1][..Min(2,tmpFloatText[1].length)]
  1062. SetGadgetText fbutton,font_name+" : "+".".Join(tmpFloatText)+"pt"
  1063. End Method
  1064. Function Create:TGadgetStyle(name$,xpos,ypos,window:TGadget)
  1065. Local s:TGadgetStyle
  1066. s=New TGadgetStyle
  1067. s.fg=New TColor
  1068. s.bg=New TColor
  1069. s.label=CreateLabel(name,xpos,ypos+ScaledSize(LABELOFFSET),ScaledSize(66),ScaledSize(50),window)
  1070. s.fpanel=CreatePanel(xpos+ScaledSize(88),ypos,ScaledSize(24),ScaledSize(24),window,PANEL_BORDER|PANEL_ACTIVE)
  1071. s.bpanel=CreatePanel(xpos+ScaledSize(116),ypos,ScaledSize(24),ScaledSize(24),window,PANEL_BORDER|PANEL_ACTIVE)
  1072. s.fbutton=CreateButton("..",xpos+ScaledSize(142),ypos+ScaledSize(30),ClientWidth(window)-(xpos+ScaledSize(148)),ScaledSize(24),window)
  1073. s.fcombo=CreateComboBox(xpos+ScaledSize(142),ypos,ClientWidth(window)-(xpos+ScaledSize(148)),ScaledSize(24),window)
  1074. AddGadgetItem s.fcombo, "{{options_font_desc_user}}", GADGETITEM_DEFAULT|GADGETITEM_LOCALIZED
  1075. AddGadgetItem s.fcombo, "{{options_font_desc_guidefault}}", GADGETITEM_LOCALIZED
  1076. AddGadgetItem s.fcombo, "{{options_font_desc_monospaced}}", GADGETITEM_LOCALIZED
  1077. AddGadgetItem s.fcombo, "{{options_font_desc_sansserif}}", GADGETITEM_LOCALIZED
  1078. AddGadgetItem s.fcombo, "{{options_font_desc_serif}}", GADGETITEM_LOCALIZED
  1079. AddGadgetItem s.fcombo, "{{options_font_desc_script}}", GADGETITEM_LOCALIZED
  1080. Return s
  1081. End Function
  1082. End Type
  1083. Const NORMAL=0
  1084. Const COMMENT=1
  1085. Const QUOTED=2
  1086. Const KEYWORD=3
  1087. Const NUMBER=4
  1088. Const MATCHING=5
  1089. Type TOptionsRequester Extends TPanelRequester
  1090. ' panels
  1091. Field optionspanel:TGadget,editorpanel:TGadget,toolpanel:TGadget,appstubpanel:TGadget
  1092. ' settings
  1093. Field showtoolbar,restoreopenfiles,autocapitalize,syntaxhighlight,autobackup,autoindent,hideoutput
  1094. Field bracketmatching, externalhelp,systemkeys,sortcode,restartaftershutdown
  1095. Field tabsize,language$
  1096. Field editfontname$,editfontsize,editcolor:TColor
  1097. Field outputfontname$,outputfontsize,outputcolor:TColor
  1098. ' states
  1099. Field editfont:TGUIFont
  1100. ' gadgets
  1101. Field languages:TGadget
  1102. Field tabbutton:TGadget
  1103. Field editpanel:TGadget,editbutton:TGadget
  1104. Field buttons:TGadget[12]
  1105. Field styles:TTextStyle[]
  1106. Field textarea:TGadget
  1107. Field outputstyle:TGadgetStyle
  1108. Field navstyle:TGadgetStyle
  1109. Field dirty
  1110. Field undo:TBank
  1111. Field appstublist:TGadget
  1112. Field appstubs:String[]
  1113. Field appstubedit:TGadget
  1114. Field addappstub:TGadget
  1115. Field delappstub:TGadget
  1116. Field caretStyle:TCaretStyle
  1117. Field lineNumberStyle:TLineNumberStyle
  1118. Field outputLineNumberStyle:TLineNumberStyle
  1119. Method Show()
  1120. RefreshGadgets()
  1121. Super.Show()
  1122. EndMethod
  1123. Method Snapshot()
  1124. If Not undo undo=CreateBank(8192)
  1125. Local stream:TStream=CreateBankStream(undo)
  1126. write stream
  1127. stream.close
  1128. End Method
  1129. Method Restore()
  1130. If Not undo Return
  1131. Local stream:TStream=CreateBankStream(undo)
  1132. Read stream
  1133. stream.close
  1134. End Method
  1135. Method SetDefaults()
  1136. language=DEFAULT_LANGUAGEPATH
  1137. bracketmatching=True
  1138. showtoolbar=True
  1139. restoreopenfiles=True
  1140. autocapitalize=True
  1141. syntaxhighlight=True
  1142. autobackup=True
  1143. autoindent=True
  1144. tabsize=4
  1145. editfontname$=FontName(TGadgetStyle.fntLibrary[GUIFONT_MONOSPACED])
  1146. editfontsize=FontSize(TGadgetStyle.fntLibrary[GUIFONT_MONOSPACED])
  1147. editcolor.set( $334455 )
  1148. styles[NORMAL].set( $ffffff,0 )
  1149. styles[COMMENT].set( $bbeeff,0 )
  1150. styles[QUOTED].set( $00ff66,0 )
  1151. styles[KEYWORD].set( $ffff00,0 )
  1152. styles[NUMBER].set( $40ffff,0 )
  1153. styles[MATCHING].set( $ff4040,TEXTFORMAT_BOLD )
  1154. outputstyle.set(0,-1,GUIFONT_MONOSPACED)
  1155. outputLineNumberStyle.set(0,$ededed, False)
  1156. navstyle.set(0,-1,GUIFONT_SYSTEM)
  1157. appstubs = ["brl.appstub"]
  1158. caretStyle.set($ffffff,1, $ffffff, False)
  1159. lineNumberStyle.set($ffffff,$425c75, True)
  1160. restartaftershutdown=True
  1161. RefreshGadgets
  1162. End Method
  1163. Method Write(stream:TStream)
  1164. stream.WriteLine "[Options]"
  1165. stream.WriteLine "language="+language
  1166. stream.WriteLine "showtoolbar="+showtoolbar
  1167. stream.WriteLine "restoreopenfiles="+restoreopenfiles
  1168. stream.WriteLine "autocapitalize="+autocapitalize
  1169. stream.WriteLine "syntaxhighlight="+syntaxhighlight
  1170. stream.WriteLine "bracketmatching="+bracketmatching
  1171. stream.WriteLine "autobackup="+autobackup
  1172. stream.WriteLine "autoindent="+autoindent
  1173. stream.WriteLine "tabsize="+tabsize
  1174. stream.WriteLine "editfontname="+editfontname
  1175. stream.WriteLine "editfontsize="+editfontsize
  1176. stream.WriteLine "editcolor="+editcolor.ToString()
  1177. stream.WriteLine "normal_style="+styles[NORMAL].ToString()
  1178. stream.WriteLine "comment_style="+styles[COMMENT].ToString()
  1179. stream.WriteLine "quote_style="+styles[QUOTED].ToString()
  1180. stream.WriteLine "keyword_style="+styles[KEYWORD].ToString()
  1181. stream.WriteLine "number_style="+styles[NUMBER].ToString()
  1182. stream.WriteLine "matched_style="+styles[MATCHING].ToString()
  1183. stream.WriteLine "console_style="+outputstyle.ToString() 'Renamed from 'output_style' to bump users to default monospace font.
  1184. stream.WriteLine "console_linenumber_style="+outputLineNumberStyle.ToString()
  1185. stream.WriteLine "navi_style="+navstyle.ToString() 'Renamed from 'nav_style' to bump users to default treeview font.
  1186. stream.WriteLine "hide_output="+hideoutput
  1187. stream.WriteLine "external_help="+externalhelp
  1188. stream.WriteLine "system_keys="+systemkeys
  1189. stream.WriteLine "sort_code="+sortcode
  1190. stream.WriteLine "restart_after_shutdown="+restartaftershutdown
  1191. For Local i:Int = 1 Until appstubs.length
  1192. stream.WriteLine "appstub_" + i + "="+appstubs[i]
  1193. Next
  1194. stream.WriteLine "caret_style="+caretstyle.ToString()
  1195. stream.WriteLine "linenumber_style="+lineNumberStyle.ToString()
  1196. End Method
  1197. Method Read(stream:TStream)
  1198. Local f$,p,a$,b$,t
  1199. appstubs = ["brl.appstub"]
  1200. While Not stream.Eof()
  1201. f$=stream.ReadLine()
  1202. If f$="" Or (f$[..1]="[" And f$<>"[Options]") Exit
  1203. p=f.find("=")
  1204. a$=f[..p]
  1205. b$=f[p+1..]
  1206. t=Int(b)
  1207. Select a$
  1208. Case "showtoolbar" showtoolbar=t
  1209. Case "restoreopenfiles" restoreopenfiles=t
  1210. Case "autocapitalize" autocapitalize=t
  1211. Case "syntaxhighlight" syntaxhighlight=t
  1212. Case "bracketmatching" bracketmatching=t
  1213. Case "autobackup" autobackup=t
  1214. Case "autoindent" autoindent=t
  1215. Case "tabsize" tabsize=t
  1216. Case "editfontname" editfontname=b
  1217. Case "editfontsize" editfontsize=t
  1218. Case "editcolor" editcolor.FromString(b)
  1219. Case "normal_style" styles[NORMAL].FromString(b)
  1220. Case "comment_style" styles[COMMENT].FromString(b)
  1221. Case "quote_style" styles[QUOTED].FromString(b)
  1222. Case "keyword_style" styles[KEYWORD].FromString(b)
  1223. Case "number_style" styles[NUMBER].FromString(b)
  1224. Case "matched_style" styles[MATCHING].FromString(b)
  1225. Case "console_style" outputstyle.FromString(b) 'Renamed from 'output_style' to bump users to default monospace font.
  1226. Case "console_linenumber_style" outputLineNumberStyle.FromString(b)
  1227. Case "navi_style" navstyle.FromString(b) 'Renamed from 'nav_style' to bump users to default treeview font.
  1228. Case "hide_output" hideoutput=t
  1229. Case "external_help" externalhelp=t
  1230. Case "system_keys" systemkeys=t
  1231. Case "sort_code" sortcode=t
  1232. Case "restart_after_shutdown" restartaftershutdown=t
  1233. Case "caret_style" caretstyle.FromString(b)
  1234. Case "linenumber_style" lineNumberStyle.FromString(b)
  1235. Case "language"
  1236. Try
  1237. Local tmpLanguage:TMaxGUILanguage = LoadLanguage(host.FullPath(b))
  1238. If tmpLanguage Then
  1239. language = b
  1240. SetLocalizationLanguage tmpLanguage
  1241. host.RefreshMenu()
  1242. EndIf
  1243. Catch excn:Object
  1244. EndTry
  1245. End Select
  1246. If a.StartsWith("appstub_") Then
  1247. appstubs :+ [b]
  1248. End If
  1249. Wend
  1250. RefreshGadgets
  1251. End Method
  1252. Method RefreshGadgets()
  1253. Local rgb:TColor,flags
  1254. editfont=LoadGuiFont(editfontname,editfontsize)
  1255. 'Language Loading / Enumeration
  1256. ClearGadgetItems languages
  1257. AddGadgetItem languages, "English (English) [Embedded]", GADGETITEM_DEFAULT,-1,"",DEFAULT_LANGUAGEPATH
  1258. For Local tmpFile$ = EachIn LoadDir( host.bmxpath+"/cfg", True )
  1259. Local tmpPath$ = host.bmxpath+"/cfg/"+tmpFile
  1260. If FileType(tmpPath) = FILETYPE_FILE And tmpFile.ToLower().EndsWith(".language.ini") Then
  1261. If tmpPath = host.FullPath(language) Then flags = GADGETITEM_DEFAULT Else flags = 0
  1262. AddGadgetItem languages, tmpFile.Split(".")[0], flags, -1, "", "$BMXPATH/cfg/"+tmpFile
  1263. EndIf
  1264. Next
  1265. SetButtonState buttons[0],showtoolbar
  1266. SetButtonState buttons[1],restoreopenfiles
  1267. SetButtonState buttons[2],autocapitalize
  1268. SetButtonState buttons[3],syntaxhighlight
  1269. SetButtonState buttons[4],bracketmatching
  1270. SetButtonState buttons[5],autobackup
  1271. SetButtonState buttons[6],autoindent
  1272. SetButtonState buttons[7],hideoutput
  1273. SetButtonState buttons[8],externalhelp
  1274. SetButtonState buttons[9],systemkeys
  1275. SetButtonState buttons[10],sortcode
  1276. SetButtonState buttons[11],restartaftershutdown
  1277. SelectGadgetItem tabbutton,Min(Max(tabsize/2-1,0),7)
  1278. SetPanelColor editpanel,editcolor.red,editcolor.green,editcolor.blue
  1279. SetGadgetText editbutton,editfontname+" : "+editfontsize + "pt"
  1280. For Local i:Int = 0 Until styles.length
  1281. styles[i].Refresh
  1282. Next
  1283. caretstyle.Refresh
  1284. LockTextArea textarea
  1285. SetTextAreaColor textarea,editcolor.red,editcolor.green,editcolor.blue,True
  1286. SetGadgetFont textarea,editfont
  1287. styles[NORMAL].format(textarea,0,TEXTAREA_ALL)
  1288. styles[COMMENT].format(textarea,0,12)
  1289. styles[MATCHING].format(textarea,24,1)
  1290. styles[NUMBER].format(textarea,25,3)
  1291. styles[NUMBER].format(textarea,31,1)
  1292. styles[MATCHING].format(textarea,32,1)
  1293. styles[NUMBER].format(textarea,36,1)
  1294. styles[KEYWORD].format(textarea,39,5)
  1295. styles[QUOTED].format(textarea,46,10)
  1296. lineNumberStyle.Refresh
  1297. TextAreaSetLineNumberBackColor textarea, lineNumberStyle.bg.red, lineNumberStyle.bg.green, lineNumberStyle.bg.blue
  1298. TextAreaSetLineNumberForeColor textarea, lineNumberStyle.fg.red, lineNumberStyle.fg.green, lineNumberStyle.fg.blue
  1299. TextAreaSetLineNumberEnable textarea, lineNumberStyle.flags
  1300. TextAreaSetCaretLineBackgroundColor(textarea, caretStyle.caretLineColor.red, caretStyle.caretLineColor.green, caretStyle.caretLineColor.blue, caretStyle.caretLineAlpha)
  1301. TextAreaSetCaretLineVisible(textarea, caretStyle.caretLineVisible)
  1302. TextAreaSetBracketMatchingColor textarea, styles[MATCHING].color.red, styles[MATCHING].color.green, styles[MATCHING].color.blue, styles[MATCHING].flags
  1303. UnlockTextArea textarea
  1304. outputstyle.Refresh
  1305. outputLineNumberStyle.Refresh
  1306. navstyle.Refresh
  1307. dirty=True
  1308. ClearGadgetItems appstublist
  1309. For Local appstub:String = EachIn appstubs
  1310. AddGadgetItem appstublist,appstub
  1311. Next
  1312. DisableGadget addappstub
  1313. DisableGadget delappstub
  1314. End Method
  1315. Method Poll()
  1316. Local font:TGUIFont,refresh,processed = 1
  1317. For Local i:Int = 0 Until styles.length
  1318. refresh:|styles[i].Poll()
  1319. Next
  1320. refresh:|caretstyle.Poll()
  1321. refresh:|lineNumberStyle.Poll()
  1322. refresh:|outputstyle.Poll()
  1323. refresh:|outputLineNumberStyle.Poll()
  1324. refresh:|navstyle.Poll()
  1325. Select EventID()
  1326. Case EVENT_GADGETACTION, EVENT_WINDOWCLOSE
  1327. Select EventSource()
  1328. Case buttons[0];showtoolbar=ButtonState(buttons[0]);dirty=True
  1329. Case buttons[1];restoreopenfiles=ButtonState(buttons[1])
  1330. Case buttons[2];autocapitalize=ButtonState(buttons[2]);dirty=True
  1331. Case buttons[3];syntaxhighlight=ButtonState(buttons[3]);dirty=True
  1332. Case buttons[4];bracketmatching=ButtonState(buttons[4])
  1333. Case buttons[5];autobackup=ButtonState(buttons[5])
  1334. Case buttons[6];autoindent=ButtonState(buttons[6])
  1335. Case buttons[7];hideoutput=ButtonState(buttons[7])
  1336. Case buttons[8];externalhelp=ButtonState(buttons[8])
  1337. Case buttons[9];systemkeys=ButtonState(buttons[9]);dirty=2
  1338. Case buttons[10];sortcode=ButtonState(buttons[10]);dirty=3
  1339. Case buttons[11];restartaftershutdown=ButtonState(buttons[11]);dirty=4
  1340. Case tabber;SetPanelIndex SelectedGadgetItem(tabber)
  1341. Case ok
  1342. Hide()
  1343. Select dirty
  1344. Case 1
  1345. host.RefreshAll
  1346. Case 2
  1347. host.Restart
  1348. Case 3
  1349. host.RefreshAppStubs
  1350. Case 4
  1351. host.UpdateRestartState()
  1352. End Select
  1353. dirty=False
  1354. SnapShot()
  1355. Case window
  1356. If EventID()=EVENT_WINDOWCLOSE
  1357. Restore()
  1358. dirty=False
  1359. Hide()
  1360. EndIf
  1361. Case cancel
  1362. Restore()
  1363. dirty=False
  1364. Hide()
  1365. Case tabbutton
  1366. tabsize=(SelectedGadgetItem(tabbutton)+1)*2
  1367. refresh=True
  1368. Case editpanel
  1369. If EventID()=EVENT_MOUSEDOWN
  1370. refresh=editcolor.Request()
  1371. EndIf
  1372. Case editbutton
  1373. font=RequestFont(editfont)
  1374. If font
  1375. editfontname=FontName(font)
  1376. editfontsize=FontSize(font)
  1377. refresh=True
  1378. EndIf
  1379. Case languages
  1380. If EventData() > 0 Then
  1381. language = String(GadgetItemExtra(languages,EventData()))
  1382. SetLocalizationLanguage TMaxGUILanguage(LoadLanguage(host.FullPath(language)))
  1383. Else
  1384. language = DEFAULT_LANGUAGEPATH
  1385. SetLocalizationLanguage defaultLanguage
  1386. EndIf
  1387. host.RefreshMenu()
  1388. Case addappstub
  1389. If GadgetText(appstubedit) Then
  1390. appstubs :+ [GadgetText(appstubedit).ToLower()]
  1391. SetGadgetText appstubedit, ""
  1392. End If
  1393. refresh=True
  1394. dirty=3
  1395. Case delappstub
  1396. Local index:Int = SelectedGadgetItem(appstublist)
  1397. If index > 0 Then
  1398. If index < appstubs.length
  1399. appstubs = appstubs[..index] + appstubs[index+1..]
  1400. Else
  1401. appstubs = appstubs[..index]
  1402. End If
  1403. refresh=True
  1404. dirty=3
  1405. End If
  1406. Case appstubedit
  1407. If GadgetText(appstubedit) Then
  1408. EnableGadget addappstub
  1409. Else
  1410. DisableGadget addappstub
  1411. End If
  1412. Default
  1413. processed = 0
  1414. EndSelect
  1415. Case EVENT_GADGETSELECT
  1416. Select EventSource()
  1417. Case appstublist
  1418. If SelectedGadgetItem(appstublist) > 0 Then
  1419. EnableGadget delappstub
  1420. Else
  1421. DisableGadget delappstub
  1422. End If
  1423. End Select
  1424. Case EVENT_MOUSEDOWN
  1425. Select EventSource()
  1426. Case editpanel
  1427. If EventID()=EVENT_MOUSEDOWN
  1428. editcolor.Request()
  1429. refresh=True
  1430. EndIf
  1431. Default
  1432. processed = 0
  1433. EndSelect
  1434. EndSelect
  1435. If refresh Then RefreshGadgets()
  1436. Return processed
  1437. End Method
  1438. Method InitOptionsRequester(host:TCodePlay)
  1439. Local w:TGadget
  1440. InitPanelRequester(host,"{{options_window_title}}", ScaledSize(420), ScaledSize(530))
  1441. ' init values
  1442. editcolor=New TColor
  1443. ' init gadgets
  1444. optionspanel=AddPanel("{{options_optionstab}}")
  1445. editorpanel=AddPanel("{{options_editortab}}")
  1446. toolpanel=AddPanel("{{options_toolstab}}")
  1447. appstubpanel=AddPanel("{{options_appstubtab}}")
  1448. SetGadgetShape( tabber, GadgetX(tabber), GadgetY(tabber)+ScaledSize(32), GadgetWidth(tabber), GadgetHeight(tabber)-ScaledSize(32) )
  1449. w=window
  1450. CreateLabel("{{options_options_label_language}}:",ScaledSize(6),ScaledSize(6+4),ScaledSize(80),ScaledSize(24),w)
  1451. languages = CreateComboBox(ScaledSize(90),ScaledSize(6),ClientWidth(w)-ScaledSize(96),ScaledSize(26),w)
  1452. w=optionspanel
  1453. buttons[0]=CreateButton("{{options_options_btn_showtoolbar}}",ScaledSize(6),ScaledSize(6),ClientWidth(w)-ScaledSize(12),ScaledSize(26),w,BUTTON_CHECKBOX)
  1454. buttons[1]=CreateButton("{{options_options_btn_autorestore}}",ScaledSize(6),ScaledSize(34),ClientWidth(w)-ScaledSize(12),ScaledSize(26),w,BUTTON_CHECKBOX)
  1455. buttons[2]=CreateButton("{{options_options_btn_autocaps}}",ScaledSize(6),ScaledSize(60),ClientWidth(w)-ScaledSize(12),ScaledSize(26),w,BUTTON_CHECKBOX)
  1456. buttons[3]=CreateButton("{{options_options_btn_syntaxhighlight}}",ScaledSize(6),ScaledSize(86),ClientWidth(w)-ScaledSize(12),ScaledSize(26),w,BUTTON_CHECKBOX)
  1457. buttons[4]=CreateButton("{{options_options_btn_bracketmatching}}",ScaledSize(6),ScaledSize(112),ClientWidth(w)-ScaledSize(12),ScaledSize(26),w,BUTTON_CHECKBOX)
  1458. buttons[5]=CreateButton("{{options_options_btn_autobackup}}",ScaledSize(6),ScaledSize(138),ClientWidth(w)-ScaledSize(12),ScaledSize(26),w,BUTTON_CHECKBOX)
  1459. buttons[6]=CreateButton("{{options_options_btn_autoindent}}",ScaledSize(6),ScaledSize(164),ClientWidth(w)-ScaledSize(12),ScaledSize(26),w,BUTTON_CHECKBOX)
  1460. buttons[7]=CreateButton("{{options_options_btn_autohideoutput}}",ScaledSize(6),ScaledSize(190),ClientWidth(w)-ScaledSize(12),ScaledSize(26),w,BUTTON_CHECKBOX)
  1461. buttons[8]=CreateButton("{{options_options_btn_useexternalbrowser}}",ScaledSize(6),ScaledSize(216),ClientWidth(w)-ScaledSize(12),ScaledSize(26),w,BUTTON_CHECKBOX)
  1462. buttons[9]=CreateButton("{{options_options_btn_osshortcuts}}",ScaledSize(6),ScaledSize(242),ClientWidth(w)-ScaledSize(12),ScaledSize(26),w,BUTTON_CHECKBOX)
  1463. buttons[10]=CreateButton("{{options_options_btn_sortcodeviewnodes}}",ScaledSize(6),ScaledSize(268),ClientWidth(w)-ScaledSize(12),ScaledSize(26),w,BUTTON_CHECKBOX)
  1464. buttons[11]=CreateButton("{{options_options_btn_restartaftershutdown}}",ScaledSize(6),ScaledSize(294),ClientWidth(w)-ScaledSize(12),ScaledSize(26),w,BUTTON_CHECKBOX)
  1465. w=editorpanel
  1466. CreateLabel("{{options_editor_label_background}}:",ScaledSize(6),ScaledSize(6+4),ScaledSize(90),ScaledSize(24),w)
  1467. editpanel=CreatePanel(ScaledSize(120),ScaledSize(6),ScaledSize(24),ScaledSize(24),w,PANEL_BORDER|PANEL_ACTIVE)
  1468. editbutton=CreateButton("..",ScaledSize(148),ScaledSize(6),ClientWidth(w)-ScaledSize(154),ScaledSize(24),w)
  1469. tabbutton=CreateComboBox(ScaledSize(148),ScaledSize(36),ClientWidth(w)-ScaledSize(154),ScaledSize(24),w)
  1470. For Local i=1 To 8
  1471. AddGadgetItem tabbutton,"{{options_editor_itemlabel_tabsize}} "+(i*2),GADGETITEM_LOCALIZED
  1472. Next
  1473. styles=New TTextStyle[6]
  1474. styles[NORMAL]=TTextStyle.Create("{{options_editor_label_plaintext}}:",ScaledSize(6),ScaledSize(70),w)
  1475. styles[COMMENT]=TTextStyle.Create("{{options_editor_label_remarks}}:",ScaledSize(6),ScaledSize(104),w)
  1476. styles[QUOTED]=TTextStyle.Create("{{options_editor_label_strings}}:",ScaledSize(6),ScaledSize(138),w)
  1477. styles[KEYWORD]=TTextStyle.Create("{{options_editor_label_keywords}}:",ScaledSize(6),ScaledSize(172),w)
  1478. styles[NUMBER]=TTextStyle.Create("{{options_editor_label_numbers}}:",ScaledSize(6),ScaledSize(206),w)
  1479. styles[MATCHING]=TTextStyle.Create("{{options_editor_label_matchings}}:",ScaledSize(6),ScaledSize(240),w)
  1480. caretstyle = TCaretStyle.Create("{{options_editor_label_caret}}:",ScaledSize(6),ScaledSize(274),w)
  1481. lineNumberStyle = TLineNumberStyle.Create("{{options_editor_label_line_number}}:",ScaledSize(6),ScaledSize(308),w)
  1482. textarea=CreateTextArea(ScaledSize(6),ScaledSize(342),ClientWidth(w)-ScaledSize(12),ClientHeight(w)-ScaledSize(250),w,TEXTAREA_READONLY)
  1483. SetGadgetText textarea,"'Sample Code~n~nresult = ((2.0 * 4) + 1)~nPrint( ~qResult: ~q + result )~n"
  1484. w=toolpanel
  1485. outputstyle=TGadgetStyle.Create("{{options_tools_label_output}}: ",ScaledSize(6),ScaledSize(6),w)
  1486. outputLineNumberStyle = TLineNumberStyle.Create("{{options_editor_label_output_line_number}}:",ScaledSize(6),ScaledSize(70),w)
  1487. navstyle=TGadgetStyle.Create("{{options_tools_label_navbar}}: ",ScaledSize(6),ScaledSize(104),w)
  1488. w=appstubpanel
  1489. appstublist=CreateListBox(ScaledSize(6),ScaledSize(6),ClientWidth(w)-ScaledSize(12),ClientHeight(w)-ScaledSize(95),w)
  1490. appstubedit=CreateTextField(ScaledSize(6),ClientHeight(w)-ScaledSize(81),ClientWidth(w)-ScaledSize(12),ScaledSize(21),w)
  1491. addappstub=CreateButton("{{options_appstub_btn_add}}",ScaledSize(6),ClientHeight(w)-ScaledSize(40),ScaledSize(140),ScaledSize(26),w,BUTTON_PUSH)
  1492. delappstub=CreateButton("{{options_appstub_btn_del}}",ClientWidth(w)-ScaledSize(146),ClientHeight(w)-ScaledSize(40),ScaledSize(140),ScaledSize(26),w,BUTTON_PUSH)
  1493. appstubs = ["brl.appstub"]
  1494. AddGadgetItem appstublist,appstubs[0]
  1495. DisableGadget addappstub
  1496. DisableGadget delappstub
  1497. SetDefaults()
  1498. SetPanel optionspanel
  1499. SnapShot
  1500. End Method
  1501. Function Create:TOptionsRequester(host:TCodePlay)
  1502. Local o:TOptionsRequester
  1503. o=New TOptionsRequester
  1504. o.InitOptionsRequester host
  1505. Return o
  1506. End Function
  1507. End Type
  1508. Type TFindRequester Extends TRequester
  1509. Field findterm:TGadget
  1510. Method ShowFind(term$="")
  1511. If term SetGadgetText(findterm,term)
  1512. Super.Show()
  1513. ActivateGadget findterm
  1514. End Method
  1515. Method Poll()
  1516. Local find$,data
  1517. Select EventSource()
  1518. Case window
  1519. If EventID()=EVENT_WINDOWCLOSE
  1520. Hide()
  1521. EndIf
  1522. Case ok
  1523. If EventID() = EVENT_GADGETACTION
  1524. If TextFieldText(findterm)
  1525. find=TextFieldText(findterm)
  1526. Hide()
  1527. host.activepanel.Invoke TOOLFINDNEXT,find
  1528. Else
  1529. Notify LocalizeString("{{search_error_nosearchstring}}"), True
  1530. ActivateGadget findterm
  1531. EndIf
  1532. EndIf
  1533. Case cancel
  1534. If EventID() = EVENT_GADGETACTION Then Hide()
  1535. Default
  1536. Return 0
  1537. End Select
  1538. Return 1
  1539. End Method
  1540. Function Create:TFindRequester(host:TCodePlay)
  1541. Local seek:TFindRequester
  1542. seek=New TFindRequester
  1543. seek.initrequester(host,"{{find_window_title}}",ScaledSize(280),ScaledSize(66),STYLE_OK|STYLE_CANCEL|STYLE_DIVIDER|STYLE_MODAL,"{{find_btn_find}}")
  1544. CreateLabel("{{find_label_find}}:",ScaledSize(6),ScaledSize(12),ScaledSize(82),ScaledSize(24),seek.window)
  1545. seek.findterm=CreateTextField(ScaledSize(88),ScaledSize(8),ClientWidth(seek.window)-ScaledSize(88+6),ScaledSize(21),seek.window)
  1546. Return seek
  1547. End Function
  1548. End Type
  1549. Type TReplaceRequester Extends TRequester
  1550. Field findterm:TGadget,replaceterm:TGadget
  1551. Field findnext:TGadget,replaceit:TGadget,replaceall:TGadget
  1552. Method Show()
  1553. Super.Show()
  1554. ActivateGadget findterm
  1555. End Method
  1556. Method Poll()
  1557. Local find$,Replace$
  1558. Select EventSource()
  1559. Case window
  1560. If EventID()=EVENT_WINDOWCLOSE
  1561. Hide()
  1562. EndIf
  1563. Case cancel
  1564. If EventID() = EVENT_GADGETACTION Then Hide
  1565. Case ok
  1566. If EventID() = EVENT_GADGETACTION Then
  1567. If TextFieldText(findterm) Then
  1568. find=TextFieldText(findterm)
  1569. host.activepanel.Invoke TOOLFINDNEXT,find
  1570. Else
  1571. Notify LocalizeString("{{search_error_nosearchstring}}"), True
  1572. ActivateGadget findterm
  1573. EndIf
  1574. EndIf
  1575. Case replaceit
  1576. If EventID() = EVENT_GADGETACTION Then
  1577. Replace=TextFieldText(replaceterm)
  1578. If host.activepanel.Invoke(TOOLREPLACE,Replace)
  1579. host.activepanel.Invoke TOOLFINDNEXT,find
  1580. EndIf
  1581. EndIf
  1582. Case replaceall
  1583. If EventID() = EVENT_GADGETACTION Then
  1584. find=TextFieldText(findterm)
  1585. Replace=TextFieldText(replaceterm)
  1586. host.activepanel.Invoke TOOLREPLACE,find+Chr(0)+Replace
  1587. EndIf
  1588. Default
  1589. Return 0
  1590. End Select
  1591. Return 1
  1592. End Method
  1593. Function Create:TReplaceRequester(host:TCodePlay)
  1594. Local x,y
  1595. Local seek:TReplaceRequester
  1596. seek=New TReplaceRequester
  1597. seek.initrequester(host,"{{replace_window_title}}",ScaledSize(410),ScaledSize(80),STYLE_OK|STYLE_CANCEL|STYLE_DIVIDER,"{{replace_btn_findnext}}")
  1598. y=11
  1599. CreateLabel( "{{replace_label_find}}:",ScaledSize(6),ScaledSize(y+4),ScaledSize(88),ScaledSize(24),seek.window )
  1600. seek.findterm=CreateTextField( ScaledSize(116),ScaledSize(y),ScaledSize(168),ScaledSize(21),seek.window )
  1601. y:+32
  1602. CreateLabel( "{{replace_label_replacewith}}:",ScaledSize(6),ScaledSize(y+4),ScaledSize(88),ScaledSize(24),seek.window )
  1603. seek.replaceterm=CreateTextField( ScaledSize(116),ScaledSize(y),ScaledSize(168),ScaledSize(21),seek.window )
  1604. x=ClientWidth(seek.window)-ScaledSize(122)
  1605. y=8
  1606. seek.replaceit=CreateButton("{{replace_btn_replace}}",x,ScaledSize(y),ScaledSize(96),ScaledSize(26),seek.window)
  1607. seek.replaceall=CreateButton("{{replace_btn_replaceall}}",x,ScaledSize(y+32),ScaledSize(96),ScaledSize(26),seek.window)
  1608. Return seek
  1609. End Function
  1610. End Type
  1611. Type TEventHandler Extends TTool
  1612. Method OnEvent() Abstract
  1613. End Type
  1614. Type TToolPanel Extends TEventHandler
  1615. Field name$,path$
  1616. Field panel:TGadget
  1617. Field index
  1618. Field active
  1619. Method Show()
  1620. End Method
  1621. End Type
  1622. Type TView
  1623. Field node:TGadget
  1624. Field state
  1625. End Type
  1626. Type TNode Extends TTool
  1627. Const HIDESTATE=0
  1628. Const CLOSEDSTATE=1
  1629. Const OPENSTATE=2
  1630. Field name$,sortname$
  1631. Field parent:TNode
  1632. Field kids:TList=New TList
  1633. Field views:TView[]
  1634. ' activate program
  1635. Field target:TTool
  1636. Field action
  1637. Field argument:Object
  1638. Method SortKids( ascending=True )
  1639. Local term:TLink=kids._head
  1640. Repeat
  1641. Local link:TLink=kids._head._succ
  1642. Local sorted=True
  1643. Repeat
  1644. Local succ:TLink=link._succ
  1645. If succ=term Exit
  1646. Local cc=TNode(link._value).sortname.Compare( TNode(succ._value).sortname )
  1647. If (cc>0 And ascending) Or (cc<0 And Not ascending)
  1648. Local link_pred:TLink=link._pred
  1649. Local succ_succ:TLink=succ._succ
  1650. link_pred._succ=succ
  1651. succ._succ=link
  1652. succ._pred=link_pred
  1653. link._succ=succ_succ
  1654. link._pred=succ
  1655. succ_succ._pred=link
  1656. sorted=False
  1657. Else
  1658. link=succ
  1659. EndIf
  1660. Forever
  1661. If sorted Return
  1662. term=link
  1663. Forever
  1664. End Method
  1665. Method FindArgument:TNode(arg:Object)
  1666. Local n:TNode,r:TNode,a$
  1667. If arg.Compare(argument)=0 Return Self
  1668. a$=(String(arg)).ToLower()
  1669. If a And a=(String(argument)).toLower() Return Self
  1670. For n=EachIn kids
  1671. r=n.FindArgument(arg)
  1672. If r Return r
  1673. Next
  1674. End Method
  1675. ?Debug
  1676. Method Dump(indent$="")
  1677. Local n:TNode
  1678. Print indent+name
  1679. indent:+"~t"
  1680. For n=EachIn kids
  1681. n.Dump indent
  1682. Next
  1683. End Method
  1684. ?
  1685. Method IsHidden()
  1686. Local v:TView
  1687. If Not parent Return False
  1688. For v=EachIn parent.views
  1689. If v.state=OPENSTATE Return False
  1690. Next
  1691. Return True
  1692. End Method
  1693. Method SetAction(tool:TTool,cmd,arg:Object=Null)
  1694. target=tool
  1695. action=cmd
  1696. argument=arg
  1697. End Method
  1698. Method Hide(v:TView=Null) 'null means hide in all views
  1699. For Local n:TNode = EachIn kids
  1700. n.hide v
  1701. Next
  1702. If v
  1703. If v.node FreeTreeViewNode v.node;v.node=Null
  1704. Else
  1705. For v=EachIn views
  1706. If v.node FreeTreeViewNode v.node;v.node=Null
  1707. Next
  1708. EndIf
  1709. End Method
  1710. Method Detach()
  1711. Hide()
  1712. If parent parent.kids.remove Self;parent=Null
  1713. End Method
  1714. Method FreeKids()
  1715. For Local n:TNode = EachIn kids
  1716. n.free
  1717. Next
  1718. End Method
  1719. Method Free()
  1720. FreeKids()
  1721. Detach()
  1722. target=Null;argument=Null;views=Null
  1723. End Method
  1724. Method Invoke(command,arg:Object=Null)
  1725. Select command
  1726. Case TOOLACTIVATE
  1727. If target Return target.Invoke(action,argument)
  1728. End Select
  1729. End Method
  1730. Method Find:TNode(treeviewnode:TGadget,view=0)
  1731. Local n:TNode,r:TNode
  1732. Local v:TView
  1733. v=getview(view)
  1734. If v And v.node=treeviewnode Return Self
  1735. For n=EachIn kids
  1736. r=n.Find(treeviewnode,view)
  1737. If r Return r
  1738. Next
  1739. End Method
  1740. Method SetNode(treeviewnode:TGadget,view=0)
  1741. Local v:TView = getview(view)
  1742. v.node=treeviewnode
  1743. open view
  1744. End Method
  1745. Method HighLight(view=-1)
  1746. Local v:TView
  1747. If view=-1
  1748. For view=0 Until views.length
  1749. HighLight view
  1750. Next
  1751. Return
  1752. EndIf
  1753. v=GetView(view)
  1754. If v.node SelectTreeViewNode v.node
  1755. End Method
  1756. Method Open(view=-1)
  1757. Local v:TView
  1758. If view=-1
  1759. For view=0 Until views.length
  1760. Open view
  1761. Next
  1762. Return
  1763. EndIf
  1764. v=GetView(view)
  1765. If v.state<>OPENSTATE
  1766. v.state=OPENSTATE
  1767. RefreshView view
  1768. ' If v.node ExpandTreeViewNode v.node
  1769. EndIf
  1770. End Method
  1771. Method Close(view=0)
  1772. Local v:TView = GetView(view)
  1773. If v.state<>CLOSEDSTATE
  1774. v.state=CLOSEDSTATE
  1775. ' If v.node CollapseTreeViewNode v.node
  1776. EndIf
  1777. End Method
  1778. Method GetState(view=0)
  1779. Return GetView(view).state
  1780. End Method
  1781. Method GetView:TView(view=0)
  1782. If view>=views.length
  1783. views=views[..view+1]
  1784. EndIf
  1785. If Not views[view] views[view] = New TView
  1786. Return views[view]
  1787. End Method
  1788. Method GetIndex()
  1789. Local node:TNode
  1790. Local i
  1791. If parent
  1792. For node=EachIn parent.kids
  1793. If node=Self Return i
  1794. i:+1
  1795. Next
  1796. EndIf
  1797. End Method
  1798. Method Refresh()
  1799. For Local i:Int = 0 Until views.length
  1800. RefreshView i
  1801. Next
  1802. End Method
  1803. Method RefreshView(view=0)
  1804. Local n:TNode,quick,nodeToOpen:TGadget
  1805. Local v:TView,vv:TView
  1806. Local node
  1807. If parent And parent.getstate(view)=CLOSEDSTATE quick=True
  1808. v=getview(view)
  1809. If v.node And parent
  1810. If GadgetText(v.node) <> name Then
  1811. ModifyTreeViewNode v.node,name
  1812. LocalizeGadget(v.node,name,"")
  1813. EndIf
  1814. If v.state=OPENSTATE nodeToOpen = v.node;quick = False
  1815. Else
  1816. If parent And name
  1817. vv=parent.getview(view)
  1818. If vv.node
  1819. v.node=InsertTreeViewNode(GetIndex(),name,vv.node)
  1820. If v.state=HIDESTATE v.state=CLOSEDSTATE
  1821. If vv.state=OPENSTATE nodeToOpen = vv.node
  1822. quick=False
  1823. EndIf
  1824. EndIf
  1825. EndIf
  1826. If quick Return
  1827. If Not kids Return
  1828. For n=EachIn kids
  1829. n.RefreshView view
  1830. Next
  1831. If nodeToOpen Then ExpandTreeViewNode nodeToOpen
  1832. End Method
  1833. Method NodeAfter:TNode(node:TNode)
  1834. Local link:TLink
  1835. If node link=kids.FindLink(node)
  1836. If link link=link.NextLink()
  1837. If link Return TNode(link.Value())
  1838. End Method
  1839. Method Sync(snap:TNode)
  1840. Local snapkid:TNode
  1841. Local currentkid:TNode
  1842. Local kid:TNode
  1843. Local t:TNode
  1844. Local link:TLink
  1845. If snap.name<>name Return
  1846. If kids.Count() currentkid=TNode(kids.First())
  1847. For snapkid=EachIn snap.kids
  1848. ' if same name in list
  1849. kid=currentkid
  1850. While kid
  1851. If kid.name=snapkid.name Exit
  1852. kid=NodeAfter(kid)
  1853. Wend
  1854. ' then remove entries in front
  1855. If kid
  1856. While currentkid<>kid
  1857. t=currentkid
  1858. currentkid=NodeAfter(currentkid)
  1859. t.free()
  1860. Wend
  1861. EndIf
  1862. ' if same name sync else insert
  1863. If currentkid And currentkid.name=snapkid.name 'merge values if same name
  1864. currentkid.Sync snapkid
  1865. currentkid=NodeAfter(currentkid)
  1866. Else
  1867. snapkid.detach
  1868. If currentkid
  1869. link=kids.FindLink(currentkid)
  1870. kids.InsertBeforeLink snapkid,link
  1871. Else
  1872. kids.AddLast snapkid
  1873. EndIf
  1874. snapkid.parent=Self
  1875. EndIf
  1876. Next
  1877. ' remove any entries at end
  1878. While currentkid
  1879. t=currentkid
  1880. currentkid=NodeAfter(currentkid)
  1881. t.free()
  1882. Wend
  1883. Refresh()
  1884. End Method
  1885. Method SetName(n$)
  1886. name=n
  1887. End Method
  1888. Method AddNode:TNode(name$)
  1889. Local v:TNode
  1890. v=New TNode
  1891. v.setname name
  1892. Append v
  1893. Return v
  1894. End Method
  1895. Method Append(v:TNode)
  1896. v.parent=Self
  1897. kids.AddLast v
  1898. End Method
  1899. Function CreateNode:TNode(name$)
  1900. Local node:TNode
  1901. node=New TNode
  1902. node.setname name
  1903. Return node
  1904. End Function
  1905. End Type
  1906. Type THelpPanel Extends TToolPanel
  1907. Field host:TCodePlay
  1908. Field htmlview:TGadget
  1909. Method AddLink:TNode(parent:TNode,name$,href$)
  1910. Local n:TNode
  1911. If parent
  1912. n=parent.AddNode(name)
  1913. Else
  1914. n=host.helproot
  1915. EndIf
  1916. If href href=RealPath(href)
  1917. n.SetAction(Self,TOOLNAVIGATE,href)
  1918. Return n
  1919. End Method
  1920. Method ImportLinks( node:TNode,path$ )
  1921. Local t$=path+"/index.html"
  1922. If FileType( t )<>FILETYPE_FILE Return
  1923. node=AddLink( node,StripDir( path ),t )
  1924. Local map:TMap=New TMap
  1925. 'scan for html files
  1926. For Local e$=EachIn LoadDir( path )
  1927. If e="index.html" Continue
  1928. Local p$=path+"/"+e
  1929. Select FileType( p )
  1930. Case FILETYPE_DIR
  1931. ImportLinks node,p
  1932. Case FILETYPE_FILE
  1933. If Not e.StartsWith( "_" ) And ExtractExt( e ).Tolower()="html"
  1934. map.Insert StripExt( e ),p
  1935. EndIf
  1936. End Select
  1937. Next
  1938. 'scan for anchors in index.html...
  1939. '
  1940. 'note: anchors must be quote enclosed and of simple form <a name="blah">
  1941. Local c$=CacheAndLoadText( t ),i
  1942. Repeat
  1943. i=c.Find( "<a name=~q",i )
  1944. If i=-1 Exit
  1945. i:+9
  1946. Local i2=c.Find( "~q>",i )
  1947. If i2=-1 Exit
  1948. Local q$=c[i..i2]
  1949. If q.StartsWith( "_" ) Continue
  1950. map.Insert q,t+"#"+q
  1951. i=i2+1
  1952. Forever
  1953. For Local kv:TKeyValue=EachIn map
  1954. AddLink node,String( kv.Key() ),String( kv.Value() )
  1955. Next
  1956. End Method
  1957. Method SyncDocs()
  1958. host.helproot.FreeKids
  1959. ImportLinks Null,host.bmxpath+"/docs/html"
  1960. Local link:TNode
  1961. For Local m$=EachIn EnumModules()
  1962. If m.StartsWith( "brl." ) Or m.StartsWith( "pub." ) Or m.StartsWith("maxgui.") Continue
  1963. Local p$=ModulePath( m )+"/doc/commands.html"
  1964. If FileType( p )<>FILETYPE_FILE Continue
  1965. If Not link link=AddLink( host.helproot,"{{navnode_thirdpartymods}}","" )
  1966. AddLink link,m,p
  1967. Next
  1968. link=AddLink( host.helproot,"{{navnode_moduleindex}}","" )
  1969. If FileType( host.bmxpath+"/docs/html/Modules/commands.txt" )=FILETYPE_FILE
  1970. Local comm$=CacheAndLoadText( host.bmxpath+"/docs/html/Modules/commands.txt" )
  1971. For Local line$=EachIn comm.Split( "~n" )
  1972. Local bits$[]=line.Split( "|" )
  1973. If bits.length<>2 Continue
  1974. Local i=bits[0].Find( " : " )
  1975. If i<>-1 bits[0]=bits[0][..i]
  1976. AddLink link,bits[0],host.bmxpath+bits[1]
  1977. Next
  1978. EndIf
  1979. host.helproot.Refresh
  1980. End Method
  1981. Method Invoke(command,argument:Object=Null)
  1982. Local href$
  1983. If Not htmlview Return
  1984. Select command
  1985. Case TOOLCUT
  1986. GadgetCut htmlview
  1987. Case TOOLCOPY
  1988. GadgetCopy htmlview
  1989. Case TOOLPASTE
  1990. GadgetPaste htmlview
  1991. Case TOOLSHOW
  1992. ActivateGadget htmlview
  1993. host.SetTitle
  1994. Case TOOLNAVIGATE
  1995. href$=String(argument)
  1996. If href Go href
  1997. Case TOOLPRINT
  1998. GadgetPrint htmlview
  1999. End Select
  2000. End Method
  2001. Method OnEvent()
  2002. Local url$,p,t$
  2003. If EventSource()=htmlview
  2004. Select EventID()
  2005. Case EVENT_GADGETACTION 'NAVIGATEREQUEST
  2006. url$=String( EventExtra() )
  2007. If url[..5]="http:"
  2008. OpenURL url
  2009. Else
  2010. p=url.findlast(".")
  2011. If p>-1
  2012. t$=url[p..].tolower()
  2013. If t$=".bmx"
  2014. If url.Find( "file://" )=0
  2015. url=url[7..]
  2016. ?Win32
  2017. url=url[1..]
  2018. ?
  2019. EndIf
  2020. url=url.Replace("%20"," ")
  2021. Local source:TOpenCode=host.OpenSource(url)
  2022. If source source.MakePathTemp
  2023. Else
  2024. url=url.Replace("\","/")
  2025. url=url.Replace("user/index","user/welcome")
  2026. url=url.Replace("lang/index","lang/welcome")
  2027. url=url.Replace("mods/index","mods/welcome")
  2028. Go url$
  2029. EndIf
  2030. EndIf
  2031. EndIf
  2032. End Select
  2033. EndIf
  2034. End Method
  2035. Method Go(url$,internal=False)
  2036. Local node:TNode
  2037. If host.options.externalhelp And Not internal
  2038. PollSystem
  2039. OpenURL url
  2040. MinimizeWindow host.window
  2041. PollSystem
  2042. Return
  2043. EndIf
  2044. HtmlViewGo htmlview,url
  2045. host.SelectPanel Self
  2046. node=host.helproot.FindArgument(RealPath(url))
  2047. If node
  2048. node.Highlight
  2049. ' Else
  2050. ' print "node not found"
  2051. EndIf
  2052. ActivateGadget htmlview
  2053. End Method
  2054. Method Home()
  2055. Go host.bmxpath+HOMEPAGE,True
  2056. End Method
  2057. Method Forward()
  2058. HtmlViewForward htmlview
  2059. End Method
  2060. Method Back()
  2061. HtmlViewBack htmlview
  2062. End Method
  2063. Function Create:THelpPanel(host:TCodePlay)
  2064. Local root,style
  2065. Local p:THelpPanel = New THelpPanel
  2066. p.host=host
  2067. p.name="{{tab_help}}"
  2068. codeplay.addpanel(p)
  2069. style=HTMLVIEW_NONAVIGATE 'HTMLVIEW_NOCONTEXTMENU
  2070. p.htmlview=CreateHTMLView(0,0,ClientWidth(p.panel),ClientHeight(p.panel),p.panel,style)
  2071. SetGadgetLayout p.htmlview,EDGE_ALIGNED,EDGE_ALIGNED,EDGE_ALIGNED,EDGE_ALIGNED
  2072. ' p.Home
  2073. p.SyncDocs
  2074. Return p
  2075. End Function
  2076. End Type
  2077. Type TSearchResult
  2078. Field filepath$
  2079. Field char%, line%
  2080. Field linestring$
  2081. Method AddToListbox( pGadget:TGadget )
  2082. AddGadgetItem pGadget, "[" + line + ", " + char + "] " + filepath, 0, -1, StripWhitespace(linestring,char), Self
  2083. EndMethod
  2084. Method Set:TSearchResult(pFilePath$,pChar%,pLine%,pLineString$)
  2085. filepath = pFilePath
  2086. char = pChar
  2087. line = pLine
  2088. linestring = pLineString
  2089. Return Self
  2090. EndMethod
  2091. Function StripWhitespace$(pString$,pChar%)
  2092. If pString.length < pChar Then Return pString
  2093. Local outString$
  2094. For Local i:Int = 0 Until pString.length
  2095. Select pString[i]
  2096. Case Asc(" "), Asc("~t"), Asc("~n"), Asc("~r")
  2097. If outString And Not outString.EndsWith(" ") Then outString:+" "
  2098. Default
  2099. outString:+pString[i..i+1]
  2100. EndSelect
  2101. Next
  2102. Return outString
  2103. EndFunction
  2104. EndType
  2105. Type TSearchRequester Extends TRequester
  2106. Const strSearchText$ = "{{search_btn_startsearch}}", strStopSearchText$ = "{{search_btn_stopsearch}}"
  2107. Global strFileExts$[][] = [["bmx"],filetypes.Split(","),String[](Null)]
  2108. Field findbox:TGadget,typebox:TGadget,pathbox:TGadget,pathbutton:TGadget,pathsubdir:TGadget,results:TGadget
  2109. Field lstSearchResults:TList = New TList
  2110. Field safetyCount% = -1, safetyThreshold = 500, safetyResetCount% = 0
  2111. Method Poll()
  2112. Local id:Int = EventID()
  2113. Local data:Int = EventData()
  2114. Select EventSource()
  2115. Case results
  2116. Select id
  2117. Case EVENT_GADGETACTION
  2118. Local tmpSearchResult:TSearchResult = TSearchResult(EventExtra())
  2119. If tmpSearchResult Then
  2120. host.DebugSource( tmpSearchResult.filepath, tmpSearchResult.line, tmpSearchResult.char )
  2121. 'Hide()
  2122. EndIf
  2123. EndSelect
  2124. Case pathbutton
  2125. If EventID()=EVENT_GADGETACTION
  2126. Local tmpString$ = RequestDir( LocalizeString("{{search_requestfolder_title}}"),GadgetText(pathbox))
  2127. If tmpString Then SetGadgetText(pathbox,tmpString)
  2128. EndIf
  2129. Case window
  2130. If EventID()=EVENT_WINDOWCLOSE Then Hide()
  2131. Case findbox
  2132. If EventID() = EVENT_GADGETACTION Then
  2133. If GadgetText(findbox) Then EnableGadget(ok) Else DisableGadget(ok)
  2134. EndIf
  2135. Case ok
  2136. If EventID()=EVENT_GADGETACTION
  2137. If safetyCount < 0 Then StartSearch() Else safetyCount = -2
  2138. EndIf
  2139. Case cancel
  2140. If EventID()=EVENT_GADGETACTION Then Hide()
  2141. End Select
  2142. End Method
  2143. Method Hide()
  2144. safetyCount = -2
  2145. Super.Hide()
  2146. EndMethod
  2147. Method ShowWithPath( pPath$ )
  2148. If pPath Then SetGadgetText( pathbox, pPath )
  2149. Show()
  2150. ActivateGadget( findbox )
  2151. EndMethod
  2152. Method StartSearch()
  2153. PollSystem()
  2154. Select FileType(RealPath(GadgetText(pathbox)))
  2155. Case FILETYPE_NONE
  2156. Notify LocalizeString("{{search_error_pathnotfound}}"),True
  2157. ActivateGadget(pathbox)
  2158. Return
  2159. Case FILETYPE_FILE
  2160. Notify LocalizeString("{{search_error_pathisfile}}"),True
  2161. ActivateGadget(pathbox)
  2162. Return
  2163. EndSelect
  2164. If Not GadgetText(findbox) Then
  2165. Notify LocalizeString("{{search_error_nosearchstring}}"),True
  2166. ActivateGadget(findbox);Return
  2167. EndIf
  2168. safetyResetCount = 0;safetyCount = 0
  2169. LocalizeGadget ok, strStopSearchText;ClearGadgetItems results
  2170. SearchPath( GadgetText(pathbox), strFileExts[SelectedGadgetItem(typebox)], GadgetText(findbox).ToLower(), ButtonState(pathsubdir) )
  2171. LocalizeGadget ok, strSearchText;safetyCount = -1
  2172. SetStatusText window, LocalizeString("{{search_msg_complete}}").Replace("%1",CountGadgetItems(results))
  2173. EndMethod
  2174. Method SearchPath(pPath$,pFileType$[],pString$,pRecurse% = True)
  2175. pPath$ = RealPath(pPath) 'Make sure we are using a real path
  2176. Local tmpSearchDir$[] = LoadDir(pPath,True) 'Load directors contents into string array
  2177. If Not tmpSearchDir Then Return 'Return if the directory is invalid
  2178. tmpSearchDir.Sort() 'Sort the contents alphabetically
  2179. SetStatusText window, LocalizeString("{{search_msg_searchingdir}}").Replace("%1", pPath) 'And let user know which directory is being searched
  2180. Local tmpFullPath$
  2181. For Local tmpItem$ = EachIn tmpSearchDir
  2182. tmpFullPath = pPath + "/" + tmpItem
  2183. Select FileType(tmpFullPath)
  2184. Case FILETYPE_NONE;Continue 'Skip item if, for whatever reason, it doesn't exist
  2185. Case FILETYPE_FILE 'If file, then check extension and search if valid
  2186. If Not pFileType
  2187. SearchFile(tmpFullPath,pString)
  2188. Else
  2189. Local tmpExt$ = ExtractExt(tmpFullPath).ToLower$()
  2190. For Local tmpValidExt$ = EachIn pFileType
  2191. If tmpExt = tmpValidExt Then SearchFile(tmpFullPath,pString)
  2192. Next
  2193. EndIf
  2194. Case FILETYPE_DIR 'If folder, then we might have to search recursively
  2195. If pRecurse Then SearchPath(tmpFullPath,pFileType,pString,pRecurse)
  2196. EndSelect
  2197. If Not ShouldContinue() Then Return
  2198. Next
  2199. PollSystem();If PeekEvent() Then host.Poll() 'Let the system update as we could be searching a while
  2200. EndMethod
  2201. Method SearchFile(pPath$,pString$)
  2202. Local tmpText$ = CacheAndLoadText( pPath ), tmpLines$[], tmpFindPos%, tmpCharCount%, tmpLineNo%
  2203. Local tmpStringLength% = pString.length, tmpChunkLines$[], tmpPrevLines$
  2204. If tmpText Then
  2205. tmpLines = tmpText.Split("~n")
  2206. tmpText = tmpText.ToLower()
  2207. tmpFindPos = tmpText.Find(pString)
  2208. While ShouldContinue() And tmpFindPos > -1
  2209. tmpChunkLines = tmpText[..tmpFindPos].Split("~n")
  2210. tmpPrevLines = "~n".Join(tmpChunkLines[..tmpChunkLines.length-1])
  2211. tmpLineNo:+(tmpChunkLines.length)-1
  2212. Local tmpSearchResult:TSearchResult = New TSearchResult.Set(pPath,tmpFindPos-tmpPrevLines.length,tmpLineNo+1,tmpLines[tmpLineNo])
  2213. tmpSearchResult.AddToListbox(results);safetyCount:+1
  2214. tmpCharCount:+tmpFindPos+tmpStringLength
  2215. tmpText = tmpText[tmpFindPos+tmpStringLength..]
  2216. tmpFindPos = tmpText.Find(pString)
  2217. Wend
  2218. EndIf
  2219. EndMethod
  2220. Method ShouldContinue()
  2221. If safetyCount < 0 Then Return False
  2222. If safetyCount >= safetyThreshold Then
  2223. If Confirm( LocalizeString("{{search_safetynotification}}").Replace("%1",(safetyResetCount*safetyThreshold)+safetyCount) ) Then
  2224. safetyCount = 0
  2225. safetyResetCount:+1
  2226. Else
  2227. safetyCount = -1
  2228. Return False
  2229. EndIf
  2230. EndIf
  2231. Return True
  2232. EndMethod
  2233. Function Create:TSearchRequester(host:TCodePlay)
  2234. Local search:TSearchRequester = New TSearchRequester
  2235. search.initrequester(host,"{{search_window_title}}",ScaledSize(440),ScaledSize(280),STYLE_CANCEL|STYLE_DIVIDER|STYLE_OK|STYLE_STATUS|STYLE_RESIZABLE,strSearchText)
  2236. DisableGadget(search.ok)
  2237. SetGadgetLayout(CreateLabel("{{search_label_find}}:",ScaledSize(6),ScaledSize(8+4),ScaledSize(95),ScaledSize(24),search.window),EDGE_ALIGNED,EDGE_CENTERED,EDGE_ALIGNED,EDGE_CENTERED)
  2238. search.findbox=CreateTextField(ScaledSize(103),ScaledSize(8),ClientWidth(search.window)-ScaledSize(103+6),ScaledSize(21),search.window);SetGadgetLayout(search.findbox,EDGE_ALIGNED,EDGE_ALIGNED,EDGE_ALIGNED,EDGE_CENTERED)
  2239. SetGadgetLayout(CreateLabel("{{search_label_filetypes}}:",ScaledSize(6),ScaledSize(38+4),ScaledSize(95),ScaledSize(24),search.window),EDGE_ALIGNED,EDGE_CENTERED,EDGE_ALIGNED,EDGE_CENTERED)
  2240. search.typebox=CreateComboBox(ScaledSize(103),ScaledSize(38),ClientWidth(search.window)-ScaledSize(103+6),ScaledSize(24),search.window);SetGadgetLayout(search.typebox,EDGE_ALIGNED,EDGE_ALIGNED,EDGE_ALIGNED,EDGE_CENTERED)
  2241. AddGadgetItem( search.typebox, "{{search_type_bmaxfiles}}",GADGETITEM_DEFAULT|GADGETITEM_LOCALIZED,-1,"*.bmx" )
  2242. AddGadgetItem( search.typebox, "{{search_type_codefiles}}",GADGETITEM_LOCALIZED,-1,fileTypes )
  2243. AddGadgetItem( search.typebox, "{{search_type_allfiles}}",GADGETITEM_LOCALIZED,-1,"*")
  2244. SetGadgetLayout(CreateLabel("{{search_label_searchpath}}:",ScaledSize(6),ScaledSize(68+4),ScaledSize(95),ScaledSize(24),search.window),1,0,1,0)
  2245. search.pathbox=CreateTextField(ScaledSize(103),ScaledSize(68),ClientWidth(search.window)-ScaledSize(103+6+30+6+6+6),ScaledSize(21),search.window);SetGadgetLayout(search.pathbox,EDGE_ALIGNED,EDGE_ALIGNED,EDGE_ALIGNED,EDGE_CENTERED)
  2246. search.pathbutton=CreateButton("..",ClientWidth(search.window)-ScaledSize(34+6+6),ScaledSize(68),ScaledSize(34),ScaledSize(21),search.window);SetGadgetLayout(search.pathbutton,EDGE_CENTERED,EDGE_ALIGNED,EDGE_ALIGNED,EDGE_CENTERED)
  2247. SetGadgetText(search.pathbox, CurrentDir())
  2248. search.pathsubdir=CreateButton("{{search_btn_searchsubfolders}}",ScaledSize(103),ScaledSize(98),ClientWidth(search.window)-ScaledSize(103+6),ScaledSize(20),search.window,BUTTON_CHECKBOX);SetGadgetLayout(search.pathsubdir,EDGE_ALIGNED,EDGE_ALIGNED,EDGE_ALIGNED,EDGE_CENTERED)
  2249. SetButtonState(search.pathsubdir,True)
  2250. search.results=CreateListBox(ScaledSize(8),ScaledSize(128),ClientWidth(search.window)-ScaledSize(16),ScaledSize(280-(128+6)),search.window);SetGadgetLayout(search.results,EDGE_ALIGNED,EDGE_ALIGNED,EDGE_ALIGNED,EDGE_ALIGNED)
  2251. Return search
  2252. End Function
  2253. End Type
  2254. Type TProjectRequester Extends TRequester
  2255. Field projects:TProjects
  2256. Field listbox:TGadget
  2257. Field add:TGadget
  2258. Field remove:TGadget
  2259. Field props:TGadget
  2260. Field moveup:TGadget
  2261. Field movedown:TGadget
  2262. Field Current:TProjectFolderNode
  2263. Method Invoke(command,arg:Object=Null)
  2264. Select command
  2265. Case TOOLACTIVATE
  2266. Refresh
  2267. End Select
  2268. End Method
  2269. Method SetCurrent(i)
  2270. If i=-1
  2271. DisableGadget remove
  2272. DisableGadget moveup
  2273. DisableGadget movedown
  2274. DisableGadget props
  2275. Current=Null
  2276. Else
  2277. Current=TProjectFolderNode(GadgetItemExtra(listbox,i))
  2278. If Current
  2279. EnableGadget remove
  2280. EnableGadget props
  2281. EnableGadget moveup
  2282. EnableGadget movedown
  2283. EndIf
  2284. EndIf
  2285. End Method
  2286. Method Poll()
  2287. Local index
  2288. Select EventSource()
  2289. Case window
  2290. If EventID()=EVENT_WINDOWCLOSE Then Hide()
  2291. Case add
  2292. If EventID() = EVENT_GADGETACTION Then
  2293. projects.NewProject
  2294. Refresh
  2295. EndIf
  2296. Case remove
  2297. If EventID() = EVENT_GADGETACTION Then
  2298. projects.RemoveProject SelectedGadgetItem(listbox)
  2299. Refresh
  2300. EndIf
  2301. Case cancel
  2302. If EventID() = EVENT_GADGETACTION Then Hide
  2303. Case props
  2304. If EventID() = EVENT_GADGETACTION And Current
  2305. host.projectprops.Open(Current)
  2306. EndIf
  2307. Case listbox
  2308. If EventID()=EVENT_GADGETSELECT
  2309. SetCurrent SelectedGadgetItem(listbox) 'EventData()
  2310. ElseIf EventID()=EVENT_GADGETACTION
  2311. SetCurrent SelectedGadgetItem(listbox)
  2312. host.projectprops.Open(Current)
  2313. EndIf
  2314. Case moveup
  2315. If EventID()=EVENT_GADGETACTION Then
  2316. index=projects.MoveProject(SelectedGadgetItem(listbox),-1)
  2317. Refresh
  2318. SelectGadgetItem listbox,index
  2319. SetCurrent(index)
  2320. EndIf
  2321. Case movedown
  2322. If EventID()=EVENT_GADGETACTION Then
  2323. index=projects.MoveProject(SelectedGadgetItem(listbox),1)
  2324. Refresh
  2325. SelectGadgetItem listbox,index
  2326. SetCurrent(index)
  2327. EndIf
  2328. End Select
  2329. End Method
  2330. Method Refresh()
  2331. ClearGadgetItems listbox
  2332. For Local node:TNode = EachIn projects.kids
  2333. If TFolderNode(node)'node.argument
  2334. AddGadgetItem listbox,node.name,0,-1,"",node
  2335. EndIf
  2336. Next
  2337. SetCurrent -1
  2338. End Method
  2339. Method Open(projnode:TProjects)
  2340. projects=projnode
  2341. Refresh
  2342. Show
  2343. End Method
  2344. Function Create:TProjectRequester(host:TCodePlay)
  2345. Local x,y
  2346. Local proj:TProjectRequester = New TProjectRequester
  2347. proj.initrequester(host,"{{projman_window_title}}",ScaledSize(440),ScaledSize(188),STYLE_CANCEL|STYLE_DIVIDER|STYLE_MODAL)
  2348. proj.listbox=CreateListBox( ScaledSize(6),ScaledSize(8),ScaledSize(244),ScaledSize(174),proj.window )
  2349. x=ClientWidth(proj.window)-ScaledSize(164)
  2350. proj.add=CreateButton("{{projman_btn_addproj}}",x,ScaledSize(8),ScaledSize(158),ScaledSize(26),proj.window)
  2351. proj.remove=CreateButton("{{projman_btn_delproj}}",x,ScaledSize(44),ScaledSize(158),ScaledSize(26),proj.window)
  2352. proj.moveup=CreateButton("{{projman_btn_moveup}}",x,ScaledSize(80),ScaledSize(158),ScaledSize(26),proj.window)
  2353. proj.movedown=CreateButton("{{projman_btn_movedn}}",x,ScaledSize(116),ScaledSize(158),ScaledSize(26),proj.window)
  2354. proj.props=CreateButton("{{projman_btn_properties}}",x,ScaledSize(152),ScaledSize(158),ScaledSize(26),proj.window)
  2355. DisableGadget proj.remove
  2356. DisableGadget proj.moveup
  2357. DisableGadget proj.movedown
  2358. DisableGadget proj.props
  2359. Return proj
  2360. End Function
  2361. End Type
  2362. Type TProjectProperties Extends TRequester
  2363. Field proj:TProjectFolderNode
  2364. Field newproj:Int = False 'If 'True' then cancel/close deletes project.
  2365. Field localname:TGadget
  2366. Field localpath:TGadget
  2367. Field pathbutton:TGadget
  2368. Field poprequester:TRequester 'hack for restoring to projectmanager requester
  2369. Field dirty
  2370. Method Invoke(command,arg:Object=Null)
  2371. Select command
  2372. Case TOOLACTIVATE
  2373. Refresh
  2374. End Select
  2375. End Method
  2376. Method Tidy()
  2377. newproj = False
  2378. If dirty
  2379. proj.Set GadgetText(localname),GadgetText(localpath)
  2380. dirty=False
  2381. EndIf
  2382. End Method
  2383. Method Poll()
  2384. If (EventID() <> EVENT_GADGETACTION) And (EventID() <> EVENT_WINDOWCLOSE) Then Return
  2385. Select EventSource()
  2386. Case localname,localpath
  2387. dirty=True
  2388. Case pathbutton
  2389. Local dir$=RequestDir(LocalizeString("{{project_requestfolder_title}}"))
  2390. If dir
  2391. If dir[dir.length-1..]="/" 'fltk hack
  2392. dir=dir[..dir.length-1]
  2393. EndIf
  2394. SetGadgetText localpath,dir
  2395. If GadgetText(localname)=""
  2396. SetGadgetText localname,StripDir(dir)
  2397. EndIf
  2398. dirty=True
  2399. EndIf
  2400. Case ok
  2401. Tidy()
  2402. Hide()
  2403. Case cancel
  2404. Hide()
  2405. Case window
  2406. If EventID()=EVENT_WINDOWCLOSE
  2407. Hide()
  2408. EndIf
  2409. End Select
  2410. End Method
  2411. Method Hide()
  2412. If proj And newproj Then proj.Free()
  2413. EnableGadget host.window
  2414. HideGadget window
  2415. host.UnhookRequester Self'poprequester
  2416. If poprequester poprequester.Show
  2417. End Method
  2418. Method Refresh()
  2419. SetGadgetText localname,proj.name
  2420. SetGadgetText localpath,proj.path
  2421. End Method
  2422. Method Open(projnode:TProjectFolderNode, newproject:Int = False)
  2423. newproj=newproject
  2424. proj=projnode
  2425. Refresh()
  2426. Show()
  2427. End Method
  2428. Function Create:TProjectProperties(host:TCodePlay)
  2429. Local proj:TProjectProperties = New TProjectProperties
  2430. proj.initrequester(host,"{{project_window_title}}",ScaledSize(480),ScaledSize(110),STYLE_OK|STYLE_CANCEL|STYLE_DIVIDER|STYLE_MODAL)
  2431. proj.modal = True
  2432. Local projectdetails:TGadget = CreatePanel(ScaledSize(6),ScaledSize(8),ClientWidth(proj.window)-ScaledSize(12),ScaledSize(85),proj.window,PANEL_GROUP,"{{project_group_details}}")
  2433. Local i,n,y
  2434. y=4
  2435. CreateLabel("{{project_label_name}}:",ScaledSize(6),ScaledSize(y+4),ScaledSize(72),ScaledSize(24),projectdetails)
  2436. proj.localname=CreateTextField(ScaledSize(88),ScaledSize(y),ClientWidth(projectdetails)-ScaledSize(88+6),ScaledSize(21),projectdetails)
  2437. y:+30
  2438. CreateLabel("{{project_label_path}}:",ScaledSize(6),ScaledSize(y+4),ScaledSize(72),ScaledSize(24),projectdetails)
  2439. proj.localpath=CreateTextField(ScaledSize(88),ScaledSize(y),ClientWidth(projectdetails)-ScaledSize(88+34+6+6+6),ScaledSize(21),projectdetails)
  2440. proj.pathbutton=CreateButton("..",ClientWidth(projectdetails)-ScaledSize(34+6+6),ScaledSize(y),ScaledSize(34),ScaledSize(21),projectdetails)
  2441. Return proj
  2442. End Function
  2443. End Type
  2444. Function GetInfo$(a$ Var)
  2445. Local p,r$
  2446. p=a.Find("|")+1
  2447. If p=0 p=a.length+1
  2448. r$=a$[..p-1]
  2449. a$=a$[p..]
  2450. Return r$
  2451. End Function
  2452. Type TFolderNode Extends TNode
  2453. Field owner:TNode
  2454. Field path$
  2455. Field scanned
  2456. Field version
  2457. Field foldertype
  2458. Const PROJECTFOLDER=0
  2459. Const DIRECTORYFOLDER=1
  2460. Const FILEFOLDER=2
  2461. Method FindFolderFromPath:TFolderNode(dir$)
  2462. Local result:TFolderNode
  2463. If path=dir Return Self
  2464. For Local folder:TFolderNode = EachIn kids
  2465. result=folder.FindFolderFromPath(dir)
  2466. If result Return result
  2467. Next
  2468. End Method
  2469. Method SetName(n$)
  2470. If version Then n:+"("+version+")"
  2471. Super.SetName( n )
  2472. Refresh
  2473. End Method
  2474. Method SetVersion(ver)
  2475. version=ver
  2476. SetName StripDir(path)
  2477. End Method
  2478. Method Write(stream:TStream)
  2479. Local isopen
  2480. If GetState()=OPENSTATE isopen=True
  2481. If version Or isopen
  2482. stream.WriteLine "proj_data="+path+"|"+isopen+"|"+version+"|"
  2483. EndIf
  2484. For Local folder:TFolderNode = EachIn kids
  2485. folder.Write(stream)
  2486. Next
  2487. End Method
  2488. Method ProjectHost:TCodePlay()
  2489. Local n:TNode = Self
  2490. While n
  2491. If TProjects(n) Return TProjects(n).host
  2492. n=n.parent
  2493. Wend
  2494. End Method
  2495. Method ProjectNode:TProjectFolderNode()
  2496. Local n:TNode = Self
  2497. While n
  2498. If TProjectFolderNode(n) Return TProjectFolderNode(n)
  2499. n=n.parent
  2500. Wend
  2501. End Method
  2502. Method Open(view=-1)
  2503. Update(True)
  2504. Super.Open view
  2505. End Method
  2506. Method AddFileNode:TNode(file$)
  2507. Local n:TNode
  2508. Local ext$
  2509. If (","+FileTypes+",").Contains(","+ExtractExt(file).toLower()+",") Then
  2510. n=AddNode(StripDir(file))
  2511. n.SetAction(owner,TOOLOPEN,file)
  2512. ext=ExtractExt(file$).ToLower()
  2513. n.sortname=ext+n.name
  2514. Return n
  2515. EndIf
  2516. End Method
  2517. Method AddFolderNode:TNode(path$)
  2518. Local n:TFolderNode = TFolderNode.CreateFolderNode(path,DIRECTORYFOLDER)
  2519. n.owner = owner
  2520. n.sortname=" "+n.name
  2521. Append n
  2522. Return n
  2523. End Method
  2524. Method Scan(o:TNode)
  2525. Local p$
  2526. Local flist:TList = New TList
  2527. owner=o
  2528. For Local f$ = EachIn LoadDir(path,True)
  2529. If f[..1] = "." Then Continue
  2530. p$=path+"/"+f
  2531. Select FileType(p$)
  2532. Case FILETYPE_FILE
  2533. AddFileNode p$
  2534. Case FILETYPE_DIR
  2535. AddFolderNode p$
  2536. End Select
  2537. Next
  2538. SortKids
  2539. scanned = True
  2540. End Method
  2541. Method ScanKids()
  2542. For Local f:TFolderNode = EachIn kids
  2543. f.owner = owner
  2544. f.Update(False)
  2545. Next
  2546. End Method
  2547. Method Rescan()
  2548. scanned = False
  2549. Update()
  2550. EndMethod
  2551. Method Update( alwaysScanKids:Int = False )
  2552. If Not scanned Then
  2553. FreeKids()
  2554. Scan owner
  2555. EndIf
  2556. If alwaysScanKids Or Not IsHidden() Then ScanKids()
  2557. Refresh()
  2558. End Method
  2559. Method Invoke(command,argument:Object=Null)
  2560. Local host:TCodePlay
  2561. Local cmd,p
  2562. Local line$
  2563. host=ProjectHost()
  2564. If Not host Notify LocalizeString("{{svn_notification_nodehostnotfound}}");Return
  2565. Select command
  2566. Case TOOLOUTPUT
  2567. line$=String(argument)
  2568. p=line.find(" revision ")
  2569. If p>-1
  2570. SetVersion Int(line[p+10..])
  2571. EndIf
  2572. ' If line[..12]="At revision "
  2573. ' DebugLog "TOOLOUTPUT:"+line
  2574. Return
  2575. Case TOOLERROR
  2576. line$=String(argument)
  2577. ' DebugLog "TOOLERROR:"+line
  2578. Return
  2579. Case TOOLMENU
  2580. cmd=Int(String(argument))
  2581. Select cmd
  2582. Case 0 'special toolmenu-command=0 fired by rightbutton node context
  2583. Highlight
  2584. Local menu:TGadget
  2585. menu=host.projects.projmenu
  2586. PopupWindowMenu host.window,menu,Self
  2587. Case MENUREFRESH
  2588. Rescan()
  2589. Case MENUBROWSE
  2590. OpenURL RealPath(path)
  2591. Case MENUSHELL
  2592. Local cd$=CurrentDir()
  2593. ChangeDir RealPath(path)
  2594. ?MacOS
  2595. host.execute "/bin/bash","Shell Terminal"
  2596. ?Linux
  2597. host.execute "/bin/bash","Shell Terminal"
  2598. ?Win32
  2599. host.execute "cmd","Shell Terminal - Type Exit To End"
  2600. ?
  2601. ChangeDir cd
  2602. ' Case MENUPROPS
  2603. ' host.projectprops.Open(Self)
  2604. Case MENUFINDINFILES
  2605. host.searchreq.ShowWithPath( RealPath(path) )
  2606. End Select
  2607. End Select
  2608. End Method
  2609. Function CreateFolderNode:TFolderNode(path$,foldertype)
  2610. Local n:TFolderNode = New TFolderNode
  2611. ' n.host=host
  2612. n.SetName( StripDir(path) )
  2613. n.path = path
  2614. n.foldertype = foldertype
  2615. Return n
  2616. End Function
  2617. End Type
  2618. Type TProjectFolderNode Extends TFolderNode
  2619. Field owner:TProjects
  2620. Method ToString$()
  2621. Local prj$
  2622. Local isopen
  2623. If GetState()&OPENSTATE isopen=True
  2624. 'for compatibility issues we enter blank values for 3 svn details
  2625. prj=name+"|"+path+"| | | |"+isopen+"|"+version
  2626. Return prj
  2627. End Method
  2628. Method Write(stream:TStream)
  2629. stream.WriteLine "proj_node="+ToString()
  2630. For Local folder:TFolderNode = EachIn kids
  2631. folder.Write(stream)
  2632. Next
  2633. End Method
  2634. Method FromString(info$)
  2635. Local n$ = GetInfo(info)
  2636. If Not n Then n = "Unknown"
  2637. SetName( n )
  2638. path=GetInfo(info)
  2639. If path path=owner.host.FullPath(path)
  2640. 'unused 3 values
  2641. GetInfo(info)
  2642. GetInfo(info)
  2643. GetInfo(info)
  2644. Scan(owner)
  2645. Local isopen,vers
  2646. isopen=Int(GetInfo(info))
  2647. If isopen
  2648. Open
  2649. EndIf
  2650. vers=Int(GetInfo(info))
  2651. If vers
  2652. SetVersion vers
  2653. EndIf
  2654. End Method
  2655. Method Invoke(command,argument:Object=Null)
  2656. Local cmd
  2657. Select command
  2658. Case TOOLMENU
  2659. cmd=Int(String(argument))
  2660. Select cmd
  2661. Case MENUPROPS
  2662. Return owner.host.projectprops.Open(Self)
  2663. End Select
  2664. End Select
  2665. Return Super.Invoke(command,argument)
  2666. End Method
  2667. Method Set(n$,p$)
  2668. path=owner.host.FullPath(p)
  2669. setname n
  2670. Rescan()
  2671. owner.host.projectreq.Refresh()
  2672. End Method
  2673. Function CreateProjectNode:TProjectFolderNode(projects:TProjects,info$)
  2674. Local n:TProjectFolderNode = New TProjectFolderNode
  2675. n.owner=projects
  2676. n.FromString(info)
  2677. n.foldertype=PROJECTFOLDER
  2678. Return n
  2679. End Function
  2680. End Type
  2681. Type TProjects Extends TNode
  2682. Field host:TCodePlay
  2683. Field addproj:TNode
  2684. Field projmenu:TGadget
  2685. Field projmenuprops:TGadget
  2686. Method RemoveProject(index)
  2687. Local node:TNode
  2688. If index<0 Or index>=kids.Count() Return
  2689. node=TNode(kids.ValueAtIndex(index))
  2690. If node node.Free
  2691. Refresh
  2692. End Method
  2693. Method MoveProject(index,dir)
  2694. Local node:TNode
  2695. Local link:TLink
  2696. If index<0 Or index>=kids.Count() Return index
  2697. node=TNode(kids.ValueAtIndex(index))
  2698. If node
  2699. addproj.Detach
  2700. node.Hide
  2701. link=kids.FindLink(node)
  2702. If dir>0
  2703. If link link=link._succ
  2704. If link
  2705. kids.Remove node
  2706. kids.InsertAfterLink node,link
  2707. index:+1
  2708. EndIf
  2709. Else
  2710. If link link=link._pred
  2711. If link
  2712. kids.Remove node
  2713. kids.InsertBeforeLink node,link
  2714. index:-1
  2715. EndIf
  2716. EndIf
  2717. Append addproj
  2718. Refresh
  2719. EndIf
  2720. Return index
  2721. End Method
  2722. Method NewProject()
  2723. addproj.Detach
  2724. Local proj:TProjectFolderNode = TProjectFolderNode.CreateProjectNode(Self,LocalizeString("{{project_defaultname}}"))
  2725. ' proj.scan(Self)
  2726. Append proj
  2727. Append addproj
  2728. host.projectprops.Open(proj, True)
  2729. Refresh
  2730. End Method
  2731. Method AddProject(data:TList)
  2732. Local project:TProjectFolderNode
  2733. Local folder:TFolderNode
  2734. For Local info$ = EachIn data
  2735. If Not project
  2736. addproj.Detach
  2737. project=TProjectFolderNode.CreateProjectNode(Self,info)
  2738. Append project
  2739. Append addproj
  2740. Refresh
  2741. Else
  2742. Local path$
  2743. Local popen
  2744. Local pversion
  2745. path=GetInfo(info)
  2746. popen=Int(GetInfo(info))
  2747. pversion=Int(GetInfo(info))
  2748. folder=project.FindFolderFromPath(path)
  2749. If folder
  2750. folder.SetVersion pversion
  2751. folder.ReScan()
  2752. If popen Then folder.Open()
  2753. EndIf
  2754. EndIf
  2755. Next
  2756. End Method
  2757. Method Write(stream:TStream)
  2758. For Local project:TProjectFolderNode = EachIn kids
  2759. project.Write(stream)
  2760. Next
  2761. End Method
  2762. Method Invoke(command,argument:Object=Null)
  2763. Select command
  2764. Case TOOLNEW
  2765. NewProject
  2766. Case TOOLOPEN
  2767. host.OpenSource String(argument)
  2768. End Select
  2769. End Method
  2770. Function CreateProjects:TProjects(host:TCodePlay)
  2771. Local p:TProjects = New TProjects
  2772. p.SetName("{{navnode_projects}}")
  2773. p.host=host
  2774. p.addproj=p.AddNode("{{navnode_addproject}}")
  2775. p.addproj.SetAction p,TOOLNEW
  2776. p.projmenu=CreateMenu("{{popup_nav_proj}}",0,Null)
  2777. CreateMenu "{{popup_nav_proj_refresh}}",MENUREFRESH,p.projmenu
  2778. CreateMenu "{{popup_nav_proj_findinfiles}}",MENUFINDINFILES,p.projmenu
  2779. CreateMenu "{{popup_nav_proj_explore}}",MENUBROWSE,p.projmenu
  2780. CreateMenu "{{popup_nav_proj_shell}}",MENUSHELL,p.projmenu
  2781. CreateMenu "",0,p.projmenu
  2782. p.projmenuprops=CreateMenu("{{popup_nav_proj_properties}}",MENUPROPS,p.projmenu)
  2783. host.projectreq.projects=p
  2784. Return p
  2785. End Function
  2786. End Type
  2787. ?Not bmxng
  2788. Type TByteBuffer Extends TStream
  2789. Field bytes:Byte[]
  2790. Field readpointer
  2791. Method Read( buf:Byte Ptr,count )
  2792. If count>readpointer count=readpointer
  2793. If Not count Return
  2794. MemCopy buf,bytes,count
  2795. readpointer:-count
  2796. If readpointer MemMove bytes,Varptr bytes[count],readpointer
  2797. Return count
  2798. End Method
  2799. Method ReadLine$()
  2800. For Local i:Int = 0 Until readpointer
  2801. If bytes[i]=10 Or bytes[i] = 0 Then
  2802. Local tmpBytes:Byte[] = New Byte[i+1]
  2803. If i And bytes[i-1] = 13 Then i:-1
  2804. Read(tmpBytes,tmpBytes.length)
  2805. Return String.FromBytes(tmpBytes, i)
  2806. EndIf
  2807. Next
  2808. EndMethod
  2809. Method WriteFromPipe( pipe:TPipeStream )
  2810. Local n,m,count = pipe.ReadAvail()
  2811. n=readpointer+count
  2812. If n>bytes.length
  2813. m=Max(bytes.length*1.5,n)
  2814. bytes=bytes[..m]
  2815. EndIf
  2816. pipe.Read( Varptr bytes[readpointer], count )
  2817. readpointer=n
  2818. Return count
  2819. EndMethod
  2820. Method Write( buf:Byte Ptr,count )
  2821. Local n,m
  2822. n=readpointer+count
  2823. If n>bytes.length
  2824. m=Max(bytes.length*1.5,n)
  2825. bytes=bytes[..m]
  2826. EndIf
  2827. MemCopy Varptr bytes[readpointer],buf,count
  2828. readpointer=n
  2829. Return count
  2830. End Method
  2831. Method LineAvail()
  2832. For Local i:Int = 0 Until readpointer
  2833. If bytes[i]=10 Return True
  2834. Next
  2835. End Method
  2836. Method FlushBytes:Byte[]()
  2837. Local res:Byte[] = bytes[..readpointer]
  2838. readpointer = 0
  2839. Return res
  2840. End Method
  2841. End Type
  2842. ?bmxng
  2843. Type TByteBuffer Extends TStream
  2844. Field bytes:Byte[]
  2845. Field readpointer:Long
  2846. Method Read:Long( buf:Byte Ptr,count:Long )
  2847. If count>readpointer count=readpointer
  2848. If Not count Return
  2849. MemCopy buf,bytes,Size_T(count)
  2850. readpointer:-count
  2851. If readpointer MemMove bytes,Varptr bytes[count],Size_T(readpointer)
  2852. Return count
  2853. End Method
  2854. Method ReadLine$()
  2855. For Local i:Int = 0 Until readpointer
  2856. If bytes[i]=10 Or bytes[i] = 0 Then
  2857. Local tmpBytes:Byte[] = New Byte[i+1]
  2858. If i And bytes[i-1] = 13 Then i:-1
  2859. Read(tmpBytes,tmpBytes.length)
  2860. Return String.FromBytes(tmpBytes, i)
  2861. EndIf
  2862. Next
  2863. EndMethod
  2864. Method WriteFromPipe( pipe:TPipeStream )
  2865. Local n,m,count = pipe.ReadAvail()
  2866. n=readpointer+count
  2867. If n>bytes.length
  2868. m=Max(bytes.length*1.5,n)
  2869. bytes=bytes[..m]
  2870. EndIf
  2871. pipe.Read( Varptr bytes[readpointer], count )
  2872. readpointer=n
  2873. Return count
  2874. EndMethod
  2875. Method Write:Long( buf:Byte Ptr,count:Long )
  2876. Local n:Long,m:Long
  2877. n=readpointer+count
  2878. If n>bytes.length
  2879. m=Max(bytes.length*1.5,n)
  2880. bytes=bytes[..m]
  2881. EndIf
  2882. MemCopy Varptr bytes[readpointer],buf,Size_T(count)
  2883. readpointer=n
  2884. Return count
  2885. End Method
  2886. Method LineAvail()
  2887. For Local i:Int = 0 Until readpointer
  2888. If bytes[i]=10 Return True
  2889. Next
  2890. End Method
  2891. Method FlushBytes:Byte[]()
  2892. Local res:Byte[] = bytes[..readpointer]
  2893. readpointer = 0
  2894. Return res
  2895. End Method
  2896. End Type
  2897. ?
  2898. Type TObj
  2899. Field addr$,sync,refs,syncnext
  2900. Method ShouldSync( pDebugTree:TDebugTree )
  2901. If sync < pDebugTree.sync Then pDebugTree.QueueSync( Self )
  2902. EndMethod
  2903. Method HasSynced( pSync% )
  2904. sync = pSync;syncnext = False
  2905. EndMethod
  2906. End Type
  2907. Type TVar Extends TNode
  2908. Field owner:TDebugTree
  2909. Field obj:Object
  2910. Method Free()
  2911. If TObj(obj) owner.RemoveObj TObj(obj)
  2912. obj=Null
  2913. Super.Free()
  2914. End Method
  2915. Method SetVarName(n$)
  2916. Local p
  2917. name=n
  2918. ' if object ref set addr$ field
  2919. If name.find("$=")=-1 And name.find( ":String=" )=-1 And name.find(")=$")=-1
  2920. p=name.find("=$")
  2921. If p<>-1
  2922. If TObj(obj) Then
  2923. If TObj(obj).addr <> name[p+2..] Then
  2924. TDebugTree.RemoveObj TObj(obj)
  2925. Else
  2926. TObj(obj).refs:-1
  2927. EndIf
  2928. EndIf
  2929. obj=TDebugTree.AddObj(name[p+2..])
  2930. 'Request object dump if we are visible now that
  2931. 'we have updated our own object pointer.
  2932. If Not IsHidden() Then Request()
  2933. Return
  2934. EndIf
  2935. p=name.find("=Null")
  2936. If p<>-1
  2937. FreeKids
  2938. TDebugTree.RemoveObj TObj(obj)
  2939. obj=Null
  2940. EndIf
  2941. EndIf
  2942. End Method
  2943. Method AddVar(name$)
  2944. Local v:TVar=New TVar
  2945. v.owner=owner
  2946. Append v
  2947. v.setvarname name
  2948. End Method
  2949. Method SetValue(val:TVar)
  2950. Local v:TVar,w:TVar,i,kidsarray:Object[]
  2951. ' if this is a reference to same object refresh values
  2952. If obj And obj=val.obj
  2953. If kids.IsEmpty()
  2954. For v=EachIn val.kids
  2955. AddVar v.name
  2956. Next
  2957. Else
  2958. kidsarray = kids.ToArray()
  2959. For v=EachIn val.kids
  2960. If i<kidsarray.length
  2961. w=TVar(kidsarray[i])
  2962. If w w.SetVarName v.name
  2963. Else
  2964. AddVar v.name
  2965. EndIf
  2966. i:+1
  2967. Next
  2968. kidsarray = Null
  2969. EndIf
  2970. Refresh
  2971. EndIf
  2972. ' recurse so all references are updated
  2973. If IsHidden() Then Return 'parent And parent.state=CLOSEDSTATE Return
  2974. For v=EachIn kids
  2975. v.SetValue val
  2976. Next
  2977. End Method
  2978. Method Open(open=-1)
  2979. For Local kid:TVar = EachIn kids
  2980. kid.Request()
  2981. Next
  2982. Super.Open(open)
  2983. EndMethod
  2984. Method Request()
  2985. If TObj(obj) Then TObj(obj).ShouldSync(owner)
  2986. EndMethod
  2987. End Type
  2988. Type TScope Extends TVar
  2989. Field tree:TDebugTree
  2990. Field file$,line,column
  2991. Method Invoke(command,argument:Object=Null)
  2992. Select command
  2993. Case TOOLACTIVATE
  2994. tree.SelectScope Self,True
  2995. End Select
  2996. End Method
  2997. Method SetScope(s:TScope)
  2998. Local v:TVar
  2999. file=s.file
  3000. line=s.line
  3001. column=s.column
  3002. s.obj=Self
  3003. SetValue s
  3004. End Method
  3005. Method SetFile(debugtree:TDebugTree,f$)
  3006. tree=debugtree
  3007. Local p=f.Find("<")+1
  3008. Local q=f.Find(">")+1
  3009. Local r=f.Find(",")+1
  3010. If p And q And r
  3011. file=f[..p-1]
  3012. line=Int(f[p..r-1])
  3013. column=Int(f[r..q-1])
  3014. EndIf
  3015. obj=Self
  3016. End Method
  3017. Method Request()
  3018. For Local kid:TVar = EachIn kids
  3019. kid.Request()
  3020. Next
  3021. EndMethod
  3022. End Type
  3023. Type TDebugTree Extends TVar
  3024. Global sync
  3025. Global objmap:TMap = CreateMap()
  3026. Field host:TCodePlay
  3027. Field instack:TList
  3028. Field inscope:TScope
  3029. Field invar:TVar
  3030. Field infile$
  3031. Field inexception$
  3032. Field firststop
  3033. Field cancontinue
  3034. Method Reset()
  3035. ' host.SetMode host.DEBUGMODE
  3036. SetStack( New TList )
  3037. ClearMap objmap
  3038. instack=Null
  3039. inscope=Null
  3040. invar=Null
  3041. infile=""
  3042. inexception=""
  3043. sync=0
  3044. firststop=True
  3045. cancontinue=False
  3046. End Method
  3047. Function AddObj:TObj(addr$)
  3048. Local o:TObj = TObj(MapValueForKey( objmap, addr ))
  3049. If o Then
  3050. o.refs:+1
  3051. Else
  3052. o=New TObj
  3053. o.addr=addr
  3054. o.refs=1
  3055. MapInsert objmap, addr, o
  3056. EndIf
  3057. Return o
  3058. End Function
  3059. Function FindObj:TObj(addr$)
  3060. Return TObj(MapValueForKey( objmap, addr ))
  3061. End Function
  3062. Function RemoveObj(obj:TObj) ':TObj
  3063. If obj Then
  3064. obj.refs:-1
  3065. If Not obj.refs Then MapRemove objmap, obj.addr
  3066. EndIf
  3067. End Function
  3068. Method SyncVars()
  3069. sync:+1
  3070. For Local tmpVar:TVar = EachIn kids
  3071. tmpVar.Request()
  3072. Next
  3073. End Method
  3074. Method QueueSync( pObj:TObj )
  3075. If Not pObj Then Return
  3076. 'Sync as soon as the debug pipe is clear
  3077. '(see TOuputPanel.SendDumpRequests()).
  3078. pObj.syncnext = True
  3079. EndMethod
  3080. Method SetStack(list:TList)
  3081. Local openscope:TScope
  3082. Local s:TScope
  3083. Local count,i
  3084. count=kids.count() 'root.varlist.count()
  3085. For Local scope:TScope = EachIn list
  3086. If i>=count
  3087. Append scope 'root.Append scope
  3088. s=scope
  3089. Else
  3090. s=TScope(kids.ValueAtIndex(i))
  3091. ' simon was here
  3092. If s.name=scope.name
  3093. s.SetScope scope
  3094. scope.Free
  3095. Else
  3096. While kids.count()>i
  3097. s=TScope(kids.Last())
  3098. s.free
  3099. Wend
  3100. Append scope
  3101. s=scope
  3102. count=i+1
  3103. EndIf
  3104. EndIf
  3105. If firststop
  3106. If host.IsSourceOpen(s.file) openscope=s
  3107. Else
  3108. openscope=s
  3109. EndIf
  3110. i:+1
  3111. Next
  3112. While kids.count()>i
  3113. s=TScope(kids.Last())
  3114. s.free
  3115. Wend
  3116. If list.IsEmpty() Return
  3117. If Not openscope openscope=TScope(list.First())
  3118. If openscope SelectScope openscope,True
  3119. Refresh
  3120. firststop=False
  3121. End Method
  3122. Method SelectScope(scope:TScope,open)
  3123. If Not scope Return
  3124. host.SetMode host.DEBUGMODE ' simon was here, smoved from reset
  3125. If scope.file host.DebugSource scope.file,scope.line,scope.column
  3126. scope.Open()
  3127. ' If open
  3128. ' SelectTreeViewNode scope.node
  3129. ' scope.open
  3130. ' EndIf
  3131. End Method
  3132. Method ProcessError$(line$)
  3133. Local p
  3134. While p < line.length
  3135. If line[p]=$3E Then p:+1 Else Exit '">"
  3136. Wend
  3137. If p = line.length Return
  3138. If p Then line = line[p..]
  3139. If Not line.StartsWith("~~>") Return line
  3140. line=line[2..]
  3141. If invar
  3142. If line="}"
  3143. SetValue invar 'root
  3144. invar.Free
  3145. invar=Null
  3146. Else
  3147. ' If Not invar.name
  3148. ' invar.name=line
  3149. ' Else
  3150. invar.AddVar line
  3151. ' EndIf
  3152. EndIf
  3153. Return
  3154. EndIf
  3155. If instack
  3156. If line="}"
  3157. SetStack instack
  3158. instack=Null
  3159. inscope=Null
  3160. 'Request first object dumps, and bump sync count
  3161. SyncVars
  3162. If inexception
  3163. Notify inexception
  3164. inexception=""
  3165. EndIf
  3166. Return
  3167. EndIf
  3168. If infile
  3169. If line="Local <local>"
  3170. Else
  3171. inscope=New TScope
  3172. ' Print "inscope.line="+line
  3173. inscope.name=line
  3174. inscope.owner=Self
  3175. instack.AddLast inscope
  3176. EndIf
  3177. If inscope inscope.setfile Self,infile
  3178. infile=""
  3179. Return
  3180. EndIf
  3181. If line.StartsWith("@") And line.Contains("<")
  3182. infile=line[1..]
  3183. Else
  3184. If inscope inscope.AddVar line
  3185. EndIf
  3186. Return
  3187. EndIf
  3188. If line.StartsWith("Unhandled Exception:")
  3189. inexception=line
  3190. host.output.WritePipe "t"
  3191. cancontinue=False
  3192. Return
  3193. EndIf
  3194. If line="StackTrace{"
  3195. instack=New TList
  3196. Return
  3197. EndIf
  3198. If line="Debug:" Or line="DebugStop:"
  3199. host.output.WritePipe "t"
  3200. If Not cancontinue Then
  3201. cancontinue=True
  3202. host.RefreshToolbar()
  3203. EndIf
  3204. Return
  3205. EndIf
  3206. If line.StartsWith("ObjectDump@")
  3207. p=line.find("{",11)
  3208. If p=-1 Return line
  3209. line=line[11..p]
  3210. invar=New TVar
  3211. invar.obj=FindObj(line)
  3212. invar.owner=Self
  3213. Return
  3214. EndIf
  3215. End Method
  3216. Function CreateDebugTree:TDebugTree(host:TCodePlay)
  3217. Local d:TDebugTree = New TDebugTree
  3218. d.owner=d
  3219. d.SetName "{{navtab_debug}}"
  3220. d.host=host
  3221. d.Open
  3222. Return d
  3223. End Function
  3224. End Type
  3225. Type TNodeView
  3226. Field owner:TNavBar
  3227. Field root:TNode
  3228. Field treeview:TGadget
  3229. Field index
  3230. Method NewView()
  3231. Local n:TNode,hnode:TGadget
  3232. hnode=SelectedTreeViewNode(treeview)
  3233. n=root.Find(hnode,index)
  3234. If n And n.parent owner.AddView n
  3235. End Method
  3236. Method OnEvent()
  3237. Local n:TNode = root.Find(TGadget(EventExtra()),index)
  3238. If Not n Return 'probably an eventgadgetselect -1 Notify("could not find in root");Return
  3239. Select EventID()
  3240. Case EVENT_GADGETSELECT
  3241. n.invoke(TOOLSELECT)
  3242. Case EVENT_GADGETACTION
  3243. n.invoke(TOOLACTIVATE)
  3244. Case EVENT_GADGETMENU
  3245. n.invoke(TOOLMENU,Self)
  3246. Case EVENT_GADGETOPEN
  3247. n.open index
  3248. Case EVENT_GADGETCLOSE
  3249. n.close index
  3250. End Select
  3251. End Method
  3252. End Type
  3253. Type TNavBar Extends TEventHandler
  3254. Field host:TCodePlay
  3255. Field tabber:TGadget
  3256. Field viewlist:TList=New TList
  3257. Field selected:TNodeView
  3258. Field navmenu:TGadget
  3259. Method SelectedView()
  3260. If selected Return selected.index
  3261. End Method
  3262. Method SelectView(index)
  3263. Local n:TNodeView
  3264. If index>=viewlist.count() Return
  3265. n=TNodeView(viewlist.ValueAtIndex(index))
  3266. If Not n Print "selectview failed";Return
  3267. If n<>selected
  3268. If selected HideGadget selected.treeview
  3269. selected=n
  3270. EndIf
  3271. ShowGadget n.treeview
  3272. SelectGadgetItem tabber,index
  3273. End Method
  3274. Method AddView(node:TNode)
  3275. Local n:TNodeView
  3276. Local index,root:TGadget
  3277. For n=EachIn viewlist
  3278. If n.root=node SelectView n.index;Return
  3279. Next
  3280. n=New TNodeView
  3281. n.owner=Self
  3282. n.root=node
  3283. n.treeview=CreateTreeView(0,0,ClientWidth(tabber),ClientHeight(tabber),tabber)
  3284. host.options.navstyle.Apply n.treeview
  3285. SetGadgetLayout n.treeview,EDGE_ALIGNED,EDGE_ALIGNED,EDGE_ALIGNED,EDGE_ALIGNED
  3286. HideGadget n.treeview
  3287. n.index=viewlist.Count()
  3288. viewlist.AddLast n
  3289. AddGadgetItem tabber,node.name,GADGETITEM_LOCALIZED
  3290. root=TreeViewRoot(n.treeview)
  3291. node.setnode root,n.index
  3292. SelectView n.index
  3293. Return n.index
  3294. End Method
  3295. Method OnEvent()
  3296. If EventSource()=tabber
  3297. SelectView SelectedGadgetItem(tabber)
  3298. End If
  3299. If selected And EventSource()=selected.treeview
  3300. selected.OnEvent
  3301. EndIf
  3302. End Method
  3303. Method Refresh()
  3304. For Local view:TNodeView = EachIn viewlist
  3305. host.options.navstyle.Apply view.treeview
  3306. Next
  3307. End Method
  3308. Method Invoke(command,argument:Object=Null)
  3309. If command=TOOLREFRESH Refresh()
  3310. If command=TOOLNEWVIEW And selected selected.NewView
  3311. End Method
  3312. Function CreateNavMenu:TGadget()
  3313. Local edit:TGadget = CreateMenu("&Nav",0,Null)
  3314. CreateMenu "&New View",MENUNEWVIEW,edit
  3315. Return edit
  3316. End Function
  3317. Function Create:TNavBar(host:TCodePlay, parent:TGadget) ',root:TNode)
  3318. Local n:TNavBar = New TNavBar
  3319. n.host=host
  3320. n.tabber=CreateTabber(0,0,ClientWidth(parent),ClientHeight(parent),parent)
  3321. SetGadgetLayout(n.tabber,EDGE_ALIGNED,EDGE_ALIGNED,EDGE_ALIGNED,EDGE_ALIGNED)
  3322. ' n.AddView root
  3323. n.navmenu=CreateNavMenu()
  3324. Return n
  3325. End Function
  3326. End Type
  3327. Type TOutputPanel Extends TToolPanel 'used build and run
  3328. Field host:TCodePlay
  3329. Field output:TGadget
  3330. Field process:TProcess
  3331. Field pipe:TStream
  3332. Field wpipe:TTextStream
  3333. Field user$,cmdline$,err$,post$
  3334. Field errbuffer:TByteBuffer
  3335. Field outputmenu:TGadget
  3336. Field posttool:TTool
  3337. Method ClearDumpRequests()
  3338. For Local o:TObj = EachIn MapValues(host.debugtree.objmap)
  3339. o.HasSynced(o.sync)
  3340. Next
  3341. EndMethod
  3342. Method SendDumpRequests()
  3343. For Local o:TObj = EachIn MapValues(host.debugtree.objmap)
  3344. If o.syncnext Then
  3345. If o.addr <> "00000000" Then WritePipe "d"+o.addr
  3346. o.HasSynced( host.debugtree.sync )
  3347. EndIf
  3348. Next
  3349. EndMethod
  3350. Method Clear()
  3351. If Not output Open()
  3352. SetGadgetText output,""
  3353. End Method
  3354. Method WriteAscii(mess$)
  3355. If Not output Open()
  3356. AddTextAreaText output,mess.Replace("~0","")
  3357. End Method
  3358. Method Write(mess$)
  3359. If Not output Open()
  3360. AddTextAreaText output,mess.Replace("~0","")
  3361. End Method
  3362. Method Execute(cmd$,mess$="",exe$="",home=True,owner:TTool=Null)
  3363. If Not output Open()
  3364. If Not mess$ mess$=cmd$
  3365. err$=""
  3366. post$=exe
  3367. posttool=owner
  3368. host.SelectPanel Self
  3369. host.debugtree.Reset
  3370. If process And ProcessStatus(process)
  3371. Delay 500
  3372. If ProcessStatus(process)
  3373. Notify LocalizeString("{{output_notification_stillbusy}}").Replace("%1",cmdline)
  3374. Return
  3375. EndIf
  3376. EndIf
  3377. cmd=cmd.Trim()
  3378. process=CreateProcess(cmd$,HIDECONSOLE)
  3379. If Not process Then Notify LocalizeString("{{output_notification_processfailure}}").Replace("%1",cmd);Return
  3380. If Not process.status() Then Notify LocalizeString("{{output_notification_failedstart}}").Replace("%1",cmd);process=Null;Return
  3381. pipe=Process.pipe
  3382. wpipe=TTextStream.Create(pipe,TTextStream.UTF8)
  3383. cmdline=cmd
  3384. If home Clear
  3385. Write( mess+"~n" )
  3386. errbuffer = New TByteBuffer
  3387. host.RefreshToolbar
  3388. End Method
  3389. Method WritePipe(l$)
  3390. Try
  3391. If pipe pipe.WriteLine(l)
  3392. Catch ex:TStreamWriteException
  3393. Write LocalizeString("{{output_msg_debugfailure}}~n").Replace("%1",l)
  3394. Stop
  3395. EndTry
  3396. End Method
  3397. Method Go()
  3398. WritePipe "r"
  3399. host.debugtree.cancontinue = False
  3400. host.SelectPanel Self
  3401. host.RefreshToolbar()
  3402. End Method
  3403. Method StepOver()
  3404. ClearDumpRequests()
  3405. WritePipe "s"
  3406. End Method
  3407. Method StepIn()
  3408. ClearDumpRequests()
  3409. WritePipe "e"
  3410. End Method
  3411. Method StepOut()
  3412. ClearDumpRequests()
  3413. WritePipe "l"
  3414. End Method
  3415. Method Stop()
  3416. If Not process Return
  3417. 'does not exit apps if they use "AppTerminate()" and get debugged
  3418. 'process.Terminate()
  3419. process.Kill()
  3420. FlushPipes process.pipe,process.err
  3421. process.Close()
  3422. process=Null
  3423. Write LocalizeString("~n{{output_msg_processterminated}}~n")
  3424. host.DebugExit()
  3425. Close()
  3426. End Method
  3427. Method Wait()
  3428. While process And process.status()
  3429. PollSystem
  3430. Wend
  3431. End Method
  3432. Method Invoke(command,argument:Object=Null)
  3433. Select command
  3434. Case TOOLSHOW
  3435. host.SetTitle()
  3436. If output ActivateGadget output
  3437. Case TOOLCLOSE
  3438. host.RemovePanel Self
  3439. output=Null
  3440. Case TOOLCUT
  3441. GadgetCut output
  3442. Case TOOLCOPY
  3443. GadgetCopy output
  3444. Case TOOLPASTE
  3445. GadgetPaste output
  3446. Case TOOLSELECTALL
  3447. If output SelectTextAreaText output
  3448. Case TOOLREFRESH
  3449. RefreshStyle()
  3450. End Select
  3451. End Method
  3452. Method RefreshStyle()
  3453. host.options.outputstyle.apply output
  3454. Local rgb:TColor=host.options.outputLineNumberStyle.bg
  3455. TextAreaSetLineNumberBackColor output,rgb.red,rgb.green,rgb.blue
  3456. rgb=host.options.outputLineNumberStyle.fg
  3457. TextAreaSetLineNumberForeColor output,rgb.red,rgb.green,rgb.blue
  3458. TextAreaSetLineNumberEnable output, host.options.outputLineNumberStyle.flags
  3459. End Method
  3460. Method Close()
  3461. host.SelectPanel host.activepanel
  3462. End Method
  3463. Method Escape()
  3464. Stop
  3465. Close
  3466. End Method
  3467. Function outputfilter(event:TEvent,context:Object)
  3468. Local out:TOutputPanel=TOutputPanel(context)
  3469. If Not out Return
  3470. Select event.id
  3471. Case EVENT_KEYDOWN
  3472. If event.data=27
  3473. out.Escape()
  3474. Return 0
  3475. EndIf
  3476. Case EVENT_KEYCHAR
  3477. ' Print "output_keychar "+event.data
  3478. out.writechar(event.data)
  3479. End Select
  3480. Return 1
  3481. End Function
  3482. Method OnEvent()
  3483. If EventSource()=output
  3484. If EventID()=EVENT_GADGETMENU
  3485. PopupWindowMenu host.window,outputmenu
  3486. EndIf
  3487. EndIf
  3488. ' Case EVENT_TIMERTICK
  3489. If Not process Return
  3490. ReadPipes process.pipe,process.err
  3491. If Not process.status()
  3492. process.terminate
  3493. FlushPipes process.pipe,process.err
  3494. process.close()
  3495. process = Null
  3496. Write LocalizeString("~n{{output_msg_processcomplete}}~n")
  3497. host.DebugExit
  3498. host.SelectPanel Self
  3499. If err
  3500. host.ParseError err
  3501. Else
  3502. If post$
  3503. Local menuaction=Int(post)
  3504. If menuaction
  3505. host.OnMenu menuaction,posttool
  3506. ' Else
  3507. ' Execute post$,"","",False,0
  3508. EndIf
  3509. Else
  3510. If host.options.hideoutput Close()
  3511. EndIf
  3512. EndIf
  3513. EndIf
  3514. End Method
  3515. Method FlushPipes(pipe:TPipeStream,errpipe:TPipeStream)
  3516. ReadPipes(pipe,errpipe)
  3517. Local bytes:Byte[] = errbuffer.flushbytes()
  3518. If bytes
  3519. Local line$=String.FromBytes(bytes,Len bytes)
  3520. line=line.Replace(Chr(13),"")
  3521. If line<>">" Write line
  3522. EndIf
  3523. End Method
  3524. Method ReadPipes(pipe:TPipeStream,errpipe:TPipeStream)
  3525. Local status
  3526. Local bytes:Byte[],line$
  3527. bytes=pipe.ReadPipe()
  3528. If bytes
  3529. line$=String.FromBytes(bytes,Len bytes)
  3530. line=line.Replace(Chr(13),"")
  3531. Write line
  3532. EndIf
  3533. If errpipe.ReadAvail() Then
  3534. errbuffer.WriteFromPipe(errpipe)
  3535. Else
  3536. SendDumpRequests()
  3537. EndIf
  3538. ' If bytes Write String.FromBytes(bytes,bytes.length)
  3539. While errbuffer.LineAvail()
  3540. line$=errbuffer.ReadLine()
  3541. line=host.debugtree.ProcessError(line)
  3542. If line
  3543. Write line+"~n"
  3544. err:+line+"~n"
  3545. EndIf
  3546. Wend
  3547. End Method
  3548. Method WriteChar(char)
  3549. Local pipe:TPipeStream
  3550. If Not process Return
  3551. pipe=process.pipe
  3552. If char=3 'CTRL-C
  3553. Stop()
  3554. EndIf
  3555. If char=13 'ENTER
  3556. ' Write Chr(10)
  3557. pipe.WriteLine user$
  3558. user=""
  3559. EndIf
  3560. If char=8 And user.length 'DELETE
  3561. ' Local pos=TextAreaLen(output)
  3562. ' If pos SetTextAreaText output,"",pos-1,1,TEXTAREA_CHARS
  3563. user=user[..user.length-1]
  3564. EndIf
  3565. If char>31
  3566. ' Write Chr(char)
  3567. user:+Chr(char)
  3568. EndIf
  3569. End Method
  3570. Method Open()
  3571. If output Then
  3572. codeplay.SelectPanel Self
  3573. Return
  3574. EndIf
  3575. codeplay.addpanel(Self)
  3576. output=CreateTextArea(0,0,ClientWidth(panel),ClientHeight(panel),panel,TEXTAREA_WORDWRAP)
  3577. DelocalizeGadget output
  3578. SetGadgetLayout output,EDGE_ALIGNED,EDGE_ALIGNED,EDGE_ALIGNED,EDGE_ALIGNED
  3579. SetGadgetFilter output,outputfilter,Self
  3580. SetGadgetText output," " 'simon was here
  3581. TextAreaEnableUndoRedo(output, False)
  3582. RefreshStyle()
  3583. End Method
  3584. Function CreateOutputMenu:TGadget()
  3585. Local edit:TGadget = CreateMenu("{{popup_output}}",0,Null)
  3586. CreateMenu "{{popup_output_cut}}",MENUCUT,edit
  3587. CreateMenu "{{popup_output_copy}}",MENUCOPY,edit
  3588. CreateMenu "{{popup_output_paste}}",MENUPASTE,edit
  3589. CreateMenu "",0,edit
  3590. CreateMenu "{{popup_output_stop}}",MENUSTOP,edit
  3591. Return edit
  3592. End Function
  3593. Function Create:TOutputPanel(host:TCodePlay)
  3594. Local o:TOutputPanel = New TOutputPanel
  3595. o.host=host
  3596. o.name="{{tab_output}}"
  3597. o.outputmenu=CreateOutputMenu()
  3598. ' o.Open
  3599. Return o
  3600. End Function
  3601. End Type
  3602. Type TCodeNode Extends TNode
  3603. Field owner:TOpenCode
  3604. Field pos,count
  3605. 'Field groups:TMap=New TMap
  3606. Method Invoke(command,argument:Object=Null)
  3607. Select command
  3608. Case TOOLACTIVATE
  3609. owner.ShowPos(pos)
  3610. End Select
  3611. End Method
  3612. Method Sync(snap:TNode)
  3613. If snap.name<>name SetName(snap.name)
  3614. Local n:TCodeNode = TCodeNode(snap)
  3615. If n pos=n.pos;count=n.count
  3616. Super.Sync(snap)
  3617. End Method
  3618. Method SetName(n$)
  3619. Local p = n.find("'")
  3620. If p<>-1 n=n[..p]
  3621. name=n.Trim()
  3622. ' If owner.host.options.sortcode
  3623. sortname=n
  3624. End Method
  3625. Method Free()
  3626. owner = Null
  3627. Super.Free()
  3628. End Method
  3629. Method AddCodeNode:TCodeNode(n$,p0,p1)
  3630. Local t$
  3631. Local i:Int = n.find(" ") 'if space then group
  3632. If i>0
  3633. t=n[..i]
  3634. n=n[i+1..]
  3635. Rem
  3636. p=TNode(groups.ValueForKey(t))
  3637. If Not p
  3638. p=AddNode(t+"s")
  3639. p.Open
  3640. groups.insert t,p
  3641. EndIf
  3642. EndRem
  3643. EndIf
  3644. Local c:TCodeNode = New TCodeNode
  3645. c.owner=owner
  3646. c.setname n$
  3647. c.pos=p0
  3648. c.count=p1-p0
  3649. Append(c)
  3650. Return c
  3651. End Method
  3652. End Type
  3653. Type TDiff
  3654. Field pos,count,del$,add$,pos0,count0,pos1,textchange = True
  3655. End Type
  3656. Type TOpenCode Extends TToolPanel
  3657. Global msgHighlightingStatus$ = "Highlighting"
  3658. Field host:TCodePlay
  3659. Field textarea:TGadget
  3660. Field dirty=True
  3661. Field filesrc$,cleansrc$,cleansrcl$
  3662. Field Current:TDiff
  3663. Field undolist:TList=New TList
  3664. Field redolist:TList=New TList
  3665. Field helpcmd$,helpstring$
  3666. Field seek$
  3667. Field cursorpos,cursorlen,cursorline
  3668. Field oldpos,oldlen
  3669. Field isbmx,isc,iscpp,ishtml
  3670. Field deferpos = -1
  3671. Field tidyqueue1 = -1, tidyqueue2 = -1
  3672. Field editmenu:TGadget
  3673. Field codenode:TCodeNode
  3674. Field dirtynode,uc,nativeundo
  3675. Function RefreshHighlightingMsg()
  3676. msgHighlightingStatus = LocalizeString("{{msg_highlightingcode}}")
  3677. EndFunction
  3678. Function IsNotAlpha(c)
  3679. If c<48 Return True
  3680. If c>=58 And c<65 Return True
  3681. If c>=91 And c<95 Return True
  3682. If c>=96 And c<97 Return True
  3683. If c>=123 Return True
  3684. End Function
  3685. Function WordAtPos$(a$,p)
  3686. Local c,q,r,n
  3687. ' string literal
  3688. q=a.findlast(EOL$,a.length-p)
  3689. If q=-1 q=0
  3690. For q=q To p-1
  3691. If a[q]=34 Then
  3692. n=Not n
  3693. r=q
  3694. EndIf
  3695. Next
  3696. If n
  3697. q=a.Find("~q",r+1)+1
  3698. If q=0 q=a.length
  3699. Return a[r..q]
  3700. EndIf
  3701. ' alphanumeric
  3702. p=Min(p,a.length-1) 'simon was here - crash when checking at last char
  3703. For p=p Until 0 Step -1 'simon was here unto->to
  3704. If IsNotAlpha(a$[p]) Continue
  3705. Exit
  3706. Next
  3707. For q=p-1 To 0 Step -1
  3708. If IsNotAlpha(a$[q]) Exit
  3709. Next
  3710. For r=p To a.length-1
  3711. If IsNotAlpha(a$[r]) Exit
  3712. Next
  3713. Return a[q+1..r]
  3714. End Function
  3715. Function FirstDiff(s0$,s1$)
  3716. Local n = Min(s0.length,s1.length)
  3717. For Local i:Int = 0 Until n
  3718. If s0[i]<>s1[i] Return i
  3719. Next
  3720. Return n
  3721. End Function
  3722. Function LastDiff(s0$,s1$)
  3723. Local n = Min(s0.length,s1.length)
  3724. Local i = s0.length-1
  3725. Local j = s1.length-1
  3726. While n>0
  3727. If s0[i]<>s1[j] Exit
  3728. i:-1;j:-1;n:-1
  3729. Wend
  3730. Return i+1
  3731. End Function
  3732. Method parsebmx(n:TCodeNode)
  3733. Local src$,line,col
  3734. Local p,p1,r,t,m,f,l,e
  3735. src=cleansrcl
  3736. p1=src.length
  3737. p=-1;r=-1;t=-1;m=-1;f=-1;l=-1
  3738. While p<p1 'update rem,type,method,function,label pointers
  3739. While r<=p
  3740. r=FindToken("rem",src,r+1)
  3741. Wend
  3742. While t<=p
  3743. t=FindToken("type",src,t+1)
  3744. Wend
  3745. While m<=p
  3746. m=FindToken("method",src,m+1)
  3747. Wend
  3748. While f<=p
  3749. f=FindToken("function",src,f+1)
  3750. Wend
  3751. While l<=p
  3752. l=FindLabel(src,l+1)
  3753. Wend
  3754. If r<t And r<m And r<f And r<l
  3755. p=FindEndToken("rem",src,r+1,True)
  3756. Continue
  3757. EndIf
  3758. p=Min(t,Min(m,Min(f,l)))
  3759. If p=src.length Exit
  3760. While (n And n.parent And p>n.pos+n.count)
  3761. If Not TCodeNode(n.parent)
  3762. If n.parent.parent
  3763. n = TCodeNode(n.parent.parent)
  3764. Else
  3765. n = Null
  3766. EndIf
  3767. Else
  3768. n=TCodeNode(n.parent)
  3769. EndIf
  3770. Wend
  3771. If t<m And t<f And t<l
  3772. e=src.find(EOL,t)
  3773. n=n.AddCodeNode(cleansrc[t..e],t,FindEndToken("type",src,t,True))
  3774. p=t+1
  3775. Continue
  3776. EndIf
  3777. If m<f And m<l
  3778. e=src.find(EOL,m)
  3779. n.AddCodeNode(cleansrc[m..e],m,e)
  3780. p=m+1
  3781. Continue
  3782. EndIf
  3783. If f<l
  3784. e=src.find(EOL,f)
  3785. n.AddCodeNode(cleansrc[f..e],f,e)
  3786. p=f+1
  3787. Continue
  3788. Else
  3789. e=src.find(EOL,l)
  3790. n.AddCodeNode(cleansrc[l..e],l,e)
  3791. p=l+1
  3792. Continue
  3793. EndIf
  3794. Wend
  3795. End Method
  3796. Method GetNode:TNode()
  3797. Local root:TCodeNode = New TCodeNode
  3798. root.name = StripDir(path)
  3799. root.owner = Self
  3800. root.count = cleansrc.length
  3801. If isbmx parsebmx(root) ' stopped code view parse on non bmx files
  3802. If codenode
  3803. If host.options.sortcode root.sortkids
  3804. codenode.Sync(root)
  3805. root.Free()
  3806. Else
  3807. codenode=root
  3808. EndIf
  3809. Return codenode
  3810. End Method
  3811. Method HighlightLine(line,column = 0)
  3812. Local i:Int, tmpCharLineStart% = TextAreaChar(textarea,line)
  3813. Local tmpLine$ = TextAreaText( textarea, line, 1, TEXTAREA_LINES ).Replace("~r","").Replace("~n","")
  3814. For i = column Until tmpLine.length
  3815. If IsNotAlpha(tmpLine[i]) Then tmpCharLineStart:+1 Else Exit
  3816. Next
  3817. SelectTextAreaText textarea,line-1,0,TEXTAREA_LINES
  3818. SelectTextAreaText textarea,line+1,0,TEXTAREA_LINES
  3819. If i = tmpLine.length Or ..
  3820. ( TextAreaCharX( textarea, tmpCharLineStart + tmpLine.length-i ) - TextAreaCharX( textarea, tmpCharLineStart ) >= ClientWidth(textarea) ) Then
  3821. SelectTextAreaText textarea,line,1,TEXTAREA_LINES
  3822. Else
  3823. SelectTextAreaText textarea,tmpCharLineStart,tmpLine.length-i,TEXTAREA_CHARS
  3824. EndIf
  3825. EndMethod
  3826. Method ShowPos(pos)
  3827. host.SelectPanel( Self )
  3828. HighlightLine( TextAreaLine(textarea,pos) )
  3829. UpdateCursor()
  3830. ActivateGadget( textarea )
  3831. End Method
  3832. Method Debug(line,column)
  3833. HighlightLine( line-1 )
  3834. UpdateCursor()
  3835. End Method
  3836. Method Edit()
  3837. SelectTextAreaText( textarea,cursorpos,0,TEXTAREA_CHARS )
  3838. ActivateGadget( textarea )
  3839. UpdateStatus()
  3840. End Method
  3841. Method UpdateStatus()
  3842. Local c = cursorpos+cursorlen
  3843. If cursorline Then c:-TextAreaChar(textarea,cursorline-1)
  3844. host.SetStatus helpstring+"~t~t"+LocalizeString("{{status_line_char}}").Replace("%1",cursorline).Replace("%2",(c+1))
  3845. End Method
  3846. Method UpdateCursor()
  3847. oldpos=cursorpos
  3848. oldlen=cursorlen
  3849. cursorpos=TextAreaCursor(textarea,TEXTAREA_CHARS)
  3850. cursorlen=TextAreaSelLen(textarea,TEXTAREA_CHARS)
  3851. If cursorpos<>oldpos Or cursorlen<>oldlen
  3852. Local l = TextAreaLine(textarea,cursorpos)+1
  3853. If l<>cursorline And dirtynode
  3854. GetNode().Refresh
  3855. dirtynode=False
  3856. If (deferpos>=0) UpdateCode 'SetCode cleansrc
  3857. EndIf
  3858. cursorline=l
  3859. UpdateStatus()
  3860. BracketMatching(cleansrcl)
  3861. If (tidyqueue1 >= 0 Or tidyqueue2 >= 0) Then UpdateCode()
  3862. PollSystem
  3863. EndIf
  3864. End Method
  3865. ' tdiff - pos del$ add$
  3866. Method CalcDiff:TDiff(src$)
  3867. Local d:TDiff
  3868. If src.length<>cleansrc.length
  3869. d=New TDiff
  3870. d.pos0=cursorpos
  3871. d.count0=cursorlen
  3872. d.pos=oldpos
  3873. d.count=oldlen
  3874. If cursorlen And oldlen 'block modified
  3875. d.del=cleansrc[oldpos..oldpos+oldlen]
  3876. d.add=src[oldpos..cursorpos+cursorlen]
  3877. d.pos1=oldpos
  3878. Else
  3879. If cursorpos<=oldpos And cursorlen<=oldlen 'backspace
  3880. d.del=cleansrc[cursorpos..cursorpos+cleansrc.length-src.length]
  3881. d.pos1=cursorpos
  3882. Else 'insert
  3883. d.del=cleansrc[oldpos..oldpos+oldlen]
  3884. d.add=src[oldpos..cursorpos+cursorlen]
  3885. d.pos1=oldpos
  3886. EndIf
  3887. EndIf
  3888. Else
  3889. If cursorpos>oldpos 'overwrite
  3890. d=New TDiff
  3891. d.pos0=cursorpos
  3892. d.count0=cursorlen
  3893. d.pos=oldpos
  3894. d.count=oldlen
  3895. d.del=cleansrc[oldpos..cursorpos]
  3896. d.add=src[oldpos..cursorpos]
  3897. d.pos1=oldpos
  3898. If d.del = d.add Then d.textchange=False
  3899. EndIf
  3900. EndIf
  3901. Return d
  3902. End Method
  3903. Method UpdateCode(makeundo=True)
  3904. Local cpos
  3905. Local src$ = TextAreaText(textarea)
  3906. Local d:TDiff = CalcDiff(src)
  3907. If d
  3908. If Not nativeundo Then
  3909. If makeundo And d.textchange
  3910. undolist.AddLast d
  3911. redolist.Clear
  3912. EndIf
  3913. End If
  3914. SetCode src,d
  3915. If d.textchange Then dirtynode=True
  3916. EndIf
  3917. If (deferpos >= 0) Or (tidyqueue1 >= 0) Or (tidyqueue2 >= 0) Then SetCode src
  3918. End Method
  3919. Method Undo()
  3920. If nativeundo Then
  3921. TextAreaUndo(textarea)
  3922. Local src$ = TextAreaText(textarea)
  3923. Local d:TDiff = CalcDiff(src)
  3924. SetCode TextAreaText(textarea),d
  3925. UpdateCursor
  3926. Else
  3927. Local d:TDiff
  3928. If undolist.IsEmpty() Return
  3929. d=TDiff(undolist.RemoveLast())
  3930. redolist.AddLast d
  3931. SetTextAreaText textarea,d.del,d.pos1,d.add.length
  3932. SelectTextAreaText(textarea,d.pos,d.count)
  3933. SetCode TextAreaText(textarea),d
  3934. UpdateCursor
  3935. End If
  3936. End Method
  3937. Method Redo()
  3938. Local d:TDiff
  3939. If nativeundo Then
  3940. TextAreaRedo(textarea)
  3941. Local src$ = TextAreaText(textarea)
  3942. Local d:TDiff = CalcDiff(src)
  3943. SetCode TextAreaText(textarea),d
  3944. UpdateCursor
  3945. Else
  3946. If redolist.IsEmpty() Return
  3947. d=TDiff(redolist.RemoveLast())
  3948. undolist.AddLast d
  3949. SetTextAreaText textarea,d.add,d.pos,d.del.length
  3950. SelectTextAreaText(textarea,d.pos0,d.count0)
  3951. UpdateCursor
  3952. SetCode TextAreaText(textarea),d
  3953. End If
  3954. End Method
  3955. Method RefreshStyle()
  3956. Local rgb:TColor
  3957. Local src$
  3958. Local charwidth
  3959. charwidth=host.options.editfont.CharWidth(32)
  3960. If TextAreaHasHighlighting(textarea) Then
  3961. Local back:TColor = host.options.editcolor
  3962. Local fore:TColor = host.options.styles[0].color
  3963. TextAreaClearHighlightStyles(textarea, back.red, back.green, back.blue, fore.red, fore.green, fore.blue)
  3964. End If
  3965. SetTextAreaTabs textarea,host.options.tabsize*charwidth
  3966. SetMargins textarea,4
  3967. SetTextAreaFont textarea,host.options.editfont
  3968. If Not TextAreaHasHighlighting(textarea) Then
  3969. rgb=host.options.editcolor
  3970. SetTextAreaColor textarea,rgb.red,rgb.green,rgb.blue,True
  3971. rgb=host.options.styles[0].color
  3972. SetTextAreaColor textarea,rgb.red,rgb.green,rgb.blue,False
  3973. Else
  3974. If host.options.syntaxhighlight
  3975. For Local i:Int = 0 Until 5
  3976. Local style:TTextStyle = host.options.styles[i]
  3977. TextAreaSetHighlightStyle(textarea, i, style.flags, style.color.red, style.color.green, style.color.blue)
  3978. Next
  3979. End If
  3980. End If
  3981. If TextAreaHasLineNumbers(textarea) Then
  3982. TextAreaSetLineNumberForeColor(textarea, 0, 0, 0)
  3983. End If
  3984. SetTextAreaCaretWidth textarea,host.options.caretstyle.width
  3985. rgb=host.options.caretstyle.color
  3986. SetTextAreaCaretColor textarea,rgb.red,rgb.green,rgb.blue
  3987. rgb=host.options.lineNumberStyle.bg
  3988. TextAreaSetLineNumberBackColor textarea,rgb.red,rgb.green,rgb.blue
  3989. rgb=host.options.lineNumberStyle.fg
  3990. TextAreaSetLineNumberForeColor textarea,rgb.red,rgb.green,rgb.blue
  3991. TextAreaSetLineNumberEnable textarea, host.options.lineNumberStyle.flags
  3992. TextAreaSetCaretLineBackgroundColor(textarea, host.options.caretStyle.caretLineColor.red, host.options.caretStyle.caretLineColor.green, host.options.caretStyle.caretLineColor.blue,host.options.caretStyle.caretLineAlpha)
  3993. TextAreaSetCaretLineVisible(textarea, host.options.caretStyle.caretLineVisible)
  3994. TextAreaSetBracketMatchingColor(textarea, host.options.styles[MATCHING].color.red, host.options.styles[MATCHING].color.green, host.options.styles[MATCHING].color.blue, host.options.styles[MATCHING].flags)
  3995. src=cleansrc
  3996. cleansrc=""
  3997. cleansrcl=""
  3998. cursorpos=0
  3999. SetCode(src)
  4000. End Method
  4001. Function IsntAlphaNumeric(c) 'lowercase test only
  4002. If c<48 Return True
  4003. If c>=58 And c<95 Return True
  4004. If c=96 Return True
  4005. If c>=123 Return True
  4006. End Function
  4007. Function IsntAlphaNumericOrQuote(c) 'lowercase test only
  4008. If c=34 Return False
  4009. If c<48 Return True
  4010. If c>=58 And c<95 Return True
  4011. If c=96 Return True
  4012. If c>=123 Return True
  4013. End Function
  4014. Function IsCode(src$,p)
  4015. Local n
  4016. Local l = src.FindLast(EOL$,src.length-p)
  4017. If l=-1 l=0
  4018. Local q = src.Find("'",l)
  4019. If q<>-1 And q<p Return
  4020. q=l
  4021. While q<p
  4022. q=src.Find(QUOTES$,q)+1
  4023. If q=0 Exit
  4024. If q<=p n:+1
  4025. Wend
  4026. Return Not(n&1)
  4027. End Function
  4028. Function FindLabel(src$,pos)
  4029. Local p,q,c
  4030. While pos>=0
  4031. p=src.Find("#",pos)
  4032. If p=-1 Exit
  4033. q=p
  4034. While q>0
  4035. q:-1
  4036. c=src[q]
  4037. If c=13 Return p
  4038. If c=10 Return p
  4039. If c=32 Or c=9 Continue
  4040. Exit
  4041. Wend
  4042. If q<0 Return p
  4043. pos=p+1
  4044. Wend
  4045. Return src.length
  4046. End Function
  4047. Function FindToken(token$,src$,pos) 'lowercase src only!
  4048. Local p,c
  4049. Local n=token.length
  4050. While pos>=0
  4051. p=src.Find(token,pos)
  4052. If p=-1 Exit
  4053. c=10 If p>0 c=src[p-1]
  4054. If isntalphanumeric(c)
  4055. If p+n<src.length c=src[p+n]
  4056. If isntalphanumeric(c)
  4057. If iscode(src,p)
  4058. If p<4 Or src[p-4..p]<>"end " Return p
  4059. EndIf
  4060. EndIf
  4061. EndIf
  4062. pos=p+1
  4063. Wend
  4064. Return src.length
  4065. End Function
  4066. Function FindEndToken(token$,src$,pos,returnlast=False) 'if true returns first character after endtoken
  4067. Local p,q,e$,n
  4068. p=pos
  4069. e$="end"+token
  4070. n=e.length
  4071. While p<src.length
  4072. p=src.Find(e$,p)
  4073. If p=-1 Exit
  4074. If p+n=src.length Or isntalphanumeric(src[p+n])
  4075. If iscode(src,p)
  4076. If p=0 Or isntalphanumeric(src[p-1]) Exit
  4077. EndIf
  4078. EndIf
  4079. p=p+n
  4080. Wend
  4081. If p=-1 p=src.length Else If returnlast p:+n
  4082. q=pos
  4083. e$="end "+token
  4084. n=e.length
  4085. While q<src.length
  4086. q=src.Find(e$,q)
  4087. If q=-1 Exit
  4088. If q+n=src.length Or isntalphanumeric(src[q+n])
  4089. If iscode(src,q)
  4090. If q=0 Or isntalphanumeric(src[q-1]) Exit
  4091. EndIf
  4092. EndIf
  4093. q=q+n
  4094. Wend
  4095. If q=-1 q=src.length Else If returnlast q:+n
  4096. Return Min(p,q)
  4097. End Function
  4098. Function IsFirstCharOnLine(src$,pos)
  4099. Local c
  4100. For Local i:Int = 1 To pos
  4101. c=src[pos-i]
  4102. If c=10 Or c=13 Return True
  4103. If c>32 Return False
  4104. Next
  4105. Return True
  4106. End Function
  4107. ' rem and endrem must be first nonwhitespace on line - following funcs are for lowercase src only
  4108. Function FindRem(src$,pos)
  4109. While pos<src.length
  4110. pos=FindToken("rem",src,pos)
  4111. If pos=src.length Exit
  4112. If IsFirstCharOnLine(src,pos) Return pos
  4113. pos:+1
  4114. Wend
  4115. Return pos
  4116. End Function
  4117. Function FindEndRem(src$,pos,returnlast=False)
  4118. Local i,c
  4119. While pos<src.length
  4120. pos=FindEndToken("rem",src,pos)
  4121. If pos=src.length Exit
  4122. If IsFirstCharOnLine(src,pos)
  4123. If returnlast
  4124. If src[pos+5]=Asc("e") Or src[pos+5]=Asc("E") pos:+1
  4125. pos:+6
  4126. EndIf
  4127. Return pos
  4128. EndIf
  4129. pos:+1
  4130. Wend
  4131. Return src.length
  4132. End Function
  4133. Function FindPrevRem(src$,pos) 'lowercase src only!
  4134. Local p,c
  4135. While pos>0
  4136. If pos>src.length Exit 'fixed endrem on lastline overrun
  4137. p=src.FindLast("rem",src.length-pos)
  4138. If p=-1 Exit
  4139. If ( p>=src.length-3 Or isntalphanumeric(src[p+3]) ) And IsFirstCharOnLine(src,p) Return p
  4140. pos=p-1
  4141. Wend
  4142. Return -1
  4143. End Function
  4144. Method IsRemmed(pos,src$)
  4145. Local p = FindPrevRem(src$,Min(pos+3,src.length))
  4146. If p<0 Return
  4147. p=FindEndRem(src$,p)
  4148. If p<0 Or pos<p Return True
  4149. EndMethod
  4150. Method WasRemmed(pos,src$)
  4151. Local s$ = cleansrcl
  4152. Local p = (src.length-s.length)
  4153. If p<0 pos:-p
  4154. p=FindPrevRem(s$,Min(pos+3,s.length))
  4155. If p<0 Return
  4156. p=FindEndRem(s$,p)
  4157. If pos<p Return True
  4158. End Method
  4159. Method CheckDirty(src$)
  4160. SetDirty (Not (src=filesrc And undolist.IsEmpty()))
  4161. End Method
  4162. Method HasTidyQueue()
  4163. Return ((deferpos >= 0) Or (tidyqueue1 >= 0) Or (tidyqueue2 >= 0))
  4164. EndMethod
  4165. Method ClearTidyQueue(start,endpos)
  4166. If start<=deferpos And deferpos < endpos Then deferpos = -1
  4167. If start<=tidyqueue1 And tidyqueue1 < endpos Then tidyqueue1 = -1
  4168. If start<=tidyqueue2 And tidyqueue2 < endpos Then tidyqueue2 = -1
  4169. EndMethod
  4170. Method SetCode(src$,diff:TDiff=Null)
  4171. Local same,i,p,startp,p1,q,r,a,t$,h$,lsrc$,r0,r1,cpos,autocap
  4172. Local style:TTextStyle[5],s:TTextStyle
  4173. ' update dirty flag
  4174. CheckDirty src
  4175. same = Not ((diff) Or (src<>cleansrc))
  4176. If same And Not (diff Or HasTidyQueue()) Then Return
  4177. autocap=host.options.autocapitalize
  4178. Local shouldHighlight:Int = Not TextAreaHasHighlighting(textarea)
  4179. If Not isbmx Or Not host.quickhelp Or Not host.options.syntaxhighlight Or (Not autocap And Not shouldHighlight)
  4180. If Not same Then
  4181. cleansrc=src
  4182. cleansrcl=src.ToLower()
  4183. EndIf
  4184. Return
  4185. EndIf
  4186. ' doit
  4187. If same Then lsrc = cleansrcl Else lsrc=src.ToLower()
  4188. cpos=TextAreaCursor(textarea,TEXTAREA_CHARS)
  4189. LockTextArea textarea
  4190. TextAreaEnableUndoRedo(textarea, False)
  4191. style=host.options.styles
  4192. ' calculate highlight region
  4193. If diff
  4194. p=diff.pos
  4195. p1=p+diff.add.length
  4196. If Not diff.add.length Then
  4197. p:-diff.del.length
  4198. EndIf
  4199. ElseIf HasTidyQueue()
  4200. p=src.length
  4201. If (deferpos>=0) Then
  4202. p = Min(p,deferpos)
  4203. p1 = Max(p1,deferpos+1)
  4204. EndIf
  4205. If (tidyqueue1>=0) Then
  4206. p = Min(p,tidyqueue1)
  4207. p1 = Max(p1, tidyqueue1+1)
  4208. EndIf
  4209. If (tidyqueue2>=0) Then
  4210. p = Min(p,tidyqueue2)
  4211. p1 = Max(p1, tidyqueue2+1)
  4212. EndIf
  4213. Else
  4214. p=firstdiff(src,cleansrc)
  4215. p1=lastdiff(src,cleansrc)
  4216. EndIf
  4217. q=src.length-cleansrc.length
  4218. If p1-p<q p1=p+q
  4219. If p1<p p1=p
  4220. ' round region to line breaks
  4221. 'Print "p="+p+" p1="+p1
  4222. If p>src.length p=src.length
  4223. p=src.findlast(EOL,src.length-(p-1))+1
  4224. p1=src.find(EOL,p1)+1
  4225. If p1=0 p1=src.length
  4226. ' if endrem between p0,p1 and next rem after p1 move p1 forwards
  4227. r1=FindEndRem(lsrc,p)
  4228. If r1<p1 And wasremmed(r1+6,lsrc)
  4229. r0=FindRem(lsrc,r1+6)
  4230. If r0>p1 p1=r0
  4231. EndIf
  4232. ' if rem between p0,p1 and matching endrem after p1 move p1 forewards
  4233. r0=FindPrevRem(lsrc,p1)
  4234. If r0>=p And r0+3<>cpos 'defer fix
  4235. r1=FindEndRem(lsrc,r0,True)
  4236. If r1>p1 p1=r1
  4237. EndIf
  4238. ' if rem before p0 and matching endrem after p0 highlight to endrem and move p0 forwards
  4239. r0=FindPrevRem(lsrc,p)
  4240. If r0<>-1 And r0<p
  4241. r1=FindEndRem(lsrc,r0,True)
  4242. If r1>p
  4243. s=style[COMMENT]
  4244. If shouldHighlight And r1>p s.Format(textarea,p,r1-p)
  4245. If autocap And r1<src.length
  4246. If lsrc[r1-6..r1]="endrem" And src[r1-6..r1]<>"EndRem" SetTextAreaText textarea,"EndRem",r1-6,6
  4247. If lsrc[r1-7..r1]="end rem" And src[r1-7..r1]<>"End Rem" SetTextAreaText textarea,"End Rem",r1-7,7
  4248. EndIf
  4249. ClearTidyQueue(p,r1)
  4250. p=r1
  4251. EndIf
  4252. EndIf
  4253. ' if was remmed and now isn't move p1 down to nearest rem or endrem
  4254. If WasRemmed(p,lsrc)
  4255. r0=FindRem(lsrc,p)
  4256. r1=FindEndRem(lsrc,r0,True)
  4257. p1=Max(p1,Min(r0,r1))
  4258. EndIf
  4259. ' highlight code
  4260. ClearTidyQueue(p,p1)
  4261. s=style[NORMAL]
  4262. If shouldHighlight And p1>p s.format(textarea,p,p1-p)
  4263. startp = p
  4264. While p<p1
  4265. host.UpdateProgress(msgHighlightingStatus,(p*100)/p1)
  4266. a=src[p]
  4267. ' quoted strings
  4268. If a=34
  4269. q=p1
  4270. r=src.Find(Chr(34),p+1)
  4271. If r>-1 And r<q q=r+1
  4272. r=src.Find(EOL,p+1)
  4273. If r>-1 And r<q q=r
  4274. s=style[QUOTED]
  4275. If shouldHighlight s.format(textarea,p,q-p)
  4276. p=q
  4277. Continue
  4278. EndIf
  4279. ' single line comments
  4280. If a=39
  4281. q=p1
  4282. r=src.Find(EOL,p+1)
  4283. If r>-1 And r<q q=r
  4284. s=style[COMMENT]
  4285. If shouldHighlight s.format(textarea,p,q-p)
  4286. p=q
  4287. Continue
  4288. EndIf
  4289. ' tokens
  4290. If (a>=65 And a<91) Or (a>=97 And a<123) Or (a=95)
  4291. q=p+1
  4292. While q<p1
  4293. a=src[q]
  4294. If a<48 Exit 'changed to include dot (chr 47)
  4295. If a>=58 And a<65 Exit
  4296. If a>=91 And a<95 Exit
  4297. If a=96 Exit
  4298. If a>122 Exit
  4299. q:+1
  4300. Wend
  4301. t$=src[p..q]
  4302. h$=host.quickhelp.token(t$)
  4303. If h$
  4304. If h$<>t$ And autocap
  4305. If cpos<p Or cpos>q
  4306. SetTextAreaText textarea,h,p,h.length
  4307. Else
  4308. deferpos=q
  4309. EndIf
  4310. EndIf
  4311. s=style[KEYWORD]
  4312. If h$="Rem" And IsFirstCharOnLine(lsrc,p) ' Not (p>4 And lsrc[p-4..p]="end ")
  4313. If q<>cpos
  4314. q=FindEndRem(lsrc,p,True)
  4315. s=style[COMMENT]
  4316. Else
  4317. deferpos=q
  4318. EndIf
  4319. EndIf
  4320. If shouldHighlight s.format(textarea,p,q-p)
  4321. EndIf
  4322. p=q
  4323. Continue
  4324. EndIf
  4325. ' numbers
  4326. If (p=0 Or IsntAlphaNumeric(lsrc[p-1])) And ((a>=$30 And a<$3A) Or (a=$24) Or (a=$25) Or (a=$2E)) '0-9, $, %, .
  4327. q=p+1
  4328. Local hexed:Int = (a=$24), binaried:Int = (a=$25), dots:Int = (a=$2E)
  4329. Local valid:Int = Not(hexed Or binaried Or dots)
  4330. While q<(p1)
  4331. a=lsrc[q]
  4332. q:+1
  4333. If (a>=$30 And a<$3A) Then
  4334. valid = True
  4335. Continue '0-9
  4336. EndIf
  4337. If hexed
  4338. If (a>=$61 And a<$67) Then 'a-f (only test lower as 'a' var is from lsrc)
  4339. valid = True
  4340. Continue
  4341. EndIf
  4342. EndIf
  4343. If (a=$2E) Then
  4344. 'Hex or Binary literals don't support decimal points
  4345. If Not (hexed Or binaried) Then
  4346. dots:+1
  4347. 'Fix for slicing '..' syntax
  4348. If src[q-2] = $2E Then
  4349. dots:-2
  4350. q:-2
  4351. Exit
  4352. EndIf
  4353. 'End Fix
  4354. Continue
  4355. EndIf
  4356. EndIf
  4357. If Not IsntAlphaNumeric(a) Then valid = False
  4358. q:-1
  4359. Exit
  4360. Wend
  4361. If shouldHighlight And valid And dots < 2 Then style[NUMBER].format(textarea,p,(q-p))
  4362. 'Fix for slicing '..' syntax
  4363. If q<src.length And (src[q]=Asc(".")) Then q:+1
  4364. If q<src.length And (src[q]=Asc(".")) Then q:+1
  4365. 'End Fix
  4366. p=q
  4367. Continue
  4368. EndIf
  4369. p:+1
  4370. Wend
  4371. If shouldHighlight BracketMatching(lsrc,startp,p1,True)
  4372. TextAreaEnableUndoRedo(textarea, True)
  4373. UnlockTextArea textarea
  4374. If Not same
  4375. cleansrc=src
  4376. cleansrcl=lsrc
  4377. EndIf
  4378. ' CheckDirty src simon was here
  4379. End Method
  4380. Field currentbrackets:Int[]
  4381. Method BracketMatching(lsrc$,cln1=-1,cln2=-1,alwaysfind:Int = False)
  4382. If TextAreaHasBracketMatching(textarea) Then
  4383. TextAreaMatchBrackets(textarea)
  4384. Return
  4385. End If
  4386. Local check:Int, depth:Int, style:TTextStyle[] = host.options.styles
  4387. Local otherchar:Int = 0, absotherchar:Int = 0, othercharpos:Int = 0, limit:Int
  4388. Local currentchar:Int = 0, currentcharpos:Int = Max(cursorpos-1,0)
  4389. If cursorlen Then Return
  4390. If currentbrackets Then
  4391. If Not(cln2 > currentbrackets[0] And cln1 <= currentbrackets[0]) Then
  4392. If currentbrackets[0]>-1 Then tidyqueue1 = currentbrackets[0]
  4393. EndIf
  4394. If Not(cln2 > currentbrackets[1] And cln1 <= currentbrackets[1]) Then
  4395. If currentbrackets[1]>-1 Then tidyqueue2 = currentbrackets[1]
  4396. EndIf
  4397. currentbrackets = Null
  4398. If Not alwaysfind Then Return
  4399. EndIf
  4400. If host.options.bracketmatching And isbmx And Not IsRemmed(currentcharpos,lsrc) Then
  4401. limit = Min(lsrc.length,currentcharpos+2)
  4402. While currentcharpos >= 0 And currentcharpos < limit
  4403. If IsCode(lsrc,currentcharpos) Then
  4404. Select lsrc[currentcharpos]
  4405. Case Asc("(");otherchar = Asc(")");Exit
  4406. Case Asc("{");otherchar = Asc("}");Exit
  4407. Case Asc("[");otherchar = Asc("]");Exit
  4408. ' Negate char code to search backwards
  4409. Case Asc(")");otherchar = -Asc("(");Exit
  4410. Case Asc("}");otherchar = -Asc("{");Exit
  4411. Case Asc("]");otherchar = -Asc("[");Exit
  4412. EndSelect
  4413. EndIf
  4414. currentcharpos:+1
  4415. Wend
  4416. If otherchar Then
  4417. absotherchar = Abs(otherchar)
  4418. currentchar = lsrc[currentcharpos]
  4419. LockTextArea textarea
  4420. style[MATCHING].format(textarea, currentcharpos, 1)
  4421. currentbrackets = [currentcharpos,-1]
  4422. othercharpos = currentcharpos+(otherchar/absotherchar)
  4423. While othercharpos < lsrc.length And othercharpos >= 0
  4424. If IsCode(lsrc,othercharpos) Then
  4425. Select lsrc[othercharpos]
  4426. Case Asc(" "), Asc("~t")
  4427. 'Do nothing
  4428. Case Asc("'")
  4429. Exit
  4430. Case absotherchar
  4431. If check < 0 Then Exit Else check = 0
  4432. If depth Then
  4433. depth:-1
  4434. Else
  4435. style[MATCHING].format(textarea, othercharpos, 1)
  4436. currentbrackets[1] = othercharpos
  4437. UnlockTextArea textarea
  4438. Return
  4439. EndIf
  4440. Case Asc("~n")
  4441. If (otherchar/absotherchar) > 0 Then
  4442. If check = 2 Then check = 0 Else Exit
  4443. Else
  4444. If check < 0 Then Exit Else check = -2
  4445. EndIf
  4446. Case Asc(".")
  4447. check:+1
  4448. Default
  4449. If check < 0 Then Exit Else check = 0
  4450. If lsrc[othercharpos] = lsrc[currentcharpos] Then depth:+1
  4451. EndSelect
  4452. EndIf
  4453. othercharpos:+(otherchar/absotherchar)
  4454. Wend
  4455. UnlockTextArea textarea
  4456. EndIf
  4457. EndIf
  4458. EndMethod
  4459. Method AutoIndent()
  4460. Local p,q
  4461. Local c = TextAreaCursor(textarea,TEXTAREA_CHARS)
  4462. Local n = TextAreaSelLen(textarea,TEXTAREA_CHARS)
  4463. If c<cleansrc.length
  4464. p=cleansrc.FindLast(EOL,cleansrc.length-(c-1))+1
  4465. q=p
  4466. While cleansrc[q]=9 And q<c
  4467. q:+1
  4468. Wend
  4469. If q>c q=c
  4470. EndIf
  4471. SetTextAreaText textarea,EOL$+cleansrc[p..q],c,n
  4472. SelectTextAreaText textarea,c+1+q-p,0
  4473. UpdateCursor
  4474. UpdateCode
  4475. End Method
  4476. Method IndentCode()
  4477. Local a$
  4478. ' blockindent
  4479. Local p0 = TextAreaCursor(textarea,TEXTAREA_LINES)
  4480. Local p1 = TextAreaSelLen(textarea,TEXTAREA_LINES)
  4481. ' v122: make sure the entire block is selected (start cursor pos may in the middle of the line)
  4482. SelectTextAreaText textarea , p0 , p1 , TEXTAREA_LINES
  4483. UpdateCursor
  4484. TextAreaBeginUndoAction textarea
  4485. For Local i:Int = 0 Until p1
  4486. a$="~t"+TextAreaText(textarea,p0+i,1,TEXTAREA_LINES)
  4487. SetTextAreaText textarea,a$,p0+i,1,TEXTAREA_LINES
  4488. Next
  4489. SelectTextAreaText textarea,p0,p1,TEXTAREA_LINES
  4490. TextAreaEndUndoAction textarea
  4491. UpdateCursor
  4492. UpdateCode
  4493. End Method
  4494. Method OutdentCode()
  4495. Local a$,modified
  4496. ' blockoutdent
  4497. Local p0 = TextAreaCursor(textarea,TEXTAREA_LINES)
  4498. Local p1 = TextAreaSelLen(textarea,TEXTAREA_LINES)
  4499. ' v122: make sure the entire block is selected (start cursor pos may in the middle of the line)
  4500. SelectTextAreaText textarea , p0 , p1 , TEXTAREA_LINES
  4501. UpdateCursor
  4502. TextAreaBeginUndoAction textarea
  4503. For Local i:Int = 0 Until p1
  4504. a$=TextAreaText(textarea,p0+i,1,TEXTAREA_LINES)
  4505. If a[0]=9 a$=a$[1..];modified=True
  4506. SetTextAreaText textarea,a$,p0+i,1,TEXTAREA_LINES
  4507. Next
  4508. If Not modified
  4509. For Local i:Int = 0 Until p1
  4510. a$=TextAreaText(textarea,p0+i,1,TEXTAREA_LINES)
  4511. If a[0]=32 a$=a$[1..]
  4512. SetTextAreaText textarea,a$,p0+i,1,TEXTAREA_LINES
  4513. Next
  4514. EndIf
  4515. SelectTextAreaText textarea,p0,p1,TEXTAREA_LINES
  4516. TextAreaEndUndoAction textarea
  4517. UpdateCursor
  4518. UpdateCode
  4519. End Method
  4520. Function FilterKey(event:TEvent,context:Object)
  4521. ' If event.id<>EVENT_KEYCHAR Return 1
  4522. Local id=event.id
  4523. Local key=event.data
  4524. Local mods=event.mods
  4525. Local this:TOpenCode=TOpenCode(context)
  4526. ?MacOS
  4527. If key=25 And mods=MODIFIER_SHIFT key=KEY_TAB
  4528. ?
  4529. If id=EVENT_KEYCHAR And this And key=KEY_TAB And Not TextAreaHasBlockIndent(this.textarea) And TextAreaSelLen( this.textarea,TEXTAREA_CHARS )
  4530. Select mods
  4531. Case MODIFIER_NONE
  4532. this.IndentCode
  4533. Case MODIFIER_SHIFT
  4534. this.OutdentCode
  4535. End Select
  4536. Return 0
  4537. EndIf
  4538. If id=EVENT_KEYDOWN And key=KEY_ENTER And this And this.host.options.autoindent
  4539. this.AutoIndent()
  4540. Return 0
  4541. EndIf
  4542. '
  4543. ' the scintilla textarea uses KEYCHAR events to update its contents.
  4544. ' so we need to also suppress those for our autoindent funcitonality.
  4545. If id=EVENT_KEYCHAR And key=KEY_ENTER And this And this.host.options.autoindent And TextAreaHasCharEventSupressionFixup(this.textarea) Then
  4546. Return 0
  4547. End If
  4548. Return 1
  4549. End Function
  4550. Method OnEvent()
  4551. Select EventSource()
  4552. Case textarea
  4553. Select EventID()
  4554. Case EVENT_GADGETMENU
  4555. PopupWindowMenu host.window,editmenu
  4556. Case EVENT_GADGETACTION
  4557. UpdateCode
  4558. Case EVENT_GADGETSELECT
  4559. UpdateCursor
  4560. End Select
  4561. End Select
  4562. End Method
  4563. Method SetDirty( bool )
  4564. If dirty=bool Return
  4565. dirty=bool
  4566. name=StripDir(path)
  4567. If (dirty) name:+"*"
  4568. If (host.lockedpanel=Self) name=LocalizeString("{{tab_locked:%1}}").Replace("%1",name)
  4569. host.RefreshPanel Self
  4570. PollSystem
  4571. End Method
  4572. Method SetLocked( bool )
  4573. Local locked:TOpenCode = TOpenCode(host.lockedpanel)
  4574. If locked And locked<>Self locked.SetLocked False
  4575. name=StripDir(path)
  4576. If (dirty) name:+"*"
  4577. If (bool)
  4578. name=LocalizeString("{{tab_locked:%1}}").Replace("%1",name)
  4579. host.lockedpanel=Self
  4580. Else
  4581. host.lockedpanel=Null
  4582. EndIf
  4583. host.RefreshPanel Self
  4584. 'toolbar changes (lock icon)
  4585. host.RefreshToolbar
  4586. 'menu entry changes
  4587. host.RefreshMenu
  4588. End Method
  4589. Method Help()
  4590. If Not host.quickhelp Return
  4591. Local p = TextAreaCursor(textarea,TEXTAREA_CHARS)
  4592. Local a$ = WordAtPos(cleansrc,p)
  4593. If a=helpcmd
  4594. Local l$ = host.quickhelp.link(a$)
  4595. If l
  4596. host.helppanel.go host.bmxpath+l$
  4597. EndIf
  4598. Else
  4599. helpcmd=a$
  4600. helpstring$=host.quickhelp.help(a$)
  4601. UpdateStatus 'host.setstatus helpstring$
  4602. EndIf
  4603. End Method
  4604. Method Find()
  4605. host.findreq.ShowFind WordAtPos(cleansrc,TextAreaCursor(textarea,TEXTAREA_CHARS))
  4606. End Method
  4607. Method FindNext(s$)
  4608. If s seek=s Else s=seek
  4609. Local p = TextAreaCursor(textarea,TEXTAREA_CHARS)
  4610. p:+TextAreaSelLen(textarea,TEXTAREA_CHARS)
  4611. ' case insensitive
  4612. Local l$ = s.toLower()
  4613. p=cleansrcl.Find(l$,p)
  4614. If p=-1 p=cleansrcl.Find(l$)
  4615. ' case sensitive
  4616. ' p=cleansrc.Find(s$,p+1)
  4617. ' if p=-1 p=cleansrc.Find(s$)
  4618. If p=-1
  4619. Notify LocalizeString("{{find_notification_cannotfind}}").Replace("%1",s)
  4620. Return False
  4621. Else
  4622. SelectTextAreaText textarea,p,Len s,TEXTAREA_CHARS
  4623. UpdateCursor
  4624. Return True
  4625. EndIf
  4626. End Method
  4627. Method ReplaceAll(s$,r$)
  4628. Local t$ = TextAreaText( textarea ).ToLower()
  4629. Local c = TextAreaCursor(textarea,TEXTAREA_CHARS),i,p
  4630. s = s.ToLower()
  4631. Repeat
  4632. Local i2=t.Find( s,i )
  4633. If i2=-1 Exit
  4634. p:+i2-i
  4635. i=i2+s.length
  4636. SelectTextAreaText textarea,p,s.length
  4637. UpdateCursor
  4638. UpdateCode
  4639. SetTextAreaText textarea,r,p,s.length
  4640. If p<c c=c+r.length-s.length
  4641. p:+r.length
  4642. SelectTextAreaText textarea,p,0
  4643. UpdateCursor
  4644. UpdateCode
  4645. Forever
  4646. SelectTextAreaText textarea,c,0
  4647. UpdateCursor
  4648. End Method
  4649. Method FindReplace(r$)
  4650. Local n, f$, x$
  4651. Local p = r.Find("~0")
  4652. If p>0
  4653. f$=r[..p]
  4654. r$=r[p+1..]
  4655. ReplaceAll f$,r$
  4656. Else
  4657. p=TextAreaCursor(textarea,TEXTAREA_CHARS)
  4658. n=TextAreaSelLen(textarea,TEXTAREA_CHARS)
  4659. If Not n Return
  4660. SetTextAreaText textarea,r$,p,n
  4661. SelectTextAreaText textarea,p+r.length,0
  4662. UpdateCursor
  4663. UpdateCode
  4664. EndIf
  4665. Return True
  4666. End Method
  4667. Method ReadSource(path$)
  4668. Local src$
  4669. src=CacheAndLoadText(path)
  4670. src=src.Replace(Chr(13),"")
  4671. src=src.Replace(Chr(11),"")
  4672. LockTextArea textarea
  4673. SetTextAreaText textarea,src
  4674. UnlockTextArea textarea
  4675. filesrc=TextAreaText(textarea)
  4676. cleansrc=""
  4677. cleansrcl=""
  4678. ActivateGadget textarea
  4679. End Method
  4680. Method SaveSource(file$)
  4681. If host.options.autobackup
  4682. DeleteFile file+".bak"
  4683. RenameFile file,file+".bak"
  4684. EndIf
  4685. Local src$ = TextAreaText(textarea)
  4686. filesrc=src
  4687. src=src.Replace(Chr(13),Chr(10))
  4688. src=src.Replace(Chr(11),"")
  4689. Local txt$ = src.Replace$(Chr(10),Chr(13)+Chr(10))
  4690. Try
  4691. SaveText txt,file
  4692. Catch exception:Object
  4693. Local err$=String(exception)
  4694. Notify "Save Error~n"+err
  4695. Return False
  4696. EndTry
  4697. path=host.FullPath$(file)
  4698. dirty=True
  4699. SetDirty False
  4700. host.AddRecent(path$)
  4701. Return True
  4702. End Method
  4703. Method BuildSource(quick,debug,threaded,consoleBuild,guiBuild,makelibBuild,run, verbose, quickscan, universal, warnover, gdbdebug, requireOverride, overrideError, useUPX:Int, platform:String = Null, architecture:String = Null, appstub:String = Null)
  4704. Local cmd$,out$,arg$
  4705. If isbmx Or isc Or iscpp
  4706. cmd$=quote(host.bmkpath)
  4707. If guiBuild Or consoleBuild Then
  4708. cmd$:+" makeapp"
  4709. Else
  4710. cmd:+" makelib"
  4711. End If
  4712. If run cmd$:+" -x"
  4713. If debug cmd$:+" -d" Else cmd$:+" -r" '-v
  4714. If threaded cmd$:+" -h"
  4715. If guiBuild cmd$:+" -t gui"
  4716. If Not quick cmd$:+" -a"
  4717. If verbose cmd :+ " -v"
  4718. If quickscan cmd :+ " -quick"
  4719. If universal cmd :+ " -i"
  4720. If warnover cmd :+ " -w"
  4721. If gdbdebug cmd :+ " -gdb"
  4722. 'UPX compression is only available for "makeapp"
  4723. If (guiBuild Or consoleBuild) And useUPX cmd :+ " -upx"
  4724. If requireOverride cmd :+ " -override"
  4725. 'bmk requires "-override" to use "-overerr"
  4726. If requireOverride And overrideError cmd :+ " -overerr"
  4727. If appstub And appstub <> "brl.appstub" cmd :+ " -b " + appstub
  4728. If platform cmd :+ " -l " + platform
  4729. If architecture cmd :+ " -g " + architecture
  4730. If debug Or threaded
  4731. out=StripExt(host.FullPath(path))
  4732. If debug out:+".debug"
  4733. cmd:+" -o "+quote(out$)+" "
  4734. EndIf
  4735. cmd$:+" "+quote(host.FullPath(path))
  4736. If run
  4737. arg$=host.GetCommandLine()
  4738. If arg cmd$:+" "+arg
  4739. EndIf
  4740. host.execute cmd,"Building "+StripExt(StripDir(path)) ',exe$
  4741. Else
  4742. If ishtml
  4743. host.helppanel.Go "file://"+path
  4744. Else
  4745. 'see what the system shell thinks of the file
  4746. Local cd$=CurrentDir()
  4747. ChangeDir ExtractDir(path)
  4748. cmd=StripDir(path)
  4749. host.execute cmd,"Building "+cmd
  4750. ChangeDir cd
  4751. EndIf
  4752. EndIf
  4753. ' print cmd
  4754. End Method
  4755. Method Save()
  4756. Local file$ = path
  4757. If host.IsTempPath(path)
  4758. file=RequestFile(LocalizeString("{{request_saveas_title}}"),FileTypeFilters,True,"")
  4759. If file="" Return False
  4760. If ExtractExt(file)="" file=file+".bmx"
  4761. dirty=True
  4762. EndIf
  4763. If dirty SaveSource(file)
  4764. Return True
  4765. End Method
  4766. ' common command interface
  4767. Method Invoke(command,argument:Object=Null)
  4768. Local file$,ex$
  4769. Local p,res
  4770. Select command
  4771. Case TOOLSHOW
  4772. host.SetCodeNode GetNode()
  4773. host.SetTitle path
  4774. ' simon was here If textarea Edit
  4775. If textarea ActivateGadget textarea
  4776. Case TOOLCLOSE
  4777. If dirty 'Or host.IsTempPath(path)
  4778. Invoke(TOOLSHOW)
  4779. p=Proceed(LocalizeString("{{request_savechanges}}").Replace("%1",name)) 'the current file?
  4780. If p=-1 Return True
  4781. If p=1
  4782. If Not Save() Return True
  4783. EndIf
  4784. EndIf
  4785. If codenode Then
  4786. codenode.Free()
  4787. codenode=Null
  4788. EndIf
  4789. 'Added just in case MaxGUI driver doesn't handle properly.
  4790. SetGadgetFilter textarea,Null,Null
  4791. 'Seb gone.
  4792. host.RemovePanel Self
  4793. FreeGadget(editmenu)
  4794. Case TOOLSAVE
  4795. Save
  4796. Case TOOLQUICKSAVE
  4797. file=path
  4798. If dirty SaveSource(file)
  4799. Case TOOLSAVEAS
  4800. file=path
  4801. If host.IsTempPath(path) file$=""
  4802. file=RequestFile(LocalizeString("{{request_saveas_title}}"),FileTypeFilters,True,file)
  4803. If file="" Return
  4804. ex$=ExtractExt(file)
  4805. If ex$=""
  4806. file=file+".bmx"
  4807. isbmx=True
  4808. Else
  4809. isbmx=(ex.ToLower()="bmx")
  4810. ishtml=(ex.ToLower()="html")
  4811. isc=(ex.ToLower()="c")
  4812. iscpp=(ex.ToLower()="cpp" Or ex.ToLower()="cxx")
  4813. EndIf
  4814. SaveSource(file$)
  4815. RefreshStyle()
  4816. GetNode().Refresh
  4817. SetDirty False
  4818. host.SetTitle path
  4819. Case TOOLGOTO
  4820. Local line=Int(String(argument))
  4821. SelectTextAreaText textarea,line-1,0,TEXTAREA_LINES
  4822. UpdateCursor
  4823. ActivateGadget textarea
  4824. Case TOOLFIND
  4825. Find
  4826. Case TOOLFINDNEXT
  4827. Return FindNext(String(argument))
  4828. Case TOOLREPLACE
  4829. Return FindReplace(String(argument))
  4830. Case TOOLBUILD
  4831. BuildSource host.quickenabled,host.debugenabled,host.threadedenabled,host.consoleenabled, host.guienabled, host.makelibenabled,False, host.verboseenabled, host.quickscanenabled, host.universalenabled, host.warnoverenabled, host.gdbdebugenabled, host.requireOverrideEnabled, host.overrideErrorsEnabled, host.upxEnabled, host.GetPlatform(), host.GetArchitecture(), host.selectedappstub
  4832. Case TOOLRUN
  4833. BuildSource host.quickenabled,host.debugenabled,host.threadedenabled,host.consoleenabled, host.guienabled, host.makelibenabled,True, host.verboseenabled, host.quickscanenabled, host.universalenabled, host.warnoverenabled, host.gdbdebugenabled, host.requireOverrideEnabled, host.overrideErrorsEnabled, host.upxEnabled, host.GetPlatform(), host.GetArchitecture(), host.selectedappstub
  4834. Case TOOLLOCK
  4835. SetLocked True
  4836. Case TOOLUNLOCK
  4837. SetLocked False
  4838. Case TOOLHELP
  4839. Help()
  4840. Case TOOLUNDO
  4841. Undo()
  4842. Case TOOLREDO
  4843. Redo()
  4844. Case TOOLREFRESH
  4845. RefreshStyle()
  4846. Case TOOLCUT
  4847. GadgetCut textarea
  4848. UpdateCursor()
  4849. UpdateCode()
  4850. Case TOOLCOPY
  4851. GadgetCopy textarea
  4852. Case TOOLPASTE
  4853. GadgetPaste textarea
  4854. UpdateCursor()
  4855. UpdateCode()
  4856. Case TOOLSELECTALL
  4857. SelectTextAreaText textarea
  4858. UpdateCursor()
  4859. Case TOOLINDENT
  4860. IndentCode()
  4861. Case TOOLOUTDENT
  4862. OutdentCode()
  4863. Case TOOLPRINT
  4864. GadgetPrint textarea
  4865. End Select
  4866. End Method
  4867. Function CreateEditMenu:TGadget()
  4868. Local edit:TGadget = CreateMenu("{{popup_edit}}",0,Null)
  4869. CreateMenu "{{popup_edit_quickhelp}}",MENUQUICKHELP,edit
  4870. CreateMenu "",0,edit
  4871. CreateMenu "{{popup_edit_cut}}",MENUCUT,edit
  4872. CreateMenu "{{popup_edit_copy}}",MENUCOPY,edit
  4873. CreateMenu "{{popup_edit_paste}}",MENUPASTE,edit
  4874. CreateMenu "",0,edit
  4875. CreateMenu "{{popup_edit_selectall}}",MENUSELECTALL,edit
  4876. CreateMenu "",0,edit
  4877. CreateMenu "{{popup_edit_blockindent}}",MENUINDENT,edit
  4878. CreateMenu "{{popup_edit_blockoutdent}}",MENUOUTDENT,edit
  4879. CreateMenu "",0,edit
  4880. CreateMenu "{{popup_edit_find}}",MENUFIND,edit
  4881. CreateMenu "{{popup_edit_findnext}}",MENUFINDNEXT,edit
  4882. CreateMenu "{{popup_edit_replace}}",MENUREPLACE,edit
  4883. CreateMenu "{{popup_edit_goto}}",MENUGOTO,edit
  4884. Return edit
  4885. End Function
  4886. Method MakePathTemp()
  4887. ' prepends "." to file name with code borrowed from SaveAs
  4888. Local file$=ExtractDir(path)+"/."+StripDir(path)
  4889. SaveSource(file$)
  4890. ' Refresh
  4891. GetNode().Refresh
  4892. ' setdirty False
  4893. host.SetTitle path
  4894. End Method
  4895. Method SetLanguage(path:String)
  4896. If host.options.syntaxhighlight And TextAreaHasHighlighting(textarea) Then
  4897. Local lang:String
  4898. Local keywords:String[] = New String[6]
  4899. Select ExtractExt(path).ToLower()
  4900. Case "bmx"
  4901. lang = "blitzmax"
  4902. If host.quickhelp Then
  4903. keywords[0] = host.quickhelp.tokens
  4904. End If
  4905. Case "bmk","lua"
  4906. lang = "lua"
  4907. keywords[0] = KEYWORDS_LUA
  4908. Case "c"
  4909. lang = "cpp"
  4910. keywords[0] = KEYWORDS_C
  4911. keywords[4] = KEYWORDS_CPP_PP
  4912. Case "cc","cpp","cxx","cs","h","hh","hpp","hxx"
  4913. lang = "cpp"
  4914. keywords[0] = KEYWORDS_CPP
  4915. keywords[4] = KEYWORDS_CPP_PP
  4916. Case "mm", "m"
  4917. lang = "cpp"
  4918. keywords[0] = KEYWORDS_OBJC
  4919. Case "htm","html","shtml","htt","cfm","tpl","hta"
  4920. lang = "html"
  4921. Case "xml","gcl","xsl","svg","xul","xsd","dtd","xslt","axl"
  4922. lang = "xml"
  4923. End Select
  4924. If lang Then
  4925. TextAreaSetHighlightLanguage(textarea, lang)
  4926. End If
  4927. For Local i:Int = 0 Until keywords.length
  4928. If keywords[i] Then
  4929. TextAreaSetHighlightKeywords(textarea, i, keywords[i])
  4930. End If
  4931. Next
  4932. End If
  4933. End Method
  4934. Function Create:TOpenCode(path$,host:TCodePlay)
  4935. Local code:TOpenCode
  4936. Local stream:TStream
  4937. Local isnew
  4938. If path
  4939. If FileType(path)<>FILETYPE_FILE
  4940. Return Null
  4941. EndIf
  4942. stream=ReadFile(path)
  4943. If Not stream
  4944. ' Notify "Open could not read from "+path
  4945. Return Null
  4946. EndIf
  4947. CloseFile stream
  4948. Else
  4949. TEMPCOUNT:+1
  4950. path=host.bmxpath+"/tmp/untitled"+TEMPCOUNT+".bmx"
  4951. isnew=True
  4952. EndIf
  4953. code=New TOpenCode
  4954. code.host=host
  4955. code.active=True
  4956. code.path=host.FullPath(path)
  4957. code.editmenu=CreateEditMenu()
  4958. codeplay.addpanel(code)
  4959. code.textarea=CreateTextArea(0,0,ClientWidth(code.panel),ClientHeight(code.panel),code.panel,0)
  4960. DelocalizeGadget code.textarea
  4961. SetGadgetFilter code.textarea,code.FilterKey,code
  4962. SetTextAreaText code.textarea,"~n"
  4963. SetGadgetLayout code.textarea,EDGE_ALIGNED,EDGE_ALIGNED,EDGE_ALIGNED,EDGE_ALIGNED
  4964. code.SetLanguage(path)
  4965. code.RefreshStyle()
  4966. code.nativeundo = TextAreaHasUndoRedo(code.textarea)
  4967. If isnew
  4968. code.SaveSource path
  4969. code.filesrc="~n"
  4970. ActivateGadget code.textarea
  4971. Else
  4972. host.UpdateProgress "Reading Stream"
  4973. code.ReadSource(path)
  4974. EndIf
  4975. If ExtractExt(path).toLower()="bmx" code.isbmx=True
  4976. If ExtractExt(path).toLower()="c" code.isc=True
  4977. If ExtractExt(path).toLower()="cpp" code.iscpp=True
  4978. If ExtractExt(path).toLower()="cxx" code.iscpp=True
  4979. If ExtractExt(path).toLower()="h" code.iscpp=True
  4980. If ExtractExt(path).toLower()="html" code.ishtml=True
  4981. If ExtractExt(path).toLower()="htm" code.ishtml=True
  4982. code.UpdateCode False
  4983. code.filesrc=TextAreaText(code.textarea)
  4984. TextAreaClearUndoRedo(code.textarea)
  4985. If host.options.syntaxhighlight And TextAreaHasHighlighting(code.textarea) Then
  4986. TextAreaHighlight(code.textarea)
  4987. End If
  4988. Return code
  4989. End Function
  4990. Const KEYWORDS_C:String = "auto break case char const continue default do double else enum extern float for goto if int long " + ..
  4991. "register return short signed sizeof static struct switch typedef union unsigned void volatile while"
  4992. Const KEYWORDS_CPP:String = "alignas alignof and and_eq asm atomic_cancel atomic_commit atomic_noexcept auto bitand bitor bool break case catch " + ..
  4993. "char char8_t char16_t char32_t class compl concept const consteval constexpr const_cast continue co_await co_return " + ..
  4994. "co_yield decltype default delete do double dynamic_cast else enum explicit export extern false float for friend goto if " + ..
  4995. "import inline int long module mutable namespace new noexcept not not_eq nullptr operator or or_eq private protected " + ..
  4996. "public reflexpr register reinterpret_cast requires return short signed sizeof static static_assert static_cast struct " + ..
  4997. "switch synchronized template this thread_local throw true try typedef typeid typename union unsigned using(1) virtual void volatile wchar_t while xor xor_eq"
  4998. Const KEYWORDS_CPP_PP:String = "#include #define #undef #if #ifdef #ifndef #error __FILE__ __LINE__ __DATE__ __TIME__ __TIMESTAMP__ pragma"
  4999. Const KEYWORDS_OBJC:String = "auto else long switch break enum register typedef case extern return union char float short " + ..
  5000. "unsigned const for signed void continue goto sizeof volatile default if static while do int " + ..
  5001. "struct _Packed double protocol interface implementation NSObject NSInteger NSNumber CGFloat " + ..
  5002. "property nonatomic retain strong weak unsafe_unretained readwrite readonly"
  5003. Const KEYWORDS_LUA:String = "and break do else elseif end false for function if in local nil not or repeat return then true until while"
  5004. End Type
  5005. Type TRect
  5006. Field x,y,w,h
  5007. Method Set(xpos,ypos,width,height)
  5008. x=xpos;y=ypos;w=width;h=height
  5009. End Method
  5010. Method ToString$()
  5011. Return ""+x+","+y+","+w+","+h
  5012. End Method
  5013. Method FromString(s$)
  5014. Local p,q,r
  5015. p=s.Find(",")+1;If Not p Return
  5016. q=s.Find(",",p)+1;If Not q Return
  5017. r=s.Find(",",q)+1;If Not r Return
  5018. x=Int(s[..p-1])
  5019. y=Int(s[p..q-1])
  5020. w=Int(s[q..r-1])
  5021. h=Int(s[r..])
  5022. End Method
  5023. Method IsOutside(tx,ty,tw,th)
  5024. If x+w<=tx Or y+h<=ty Return True
  5025. If x>=tx+tw Or y>=ty+th Return True
  5026. End Method
  5027. End Type
  5028. Type TCodePlay
  5029. Const EDITMODE=1
  5030. Const DEBUGMODE=2
  5031. Field bmxpath$,bmkpath$
  5032. Field panels:TToolPanel[]
  5033. Field helppanel:THelpPanel
  5034. Field currentpanel:TToolPanel
  5035. Field output:TOutputPanel
  5036. Field lockedpanel:TToolPanel
  5037. Field activepanel:TToolPanel
  5038. Field cmdlinereq:TCmdLineRequester
  5039. Field cmdline$
  5040. Field gotoreq:TGotoRequester
  5041. Field findreq:TFindRequester
  5042. Field replacereq:TReplaceRequester
  5043. Field options:TOptionsRequester
  5044. ' Field progress:TProgressRequester
  5045. Field activerequesters:TList = New TList
  5046. Field projectreq:TProjectRequester
  5047. Field projectprops:TProjectProperties
  5048. Field searchreq:TSearchRequester
  5049. Field aboutreq:TAboutRequester
  5050. Field eventhandlers:TList=New TList
  5051. Field window:TGadget,menubar:TGadget,toolbar:TGadget,client:TGadget,tabbar:TGadget
  5052. Field split:TSplitter
  5053. Field debugtree:TDebugTree
  5054. Field root:TNode
  5055. Field helproot:TNode
  5056. Field projects:TProjects
  5057. Field coderoot:TNode
  5058. Field navbar:TNavBar
  5059. Field Mode
  5060. Field debugcode:TOpenCode
  5061. Field quickenable:TGadget,quickenabled 'menu,state
  5062. Field debugenable:TGadget,debugenabled 'menu,state
  5063. Field threadedenable:TGadget,threadedenabled
  5064. Field consoleenable:TGadget,consoleenabled 'menu,state
  5065. Field guienable:TGadget,guienabled 'menu,state
  5066. Field makelibenable:TGadget,makelibenabled 'menu,state
  5067. Field verboseenable:TGadget,verboseenabled 'menu,state
  5068. Field quickscanenable:TGadget,quickscanenabled 'menu,state
  5069. Field universalenable:TGadget,universalenabled 'menu,state
  5070. Field warnoverenable:TGadget,warnoverenabled 'menu,state
  5071. Field gdbdebugenable:TGadget,gdbdebugenabled 'menu,state
  5072. Field requireOverrideEnable:TGadget,requireOverrideEnabled 'menu,state
  5073. Field overrideErrorsEnable:TGadget,overrideErrorsEnabled 'menu,state
  5074. Field lockBuildMenuItem:TGadget
  5075. Field unlockBuildMenuItem:TGadget
  5076. Field gotoBuildMenuItem:TGadget
  5077. Field miscoptionsmenu:TGadget
  5078. Field upxEnable:TGadget, upxEnabled:Int 'menu,state
  5079. Field quickhelp:TQuickHelp
  5080. Field running
  5081. Field recentmenu:TGadget
  5082. Field recentfiles:TList=New TList
  5083. Field recentmenus:TGadget[]
  5084. Field openlist:TList=New TList
  5085. Field openlock$
  5086. Field projlist:TList=New TList
  5087. Field winsize:TRect=New TRect
  5088. Field winmax,tooly,splitpos,debugview,navtab
  5089. Field progress,splitorientation
  5090. Field selectedappstub:String
  5091. Field win32enable:TGadget 'menu
  5092. Field linuxenable:TGadget 'menu
  5093. Field macosxenable:TGadget 'menu
  5094. Field iosenable:TGadget 'menu
  5095. Field raspberrypienable:TGadget 'menu
  5096. Field androidenable:TGadget 'menu
  5097. Field emscriptenenable:TGadget 'menu
  5098. Field nxenable:TGadget 'menu
  5099. Field platformenabled:Int[8]
  5100. Const PLATFORMOFFSET:Int = 81
  5101. Field x86enable:TGadget 'menu
  5102. Field x64enable:TGadget 'menu
  5103. Field ppcenable:TGadget 'menu
  5104. Field armenable:TGadget 'menu
  5105. Field armeabiv5enable:TGadget 'menu
  5106. Field armeabiv7aenable:TGadget 'menu
  5107. Field arm64v8aenable:TGadget 'menu
  5108. Field jsenable:TGadget 'menu
  5109. Field armv7enable:TGadget 'menu
  5110. Field arm64enable:TGadget 'menu
  5111. Field architectureenabled:Int[10]
  5112. Const ARCHITECTUREOFFSET:Int = 91
  5113. Const APPSTUBOFFSET:Int = 161
  5114. Field appstubmenus:TGadget[]
  5115. Field appstubmenu:TGadget
  5116. ?MacOS
  5117. Method RanlibMods()
  5118. Local cmd$=Quote( bmxpath+"/bin/bmk" )+" ranlibdir "+Quote( bmxpath+"/mod" )
  5119. system_ cmd
  5120. End Method
  5121. ?
  5122. Method CheckVersion$()
  5123. Local process:TProcess
  5124. Local bytes:Byte[]
  5125. Local cmd$,version$
  5126. cmd$=bmxpath+"/bin/bcc"
  5127. ?win32
  5128. cmd:+".exe"
  5129. ?
  5130. cmd=Quote(cmd)
  5131. process=CreateProcess(cmd$,HIDECONSOLE)
  5132. If process
  5133. Repeat
  5134. Delay 10
  5135. bytes=process.pipe.ReadPipe()
  5136. If bytes
  5137. version:+String.FromBytes(bytes,bytes.length)
  5138. EndIf
  5139. Until Not process.Status()
  5140. EndIf
  5141. If version=""
  5142. Notify "Unable to determine BlitzMax version.~n~nPlease reinstall BlitzMax to repair this problem."
  5143. End
  5144. EndIf
  5145. BCC_VERSION=version.Trim()
  5146. ' print "bcc version="+version
  5147. End Method
  5148. Method OpenProgress(message$)
  5149. ' progress.Open message
  5150. DisableGadget window
  5151. SetStatus message
  5152. progress=-1
  5153. End Method
  5154. Method CloseProgress()
  5155. ' progress.Hide
  5156. SetStatus ""
  5157. EnableGadget window
  5158. progress=0
  5159. End Method
  5160. Method UpdateProgress(message$,value=0) 'returns false if cancelled
  5161. ' Return progress.Update(message,value)
  5162. If progress
  5163. If progress/5<>value/5
  5164. SetStatus message+" "+value+"%"
  5165. progress=value
  5166. ' Pollsystem
  5167. EndIf
  5168. EndIf
  5169. End Method
  5170. Method FullPath$(path$)
  5171. If path[..8]="$BMXPATH" path=bmxpath+path[8..]
  5172. If Not path.Contains("::") Then path = RealPath(path)
  5173. ?win32
  5174. path=path.Replace("\","/")
  5175. ?
  5176. Return path
  5177. End Method
  5178. Method IsTempPath(path$)
  5179. If path[..bmxpath.length+5]=bmxpath+"/tmp/" Return True
  5180. End Method
  5181. Method AddDefaultProj(p$)
  5182. Local projdata:TList = New TList
  5183. projdata.AddLast p
  5184. projlist.AddLast projdata
  5185. End Method
  5186. Method ReadConfig()
  5187. Local stream:TStream
  5188. Local f$,p,a$,b$
  5189. ' defaults
  5190. Local wh=GadgetHeight(Desktop())-80'32
  5191. Local ww=wh
  5192. Local wx=(GadgetWidth(Desktop())-ww)/2
  5193. Local wy=(GadgetHeight(Desktop())-wh)/2
  5194. winsize.set( wx,wy,ww,wh )
  5195. quickenabled=False
  5196. debugenabled=True
  5197. threadedenabled=False
  5198. consoleenabled=False
  5199. guienabled=True
  5200. makelibenabled=False
  5201. upxEnabled=False
  5202. verboseenabled=False
  5203. quickscanenabled=True
  5204. universalenabled=False
  5205. warnoverenabled=True
  5206. gdbdebugenabled=False
  5207. requireOverrideEnabled=False
  5208. overrideErrorsEnabled=False
  5209. For Local i:Int = 0 Until platformenabled.length
  5210. platformenabled[i] = False
  5211. Next
  5212. ?win32
  5213. platformenabled[MENUWIN32ENABLED - PLATFORMOFFSET] = True
  5214. ?linuxx86
  5215. platformenabled[MENULINUXENABLED - PLATFORMOFFSET] = True
  5216. ?linuxx64
  5217. platformenabled[MENULINUXENABLED - PLATFORMOFFSET] = True
  5218. ?macos
  5219. platformenabled[MENUMACOSXENABLED - PLATFORMOFFSET] = True
  5220. ?raspberrypi
  5221. platformenabled[MENURASPBERRYPIENABLED - PLATFORMOFFSET] = True
  5222. ?emscripten
  5223. platformenabled[MENUEMSCRIPTENENABLED - PLATFORMOFFSET] = True
  5224. ?
  5225. splitpos=200;splitorientation = SPLIT_VERTICAL
  5226. selectedappstub="brl.appstub"
  5227. ' read ini
  5228. stream=ReadFile(bmxpath+"/cfg/ide.ini")
  5229. If Not stream
  5230. AddDefaultProj "Samples|samples"
  5231. AddDefaultProj "Modules Source|mod"
  5232. AddDefaultProj "BlitzMax Source|src"
  5233. Return
  5234. EndIf
  5235. options.Read(stream)
  5236. options.Snapshot
  5237. Local projdata:TList
  5238. While Not stream.Eof()
  5239. f$=stream.ReadLine()
  5240. p=f.find("=")
  5241. If p=-1 Continue
  5242. a$=f[..p]
  5243. b$=f[p+1..]
  5244. Select a$
  5245. Case "ide_version"
  5246. Case "file_recent"
  5247. recentfiles.addlast b$
  5248. Case "file_open"
  5249. openlist.addlast b$
  5250. Case "prg_quick"
  5251. quickenabled=Int(b$)
  5252. Case "prg_debug"
  5253. debugenabled=Int(b$)
  5254. Case "prg_threaded"
  5255. threadedenabled=Int(b$)
  5256. Case "prg_console"
  5257. consoleenabled=Int(b$)
  5258. Case "prg_gui"
  5259. guienabled=Int(b$)
  5260. Case "prg_makelib"
  5261. makelibenabled=Int(b$)
  5262. Case "prg_upx"
  5263. upxEnabled=Int(b$)
  5264. Case "prg_verbose"
  5265. verboseenabled=Int(b$)
  5266. Case "prg_quickscan"
  5267. quickscanenabled=Int(b$)
  5268. Case "prg_universal"
  5269. universalenabled=Int(b$)
  5270. Case "prg_warnover"
  5271. warnoverenabled=Int(b$)
  5272. Case "prg_gdbdebug"
  5273. gdbdebugenabled=Int(b$)
  5274. Case "prg_requireoverride"
  5275. requireOverrideEnabled=Int(b$)
  5276. Case "prg_overrideerrors"
  5277. overrideErrorsEnabled=Int(b$)
  5278. Case "prg_platform"
  5279. For Local i:Int = 0 Until platformenabled.length
  5280. platformenabled[i] = False
  5281. If i = Int(b$) Then
  5282. platformenabled[i] = True
  5283. End If
  5284. Next
  5285. Case "prg_architecture"
  5286. For Local i:Int = 0 Until architectureenabled.length
  5287. architectureenabled[i] = False
  5288. If i = Int(b$) Then
  5289. architectureenabled[i] = True
  5290. End If
  5291. Next
  5292. Case "cmd_line"
  5293. cmdline=b$
  5294. Case "prg_locked"
  5295. openlock=b$
  5296. Case "win_size"
  5297. winsize.FromString(b$)
  5298. Case "win_max"
  5299. winmax=Int(b$)
  5300. Case "split_position"
  5301. splitpos=Int(b$)
  5302. Case "split_orientation"
  5303. splitorientation=Int(b$)
  5304. Case "proj_node"
  5305. projdata=New TList
  5306. projdata.AddLast b
  5307. projlist.AddLast projdata
  5308. Case "proj_data"
  5309. If projdata projdata.AddLast b
  5310. Case "appstub"
  5311. selectedappstub = b
  5312. End Select
  5313. Wend
  5314. If Not guienabled And Not makelibenabled Then
  5315. consoleenabled = True
  5316. End If
  5317. stream.close()
  5318. End Method
  5319. Method WriteConfig()
  5320. Local panel:TToolPanel
  5321. Local node:TNode
  5322. Local f$
  5323. Local stream:TStream = WriteFile(bmxpath+"/cfg/ide.ini")
  5324. If Not stream Return
  5325. ' options
  5326. options.write(stream)
  5327. ' defaults
  5328. stream.WriteLine "[Defaults]"
  5329. stream.WriteLine "ide_version="+IDE_VERSION$
  5330. stream.WriteLine "prg_quick="+quickenabled
  5331. stream.WriteLine "prg_debug="+debugenabled
  5332. stream.WriteLine "prg_threaded="+threadedenabled
  5333. stream.WriteLine "prg_console="+consoleenabled
  5334. stream.WriteLine "prg_gui="+guienabled
  5335. stream.WriteLine "prg_makelib="+makelibenabled
  5336. stream.WriteLine "prg_upx="+upxEnabled
  5337. stream.WriteLine "prg_verbose="+verboseenabled
  5338. stream.WriteLine "prg_quickscan="+quickscanenabled
  5339. stream.WriteLine "prg_universal="+universalenabled
  5340. stream.WriteLine "prg_warnover="+warnoverenabled
  5341. stream.WriteLine "prg_gdbdebug="+gdbdebugenabled
  5342. stream.WriteLine "prg_requireoverride="+requireOverrideEnabled
  5343. stream.WriteLine "prg_overrideerrors="+overrideErrorsEnabled
  5344. For Local i:Int = 0 Until platformenabled.length
  5345. If platformenabled[i] Then
  5346. stream.WriteLine "prg_platform=" + i
  5347. End If
  5348. Next
  5349. For Local i:Int = 0 Until architectureenabled.length
  5350. If architectureenabled[i] Then
  5351. stream.WriteLine "prg_architecture=" + i
  5352. End If
  5353. Next
  5354. stream.WriteLine "win_size="+winsize.ToString()
  5355. stream.WriteLine "win_max="+winmax
  5356. stream.WriteLine "split_position="+SplitterPosition(split)
  5357. stream.WriteLine "split_orientation="+SplitterOrientation(split)
  5358. stream.WriteLine "cmd_line="+cmdline
  5359. If selectedappstub Then
  5360. stream.WriteLine "appstub="+selectedappstub
  5361. End If
  5362. If lockedpanel stream.WriteLine "prg_locked="+lockedpanel.path
  5363. Local n:Int
  5364. For f$=EachIn recentfiles
  5365. stream.WriteLine "file_recent="+f$
  5366. ' only last 20
  5367. If n=20 Exit
  5368. n:+1
  5369. Next
  5370. For Local panel:TToolPanel = EachIn panels
  5371. f$=panel.path
  5372. If TOpenCode(panel)
  5373. Local openCode:TOpenCode = TOpenCode(panel)
  5374. Local isActive:Int = (activepanel = openCode)
  5375. If f$ And Not IsTempPath(f$) stream.WriteLine "file_open=" + f$ + "|" + isActive + "|" + openCode.cursorPos
  5376. Else
  5377. If f$ And Not IsTempPath(f$) stream.WriteLine "file_open="+f$
  5378. EndIf
  5379. Next
  5380. projects.write(stream)
  5381. stream.close
  5382. End Method
  5383. Method CloseAll(dontask,inccurrent=True) 'returns true if successful
  5384. Local count, cancel
  5385. For Local panel:TToolPanel = EachIn panels
  5386. If TOpenCode(panel) And (inccurrent Or currentpanel <> panel) count:+1
  5387. Next
  5388. If (Not count) Or dontask Or Confirm(LocalizeString("{{request_closeall}}"))
  5389. For Local panel:TToolPanel = EachIn panels[..] 'Use a copy of the original array for iterating.
  5390. If (inccurrent Or currentpanel <> panel) And panel.invoke(TOOLCLOSE) Then
  5391. cancel=True
  5392. Exit
  5393. EndIf
  5394. Next
  5395. Return Not cancel
  5396. EndIf
  5397. End Method
  5398. Method Quit()
  5399. WriteConfig()
  5400. If CloseAll(True) running=False
  5401. End Method
  5402. Method DebugExit()
  5403. If debugcode
  5404. debugtree.cancontinue = False
  5405. debugcode.Edit 'restore cursor etc.
  5406. debugcode=Null
  5407. EndIf
  5408. SetMode EDITMODE
  5409. RefreshToolbar()
  5410. End Method
  5411. Method DebugSource(path$,line,column)
  5412. Local code:TOpenCode
  5413. path=FullPath(path)
  5414. code=OpenSource(path)
  5415. If Not code Then
  5416. Notify(LocalizeString("{{loaderror_failed}}").Replace("%1",path), True)
  5417. Return
  5418. EndIf
  5419. If debugcode And debugcode<>code Then debugcode.Edit() 'restore cursor etc.
  5420. debugcode=code
  5421. debugcode.debug(line,column)
  5422. ActivateWindow window
  5423. PollSystem
  5424. End Method
  5425. Method SetMode(m)
  5426. If Mode=m Return
  5427. ActivateWindow window
  5428. Select m
  5429. Case DEBUGMODE
  5430. navtab=navbar.SelectedView()
  5431. navbar.SelectView debugview
  5432. Case EDITMODE
  5433. navbar.SelectView navtab
  5434. End Select
  5435. Mode=m
  5436. RefreshToolbar
  5437. End Method
  5438. Method RefreshMenu()
  5439. TOpenCode.RefreshHighlightingMsg()
  5440. 'disable menu entry to unlock build lock if there is none
  5441. If unlockBuildMenuItem and gotoBuildMenuItem
  5442. If not lockedPanel
  5443. DisableMenu(unlockBuildMenuItem)
  5444. DisableMenu(gotoBuildMenuItem)
  5445. Else
  5446. EnableMenu(unlockBuildMenuItem)
  5447. EnableMenu(gotoBuildMenuItem)
  5448. EndIf
  5449. EndIf
  5450. UpdateWindowMenu window
  5451. EndMethod
  5452. Method RefreshToolbar()
  5453. Local i
  5454. ' sourceedit buttons
  5455. If THelpPanel(CurrentPanel)
  5456. DisableGadgetItem toolbar,TB_CLOSE
  5457. Else
  5458. EnableGadgetItem toolbar,TB_CLOSE
  5459. EndIf
  5460. If TOpenCode(CurrentPanel)
  5461. EnableGadgetItem toolbar,TB_SAVE
  5462. For i=TB_CUT To TB_FIND
  5463. EnableGadgetItem toolbar,i
  5464. Next
  5465. Else
  5466. DisableGadgetItem toolbar,TB_SAVE
  5467. For i=TB_CUT To TB_FIND
  5468. DisableGadgetItem toolbar,i
  5469. Next
  5470. EndIf
  5471. ' debug buttons
  5472. If Mode = DEBUGMODE And debugtree.cancontinue Then
  5473. If GadgetItemIcon( toolbar, TB_BUILDRUN ) = TB_BUILDRUN Then
  5474. ModifyGadgetItem( toolbar, TB_BUILDRUN, "", GADGETITEM_LOCALIZED, TB_CONTINUE, "{{tb_continue}}" )
  5475. EndIf
  5476. Else
  5477. If GadgetItemIcon( toolbar, TB_BUILDRUN ) <> TB_BUILDRUN Then
  5478. ModifyGadgetItem( toolbar, TB_BUILDRUN, "", GADGETITEM_LOCALIZED, TB_BUILDRUN, "{{tb_buildrun}}" )
  5479. EndIf
  5480. EndIf
  5481. For i=TB_STEP To TB_STEPOUT
  5482. If Mode=DEBUGMODE And debugtree.cancontinue Then
  5483. EnableGadgetItem toolbar,i
  5484. Else
  5485. DisableGadgetItem toolbar,i
  5486. EndIf
  5487. Next
  5488. ' stop button
  5489. If output And output.process
  5490. EnableGadgetItem toolbar,TB_STOP
  5491. Else
  5492. DisableGadgetItem toolbar,TB_STOP
  5493. EndIf
  5494. ' locked build file buttons
  5495. If lockedpanel
  5496. If GadgetItemIcon( toolbar, TB_LOCKOPEN ) <> TB_LOCKCLOSED
  5497. ModifyGadgetItem( toolbar, TB_LOCKOPEN, "", GADGETITEM_LOCALIZED, TB_LOCKCLOSED, "{{tb_lockedbuildfile}}: " + lockedpanel.path )
  5498. EnableGadgetItem( toolbar, TB_LOCKGOTO)
  5499. EndIf
  5500. Else
  5501. If GadgetItemIcon( toolbar, TB_LOCKOPEN ) <> TB_LOCKOPEN
  5502. ModifyGadgetItem( toolbar, TB_LOCKOPEN, "", GADGETITEM_LOCALIZED, TB_LOCKOPEN, "{{tb_lockbuildfile}}" )
  5503. DisableGadgetItem( toolbar, TB_LOCKGOTO)
  5504. EndIf
  5505. EndIf
  5506. End Method
  5507. Method IsSourceOpen(path$)
  5508. Local p$ = FullPath(path)
  5509. For Local panel:TToolPanel = EachIn panels
  5510. If panel.path=p Return True
  5511. Next
  5512. End Method
  5513. Method OpenSource:TOpenCode(path$)
  5514. Local code:TOpenCode
  5515. Local ext$,p$
  5516. If path$="."
  5517. path$=RequestFile(LocalizeString("{{request_openfile}}"),FileTypeFilters )
  5518. If path$="" Return
  5519. EndIf
  5520. ' check if already open
  5521. p$=FullPath(path).ToLower()
  5522. For Local panel:TToolPanel = EachIn panels
  5523. If panel.path.ToLower()=p
  5524. SelectPanel panel
  5525. Return TOpenCode(panel)
  5526. EndIf
  5527. Next
  5528. ' open based on extension
  5529. ' Select ExtractExt(Upper(path$))
  5530. ' Case "BMX","TXT","BB","CPP","C","S","I","H","HTML","CSS","BAT","FS","VS","README",""
  5531. OpenProgress LocalizeString("{{msg_loading}}").Replace("%1",StripDir(path))
  5532. code=TOpenCode.Create(path,Self)
  5533. If code
  5534. AddRecent code.path
  5535. EndIf
  5536. CloseProgress
  5537. If code
  5538. ActivateGadget code.textarea
  5539. code.GetNode().Refresh
  5540. EndIf
  5541. Return code
  5542. ' end select
  5543. End Method
  5544. Method AddRecent(path$)
  5545. For Local f$ = EachIn recentfiles
  5546. If f$=path$ recentfiles.Remove(f$);Exit
  5547. Next
  5548. recentfiles.AddFirst(path$)
  5549. RefreshRecentFiles
  5550. UpdateWindowMenu window
  5551. End Method
  5552. Method RefreshRecentFiles()
  5553. Local n
  5554. For Local m:TGadget = EachIn recentmenus
  5555. FreeMenu m
  5556. Next
  5557. n=Min(recentfiles.count(),16)
  5558. recentmenus=New TGadget[n]
  5559. n=0
  5560. For Local f$ = EachIn recentfiles
  5561. recentmenus[n]=CreateMenu(f$,MENURECENT+n,recentmenu)
  5562. n:+1
  5563. If n=16 Exit
  5564. Next
  5565. End Method
  5566. Method RefreshAppStubs()
  5567. For Local m:TGadget = EachIn appstubmenus
  5568. FreeMenu m
  5569. Next
  5570. Local n:Int = options.appstubs.length
  5571. appstubmenus=New TGadget[n]
  5572. n=0
  5573. Local checked:Int
  5574. For Local a:String = EachIn options.appstubs
  5575. appstubmenus[n]=CreateMenu(a,APPSTUBOFFSET+n,appstubmenu)
  5576. If selectedappstub = a Then
  5577. CheckMenu appstubmenus[n]
  5578. checked = True
  5579. Else
  5580. UncheckMenu appstubmenus[n]
  5581. End If
  5582. n:+1
  5583. Next
  5584. ' didn't match any app stubs. choose default (brl.appstub)
  5585. If Not checked Then
  5586. selectedappstub = options.appstubs[0]
  5587. CheckMenu appstubmenus[0]
  5588. End If
  5589. End Method
  5590. Method UpdateRestartState()
  5591. ?win32x64
  5592. If options.restartaftershutdown Then
  5593. ' set to restart if the system restarted
  5594. RegisterApplicationRestart(Null, RESTART_NO_CRASH | RESTART_NO_HANG)
  5595. Else
  5596. UnregisterApplicationRestart()
  5597. End If
  5598. ?
  5599. End Method
  5600. Method BuildModules(buildall)
  5601. Local cmd$,out$,exe$
  5602. output.Stop
  5603. SaveAll
  5604. cmd$=quote(bmkpath)
  5605. cmd$:+" makemods "
  5606. If buildall cmd$:+"-a "
  5607. If threadedenabled cmd:+"-h "
  5608. If verboseenabled cmd:+"-v "
  5609. If quickscanenabled cmd:+"-quick "
  5610. If universalenabled cmd:+"-i "
  5611. If warnoverenabled cmd:+"-w "
  5612. If gdbdebugenabled cmd:+"-gdb "
  5613. If requireOverrideEnabled
  5614. cmd:+"-override "
  5615. 'bmk requires "-override" to use "-overerr"
  5616. If overrideErrorsEnabled
  5617. cmd :+ " -overerr"
  5618. EndIf
  5619. EndIf
  5620. Local platform:String = GetPlatform()
  5621. Local architecture:String = GetArchitecture()
  5622. If platform cmd :+ "-l " + platform + " "
  5623. If architecture cmd :+ "-g " + architecture + " "
  5624. Execute cmd,LocalizeString("{{output_msg_buildingmods}}")
  5625. End Method
  5626. Method ImportBB()
  5627. Local f$ = RequestFile(LocalizeString("{{request_importbb_title}}"),"bb" )
  5628. If Not f$ Return
  5629. Local cmd$ = Quote(bmkpath$)
  5630. cmd$:+" convertbb "
  5631. cmd$:+quote(FullPath(f$))
  5632. Execute cmd,LocalizeString("{{output_msg_converting}}").Replace("%1",StripExt(StripDir(f$)))
  5633. output.wait
  5634. OpenSource(StripExt(f$)+".bmx")
  5635. End Method
  5636. Method GetCommandLine$()
  5637. Return cmdline
  5638. End Method
  5639. Method SetCommandLine(Text$)
  5640. cmdline=Text
  5641. End Method
  5642. Method SetStatus(Text$)
  5643. SetStatusText window,Text
  5644. End Method
  5645. Method Execute(cmd$,mess$="",post$="",home=True,tool:TTool=Null)
  5646. If Not output output=TOutputPanel.Create(Self)
  5647. output.execute cmd$,mess$,post$,home,tool
  5648. End Method
  5649. Method SelectError(path$,column,line)
  5650. Local panel:TOpenCode,found
  5651. For panel=EachIn panels
  5652. If panel.path=path found=True;Exit
  5653. Next
  5654. If Not found panel=OpenSource(path)
  5655. If panel
  5656. SelectPanel panel
  5657. panel.Debug line,column
  5658. EndIf
  5659. End Method
  5660. Method ParseError(err$)
  5661. Local mess$,file$,p,q
  5662. Local line,column
  5663. ' bcc error
  5664. If err$[..13]="Compile Error"
  5665. err=err[14..]
  5666. p=err.find(EOL$)
  5667. If p=-1 p=err.length
  5668. mess=err[..p]
  5669. err=err[p+1..]
  5670. If err[..1]="["
  5671. p=err.find("]")
  5672. If p=-1 p=err.length
  5673. file$=err[1..p]
  5674. p=file.find(";")+1
  5675. If p=0 p=err.length
  5676. q=file.find(";",p)+1
  5677. If q=0 q=err.length
  5678. line=Int(file[p..q-1])
  5679. column=Int(file[q..])
  5680. file=FullPath(file[..p-1])
  5681. SelectError file,column,line
  5682. EndIf
  5683. Notify LocalizeString("{{output_error_compileerror}}").Replace("%1",mess)
  5684. SetStatus mess
  5685. Return
  5686. EndIf
  5687. ' gcc error
  5688. err=err.Replace(EOL+" "," ")
  5689. While err
  5690. p=err.find(EOL)
  5691. If p=-1 p:+err.length 'equiv. to p=err.length-1 ;-)
  5692. mess=err[..p]
  5693. err=err[p+1..]
  5694. p=0
  5695. Repeat
  5696. p=mess.Find(":",p)+1
  5697. If p=0 Exit
  5698. q=mess.Find(":",p)
  5699. If q<>-1
  5700. file=mess[..p-1]
  5701. line=Int(mess[p..q])
  5702. If line
  5703. mess=mess[q+1..]
  5704. SelectError file,column,line
  5705. Notify LocalizeString("{{output_error_compileerror}}").Replace("%1",mess)
  5706. Return
  5707. EndIf
  5708. p=q+1
  5709. EndIf
  5710. Forever
  5711. Wend
  5712. End Method
  5713. Method AddPanel(tabpanel:TToolPanel)
  5714. Local panel:TGadget,index
  5715. index=CountGadgetItems(tabbar)
  5716. If panels.length<=index panels=panels[..index+1]
  5717. AddGadgetItem(tabbar,tabpanel.name$,GADGETITEM_DEFAULT|GADGETITEM_LOCALIZED)
  5718. panel=CreatePanel(0,0,ClientWidth(tabbar),ClientHeight(tabbar),tabbar,0) 'name
  5719. SetGadgetLayout panel,EDGE_ALIGNED,EDGE_ALIGNED,EDGE_ALIGNED,EDGE_ALIGNED
  5720. tabpanel.panel=panel
  5721. tabpanel.index=index
  5722. panels[index]=tabpanel
  5723. SelectPanel tabpanel
  5724. AddHandler tabpanel
  5725. End Method
  5726. Method AddHandler(handler:TEventHandler)
  5727. eventhandlers.addlast handler
  5728. End Method
  5729. Method RemovePanel(tabpanel:TToolPanel)
  5730. Local p:TToolPanel[]
  5731. Local index
  5732. eventhandlers.remove tabpanel
  5733. ' unset debugcode
  5734. If debugcode=tabpanel debugcode=Null
  5735. ' activate next panel
  5736. If tabpanel=activepanel activepanel=helppanel
  5737. If tabpanel=lockedpanel lockedpanel=Null
  5738. If tabpanel=currentpanel
  5739. index=tabpanel.index+1
  5740. If index>=panels.length index=panels.length-2
  5741. SelectPanel panels[index]
  5742. EndIf
  5743. ' remove from array
  5744. p=panels
  5745. panels=panels[..panels.length-1]
  5746. For index=tabpanel.index To panels.length-1
  5747. panels[index]=p[index+1]
  5748. panels[index].index=index
  5749. Next
  5750. ' remove gadget - simon come here, placing before remove needs fix in fltk
  5751. FreeGadget tabpanel.panel
  5752. RemoveGadgetItem tabbar,tabpanel.index
  5753. tabpanel.panel=Null
  5754. End Method
  5755. Method HookRequester(req:TRequester)
  5756. If Not activerequesters.Contains(req) Then
  5757. If req.IsModal() Then
  5758. For Local tmpRequester:TRequester = EachIn activerequesters
  5759. DisableGadget tmpRequester.window
  5760. Next
  5761. DisableGadget window
  5762. EndIf
  5763. activerequesters.AddFirst(req)
  5764. EndIf
  5765. End Method
  5766. Method UnhookRequester(req:TRequester)
  5767. If activerequesters.Contains(req) Then
  5768. activerequesters.Remove(req)
  5769. If req.IsModal() Then
  5770. For Local tmpRequester:TRequester = EachIn activerequesters
  5771. EnableGadget tmpRequester.window
  5772. Next
  5773. EnableGadget window
  5774. EndIf
  5775. EndIf
  5776. EndMethod
  5777. Method SetTitle(title$="")
  5778. If title title=" - "+title
  5779. SetGadgetText window,"MaxIDE"+title
  5780. End Method
  5781. Method SelectPanel(panel:TToolPanel)
  5782. Local curr:TToolPanel = currentpanel
  5783. currentpanel=panel
  5784. If curr And curr<>currentpanel
  5785. SelectGadgetItem tabbar,panel.index
  5786. ShowGadget panel.panel
  5787. If panel.active activepanel=panel
  5788. HideGadget curr.panel
  5789. RefreshToolbar
  5790. EndIf
  5791. currentpanel.Invoke TOOLSHOW
  5792. End Method
  5793. Method RefreshPanel(panel:TToolPanel) 'call after a name change
  5794. ModifyGadgetItem( tabbar,panel.index,panel.name,GADGETITEM_LOCALIZED )
  5795. End Method
  5796. Function OutsideDesktop(winrect:TRect)
  5797. Local x,y,w,h
  5798. Local desk:TGadget = Desktop()
  5799. x=GadgetX(desk)
  5800. y=GadgetY(desk)
  5801. w=GadgetWidth(desk)
  5802. h=GadgetHeight(desk)
  5803. Return winrect.IsOutside(x,y,w,h)
  5804. End Function
  5805. Method SetCodeNode(code:TNode)
  5806. Local node:TNode
  5807. If coderoot.kids.count() node=TNode(coderoot.kids.First())
  5808. If node=code Return
  5809. If node node.Detach
  5810. If code
  5811. coderoot.Append code
  5812. coderoot.Refresh
  5813. coderoot.Open
  5814. code.Open
  5815. EndIf
  5816. End Method
  5817. Method Initialize()
  5818. Local open:TOpenCode, splash:TGadget
  5819. Local dir$,nomods,pname$,p
  5820. Local stream:TStream
  5821. Try
  5822. bmxpath=BlitzMaxPath()
  5823. Catch err$
  5824. Notify "Unable to determine BlitzMax installation directory."
  5825. End
  5826. EndTry
  5827. CreateDir bmxpath+"/tmp"
  5828. If FileType( bmxpath+"/tmp" )<>FILETYPE_DIR
  5829. Notify "Unable to create BlitzMax 'tmp' directory."
  5830. End
  5831. EndIf
  5832. ?Win32
  5833. CreateFile bmxpath+"/tmp/t.exe"
  5834. If FileType( bmxpath+"/tmp/t.exe" ) <> FILETYPE_FILE
  5835. Notify "Unable to write to BlitzMax installation directory.~n"+..
  5836. "Please run MaxIDE as administrator, or reinstall BlitzMax to a different directory."
  5837. End
  5838. EndIf
  5839. DeleteFile bmxpath+"/tmp/t.exe"
  5840. ?
  5841. bmkpath=bmxpath+"/bin/bmk"
  5842. ?Win32
  5843. bmkpath:+".exe"
  5844. ?
  5845. dir$=bmxpath+"/mod"
  5846. If FileType(dir)=FILETYPE_NONE
  5847. If Not CreateDir(dir)
  5848. Notify "Failed to create %1 directory:~n%2".Replace("%1","Module").Replace("%2",dir)
  5849. End
  5850. EndIf
  5851. nomods=True
  5852. EndIf
  5853. dir$=bmxpath+"/tmp"
  5854. If FileType(dir)=FILETYPE_NONE
  5855. If Not CreateDir(dir)
  5856. Notify "Failed to create %1 directory:~n%2".Replace("%1","Temp").Replace("%2",dir)
  5857. End
  5858. EndIf
  5859. EndIf
  5860. dir$=bmxpath+"/cfg"
  5861. If FileType(dir)=FILETYPE_NONE
  5862. If Not CreateDir(dir)
  5863. Notify "Failed to create %1 directory:~n%2".Replace("%1","Config").Replace("%2",dir)
  5864. End
  5865. EndIf
  5866. EndIf
  5867. CheckVersion()
  5868. splash=CreateWindow("MaxIDE",ScaledSize(200),ScaledSize(200),ScaledSize(400),ScaledSize(160),Null,WINDOW_CLIENTCOORDS|WINDOW_HIDDEN|WINDOW_CENTER)
  5869. Local panel:TGadget = CreatePanel(0,0,ClientWidth(splash),ClientHeight(splash),splash,0)
  5870. SetPanelColor panel,255,255,255;SetPanelPixmap panel, LoadPixmapPNG("incbin::splash.png"), PANELPIXMAP_FIT2
  5871. Local progress:TGadget = CreateProgBar(ScaledSize(2),ClientHeight(panel)-ScaledSize(22),ClientWidth(panel)-ScaledSize(4),ScaledSize(20),panel)
  5872. ShowGadget splash;PollSystem
  5873. window=CreateWindow("MaxIDE",20,20,760,540,Null,WINDOW_TITLEBAR|WINDOW_RESIZABLE|WINDOW_STATUS|WINDOW_HIDDEN|WINDOW_ACCEPTFILES|WINDOW_MENU)
  5874. ?Linux
  5875. SetGadgetPixmap(window, LoadPixmapPNG("incbin::window_icon.png"), GADGETPIXMAP_ICON )
  5876. ?
  5877. cmdlinereq=TCmdLineRequester.Create(Self)
  5878. gotoreq=TGotoRequester.Create(Self)
  5879. findreq=TFindRequester.Create(Self)
  5880. replacereq=TReplaceRequester.Create(Self)
  5881. options=TOptionsRequester.Create(Self)
  5882. ' progress=TProgressRequester.Create(Self)
  5883. projectreq=TProjectRequester.Create(Self)
  5884. projectprops=TProjectProperties.Create(Self)
  5885. searchreq=TSearchRequester.Create(Self)
  5886. aboutreq=TAboutRequester.Create(Self)
  5887. UpdateProgBar progress, 0.1;PollSystem
  5888. ReadConfig()
  5889. Local tbSize:String
  5890. Local scale:Int = GadgetScaleFactor(Desktop())
  5891. If scale = 2 Then
  5892. tbSize = "_48"
  5893. Else If scale > 2 Then
  5894. tbSize = "_64"
  5895. End If
  5896. toolbar=CreateToolBar("incbin::toolbar" + tbSize + ".png",0,0,0,0,window )
  5897. ?win32
  5898. 'create some better looking grayscale icons for disabled icons (original ones have some
  5899. 'blackish outline when using default windows algorithm)
  5900. TWindowsToolbar(toolbar).CreateAndSetDisabledIconStrip(LoadPixmap("incbin::toolbar" + tbSize + ".png"), 0.1, 0.4)
  5901. ?
  5902. Rem
  5903. ?win32
  5904. Local disabledPixmap:TPixmap = LoadPixmap("incbin::toolbar.png")
  5905. For Local x:Int = 0 Until disabledPixmap.width
  5906. For Local y:Int = 0 Until disabledPixmap.height
  5907. Local c:Int = disabledPixmap.ReadPixel(x,y)
  5908. Local a:Int = (c Shr 24) & $ff
  5909. Local r:Int = (c Shr 16) & $ff
  5910. Local g:Int = (c Shr 8) & $ff
  5911. Local b:Int = c & $ff
  5912. 'convert to grayscale
  5913. Local luminance:Float = Sqr(0.299 * r*r + 0.587 * g*g + 0.114 * b*b)
  5914. r = Min(255, Max(0, luminance + (r - luminance) * 0.1))
  5915. g = Min(255, Max(0, luminance + (g - luminance) * 0.1))
  5916. b = Min(255, Max(0, luminance + (b - luminance) * 0.1))
  5917. disabledPixmap.WritePixel(x,y, Int(a*0.4) * $1000000 + r * $10000 + g * $100 + b)
  5918. Next
  5919. Next
  5920. TWindowsToolbar(toolbar).SetDisabledIconstrip( LoadIconStrip(disabledPixmap) )
  5921. ?
  5922. EndRem
  5923. 'you cannot simply remove by "sprite index", so better just
  5924. 'remove the last entry each time
  5925. 'RemoveGadgetItem toolbar, TB_CONTINUE
  5926. 'RemoveGadgetItem toolbar, TB_LOCKCLOSED
  5927. RemoveGadgetItem toolbar, CountGadgetItems(toolbar)-1
  5928. RemoveGadgetItem toolbar, CountGadgetItems(toolbar)-1
  5929. 'Rem
  5930. SetToolBarTips toolbar, ["{{tb_new}}","{{tb_open}}","{{tb_close}}","{{tb_save}}", ..
  5931. "", ..
  5932. "{{tb_cut}}","{{tb_copy}}","{{tb_paste}}","{{tb_find}}", ..
  5933. "", ..
  5934. "{{tb_build}}","{{tb_buildrun}}","{{tb_step}}","{{tb_stepin}}","{{tb_stepout}}","{{tb_stop}}", ..
  5935. "", ..
  5936. "{{tb_home}}","{{tb_back}}","{{tb_forward}}", ..
  5937. "", ..
  5938. "{{tb_lockbuildfile}}", "{{tb_gotobuildfile}}"]
  5939. 'End Rem
  5940. If Not options.showtoolbar Then HideGadget toolbar
  5941. If OutsideDesktop(winsize)
  5942. winsize.set(20,20,760,540)
  5943. EndIf
  5944. UpdateProgBar progress, 0.2;PollSystem
  5945. SetGadgetShape(window, winsize.x, winsize.y, winsize.w, winsize.h)
  5946. client=window
  5947. split=CreateSplitter(0,0,ClientWidth(client),ClientHeight(client),client,SPLIT_VERTICAL)
  5948. SetGadgetLayout(split,EDGE_ALIGNED,EDGE_ALIGNED,EDGE_ALIGNED,EDGE_ALIGNED)
  5949. tabbar=CreateTabber(0,0,ClientWidth(SplitterPanel(split,SPLITPANEL_MAIN)),ClientHeight(SplitterPanel(split,SPLITPANEL_MAIN)),SplitterPanel(split,SPLITPANEL_MAIN))
  5950. SetGadgetLayout(tabbar,EDGE_ALIGNED,EDGE_ALIGNED,EDGE_ALIGNED,EDGE_ALIGNED)
  5951. debugtree=TDebugTree.CreateDebugTree(Self)
  5952. root=TNode.CreateNode("{{navtab_home}}")
  5953. helproot=root.AddNode("{{navnode_help}}")
  5954. projects=TProjects.CreateProjects(Self)
  5955. root.Append projects
  5956. ' opencoderoot=root.AddNode("Open")
  5957. coderoot=TNode.CreateNode("{{navtab_code}}")
  5958. coderoot.Open()
  5959. navbar=TNavBar.Create(Self,SplitterPanel(split,SPLITPANEL_SIDEPANE))
  5960. navbar.AddView root
  5961. navbar.AddView coderoot
  5962. debugview=navbar.AddView(debugtree)
  5963. navbar.SelectView 0
  5964. helproot.Open
  5965. projects.Open
  5966. AddHandler navbar
  5967. SetMode EDITMODE
  5968. UpdateProgBar progress, 0.3;PollSystem
  5969. quickhelp=TQuickHelp.LoadCommandsTxt(bmxpath)
  5970. helppanel=THelpPanel.Create(Self)
  5971. output=TOutputPanel.Create(Self)
  5972. activepanel=helppanel
  5973. InitMenu
  5974. InitHotkeys
  5975. RefreshAll
  5976. UpdateProgBar progress, 0.4;PollSystem 'allow repaint
  5977. Local mkdocs
  5978. If FileType( bmxpath+"/docs/html/User Guide/index.html" )<>FILETYPE_FILE
  5979. CreateDir bmxpath+"/docs/html"
  5980. CreateFile bmxpath+"/docs/html/index.html"
  5981. mkdocs=True
  5982. EndIf
  5983. helppanel.Home()
  5984. UpdateProgBar progress, 0.5;PollSystem
  5985. ' scan projects in projlist
  5986. For Local pdata:TList = EachIn projlist
  5987. projects.AddProject pdata
  5988. Next
  5989. UpdateProgBar progress, 0.6;PollSystem
  5990. Local tmpProgValue# = 0.6
  5991. Local tmpProgStep#
  5992. 'open files from .ini restorelist
  5993. If options.restoreopenfiles
  5994. Local activePanel:TToolPanel
  5995. If Not openlist.IsEmpty() Then tmpProgStep = (0.3/openlist.Count())
  5996. For Local openListLine:String = EachIn openlist
  5997. Local parts:String[] = openListLine.split("|")
  5998. Local fileURI:String = parts[0]
  5999. Local fileActive:Int = 0
  6000. Local fileCursorPos:Int = 0
  6001. If parts.length > 1 Then fileActive = Int(parts[1])
  6002. If parts.length > 2 Then fileCursorPos = Int(parts[2])
  6003. open=OpenSource(fileURI)
  6004. If open
  6005. If fileActive Then activePanel = open
  6006. 'set to stored cursor position
  6007. open.cursorPos = fileCursorPos
  6008. SelectTextAreaText( open.textarea, open.cursorpos, 0, TEXTAREA_CHARS )
  6009. EndIf
  6010. If open And fileURI = openlock
  6011. open.SetLocked(True)
  6012. EndIf
  6013. tmpProgValue :+ tmpProgStep
  6014. UpdateProgBar progress,tmpProgValue
  6015. Next
  6016. If activePanel Then SelectPanel( activePanel )
  6017. EndIf
  6018. tmpProgValue = 0.9
  6019. If AppArgs.length > 1 Then tmpProgStep = (0.1/(AppArgs.length-1)) Else tmpProgValue = 1.0
  6020. UpdateProgBar progress,tmpProgValue;PollSystem
  6021. ' open files specified in command line
  6022. For Local i:Int = 1 Until AppArgs.length
  6023. open=OpenSource(AppArgs[i])
  6024. tmpProgValue:+tmpProgStep;UpdateProgBar progress,tmpProgValue;PollSystem
  6025. Next
  6026. If options.restartaftershutdown Then
  6027. UpdateRestartState()
  6028. End If
  6029. HideGadget splash;FreeGadget splash
  6030. PollSystem
  6031. SetSplitterPosition(split,splitpos);SetSplitterOrientation(split,splitorientation)
  6032. If winmax MaximizeWindow(window)
  6033. ShowGadget window
  6034. PollSystem
  6035. running=True
  6036. CreateTimer(TIMER_FREQUENCY)
  6037. 'build docs if not there
  6038. If mkdocs
  6039. If Confirm( LocalizeString("{{loaderror_docsnotfound}}") ) And CloseAll( False ) DocMods
  6040. EndIf
  6041. End Method
  6042. Method DocMods()
  6043. Local cmd$=quote(bmxpath+"/bin/makedocs")
  6044. execute cmd,LocalizeString("{{output_msg_rebuildingdocs}}"),MENUTRIGGERSYNCDOCS
  6045. ?MacOS
  6046. RanLibMods()
  6047. ?
  6048. End Method
  6049. Method SyncDocs()
  6050. helppanel.SyncDocs()
  6051. quickhelp=TQuickHelp.LoadCommandsTxt(bmxpath)
  6052. helppanel.Home
  6053. End Method
  6054. Method InitMenu()
  6055. Local menu:TGadget,file:TGadget,edit:TGadget,program:TGadget,tools:TGadget
  6056. Local help:TGadget,buildoptions:TGadget,devoptions:TGadget
  6057. Local buildmods:TGadget,buildallmods:TGadget,docmods:TGadget
  6058. Local platform:TGadget,architecture:TGadget
  6059. Local appoptions:TGadget
  6060. Local MENUMOD=MODIFIER_COMMAND
  6061. If options.systemkeys
  6062. MENUMOD=MODIFIER_CONTROL
  6063. EndIf
  6064. menu=WindowMenu(window)
  6065. file=CreateMenu("{{menu_file}}",0,menu)
  6066. CreateMenu "{{menu_file_new}}",MENUNEW,file,KEY_N,MENUMOD
  6067. CreateMenu "{{menu_file_open}}",MENUOPEN,file,KEY_O,MENUMOD
  6068. recentmenu=CreateMenu("{{menu_file_open_recent}}",0,file)
  6069. CreateMenu "",0,file
  6070. CreateMenu "{{menu_file_closetab}}",MENUCLOSE,file,KEY_W,MENUMOD
  6071. CreateMenu "{{menu_file_closealltabs}}",MENUCLOSEALL,file,KEY_W,MENUMOD|MODIFIER_SHIFT
  6072. CreateMenu "{{menu_file_closeothertabs}}",MENUCLOSEOTHERS,file,KEY_W,MENUMOD|MODIFIER_ALT
  6073. CreateMenu "",0,file
  6074. CreateMenu "{{menu_file_save}}",MENUSAVE,file,KEY_S,MENUMOD
  6075. CreateMenu "{{menu_file_saveas}}",MENUSAVEAS,file,KEY_S,MENUMOD|MODIFIER_SHIFT
  6076. CreateMenu "{{menu_file_saveall}}",MENUSAVEALL,file
  6077. CreateMenu "",0,file
  6078. If options.systemkeys
  6079. ?MacOS
  6080. CreateMenu "{{menu_file_nexttab}}",MENUNEXT,file,KEY_RIGHT,MENUMOD
  6081. CreateMenu "{{menu_file_prevtab}}",MENUPREV,file,KEY_LEFT,MENUMOD
  6082. ?Not MacOS
  6083. CreateMenu "{{menu_file_nexttab}}",MENUNEXT,file,KEY_RIGHT,MODIFIER_ALT
  6084. CreateMenu "{{menu_file_prevtab}}",MENUPREV,file,KEY_LEFT,MODIFIER_ALT
  6085. ?
  6086. Else
  6087. CreateMenu "{{menu_file_nexttab}}",MENUNEXT,file,KEY_RIGHT,MENUMOD
  6088. CreateMenu "{{menu_file_prevtab}}",MENUPREV,file,KEY_LEFT,MENUMOD
  6089. EndIf
  6090. CreateMenu "",0,file
  6091. CreateMenu "{{menu_file_importbb}}",MENUIMPORTBB,file
  6092. CreateMenu "",0,file
  6093. CreateMenu "{{menu_file_ideoptions}}",MENUOPTIONS,file
  6094. CreateMenu "{{menu_file_projectmanager}}",MENUPROJECTMANAGER,file
  6095. CreateMenu "",0,file
  6096. CreateMenu "{{menu_file_print}}",MENUPRINT,file,KEY_P,MENUMOD
  6097. ?Not MacOS
  6098. CreateMenu "",0,file
  6099. CreateMenu "{{menu_file_exit}}",MENUQUIT,file
  6100. ?
  6101. edit=CreateMenu("{{menu_edit}}",0,menu)
  6102. CreateMenu "{{menu_edit_undo}}",MENUUNDO,edit,KEY_Z,MENUMOD
  6103. ?MacOS
  6104. CreateMenu "{{menu_edit_redo}}",MENUREDO,edit,KEY_Z,MENUMOD|MODIFIER_SHIFT
  6105. ?Not MacOS
  6106. CreateMenu "{{menu_edit_redo}}",MENUREDO,edit,KEY_Y,MENUMOD
  6107. ?
  6108. CreateMenu "",0,edit
  6109. CreateMenu "{{menu_edit_cut}}",MENUCUT,edit,KEY_X,MENUMOD
  6110. CreateMenu "{{menu_edit_copy}}",MENUCOPY,edit,KEY_C,MENUMOD
  6111. CreateMenu "{{menu_edit_paste}}",MENUPASTE,edit,KEY_V,MENUMOD
  6112. CreateMenu "",0,edit
  6113. CreateMenu "{{menu_edit_selectall}}",MENUSELECTALL,edit,KEY_A,MENUMOD
  6114. CreateMenu "",0,edit
  6115. CreateMenu "{{menu_edit_blockindent}}",MENUINDENT,edit,KEY_CLOSEBRACKET,MENUMOD
  6116. CreateMenu "{{menu_edit_blockoutdent}}",MENUOUTDENT,edit,KEY_OPENBRACKET,MENUMOD
  6117. CreateMenu "",0,edit
  6118. CreateMenu "{{menu_edit_find}}",MENUFIND,edit,KEY_F,MENUMOD
  6119. ?MacOS
  6120. CreateMenu "{{menu_edit_findnext}}",MENUFINDNEXT,edit,KEY_G,MENUMOD
  6121. CreateMenu "{{menu_edit_replace}}",MENUREPLACE,edit,KEY_H,MENUMOD
  6122. CreateMenu "{{menu_edit_gotoline}}",MENUGOTO,edit,KEY_L,MENUMOD
  6123. ?Not MacOS
  6124. CreateMenu "{{menu_edit_findnext}}",MENUFINDNEXT,edit,KEY_F3
  6125. CreateMenu "{{menu_edit_replace}}",MENUREPLACE,edit,KEY_H,MENUMOD
  6126. CreateMenu "{{menu_edit_gotoline}}",MENUGOTO,edit,KEY_G,MENUMOD
  6127. ?
  6128. CreateMenu "",0,edit
  6129. CreateMenu "{{menu_edit_findinfiles}}",MENUFINDINFILES,edit,KEY_F,MENUMOD|MODIFIER_SHIFT
  6130. program=CreateMenu("{{menu_program}}",0,menu)
  6131. CreateMenu "{{menu_program_build}}",MENUBUILD,program,KEY_B,MENUMOD
  6132. CreateMenu "{{menu_program_buildandrun}}",MENURUN,program,KEY_R,MENUMOD
  6133. CreateMenu "{{menu_program_commandline}}",MENUCOMMANDLINE,program
  6134. CreateMenu "",0,program
  6135. CreateMenu "{{menu_program_step}}",MENUSTEP,program,KEY_F9
  6136. CreateMenu "{{menu_program_stepin}}",MENUSTEPIN,program,KEY_F10
  6137. CreateMenu "{{menu_program_stepout}}",MENUSTEPOUT,program,KEY_F11
  6138. CreateMenu "{{menu_program_terminate}}",MENUSTOP,program
  6139. CreateMenu "",0,program
  6140. buildoptions=CreateMenu("{{menu_program_buildoptions}}",0,program)
  6141. quickenable=CreateMenu("{{menu_program_buildoptions_quick}}",MENUQUICKENABLED,buildoptions)
  6142. debugenable=CreateMenu("{{menu_program_buildoptions_debug}}",MENUDEBUGENABLED,buildoptions)
  6143. 'If (FileType( BlitzMaxPath()+"/mod/brl.mod/blitz.mod/blitz_gc_ms.c" )=FILETYPE_FILE) ..
  6144. ' Or (FileType( BlitzMaxpath()+"/mod/brl.mod/blitz.mod/bdwgc" )=FILETYPE_DIR)
  6145. ' threadedenable=CreateMenu("{{menu_program_buildoptions_threaded}}",MENUTHREADEDENABLED,buildoptions)
  6146. 'EndIf
  6147. appoptions=CreateMenu("{{menu_program_appoptions}}",0,program)
  6148. consoleenable=CreateMenu("{{menu_program_buildoptions_consoleapp}}",MENUCONSOLEENABLED,appoptions)
  6149. guienable=CreateMenu("{{menu_program_buildoptions_guiapp}}",MENUGUIENABLED,appoptions)
  6150. makelibenable=CreateMenu("{{menu_program_buildoptions_makelib}}",MENUMAKELIBENABLED,appoptions)
  6151. quickscanenable=CreateMenu("{{menu_program_buildoptions_quickscan}}",MENUQUICKSCANENABLED,buildoptions)
  6152. ?macos
  6153. universalenable=CreateMenu("{{menu_program_buildoptions_universal}}",MENUUNIVERSALENABLED,buildoptions)
  6154. ?
  6155. warnoverenable=CreateMenu("{{menu_program_buildoptions_warnover}}",MENUWARNOVERENABLED,buildoptions)
  6156. requireOverrideEnable=CreateMenu("{{menu_program_buildoptions_requireoverride}}",MENUREQUIREOVERRIDEENABLED,buildoptions)
  6157. overrideErrorsEnable=CreateMenu("{{menu_program_buildoptions_overrideerrors}}",MENUOVERRIDEERRORSENABLED,buildoptions)
  6158. platform=CreateMenu("{{menu_program_platform}}",0,program)
  6159. ?Not raspberrypi
  6160. win32enable=CreateMenu("{{menu_program_platform_win32}}",MENUWIN32ENABLED,platform)
  6161. ?linux
  6162. linuxenable=CreateMenu("{{menu_program_platform_linux}}",MENULINUXENABLED,platform)
  6163. ?
  6164. ?macos
  6165. macosxenable=CreateMenu("{{menu_program_platform_macosx}}",MENUMACOSXENABLED,platform)
  6166. iosenable=CreateMenu("{{menu_program_platform_ios}}",MENUIOSENABLED,platform)
  6167. ?
  6168. raspberrypienable=CreateMenu("{{menu_program_platform_raspberrypi}}",MENURASPBERRYPIENABLED,platform)
  6169. ?Not raspberrypi
  6170. androidenable=CreateMenu("{{menu_program_platform_android}}",MENUANDROIDENABLED,platform)
  6171. ?
  6172. nxenable=CreateMenu("{{menu_program_platform_nx}}",MENUNXENABLED,platform)
  6173. emscriptenenable=CreateMenu("{{menu_program_platform_emscripten}}",MENUEMSCRIPTENENABLED,platform)
  6174. 'ARCHITECTURE MENU
  6175. architecture=CreateMenu("{{menu_program_arch}}",0,program)
  6176. x86enable=CreateMenu("{{menu_program_arch_x86}}",MENUX86ENABLED,architecture)
  6177. x64enable=CreateMenu("{{menu_program_arch_x64}}",MENUX64ENABLED,architecture)
  6178. ppcenable=CreateMenu("{{menu_program_arch_ppc}}",MENUPPCENABLED,architecture)
  6179. armenable=CreateMenu("{{menu_program_arch_arm}}",MENUARMENABLED,architecture)
  6180. armeabiv5enable=CreateMenu("{{menu_program_arch_armeabiv5}}",MENUARMEABIV5ENABLED,architecture)
  6181. armeabiv7aenable=CreateMenu("{{menu_program_arch_armeabiv7a}}",MENUARMEABIV7AENABLED,architecture)
  6182. arm64v8aenable=CreateMenu("{{menu_program_arch_arm64v8a}}",MENUARM64V8AENABLED,architecture)
  6183. jsenable=CreateMenu("{{menu_program_arch_js}}",MENUJSENABLED,architecture)
  6184. armv7enable=CreateMenu("{{menu_program_arch_armv7}}",MENUARMV7ENABLED,architecture)
  6185. arm64enable=CreateMenu("{{menu_program_arch_arm64}}",MENUARM64ENABLED,architecture)
  6186. 'MISC OPTIONS MENU
  6187. miscoptionsmenu = CreateMenu("{{menu_program_miscoptions}}",0,program)
  6188. upxEnable = CreateMenu("{{menu_program_miscoptions_upx}}",MENUUPXENABLED,miscoptionsmenu)
  6189. 'APP STUB MENU
  6190. appstubmenu=CreateMenu("{{menu_program_appstub}}",0,program)
  6191. 'DEVELOPER MENU
  6192. devoptions=CreateMenu("{{menu_program_buildoptions_dev}}",0,program)
  6193. verboseenable=CreateMenu("{{menu_program_buildoptions_verbose}}",MENUVERBOSEENABLED,devoptions)
  6194. gdbdebugenable=CreateMenu("{{menu_program_buildoptions_gdbdebug}}",MENUGDBDEBUGENABLED,devoptions)
  6195. CreateMenu "",0,program
  6196. lockBuildMenuItem = CreateMenu("{{menu_program_lockbuildfile}}",MENULOCKBUILD,program)
  6197. unlockBuildMenuItem=CreateMenu("{{menu_program_unlockbuildfile}}",MENUUNLOCKBUILD,program)
  6198. gotoBuildMenuItem=CreateMenu("{{menu_program_gotobuildfile}}",MENUGOTOBUILD,program)
  6199. CreateMenu "",0,program
  6200. buildmods=CreateMenu("{{menu_program_buildmods}}",MENUBUILDMODULES,program,KEY_D,MENUMOD)
  6201. buildallmods=CreateMenu("{{menu_program_rebuildallmods}}",MENUBUILDALLMODULES,program)
  6202. docmods=CreateMenu("{{menu_program_rebuilddocs}}",MENUDOCMODS,program)
  6203. help=CreateMenu("{{menu_help}}",0,menu)
  6204. CreateMenu "{{menu_help_home}}",MENUHOME,help
  6205. CreateMenu "{{menu_help_back}}",MENUBACK,help
  6206. CreateMenu "{{menu_help_forward}}",MENUFORWARD,help
  6207. CreateMenu "{{menu_help_quickhelp}}",MENUQUICKHELP,help,KEY_F1
  6208. CreateMenu "{{menu_help_aboutmaxide}}",MENUABOUT,help
  6209. If quickenabled CheckMenu quickenable
  6210. If debugenabled CheckMenu debugenable
  6211. If threadedenabled CheckMenu threadedenable
  6212. If consoleenabled CheckMenu consoleenable
  6213. If guienabled CheckMenu guienable
  6214. If makelibenabled CheckMenu makelibenable
  6215. If upxEnabled CheckMenu upxEnable
  6216. 'disable for sharedlibs
  6217. If makelibenabled DisableMenu upxEnable
  6218. If verboseenabled CheckMenu verboseenable
  6219. If quickscanenabled CheckMenu quickscanenable
  6220. If universalenabled CheckMenu universalenable
  6221. If warnoverenabled CheckMenu warnoverenable
  6222. If gdbdebugenabled CheckMenu gdbdebugenable
  6223. If requireOverrideEnabled CheckMenu requireOverrideEnable
  6224. If overrideErrorsEnabled CheckMenu overrideErrorsEnable
  6225. 'need to do this below "CheckMenu" as it automatically enables
  6226. 'the menu (again)
  6227. If Not requireOverrideEnabled DisableMenu overrideErrorsEnable
  6228. If Not lockedPanel
  6229. DisableMenu unlockBuildMenuItem
  6230. DisableMenu gotoBuildMenuItem
  6231. EndIf
  6232. Local defaultArch:Int = -1
  6233. For Local i:Int = 0 Until architectureenabled.length
  6234. If architectureenabled[i] Then
  6235. defaultArch = i
  6236. Exit
  6237. End If
  6238. Next
  6239. For Local i:Int = 0 Until platformenabled.length
  6240. If platformenabled[i] Then
  6241. UpdatePlatformMenus(i + PLATFORMOFFSET)
  6242. If defaultArch < 0 Then
  6243. DefaultArchitectureMenuForPlatform(i + PLATFORMOFFSET)
  6244. Else
  6245. UpdateArchitectureMenus(defaultArch + ARCHITECTUREOFFSET)
  6246. End If
  6247. Exit
  6248. End If
  6249. Next
  6250. 'UpdateArchitectureMenus()
  6251. ?Win32
  6252. Local mingw:String = MinGWPath()
  6253. If Not mingw
  6254. DisableMenu buildmods
  6255. DisableMenu buildallmods
  6256. EndIf
  6257. ?
  6258. RefreshRecentFiles
  6259. RefreshAppStubs
  6260. UpdateWindowMenu window
  6261. End Method
  6262. Method RunCode()
  6263. If Mode=DEBUGMODE And debugtree.cancontinue
  6264. output.Go()
  6265. Return
  6266. EndIf
  6267. output.Stop()
  6268. SaveAll()
  6269. If lockedpanel
  6270. lockedpanel.invoke TOOLRUN
  6271. Else
  6272. activepanel.invoke TOOLRUN
  6273. EndIf
  6274. End Method
  6275. Method BuildCode()
  6276. output.Stop()
  6277. SaveAll()
  6278. If lockedpanel
  6279. lockedpanel.invoke TOOLBUILD
  6280. Else
  6281. activepanel.invoke TOOLBUILD
  6282. EndIf
  6283. End Method
  6284. Method AddEventHotKey(key,mods,id,data)
  6285. SetHotKeyEvent key,mods,CreateEvent(id,Null,data)
  6286. End Method
  6287. Method InitHotkeys()
  6288. AddEventHotKey KEY_F5,MODIFIER_NONE,EVENT_MENUACTION,MENURUN
  6289. AddEventHotKey KEY_F7,MODIFIER_NONE,EVENT_MENUACTION,MENUBUILD
  6290. End Method
  6291. Method SaveAll()
  6292. For Local panel:TToolPanel = EachIn panels
  6293. panel.invoke TOOLQUICKSAVE
  6294. Next
  6295. End Method
  6296. Method Restart()
  6297. If Confirm(LocalizeString("{{request_restart}}"))
  6298. Quit
  6299. EndIf
  6300. End Method
  6301. Method RefreshAll()
  6302. ' hide/show toolbar
  6303. If options.showtoolbar Then ShowGadget toolbar Else HideGadget toolbar
  6304. ' refresh panels
  6305. For Local panel:TToolPanel = EachIn panels
  6306. panel.invoke TOOLREFRESH
  6307. Next
  6308. ' refresh navbar
  6309. navbar.invoke TOOLREFRESH
  6310. ' refresh appstub menus
  6311. RefreshAppStubs
  6312. End Method
  6313. Method SnapshotWindow()
  6314. If WindowMaximized(window)
  6315. winmax=True
  6316. Else
  6317. If Not WindowMinimized(window)
  6318. winmax=False
  6319. winsize.x=GadgetX(window)
  6320. winsize.y=GadgetY(window)
  6321. winsize.w=GadgetWidth(window)
  6322. winsize.h=GadgetHeight(window)
  6323. EndIf
  6324. EndIf
  6325. options.showtoolbar = Not GadgetHidden(toolbar)
  6326. End Method
  6327. Method OnMenu(menu,extra:Object=Null)
  6328. Local index
  6329. Local tool:TTool = TTool(extra)
  6330. If tool
  6331. tool.invoke(TOOLMENU,""+menu)
  6332. Return
  6333. EndIf
  6334. Select menu
  6335. Case MENUNEW
  6336. OpenSource ""
  6337. Case MENUOPEN
  6338. OpenSource "."
  6339. Case MENUCLOSE
  6340. currentpanel.invoke TOOLCLOSE
  6341. Case MENUCLOSEALL
  6342. CloseAll True
  6343. Case MENUCLOSEOTHERS
  6344. CloseAll True, False
  6345. Case MENUSAVE
  6346. currentpanel.invoke TOOLSAVE
  6347. Case MENUSAVEAS
  6348. currentpanel.invoke TOOLSAVEAS
  6349. Case MENUSAVEALL
  6350. SaveAll()
  6351. Case MENUPRINT
  6352. currentpanel.invoke TOOLPRINT
  6353. Case MENUQUIT
  6354. Quit()
  6355. Case MENUGOTO
  6356. gotoreq.Show()
  6357. Case MENUFIND
  6358. currentpanel.invoke TOOLFIND
  6359. Case MENUFINDNEXT
  6360. currentpanel.invoke TOOLFINDNEXT
  6361. Case MENUREPLACE
  6362. replacereq.Show()
  6363. Case MENUUNDO currentpanel.invoke TOOLUNDO
  6364. Case MENUREDO currentpanel.invoke TOOLREDO
  6365. Case MENUCUT currentpanel.invoke TOOLCUT
  6366. Case MENUCOPY currentpanel.invoke TOOLCOPY
  6367. Case MENUPASTE currentpanel.invoke TOOLPASTE
  6368. Case MENUSELECTALL currentpanel.invoke TOOLSELECTALL
  6369. Case MENUBUILD
  6370. BuildCode()
  6371. Case MENURUN
  6372. RunCode()
  6373. Case MENUBUILDMODULES
  6374. BuildModules False
  6375. Case MENUBUILDALLMODULES
  6376. BuildModules True
  6377. Case MENUDOCMODS
  6378. If CloseAll(False) DocMods
  6379. Case MENUTRIGGERDOCMODS
  6380. DocMods()
  6381. Case MENUTRIGGERSYNCDOCS
  6382. SyncDocs()
  6383. Case MENUSTEP If output output.StepOver()
  6384. Case MENUSTEPIN If output output.StepIn()
  6385. Case MENUSTEPOUT If output output.StepOut()
  6386. Case MENUSTOP If output output.Stop()
  6387. Case MENULOCKBUILD
  6388. activepanel.invoke TOOLLOCK
  6389. Case MENUUNLOCKBUILD
  6390. If lockedpanel lockedpanel.invoke TOOLUNLOCK
  6391. Case MENUGOTOBUILD
  6392. If lockedpanel
  6393. SelectPanel(lockedPanel)
  6394. EndIf
  6395. Case MENUCOMMANDLINE cmdlinereq.Show
  6396. Case MENUQUICKENABLED
  6397. If quickenabled
  6398. quickenabled=False
  6399. UncheckMenu quickenable
  6400. Else
  6401. quickenabled=True
  6402. CheckMenu quickenable
  6403. EndIf
  6404. UpdateWindowMenu window
  6405. Case MENUDEBUGENABLED
  6406. If debugenabled
  6407. debugenabled=False
  6408. UncheckMenu debugenable
  6409. Else
  6410. debugenabled=True
  6411. CheckMenu debugenable
  6412. EndIf
  6413. UpdateWindowMenu window
  6414. Case MENUTHREADEDENABLED
  6415. If threadedenabled
  6416. threadedenabled=False
  6417. UncheckMenu threadedenable
  6418. Else
  6419. threadedenabled=True
  6420. CheckMenu threadedenable
  6421. EndIf
  6422. UpdateWindowMenu window
  6423. Case MENUGUIENABLED
  6424. If Not guienabled
  6425. guienabled=True
  6426. CheckMenu guienable
  6427. consoleenabled=False
  6428. UncheckMenu consoleenable
  6429. makelibenabled=False
  6430. UncheckMenu makelibenable
  6431. 'only enable if the UPX binary is present
  6432. If CanRunUPX() Then EnableMenu(upxEnable)
  6433. EndIf
  6434. UpdateWindowMenu window
  6435. Case MENUCONSOLEENABLED
  6436. If Not consoleenabled
  6437. consoleenabled=True
  6438. CheckMenu consoleenable
  6439. guienabled=False
  6440. UncheckMenu guienable
  6441. makelibenabled=False
  6442. UncheckMenu makelibenable
  6443. 'only enable if the UPX binary is present
  6444. If CanRunUPX() Then EnableMenu(upxEnable)
  6445. EndIf
  6446. UpdateWindowMenu window
  6447. Case MENUMAKELIBENABLED
  6448. If Not makelibenabled
  6449. makelibenabled=True
  6450. CheckMenu makelibenable
  6451. consoleenabled=False
  6452. UncheckMenu consoleenable
  6453. guienabled=False
  6454. UncheckMenu guienable
  6455. 'upx is only available for "makeapp" (console/GUI)
  6456. 'do not set the flag to false to avoid having
  6457. 'to reconfigure it after switching to console/GUI
  6458. 'upxEnabled=False
  6459. DisableMenu upxEnable
  6460. EndIf
  6461. UpdateWindowMenu window
  6462. Case MENUVERBOSEENABLED
  6463. If verboseenabled
  6464. verboseenabled=False
  6465. UncheckMenu verboseenable
  6466. Else
  6467. verboseenabled=True
  6468. CheckMenu verboseenable
  6469. EndIf
  6470. UpdateWindowMenu window
  6471. Case MENUQUICKSCANENABLED
  6472. If quickscanenabled
  6473. quickscanenabled=False
  6474. UncheckMenu quickscanenable
  6475. Else
  6476. quickscanenabled=True
  6477. CheckMenu quickscanenable
  6478. EndIf
  6479. UpdateWindowMenu window
  6480. Case MENUUNIVERSALENABLED
  6481. If universalenabled
  6482. universalenabled=False
  6483. UncheckMenu universalenable
  6484. Else
  6485. universalenabled=True
  6486. CheckMenu universalenable
  6487. EndIf
  6488. UpdateWindowMenu window
  6489. Case MENUWARNOVERENABLED
  6490. If warnoverenabled
  6491. warnoverenabled=False
  6492. UncheckMenu warnoverenable
  6493. Else
  6494. warnoverenabled=True
  6495. CheckMenu warnoverenable
  6496. EndIf
  6497. UpdateWindowMenu window
  6498. Case MENUREQUIREOVERRIDEENABLED
  6499. If requireOverrideEnabled
  6500. requireOverrideEnabled=False
  6501. UncheckMenu requireOverrideEnable
  6502. 'disable menu entry as it requires "require override"
  6503. 'this keeps "checked" information intact in case of
  6504. 'a settings reactivation
  6505. If overrideErrorsEnable Then DisableMenu overrideErrorsEnable
  6506. Else
  6507. requireOverrideEnabled=True
  6508. CheckMenu requireOverrideEnable
  6509. If overrideErrorsEnable Then EnableMenu overrideErrorsEnable
  6510. EndIf
  6511. UpdateWindowMenu window
  6512. Case MENUOVERRIDEERRORSENABLED
  6513. If overrideErrorsEnabled
  6514. overrideErrorsEnabled=False
  6515. UncheckMenu overrideErrorsEnable
  6516. Else
  6517. overrideErrorsEnabled=True
  6518. CheckMenu overrideErrorsEnable
  6519. EndIf
  6520. UpdateWindowMenu window
  6521. Case MENUGDBDEBUGENABLED
  6522. If gdbdebugenabled
  6523. gdbdebugenabled=False
  6524. UncheckMenu gdbdebugenable
  6525. Else
  6526. gdbdebugenabled=True
  6527. CheckMenu gdbdebugenable
  6528. EndIf
  6529. UpdateWindowMenu window
  6530. Case MENUWIN32ENABLED, MENULINUXENABLED, MENUMACOSXENABLED, MENURASPBERRYPIENABLED, ..
  6531. MENUANDROIDENABLED, MENUEMSCRIPTENENABLED, MENUIOSENABLED, MENUNXENABLED
  6532. UpdatePlatformMenus(menu)
  6533. UpdateWindowMenu window
  6534. Case MENUX86ENABLED, MENUX64ENABLED, MENUPPCENABLED, MENUARMENABLED, ..
  6535. MENUARMEABIV5ENABLED, MENUARMEABIV7AENABLED, MENUARM64V8AENABLED, ..
  6536. MENUJSENABLED, MENUARMV7ENABLED, MENUARM64ENABLED
  6537. UpdateArchitectureMenus(menu)
  6538. UpdateWindowMenu window
  6539. Case MENUUPXENABLED
  6540. If upxEnabled
  6541. upxEnabled = False
  6542. UncheckMenu(upxEnable)
  6543. Else
  6544. upxEnabled = True
  6545. CheckMenu(upxEnable)
  6546. EndIf
  6547. UpdateWindowMenu window
  6548. Case MENUIMPORTBB
  6549. ImportBB
  6550. Case MENUFINDINFILES
  6551. If activepanel Then searchreq.ShowWithPath( ExtractDir(activepanel.path) ) Else searchreq.Show()
  6552. Case MENUPROJECTMANAGER
  6553. projectreq.Open projects
  6554. Case MENUSHOWCONSOLE
  6555. If output Then output.Open()
  6556. Case MENUOPTIONS
  6557. options.Show()
  6558. Case MENUNEXT
  6559. If Not currentpanel Return
  6560. index=currentpanel.index+1
  6561. If index=panels.length index=0
  6562. SelectPanel panels[index]
  6563. Case MENUPREV
  6564. If Not currentpanel Return
  6565. index=currentpanel.index-1
  6566. If index<0 index=panels.length-1
  6567. SelectPanel panels[index]
  6568. Case MENUQUICKHELP
  6569. currentpanel.invoke TOOLHELP
  6570. Case MENUHOME
  6571. helppanel.Home()
  6572. SelectPanel helppanel
  6573. Case MENUBACK
  6574. helppanel.Back()
  6575. SelectPanel helppanel
  6576. Case MENUFORWARD
  6577. helppanel.Forward()
  6578. SelectPanel helppanel
  6579. Case MENUABOUT
  6580. aboutreq.Show()
  6581. 'Notify (ABOUT.Replace( "{bcc_version}",BCC_VERSION ))
  6582. Case MENUINDENT
  6583. currentpanel.invoke TOOLINDENT
  6584. Case MENUOUTDENT
  6585. currentpanel.invoke TOOLOUTDENT
  6586. Case MENUNEWVIEW
  6587. navbar.invoke TOOLNEWVIEW
  6588. End Select
  6589. If menu>=MENURECENT
  6590. Local f:String = String(recentfiles.ValueAtIndex(menu-MENURECENT))
  6591. If f$ OpenSource f$
  6592. Else If menu >= APPSTUBOFFSET
  6593. Local index:Int = menu - APPSTUBOFFSET
  6594. If index < options.appstubs.length Then
  6595. selectedappstub = options.appstubs[index]
  6596. RefreshAppStubs
  6597. End If
  6598. EndIf
  6599. End Method
  6600. Method UpdatePlatformMenus(menu:Int)
  6601. Local index:Int = menu - PLATFORMOFFSET
  6602. Local platformChanged:Int = Not platformenabled[index]
  6603. For Local i:Int = 0 Until platformenabled.Length
  6604. If platformenabled[i] And i <> index Then
  6605. Select PLATFORMOFFSET + i
  6606. Case MENUWIN32ENABLED
  6607. UncheckMenu win32enable
  6608. Case MENULINUXENABLED
  6609. UncheckMenu linuxenable
  6610. Case MENUMACOSXENABLED
  6611. UncheckMenu macosxenable
  6612. Case MENUIOSENABLED
  6613. UncheckMenu iosenable
  6614. Case MENURASPBERRYPIENABLED
  6615. UncheckMenu raspberrypienable
  6616. Case MENUANDROIDENABLED
  6617. UncheckMenu androidenable
  6618. Case MENUEMSCRIPTENENABLED
  6619. UncheckMenu emscriptenenable
  6620. Case MENUNXENABLED
  6621. UncheckMenu nxenable
  6622. End Select
  6623. End If
  6624. platformenabled[i] = False
  6625. Next
  6626. platformenabled[index] = True
  6627. Select menu
  6628. Case MENUWIN32ENABLED
  6629. CheckMenu win32enable
  6630. Case MENULINUXENABLED
  6631. CheckMenu linuxenable
  6632. Case MENUMACOSXENABLED
  6633. CheckMenu macosxenable
  6634. Case MENUIOSENABLED
  6635. CheckMenu iosenable
  6636. Case MENURASPBERRYPIENABLED
  6637. CheckMenu raspberrypienable
  6638. Case MENUANDROIDENABLED
  6639. CheckMenu androidenable
  6640. Case MENUEMSCRIPTENENABLED
  6641. CheckMenu emscriptenenable
  6642. Case MENUNXENABLED
  6643. CheckMenu nxenable
  6644. End Select
  6645. UpdateArchitectureMenuState menu
  6646. If platformChanged Then
  6647. DefaultArchitectureMenuForPlatform(menu)
  6648. End If
  6649. End Method
  6650. Method UpdateArchitectureMenus(menu:Int)
  6651. Local index:Int = menu - ARCHITECTUREOFFSET
  6652. For Local i:Int = 0 Until architectureenabled.Length
  6653. If architectureenabled[i] And i <> index Then
  6654. Select ARCHITECTUREOFFSET + i
  6655. Case MENUX86ENABLED
  6656. UncheckMenu x86enable
  6657. Case MENUX64ENABLED
  6658. UncheckMenu x64enable
  6659. Case MENUPPCENABLED
  6660. UncheckMenu ppcenable
  6661. Case MENUARMENABLED
  6662. UncheckMenu armenable
  6663. Case MENUARMEABIV5ENABLED
  6664. UncheckMenu armeabiv5enable
  6665. Case MENUARMEABIV7AENABLED
  6666. UncheckMenu armeabiv7aenable
  6667. Case MENUARM64V8AENABLED
  6668. UncheckMenu arm64v8aenable
  6669. Case MENUJSENABLED
  6670. UncheckMenu jsenable
  6671. Case MENUARMV7ENABLED
  6672. UncheckMenu armv7enable
  6673. Case MENUARM64ENABLED
  6674. UncheckMenu arm64enable
  6675. End Select
  6676. End If
  6677. architectureenabled[i] = False
  6678. Next
  6679. architectureenabled[index] = True
  6680. Select menu
  6681. Case MENUX86ENABLED
  6682. CheckMenu x86enable
  6683. Case MENUX64ENABLED
  6684. CheckMenu x64enable
  6685. Case MENUPPCENABLED
  6686. CheckMenu ppcenable
  6687. Case MENUARMENABLED
  6688. CheckMenu armenable
  6689. Case MENUARMEABIV5ENABLED
  6690. CheckMenu armeabiv5enable
  6691. Case MENUARMEABIV7AENABLED
  6692. CheckMenu armeabiv7aenable
  6693. Case MENUARM64V8AENABLED
  6694. CheckMenu arm64v8aenable
  6695. Case MENUJSENABLED
  6696. CheckMenu jsenable
  6697. Case MENUARMV7ENABLED
  6698. CheckMenu armv7enable
  6699. Case MENUARM64ENABLED
  6700. CheckMenu arm64enable
  6701. End Select
  6702. End Method
  6703. Method UpdateArchitectureMenuState(platformMenu:Int)
  6704. DisableMenu x86enable
  6705. DisableMenu x64enable
  6706. DisableMenu ppcenable
  6707. DisableMenu armenable
  6708. DisableMenu armeabiv5enable
  6709. DisableMenu armeabiv7aenable
  6710. DisableMenu arm64v8aenable
  6711. DisableMenu jsenable
  6712. DisableMenu armv7enable
  6713. DisableMenu arm64enable
  6714. DisableMenu makelibenable
  6715. Select platformMenu
  6716. Case MENUWIN32ENABLED, MENULINUXENABLED
  6717. EnableMenu x86enable
  6718. EnableMenu x64enable
  6719. Case MENUMACOSXENABLED
  6720. ?Not ppc
  6721. EnableMenu x86enable
  6722. EnableMenu x64enable
  6723. ?ppc
  6724. EnableMenu ppcenable
  6725. ?
  6726. Case MENUIOSENABLED
  6727. EnableMenu x86enable
  6728. EnableMenu x64enable
  6729. EnableMenu armv7enable
  6730. EnableMenu arm64enable
  6731. Case MENURASPBERRYPIENABLED
  6732. EnableMenu armenable
  6733. Case MENUANDROIDENABLED
  6734. EnableMenu x86enable
  6735. EnableMenu x64enable
  6736. EnableMenu armeabiv5enable
  6737. EnableMenu armeabiv7aenable
  6738. EnableMenu arm64v8aenable
  6739. Case MENUEMSCRIPTENENABLED
  6740. EnableMenu jsenable
  6741. Case MENUNXENABLED
  6742. EnableMenu arm64enable
  6743. End Select
  6744. Select platformMenu
  6745. Case MENUWIN32ENABLED
  6746. EnableMenu makelibenable
  6747. Default
  6748. If makelibenabled Then
  6749. UncheckMenu makelibenable
  6750. makelibenabled = False
  6751. CheckMenu guienable
  6752. guienabled = True
  6753. End If
  6754. End Select
  6755. End Method
  6756. Method DefaultArchitectureMenuForPlatform(platformMenu:Int)
  6757. For Local i:Int = 0 Until architectureenabled.Length
  6758. If architectureenabled[i] Then
  6759. Select ARCHITECTUREOFFSET + i
  6760. Case MENUX86ENABLED
  6761. UncheckMenu x86enable
  6762. Case MENUX64ENABLED
  6763. UncheckMenu x64enable
  6764. Case MENUPPCENABLED
  6765. UncheckMenu ppcenable
  6766. Case MENUARMENABLED
  6767. UncheckMenu armenable
  6768. Case MENUARMEABIV5ENABLED
  6769. UncheckMenu armeabiv5enable
  6770. Case MENUARMEABIV7AENABLED
  6771. UncheckMenu armeabiv7aenable
  6772. Case MENUARM64V8AENABLED
  6773. UncheckMenu arm64v8aenable
  6774. Case MENUJSENABLED
  6775. UncheckMenu jsenable
  6776. Case MENUARMV7ENABLED
  6777. UncheckMenu armv7enable
  6778. Case MENUARM64ENABLED
  6779. UncheckMenu arm64enable
  6780. End Select
  6781. End If
  6782. architectureenabled[i] = False
  6783. Next
  6784. Select platformMenu
  6785. Case MENUWIN32ENABLED, MENULINUXENABLED
  6786. ?x86
  6787. CheckMenu x86enable
  6788. architectureenabled[MENUX86ENABLED - ARCHITECTUREOFFSET] = True
  6789. ?x64
  6790. CheckMenu x64enable
  6791. architectureenabled[MENUX64ENABLED - ARCHITECTUREOFFSET] = True
  6792. ?
  6793. Case MENUMACOSXENABLED
  6794. ?x86
  6795. CheckMenu x86enable
  6796. architectureenabled[MENUX86ENABLED - ARCHITECTUREOFFSET] = True
  6797. ?x64
  6798. CheckMenu x64enable
  6799. architectureenabled[MENUX64ENABLED - ARCHITECTUREOFFSET] = True
  6800. ?ppc
  6801. CheckMenu ppcenable
  6802. architectureenabled[MENUPPCENABLED - ARCHITECTUREOFFSET] = True
  6803. ?
  6804. Case MENUIOSENABLED
  6805. ?x86
  6806. CheckMenu x86enable
  6807. architectureenabled[MENUX86ENABLED - ARCHITECTUREOFFSET] = True
  6808. ?x64
  6809. CheckMenu x64enable
  6810. architectureenabled[MENUX64ENABLED - ARCHITECTUREOFFSET] = True
  6811. ?
  6812. Case MENURASPBERRYPIENABLED
  6813. CheckMenu armenable
  6814. architectureenabled[MENUARMENABLED - ARCHITECTUREOFFSET] = True
  6815. Case MENUANDROIDENABLED
  6816. CheckMenu armeabiv5enable
  6817. architectureenabled[MENUARMEABIV5ENABLED - ARCHITECTUREOFFSET] = True
  6818. Case MENUEMSCRIPTENENABLED
  6819. CheckMenu jsenable
  6820. architectureenabled[MENUJSENABLED - ARCHITECTUREOFFSET] = True
  6821. Case MENUNXENABLED
  6822. CheckMenu arm64enable
  6823. architectureenabled[MENUARM64ENABLED - ARCHITECTUREOFFSET] = True
  6824. End Select
  6825. End Method
  6826. Method GetPlatform:String()
  6827. For Local i:Int = 0 Until platformenabled.Length
  6828. If platformenabled[i] Then
  6829. Select PLATFORMOFFSET + i
  6830. Case MENUWIN32ENABLED
  6831. Return "win32"
  6832. Case MENULINUXENABLED
  6833. Return "linux"
  6834. Case MENUMACOSXENABLED
  6835. Return "macos"
  6836. Case MENUIOSENABLED
  6837. Return "ios"
  6838. Case MENURASPBERRYPIENABLED
  6839. Return "raspberrypi"
  6840. Case MENUANDROIDENABLED
  6841. Return "android"
  6842. Case MENUEMSCRIPTENENABLED
  6843. Return "emscripten"
  6844. Case MENUNXENABLED
  6845. Return "nx"
  6846. End Select
  6847. End If
  6848. Next
  6849. Return Null
  6850. End Method
  6851. Method GetArchitecture:String()
  6852. For Local i:Int = 0 Until architectureenabled.Length
  6853. If architectureenabled[i] Then
  6854. Select ARCHITECTUREOFFSET + i
  6855. Case MENUX86ENABLED
  6856. Return "x86"
  6857. Case MENUX64ENABLED
  6858. Return "x64"
  6859. Case MENUPPCENABLED
  6860. Return "ppc"
  6861. Case MENUARMENABLED
  6862. Return "arm"
  6863. Case MENUARMEABIV5ENABLED
  6864. Return "armeabi"
  6865. Case MENUARMEABIV7AENABLED
  6866. Return "armeabiv7a"
  6867. Case MENUARM64V8AENABLED
  6868. Return "arm64v8a"
  6869. Case MENUJSENABLED
  6870. Return "js"
  6871. Case MENUARMV7ENABLED
  6872. Return "armv7"
  6873. Case MENUARM64ENABLED
  6874. Return "arm64"
  6875. End Select
  6876. End If
  6877. Next
  6878. Return Null
  6879. End Method
  6880. Method CanRunUPX:Int()
  6881. Local platform:String = GetPlatform()
  6882. If platform = "emscripten" Or platform = "nx" Or platform = "ios" Then
  6883. Return False
  6884. End If
  6885. Local upx:String = BlitzMaxPath() + "/bin/upx"
  6886. ?win32
  6887. upx :+ ".exe"
  6888. ?
  6889. If FileType(upx) = FILETYPE_FILE
  6890. Return True
  6891. End If
  6892. Return False
  6893. End Method
  6894. Method poll()
  6895. Local src:TGadget
  6896. Local event = WaitEvent()
  6897. If Not activerequesters.IsEmpty()
  6898. Select event
  6899. Case EVENT_MENUACTION
  6900. src = ActiveGadget()
  6901. If src And (GadgetClass(src) = GADGET_TEXTFIELD) Then
  6902. Select EventData()
  6903. Case MENUSELECTALL
  6904. ActivateGadget(src)
  6905. Case MENUCOPY
  6906. GadgetCopy(src)
  6907. Case MENUPASTE
  6908. GadgetPaste(src)
  6909. Case MENUCUT
  6910. GadgetCut(src)
  6911. EndSelect
  6912. Return
  6913. EndIf
  6914. src = Null
  6915. Case EVENT_MOUSEENTER,EVENT_MOUSELEAVE,EVENT_GADGETLOSTFOCUS
  6916. Return
  6917. End Select
  6918. 'DebugLog CurrentEvent.ToString()
  6919. For Local activerequester:TRequester = EachIn activerequesters
  6920. If activerequester.Poll() Then Return
  6921. Next
  6922. EndIf
  6923. For Local handler:TEventHandler = EachIn eventhandlers
  6924. handler.OnEvent()
  6925. Next
  6926. src = TGadget(EventSource())
  6927. Select event
  6928. Case EVENT_GADGETACTION
  6929. Select EventSource()
  6930. Case toolbar
  6931. Select EventData()
  6932. Case TB_NEW
  6933. OpenSource ""
  6934. Case TB_OPEN
  6935. OpenSource "."
  6936. Case TB_CLOSE
  6937. currentpanel.invoke TOOLCLOSE
  6938. Case TB_SAVE
  6939. currentpanel.invoke TOOLSAVE
  6940. Case TB_CUT
  6941. currentpanel.invoke TOOLCUT
  6942. Case TB_COPY
  6943. currentpanel.invoke TOOLCOPY
  6944. Case TB_PASTE
  6945. currentpanel.invoke TOOLPASTE
  6946. Case TB_FIND
  6947. currentpanel.invoke TOOLFIND
  6948. Case TB_BUILD
  6949. BuildCode
  6950. Case TB_BUILDRUN
  6951. RunCode
  6952. Case TB_STEP
  6953. If output output.stepover
  6954. Case TB_STEPIN
  6955. If output output.stepin
  6956. Case TB_STEPOUT
  6957. If output output.stepout
  6958. Case TB_STOP
  6959. If output output.Stop
  6960. Case TB_HOME
  6961. helppanel.Home
  6962. SelectPanel helppanel
  6963. Case TB_BACK
  6964. helppanel.Back
  6965. SelectPanel helppanel
  6966. Case TB_FORWARDS
  6967. helppanel.Forward
  6968. SelectPanel helppanel
  6969. Case TB_LOCKOPEN
  6970. 'unlock
  6971. If lockedPanel
  6972. TOpenCode(lockedPanel).SetLocked(False)
  6973. 'lock if lockable
  6974. ElseIf TOpenCode(activePanel)
  6975. TOpenCode(activePanel).SetLocked(True)
  6976. EndIf
  6977. Case TB_LOCKGOTO
  6978. If lockedPanel
  6979. SelectPanel(lockedPanel)
  6980. EndIf
  6981. End Select
  6982. Case tabbar
  6983. Local index = EventData()
  6984. If index>=0 And index<panels.length
  6985. SelectPanel panels[index]
  6986. EndIf
  6987. End Select
  6988. Case EVENT_WINDOWACCEPT, EVENT_APPOPENFILE
  6989. OpenSource EventText()
  6990. Case EVENT_APPTERMINATE
  6991. Quit()
  6992. Case EVENT_WINDOWACTIVATE
  6993. If (src=window) Then SelectPanel currentpanel
  6994. Case EVENT_WINDOWCLOSE
  6995. If (src=window) Then Quit()
  6996. Case EVENT_WINDOWMOVE, EVENT_WINDOWSIZE
  6997. If (src=window) Then SnapshotWindow()
  6998. Case EVENT_MENUACTION
  6999. OnMenu EventData(),EventExtra()
  7000. EndSelect
  7001. EndMethod
  7002. EndType
  7003. Function CacheAndLoadText$(url:Object)
  7004. Local tmpResult$
  7005. Local tmpBytes:Byte[] = LoadByteArray(url)
  7006. url = CreateRamStream( tmpBytes, tmpBytes.length, True, False )
  7007. tmpResult = LoadText(url)
  7008. TRamStream(url).Close()
  7009. Return tmpResult
  7010. EndFunction
  7011. Function ScaledSize:Int(value:Int)
  7012. Global cached:Int = GadgetScaleFactor(Desktop())
  7013. Return value * cached
  7014. End Function