maxide.bmx 168 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724172517261727172817291730173117321733173417351736173717381739174017411742174317441745174617471748174917501751175217531754175517561757175817591760176117621763176417651766176717681769177017711772177317741775177617771778177917801781178217831784178517861787178817891790179117921793179417951796179717981799180018011802180318041805180618071808180918101811181218131814181518161817181818191820182118221823182418251826182718281829183018311832183318341835183618371838183918401841184218431844184518461847184818491850185118521853185418551856185718581859186018611862186318641865186618671868186918701871187218731874187518761877187818791880188118821883188418851886188718881889189018911892189318941895189618971898189919001901190219031904190519061907190819091910191119121913191419151916191719181919192019211922192319241925192619271928192919301931193219331934193519361937193819391940194119421943194419451946194719481949195019511952195319541955195619571958195919601961196219631964196519661967196819691970197119721973197419751976197719781979198019811982198319841985198619871988198919901991199219931994199519961997199819992000200120022003200420052006200720082009201020112012201320142015201620172018201920202021202220232024202520262027202820292030203120322033203420352036203720382039204020412042204320442045204620472048204920502051205220532054205520562057205820592060206120622063206420652066206720682069207020712072207320742075207620772078207920802081208220832084208520862087208820892090209120922093209420952096209720982099210021012102210321042105210621072108210921102111211221132114211521162117211821192120212121222123212421252126212721282129213021312132213321342135213621372138213921402141214221432144214521462147214821492150215121522153215421552156215721582159216021612162216321642165216621672168216921702171217221732174217521762177217821792180218121822183218421852186218721882189219021912192219321942195219621972198219922002201220222032204220522062207220822092210221122122213221422152216221722182219222022212222222322242225222622272228222922302231223222332234223522362237223822392240224122422243224422452246224722482249225022512252225322542255225622572258225922602261226222632264226522662267226822692270227122722273227422752276227722782279228022812282228322842285228622872288228922902291229222932294229522962297229822992300230123022303230423052306230723082309231023112312231323142315231623172318231923202321232223232324232523262327232823292330233123322333233423352336233723382339234023412342234323442345234623472348234923502351235223532354235523562357235823592360236123622363236423652366236723682369237023712372237323742375237623772378237923802381238223832384238523862387238823892390239123922393239423952396239723982399240024012402240324042405240624072408240924102411241224132414241524162417241824192420242124222423242424252426242724282429243024312432243324342435243624372438243924402441244224432444244524462447244824492450245124522453245424552456245724582459246024612462246324642465246624672468246924702471247224732474247524762477247824792480248124822483248424852486248724882489249024912492249324942495249624972498249925002501250225032504250525062507250825092510251125122513251425152516251725182519252025212522252325242525252625272528252925302531253225332534253525362537253825392540254125422543254425452546254725482549255025512552255325542555255625572558255925602561256225632564256525662567256825692570257125722573257425752576257725782579258025812582258325842585258625872588258925902591259225932594259525962597259825992600260126022603260426052606260726082609261026112612261326142615261626172618261926202621262226232624262526262627262826292630263126322633263426352636263726382639264026412642264326442645264626472648264926502651265226532654265526562657265826592660266126622663266426652666266726682669267026712672267326742675267626772678267926802681268226832684268526862687268826892690269126922693269426952696269726982699270027012702270327042705270627072708270927102711271227132714271527162717271827192720272127222723272427252726272727282729273027312732273327342735273627372738273927402741274227432744274527462747274827492750275127522753275427552756275727582759276027612762276327642765276627672768276927702771277227732774277527762777277827792780278127822783278427852786278727882789279027912792279327942795279627972798279928002801280228032804280528062807280828092810281128122813281428152816281728182819282028212822282328242825282628272828282928302831283228332834283528362837283828392840284128422843284428452846284728482849285028512852285328542855285628572858285928602861286228632864286528662867286828692870287128722873287428752876287728782879288028812882288328842885288628872888288928902891289228932894289528962897289828992900290129022903290429052906290729082909291029112912291329142915291629172918291929202921292229232924292529262927292829292930293129322933293429352936293729382939294029412942294329442945294629472948294929502951295229532954295529562957295829592960296129622963296429652966296729682969297029712972297329742975297629772978297929802981298229832984298529862987298829892990299129922993299429952996299729982999300030013002300330043005300630073008300930103011301230133014301530163017301830193020302130223023302430253026302730283029303030313032303330343035303630373038303930403041304230433044304530463047304830493050305130523053305430553056305730583059306030613062306330643065306630673068306930703071307230733074307530763077307830793080308130823083308430853086308730883089309030913092309330943095309630973098309931003101310231033104310531063107310831093110311131123113311431153116311731183119312031213122312331243125312631273128312931303131313231333134313531363137313831393140314131423143314431453146314731483149315031513152315331543155315631573158315931603161316231633164316531663167316831693170317131723173317431753176317731783179318031813182318331843185318631873188318931903191319231933194319531963197319831993200320132023203320432053206320732083209321032113212321332143215321632173218321932203221322232233224322532263227322832293230323132323233323432353236323732383239324032413242324332443245324632473248324932503251325232533254325532563257325832593260326132623263326432653266326732683269327032713272327332743275327632773278327932803281328232833284328532863287328832893290329132923293329432953296329732983299330033013302330333043305330633073308330933103311331233133314331533163317331833193320332133223323332433253326332733283329333033313332333333343335333633373338333933403341334233433344334533463347334833493350335133523353335433553356335733583359336033613362336333643365336633673368336933703371337233733374337533763377337833793380338133823383338433853386338733883389339033913392339333943395339633973398339934003401340234033404340534063407340834093410341134123413341434153416341734183419342034213422342334243425342634273428342934303431343234333434343534363437343834393440344134423443344434453446344734483449345034513452345334543455345634573458345934603461346234633464346534663467346834693470347134723473347434753476347734783479348034813482348334843485348634873488348934903491349234933494349534963497349834993500350135023503350435053506350735083509351035113512351335143515351635173518351935203521352235233524352535263527352835293530353135323533353435353536353735383539354035413542354335443545354635473548354935503551355235533554355535563557355835593560356135623563356435653566356735683569357035713572357335743575357635773578357935803581358235833584358535863587358835893590359135923593359435953596359735983599360036013602360336043605360636073608360936103611361236133614361536163617361836193620362136223623362436253626362736283629363036313632363336343635363636373638363936403641364236433644364536463647364836493650365136523653365436553656365736583659366036613662366336643665366636673668366936703671367236733674367536763677367836793680368136823683368436853686368736883689369036913692369336943695369636973698369937003701370237033704370537063707370837093710371137123713371437153716371737183719372037213722372337243725372637273728372937303731373237333734373537363737373837393740374137423743374437453746374737483749375037513752375337543755375637573758375937603761376237633764376537663767376837693770377137723773377437753776377737783779378037813782378337843785378637873788378937903791379237933794379537963797379837993800380138023803380438053806380738083809381038113812381338143815381638173818381938203821382238233824382538263827382838293830383138323833383438353836383738383839384038413842384338443845384638473848384938503851385238533854385538563857385838593860386138623863386438653866386738683869387038713872387338743875387638773878387938803881388238833884388538863887388838893890389138923893389438953896389738983899390039013902390339043905390639073908390939103911391239133914391539163917391839193920392139223923392439253926392739283929393039313932393339343935393639373938393939403941394239433944394539463947394839493950395139523953395439553956395739583959396039613962396339643965396639673968396939703971397239733974397539763977397839793980398139823983398439853986398739883989399039913992399339943995399639973998399940004001400240034004400540064007400840094010401140124013401440154016401740184019402040214022402340244025402640274028402940304031403240334034403540364037403840394040404140424043404440454046404740484049405040514052405340544055405640574058405940604061406240634064406540664067406840694070407140724073407440754076407740784079408040814082408340844085408640874088408940904091409240934094409540964097409840994100410141024103410441054106410741084109411041114112411341144115411641174118411941204121412241234124412541264127412841294130413141324133413441354136413741384139414041414142414341444145414641474148414941504151415241534154415541564157415841594160416141624163416441654166416741684169417041714172417341744175417641774178417941804181418241834184418541864187418841894190419141924193419441954196419741984199420042014202420342044205420642074208420942104211421242134214421542164217421842194220422142224223422442254226422742284229423042314232423342344235423642374238423942404241424242434244424542464247424842494250425142524253425442554256425742584259426042614262426342644265426642674268426942704271427242734274427542764277427842794280428142824283428442854286428742884289429042914292429342944295429642974298429943004301430243034304430543064307430843094310431143124313431443154316431743184319432043214322432343244325432643274328432943304331433243334334433543364337433843394340434143424343434443454346434743484349435043514352435343544355435643574358435943604361436243634364436543664367436843694370437143724373437443754376437743784379438043814382438343844385438643874388438943904391439243934394439543964397439843994400440144024403440444054406440744084409441044114412441344144415441644174418441944204421442244234424442544264427442844294430443144324433443444354436443744384439444044414442444344444445444644474448444944504451445244534454445544564457445844594460446144624463446444654466446744684469447044714472447344744475447644774478447944804481448244834484448544864487448844894490449144924493449444954496449744984499450045014502450345044505450645074508450945104511451245134514451545164517451845194520452145224523452445254526452745284529453045314532453345344535453645374538453945404541454245434544454545464547454845494550455145524553455445554556455745584559456045614562456345644565456645674568456945704571457245734574457545764577457845794580458145824583458445854586458745884589459045914592459345944595459645974598459946004601460246034604460546064607460846094610461146124613461446154616461746184619462046214622462346244625462646274628462946304631463246334634463546364637463846394640464146424643464446454646464746484649465046514652465346544655465646574658465946604661466246634664466546664667466846694670467146724673467446754676467746784679468046814682468346844685468646874688468946904691469246934694469546964697469846994700470147024703470447054706470747084709471047114712471347144715471647174718471947204721472247234724472547264727472847294730473147324733473447354736473747384739474047414742474347444745474647474748474947504751475247534754475547564757475847594760476147624763476447654766476747684769477047714772477347744775477647774778477947804781478247834784478547864787478847894790479147924793479447954796479747984799480048014802480348044805480648074808480948104811481248134814481548164817481848194820482148224823482448254826482748284829483048314832483348344835483648374838483948404841484248434844484548464847484848494850485148524853485448554856485748584859486048614862486348644865486648674868486948704871487248734874487548764877487848794880488148824883488448854886488748884889489048914892489348944895489648974898489949004901490249034904490549064907490849094910491149124913491449154916491749184919492049214922492349244925492649274928492949304931493249334934493549364937493849394940494149424943494449454946494749484949495049514952495349544955495649574958495949604961496249634964496549664967496849694970497149724973497449754976497749784979498049814982498349844985498649874988498949904991499249934994499549964997499849995000500150025003500450055006500750085009501050115012501350145015501650175018501950205021502250235024502550265027502850295030503150325033503450355036503750385039504050415042504350445045504650475048504950505051505250535054505550565057505850595060506150625063506450655066506750685069507050715072507350745075507650775078507950805081508250835084508550865087508850895090509150925093509450955096509750985099510051015102510351045105510651075108510951105111511251135114511551165117511851195120512151225123512451255126512751285129513051315132513351345135513651375138513951405141514251435144514551465147514851495150515151525153515451555156515751585159516051615162516351645165516651675168516951705171517251735174517551765177517851795180518151825183518451855186518751885189519051915192519351945195519651975198519952005201520252035204520552065207520852095210521152125213521452155216521752185219522052215222522352245225522652275228522952305231523252335234523552365237523852395240524152425243524452455246524752485249525052515252525352545255525652575258525952605261526252635264526552665267526852695270527152725273527452755276527752785279528052815282528352845285528652875288528952905291529252935294529552965297529852995300530153025303530453055306530753085309531053115312531353145315531653175318531953205321532253235324532553265327532853295330533153325333533453355336533753385339534053415342534353445345534653475348534953505351535253535354535553565357535853595360536153625363536453655366536753685369537053715372537353745375537653775378537953805381538253835384538553865387538853895390539153925393539453955396539753985399540054015402540354045405540654075408540954105411541254135414541554165417541854195420542154225423542454255426542754285429543054315432543354345435543654375438543954405441544254435444544554465447544854495450545154525453545454555456545754585459546054615462546354645465546654675468546954705471547254735474547554765477547854795480548154825483548454855486548754885489549054915492549354945495549654975498549955005501550255035504550555065507550855095510551155125513551455155516551755185519552055215522552355245525552655275528552955305531553255335534553555365537553855395540554155425543554455455546554755485549555055515552555355545555555655575558555955605561556255635564556555665567556855695570557155725573557455755576557755785579558055815582558355845585558655875588558955905591559255935594559555965597559855995600560156025603560456055606560756085609561056115612561356145615561656175618561956205621562256235624562556265627562856295630563156325633563456355636563756385639564056415642564356445645564656475648564956505651565256535654565556565657565856595660566156625663566456655666566756685669567056715672567356745675567656775678567956805681568256835684568556865687568856895690569156925693569456955696569756985699570057015702570357045705570657075708570957105711571257135714571557165717571857195720572157225723572457255726572757285729573057315732573357345735573657375738573957405741574257435744574557465747574857495750575157525753575457555756575757585759576057615762576357645765576657675768576957705771577257735774577557765777577857795780578157825783578457855786578757885789579057915792579357945795579657975798579958005801580258035804580558065807580858095810581158125813581458155816581758185819582058215822582358245825582658275828582958305831583258335834583558365837583858395840584158425843584458455846584758485849585058515852585358545855585658575858585958605861586258635864586558665867586858695870587158725873587458755876587758785879588058815882588358845885588658875888588958905891589258935894589558965897589858995900590159025903590459055906590759085909591059115912591359145915591659175918591959205921592259235924592559265927592859295930593159325933593459355936593759385939594059415942594359445945594659475948594959505951595259535954595559565957595859595960596159625963596459655966596759685969597059715972597359745975597659775978597959805981598259835984598559865987598859895990599159925993599459955996599759985999600060016002600360046005600660076008600960106011601260136014601560166017601860196020602160226023602460256026602760286029603060316032603360346035603660376038603960406041604260436044604560466047604860496050605160526053605460556056605760586059606060616062606360646065606660676068606960706071607260736074607560766077607860796080608160826083608460856086608760886089609060916092609360946095609660976098609961006101610261036104610561066107610861096110611161126113611461156116611761186119612061216122612361246125612661276128612961306131613261336134613561366137613861396140614161426143614461456146614761486149615061516152615361546155615661576158615961606161616261636164616561666167616861696170617161726173617461756176617761786179618061816182618361846185618661876188618961906191619261936194619561966197619861996200620162026203620462056206620762086209621062116212621362146215621662176218621962206221622262236224622562266227622862296230623162326233623462356236623762386239624062416242624362446245624662476248624962506251625262536254625562566257625862596260626162626263626462656266626762686269627062716272627362746275627662776278627962806281628262836284628562866287628862896290629162926293629462956296629762986299630063016302630363046305630663076308630963106311631263136314631563166317631863196320632163226323632463256326632763286329633063316332633363346335633663376338633963406341634263436344634563466347634863496350635163526353635463556356635763586359636063616362636363646365636663676368636963706371637263736374637563766377637863796380638163826383638463856386638763886389639063916392639363946395639663976398639964006401640264036404640564066407640864096410641164126413641464156416641764186419642064216422642364246425642664276428642964306431643264336434643564366437643864396440644164426443644464456446644764486449645064516452645364546455645664576458645964606461646264636464646564666467646864696470647164726473647464756476647764786479648064816482648364846485648664876488648964906491649264936494649564966497649864996500650165026503650465056506650765086509651065116512651365146515651665176518651965206521652265236524652565266527652865296530653165326533653465356536653765386539654065416542654365446545654665476548654965506551655265536554655565566557655865596560
  1. ' maxide.bmx - blitzmax native integrated development environment
  2. ' by [email protected]
  3. ' released under the Blitz Shared Source Code License 2005
  4. ' released into the public domain 2006
  5. ' requires MaxGui modules to run
  6. Strict
  7. Framework MaxGUI.Drivers
  8. Import MaxGUI.ProxyGadgets
  9. ?Win32
  10. Import "maxicons.o"
  11. ?
  12. 'Import bah.gtkmaxgui
  13. 'Import bah.gtkwebgtkhtml
  14. 'Import bah.gtkwebmozilla
  15. Import brl.eventqueue
  16. Import brl.standardio
  17. Import brl.filesystem
  18. Import brl.system
  19. Import brl.ramstream
  20. Import pub.freeprocess
  21. Import brl.pngloader
  22. Import brl.timer
  23. Import brl.maxutil
  24. Incbin "bmxlogo.png"
  25. Incbin "toolbar.png"
  26. Incbin "splash.png"
  27. Incbin "default.language.ini"
  28. Const DEFAULT_LANGUAGEPATH$ = "incbin::default.language.ini"
  29. ?Linux
  30. Incbin "window_icon.png"
  31. ?
  32. AppTitle = "MaxIDE"
  33. Const IDE_VERSION$="1.43"
  34. Const TIMER_FREQUENCY=15
  35. ?Win32
  36. Extern
  37. Global _bbusew 'secret 'NT' flag
  38. End Extern
  39. If Not _bbusew
  40. Notify..
  41. "This program is not compatible with Windows 95/98/ME.~n~n"+..
  42. "Please visit www.blitzbasic.com to download a compatible version.",True
  43. End
  44. EndIf
  45. ?
  46. Global BCC_VERSION$="{unknown}" 'not valid until codeplay opened
  47. Const EOL$="~n"
  48. Const ABOUT$=..
  49. "{bcc_version} - Copyright Blitz Research Ltd.~n~n"+..
  50. "Please visit www.blitzbasic.com for all your Blitz related needs!"
  51. Const ABOUTDEMO$=..
  52. "This demo features both the core BlitzMax package and optional MaxGUI module.~n~n"+..
  53. "Please note that the MaxGUI module must be purchased separately."
  54. 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,mm,as,java,bbx,cx"
  55. Const FileTypeFilters$="Code Files:"+FileTypes$+";All Files:*"
  56. Const HOMEPAGE$="/docs/html/index.html"
  57. ?MacOS
  58. Global SVNCMD$="/usr/local/bin/svn"
  59. Const LABELOFFSET=2
  60. ?Win32
  61. Global SVNCMD$="svn"
  62. Const LABELOFFSET=4
  63. ?Linux
  64. Global SVNCMD$="/usr/bin/svn"
  65. Const LABELOFFSET=0
  66. ?
  67. Const MENUNEW=1
  68. Const MENUOPEN=2
  69. Const MENUCLOSE=3
  70. Const MENUSAVE=4
  71. Const MENUSAVEAS=5
  72. Const MENUSAVEALL=6
  73. Const MENUPRINT=7
  74. Const MENUQUIT=8
  75. Const MENUUNDO=9
  76. Const MENUREDO=10
  77. Const MENUCUT=11
  78. Const MENUCOPY=12
  79. Const MENUPASTE=13
  80. Const MENUSELECTALL=14
  81. Const MENUGOTO=15
  82. Const MENUINDENT=16
  83. Const MENUOUTDENT=17
  84. Const MENUFIND=18
  85. Const MENUFINDNEXT=19
  86. Const MENUREPLACE=20
  87. Const MENUNEXT=21
  88. Const MENUPREV=22
  89. Const MENUBUILD=23
  90. Const MENURUN=24
  91. Const MENUSTEP=25
  92. Const MENUSTEPIN=26
  93. Const MENUSTEPOUT=27
  94. Const MENUSTOP=28
  95. Const MENULOCKBUILD=29
  96. Const MENUUNLOCKBUILD=30
  97. Const MENUBUILDMODULES=31
  98. Const MENUBUILDALLMODULES=32
  99. Const MENUQUICKENABLED=33
  100. Const MENUDEBUGENABLED=34
  101. Const MENUGUIENABLED=35
  102. Const MENUCOMMANDLINE=36
  103. 'Const MENUSYNCMODS=37
  104. Const MENUIMPORTBB=38
  105. Const MENUFINDINFILES=39
  106. Const MENUPROJECTMANAGER=40
  107. Const MENUSHOWCONSOLE=41
  108. Const MENUOPTIONS=42
  109. Const MENUHOME=43
  110. Const MENUBACK=44
  111. Const MENUFORWARD=45
  112. Const MENUQUICKHELP=46
  113. Const MENUABOUT=47
  114. Const MENUNEWVIEW=48
  115. Const MENUDOCMODS=49
  116. Const MENUTRIGGERDOCMODS=50
  117. Const MENUTRIGGERSYNCDOCS=51
  118. Const MENUCLOSEALL=53
  119. Const MENUREFRESH=54
  120. Const MENUBROWSE=55
  121. Const MENUSHELL=56
  122. Const MENUPROPS=57
  123. Const MENUUPDATE=58
  124. Const MENUCOMMIT=59
  125. Const MENUCLOSEOTHERS=60
  126. Const MENUTHREADEDENABLED=61
  127. Const MENURECENT=256
  128. Const TB_NEW=0
  129. Const TB_OPEN=1
  130. Const TB_CLOSE=2
  131. Const TB_SAVE=3
  132. Const TB_CUT=5
  133. Const TB_COPY=6
  134. Const TB_PASTE=7
  135. Const TB_FIND=8
  136. Const TB_BUILD=10
  137. Const TB_BUILDRUN=11
  138. Const TB_STEP=12
  139. Const TB_STEPIN=13
  140. Const TB_STEPOUT=14
  141. Const TB_STOP=15
  142. Const TB_HOME=17
  143. Const TB_BACK=18
  144. Const TB_FORWARDS=19
  145. Const TB_CONTINUE=20
  146. Const TAB$=Chr(9)
  147. Const QUOTES$=Chr(34)
  148. Global TEMPCOUNT
  149. Global is_demo
  150. Global codeplay:TCodePlay
  151. Function CheckDemo()
  152. If Not is_demo Return 1
  153. Notify LocalizeString("{{notify_demo_featureunavailable}}")
  154. Return 0
  155. End Function
  156. Global defaultLanguage:TMaxGUILanguage = LoadLanguage( DEFAULT_LANGUAGEPATH )
  157. SetLocalizationLanguage( defaultLanguage )
  158. SetLocalizationMode( LOCALIZATION_ON|LOCALIZATION_OVERRIDE )
  159. codeplay=New TCodePlay
  160. codeplay.Initialize
  161. While codeplay.running
  162. codeplay.poll
  163. Wend
  164. End
  165. Function Quote$(a$) 'add quotes to arg if spaces found
  166. Local p
  167. If Not a.length Return
  168. If a[0]=34 Return a 'already quoted
  169. p=a.find(" ")
  170. If p=-1 Return a 'no spaces
  171. Return Chr(34)+a+Chr(34)
  172. End Function
  173. Type TToken
  174. Field token$
  175. Field help$
  176. Field ref$
  177. Method Create:TToken(t$,h$,r$)
  178. token=t
  179. help=h
  180. ref=r
  181. Return Self
  182. End Method
  183. End Type
  184. Type TQuickHelp
  185. Field map:TMap=New TMap 'key=lower(token) value=token:TToken
  186. Method AddCommand:TQuickHelp(t$,l$,a$)
  187. map.Insert t.ToLower(),New TToken.Create(t$,l$,a$)
  188. End Method
  189. Method Token$(cmd$)
  190. Local t:TToken = TToken(map.ValueForKey(cmd.toLower()))
  191. If t Return t.token
  192. End Method
  193. Method Help$(cmd$)
  194. Local t:TToken = TToken(map.ValueForKey(cmd.toLower()))
  195. If t Return t.help
  196. End Method
  197. Method Link$(cmd$)
  198. Local t:TToken = TToken(map.ValueForKey(cmd.toLower()))
  199. If t Return t.ref
  200. End Method
  201. Function LoadCommandsTxt:TQuickHelp(bmxpath$)
  202. Local text$
  203. Local qh:TQuickHelp
  204. Local i:Int,c,p,q
  205. Local token$,help$,anchor$
  206. Try
  207. text=CacheAndLoadText(bmxpath+"/docs/html/Modules/commands.txt")
  208. Catch exception:Object
  209. Return Null
  210. EndTry
  211. If Not text Return Null
  212. qh=New TQuickHelp
  213. For Local l$ = EachIn text.Split("~n")
  214. For i=0 Until l.length
  215. c=l[i]
  216. If c=Asc("_") Continue
  217. If c>=Asc("0") And c<=Asc("9") Continue
  218. If c>=Asc("a") And c<=Asc("z") Continue
  219. If c>=Asc("A") And c<=Asc("Z") Continue
  220. Exit
  221. Next
  222. token$=l[..i]
  223. help$=""
  224. anchor$=""
  225. q=l.findlast("|")
  226. If q>=0
  227. help=l[..q]
  228. anchor=l[q+1..]
  229. EndIf
  230. qh.AddCommand token,help,anchor
  231. Next
  232. Return qh
  233. End Function
  234. End Type
  235. Const TOOLSHOW=1
  236. Const TOOLREFRESH=2
  237. Const TOOLNEW=3
  238. Const TOOLOPEN=4
  239. Const TOOLCLOSE=5
  240. Const TOOLSAVE=6
  241. Const TOOLHELP=7
  242. Const TOOLUNDO=8
  243. Const TOOLREDO=9
  244. Const TOOLCUT=10
  245. Const TOOLCOPY=11
  246. Const TOOLPASTE=12
  247. Const TOOLQUICKSAVE=13
  248. Const TOOLSAVEAS=14
  249. Const TOOLGOTO=15
  250. Const TOOLFIND=16
  251. Const TOOLFINDNEXT=17
  252. Const TOOLREPLACE=18
  253. Const TOOLBUILD=19
  254. Const TOOLRUN=20
  255. Const TOOLLOCK=21
  256. Const TOOLUNLOCK=22
  257. Const TOOLSELECT=23
  258. Const TOOLSELECTALL=24
  259. Const TOOLINDENT=25
  260. Const TOOLOUTDENT=26
  261. Const TOOLACTIVATE=27
  262. Const TOOLNAVIGATE=28
  263. Const TOOLNEWVIEW=29
  264. Const TOOLMENU=30
  265. Const TOOLPRINT=31
  266. Const TOOLERROR=32
  267. Const TOOLOUTPUT=32
  268. Type TTool
  269. Method Invoke(command,argument:Object=Null)
  270. End Method
  271. End Type
  272. Type TRequester
  273. Const STYLE_OK% = 1, STYLE_CANCEL% = 2
  274. Const STYLE_DIVIDER% = 4, STYLE_STATUS% = 8
  275. Const STYLE_RESIZABLE% = 16, STYLE_STDBORDER% = 32
  276. Const STYLE_MODAL% = 64
  277. Field host:TCodePlay
  278. Field window:TGadget,ok:TGadget,cancel:TGadget,divider:TGadget
  279. Field centered, modal
  280. Method initrequester(owner:TCodeplay,label$,w=260,h=60,flags=STYLE_OK|STYLE_CANCEL|STYLE_DIVIDER,oktext$="{{btn_ok}}")
  281. host=owner
  282. If (flags&STYLE_MODAL) Then flags:|STYLE_STDBORDER
  283. If (flags & (STYLE_CANCEL|STYLE_OK)) Then h:+32;If (flags&STYLE_DIVIDER) Then h:+12
  284. Local windowflags% = WINDOW_TITLEBAR|WINDOW_HIDDEN|WINDOW_CLIENTCOORDS
  285. If (flags & STYLE_STATUS) Then windowflags:|WINDOW_STATUS
  286. If (flags & STYLE_RESIZABLE) Then windowflags:|WINDOW_RESIZABLE
  287. If Not (flags & STYLE_STDBORDER) Then windowflags:|WINDOW_TOOL
  288. window=CreateWindow(label,0,0,w,h,host.window,windowflags)
  289. If (flags & STYLE_RESIZABLE) Then
  290. If (flags & STYLE_STDBORDER) Then SetMaxWindowSize(window,ClientWidth(Desktop()),ClientHeight(Desktop()))
  291. SetMinWindowSize(window,w,h)
  292. EndIf
  293. If (flags & STYLE_OK) Then
  294. ok=CreateButton(oktext,ClientWidth(window)-101,ClientHeight(window)-32,95,26,window,BUTTON_OK)
  295. SetGadgetLayout(ok,EDGE_CENTERED,EDGE_ALIGNED,EDGE_CENTERED,EDGE_ALIGNED)
  296. If (flags & STYLE_CANCEL) Then
  297. cancel=CreateButton("{{btn_cancel}}",6,ClientHeight(window)-32,95,26,window,BUTTON_CANCEL)
  298. SetGadgetLayout(cancel,EDGE_ALIGNED,EDGE_CENTERED,EDGE_CENTERED,EDGE_ALIGNED)
  299. EndIf
  300. Else
  301. If (flags & STYLE_CANCEL) Then
  302. cancel=CreateButton("{{btn_close}}",ClientWidth(window)-101,ClientHeight(window)-32,95,26,window,BUTTON_CANCEL)
  303. SetGadgetLayout(cancel,EDGE_CENTERED,EDGE_ALIGNED,EDGE_CENTERED,EDGE_ALIGNED)
  304. EndIf
  305. EndIf
  306. If (flags & STYLE_DIVIDER) And (flags & (STYLE_OK|STYLE_CANCEL)) Then
  307. divider = CreateLabel( "", 6, ClientHeight(window)-42, ClientWidth(window)-12, 4, window, LABEL_SEPARATOR )
  308. SetGadgetLayout(divider,EDGE_ALIGNED,EDGE_ALIGNED,EDGE_CENTERED,EDGE_ALIGNED)
  309. EndIf
  310. If (flags & STYLE_MODAL) Then modal = True Else modal = False
  311. End Method
  312. Method Show()
  313. Local x,y,w,h,win:TGadget
  314. If Not centered
  315. win=host.window
  316. w=GadgetWidth(window)
  317. h=GadgetHeight(window)
  318. x=GadgetX(win)+(GadgetWidth(win)-w)/2
  319. y=GadgetY(win)+(GadgetHeight(win)-h)/2
  320. SetGadgetShape window,x,y,w,h
  321. centered=True
  322. EndIf
  323. host.HookRequester Self
  324. ShowGadget window
  325. ActivateGadget window
  326. PollSystem
  327. End Method
  328. Method Hide()
  329. EnableGadget host.window
  330. HideGadget window
  331. host.UnhookRequester Self
  332. host.SelectPanel host.currentpanel
  333. End Method
  334. Method IsModal()
  335. Return modal
  336. EndMethod
  337. Method Poll()
  338. End Method
  339. End Type
  340. Rem
  341. Type TProgressRequester Extends TRequester
  342. Field message$,value
  343. Field showing
  344. Field label:TGadget
  345. Field progbar:TGadget
  346. Method Show() 'returns false if cancelled
  347. showing=True
  348. Super.Show
  349. End Method
  350. Method Hide()
  351. showing=False
  352. Super.Hide()
  353. End Method
  354. Method Open(title$)
  355. SetGadgetText window,title
  356. Show
  357. End Method
  358. Method Update(msg$,val)
  359. If msg$<>message
  360. message=msg
  361. If label FreeGadget label
  362. label=CreateLabel(message,8,8,260,20,window)
  363. EndIf
  364. If showing And (val&$fc)<>(value&$fc) 'only update every 4 percent
  365. UpdateProgBar( progbar,val/100.0 )
  366. PollSystem
  367. EndIf
  368. value=val
  369. End Method
  370. Function Create:TProgressRequester(host:TCodePlay)
  371. Local progress:TProgressRequester
  372. progress=New TProgressRequester
  373. progress.initrequester(host,"{{progress_window_title}}",280,128,STYLE_CANCEL)
  374. progress.progbar=CreateProgBar( 8,32,260,20,progress.window )
  375. Return progress
  376. End Function
  377. End Type
  378. EndRem
  379. Type TPanelRequester Extends TRequester
  380. Field tabber:TGadget
  381. Field panels:TGadget[]
  382. Field index
  383. Method InitPanelRequester(owner:TCodeplay,label$,w=280,h=128)
  384. InitRequester owner,label,w,h,STYLE_OK|STYLE_CANCEL|STYLE_STDBORDER|STYLE_MODAL
  385. tabber=CreateTabber(6,6,w-12,h-12,window)
  386. SetGadgetLayout tabber,EDGE_ALIGNED,EDGE_ALIGNED,EDGE_ALIGNED,EDGE_ALIGNED
  387. End Method
  388. Method SetPanelIndex(i)
  389. HideGadget panels[index]
  390. index=i
  391. ShowGadget panels[index]
  392. SelectGadgetItem tabber,index
  393. End Method
  394. Method SetPanel(panel:TGadget)
  395. Local i
  396. For Local p:TGadget = EachIn panels
  397. If p=panel SetPanelIndex i;Exit
  398. i:+1
  399. Next
  400. End Method
  401. Method AddPanel:TGadget(name$)
  402. Local panel:TGadget
  403. panel=CreatePanel(0,0,ClientWidth(tabber),ClientHeight(tabber),tabber)
  404. SetGadgetLayout panel,EDGE_ALIGNED,EDGE_ALIGNED,EDGE_ALIGNED,EDGE_ALIGNED
  405. HideGadget panel
  406. AddGadgetItem tabber,name,GADGETITEM_LOCALIZED
  407. panels=panels[..panels.length+1]
  408. panels[panels.length-1]=panel
  409. Return panel
  410. End Method
  411. Method RemovePanel(panel)
  412. End Method
  413. End Type
  414. Type TAboutRequester Extends TRequester
  415. Global pixLogo:TPixmap
  416. Field pnlLogo:TGadget, lblTitle:TGadget, lblSubtitle:TGadget
  417. Field lblLeftAligned:TGadget[], lblRightAligned:TGadget[]
  418. Field hypBlitz:TGadget
  419. Method PopulateText()
  420. Local strHeadings$[], strValues$[]
  421. strHeadings:+["{{about_label_bccver}}:"]
  422. strValues:+[BCC_VERSION]
  423. strHeadings:+[""]
  424. strValues:+[""]
  425. strHeadings:+["{{about_label_bmxpath}}:"]
  426. ?Win32
  427. strValues:+[BlitzMaxPath().Replace("/","\")]
  428. ?Not Win32
  429. strValues:+[BlitzMaxPath()]
  430. ?
  431. ?Win32
  432. strHeadings:+["{{about_label_mingwpath}}:"]
  433. If getenv_("MINGW") Then
  434. strValues:+[getenv_("MINGW")]
  435. Else
  436. strValues:+[LocalizeString("{{about_error_unavailable}}")]
  437. EndIf
  438. ?
  439. strHeadings:+[""]
  440. strValues:+[""]
  441. ?Not MacOS
  442. strHeadings:+["{{about_label_fasmver}}:"]
  443. strValues:+[GetFASM()]
  444. ?
  445. strHeadings:+["{{about_label_gccver}}:"]
  446. strValues:+[GetGCC()]
  447. strHeadings:+["{{about_label_gplusplusver}}:"]
  448. strValues:+[GetGpp()]
  449. PopulateColumns( strHeadings, strValues )
  450. EndMethod
  451. Function GetProcessOutput$(cmd$, flags$ = "")
  452. Local version$
  453. ?Win32
  454. cmd:+".exe"
  455. ?
  456. cmd=Quote(cmd)
  457. If flags Then cmd:+" "+flags
  458. Local process:TProcess = CreateProcess(cmd,HIDECONSOLE)
  459. If process
  460. Local bytes:Byte[]
  461. Local tmpTimeout:Int = MilliSecs() + 500
  462. Repeat
  463. Delay 10
  464. bytes=process.pipe.ReadPipe()
  465. If bytes
  466. version:+String.FromBytes(bytes,bytes.length)
  467. EndIf
  468. Until (Not process.status()) Or (MilliSecs() > tmpTimeout)
  469. process.Close()
  470. Return version.Trim().Replace("~r","")
  471. EndIf
  472. Return LocalizeString("{{about_error_unavailable}}")
  473. EndFunction
  474. Method GetFASM$()
  475. ?Not MacOS
  476. Local tmpSections$[] = GetProcessOutput(BlitzMaxPath()+"/bin/fasm").Split("~n")[0].Split(" ")
  477. Return tmpSections[tmpSections.length-1]
  478. ?
  479. EndMethod
  480. Method GetGCC$()
  481. ?Win32
  482. If Not getenv_("MinGW") Then Return LocalizeString("{{about_error_notapplicable}}")
  483. ?
  484. Return GetProcessOutput("gcc", "-dumpversion").Split("~n")[0]
  485. EndMethod
  486. Method GetGpp$()
  487. ?Win32
  488. If Not getenv_("MinGW") Then Return LocalizeString("{{about_error_notapplicable}}")
  489. ?
  490. Return GetProcessOutput("g++", "-dumpversion").Split("~n")[0]
  491. EndMethod
  492. Method PopulateColumns( strHeadings$[], strValues$[] )
  493. strHeadings = strHeadings[..lblLeftAligned.length]
  494. strValues = strValues[..lblRightAligned.length]
  495. For Local i:Int = 0 Until lblLeftAligned.length
  496. LocalizeGadget( lblLeftAligned[i], strHeadings[i] )
  497. Next
  498. For Local i:Int = 0 Until lblRightAligned.length
  499. SetGadgetText( lblRightAligned[i], strValues[i] )
  500. SetGadgetToolTip( lblRightAligned[i], strValues[i] )
  501. Next
  502. EndMethod
  503. Method Show()
  504. PopulateText()
  505. Super.Show()
  506. EndMethod
  507. Method Poll()
  508. Select EventSource()
  509. Case window
  510. If EventID()=EVENT_WINDOWCLOSE
  511. Hide()
  512. EndIf
  513. Case cancel
  514. If EventID()=EVENT_GADGETACTION
  515. Hide()
  516. EndIf
  517. Default
  518. Return 0
  519. End Select
  520. Return 1
  521. End Method
  522. Function Create:TAboutRequester(host:TCodePlay)
  523. Local abt:TAboutRequester = New TAboutRequester
  524. abt.initrequester(host,"{{about_window_title}}",420,255,STYLE_CANCEL|STYLE_DIVIDER|STYLE_MODAL)
  525. Local win:TGadget = abt.window, w = ClientWidth(abt.window)-12, h = ClientHeight(abt.window)
  526. abt.pnlLogo = CreatePanel(w-(64-6),0,64,64,win)
  527. SetGadgetLayout abt.pnlLogo, EDGE_CENTERED, EDGE_ALIGNED, EDGE_ALIGNED, EDGE_CENTERED
  528. 'abt.pnlLogo = CreatePanel(0,0,64,64,win)
  529. 'SetGadgetLayout abt.pnlLogo, EDGE_ALIGNED, EDGE_CENTERED, EDGE_ALIGNED, EDGE_CENTERED
  530. If Not pixLogo Then pixLogo = LoadPixmapPNG("incbin::bmxlogo.png")
  531. SetGadgetPixmap abt.pnlLogo, pixLogo, PANELPIXMAP_CENTER
  532. Local y = 12
  533. abt.lblTitle = CreateLabel("MaxIDE "+IDE_VERSION,6,y,w,18,win,LABEL_LEFT)
  534. SetGadgetFont abt.lblTitle, LookupGuiFont( GUIFONT_SYSTEM, 12, FONT_BOLD )
  535. SetGadgetLayout abt.lblTitle, EDGE_ALIGNED, EDGE_ALIGNED, EDGE_ALIGNED, EDGE_CENTERED
  536. y:+19
  537. abt.lblSubtitle = CreateLabel("Copyright Blitz Research Ltd.",6,y,w,22,win,LABEL_LEFT)
  538. SetGadgetFont abt.lblSubtitle, LookupGuiFont( GUIFONT_SYSTEM, 10, FONT_ITALIC )
  539. SetGadgetLayout abt.lblSubtitle, EDGE_ALIGNED, EDGE_ALIGNED, EDGE_ALIGNED, EDGE_CENTERED
  540. y = 64
  541. SetGadgetLayout( CreateLabel("",6,y,w,4,win,LABEL_SEPARATOR), EDGE_ALIGNED, EDGE_ALIGNED, EDGE_ALIGNED, EDGE_CENTERED )
  542. y:+(4+6)
  543. Local tmpGadget:TGadget
  544. For y = y Until (255-21) Step 22
  545. tmpGadget = CreateLabel("",6,y,135,22,win,LABEL_LEFT)
  546. SetGadgetLayout( tmpGadget, EDGE_ALIGNED, EDGE_RELATIVE, EDGE_ALIGNED, EDGE_CENTERED )
  547. abt.lblLeftAligned:+[tmpGadget]
  548. tmpGadget = CreateLabel("",135+6,y,w-135,22,win,LABEL_LEFT)
  549. SetGadgetLayout( tmpGadget, EDGE_RELATIVE, EDGE_ALIGNED, EDGE_ALIGNED, EDGE_CENTERED )
  550. DelocalizeGadget tmpGadget
  551. abt.lblRightAligned:+[tmpGadget]
  552. Next
  553. abt.hypBlitz = CreateHyperlink("http://www.blitzbasic.com/",6,(h-28),200,26,win,LABEL_LEFT)
  554. SetGadgetLayout abt.hypBlitz, EDGE_ALIGNED, EDGE_ALIGNED, EDGE_CENTERED, EDGE_ALIGNED
  555. Return abt
  556. EndFunction
  557. Function Spacer( height:Int, inpout:Int Var )
  558. inpout:+height+6
  559. Return height
  560. EndFunction
  561. EndType
  562. Type TCmdLineRequester Extends TRequester
  563. Field label:TGadget,textfield:TGadget
  564. Method Poll()
  565. Select EventSource()
  566. Case window
  567. If EventID()=EVENT_WINDOWCLOSE
  568. Hide
  569. EndIf
  570. Case ok
  571. If EventID()=EVENT_GADGETACTION
  572. host.SetCommandLine TextFieldText(textfield)
  573. Hide
  574. EndIf
  575. Case cancel
  576. If EventID()=EVENT_GADGETACTION
  577. SetGadgetText textfield,host.GetCommandLine()
  578. Hide
  579. EndIf
  580. Default
  581. Return 0
  582. End Select
  583. Return 1
  584. End Method
  585. Method Show()
  586. SetGadgetText textfield,host.GetCommandLine()
  587. Super.Show()
  588. ActivateGadget textfield
  589. End Method
  590. Function Create:TCmdLineRequester(host:TCodePlay)
  591. Local cmd:TCmdLineRequester = New TCmdLineRequester
  592. cmd.initrequester(host,"{{cmdline_window_title}}",260,60,STYLE_OK|STYLE_CANCEL|STYLE_DIVIDER|STYLE_MODAL)
  593. cmd.label=CreateLabel("{{cmdline_label_cmdline}}:",6,8,260,20,cmd.window)
  594. cmd.textfield=CreateTextField(6,30,ClientWidth(cmd.window)-12,21,cmd.window)
  595. Return cmd
  596. End Function
  597. End Type
  598. Type TGotoRequester Extends TRequester
  599. Field linenumber:TGadget
  600. Method Show()
  601. Super.Show()
  602. ActivateGadget linenumber
  603. End Method
  604. Method Poll()
  605. Local line,data,text$
  606. Select EventSource()
  607. Case linenumber
  608. If EventID() = EVENT_GADGETACTION
  609. text = GadgetText(linenumber)
  610. If text And (Int(text) <> text) Then SetGadgetText linenumber, Int(text)
  611. EndIf
  612. Case window
  613. If EventID()=EVENT_WINDOWCLOSE
  614. Hide
  615. EndIf
  616. Case ok
  617. line=Int(GadgetText(linenumber))
  618. Hide
  619. host.activepanel.Invoke TOOLGOTO,String(line)
  620. Case cancel
  621. Hide
  622. Default
  623. Return 0
  624. End Select
  625. Return 1
  626. End Method
  627. Function Create:TGotoRequester(host:TCodePlay)
  628. Local seek:TGotoRequester = New TGotoRequester
  629. seek.initrequester(host,"{{goto_window_title}}",260,66,STYLE_OK|STYLE_CANCEL|STYLE_DIVIDER|STYLE_MODAL,"{{goto_btn_goto}}")
  630. CreateLabel("{{goto_label_linenum}}:",6,8+4,114,20,seek.window)
  631. seek.linenumber=CreateTextField(150,8,ClientWidth(seek.window)-(150+6),21,seek.window)
  632. SetGadgetFilter( seek.linenumber, IntegerFilter )
  633. Return seek
  634. End Function
  635. Function IntegerFilter:Int( event:TEvent, context:Object )
  636. Select event.id
  637. Case EVENT_KEYCHAR
  638. If event.data >= Asc("0") And event.data <= Asc("9") Return True
  639. If event.data = 8 Or event.data = 127 Or event.data = 13 Return True
  640. Return False
  641. Case EVENT_KEYDOWN
  642. Return True
  643. EndSelect
  644. EndFunction
  645. End Type
  646. Type TColor
  647. Field red,green,blue
  648. Method Set(rgb)
  649. red=(rgb Shr 16)&$FF
  650. green=(rgb Shr 8)&$FF
  651. blue=rgb&$FF
  652. End Method
  653. Method ToString$()
  654. Return ""+red+","+green+","+blue
  655. End Method
  656. Method FromString(s$)
  657. Local p=s.Find(",")+1
  658. If Not p Return
  659. Local q=s.Find(",",p)+1
  660. If Not q Return
  661. red=Int(s[..p-1])
  662. green=Int(s[p..q-1])
  663. blue=Int(s[q..])
  664. End Method
  665. Method Request()
  666. If RequestColor(red,green,blue)
  667. red=RequestedRed()
  668. green=RequestedGreen()
  669. blue=RequestedBlue()
  670. Return True
  671. EndIf
  672. End Method
  673. End Type
  674. Type TTextStyle
  675. Field label:TGadget,panel:TGadget,combo:TGadget
  676. Field underline:TGadget, color:TColor
  677. Field flags
  678. Method Set(rgb,bolditalic)
  679. color.set(rgb)
  680. flags=bolditalic
  681. End Method
  682. Method Format(textarea:TGadget,pos,length,emphasise:Int = False)
  683. Local tmpFlags:Int = flags
  684. If emphasise Then tmpFlags:|TEXTFORMAT_BOLD
  685. FormatTextAreaText textarea,color.red,color.green,color.blue,tmpFlags,pos,length
  686. End Method
  687. Method ToString$()
  688. Return ""+color.red+","+color.green+","+color.blue+","+flags
  689. End Method
  690. Method FromString(s$)
  691. Local p,q,r
  692. p=s.Find(",")+1;If Not p Return
  693. q=s.Find(",",p)+1;If Not q Return
  694. r=s.Find(",",q)+1;If Not r Return
  695. color.red=Int(s[..p-1])
  696. color.green=Int(s[p..q-1])
  697. color.blue=Int(s[q..r-1])
  698. flags=Int(s[r..])
  699. End Method
  700. Method Poll()
  701. Select EventSource()
  702. Case panel
  703. If EventID()=EVENT_MOUSEDOWN
  704. Return color.Request()
  705. EndIf
  706. Case combo
  707. flags=(flags&~3)|SelectedGadgetItem(combo)
  708. Return True
  709. Case underline
  710. If EventData() Then flags:|TEXTFORMAT_UNDERLINE Else flags:&~TEXTFORMAT_UNDERLINE
  711. Return True
  712. End Select
  713. End Method
  714. Method Refresh()
  715. SetPanelColor panel,color.red,color.green,color.blue
  716. SelectGadgetItem combo,flags&3
  717. SetButtonState(underline,(flags&TEXTFORMAT_UNDERLINE <> 0))
  718. End Method
  719. Function Create:TTextStyle(name$,xpos,ypos,window:TGadget)
  720. Local s:TTextStyle
  721. s=New TTextStyle
  722. s.color=New TColor
  723. s.label=CreateLabel(name,xpos,ypos+4,90,24,window)
  724. s.panel=CreatePanel(xpos+94,ypos,24,24,window,PANEL_BORDER|PANEL_ACTIVE)
  725. SetPanelColor s.panel,255,255,0
  726. s.combo=CreateComboBox(xpos+122,ypos,96,24,window)
  727. s.underline=CreateButton("{{txtstyle_underline}}",xpos+226,ypos,ClientWidth(window)-(xpos+220),24,window,BUTTON_CHECKBOX)
  728. AddGadgetItem s.combo,"{{txtstyle_normal}}",GADGETITEM_LOCALIZED
  729. AddGadgetItem s.combo,"{{txtstyle_bold}}",GADGETITEM_LOCALIZED
  730. AddGadgetItem s.combo,"{{txtstyle_italic}}",GADGETITEM_LOCALIZED
  731. AddGadgetItem s.combo,"{{txtstyle_bolditalic}}",GADGETITEM_LOCALIZED
  732. Return s
  733. End Function
  734. End Type
  735. Type TGadgetStyle
  736. Global fntLibrary:TGUIFont[] = [TGuiFont(Null), LookupGuiFont(GUIFONT_SYSTEM), LookupGuiFont(GUIFONT_MONOSPACED), ..
  737. LookupGuiFont(GUIFONT_SANSSERIF), LookupGuiFont(GUIFONT_SERIF), ..
  738. LookupGuiFont(GUIFONT_SCRIPT) ]
  739. Field label:TGadget,fpanel:TGadget,bpanel:TGadget,fcombo:TGadget,fbutton:TGadget
  740. Field font_name$, font_size:Double
  741. Field fg:TColor, bg:TColor
  742. Field font_type = GUIFONT_SYSTEM, font:TGUIFont = fntLibrary[font_type]
  743. Method Apply(gadget:TGadget)
  744. SetGadgetFont gadget,font
  745. SetGadgetColor gadget,bg.red,bg.green,bg.blue,True
  746. SetGadgetColor gadget,fg.red,fg.green,fg.blue,False
  747. End Method
  748. Method Set(fg_rgb,bg_rgb,ftype,fname$="",fsize=0)
  749. fg.set(fg_rgb)
  750. bg.set(bg_rgb)
  751. If Not fntLibrary[ftype] Then
  752. font_name=fname
  753. font_size=fsize
  754. Else
  755. font_name=FontName(fntLibrary[ftype])
  756. font_size=FontSize(fntLibrary[ftype])
  757. EndIf
  758. font_type=ftype
  759. End Method
  760. Method ToString$()
  761. Return font_name+","+font_size+","+fg.ToString()+","+bg.ToString()+","+font_type
  762. End Method
  763. Function GetArg$(a$ Var)
  764. Local p = a.Find(",")
  765. If p=-1 Then p=a.length
  766. Local r$ = a$[..p]
  767. a$=a$[p+1..]
  768. Return r$
  769. End Function
  770. Method FromString(s$)
  771. font_name=GetArg(s$)
  772. font_size=Double(GetArg(s$))
  773. fg.red=Int(GetArg(s$))
  774. fg.green=Int(GetArg(s$))
  775. fg.blue=Int(GetArg(s$))
  776. bg.red=Int(GetArg(s$))
  777. bg.green=Int(GetArg(s$))
  778. bg.blue=Int(GetArg(s$))
  779. font_type=Int(GetArg(s$))
  780. If fntLibrary[font_type] Then
  781. font_name=FontName(fntLibrary[font_type])
  782. font_size=FontSize(fntLibrary[font_type])
  783. EndIf
  784. End Method
  785. Method Poll()
  786. Local f:TGUIFont
  787. Select EventSource()
  788. Case fpanel
  789. If EventID()=EVENT_MOUSEDOWN
  790. Return fg.Request()
  791. EndIf
  792. Case bpanel
  793. If EventID()=EVENT_MOUSEDOWN
  794. Return bg.Request()
  795. EndIf
  796. Case fcombo, fbutton
  797. If EventSource() = fcombo Then
  798. If Not (EventData() < 0) Then
  799. font_type = EventData()
  800. f = fntLibrary[font_type]
  801. EndIf
  802. Else
  803. font_type = 0
  804. SelectGadgetItem fcombo, font_type
  805. EndIf
  806. If Not f Then f=RequestFont(font)
  807. If f
  808. font_name=FontName(f)
  809. font_size=FontSize(f)
  810. Return True
  811. EndIf
  812. End Select
  813. End Method
  814. Method Refresh()
  815. font=fntLibrary[font_type]
  816. If Not font Then font=LoadGuiFont(font_name,font_size)
  817. SetPanelColor fpanel,fg.red,fg.green,fg.blue
  818. SetPanelColor bpanel,bg.red,bg.green,bg.blue
  819. SelectGadgetItem fcombo, font_type
  820. Local tmpFloatText$[] = String(font_size).Split(".")
  821. If tmpFloatText.length > 1 Then tmpFloatText[1] = tmpFloatText[1][..Min(2,tmpFloatText[1].length)]
  822. SetGadgetText fbutton,font_name+" : "+".".Join(tmpFloatText)+"pt"
  823. End Method
  824. Function Create:TGadgetStyle(name$,xpos,ypos,window:TGadget)
  825. Local s:TGadgetStyle
  826. s=New TGadgetStyle
  827. s.fg=New TColor
  828. s.bg=New TColor
  829. s.label=CreateLabel(name,xpos,ypos+LABELOFFSET,66,50,window)
  830. s.fpanel=CreatePanel(xpos+68,ypos,24,24,window,PANEL_BORDER|PANEL_ACTIVE)
  831. s.bpanel=CreatePanel(xpos+96,ypos,24,24,window,PANEL_BORDER|PANEL_ACTIVE)
  832. s.fbutton=CreateButton("..",xpos+122,ypos+30,ClientWidth(window)-(xpos+128),24,window)
  833. s.fcombo=CreateComboBox(xpos+122,ypos,ClientWidth(window)-(xpos+128),24,window)
  834. AddGadgetItem s.fcombo, "{{options_font_desc_user}}", GADGETITEM_DEFAULT|GADGETITEM_LOCALIZED
  835. AddGadgetItem s.fcombo, "{{options_font_desc_guidefault}}", GADGETITEM_LOCALIZED
  836. AddGadgetItem s.fcombo, "{{options_font_desc_monospaced}}", GADGETITEM_LOCALIZED
  837. AddGadgetItem s.fcombo, "{{options_font_desc_sansserif}}", GADGETITEM_LOCALIZED
  838. AddGadgetItem s.fcombo, "{{options_font_desc_serif}}", GADGETITEM_LOCALIZED
  839. AddGadgetItem s.fcombo, "{{options_font_desc_script}}", GADGETITEM_LOCALIZED
  840. Return s
  841. End Function
  842. End Type
  843. Const NORMAL=0
  844. Const COMMENT=1
  845. Const QUOTED=2
  846. Const KEYWORD=3
  847. Const NUMBER=4
  848. Const MATCHING=5
  849. Type TOptionsRequester Extends TPanelRequester
  850. ' panels
  851. Field optionspanel:TGadget,editorpanel:TGadget,toolpanel:TGadget
  852. ' settings
  853. Field showtoolbar,restoreopenfiles,autocapitalize,syntaxhighlight,autobackup,autoindent,hideoutput
  854. Field bracketmatching, externalhelp,systemkeys,sortcode
  855. Field tabsize,language$
  856. Field editfontname$,editfontsize,editcolor:TColor
  857. Field outputfontname$,outputfontsize,outputcolor:TColor
  858. ' states
  859. Field editfont:TGUIFont
  860. ' gadgets
  861. Field languages:TGadget
  862. Field tabbutton:TGadget
  863. Field editpanel:TGadget,editbutton:TGadget
  864. Field buttons:TGadget[11]
  865. Field styles:TTextStyle[]
  866. Field textarea:TGadget
  867. Field outputstyle:TGadgetStyle
  868. Field navstyle:TGadgetStyle
  869. Field dirty
  870. Field undo:TBank
  871. Method Show()
  872. RefreshGadgets()
  873. Super.Show()
  874. EndMethod
  875. Method Snapshot()
  876. If Not undo undo=CreateBank(8192)
  877. Local stream:TStream=CreateBankStream(undo)
  878. write stream
  879. stream.close
  880. End Method
  881. Method Restore()
  882. If Not undo Return
  883. Local stream:TStream=CreateBankStream(undo)
  884. Read stream
  885. stream.close
  886. End Method
  887. Method SetDefaults()
  888. language=DEFAULT_LANGUAGEPATH
  889. bracketmatching=True
  890. showtoolbar=True
  891. restoreopenfiles=True
  892. autocapitalize=True
  893. syntaxhighlight=True
  894. autobackup=True
  895. autoindent=True
  896. tabsize=4
  897. editfontname$=FontName(TGadgetStyle.fntLibrary[GUIFONT_MONOSPACED])
  898. editfontsize=FontSize(TGadgetStyle.fntLibrary[GUIFONT_MONOSPACED])
  899. editcolor.set( $334455 )
  900. styles[NORMAL].set( $ffffff,0 )
  901. styles[COMMENT].set( $bbeeff,0 )
  902. styles[QUOTED].set( $00ff66,0 )
  903. styles[KEYWORD].set( $ffff00,0 )
  904. styles[NUMBER].set( $40ffff,0 )
  905. styles[MATCHING].set( $ff4040,TEXTFORMAT_BOLD )
  906. outputstyle.set(0,-1,GUIFONT_MONOSPACED)
  907. navstyle.set(0,-1,GUIFONT_SYSTEM)
  908. RefreshGadgets
  909. End Method
  910. Method Write(stream:TStream)
  911. stream.WriteLine "[Options]"
  912. stream.WriteLine "language="+language
  913. stream.WriteLine "showtoolbar="+showtoolbar
  914. stream.WriteLine "restoreopenfiles="+restoreopenfiles
  915. stream.WriteLine "autocapitalize="+autocapitalize
  916. stream.WriteLine "syntaxhighlight="+syntaxhighlight
  917. stream.WriteLine "bracketmatching="+bracketmatching
  918. stream.WriteLine "autobackup="+autobackup
  919. stream.WriteLine "autoindent="+autoindent
  920. stream.WriteLine "tabsize="+tabsize
  921. stream.WriteLine "editfontname="+editfontname
  922. stream.WriteLine "editfontsize="+editfontsize
  923. stream.WriteLine "editcolor="+editcolor.ToString()
  924. stream.WriteLine "normal_style="+styles[NORMAL].ToString()
  925. stream.WriteLine "comment_style="+styles[COMMENT].ToString()
  926. stream.WriteLine "quote_style="+styles[QUOTED].ToString()
  927. stream.WriteLine "keyword_style="+styles[KEYWORD].ToString()
  928. stream.WriteLine "number_style="+styles[NUMBER].ToString()
  929. stream.WriteLine "matched_style="+styles[MATCHING].ToString()
  930. stream.WriteLine "console_style="+outputstyle.ToString() 'Renamed from 'output_style' to bump users to default monospace font.
  931. stream.WriteLine "navi_style="+navstyle.ToString() 'Renamed from 'nav_style' to bump users to default treeview font.
  932. stream.WriteLine "hide_output="+hideoutput
  933. stream.WriteLine "external_help="+externalhelp
  934. stream.WriteLine "system_keys="+systemkeys
  935. stream.WriteLine "sort_code="+sortcode
  936. End Method
  937. Method Read(stream:TStream)
  938. Local f$,p,a$,b$,t
  939. While Not stream.Eof()
  940. f$=stream.ReadLine()
  941. If f$="" Or (f$[..1]="[" And f$<>"[Options]") Exit
  942. p=f.find("=")
  943. a$=f[..p]
  944. b$=f[p+1..]
  945. t=Int(b)
  946. Select a$
  947. Case "showtoolbar" showtoolbar=t
  948. Case "restoreopenfiles" restoreopenfiles=t
  949. Case "autocapitalize" autocapitalize=t
  950. Case "syntaxhighlight" syntaxhighlight=t
  951. Case "bracketmatching" bracketmatching=t
  952. Case "autobackup" autobackup=t
  953. Case "autoindent" autoindent=t
  954. Case "tabsize" tabsize=t
  955. Case "editfontname" editfontname=b
  956. Case "editfontsize" editfontsize=t
  957. Case "editcolor" editcolor.FromString(b)
  958. Case "normal_style" styles[NORMAL].FromString(b)
  959. Case "comment_style" styles[COMMENT].FromString(b)
  960. Case "quote_style" styles[QUOTED].FromString(b)
  961. Case "keyword_style" styles[KEYWORD].FromString(b)
  962. Case "number_style" styles[NUMBER].FromString(b)
  963. Case "matched_style" styles[MATCHING].FromString(b)
  964. Case "console_style" outputstyle.FromString(b) 'Renamed from 'output_style' to bump users to default monospace font.
  965. Case "navi_style" navstyle.FromString(b) 'Renamed from 'nav_style' to bump users to default treeview font.
  966. Case "hide_output" hideoutput=t
  967. Case "external_help" externalhelp=t
  968. Case "system_keys" systemkeys=t
  969. Case "sort_code" sortcode=t
  970. Case "language"
  971. Try
  972. Local tmpLanguage:TMaxGUILanguage = LoadLanguage(host.FullPath(b))
  973. If tmpLanguage Then
  974. language = b
  975. SetLocalizationLanguage tmpLanguage
  976. host.RefreshMenu()
  977. EndIf
  978. Catch excn:Object
  979. EndTry
  980. End Select
  981. Wend
  982. RefreshGadgets
  983. End Method
  984. Method RefreshGadgets()
  985. Local rgb:TColor,flags
  986. editfont=LoadGuiFont(editfontname,editfontsize)
  987. 'Language Loading / Enumeration
  988. ClearGadgetItems languages
  989. AddGadgetItem languages, "English (English) [Embedded]", GADGETITEM_DEFAULT,-1,"",DEFAULT_LANGUAGEPATH
  990. For Local tmpFile$ = EachIn LoadDir( host.bmxpath+"/cfg", True )
  991. Local tmpPath$ = host.bmxpath+"/cfg/"+tmpFile
  992. If FileType(tmpPath) = FILETYPE_FILE And tmpFile.ToLower().EndsWith(".language.ini") Then
  993. If tmpPath = host.FullPath(language) Then flags = GADGETITEM_DEFAULT Else flags = 0
  994. AddGadgetItem languages, tmpFile.Split(".")[0], flags, -1, "", "$BMXPATH/cfg/"+tmpFile
  995. EndIf
  996. Next
  997. SetButtonState buttons[0],showtoolbar
  998. SetButtonState buttons[1],restoreopenfiles
  999. SetButtonState buttons[2],autocapitalize
  1000. SetButtonState buttons[3],syntaxhighlight
  1001. SetButtonState buttons[4],bracketmatching
  1002. SetButtonState buttons[5],autobackup
  1003. SetButtonState buttons[6],autoindent
  1004. SetButtonState buttons[7],hideoutput
  1005. SetButtonState buttons[8],externalhelp
  1006. SetButtonState buttons[9],systemkeys
  1007. SetButtonState buttons[10],sortcode
  1008. SelectGadgetItem tabbutton,Min(Max(tabsize/2-1,0),7)
  1009. SetPanelColor editpanel,editcolor.red,editcolor.green,editcolor.blue
  1010. SetGadgetText editbutton,editfontname+" : "+editfontsize + "pt"
  1011. For Local i:Int = 0 Until styles.length
  1012. styles[i].Refresh
  1013. Next
  1014. LockTextArea textarea
  1015. SetTextAreaColor textarea,editcolor.red,editcolor.green,editcolor.blue,True
  1016. SetGadgetFont textarea,editfont
  1017. styles[NORMAL].format(textarea,0,TEXTAREA_ALL)
  1018. styles[COMMENT].format(textarea,0,12)
  1019. styles[MATCHING].format(textarea,24,1)
  1020. styles[NUMBER].format(textarea,25,3)
  1021. styles[NUMBER].format(textarea,31,1)
  1022. styles[MATCHING].format(textarea,32,1)
  1023. styles[NUMBER].format(textarea,36,1)
  1024. styles[KEYWORD].format(textarea,39,5)
  1025. styles[QUOTED].format(textarea,46,10)
  1026. UnlockTextArea textarea
  1027. outputstyle.Refresh
  1028. navstyle.Refresh
  1029. dirty=True
  1030. End Method
  1031. Method Poll()
  1032. Local font:TGUIFont,refresh,processed = 1
  1033. For Local i:Int = 0 Until styles.length
  1034. refresh:|styles[i].Poll()
  1035. Next
  1036. refresh:|outputstyle.Poll()
  1037. refresh:|navstyle.Poll()
  1038. Select EventID()
  1039. Case EVENT_GADGETACTION, EVENT_WINDOWCLOSE
  1040. Select EventSource()
  1041. Case buttons[0];showtoolbar=ButtonState(buttons[0]);dirty=True
  1042. Case buttons[1];restoreopenfiles=ButtonState(buttons[1])
  1043. Case buttons[2];autocapitalize=ButtonState(buttons[2]);dirty=True
  1044. Case buttons[3];syntaxhighlight=ButtonState(buttons[3]);dirty=True
  1045. Case buttons[4];bracketmatching=ButtonState(buttons[4])
  1046. Case buttons[5];autobackup=ButtonState(buttons[5])
  1047. Case buttons[6];autoindent=ButtonState(buttons[6])
  1048. Case buttons[7];hideoutput=ButtonState(buttons[7])
  1049. Case buttons[8];externalhelp=ButtonState(buttons[8])
  1050. Case buttons[9];systemkeys=ButtonState(buttons[9]);dirty=2
  1051. Case buttons[10];sortcode=ButtonState(buttons[10]);dirty=3
  1052. Case tabber;SetPanelIndex SelectedGadgetItem(tabber)
  1053. Case ok
  1054. Hide()
  1055. Select dirty
  1056. Case 1
  1057. host.RefreshAll
  1058. Case 2
  1059. host.Restart
  1060. End Select
  1061. dirty=False
  1062. SnapShot()
  1063. Case window
  1064. If EventID()=EVENT_WINDOWCLOSE
  1065. Restore()
  1066. dirty=False
  1067. Hide()
  1068. EndIf
  1069. Case cancel
  1070. Restore()
  1071. dirty=False
  1072. Hide()
  1073. Case tabbutton
  1074. tabsize=(SelectedGadgetItem(tabbutton)+1)*2
  1075. refresh=True
  1076. Case editpanel
  1077. If EventID()=EVENT_MOUSEDOWN
  1078. refresh=editcolor.Request()
  1079. EndIf
  1080. Case editbutton
  1081. font=RequestFont(editfont)
  1082. If font
  1083. editfontname=FontName(font)
  1084. editfontsize=FontSize(font)
  1085. refresh=True
  1086. EndIf
  1087. Case languages
  1088. If EventData() > 0 Then
  1089. language = String(GadgetItemExtra(languages,EventData()))
  1090. SetLocalizationLanguage TMaxGUILanguage(LoadLanguage(host.FullPath(language)))
  1091. Else
  1092. language = DEFAULT_LANGUAGEPATH
  1093. SetLocalizationLanguage defaultLanguage
  1094. EndIf
  1095. host.RefreshMenu()
  1096. Default
  1097. processed = 0
  1098. EndSelect
  1099. Case EVENT_MOUSEDOWN
  1100. Select EventSource()
  1101. Case editpanel
  1102. If EventID()=EVENT_MOUSEDOWN
  1103. editcolor.Request()
  1104. refresh=True
  1105. EndIf
  1106. Default
  1107. processed = 0
  1108. EndSelect
  1109. EndSelect
  1110. If refresh Then RefreshGadgets()
  1111. Return processed
  1112. End Method
  1113. Method InitOptionsRequester(host:TCodePlay)
  1114. Local w:TGadget
  1115. InitPanelRequester(host,"{{options_window_title}}",380,430)
  1116. ' init values
  1117. editcolor=New TColor
  1118. ' init gadgets
  1119. optionspanel=AddPanel("{{options_optionstab}}")
  1120. editorpanel=AddPanel("{{options_editortab}}")
  1121. toolpanel=AddPanel("{{options_toolstab}}")
  1122. SetGadgetShape( tabber, GadgetX(tabber), GadgetY(tabber)+32, GadgetWidth(tabber), GadgetHeight(tabber)-32 )
  1123. w=window
  1124. CreateLabel("{{options_options_label_language}}:",6,6+4,80,24,w)
  1125. languages = CreateComboBox(90,6,ClientWidth(w)-96,26,w)
  1126. w=optionspanel
  1127. buttons[0]=CreateButton("{{options_options_btn_showtoolbar}}",6,6,ClientWidth(w)-12,26,w,BUTTON_CHECKBOX)
  1128. buttons[1]=CreateButton("{{options_options_btn_autorestore}}",6,34,ClientWidth(w)-12,26,w,BUTTON_CHECKBOX)
  1129. buttons[2]=CreateButton("{{options_options_btn_autocaps}}",6,60,ClientWidth(w)-12,26,w,BUTTON_CHECKBOX)
  1130. buttons[3]=CreateButton("{{options_options_btn_syntaxhighlight}}",6,86,ClientWidth(w)-12,26,w,BUTTON_CHECKBOX)
  1131. buttons[4]=CreateButton("{{options_options_btn_bracketmatching}}",6,112,ClientWidth(w)-12,26,w,BUTTON_CHECKBOX)
  1132. buttons[5]=CreateButton("{{options_options_btn_autobackup}}",6,138,ClientWidth(w)-12,26,w,BUTTON_CHECKBOX)
  1133. buttons[6]=CreateButton("{{options_options_btn_autoindent}}",6,164,ClientWidth(w)-12,26,w,BUTTON_CHECKBOX)
  1134. buttons[7]=CreateButton("{{options_options_btn_autohideoutput}}",6,190,ClientWidth(w)-12,26,w,BUTTON_CHECKBOX)
  1135. buttons[8]=CreateButton("{{options_options_btn_useexternalbrowser}}",6,216,ClientWidth(w)-12,26,w,BUTTON_CHECKBOX)
  1136. buttons[9]=CreateButton("{{options_options_btn_osshortcuts}}",6,242,ClientWidth(w)-12,26,w,BUTTON_CHECKBOX)
  1137. buttons[10]=CreateButton("{{options_options_btn_sortcodeviewnodes}}",6,268,ClientWidth(w)-12,26,w,BUTTON_CHECKBOX)
  1138. w=editorpanel
  1139. CreateLabel("{{options_editor_label_background}}:",6,6+4,90,24,w)
  1140. editpanel=CreatePanel(100,6,24,24,w,PANEL_BORDER|PANEL_ACTIVE)
  1141. editbutton=CreateButton("..",128,6,ClientWidth(w)-134,24,w)
  1142. tabbutton=CreateComboBox(128,36,ClientWidth(w)-134,24,w)
  1143. For Local i=1 To 8
  1144. AddGadgetItem tabbutton,"{{options_editor_itemlabel_tabsize}} "+(i*2),GADGETITEM_LOCALIZED
  1145. Next
  1146. styles=New TTextStyle[6]
  1147. styles[NORMAL]=TTextStyle.Create("{{options_editor_label_plaintext}}:",6,66,w)
  1148. styles[COMMENT]=TTextStyle.Create("{{options_editor_label_remarks}}:",6,96,w)
  1149. styles[QUOTED]=TTextStyle.Create("{{options_editor_label_strings}}:",6,126,w)
  1150. styles[KEYWORD]=TTextStyle.Create("{{options_editor_label_keywords}}:",6,156,w)
  1151. styles[NUMBER]=TTextStyle.Create("{{options_editor_label_numbers}}:",6,186,w)
  1152. styles[MATCHING]=TTextStyle.Create("{{options_editor_label_matchings}}:",6,216,w)
  1153. textarea=CreateTextArea(6,250,ClientWidth(w)-12,ClientHeight(w)-256,w,TEXTAREA_READONLY)
  1154. SetGadgetText textarea,"'Sample Code~n~nresult = ((2.0 * 4) + 1)~nPrint( ~qResult: ~q + result )~n"
  1155. w=toolpanel
  1156. outputstyle=TGadgetStyle.Create("{{options_tools_label_output}}: ",6,6,w)
  1157. navstyle=TGadgetStyle.Create("{{options_tools_label_navbar}}: ",6,66,w)
  1158. SetDefaults()
  1159. SetPanel optionspanel
  1160. SnapShot
  1161. End Method
  1162. Function Create:TOptionsRequester(host:TCodePlay)
  1163. Local o:TOptionsRequester
  1164. o=New TOptionsRequester
  1165. o.InitOptionsRequester host
  1166. Return o
  1167. End Function
  1168. End Type
  1169. Type TFindRequester Extends TRequester
  1170. Field findterm:TGadget
  1171. Method ShowFind(term$="")
  1172. If term SetGadgetText(findterm,term)
  1173. Super.Show()
  1174. ActivateGadget findterm
  1175. End Method
  1176. Method Poll()
  1177. Local find$,data
  1178. Select EventSource()
  1179. Case window
  1180. If EventID()=EVENT_WINDOWCLOSE
  1181. Hide()
  1182. EndIf
  1183. Case ok
  1184. If EventID() = EVENT_GADGETACTION
  1185. If TextFieldText(findterm)
  1186. find=TextFieldText(findterm)
  1187. Hide()
  1188. host.activepanel.Invoke TOOLFINDNEXT,find
  1189. Else
  1190. Notify LocalizeString("{{search_error_nosearchstring}}"), True
  1191. ActivateGadget findterm
  1192. EndIf
  1193. EndIf
  1194. Case cancel
  1195. If EventID() = EVENT_GADGETACTION Then Hide()
  1196. Default
  1197. Return 0
  1198. End Select
  1199. Return 1
  1200. End Method
  1201. Function Create:TFindRequester(host:TCodePlay)
  1202. Local seek:TFindRequester
  1203. seek=New TFindRequester
  1204. seek.initrequester(host,"{{find_window_title}}",280,66,STYLE_OK|STYLE_CANCEL|STYLE_DIVIDER|STYLE_MODAL,"{{find_btn_find}}")
  1205. CreateLabel("{{find_label_find}}:",6,12,82,24,seek.window)
  1206. seek.findterm=CreateTextField(88,8,ClientWidth(seek.window)-(88+6),21,seek.window)
  1207. Return seek
  1208. End Function
  1209. End Type
  1210. Type TReplaceRequester Extends TRequester
  1211. Field findterm:TGadget,replaceterm:TGadget
  1212. Field findnext:TGadget,replaceit:TGadget,replaceall:TGadget
  1213. Method Show()
  1214. Super.Show()
  1215. ActivateGadget findterm
  1216. End Method
  1217. Method Poll()
  1218. Local find$,Replace$
  1219. Select EventSource()
  1220. Case window
  1221. If EventID()=EVENT_WINDOWCLOSE
  1222. Hide()
  1223. EndIf
  1224. Case cancel
  1225. If EventID() = EVENT_GADGETACTION Then Hide
  1226. Case ok
  1227. If EventID() = EVENT_GADGETACTION Then
  1228. If TextFieldText(findterm) Then
  1229. find=TextFieldText(findterm)
  1230. host.activepanel.Invoke TOOLFINDNEXT,find
  1231. Else
  1232. Notify LocalizeString("{{search_error_nosearchstring}}"), True
  1233. ActivateGadget findterm
  1234. EndIf
  1235. EndIf
  1236. Case replaceit
  1237. If EventID() = EVENT_GADGETACTION Then
  1238. Replace=TextFieldText(replaceterm)
  1239. If host.activepanel.Invoke(TOOLREPLACE,Replace)
  1240. host.activepanel.Invoke TOOLFINDNEXT,find
  1241. EndIf
  1242. EndIf
  1243. Case replaceall
  1244. If EventID() = EVENT_GADGETACTION Then
  1245. find=TextFieldText(findterm)
  1246. Replace=TextFieldText(replaceterm)
  1247. host.activepanel.Invoke TOOLREPLACE,find+Chr(0)+Replace
  1248. EndIf
  1249. Default
  1250. Return 0
  1251. End Select
  1252. Return 1
  1253. End Method
  1254. Function Create:TReplaceRequester(host:TCodePlay)
  1255. Local x,y
  1256. Local seek:TReplaceRequester
  1257. seek=New TReplaceRequester
  1258. seek.initrequester(host,"{{replace_window_title}}",380,80,STYLE_OK|STYLE_CANCEL|STYLE_DIVIDER,"{{replace_btn_findnext}}")
  1259. y=11
  1260. CreateLabel( "{{replace_label_find}}:",6,y+4,88,24,seek.window )
  1261. seek.findterm=CreateTextField( 96,y,168,21,seek.window )
  1262. y:+32
  1263. CreateLabel( "{{replace_label_replacewith}}:",6,y+4,88,24,seek.window )
  1264. seek.replaceterm=CreateTextField( 96,y,168,21,seek.window )
  1265. x=ClientWidth(seek.window)-102
  1266. y=8
  1267. seek.replaceit=CreateButton("{{replace_btn_replace}}",x,y,96,26,seek.window)
  1268. seek.replaceall=CreateButton("{{replace_btn_replaceall}}",x,y+32,96,26,seek.window)
  1269. Return seek
  1270. End Function
  1271. End Type
  1272. Type TEventHandler Extends TTool
  1273. Method OnEvent() Abstract
  1274. End Type
  1275. Type TToolPanel Extends TEventHandler
  1276. Field name$,path$
  1277. Field panel:TGadget
  1278. Field index
  1279. Field active
  1280. Method Show()
  1281. End Method
  1282. End Type
  1283. Type TView
  1284. Field node:TGadget
  1285. Field state
  1286. End Type
  1287. Type TNode Extends TTool
  1288. Const HIDESTATE=0
  1289. Const CLOSEDSTATE=1
  1290. Const OPENSTATE=2
  1291. Field name$,sortname$
  1292. Field parent:TNode
  1293. Field kids:TList=New TList
  1294. Field views:TView[]
  1295. ' activate program
  1296. Field target:TTool
  1297. Field action
  1298. Field argument:Object
  1299. Method SortKids( ascending=True )
  1300. Local term:TLink=kids._head
  1301. Repeat
  1302. Local link:TLink=kids._head._succ
  1303. Local sorted=True
  1304. Repeat
  1305. Local succ:TLink=link._succ
  1306. If succ=term Exit
  1307. Local cc=TNode(link._value).sortname.Compare( TNode(succ._value).sortname )
  1308. If (cc>0 And ascending) Or (cc<0 And Not ascending)
  1309. Local link_pred:TLink=link._pred
  1310. Local succ_succ:TLink=succ._succ
  1311. link_pred._succ=succ
  1312. succ._succ=link
  1313. succ._pred=link_pred
  1314. link._succ=succ_succ
  1315. link._pred=succ
  1316. succ_succ._pred=link
  1317. sorted=False
  1318. Else
  1319. link=succ
  1320. EndIf
  1321. Forever
  1322. If sorted Return
  1323. term=link
  1324. Forever
  1325. End Method
  1326. Method FindArgument:TNode(arg:Object)
  1327. Local n:TNode,r:TNode,a$
  1328. If arg.Compare(argument)=0 Return Self
  1329. a$=(String(arg)).ToLower()
  1330. If a And a=(String(argument)).toLower() Return Self
  1331. For n=EachIn kids
  1332. r=n.FindArgument(arg)
  1333. If r Return r
  1334. Next
  1335. End Method
  1336. ?Debug
  1337. Method Dump(indent$="")
  1338. Local n:TNode
  1339. Print indent+name
  1340. indent:+"~t"
  1341. For n=EachIn kids
  1342. n.Dump indent
  1343. Next
  1344. End Method
  1345. ?
  1346. Method IsHidden()
  1347. Local v:TView
  1348. If Not parent Return False
  1349. For v=EachIn parent.views
  1350. If v.state=OPENSTATE Return False
  1351. Next
  1352. Return True
  1353. End Method
  1354. Method SetAction(tool:TTool,cmd,arg:Object=Null)
  1355. target=tool
  1356. action=cmd
  1357. argument=arg
  1358. End Method
  1359. Method Hide(v:TView=Null) 'null means hide in all views
  1360. For Local n:TNode = EachIn kids
  1361. n.hide v
  1362. Next
  1363. If v
  1364. If v.node FreeTreeViewNode v.node;v.node=Null
  1365. Else
  1366. For v=EachIn views
  1367. If v.node FreeTreeViewNode v.node;v.node=Null
  1368. Next
  1369. EndIf
  1370. End Method
  1371. Method Detach()
  1372. Hide()
  1373. If parent parent.kids.remove Self;parent=Null
  1374. End Method
  1375. Method FreeKids()
  1376. For Local n:TNode = EachIn kids
  1377. n.free
  1378. Next
  1379. End Method
  1380. Method Free()
  1381. FreeKids()
  1382. Detach()
  1383. target=Null;argument=Null;views=Null
  1384. End Method
  1385. Method Invoke(command,arg:Object=Null)
  1386. Select command
  1387. Case TOOLACTIVATE
  1388. If target Return target.Invoke(action,argument)
  1389. End Select
  1390. End Method
  1391. Method Find:TNode(treeviewnode:TGadget,view=0)
  1392. Local n:TNode,r:TNode
  1393. Local v:TView
  1394. v=getview(view)
  1395. If v And v.node=treeviewnode Return Self
  1396. For n=EachIn kids
  1397. r=n.Find(treeviewnode,view)
  1398. If r Return r
  1399. Next
  1400. End Method
  1401. Method SetNode(treeviewnode:TGadget,view=0)
  1402. Local v:TView = getview(view)
  1403. v.node=treeviewnode
  1404. open view
  1405. End Method
  1406. Method HighLight(view=-1)
  1407. Local v:TView
  1408. If view=-1
  1409. For view=0 Until views.length
  1410. HighLight view
  1411. Next
  1412. Return
  1413. EndIf
  1414. v=GetView(view)
  1415. If v.node SelectTreeViewNode v.node
  1416. End Method
  1417. Method Open(view=-1)
  1418. Local v:TView
  1419. If view=-1
  1420. For view=0 Until views.length
  1421. Open view
  1422. Next
  1423. Return
  1424. EndIf
  1425. v=GetView(view)
  1426. If v.state<>OPENSTATE
  1427. v.state=OPENSTATE
  1428. RefreshView view
  1429. ' If v.node ExpandTreeViewNode v.node
  1430. EndIf
  1431. End Method
  1432. Method Close(view=0)
  1433. Local v:TView = GetView(view)
  1434. If v.state<>CLOSEDSTATE
  1435. v.state=CLOSEDSTATE
  1436. ' If v.node CollapseTreeViewNode v.node
  1437. EndIf
  1438. End Method
  1439. Method GetState(view=0)
  1440. Return GetView(view).state
  1441. End Method
  1442. Method GetView:TView(view=0)
  1443. If view>=views.length
  1444. views=views[..view+1]
  1445. EndIf
  1446. If Not views[view] views[view] = New TView
  1447. Return views[view]
  1448. End Method
  1449. Method GetIndex()
  1450. Local node:TNode
  1451. Local i
  1452. If parent
  1453. For node=EachIn parent.kids
  1454. If node=Self Return i
  1455. i:+1
  1456. Next
  1457. EndIf
  1458. End Method
  1459. Method Refresh()
  1460. For Local i:Int = 0 Until views.length
  1461. RefreshView i
  1462. Next
  1463. End Method
  1464. Method RefreshView(view=0)
  1465. Local n:TNode,quick,nodeToOpen:TGadget
  1466. Local v:TView,vv:TView
  1467. Local node
  1468. If parent And parent.getstate(view)=CLOSEDSTATE quick=True
  1469. v=getview(view)
  1470. If v.node And parent
  1471. If GadgetText(v.node) <> name Then
  1472. ModifyTreeViewNode v.node,name
  1473. LocalizeGadget(v.node,name,"")
  1474. EndIf
  1475. If v.state=OPENSTATE nodeToOpen = v.node;quick = False
  1476. Else
  1477. If parent And name
  1478. vv=parent.getview(view)
  1479. If vv.node
  1480. v.node=InsertTreeViewNode(GetIndex(),name,vv.node)
  1481. If v.state=HIDESTATE v.state=CLOSEDSTATE
  1482. If vv.state=OPENSTATE nodeToOpen = vv.node
  1483. quick=False
  1484. EndIf
  1485. EndIf
  1486. EndIf
  1487. If quick Return
  1488. If Not kids Return
  1489. For n=EachIn kids
  1490. n.RefreshView view
  1491. Next
  1492. If nodeToOpen Then ExpandTreeViewNode nodeToOpen
  1493. End Method
  1494. Method NodeAfter:TNode(node:TNode)
  1495. Local link:TLink
  1496. If node link=kids.FindLink(node)
  1497. If link link=link.NextLink()
  1498. If link Return TNode(link.Value())
  1499. End Method
  1500. Method Sync(snap:TNode)
  1501. Local snapkid:TNode
  1502. Local currentkid:TNode
  1503. Local kid:TNode
  1504. Local t:TNode
  1505. Local link:TLink
  1506. If snap.name<>name Return
  1507. If kids.Count() currentkid=TNode(kids.First())
  1508. For snapkid=EachIn snap.kids
  1509. ' if same name in list
  1510. kid=currentkid
  1511. While kid
  1512. If kid.name=snapkid.name Exit
  1513. kid=NodeAfter(kid)
  1514. Wend
  1515. ' then remove entries in front
  1516. If kid
  1517. While currentkid<>kid
  1518. t=currentkid
  1519. currentkid=NodeAfter(currentkid)
  1520. t.free()
  1521. Wend
  1522. EndIf
  1523. ' if same name sync else insert
  1524. If currentkid And currentkid.name=snapkid.name 'merge values if same name
  1525. currentkid.Sync snapkid
  1526. currentkid=NodeAfter(currentkid)
  1527. Else
  1528. snapkid.detach
  1529. If currentkid
  1530. link=kids.FindLink(currentkid)
  1531. kids.InsertBeforeLink snapkid,link
  1532. Else
  1533. kids.AddLast snapkid
  1534. EndIf
  1535. snapkid.parent=Self
  1536. EndIf
  1537. Next
  1538. ' remove any entries at end
  1539. While currentkid
  1540. t=currentkid
  1541. currentkid=NodeAfter(currentkid)
  1542. t.free()
  1543. Wend
  1544. Refresh()
  1545. End Method
  1546. Method SetName(n$)
  1547. name=n
  1548. End Method
  1549. Method AddNode:TNode(name$)
  1550. Local v:TNode
  1551. v=New TNode
  1552. v.setname name
  1553. Append v
  1554. Return v
  1555. End Method
  1556. Method Append(v:TNode)
  1557. v.parent=Self
  1558. kids.AddLast v
  1559. End Method
  1560. Function CreateNode:TNode(name$)
  1561. Local node:TNode
  1562. node=New TNode
  1563. node.setname name
  1564. Return node
  1565. End Function
  1566. End Type
  1567. Type THelpPanel Extends TToolPanel
  1568. Field host:TCodePlay
  1569. Field htmlview:TGadget
  1570. Method AddLink:TNode(parent:TNode,name$,href$)
  1571. Local n:TNode
  1572. If parent
  1573. n=parent.AddNode(name)
  1574. Else
  1575. n=host.helproot
  1576. EndIf
  1577. If href href=RealPath(href)
  1578. n.SetAction(Self,TOOLNAVIGATE,href)
  1579. Return n
  1580. End Method
  1581. Method ImportLinks( node:TNode,path$ )
  1582. Local t$=path+"/index.html"
  1583. If FileType( t )<>FILETYPE_FILE Return
  1584. node=AddLink( node,StripDir( path ),t )
  1585. Local map:TMap=New TMap
  1586. 'scan for html files
  1587. For Local e$=EachIn LoadDir( path )
  1588. If e="index.html" Continue
  1589. Local p$=path+"/"+e
  1590. Select FileType( p )
  1591. Case FILETYPE_DIR
  1592. ImportLinks node,p
  1593. Case FILETYPE_FILE
  1594. If Not e.StartsWith( "_" ) And ExtractExt( e ).Tolower()="html"
  1595. map.Insert StripExt( e ),p
  1596. EndIf
  1597. End Select
  1598. Next
  1599. 'scan for anchors in index.html...
  1600. '
  1601. 'note: anchors must be quote enclosed and of simple form <a name="blah">
  1602. Local c$=CacheAndLoadText( t ),i
  1603. Repeat
  1604. i=c.Find( "<a name=~q",i )
  1605. If i=-1 Exit
  1606. i:+9
  1607. Local i2=c.Find( "~q>",i )
  1608. If i2=-1 Exit
  1609. Local q$=c[i..i2]
  1610. If q.StartsWith( "_" ) Continue
  1611. map.Insert q,t+"#"+q
  1612. i=i2+1
  1613. Forever
  1614. For Local kv:TKeyValue=EachIn map
  1615. AddLink node,String( kv.Key() ),String( kv.Value() )
  1616. Next
  1617. End Method
  1618. Method SyncDocs()
  1619. host.helproot.FreeKids
  1620. ImportLinks Null,host.bmxpath+"/docs/html"
  1621. Local link:TNode
  1622. For Local m$=EachIn EnumModules()
  1623. If m.StartsWith( "brl." ) Or m.StartsWith( "pub." ) Or m.StartsWith("maxgui.") Continue
  1624. Local p$=ModulePath( m )+"/doc/commands.html"
  1625. If FileType( p )<>FILETYPE_FILE Continue
  1626. If Not link link=AddLink( host.helproot,"{{navnode_thirdpartymods}}","" )
  1627. AddLink link,m,p
  1628. Next
  1629. link=AddLink( host.helproot,"{{navnode_moduleindex}}","" )
  1630. If FileType( host.bmxpath+"/docs/html/Modules/commands.txt" )=FILETYPE_FILE
  1631. Local comm$=CacheAndLoadText( host.bmxpath+"/docs/html/Modules/commands.txt" )
  1632. For Local line$=EachIn comm.Split( "~n" )
  1633. Local bits$[]=line.Split( "|" )
  1634. If bits.length<>2 Continue
  1635. Local i=bits[0].Find( " : " )
  1636. If i<>-1 bits[0]=bits[0][..i]
  1637. AddLink link,bits[0],host.bmxpath+bits[1]
  1638. Next
  1639. EndIf
  1640. host.helproot.Refresh
  1641. End Method
  1642. Method Invoke(command,argument:Object=Null)
  1643. Local href$
  1644. If Not htmlview Return
  1645. Select command
  1646. Case TOOLCUT
  1647. GadgetCut htmlview
  1648. Case TOOLCOPY
  1649. GadgetCopy htmlview
  1650. Case TOOLPASTE
  1651. GadgetPaste htmlview
  1652. Case TOOLSHOW
  1653. ActivateGadget htmlview
  1654. host.SetTitle
  1655. Case TOOLNAVIGATE
  1656. href$=String(argument)
  1657. If href Go href
  1658. Case TOOLPRINT
  1659. GadgetPrint htmlview
  1660. End Select
  1661. End Method
  1662. Method OnEvent()
  1663. Local url$,p,t$
  1664. If EventSource()=htmlview
  1665. Select EventID()
  1666. Case EVENT_GADGETACTION 'NAVIGATEREQUEST
  1667. url$=String( EventExtra() )
  1668. If url[..5]="http:"
  1669. OpenURL url
  1670. Else
  1671. p=url.findlast(".")
  1672. If p>-1
  1673. t$=url[p..].tolower()
  1674. If t$=".bmx"
  1675. If url.Find( "file://" )=0
  1676. url=url[7..]
  1677. ?Win32
  1678. url=url[1..]
  1679. ?
  1680. EndIf
  1681. url=url.Replace("%20"," ")
  1682. Local source:TOpenCode=host.OpenSource(url)
  1683. If source source.MakePathTemp
  1684. Else
  1685. url=url.Replace("\","/")
  1686. url=url.Replace("user/index","user/welcome")
  1687. url=url.Replace("lang/index","lang/welcome")
  1688. url=url.Replace("mods/index","mods/welcome")
  1689. Go url$
  1690. EndIf
  1691. EndIf
  1692. EndIf
  1693. End Select
  1694. EndIf
  1695. End Method
  1696. Method Go(url$,internal=False)
  1697. Local node:TNode
  1698. If host.options.externalhelp And Not internal
  1699. PollSystem
  1700. OpenURL url
  1701. MinimizeWindow host.window
  1702. PollSystem
  1703. Return
  1704. EndIf
  1705. HtmlViewGo htmlview,url
  1706. host.SelectPanel Self
  1707. node=host.helproot.FindArgument(RealPath(url))
  1708. If node
  1709. node.Highlight
  1710. ' Else
  1711. ' print "node not found"
  1712. EndIf
  1713. ActivateGadget htmlview
  1714. End Method
  1715. Method Home()
  1716. Go host.bmxpath+HOMEPAGE,True
  1717. End Method
  1718. Method Forward()
  1719. HtmlViewForward htmlview
  1720. End Method
  1721. Method Back()
  1722. HtmlViewBack htmlview
  1723. End Method
  1724. Function Create:THelpPanel(host:TCodePlay)
  1725. Local root,style
  1726. Local p:THelpPanel = New THelpPanel
  1727. p.host=host
  1728. p.name="{{tab_help}}"
  1729. codeplay.addpanel(p)
  1730. style=HTMLVIEW_NONAVIGATE 'HTMLVIEW_NOCONTEXTMENU
  1731. p.htmlview=CreateHTMLView(0,0,ClientWidth(p.panel),ClientHeight(p.panel),p.panel,style)
  1732. SetGadgetLayout p.htmlview,EDGE_ALIGNED,EDGE_ALIGNED,EDGE_ALIGNED,EDGE_ALIGNED
  1733. ' p.Home
  1734. p.SyncDocs
  1735. Return p
  1736. End Function
  1737. End Type
  1738. Type TSearchResult
  1739. Field filepath$
  1740. Field char%, line%
  1741. Field linestring$
  1742. Method AddToListbox( pGadget:TGadget )
  1743. AddGadgetItem pGadget, "[" + line + ", " + char + "] " + filepath, 0, -1, StripWhitespace(linestring,char), Self
  1744. EndMethod
  1745. Method Set:TSearchResult(pFilePath$,pChar%,pLine%,pLineString$)
  1746. filepath = pFilePath
  1747. char = pChar
  1748. line = pLine
  1749. linestring = pLineString
  1750. Return Self
  1751. EndMethod
  1752. Function StripWhitespace$(pString$,pChar%)
  1753. If pString.length < pChar Then Return pString
  1754. Local outString$
  1755. For Local i:Int = 0 Until pString.length
  1756. Select pString[i]
  1757. Case Asc(" "), Asc("~t"), Asc("~n"), Asc("~r")
  1758. If outString And Not outString.EndsWith(" ") Then outString:+" "
  1759. Default
  1760. outString:+pString[i..i+1]
  1761. EndSelect
  1762. Next
  1763. Return outString
  1764. EndFunction
  1765. EndType
  1766. Type TSearchRequester Extends TRequester
  1767. Const strSearchText$ = "{{search_btn_startsearch}}", strStopSearchText$ = "{{search_btn_stopsearch}}"
  1768. Global strFileExts$[][] = [["bmx"],filetypes.Split(","),String[](Null)]
  1769. Field findbox:TGadget,typebox:TGadget,pathbox:TGadget,pathbutton:TGadget,pathsubdir:TGadget,results:TGadget
  1770. Field lstSearchResults:TList = New TList
  1771. Field safetyCount% = -1, safetyThreshold = 500, safetyResetCount% = 0
  1772. Method Poll()
  1773. Local id:Int = EventID()
  1774. Local data:Int = EventData()
  1775. Select EventSource()
  1776. Case results
  1777. Select id
  1778. Case EVENT_GADGETACTION
  1779. Local tmpSearchResult:TSearchResult = TSearchResult(EventExtra())
  1780. If tmpSearchResult Then
  1781. host.DebugSource( tmpSearchResult.filepath, tmpSearchResult.line, tmpSearchResult.char )
  1782. 'Hide()
  1783. EndIf
  1784. EndSelect
  1785. Case pathbutton
  1786. If EventID()=EVENT_GADGETACTION
  1787. Local tmpString$ = RequestDir( LocalizeString("{{search_requestfolder_title}}"),GadgetText(pathbox))
  1788. If tmpString Then SetGadgetText(pathbox,tmpString)
  1789. EndIf
  1790. Case window
  1791. If EventID()=EVENT_WINDOWCLOSE Then Hide()
  1792. Case findbox
  1793. If EventID() = EVENT_GADGETACTION Then
  1794. If GadgetText(findbox) Then EnableGadget(ok) Else DisableGadget(ok)
  1795. EndIf
  1796. Case ok
  1797. If EventID()=EVENT_GADGETACTION
  1798. If safetyCount < 0 Then StartSearch() Else safetyCount = -2
  1799. EndIf
  1800. Case cancel
  1801. If EventID()=EVENT_GADGETACTION Then Hide()
  1802. End Select
  1803. End Method
  1804. Method Hide()
  1805. safetyCount = -2
  1806. Super.Hide()
  1807. EndMethod
  1808. Method ShowWithPath( pPath$ )
  1809. If pPath Then SetGadgetText( pathbox, pPath )
  1810. Show()
  1811. ActivateGadget( findbox )
  1812. EndMethod
  1813. Method StartSearch()
  1814. PollSystem()
  1815. Select FileType(RealPath(GadgetText(pathbox)))
  1816. Case FILETYPE_NONE
  1817. Notify LocalizeString("{{search_error_pathnotfound}}"),True
  1818. ActivateGadget(pathbox)
  1819. Return
  1820. Case FILETYPE_FILE
  1821. Notify LocalizeString("{{search_error_pathisfile}}"),True
  1822. ActivateGadget(pathbox)
  1823. Return
  1824. EndSelect
  1825. If Not GadgetText(findbox) Then
  1826. Notify LocalizeString("{{search_error_nosearchstring}}"),True
  1827. ActivateGadget(findbox);Return
  1828. EndIf
  1829. safetyResetCount = 0;safetyCount = 0
  1830. LocalizeGadget ok, strStopSearchText;ClearGadgetItems results
  1831. SearchPath( GadgetText(pathbox), strFileExts[SelectedGadgetItem(typebox)], GadgetText(findbox).ToLower(), ButtonState(pathsubdir) )
  1832. LocalizeGadget ok, strSearchText;safetyCount = -1
  1833. SetStatusText window, LocalizeString("{{search_msg_complete}}").Replace("%1",CountGadgetItems(results))
  1834. EndMethod
  1835. Method SearchPath(pPath$,pFileType$[],pString$,pRecurse% = True)
  1836. pPath$ = RealPath(pPath) 'Make sure we are using a real path
  1837. Local tmpSearchDir$[] = LoadDir(pPath,True) 'Load directors contents into string array
  1838. If Not tmpSearchDir Then Return 'Return if the directory is invalid
  1839. tmpSearchDir.Sort() 'Sort the contents alphabetically
  1840. SetStatusText window, LocalizeString("{{search_msg_searchingdir}}").Replace("%1", pPath) 'And let user know which directory is being searched
  1841. Local tmpFullPath$
  1842. For Local tmpItem$ = EachIn tmpSearchDir
  1843. tmpFullPath = pPath + "/" + tmpItem
  1844. Select FileType(tmpFullPath)
  1845. Case FILETYPE_NONE;Continue 'Skip item if, for whatever reason, it doesn't exist
  1846. Case FILETYPE_FILE 'If file, then check extension and search if valid
  1847. If Not pFileType
  1848. SearchFile(tmpFullPath,pString)
  1849. Else
  1850. Local tmpExt$ = ExtractExt(tmpFullPath).ToLower$()
  1851. For Local tmpValidExt$ = EachIn pFileType
  1852. If tmpExt = tmpValidExt Then SearchFile(tmpFullPath,pString)
  1853. Next
  1854. EndIf
  1855. Case FILETYPE_DIR 'If folder, then we might have to search recursively
  1856. If pRecurse Then SearchPath(tmpFullPath,pFileType,pString,pRecurse)
  1857. EndSelect
  1858. If Not ShouldContinue() Then Return
  1859. Next
  1860. PollSystem();If PeekEvent() Then host.Poll() 'Let the system update as we could be searching a while
  1861. EndMethod
  1862. Method SearchFile(pPath$,pString$)
  1863. Local tmpText$ = CacheAndLoadText( pPath ), tmpLines$[], tmpFindPos%, tmpCharCount%, tmpLineNo%
  1864. Local tmpStringLength% = pString.length, tmpChunkLines$[], tmpPrevLines$
  1865. If tmpText Then
  1866. tmpLines = tmpText.Split("~n")
  1867. tmpText = tmpText.ToLower()
  1868. tmpFindPos = tmpText.Find(pString)
  1869. While ShouldContinue() And tmpFindPos > -1
  1870. tmpChunkLines = tmpText[..tmpFindPos].Split("~n")
  1871. tmpPrevLines = "~n".Join(tmpChunkLines[..tmpChunkLines.length-1])
  1872. tmpLineNo:+(tmpChunkLines.length)-1
  1873. Local tmpSearchResult:TSearchResult = New TSearchResult.Set(pPath,tmpFindPos-tmpPrevLines.length,tmpLineNo+1,tmpLines[tmpLineNo])
  1874. tmpSearchResult.AddToListbox(results);safetyCount:+1
  1875. tmpCharCount:+tmpFindPos+tmpStringLength
  1876. tmpText = tmpText[tmpFindPos+tmpStringLength..]
  1877. tmpFindPos = tmpText.Find(pString)
  1878. Wend
  1879. EndIf
  1880. EndMethod
  1881. Method ShouldContinue()
  1882. If safetyCount < 0 Then Return False
  1883. If safetyCount >= safetyThreshold Then
  1884. If Confirm( LocalizeString("{{search_safetynotification}}").Replace("%1",(safetyResetCount*safetyThreshold)+safetyCount) ) Then
  1885. safetyCount = 0
  1886. safetyResetCount:+1
  1887. Else
  1888. safetyCount = -1
  1889. Return False
  1890. EndIf
  1891. EndIf
  1892. Return True
  1893. EndMethod
  1894. Function Create:TSearchRequester(host:TCodePlay)
  1895. Local search:TSearchRequester = New TSearchRequester
  1896. search.initrequester(host,"{{search_window_title}}",440,280,STYLE_CANCEL|STYLE_DIVIDER|STYLE_OK|STYLE_STATUS|STYLE_RESIZABLE,strSearchText)
  1897. DisableGadget(search.ok)
  1898. SetGadgetLayout(CreateLabel("{{search_label_find}}:",6,8+4,95,24,search.window),EDGE_ALIGNED,EDGE_CENTERED,EDGE_ALIGNED,EDGE_CENTERED)
  1899. search.findbox=CreateTextField(103,8,ClientWidth(search.window)-(103+6),21,search.window);SetGadgetLayout(search.findbox,EDGE_ALIGNED,EDGE_ALIGNED,EDGE_ALIGNED,EDGE_CENTERED)
  1900. SetGadgetLayout(CreateLabel("{{search_label_filetypes}}:",6,42,95,24,search.window),EDGE_ALIGNED,EDGE_CENTERED,EDGE_ALIGNED,EDGE_CENTERED)
  1901. search.typebox=CreateComboBox(103,38,ClientWidth(search.window)-(103+6),24,search.window);SetGadgetLayout(search.typebox,EDGE_ALIGNED,EDGE_ALIGNED,EDGE_ALIGNED,EDGE_CENTERED)
  1902. AddGadgetItem( search.typebox, "{{search_type_bmaxfiles}}",GADGETITEM_DEFAULT|GADGETITEM_LOCALIZED,-1,"*.bmx" )
  1903. AddGadgetItem( search.typebox, "{{search_type_codefiles}}",GADGETITEM_LOCALIZED,-1,fileTypes )
  1904. AddGadgetItem( search.typebox, "{{search_type_allfiles}}",GADGETITEM_LOCALIZED,-1,"*")
  1905. SetGadgetLayout(CreateLabel("{{search_label_searchpath}}:",6,72,95,48,search.window),1,0,1,0)
  1906. search.pathbox=CreateTextField(103,68,ClientWidth(search.window)-(103+6+30+6),21,search.window);SetGadgetLayout(search.pathbox,EDGE_ALIGNED,EDGE_ALIGNED,EDGE_ALIGNED,EDGE_CENTERED)
  1907. search.pathbutton=CreateButton("..",ClientWidth(search.window)-(34+6),65,34,26,search.window);SetGadgetLayout(search.pathbutton,EDGE_CENTERED,EDGE_ALIGNED,EDGE_ALIGNED,EDGE_CENTERED)
  1908. SetGadgetText(search.pathbox, CurrentDir())
  1909. search.pathsubdir=CreateButton("{{search_btn_searchsubfolders}}",103,98,ClientWidth(search.window)-(103+6),20,search.window,BUTTON_CHECKBOX);SetGadgetLayout(search.pathsubdir,EDGE_ALIGNED,EDGE_ALIGNED,EDGE_ALIGNED,EDGE_CENTERED)
  1910. SetButtonState(search.pathsubdir,True)
  1911. search.results=CreateListBox(6,128,ClientWidth(search.window)-12,280-(128+6),search.window);SetGadgetLayout(search.results,EDGE_ALIGNED,EDGE_ALIGNED,EDGE_ALIGNED,EDGE_ALIGNED)
  1912. Return search
  1913. End Function
  1914. End Type
  1915. Type TProjectRequester Extends TRequester
  1916. Field projects:TProjects
  1917. Field listbox:TGadget
  1918. Field add:TGadget
  1919. Field remove:TGadget
  1920. Field props:TGadget
  1921. Field moveup:TGadget
  1922. Field movedown:TGadget
  1923. Field Current:TProjectFolderNode
  1924. Method Invoke(command,arg:Object=Null)
  1925. Select command
  1926. Case TOOLACTIVATE
  1927. Refresh
  1928. End Select
  1929. End Method
  1930. Method SetCurrent(i)
  1931. If i=-1
  1932. DisableGadget remove
  1933. DisableGadget moveup
  1934. DisableGadget movedown
  1935. DisableGadget props
  1936. Current=Null
  1937. Else
  1938. Current=TProjectFolderNode(GadgetItemExtra(listbox,i))
  1939. If Current
  1940. EnableGadget remove
  1941. EnableGadget props
  1942. EnableGadget moveup
  1943. EnableGadget movedown
  1944. EndIf
  1945. EndIf
  1946. End Method
  1947. Method Poll()
  1948. Local index
  1949. Select EventSource()
  1950. Case window
  1951. If EventID()=EVENT_WINDOWCLOSE Then Hide()
  1952. Case add
  1953. If EventID() = EVENT_GADGETACTION Then
  1954. projects.NewProject
  1955. Refresh
  1956. EndIf
  1957. Case remove
  1958. If EventID() = EVENT_GADGETACTION Then
  1959. projects.RemoveProject SelectedGadgetItem(listbox)
  1960. Refresh
  1961. EndIf
  1962. Case cancel
  1963. If EventID() = EVENT_GADGETACTION Then Hide
  1964. Case props
  1965. If EventID() = EVENT_GADGETACTION And Current
  1966. host.projectprops.Open(Current)
  1967. EndIf
  1968. Case listbox
  1969. If EventID()=EVENT_GADGETSELECT
  1970. SetCurrent SelectedGadgetItem(listbox) 'EventData()
  1971. ElseIf EventID()=EVENT_GADGETACTION
  1972. SetCurrent SelectedGadgetItem(listbox)
  1973. host.projectprops.Open(Current)
  1974. EndIf
  1975. Case moveup
  1976. If EventID()=EVENT_GADGETACTION Then
  1977. index=projects.MoveProject(SelectedGadgetItem(listbox),-1)
  1978. Refresh
  1979. SelectGadgetItem listbox,index
  1980. SetCurrent(index)
  1981. EndIf
  1982. Case movedown
  1983. If EventID()=EVENT_GADGETACTION Then
  1984. index=projects.MoveProject(SelectedGadgetItem(listbox),1)
  1985. Refresh
  1986. SelectGadgetItem listbox,index
  1987. SetCurrent(index)
  1988. EndIf
  1989. End Select
  1990. End Method
  1991. Method Refresh()
  1992. ClearGadgetItems listbox
  1993. For Local node:TNode = EachIn projects.kids
  1994. If TFolderNode(node)'node.argument
  1995. AddGadgetItem listbox,node.name,0,-1,"",node
  1996. EndIf
  1997. Next
  1998. SetCurrent -1
  1999. End Method
  2000. Method Open(projnode:TProjects)
  2001. projects=projnode
  2002. Refresh
  2003. Show
  2004. End Method
  2005. Function Create:TProjectRequester(host:TCodePlay)
  2006. Local x,y
  2007. Local proj:TProjectRequester = New TProjectRequester
  2008. proj.initrequester(host,"{{projman_window_title}}",400,168,STYLE_CANCEL|STYLE_DIVIDER|STYLE_MODAL)
  2009. proj.listbox=CreateListBox( 6,8,244,154,proj.window )
  2010. x=ClientWidth(proj.window)-144
  2011. proj.add=CreateButton("{{projman_btn_addproj}}",x,8,138,26,proj.window)
  2012. proj.remove=CreateButton("{{projman_btn_delproj}}",x,40,138,26,proj.window)
  2013. proj.moveup=CreateButton("{{projman_btn_moveup}}",x,72,138,26,proj.window)
  2014. proj.movedown=CreateButton("{{projman_btn_movedn}}",x,104,138,26,proj.window)
  2015. proj.props=CreateButton("{{projman_btn_properties}}",x,136,138,26,proj.window)
  2016. DisableGadget proj.remove
  2017. DisableGadget proj.moveup
  2018. DisableGadget proj.movedown
  2019. DisableGadget proj.props
  2020. Return proj
  2021. End Function
  2022. End Type
  2023. Type TProjectProperties Extends TRequester
  2024. Field proj:TProjectFolderNode
  2025. Field newproj:Int = False 'If 'True' then cancel/close deletes project.
  2026. Field localname:TGadget
  2027. Field localpath:TGadget
  2028. Field pathbutton:TGadget
  2029. Field path:TGadget
  2030. Field user:TGadget
  2031. Field password:TGadget
  2032. Field checkout:TGadget
  2033. ' Field update:TGadget
  2034. ' Field commit:TGadget
  2035. Field poprequester:TRequester 'hack for restoring to projectmanager requester
  2036. Field dirty
  2037. Method Invoke(command,arg:Object=Null)
  2038. Select command
  2039. Case TOOLACTIVATE
  2040. Refresh
  2041. End Select
  2042. End Method
  2043. Method Tidy()
  2044. newproj = False
  2045. If dirty
  2046. proj.Set GadgetText(localname),GadgetText(localpath),GadgetText(path),GadgetText(user),GadgetText(password)
  2047. dirty=False
  2048. EndIf
  2049. End Method
  2050. Method Poll()
  2051. If (EventID() <> EVENT_GADGETACTION) And (EventID() <> EVENT_WINDOWCLOSE) Then Return
  2052. Select EventSource()
  2053. Case localname,localpath,path,user,password
  2054. dirty=True
  2055. Case pathbutton
  2056. Local dir$=RequestDir(LocalizeString("{{project_requestfolder_title}}"))
  2057. If dir
  2058. If dir[dir.length-1..]="/" 'fltk hack
  2059. dir=dir[..dir.length-1]
  2060. EndIf
  2061. SetGadgetText localpath,dir
  2062. If GadgetText(localname)=""
  2063. SetGadgetText localname,StripDir(dir)
  2064. EndIf
  2065. dirty=True
  2066. EndIf
  2067. Case checkout
  2068. Tidy()
  2069. Hide()
  2070. proj.CheckoutVersion()
  2071. Rem
  2072. Case commit
  2073. Tidy
  2074. Hide
  2075. proj.CommitVersion
  2076. Case update
  2077. Tidy
  2078. Hide
  2079. proj.UpdateVersion
  2080. EndRem
  2081. Case ok
  2082. Tidy()
  2083. Hide()
  2084. Case cancel
  2085. Hide()
  2086. Case window
  2087. If EventID()=EVENT_WINDOWCLOSE
  2088. Hide()
  2089. EndIf
  2090. End Select
  2091. End Method
  2092. Method Hide()
  2093. If proj And newproj Then proj.Free()
  2094. EnableGadget host.window
  2095. HideGadget window
  2096. host.UnhookRequester Self'poprequester
  2097. If poprequester poprequester.Show
  2098. End Method
  2099. Method Refresh()
  2100. SetGadgetText localname,proj.name
  2101. SetGadgetText localpath,proj.path
  2102. SetGadgetText path,proj.svnpath
  2103. SetGadgetText user,proj.svnuser
  2104. SetGadgetText password,proj.svnpass
  2105. End Method
  2106. Method Open(projnode:TProjectFolderNode, newproject:Int = False)
  2107. newproj=newproject
  2108. proj=projnode
  2109. Refresh()
  2110. Show()
  2111. End Method
  2112. Function Create:TProjectProperties(host:TCodePlay)
  2113. Local proj:TProjectProperties = New TProjectProperties
  2114. proj.initrequester(host,"{{project_window_title}}",480,250,STYLE_OK|STYLE_CANCEL|STYLE_DIVIDER|STYLE_MODAL)
  2115. proj.modal = True
  2116. Local projectdetails:TGadget = CreatePanel(6,8,ClientWidth(proj.window)-12,85,proj.window,PANEL_GROUP,"{{project_group_details}}")
  2117. Local i,n,y
  2118. y=4
  2119. CreateLabel("{{project_label_name}}:",6,y+4,72,24,projectdetails)
  2120. proj.localname=CreateTextField(88,y,ClientWidth(projectdetails)-(88+6),21,projectdetails)
  2121. ' proj.pathbutton=CreateButton("..",434,y,34,28,projectdetails)
  2122. y:+30
  2123. CreateLabel("{{project_label_path}}:",8,y+4,72,24,projectdetails)
  2124. proj.localpath=CreateTextField(88,y,ClientWidth(projectdetails)-(88+34+6+6),21,projectdetails)
  2125. proj.pathbutton=CreateButton("..",ClientWidth(projectdetails)-(34+6),y-3,34,26,projectdetails)
  2126. y:+30
  2127. Local svnbox:TGadget = CreatePanel(6,101,ClientWidth(proj.window)-12,144,proj.window,PANEL_GROUP,"{{project_group_svn}}")
  2128. y=4
  2129. CreateLabel("{{project_label_url}}:",8,y+LABELOFFSET,72,24,svnbox)
  2130. proj.path=CreateTextField(88,y,ClientWidth(svnbox)-92,21,svnbox)
  2131. y:+30
  2132. CreateLabel("{{project_label_username}}:",8,y+LABELOFFSET,72,24,svnbox)
  2133. proj.user=CreateTextField(88,y,ClientWidth(svnbox)-92,21,svnbox)
  2134. y:+30
  2135. CreateLabel("{{project_label_password}}:",8,y+LABELOFFSET,72,24,svnbox)
  2136. proj.password=CreateTextField(88,y,ClientWidth(svnbox)-92,21,svnbox,TEXTFIELD_PASSWORD)
  2137. y:+30
  2138. proj.checkout=CreateButton("{{project_btn_checkout}}",ClientWidth(svnbox)-154,ClientHeight(svnbox)-32,150,28,svnbox)
  2139. ' proj.update=CreateButton("{{project_btn_update}}",180,y+10,150,28,svnbox)
  2140. ' proj.commit=CreateButton("{{project_btn_commit}}",340,y+10,150,28,svnbox)
  2141. y:+40
  2142. Return proj
  2143. End Function
  2144. End Type
  2145. Function GetInfo$(a$ Var)
  2146. Local p,r$
  2147. p=a.Find("|")+1
  2148. If p=0 p=a.length+1
  2149. r$=a$[..p-1]
  2150. a$=a$[p..]
  2151. Return r$
  2152. End Function
  2153. Type TFolderNode Extends TNode
  2154. Field owner:TNode
  2155. Field path$
  2156. Field scanned
  2157. Field version
  2158. Field foldertype
  2159. Const PROJECTFOLDER=0
  2160. Const DIRECTORYFOLDER=1
  2161. Const FILEFOLDER=2
  2162. Method FindFolderFromPath:TFolderNode(dir$)
  2163. Local result:TFolderNode
  2164. If path=dir Return Self
  2165. For Local folder:TFolderNode = EachIn kids
  2166. result=folder.FindFolderFromPath(dir)
  2167. If result Return result
  2168. Next
  2169. End Method
  2170. Method SetName(n$)
  2171. If version Then n:+"("+version+")"
  2172. Super.SetName( n )
  2173. Refresh
  2174. End Method
  2175. Method SetVersion(ver)
  2176. version=ver
  2177. SetName StripDir(path)
  2178. End Method
  2179. Method Write(stream:TStream)
  2180. Local isopen
  2181. If GetState()=OPENSTATE isopen=True
  2182. If version Or isopen
  2183. stream.WriteLine "proj_data="+path+"|"+isopen+"|"+version+"|"
  2184. EndIf
  2185. For Local folder:TFolderNode = EachIn kids
  2186. folder.Write(stream)
  2187. Next
  2188. End Method
  2189. Method ProjectHost:TCodePlay()
  2190. Local n:TNode = Self
  2191. While n
  2192. If TProjects(n) Return TProjects(n).host
  2193. n=n.parent
  2194. Wend
  2195. End Method
  2196. Method ProjectNode:TProjectFolderNode()
  2197. Local n:TNode = Self
  2198. While n
  2199. If TProjectFolderNode(n) Return TProjectFolderNode(n)
  2200. n=n.parent
  2201. Wend
  2202. End Method
  2203. Method RunSVN(cmd$,about$,refresh)
  2204. Local host:TCodePlay = ProjectHost()
  2205. If Not host Notify LocalizeString("{{svn_notification_nodehostnotfound}}");Return
  2206. Local project:TProjectFolderNode = ProjectNode()
  2207. If Not project Notify LocalizeString("{{svn_notification_nodeprojectnotfound}}");Return
  2208. If project.svnuser
  2209. cmd:+" --username "+project.svnuser
  2210. If project.svnpass cmd:+" --password "+project.svnpass
  2211. EndIf
  2212. If refresh
  2213. host.execute cmd,about,MENUREFRESH,True,Self
  2214. Else
  2215. host.execute cmd,about,0,0,Self
  2216. EndIf
  2217. End Method
  2218. Method UpdateVersion()
  2219. Local cmd$=svncmd+" update"
  2220. cmd:+" "+quote(path)
  2221. RunSVN cmd,LocalizeString("{{svn_msg_updating}}").Replace("%1",path),True
  2222. End Method
  2223. Method CommitVersion()
  2224. Local cmd$=svncmd+" commit"
  2225. cmd:+" -m ~qmy comment~q"
  2226. cmd:+" "+quote(path)
  2227. RunSVN cmd,LocalizeString("{{svn_msg_committing}}").Replace("%1",path),False
  2228. End Method
  2229. Method Open(view=-1)
  2230. Update(True)
  2231. Super.Open view
  2232. End Method
  2233. Method AddFileNode:TNode(file$)
  2234. Local n:TNode
  2235. Local ext$
  2236. If (","+FileTypes+",").Contains(","+ExtractExt(file).toLower()+",") Then
  2237. n=AddNode(StripDir(file))
  2238. n.SetAction(owner,TOOLOPEN,file)
  2239. ext=ExtractExt(file$).ToLower()
  2240. n.sortname=ext+n.name
  2241. Return n
  2242. EndIf
  2243. End Method
  2244. Method AddFolderNode:TNode(path$)
  2245. Local n:TFolderNode = TFolderNode.CreateFolderNode(path,DIRECTORYFOLDER)
  2246. n.owner = owner
  2247. n.sortname=" "+n.name
  2248. Append n
  2249. Return n
  2250. End Method
  2251. Method Scan(o:TNode)
  2252. Local p$
  2253. Local flist:TList = New TList
  2254. owner=o
  2255. For Local f$ = EachIn LoadDir(path,True)
  2256. If f[..1] = "." Then Continue
  2257. p$=path+"/"+f
  2258. Select FileType(p$)
  2259. Case FILETYPE_FILE
  2260. AddFileNode p$
  2261. Case FILETYPE_DIR
  2262. AddFolderNode p$
  2263. End Select
  2264. Next
  2265. SortKids
  2266. scanned = True
  2267. End Method
  2268. Method ScanKids()
  2269. For Local f:TFolderNode = EachIn kids
  2270. f.owner = owner
  2271. f.Update(False)
  2272. Next
  2273. End Method
  2274. Method Rescan()
  2275. scanned = False
  2276. Update()
  2277. EndMethod
  2278. Method Update( alwaysScanKids:Int = False )
  2279. If Not scanned Then
  2280. FreeKids()
  2281. Scan owner
  2282. EndIf
  2283. If alwaysScanKids Or Not IsHidden() Then ScanKids()
  2284. Refresh()
  2285. End Method
  2286. Method Invoke(command,argument:Object=Null)
  2287. Local host:TCodePlay
  2288. Local cmd,p
  2289. Local line$
  2290. host=ProjectHost()
  2291. If Not host Notify LocalizeString("{{svn_notification_nodehostnotfound}}");Return
  2292. Select command
  2293. Case TOOLOUTPUT
  2294. line$=String(argument)
  2295. p=line.find(" revision ")
  2296. If p>-1
  2297. SetVersion Int(line[p+10..])
  2298. EndIf
  2299. ' If line[..12]="At revision "
  2300. ' DebugLog "TOOLOUTPUT:"+line
  2301. Return
  2302. Case TOOLERROR
  2303. line$=String(argument)
  2304. ' DebugLog "TOOLERROR:"+line
  2305. Return
  2306. Case TOOLMENU
  2307. cmd=Int(String(argument))
  2308. Select cmd
  2309. Case 0 'special toolmenu-command=0 fired by rightbutton node context
  2310. Highlight
  2311. Local menu:TGadget
  2312. menu=host.projects.projmenu
  2313. PopupWindowMenu host.window,menu,Self
  2314. Case MENUREFRESH
  2315. Rescan()
  2316. Case MENUBROWSE
  2317. OpenURL RealPath(path)
  2318. Case MENUSHELL
  2319. Local cd$=CurrentDir()
  2320. ChangeDir RealPath(path)
  2321. ?MacOS
  2322. host.execute "/bin/bash","Shell Terminal"
  2323. ?Linux
  2324. host.execute "/bin/bash","Shell Terminal"
  2325. ?Win32
  2326. host.execute "cmd","Shell Terminal - Type Exit To End"
  2327. ?
  2328. ChangeDir cd
  2329. Case MENUUPDATE
  2330. UpdateVersion
  2331. Case MENUCOMMIT
  2332. CommitVersion
  2333. ' Case MENUPROPS
  2334. ' host.projectprops.Open(Self)
  2335. Case MENUFINDINFILES
  2336. host.searchreq.ShowWithPath( RealPath(path) )
  2337. End Select
  2338. End Select
  2339. End Method
  2340. Function CreateFolderNode:TFolderNode(path$,foldertype)
  2341. Local n:TFolderNode = New TFolderNode
  2342. ' n.host=host
  2343. n.SetName( StripDir(path) )
  2344. n.path = path
  2345. n.foldertype = foldertype
  2346. Return n
  2347. End Function
  2348. End Type
  2349. Type TProjectFolderNode Extends TFolderNode
  2350. Field owner:TProjects
  2351. Field svnpath$,svnuser$,svnpass$,svnversion
  2352. Field svnerr$
  2353. Method CheckoutVersion() 'to do - needs to move old version to temp?
  2354. Local cmd$ = svncmd+" checkout"
  2355. cmd:+" "+quote(svnpath)
  2356. cmd:+" "+quote(path)
  2357. RunSVN cmd,LocalizeString("{{svn_msg_checkingout}}").Replace("%1",svnpath).Replace("%2",path),True
  2358. End Method
  2359. Function Crypt$(a$)
  2360. Local b$,c
  2361. For Local i:Int = 0 Until a.length
  2362. c=a[i]
  2363. If c>31 c:~((i*-5)&31)
  2364. b:+Chr(c&255)
  2365. Next
  2366. Return b
  2367. End Function
  2368. Method ToString$()
  2369. Local prj$
  2370. Local isopen
  2371. If GetState()&OPENSTATE isopen=True
  2372. prj=name+"|"+path+"|"+svnpath+"|"+svnuser+"|"+crypt(svnpass)+"|"+isopen+"|"+version
  2373. Return prj
  2374. End Method
  2375. Method Write(stream:TStream)
  2376. stream.WriteLine "proj_node="+ToString()
  2377. For Local folder:TFolderNode = EachIn kids
  2378. folder.Write(stream)
  2379. Next
  2380. End Method
  2381. Method FromString(info$)
  2382. Local n$ = GetInfo(info)
  2383. If Not n Then n = "Unknown"
  2384. SetName( n )
  2385. path=GetInfo(info)
  2386. If path path=owner.host.FullPath(path)
  2387. svnpath=GetInfo(info)
  2388. svnuser=GetInfo(info)
  2389. svnpass=GetInfo(info)
  2390. Scan(owner)
  2391. Local isopen,vers
  2392. isopen=Int(GetInfo(info))
  2393. If isopen
  2394. Open
  2395. EndIf
  2396. vers=Int(GetInfo(info))
  2397. If vers
  2398. SetVersion vers
  2399. EndIf
  2400. End Method
  2401. Method Invoke(command,argument:Object=Null)
  2402. Local cmd
  2403. Select command
  2404. Case TOOLMENU
  2405. cmd=Int(String(argument))
  2406. Select cmd
  2407. Case MENUPROPS
  2408. Return owner.host.projectprops.Open(Self)
  2409. End Select
  2410. End Select
  2411. Return Super.Invoke(command,argument)
  2412. End Method
  2413. Method Set(n$,p$,s$,user$,pass$)
  2414. path=owner.host.FullPath(p)
  2415. setname n
  2416. svnpath=s
  2417. svnuser=user
  2418. svnpass=pass
  2419. Rescan()
  2420. owner.host.projectreq.Refresh()
  2421. End Method
  2422. Function CreateProjectNode:TProjectFolderNode(projects:TProjects,info$)
  2423. Local n:TProjectFolderNode = New TProjectFolderNode
  2424. n.owner=projects
  2425. n.FromString(info)
  2426. n.foldertype=PROJECTFOLDER
  2427. Return n
  2428. End Function
  2429. End Type
  2430. Type TProjects Extends TNode
  2431. Field host:TCodePlay
  2432. Field addproj:TNode
  2433. Field projmenu:TGadget
  2434. Field projmenuprops:TGadget
  2435. Method RemoveProject(index)
  2436. Local node:TNode
  2437. If index<0 Or index>=kids.Count() Return
  2438. node=TNode(kids.ValueAtIndex(index))
  2439. If node node.Free
  2440. Refresh
  2441. End Method
  2442. Method MoveProject(index,dir)
  2443. Local node:TNode
  2444. Local link:TLink
  2445. If index<0 Or index>=kids.Count() Return index
  2446. node=TNode(kids.ValueAtIndex(index))
  2447. If node
  2448. addproj.Detach
  2449. node.Hide
  2450. link=kids.FindLink(node)
  2451. If dir>0
  2452. If link link=link._succ
  2453. If link
  2454. kids.Remove node
  2455. kids.InsertAfterLink node,link
  2456. index:+1
  2457. EndIf
  2458. Else
  2459. If link link=link._pred
  2460. If link
  2461. kids.Remove node
  2462. kids.InsertBeforeLink node,link
  2463. index:-1
  2464. EndIf
  2465. EndIf
  2466. Append addproj
  2467. Refresh
  2468. EndIf
  2469. Return index
  2470. End Method
  2471. Method NewProject()
  2472. addproj.Detach
  2473. Local proj:TProjectFolderNode = TProjectFolderNode.CreateProjectNode(Self,LocalizeString("{{project_defaultname}}"))
  2474. ' proj.scan(Self)
  2475. Append proj
  2476. Append addproj
  2477. host.projectprops.Open(proj, True)
  2478. Refresh
  2479. End Method
  2480. Method AddProject(data:TList)
  2481. Local project:TProjectFolderNode
  2482. Local folder:TFolderNode
  2483. For Local info$ = EachIn data
  2484. If Not project
  2485. addproj.Detach
  2486. project=TProjectFolderNode.CreateProjectNode(Self,info)
  2487. Append project
  2488. Append addproj
  2489. Refresh
  2490. Else
  2491. Local path$
  2492. Local popen
  2493. Local pversion
  2494. path=GetInfo(info)
  2495. popen=Int(GetInfo(info))
  2496. pversion=Int(GetInfo(info))
  2497. folder=project.FindFolderFromPath(path)
  2498. If folder
  2499. folder.SetVersion pversion
  2500. folder.ReScan()
  2501. If popen Then folder.Open()
  2502. EndIf
  2503. EndIf
  2504. Next
  2505. End Method
  2506. Method Write(stream:TStream)
  2507. For Local project:TProjectFolderNode = EachIn kids
  2508. project.Write(stream)
  2509. Next
  2510. End Method
  2511. Method Invoke(command,argument:Object=Null)
  2512. Select command
  2513. Case TOOLNEW
  2514. NewProject
  2515. Case TOOLOPEN
  2516. host.OpenSource String(argument)
  2517. End Select
  2518. End Method
  2519. Function CreateProjects:TProjects(host:TCodePlay)
  2520. Local p:TProjects = New TProjects
  2521. p.SetName("{{navnode_projects}}")
  2522. p.host=host
  2523. p.addproj=p.AddNode("{{navnode_addproject}}")
  2524. p.addproj.SetAction p,TOOLNEW
  2525. p.projmenu=CreateMenu("{{popup_nav_proj}}",0,Null)
  2526. CreateMenu "{{popup_nav_proj_refresh}}",MENUREFRESH,p.projmenu
  2527. CreateMenu "{{popup_nav_proj_findinfiles}}",MENUFINDINFILES,p.projmenu
  2528. CreateMenu "{{popup_nav_proj_explore}}",MENUBROWSE,p.projmenu
  2529. CreateMenu "{{popup_nav_proj_shell}}",MENUSHELL,p.projmenu
  2530. CreateMenu "",0,p.projmenu
  2531. CreateMenu "{{popup_nav_proj_svnupdate}}",MENUUPDATE,p.projmenu
  2532. CreateMenu "{{popup_nav_proj_svncommit}}",MENUCOMMIT,p.projmenu
  2533. CreateMenu "",0,p.projmenu
  2534. p.projmenuprops=CreateMenu("{{popup_nav_proj_properties}}",MENUPROPS,p.projmenu)
  2535. host.projectreq.projects=p
  2536. Return p
  2537. End Function
  2538. End Type
  2539. Type TByteBuffer Extends TStream
  2540. Field bytes:Byte[]
  2541. Field readpointer
  2542. Method Read( buf:Byte Ptr,count )
  2543. If count>readpointer count=readpointer
  2544. If Not count Return
  2545. MemCopy buf,bytes,count
  2546. readpointer:-count
  2547. If readpointer MemMove bytes,Varptr bytes[count],readpointer
  2548. Return count
  2549. End Method
  2550. Method ReadLine$()
  2551. For Local i:Int = 0 Until readpointer
  2552. If bytes[i]=10 Or bytes[i] = 0 Then
  2553. Local tmpBytes:Byte[] = New Byte[i+1]
  2554. If i And bytes[i-1] = 13 Then i:-1
  2555. Read(tmpBytes,tmpBytes.length)
  2556. Return String.FromBytes(tmpBytes, i)
  2557. EndIf
  2558. Next
  2559. EndMethod
  2560. Method WriteFromPipe( pipe:TPipeStream )
  2561. Local n,m,count = pipe.ReadAvail()
  2562. n=readpointer+count
  2563. If n>bytes.length
  2564. m=Max(bytes.length*1.5,n)
  2565. bytes=bytes[..m]
  2566. EndIf
  2567. pipe.Read( Varptr bytes[readpointer], count )
  2568. readpointer=n
  2569. Return count
  2570. EndMethod
  2571. Method Write( buf:Byte Ptr,count )
  2572. Local n,m
  2573. n=readpointer+count
  2574. If n>bytes.length
  2575. m=Max(bytes.length*1.5,n)
  2576. bytes=bytes[..m]
  2577. EndIf
  2578. MemCopy Varptr bytes[readpointer],buf,count
  2579. readpointer=n
  2580. Return count
  2581. End Method
  2582. Method LineAvail()
  2583. For Local i:Int = 0 Until readpointer
  2584. If bytes[i]=10 Return True
  2585. Next
  2586. End Method
  2587. Method FlushBytes:Byte[]()
  2588. Local res:Byte[] = bytes[..readpointer]
  2589. readpointer = 0
  2590. Return res
  2591. End Method
  2592. End Type
  2593. Type TObj
  2594. Field addr$,sync,refs,syncnext
  2595. Method ShouldSync( pDebugTree:TDebugTree )
  2596. If sync < pDebugTree.sync Then pDebugTree.QueueSync( Self )
  2597. EndMethod
  2598. Method HasSynced( pSync% )
  2599. sync = pSync;syncnext = False
  2600. EndMethod
  2601. End Type
  2602. Type TVar Extends TNode
  2603. Field owner:TDebugTree
  2604. Field obj:Object
  2605. Method Free()
  2606. If TObj(obj) owner.RemoveObj TObj(obj)
  2607. obj=Null
  2608. Super.Free()
  2609. End Method
  2610. Method SetVarName(n$)
  2611. Local p
  2612. name=n
  2613. ' if object ref set addr$ field
  2614. If name.find("$=")=-1 And name.find( ":String=" )=-1 And name.find(")=$")=-1
  2615. p=name.find("=$")
  2616. If p<>-1
  2617. If TObj(obj) Then
  2618. If TObj(obj).addr <> name[p+2..] Then
  2619. TDebugTree.RemoveObj TObj(obj)
  2620. Else
  2621. TObj(obj).refs:-1
  2622. EndIf
  2623. EndIf
  2624. obj=TDebugTree.AddObj(name[p+2..])
  2625. 'Request object dump if we are visible now that
  2626. 'we have updated our own object pointer.
  2627. If Not IsHidden() Then Request()
  2628. Return
  2629. EndIf
  2630. p=name.find("=Null")
  2631. If p<>-1
  2632. FreeKids
  2633. TDebugTree.RemoveObj TObj(obj)
  2634. obj=Null
  2635. EndIf
  2636. EndIf
  2637. End Method
  2638. Method AddVar(name$)
  2639. Local v:TVar=New TVar
  2640. v.owner=owner
  2641. Append v
  2642. v.setvarname name
  2643. End Method
  2644. Method SetValue(val:TVar)
  2645. Local v:TVar,w:TVar,i,kidsarray:Object[]
  2646. ' if this is a reference to same object refresh values
  2647. If obj And obj=val.obj
  2648. If kids.IsEmpty()
  2649. For v=EachIn val.kids
  2650. AddVar v.name
  2651. Next
  2652. Else
  2653. kidsarray = kids.ToArray()
  2654. For v=EachIn val.kids
  2655. If i<kidsarray.length
  2656. w=TVar(kidsarray[i])
  2657. If w w.SetVarName v.name
  2658. Else
  2659. AddVar v.name
  2660. EndIf
  2661. i:+1
  2662. Next
  2663. kidsarray = Null
  2664. EndIf
  2665. Refresh
  2666. EndIf
  2667. ' recurse so all references are updated
  2668. If IsHidden() Then Return 'parent And parent.state=CLOSEDSTATE Return
  2669. For v=EachIn kids
  2670. v.SetValue val
  2671. Next
  2672. End Method
  2673. Method Open(open=-1)
  2674. For Local kid:TVar = EachIn kids
  2675. kid.Request()
  2676. Next
  2677. Super.Open(open)
  2678. EndMethod
  2679. Method Request()
  2680. If TObj(obj) Then TObj(obj).ShouldSync(owner)
  2681. EndMethod
  2682. End Type
  2683. Type TScope Extends TVar
  2684. Field tree:TDebugTree
  2685. Field file$,line,column
  2686. Method Invoke(command,argument:Object=Null)
  2687. Select command
  2688. Case TOOLACTIVATE
  2689. tree.SelectScope Self,True
  2690. End Select
  2691. End Method
  2692. Method SetScope(s:TScope)
  2693. Local v:TVar
  2694. file=s.file
  2695. line=s.line
  2696. column=s.column
  2697. s.obj=Self
  2698. SetValue s
  2699. End Method
  2700. Method SetFile(debugtree:TDebugTree,f$)
  2701. tree=debugtree
  2702. Local p=f.Find("<")+1
  2703. Local q=f.Find(">")+1
  2704. Local r=f.Find(",")+1
  2705. If p And q And r
  2706. file=f[..p-1]
  2707. line=Int(f[p..r-1])
  2708. column=Int(f[r..q-1])
  2709. EndIf
  2710. obj=Self
  2711. End Method
  2712. Method Request()
  2713. For Local kid:TVar = EachIn kids
  2714. kid.Request()
  2715. Next
  2716. EndMethod
  2717. End Type
  2718. Type TDebugTree Extends TVar
  2719. Global sync
  2720. Global objmap:TMap = CreateMap()
  2721. Field host:TCodePlay
  2722. Field instack:TList
  2723. Field inscope:TScope
  2724. Field invar:TVar
  2725. Field infile$
  2726. Field inexception$
  2727. Field firststop
  2728. Field cancontinue
  2729. Method Reset()
  2730. ' host.SetMode host.DEBUGMODE
  2731. SetStack( New TList )
  2732. ClearMap objmap
  2733. instack=Null
  2734. inscope=Null
  2735. invar=Null
  2736. infile=""
  2737. inexception=""
  2738. sync=0
  2739. firststop=True
  2740. cancontinue=False
  2741. End Method
  2742. Function AddObj:TObj(addr$)
  2743. Local o:TObj = TObj(MapValueForKey( objmap, addr ))
  2744. If o Then
  2745. o.refs:+1
  2746. Else
  2747. o=New TObj
  2748. o.addr=addr
  2749. o.refs=1
  2750. MapInsert objmap, addr, o
  2751. EndIf
  2752. Return o
  2753. End Function
  2754. Function FindObj:TObj(addr$)
  2755. Return TObj(MapValueForKey( objmap, addr ))
  2756. End Function
  2757. Function RemoveObj(obj:TObj) ':TObj
  2758. If obj Then
  2759. obj.refs:-1
  2760. If Not obj.refs Then MapRemove objmap, obj.addr
  2761. EndIf
  2762. End Function
  2763. Method SyncVars()
  2764. sync:+1
  2765. For Local tmpVar:TVar = EachIn kids
  2766. tmpVar.Request()
  2767. Next
  2768. End Method
  2769. Method QueueSync( pObj:TObj )
  2770. If Not pObj Then Return
  2771. 'Sync as soon as the debug pipe is clear
  2772. '(see TOuputPanel.SendDumpRequests()).
  2773. pObj.syncnext = True
  2774. EndMethod
  2775. Method SetStack(list:TList)
  2776. Local openscope:TScope
  2777. Local s:TScope
  2778. Local count,i
  2779. count=kids.count() 'root.varlist.count()
  2780. For Local scope:TScope = EachIn list
  2781. If i>=count
  2782. Append scope 'root.Append scope
  2783. s=scope
  2784. Else
  2785. s=TScope(kids.ValueAtIndex(i))
  2786. ' simon was here
  2787. If s.name=scope.name
  2788. s.SetScope scope
  2789. scope.Free
  2790. Else
  2791. While kids.count()>i
  2792. s=TScope(kids.Last())
  2793. s.free
  2794. Wend
  2795. Append scope
  2796. s=scope
  2797. count=i+1
  2798. EndIf
  2799. EndIf
  2800. If firststop
  2801. If host.IsSourceOpen(s.file) openscope=s
  2802. Else
  2803. openscope=s
  2804. EndIf
  2805. i:+1
  2806. Next
  2807. While kids.count()>i
  2808. s=TScope(kids.Last())
  2809. s.free
  2810. Wend
  2811. If list.IsEmpty() Return
  2812. If Not openscope openscope=TScope(list.First())
  2813. If openscope SelectScope openscope,True
  2814. Refresh
  2815. firststop=False
  2816. End Method
  2817. Method SelectScope(scope:TScope,open)
  2818. If Not scope Return
  2819. host.SetMode host.DEBUGMODE ' simon was here, smoved from reset
  2820. If scope.file host.DebugSource scope.file,scope.line,scope.column
  2821. scope.Open()
  2822. ' If open
  2823. ' SelectTreeViewNode scope.node
  2824. ' scope.open
  2825. ' EndIf
  2826. End Method
  2827. Method ProcessError$(line$)
  2828. Local p
  2829. While p < line.length
  2830. If line[p]=$3E Then p:+1 Else Exit '">"
  2831. Wend
  2832. If p = line.length Return
  2833. If p Then line = line[p..]
  2834. If Not line.StartsWith("~~>") Return line
  2835. line=line[2..]
  2836. If invar
  2837. If line="}"
  2838. SetValue invar 'root
  2839. invar.Free
  2840. invar=Null
  2841. Else
  2842. ' If Not invar.name
  2843. ' invar.name=line
  2844. ' Else
  2845. invar.AddVar line
  2846. ' EndIf
  2847. EndIf
  2848. Return
  2849. EndIf
  2850. If instack
  2851. If line="}"
  2852. SetStack instack
  2853. instack=Null
  2854. inscope=Null
  2855. 'Request first object dumps, and bump sync count
  2856. SyncVars
  2857. If inexception
  2858. Notify inexception
  2859. inexception=""
  2860. EndIf
  2861. Return
  2862. EndIf
  2863. If infile
  2864. If line="Local <local>"
  2865. Else
  2866. inscope=New TScope
  2867. ' Print "inscope.line="+line
  2868. inscope.name=line
  2869. inscope.owner=Self
  2870. instack.AddLast inscope
  2871. EndIf
  2872. If inscope inscope.setfile Self,infile
  2873. infile=""
  2874. Return
  2875. EndIf
  2876. If line.StartsWith("@") And line.Contains("<")
  2877. infile=line[1..]
  2878. Else
  2879. If inscope inscope.AddVar line
  2880. EndIf
  2881. Return
  2882. EndIf
  2883. If line.StartsWith("Unhandled Exception:")
  2884. inexception=line
  2885. host.output.WritePipe "t"
  2886. cancontinue=False
  2887. Return
  2888. EndIf
  2889. If line="StackTrace{"
  2890. instack=New TList
  2891. Return
  2892. EndIf
  2893. If line="Debug:" Or line="DebugStop:"
  2894. host.output.WritePipe "t"
  2895. If Not cancontinue Then
  2896. cancontinue=True
  2897. host.RefreshToolbar()
  2898. EndIf
  2899. Return
  2900. EndIf
  2901. If line.StartsWith("ObjectDump@")
  2902. p=line.find("{",11)
  2903. If p=-1 Return line
  2904. line=line[11..p]
  2905. invar=New TVar
  2906. invar.obj=FindObj(line)
  2907. invar.owner=Self
  2908. Return
  2909. EndIf
  2910. End Method
  2911. Function CreateDebugTree:TDebugTree(host:TCodePlay)
  2912. Local d:TDebugTree = New TDebugTree
  2913. d.owner=d
  2914. d.SetName "{{navtab_debug}}"
  2915. d.host=host
  2916. d.Open
  2917. Return d
  2918. End Function
  2919. End Type
  2920. Type TNodeView
  2921. Field owner:TNavBar
  2922. Field root:TNode
  2923. Field treeview:TGadget
  2924. Field index
  2925. Method NewView()
  2926. Local n:TNode,hnode:TGadget
  2927. hnode=SelectedTreeViewNode(treeview)
  2928. n=root.Find(hnode,index)
  2929. If n And n.parent owner.AddView n
  2930. End Method
  2931. Method OnEvent()
  2932. Local n:TNode = root.Find(TGadget(EventExtra()),index)
  2933. If Not n Return 'probably an eventgadgetselect -1 Notify("could not find in root");Return
  2934. Select EventID()
  2935. Case EVENT_GADGETSELECT
  2936. n.invoke(TOOLSELECT)
  2937. Case EVENT_GADGETACTION
  2938. n.invoke(TOOLACTIVATE)
  2939. Case EVENT_GADGETMENU
  2940. n.invoke(TOOLMENU,Self)
  2941. Case EVENT_GADGETOPEN
  2942. n.open index
  2943. Case EVENT_GADGETCLOSE
  2944. n.close index
  2945. End Select
  2946. End Method
  2947. End Type
  2948. Type TNavBar Extends TEventHandler
  2949. Field host:TCodePlay
  2950. Field tabber:TGadget
  2951. Field viewlist:TList=New TList
  2952. Field selected:TNodeView
  2953. Field navmenu:TGadget
  2954. Method SelectedView()
  2955. If selected Return selected.index
  2956. End Method
  2957. Method SelectView(index)
  2958. Local n:TNodeView
  2959. If index>=viewlist.count() Return
  2960. n=TNodeView(viewlist.ValueAtIndex(index))
  2961. If Not n Print "selectview failed";Return
  2962. If n<>selected
  2963. If selected HideGadget selected.treeview
  2964. selected=n
  2965. EndIf
  2966. ShowGadget n.treeview
  2967. SelectGadgetItem tabber,index
  2968. End Method
  2969. Method AddView(node:TNode)
  2970. Local n:TNodeView
  2971. Local index,root:TGadget
  2972. For n=EachIn viewlist
  2973. If n.root=node SelectView n.index;Return
  2974. Next
  2975. n=New TNodeView
  2976. n.owner=Self
  2977. n.root=node
  2978. n.treeview=CreateTreeView(0,0,ClientWidth(tabber),ClientHeight(tabber),tabber)
  2979. host.options.navstyle.Apply n.treeview
  2980. SetGadgetLayout n.treeview,EDGE_ALIGNED,EDGE_ALIGNED,EDGE_ALIGNED,EDGE_ALIGNED
  2981. HideGadget n.treeview
  2982. n.index=viewlist.Count()
  2983. viewlist.AddLast n
  2984. AddGadgetItem tabber,node.name,GADGETITEM_LOCALIZED
  2985. root=TreeViewRoot(n.treeview)
  2986. node.setnode root,n.index
  2987. SelectView n.index
  2988. Return n.index
  2989. End Method
  2990. Method OnEvent()
  2991. If EventSource()=tabber
  2992. SelectView SelectedGadgetItem(tabber)
  2993. End If
  2994. If selected And EventSource()=selected.treeview
  2995. selected.OnEvent
  2996. EndIf
  2997. End Method
  2998. Method Refresh()
  2999. For Local view:TNodeView = EachIn viewlist
  3000. host.options.navstyle.Apply view.treeview
  3001. Next
  3002. End Method
  3003. Method Invoke(command,argument:Object=Null)
  3004. If command=TOOLREFRESH Refresh()
  3005. If command=TOOLNEWVIEW And selected selected.NewView
  3006. End Method
  3007. Function CreateNavMenu:TGadget()
  3008. Local edit:TGadget = CreateMenu("&Nav",0,Null)
  3009. CreateMenu "&New View",MENUNEWVIEW,edit
  3010. Return edit
  3011. End Function
  3012. Function Create:TNavBar(host:TCodePlay, parent:TGadget) ',root:TNode)
  3013. Local n:TNavBar = New TNavBar
  3014. n.host=host
  3015. n.tabber=CreateTabber(0,0,ClientWidth(parent),ClientHeight(parent),parent)
  3016. SetGadgetLayout(n.tabber,EDGE_ALIGNED,EDGE_ALIGNED,EDGE_ALIGNED,EDGE_ALIGNED)
  3017. ' n.AddView root
  3018. n.navmenu=CreateNavMenu()
  3019. Return n
  3020. End Function
  3021. End Type
  3022. Type TOutputPanel Extends TToolPanel 'used build and run
  3023. Field host:TCodePlay
  3024. Field output:TGadget
  3025. Field process:TProcess
  3026. Field pipe:TStream
  3027. Field wpipe:TTextStream
  3028. Field user$,cmdline$,err$,post$
  3029. Field errbuffer:TByteBuffer
  3030. Field outputmenu:TGadget
  3031. Field posttool:TTool
  3032. Method ClearDumpRequests()
  3033. For Local o:TObj = EachIn MapValues(host.debugtree.objmap)
  3034. o.HasSynced(o.sync)
  3035. Next
  3036. EndMethod
  3037. Method SendDumpRequests()
  3038. For Local o:TObj = EachIn MapValues(host.debugtree.objmap)
  3039. If o.syncnext Then
  3040. If o.addr <> "00000000" Then WritePipe "d"+o.addr
  3041. o.HasSynced( host.debugtree.sync )
  3042. EndIf
  3043. Next
  3044. EndMethod
  3045. Method Clear()
  3046. If Not output Open()
  3047. SetGadgetText output,""
  3048. End Method
  3049. Method WriteAscii(mess$)
  3050. If Not output Open()
  3051. AddTextAreaText output,mess.Replace("~0","")
  3052. End Method
  3053. Method Write(mess$)
  3054. If Not output Open()
  3055. AddTextAreaText output,mess.Replace("~0","")
  3056. End Method
  3057. Method Execute(cmd$,mess$="",exe$="",home=True,owner:TTool=Null)
  3058. If Not output Open()
  3059. If Not mess$ mess$=cmd$
  3060. err$=""
  3061. post$=exe
  3062. posttool=owner
  3063. host.SelectPanel Self
  3064. host.debugtree.Reset
  3065. If process And ProcessStatus(process)
  3066. Delay 500
  3067. If ProcessStatus(process)
  3068. Notify LocalizeString("{{output_notification_stillbusy}}").Replace("%1",cmdline)
  3069. Return
  3070. EndIf
  3071. EndIf
  3072. cmd=cmd.Trim()
  3073. process=CreateProcess(cmd$,HIDECONSOLE)
  3074. If Not process Then Notify LocalizeString("{{output_notification_processfailure}}").Replace("%1",cmd);Return
  3075. If Not process.status() Then Notify LocalizeString("{{output_notification_failedstart}}").Replace("%1",cmd);process=Null;Return
  3076. pipe=Process.pipe
  3077. wpipe=TTextStream.Create(pipe,TTextStream.UTF8)
  3078. cmdline=cmd
  3079. If home Clear
  3080. Write( mess+"~n" )
  3081. errbuffer = New TByteBuffer
  3082. host.RefreshToolbar
  3083. End Method
  3084. Method WritePipe(l$)
  3085. Try
  3086. If pipe pipe.WriteLine(l)
  3087. Catch ex:TStreamWriteException
  3088. Write LocalizeString("{{output_msg_debugfailure}}~n").Replace("%1",l)
  3089. Stop
  3090. EndTry
  3091. End Method
  3092. Method Go()
  3093. WritePipe "r"
  3094. host.debugtree.cancontinue = False
  3095. host.SelectPanel Self
  3096. host.RefreshToolbar()
  3097. End Method
  3098. Method StepOver()
  3099. ClearDumpRequests()
  3100. WritePipe "s"
  3101. End Method
  3102. Method StepIn()
  3103. ClearDumpRequests()
  3104. WritePipe "e"
  3105. End Method
  3106. Method StepOut()
  3107. ClearDumpRequests()
  3108. WritePipe "l"
  3109. End Method
  3110. Method Stop()
  3111. If Not process Return
  3112. process.Terminate()
  3113. FlushPipes process.pipe,process.err
  3114. process.Close()
  3115. process=Null
  3116. Write LocalizeString("~n{{output_msg_processterminated}}~n")
  3117. host.DebugExit()
  3118. Close()
  3119. End Method
  3120. Method Wait()
  3121. While process And process.status()
  3122. PollSystem
  3123. Wend
  3124. End Method
  3125. Method Invoke(command,argument:Object=Null)
  3126. Select command
  3127. Case TOOLSHOW
  3128. host.SetTitle()
  3129. If output ActivateGadget output
  3130. Case TOOLCLOSE
  3131. host.RemovePanel Self
  3132. output=Null
  3133. Case TOOLCUT
  3134. GadgetCut output
  3135. Case TOOLCOPY
  3136. GadgetCopy output
  3137. Case TOOLPASTE
  3138. GadgetPaste output
  3139. Case TOOLSELECTALL
  3140. If output SelectTextAreaText output
  3141. Case TOOLREFRESH
  3142. host.options.outputstyle.apply output
  3143. End Select
  3144. End Method
  3145. Method Close()
  3146. host.SelectPanel host.activepanel
  3147. End Method
  3148. Method Escape()
  3149. Stop
  3150. Close
  3151. End Method
  3152. Function outputfilter(event:TEvent,context:Object)
  3153. Local out:TOutputPanel=TOutputPanel(context)
  3154. If Not out Return
  3155. Select event.id
  3156. Case EVENT_KEYDOWN
  3157. If event.data=27
  3158. out.Escape()
  3159. Return 0
  3160. EndIf
  3161. Case EVENT_KEYCHAR
  3162. ' Print "output_keychar "+event.data
  3163. out.writechar(event.data)
  3164. End Select
  3165. Return 1
  3166. End Function
  3167. Method OnEvent()
  3168. If EventSource()=output
  3169. If EventID()=EVENT_GADGETMENU
  3170. PopupWindowMenu host.window,outputmenu
  3171. EndIf
  3172. EndIf
  3173. ' Case EVENT_TIMERTICK
  3174. If Not process Return
  3175. ReadPipes process.pipe,process.err
  3176. If Not process.status()
  3177. process.terminate
  3178. FlushPipes process.pipe,process.err
  3179. process.close()
  3180. process = Null
  3181. Write LocalizeString("~n{{output_msg_processcomplete}}~n")
  3182. host.DebugExit
  3183. host.SelectPanel Self
  3184. If err
  3185. host.ParseError err
  3186. Else
  3187. If post$
  3188. Local menuaction=Int(post)
  3189. If menuaction
  3190. host.OnMenu menuaction,posttool
  3191. ' Else
  3192. ' Execute post$,"","",False,0
  3193. EndIf
  3194. Else
  3195. If host.options.hideoutput Close()
  3196. EndIf
  3197. EndIf
  3198. EndIf
  3199. End Method
  3200. Method FlushPipes(pipe:TPipeStream,errpipe:TPipeStream)
  3201. ReadPipes(pipe,errpipe)
  3202. Local bytes:Byte[] = errbuffer.flushbytes()
  3203. If bytes
  3204. Local line$=String.FromBytes(bytes,Len bytes)
  3205. line=line.Replace(Chr(13),"")
  3206. If line<>">" Write line
  3207. EndIf
  3208. End Method
  3209. Method ReadPipes(pipe:TPipeStream,errpipe:TPipeStream)
  3210. Local status
  3211. Local bytes:Byte[],line$
  3212. bytes=pipe.ReadPipe()
  3213. If bytes
  3214. line$=String.FromBytes(bytes,Len bytes)
  3215. line=line.Replace(Chr(13),"")
  3216. Write line
  3217. EndIf
  3218. If errpipe.ReadAvail() Then
  3219. errbuffer.WriteFromPipe(errpipe)
  3220. Else
  3221. SendDumpRequests()
  3222. EndIf
  3223. ' If bytes Write String.FromBytes(bytes,bytes.length)
  3224. While errbuffer.LineAvail()
  3225. line$=errbuffer.ReadLine()
  3226. line=host.debugtree.ProcessError(line)
  3227. If line
  3228. Write line+"~n"
  3229. err:+line+"~n"
  3230. EndIf
  3231. Wend
  3232. End Method
  3233. Method WriteChar(char)
  3234. Local pipe:TPipeStream
  3235. If Not process Return
  3236. pipe=process.pipe
  3237. If char=3 'CTRL-C
  3238. Stop()
  3239. EndIf
  3240. If char=13 'ENTER
  3241. ' Write Chr(10)
  3242. pipe.WriteLine user$
  3243. user=""
  3244. EndIf
  3245. If char=8 And user.length 'DELETE
  3246. ' Local pos=TextAreaLen(output)
  3247. ' If pos SetTextAreaText output,"",pos-1,1,TEXTAREA_CHARS
  3248. user=user[..user.length-1]
  3249. EndIf
  3250. If char>31
  3251. ' Write Chr(char)
  3252. user:+Chr(char)
  3253. EndIf
  3254. End Method
  3255. Method Open()
  3256. If output Then
  3257. codeplay.SelectPanel Self
  3258. Return
  3259. EndIf
  3260. codeplay.addpanel(Self)
  3261. output=CreateTextArea(0,0,ClientWidth(panel),ClientHeight(panel),panel,TEXTAREA_WORDWRAP)
  3262. DelocalizeGadget output
  3263. SetGadgetLayout output,EDGE_ALIGNED,EDGE_ALIGNED,EDGE_ALIGNED,EDGE_ALIGNED
  3264. SetGadgetFilter output,outputfilter,Self
  3265. SetGadgetText output," " 'simon was here
  3266. host.options.outputstyle.apply output
  3267. End Method
  3268. Function CreateOutputMenu:TGadget()
  3269. Local edit:TGadget = CreateMenu("{{popup_output}}",0,Null)
  3270. CreateMenu "{{popup_output_cut}}",MENUCUT,edit
  3271. CreateMenu "{{popup_output_copy}}",MENUCOPY,edit
  3272. CreateMenu "{{popup_output_paste}}",MENUPASTE,edit
  3273. CreateMenu "",0,edit
  3274. CreateMenu "{{popup_output_stop}}",MENUSTOP,edit
  3275. Return edit
  3276. End Function
  3277. Function Create:TOutputPanel(host:TCodePlay)
  3278. Local o:TOutputPanel = New TOutputPanel
  3279. o.host=host
  3280. o.name="{{tab_output}}"
  3281. o.outputmenu=CreateOutputMenu()
  3282. ' o.Open
  3283. Return o
  3284. End Function
  3285. End Type
  3286. Type TCodeNode Extends TNode
  3287. Field owner:TOpenCode
  3288. Field pos,count
  3289. 'Field groups:TMap=New TMap
  3290. Method Invoke(command,argument:Object=Null)
  3291. Select command
  3292. Case TOOLACTIVATE
  3293. owner.ShowPos(pos)
  3294. End Select
  3295. End Method
  3296. Method Sync(snap:TNode)
  3297. If snap.name<>name SetName(snap.name)
  3298. Local n:TCodeNode = TCodeNode(snap)
  3299. If n pos=n.pos;count=n.count
  3300. Super.Sync(snap)
  3301. End Method
  3302. Method SetName(n$)
  3303. Local p = n.find("'")
  3304. If p<>-1 n=n[..p]
  3305. name=n.Trim()
  3306. ' If owner.host.options.sortcode
  3307. sortname=n
  3308. End Method
  3309. Method Free()
  3310. owner = Null
  3311. Super.Free()
  3312. End Method
  3313. Method AddCodeNode:TCodeNode(n$,p0,p1)
  3314. Local t$
  3315. Local i:Int = n.find(" ") 'if space then group
  3316. If i>0
  3317. t=n[..i]
  3318. n=n[i+1..]
  3319. Rem
  3320. p=TNode(groups.ValueForKey(t))
  3321. If Not p
  3322. p=AddNode(t+"s")
  3323. p.Open
  3324. groups.insert t,p
  3325. EndIf
  3326. EndRem
  3327. EndIf
  3328. Local c:TCodeNode = New TCodeNode
  3329. c.owner=owner
  3330. c.setname n$
  3331. c.pos=p0
  3332. c.count=p1-p0
  3333. Append(c)
  3334. Return c
  3335. End Method
  3336. End Type
  3337. Type TDiff
  3338. Field pos,count,del$,add$,pos0,count0,pos1,textchange = True
  3339. End Type
  3340. Type TOpenCode Extends TToolPanel
  3341. Global msgHighlightingStatus$ = "Highlighting"
  3342. Field host:TCodePlay
  3343. Field textarea:TGadget
  3344. Field dirty=True
  3345. Field filesrc$,cleansrc$,cleansrcl$
  3346. Field Current:TDiff
  3347. Field undolist:TList=New TList
  3348. Field redolist:TList=New TList
  3349. Field helpcmd$,helpstring$
  3350. Field seek$
  3351. Field cursorpos,cursorlen,cursorline
  3352. Field oldpos,oldlen
  3353. Field isbmx,isc,iscpp,ishtml
  3354. Field deferpos = -1
  3355. Field tidyqueue1 = -1, tidyqueue2 = -1
  3356. Field editmenu:TGadget
  3357. Field codenode:TCodeNode
  3358. Field dirtynode,uc
  3359. Function RefreshHighlightingMsg()
  3360. msgHighlightingStatus = LocalizeString("{{msg_highlightingcode}}")
  3361. EndFunction
  3362. Function IsNotAlpha(c)
  3363. If c<48 Return True
  3364. If c>=58 And c<65 Return True
  3365. If c>=91 And c<95 Return True
  3366. If c>=96 And c<97 Return True
  3367. If c>=123 Return True
  3368. End Function
  3369. Function WordAtPos$(a$,p)
  3370. Local c,q,r,n
  3371. ' string literal
  3372. q=a.findlast(EOL$,a.length-p)
  3373. If q=-1 q=0
  3374. For q=q To p-1
  3375. If a[q]=34 Then
  3376. n=Not n
  3377. r=q
  3378. EndIf
  3379. Next
  3380. If n
  3381. q=a.Find("~q",r+1)+1
  3382. If q=0 q=a.length
  3383. Return a[r..q]
  3384. EndIf
  3385. ' alphanumeric
  3386. p=Min(p,a.length-1) 'simon was here - crash when checking at last char
  3387. For p=p Until 0 Step -1 'simon was here unto->to
  3388. If IsNotAlpha(a$[p]) Continue
  3389. Exit
  3390. Next
  3391. For q=p-1 To 0 Step -1
  3392. If IsNotAlpha(a$[q]) Exit
  3393. Next
  3394. For r=p To a.length-1
  3395. If IsNotAlpha(a$[r]) Exit
  3396. Next
  3397. Return a[q+1..r]
  3398. End Function
  3399. Function FirstDiff(s0$,s1$)
  3400. Local n = Min(s0.length,s1.length)
  3401. For Local i:Int = 0 Until n
  3402. If s0[i]<>s1[i] Return i
  3403. Next
  3404. Return n
  3405. End Function
  3406. Function LastDiff(s0$,s1$)
  3407. Local n = Min(s0.length,s1.length)
  3408. Local i = s0.length-1
  3409. Local j = s1.length-1
  3410. While n>0
  3411. If s0[i]<>s1[j] Exit
  3412. i:-1;j:-1;n:-1
  3413. Wend
  3414. Return i+1
  3415. End Function
  3416. Method parsebmx(n:TCodeNode)
  3417. Local src$,line,col
  3418. Local p,p1,r,t,m,f,l,e
  3419. src=cleansrcl
  3420. p1=src.length
  3421. p=-1;r=-1;t=-1;m=-1;f=-1;l=-1
  3422. While p<p1 'update rem,type,method,function,label pointers
  3423. While r<=p
  3424. r=FindToken("rem",src,r+1)
  3425. Wend
  3426. While t<=p
  3427. t=FindToken("type",src,t+1)
  3428. Wend
  3429. While m<=p
  3430. m=FindToken("method",src,m+1)
  3431. Wend
  3432. While f<=p
  3433. f=FindToken("function",src,f+1)
  3434. Wend
  3435. While l<=p
  3436. l=FindLabel(src,l+1)
  3437. Wend
  3438. If r<t And r<m And r<f And r<l
  3439. p=FindEndToken("rem",src,r+1,True)
  3440. Continue
  3441. EndIf
  3442. p=Min(t,Min(m,Min(f,l)))
  3443. If p=src.length Exit
  3444. While (n And n.parent And p>n.pos+n.count)
  3445. If Not TCodeNode(n.parent)
  3446. If n.parent.parent
  3447. n = TCodeNode(n.parent.parent)
  3448. Else
  3449. n = Null
  3450. EndIf
  3451. Else
  3452. n=TCodeNode(n.parent)
  3453. EndIf
  3454. Wend
  3455. If t<m And t<f And t<l
  3456. e=src.find(EOL,t)
  3457. n=n.AddCodeNode(cleansrc[t..e],t,FindEndToken("type",src,t,True))
  3458. p=t+1
  3459. Continue
  3460. EndIf
  3461. If m<f And m<l
  3462. e=src.find(EOL,m)
  3463. n.AddCodeNode(cleansrc[m..e],m,e)
  3464. p=m+1
  3465. Continue
  3466. EndIf
  3467. If f<l
  3468. e=src.find(EOL,f)
  3469. n.AddCodeNode(cleansrc[f..e],f,e)
  3470. p=f+1
  3471. Continue
  3472. Else
  3473. e=src.find(EOL,l)
  3474. n.AddCodeNode(cleansrc[l..e],l,e)
  3475. p=l+1
  3476. Continue
  3477. EndIf
  3478. Wend
  3479. End Method
  3480. Method GetNode:TNode()
  3481. Local root:TCodeNode = New TCodeNode
  3482. root.name = StripDir(path)
  3483. root.owner = Self
  3484. root.count = cleansrc.length
  3485. If isbmx parsebmx(root) ' stopped code view parse on non bmx files
  3486. If codenode
  3487. If host.options.sortcode root.sortkids
  3488. codenode.Sync(root)
  3489. root.Free()
  3490. Else
  3491. codenode=root
  3492. EndIf
  3493. Return codenode
  3494. End Method
  3495. Method HighlightLine(line,column = 0)
  3496. Local i:Int, tmpCharLineStart% = TextAreaChar(textarea,line)
  3497. Local tmpLine$ = TextAreaText( textarea, line, 1, TEXTAREA_LINES ).Replace("~r","").Replace("~n","")
  3498. For i = column Until tmpLine.length
  3499. If IsNotAlpha(tmpLine[i]) Then tmpCharLineStart:+1 Else Exit
  3500. Next
  3501. SelectTextAreaText textarea,line-1,0,TEXTAREA_LINES
  3502. SelectTextAreaText textarea,line+1,0,TEXTAREA_LINES
  3503. If i = tmpLine.length Or ..
  3504. ( TextAreaCharX( textarea, tmpCharLineStart + tmpLine.length-i ) - TextAreaCharX( textarea, tmpCharLineStart ) >= ClientWidth(textarea) ) Then
  3505. SelectTextAreaText textarea,line,1,TEXTAREA_LINES
  3506. Else
  3507. SelectTextAreaText textarea,tmpCharLineStart,tmpLine.length-i,TEXTAREA_CHARS
  3508. EndIf
  3509. EndMethod
  3510. Method ShowPos(pos)
  3511. host.SelectPanel( Self )
  3512. HighlightLine( TextAreaLine(textarea,pos) )
  3513. UpdateCursor()
  3514. ActivateGadget( textarea )
  3515. End Method
  3516. Method Debug(line,column)
  3517. HighlightLine( line-1 )
  3518. UpdateCursor()
  3519. End Method
  3520. Method Edit()
  3521. SelectTextAreaText( textarea,cursorpos,0,TEXTAREA_CHARS )
  3522. ActivateGadget( textarea )
  3523. UpdateStatus()
  3524. End Method
  3525. Method UpdateStatus()
  3526. Local c = cursorpos+cursorlen
  3527. If cursorline Then c:-TextAreaChar(textarea,cursorline-1)
  3528. host.SetStatus helpstring+"~t~t"+LocalizeString("{{status_line_char}}").Replace("%1",cursorline).Replace("%2",(c+1))
  3529. End Method
  3530. Method UpdateCursor()
  3531. oldpos=cursorpos
  3532. oldlen=cursorlen
  3533. cursorpos=TextAreaCursor(textarea,TEXTAREA_CHARS)
  3534. cursorlen=TextAreaSelLen(textarea,TEXTAREA_CHARS)
  3535. If cursorpos<>oldpos Or cursorlen<>oldlen
  3536. Local l = TextAreaLine(textarea,cursorpos)+1
  3537. If l<>cursorline And dirtynode
  3538. GetNode().Refresh
  3539. dirtynode=False
  3540. If (deferpos>=0) UpdateCode 'SetCode cleansrc
  3541. EndIf
  3542. cursorline=l
  3543. UpdateStatus()
  3544. BracketMatching(cleansrcl)
  3545. If (tidyqueue1 >= 0 Or tidyqueue2 >= 0) Then UpdateCode()
  3546. PollSystem
  3547. EndIf
  3548. End Method
  3549. ' tdiff - pos del$ add$
  3550. Method CalcDiff:TDiff(src$)
  3551. Local d:TDiff
  3552. If src.length<>cleansrc.length
  3553. d=New TDiff
  3554. d.pos0=cursorpos
  3555. d.count0=cursorlen
  3556. d.pos=oldpos
  3557. d.count=oldlen
  3558. If cursorlen And oldlen 'block modified
  3559. d.del=cleansrc[oldpos..oldpos+oldlen]
  3560. d.add=src[oldpos..cursorpos+cursorlen]
  3561. d.pos1=oldpos
  3562. Else
  3563. If cursorpos<=oldpos And cursorlen<=oldlen 'backspace
  3564. d.del=cleansrc[cursorpos..cursorpos+cleansrc.length-src.length]
  3565. d.pos1=cursorpos
  3566. Else 'insert
  3567. d.del=cleansrc[oldpos..oldpos+oldlen]
  3568. d.add=src[oldpos..cursorpos+cursorlen]
  3569. d.pos1=oldpos
  3570. EndIf
  3571. EndIf
  3572. Else
  3573. If cursorpos>oldpos 'overwrite
  3574. d=New TDiff
  3575. d.pos0=cursorpos
  3576. d.count0=cursorlen
  3577. d.pos=oldpos
  3578. d.count=oldlen
  3579. d.del=cleansrc[oldpos..cursorpos]
  3580. d.add=src[oldpos..cursorpos]
  3581. d.pos1=oldpos
  3582. If d.del = d.add Then d.textchange=False
  3583. EndIf
  3584. EndIf
  3585. Return d
  3586. End Method
  3587. Method UpdateCode(makeundo=True)
  3588. Local cpos
  3589. Local src$ = TextAreaText(textarea)
  3590. Local d:TDiff = CalcDiff(src)
  3591. If d
  3592. If makeundo And d.textchange
  3593. undolist.AddLast d
  3594. redolist.Clear
  3595. EndIf
  3596. SetCode src,d
  3597. If d.textchange Then dirtynode=True
  3598. EndIf
  3599. If (deferpos >= 0) Or (tidyqueue1 >= 0) Or (tidyqueue2 >= 0) Then SetCode src
  3600. End Method
  3601. Method Undo()
  3602. Local d:TDiff
  3603. If undolist.IsEmpty() Return
  3604. d=TDiff(undolist.RemoveLast())
  3605. redolist.AddLast d
  3606. SetTextAreaText textarea,d.del,d.pos1,d.add.length
  3607. SelectTextAreaText(textarea,d.pos,d.count)
  3608. SetCode TextAreaText(textarea),d
  3609. UpdateCursor
  3610. End Method
  3611. Method Redo()
  3612. Local d:TDiff
  3613. If redolist.IsEmpty() Return
  3614. d=TDiff(redolist.RemoveLast())
  3615. undolist.AddLast d
  3616. SetTextAreaText textarea,d.add,d.pos,d.del.length
  3617. SelectTextAreaText(textarea,d.pos0,d.count0)
  3618. UpdateCursor
  3619. SetCode TextAreaText(textarea),d
  3620. End Method
  3621. Method RefreshStyle()
  3622. Local rgb:TColor
  3623. Local src$
  3624. Local charwidth
  3625. charwidth=host.options.editfont.CharWidth(32)
  3626. SetTextAreaTabs textarea,host.options.tabsize*charwidth
  3627. SetMargins textarea,4
  3628. SetTextAreaFont textarea,host.options.editfont
  3629. rgb=host.options.editcolor
  3630. SetTextAreaColor textarea,rgb.red,rgb.green,rgb.blue,True
  3631. rgb=host.options.styles[0].color
  3632. SetTextAreaColor textarea,rgb.red,rgb.green,rgb.blue,False
  3633. src=cleansrc
  3634. cleansrc=""
  3635. cleansrcl=""
  3636. cursorpos=0
  3637. SetCode(src)
  3638. End Method
  3639. Function IsntAlphaNumeric(c) 'lowercase test only
  3640. If c<48 Return True
  3641. If c>=58 And c<95 Return True
  3642. If c=96 Return True
  3643. If c>=123 Return True
  3644. End Function
  3645. Function IsntAlphaNumericOrQuote(c) 'lowercase test only
  3646. If c=34 Return False
  3647. If c<48 Return True
  3648. If c>=58 And c<95 Return True
  3649. If c=96 Return True
  3650. If c>=123 Return True
  3651. End Function
  3652. Function IsCode(src$,p)
  3653. Local n
  3654. Local l = src.FindLast(EOL$,src.length-p)
  3655. If l=-1 l=0
  3656. Local q = src.Find("'",l)
  3657. If q<>-1 And q<p Return
  3658. q=l
  3659. While q<p
  3660. q=src.Find(QUOTES$,q)+1
  3661. If q=0 Exit
  3662. If q<=p n:+1
  3663. Wend
  3664. Return Not(n&1)
  3665. End Function
  3666. Function FindLabel(src$,pos)
  3667. Local p,q,c
  3668. While pos>=0
  3669. p=src.Find("#",pos)
  3670. If p=-1 Exit
  3671. q=p
  3672. While q>0
  3673. q:-1
  3674. c=src[q]
  3675. If c=13 Return p
  3676. If c=10 Return p
  3677. If c=32 Or c=9 Continue
  3678. Exit
  3679. Wend
  3680. If q<0 Return p
  3681. pos=p+1
  3682. Wend
  3683. Return src.length
  3684. End Function
  3685. Function FindToken(token$,src$,pos) 'lowercase src only!
  3686. Local p,c
  3687. Local n=token.length
  3688. While pos>=0
  3689. p=src.Find(token,pos)
  3690. If p=-1 Exit
  3691. c=10 If p>0 c=src[p-1]
  3692. If isntalphanumeric(c)
  3693. If p+n<src.length c=src[p+n]
  3694. If isntalphanumeric(c)
  3695. If iscode(src,p)
  3696. If p<4 Or src[p-4..p]<>"end " Return p
  3697. EndIf
  3698. EndIf
  3699. EndIf
  3700. pos=p+1
  3701. Wend
  3702. Return src.length
  3703. End Function
  3704. Function FindEndToken(token$,src$,pos,returnlast=False) 'if true returns first character after endtoken
  3705. Local p,q,e$,n
  3706. p=pos
  3707. e$="end"+token
  3708. n=e.length
  3709. While p<src.length
  3710. p=src.Find(e$,p)
  3711. If p=-1 Exit
  3712. If p+n=src.length Or isntalphanumeric(src[p+n])
  3713. If iscode(src,p)
  3714. If p=0 Or isntalphanumeric(src[p-1]) Exit
  3715. EndIf
  3716. EndIf
  3717. p=p+n
  3718. Wend
  3719. If p=-1 p=src.length Else If returnlast p:+n
  3720. q=pos
  3721. e$="end "+token
  3722. n=e.length
  3723. While q<src.length
  3724. q=src.Find(e$,q)
  3725. If q=-1 Exit
  3726. If q+n=src.length Or isntalphanumeric(src[q+n])
  3727. If iscode(src,q)
  3728. If q=0 Or isntalphanumeric(src[q-1]) Exit
  3729. EndIf
  3730. EndIf
  3731. q=q+n
  3732. Wend
  3733. If q=-1 q=src.length Else If returnlast q:+n
  3734. Return Min(p,q)
  3735. End Function
  3736. Function IsFirstCharOnLine(src$,pos)
  3737. Local c
  3738. For Local i:Int = 1 To pos
  3739. c=src[pos-i]
  3740. If c=10 Or c=13 Return True
  3741. If c>32 Return False
  3742. Next
  3743. Return True
  3744. End Function
  3745. ' rem and endrem must be first nonwhitespace on line - following funcs are for lowercase src only
  3746. Function FindRem(src$,pos)
  3747. While pos<src.length
  3748. pos=FindToken("rem",src,pos)
  3749. If pos=src.length Exit
  3750. If IsFirstCharOnLine(src,pos) Return pos
  3751. pos:+1
  3752. Wend
  3753. Return pos
  3754. End Function
  3755. Function FindEndRem(src$,pos,returnlast=False)
  3756. Local i,c
  3757. While pos<src.length
  3758. pos=FindEndToken("rem",src,pos)
  3759. If pos=src.length Exit
  3760. If IsFirstCharOnLine(src,pos)
  3761. If returnlast
  3762. If src[pos+5]=Asc("e") Or src[pos+5]=Asc("E") pos:+1
  3763. pos:+6
  3764. EndIf
  3765. Return pos
  3766. EndIf
  3767. pos:+1
  3768. Wend
  3769. Return src.length
  3770. End Function
  3771. Function FindPrevRem(src$,pos) 'lowercase src only!
  3772. Local p,c
  3773. While pos>0
  3774. If pos>src.length Exit 'fixed endrem on lastline overrun
  3775. p=src.FindLast("rem",src.length-pos)
  3776. If p=-1 Exit
  3777. If isntalphanumeric(src[p+3]) And IsFirstCharOnLine(src,p) Return p
  3778. pos=p-1
  3779. Wend
  3780. Return -1
  3781. End Function
  3782. Method IsRemmed(pos,src$)
  3783. Local p = FindPrevRem(src$,Min(pos+3,src.length))
  3784. If p<0 Return
  3785. p=FindEndRem(src$,p)
  3786. If p<0 Or pos<p Return True
  3787. EndMethod
  3788. Method WasRemmed(pos,src$)
  3789. Local s$ = cleansrcl
  3790. Local p = (src.length-s.length)
  3791. If p<0 pos:-p
  3792. p=FindPrevRem(s$,Min(pos+3,s.length))
  3793. If p<0 Return
  3794. p=FindEndRem(s$,p)
  3795. If pos<p Return True
  3796. End Method
  3797. Method CheckDirty(src$)
  3798. SetDirty (Not (src=filesrc And undolist.IsEmpty()))
  3799. End Method
  3800. Method HasTidyQueue()
  3801. Return ((deferpos >= 0) Or (tidyqueue1 >= 0) Or (tidyqueue2 >= 0))
  3802. EndMethod
  3803. Method ClearTidyQueue(start,endpos)
  3804. If start<=deferpos And deferpos < endpos Then deferpos = -1
  3805. If start<=tidyqueue1 And tidyqueue1 < endpos Then tidyqueue1 = -1
  3806. If start<=tidyqueue2 And tidyqueue2 < endpos Then tidyqueue2 = -1
  3807. EndMethod
  3808. Method SetCode(src$,diff:TDiff=Null)
  3809. Local same,i,p,startp,p1,q,r,a,t$,h$,lsrc$,r0,r1,cpos,autocap
  3810. Local style:TTextStyle[5],s:TTextStyle
  3811. ' update dirty flag
  3812. CheckDirty src
  3813. same = Not ((diff) Or (src<>cleansrc))
  3814. If same And Not (diff Or HasTidyQueue()) Then Return
  3815. If Not isbmx Or Not host.quickhelp Or Not host.options.syntaxhighlight
  3816. If Not same Then
  3817. cleansrc=src
  3818. cleansrcl=src.ToLower()
  3819. EndIf
  3820. Return
  3821. EndIf
  3822. ' doit
  3823. autocap=host.options.autocapitalize
  3824. If same Then lsrc = cleansrcl Else lsrc=src.ToLower()
  3825. cpos=TextAreaCursor(textarea,TEXTAREA_CHARS)
  3826. LockTextArea textarea
  3827. style=host.options.styles
  3828. ' calculate highlight region
  3829. If diff
  3830. p=diff.pos
  3831. p1=p+diff.add.length
  3832. If Not diff.add.length Then
  3833. p:-diff.del.length
  3834. EndIf
  3835. ElseIf HasTidyQueue()
  3836. p=src.length
  3837. If (deferpos>=0) Then
  3838. p = Min(p,deferpos)
  3839. p1 = Max(p1,deferpos+1)
  3840. EndIf
  3841. If (tidyqueue1>=0) Then
  3842. p = Min(p,tidyqueue1)
  3843. p1 = Max(p1, tidyqueue1+1)
  3844. EndIf
  3845. If (tidyqueue2>=0) Then
  3846. p = Min(p,tidyqueue2)
  3847. p1 = Max(p1, tidyqueue2+1)
  3848. EndIf
  3849. Else
  3850. p=firstdiff(src,cleansrc)
  3851. p1=lastdiff(src,cleansrc)
  3852. EndIf
  3853. q=src.length-cleansrc.length
  3854. If p1-p<q p1=p+q
  3855. If p1<p p1=p
  3856. ' round region to line breaks
  3857. 'Print "p="+p+" p1="+p1
  3858. If p>src.length p=src.length
  3859. p=src.findlast(EOL,src.length-(p-1))+1
  3860. p1=src.find(EOL,p1)+1
  3861. If p1=0 p1=src.length
  3862. ' if endrem between p0,p1 and next rem after p1 move p1 forwards
  3863. r1=FindEndRem(lsrc,p)
  3864. If r1<p1 And wasremmed(r1+6,lsrc)
  3865. r0=FindRem(lsrc,r1+6)
  3866. If r0>p1 p1=r0
  3867. EndIf
  3868. ' if rem between p0,p1 and matching endrem after p1 move p1 forewards
  3869. r0=FindPrevRem(lsrc,p1)
  3870. If r0>=p And r0+3<>cpos 'defer fix
  3871. r1=FindEndRem(lsrc,r0,True)
  3872. If r1>p1 p1=r1
  3873. EndIf
  3874. ' if rem before p0 and matching endrem after p0 highlight to endrem and move p0 forwards
  3875. r0=FindPrevRem(lsrc,p)
  3876. If r0<>-1 And r0<p
  3877. r1=FindEndRem(lsrc,r0,True)
  3878. If r1>p
  3879. s=style[COMMENT]
  3880. If r1>p s.Format(textarea,p,r1-p)
  3881. If autocap And r1<src.length
  3882. If lsrc[r1-6..r1]="endrem" And src[r1-6..r1]<>"EndRem" SetTextAreaText textarea,"EndRem",r1-6,6
  3883. If lsrc[r1-7..r1]="end rem" And src[r1-7..r1]<>"End Rem" SetTextAreaText textarea,"End Rem",r1-7,7
  3884. EndIf
  3885. ClearTidyQueue(p,r1)
  3886. p=r1
  3887. EndIf
  3888. EndIf
  3889. ' if was remmed and now isn't move p1 down to nearest rem or endrem
  3890. If WasRemmed(p,lsrc)
  3891. r0=FindRem(lsrc,p)
  3892. r1=FindEndRem(lsrc,r0,True)
  3893. p1=Max(p1,Min(r0,r1))
  3894. EndIf
  3895. ' highlight code
  3896. ClearTidyQueue(p,p1)
  3897. s=style[NORMAL]
  3898. If p1>p s.format(textarea,p,p1-p)
  3899. startp = p
  3900. While p<p1
  3901. host.UpdateProgress(msgHighlightingStatus,(p*100)/p1)
  3902. a=src[p]
  3903. ' quoted strings
  3904. If a=34
  3905. q=p1
  3906. r=src.Find(Chr(34),p+1)
  3907. If r>-1 And r<q q=r+1
  3908. r=src.Find(EOL,p+1)
  3909. If r>-1 And r<q q=r
  3910. s=style[QUOTED]
  3911. s.format(textarea,p,q-p)
  3912. p=q
  3913. Continue
  3914. EndIf
  3915. ' single line comments
  3916. If a=39
  3917. q=p1
  3918. r=src.Find(EOL,p+1)
  3919. If r>-1 And r<q q=r
  3920. s=style[COMMENT]
  3921. s.format(textarea,p,q-p)
  3922. p=q
  3923. Continue
  3924. EndIf
  3925. ' tokens
  3926. If (a>=65 And a<91) Or (a>=97 And a<123) Or (a=95)
  3927. q=p+1
  3928. While q<p1
  3929. a=src[q]
  3930. If a<48 Exit 'changed to include dot (chr 47)
  3931. If a>=58 And a<65 Exit
  3932. If a>=91 And a<95 Exit
  3933. If a=96 Exit
  3934. If a>122 Exit
  3935. q:+1
  3936. Wend
  3937. t$=src[p..q]
  3938. h$=host.quickhelp.token(t$)
  3939. If h$
  3940. If h$<>t$ And autocap
  3941. If cpos<p Or cpos>q
  3942. SetTextAreaText textarea,h,p,h.length
  3943. Else
  3944. deferpos=q
  3945. EndIf
  3946. EndIf
  3947. s=style[KEYWORD]
  3948. If h$="Rem" And IsFirstCharOnLine(lsrc,p) ' Not (p>4 And lsrc[p-4..p]="end ")
  3949. If q<>cpos
  3950. q=FindEndRem(lsrc,p,True)
  3951. s=style[COMMENT]
  3952. Else
  3953. deferpos=q
  3954. EndIf
  3955. EndIf
  3956. s.format(textarea,p,q-p)
  3957. EndIf
  3958. p=q
  3959. Continue
  3960. EndIf
  3961. ' numbers
  3962. 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, $, %, .
  3963. q=p+1
  3964. Local hexed:Int = (a=$24), binaried:Int = (a=$25), dots:Int = (a=$2E)
  3965. Local valid:Int = Not(hexed Or binaried Or dots)
  3966. While q<(p1)
  3967. a=lsrc[q]
  3968. q:+1
  3969. If (a>=$30 And a<$3A) Then
  3970. valid = True
  3971. Continue '0-9
  3972. EndIf
  3973. If hexed
  3974. If (a>=$61 And a<$67) Then 'a-f (only test lower as 'a' var is from lsrc)
  3975. valid = True
  3976. Continue
  3977. EndIf
  3978. EndIf
  3979. If (a=$2E) Then
  3980. 'Hex or Binary literals don't support decimal points
  3981. If Not (hexed Or binaried) Then
  3982. dots:+1
  3983. 'Fix for slicing '..' syntax
  3984. If src[q-2] = $2E Then
  3985. dots:-2
  3986. q:-2
  3987. Exit
  3988. EndIf
  3989. 'End Fix
  3990. Continue
  3991. EndIf
  3992. EndIf
  3993. If Not IsntAlphaNumeric(a) Then valid = False
  3994. q:-1
  3995. Exit
  3996. Wend
  3997. If valid And dots < 2 Then style[NUMBER].format(textarea,p,(q-p))
  3998. 'Fix for slicing '..' syntax
  3999. If q<src.length And (src[q]=Asc(".")) Then q:+1
  4000. If q<src.length And (src[q]=Asc(".")) Then q:+1
  4001. 'End Fix
  4002. p=q
  4003. Continue
  4004. EndIf
  4005. p:+1
  4006. Wend
  4007. BracketMatching(lsrc,startp,p1,True)
  4008. UnlockTextArea textarea
  4009. If Not same
  4010. cleansrc=src
  4011. cleansrcl=lsrc
  4012. EndIf
  4013. ' CheckDirty src simon was here
  4014. End Method
  4015. Field currentbrackets:Int[]
  4016. Method BracketMatching(lsrc$,cln1=-1,cln2=-1,alwaysfind:Int = False)
  4017. Local check:Int, depth:Int, style:TTextStyle[] = host.options.styles
  4018. Local otherchar:Int = 0, absotherchar:Int = 0, othercharpos:Int = 0, limit:Int
  4019. Local currentchar:Int = 0, currentcharpos:Int = Max(cursorpos-1,0)
  4020. If cursorlen Then Return
  4021. If currentbrackets Then
  4022. If Not(cln2 > currentbrackets[0] And cln1 <= currentbrackets[0]) Then
  4023. If currentbrackets[0]>-1 Then tidyqueue1 = currentbrackets[0]
  4024. EndIf
  4025. If Not(cln2 > currentbrackets[1] And cln1 <= currentbrackets[1]) Then
  4026. If currentbrackets[1]>-1 Then tidyqueue2 = currentbrackets[1]
  4027. EndIf
  4028. currentbrackets = Null
  4029. If Not alwaysfind Then Return
  4030. EndIf
  4031. If host.options.bracketmatching And isbmx And Not IsRemmed(currentcharpos,lsrc) Then
  4032. limit = Min(lsrc.length,currentcharpos+2)
  4033. While currentcharpos >= 0 And currentcharpos < limit
  4034. If IsCode(lsrc,currentcharpos) Then
  4035. Select lsrc[currentcharpos]
  4036. Case Asc("(");otherchar = Asc(")");Exit
  4037. Case Asc("{");otherchar = Asc("}");Exit
  4038. Case Asc("[");otherchar = Asc("]");Exit
  4039. ' Negate char code to search backwards
  4040. Case Asc(")");otherchar = -Asc("(");Exit
  4041. Case Asc("}");otherchar = -Asc("{");Exit
  4042. Case Asc("]");otherchar = -Asc("[");Exit
  4043. EndSelect
  4044. EndIf
  4045. currentcharpos:+1
  4046. Wend
  4047. If otherchar Then
  4048. absotherchar = (Abs otherchar)
  4049. currentchar = lsrc[currentcharpos]
  4050. LockTextArea textarea
  4051. style[MATCHING].format(textarea, currentcharpos, 1)
  4052. currentbrackets = [currentcharpos,-1]
  4053. othercharpos = currentcharpos+(otherchar/absotherchar)
  4054. While othercharpos < lsrc.length And othercharpos >= 0
  4055. If IsCode(lsrc,othercharpos) Then
  4056. Select lsrc[othercharpos]
  4057. Case Asc(" "), Asc("~t")
  4058. 'Do nothing
  4059. Case Asc("'")
  4060. Exit
  4061. Case absotherchar
  4062. If check < 0 Then Exit Else check = 0
  4063. If depth Then
  4064. depth:-1
  4065. Else
  4066. style[MATCHING].format(textarea, othercharpos, 1)
  4067. currentbrackets[1] = othercharpos
  4068. UnlockTextArea textarea
  4069. Return
  4070. EndIf
  4071. Case Asc("~n")
  4072. If (otherchar/absotherchar) > 0 Then
  4073. If check = 2 Then check = 0 Else Exit
  4074. Else
  4075. If check < 0 Then Exit Else check = -2
  4076. EndIf
  4077. Case Asc(".")
  4078. check:+1
  4079. Default
  4080. If check < 0 Then Exit Else check = 0
  4081. If lsrc[othercharpos] = lsrc[currentcharpos] Then depth:+1
  4082. EndSelect
  4083. EndIf
  4084. othercharpos:+(otherchar/absotherchar)
  4085. Wend
  4086. UnlockTextArea textarea
  4087. EndIf
  4088. EndIf
  4089. EndMethod
  4090. Method AutoIndent()
  4091. Local p,q
  4092. Local c = TextAreaCursor(textarea,TEXTAREA_CHARS)
  4093. Local n = TextAreaSelLen(textarea,TEXTAREA_CHARS)
  4094. If c<cleansrc.length
  4095. p=cleansrc.FindLast(EOL,cleansrc.length-(c-1))+1
  4096. q=p
  4097. While cleansrc[q]=9 And q<c
  4098. q:+1
  4099. Wend
  4100. If q>c q=c
  4101. EndIf
  4102. SetTextAreaText textarea,EOL$+cleansrc[p..q],c,n
  4103. SelectTextAreaText textarea,c+1+q-p,0
  4104. UpdateCursor
  4105. UpdateCode
  4106. End Method
  4107. Method IndentCode()
  4108. Local a$
  4109. ' blockindent
  4110. Local p0 = TextAreaCursor(textarea,TEXTAREA_LINES)
  4111. Local p1 = TextAreaSelLen(textarea,TEXTAREA_LINES)
  4112. ' v122: make sure the entire block is selected (start cursor pos may in the middle of the line)
  4113. SelectTextAreaText textarea , p0 , p1 , TEXTAREA_LINES
  4114. UpdateCursor
  4115. For Local i:Int = 0 Until p1
  4116. a$="~t"+TextAreaText(textarea,p0+i,1,TEXTAREA_LINES)
  4117. SetTextAreaText textarea,a$,p0+i,1,TEXTAREA_LINES
  4118. Next
  4119. SelectTextAreaText textarea,p0,p1,TEXTAREA_LINES
  4120. UpdateCursor
  4121. UpdateCode
  4122. End Method
  4123. Method OutdentCode()
  4124. Local a$,modified
  4125. ' blockoutdent
  4126. Local p0 = TextAreaCursor(textarea,TEXTAREA_LINES)
  4127. Local p1 = TextAreaSelLen(textarea,TEXTAREA_LINES)
  4128. ' v122: make sure the entire block is selected (start cursor pos may in the middle of the line)
  4129. SelectTextAreaText textarea , p0 , p1 , TEXTAREA_LINES
  4130. UpdateCursor
  4131. For Local i:Int = 0 Until p1
  4132. a$=TextAreaText(textarea,p0+i,1,TEXTAREA_LINES)
  4133. If a[0]=9 a$=a$[1..];modified=True
  4134. SetTextAreaText textarea,a$,p0+i,1,TEXTAREA_LINES
  4135. Next
  4136. If Not modified
  4137. For Local i:Int = 0 Until p1
  4138. a$=TextAreaText(textarea,p0+i,1,TEXTAREA_LINES)
  4139. If a[0]=32 a$=a$[1..]
  4140. SetTextAreaText textarea,a$,p0+i,1,TEXTAREA_LINES
  4141. Next
  4142. EndIf
  4143. SelectTextAreaText textarea,p0,p1,TEXTAREA_LINES
  4144. UpdateCursor
  4145. UpdateCode
  4146. End Method
  4147. Function FilterKey(event:TEvent,context:Object)
  4148. ' If event.id<>EVENT_KEYCHAR Return 1
  4149. Local id=event.id
  4150. Local key=event.data
  4151. Local mods=event.mods
  4152. Local this:TOpenCode=TOpenCode(context)
  4153. ?MacOS
  4154. If key=25 And mods=MODIFIER_SHIFT key=KEY_TAB
  4155. ?
  4156. If id=EVENT_KEYCHAR And this And key=KEY_TAB And TextAreaSelLen( this.textarea,TEXTAREA_CHARS )
  4157. Select mods
  4158. Case MODIFIER_NONE
  4159. this.IndentCode
  4160. Case MODIFIER_SHIFT
  4161. this.OutdentCode
  4162. End Select
  4163. Return 0
  4164. EndIf
  4165. If id=EVENT_KEYDOWN And key=KEY_ENTER And this And this.host.options.autoindent
  4166. this.AutoIndent()
  4167. Return 0
  4168. EndIf
  4169. Return 1
  4170. End Function
  4171. Method OnEvent()
  4172. Select EventSource()
  4173. Case textarea
  4174. Select EventID()
  4175. Case EVENT_GADGETMENU
  4176. PopupWindowMenu host.window,editmenu
  4177. Case EVENT_GADGETACTION
  4178. UpdateCode
  4179. Case EVENT_GADGETSELECT
  4180. UpdateCursor
  4181. End Select
  4182. End Select
  4183. End Method
  4184. Method SetDirty( bool )
  4185. If dirty=bool Return
  4186. dirty=bool
  4187. name=StripDir(path)
  4188. If (dirty) name:+"*"
  4189. If (host.lockedpanel=Self) name=LocalizeString("{{tab_locked:%1}}").Replace("%1",name)
  4190. host.RefreshPanel Self
  4191. PollSystem
  4192. End Method
  4193. Method SetLocked( bool )
  4194. Local locked:TOpenCode = TOpenCode(host.lockedpanel)
  4195. If locked And locked<>Self locked.SetLocked False
  4196. name=StripDir(path)
  4197. If (dirty) name:+"*"
  4198. If (bool)
  4199. name=LocalizeString("{{tab_locked:%1}}").Replace("%1",name)
  4200. host.lockedpanel=Self
  4201. Else
  4202. host.lockedpanel=Null
  4203. EndIf
  4204. host.RefreshPanel Self
  4205. End Method
  4206. Method Help()
  4207. If Not host.quickhelp Return
  4208. Local p = TextAreaCursor(textarea,TEXTAREA_CHARS)
  4209. Local a$ = WordAtPos(cleansrc,p)
  4210. If a=helpcmd
  4211. Local l$ = host.quickhelp.link(a$)
  4212. If l
  4213. host.helppanel.go host.bmxpath+l$
  4214. EndIf
  4215. Else
  4216. helpcmd=a$
  4217. helpstring$=host.quickhelp.help(a$)
  4218. UpdateStatus 'host.setstatus helpstring$
  4219. EndIf
  4220. End Method
  4221. Method Find()
  4222. host.findreq.ShowFind WordAtPos(cleansrc,TextAreaCursor(textarea,TEXTAREA_CHARS))
  4223. End Method
  4224. Method FindNext(s$)
  4225. If s seek=s Else s=seek
  4226. Local p = TextAreaCursor(textarea,TEXTAREA_CHARS)
  4227. p:+TextAreaSelLen(textarea,TEXTAREA_CHARS)
  4228. ' case insensitive
  4229. Local l$ = s.toLower()
  4230. p=cleansrcl.Find(l$,p)
  4231. If p=-1 p=cleansrcl.Find(l$)
  4232. ' case sensitive
  4233. ' p=cleansrc.Find(s$,p+1)
  4234. ' if p=-1 p=cleansrc.Find(s$)
  4235. If p=-1
  4236. Notify LocalizeString("{{find_notification_cannotfind}}").Replace("%1",s)
  4237. Return False
  4238. Else
  4239. SelectTextAreaText textarea,p,Len s,TEXTAREA_CHARS
  4240. UpdateCursor
  4241. Return True
  4242. EndIf
  4243. End Method
  4244. Method ReplaceAll(s$,r$)
  4245. Local t$ = TextAreaText( textarea ).ToLower()
  4246. Local c = TextAreaCursor(textarea,TEXTAREA_CHARS),i,p
  4247. s = s.ToLower()
  4248. Repeat
  4249. Local i2=t.Find( s,i )
  4250. If i2=-1 Exit
  4251. p:+i2-i
  4252. i=i2+s.length
  4253. SelectTextAreaText textarea,p,s.length
  4254. UpdateCursor
  4255. UpdateCode
  4256. SetTextAreaText textarea,r,p,s.length
  4257. If p<c c=c+r.length-s.length
  4258. p:+r.length
  4259. SelectTextAreaText textarea,p,0
  4260. UpdateCursor
  4261. UpdateCode
  4262. Forever
  4263. SelectTextAreaText textarea,c,0
  4264. UpdateCursor
  4265. End Method
  4266. Method FindReplace(r$)
  4267. Local n, f$, x$
  4268. Local p = r.Find("~0")
  4269. If p>0
  4270. f$=r[..p]
  4271. r$=r[p+1..]
  4272. ReplaceAll f$,r$
  4273. Else
  4274. p=TextAreaCursor(textarea,TEXTAREA_CHARS)
  4275. n=TextAreaSelLen(textarea,TEXTAREA_CHARS)
  4276. If Not n Return
  4277. SetTextAreaText textarea,r$,p,n
  4278. SelectTextAreaText textarea,p+r.length,0
  4279. UpdateCursor
  4280. UpdateCode
  4281. EndIf
  4282. Return True
  4283. End Method
  4284. Method ReadSource(path$)
  4285. Local src$
  4286. src=CacheAndLoadText(path)
  4287. src=src.Replace(Chr(13),"")
  4288. src=src.Replace(Chr(11),"")
  4289. LockTextArea textarea
  4290. SetTextAreaText textarea,src
  4291. UnlockTextArea textarea
  4292. filesrc=TextAreaText(textarea)
  4293. cleansrc=""
  4294. cleansrcl=""
  4295. ActivateGadget textarea
  4296. End Method
  4297. Method SaveSource(file$)
  4298. If host.options.autobackup
  4299. DeleteFile file+".bak"
  4300. RenameFile file,file+".bak"
  4301. EndIf
  4302. Local src$ = TextAreaText(textarea)
  4303. filesrc=src
  4304. src=src.Replace(Chr(13),Chr(10))
  4305. src=src.Replace(Chr(11),"")
  4306. Local txt$ = src.Replace$(Chr(10),Chr(13)+Chr(10))
  4307. Try
  4308. SaveText txt,file
  4309. Catch exception:Object
  4310. Local err$=String(exception)
  4311. Notify "Save Error~n"+err
  4312. Return False
  4313. EndTry
  4314. path=host.FullPath$(file)
  4315. dirty=True
  4316. SetDirty False
  4317. host.AddRecent(path$)
  4318. Return True
  4319. End Method
  4320. Method BuildSource(quick,debug,threaded,gui,run)
  4321. Local cmd$,out$,arg$
  4322. If isbmx Or isc Or iscpp
  4323. cmd$=quote(host.bmkpath)
  4324. cmd$:+" makeapp"
  4325. If run cmd$:+" -x"
  4326. If debug cmd$:+" -d" Else cmd$:+" -r" '-v
  4327. If threaded cmd$:+" -h"
  4328. If gui cmd$:+" -t gui"
  4329. If Not quick cmd$:+" -a"
  4330. If debug Or threaded
  4331. out=StripExt(host.FullPath(path))
  4332. If debug out:+".debug"
  4333. If threaded out:+".mt"
  4334. cmd:+" -o "+quote(out$)+" "
  4335. EndIf
  4336. cmd$:+" "+quote(host.FullPath(path))
  4337. If run
  4338. arg$=host.GetCommandLine()
  4339. If arg cmd$:+" "+arg
  4340. EndIf
  4341. host.execute cmd,"Building "+StripExt(StripDir(path)) ',exe$
  4342. Else
  4343. If ishtml
  4344. host.helppanel.Go "file://"+path
  4345. Else
  4346. 'see what the system shell thinks of the file
  4347. Local cd$=CurrentDir()
  4348. ChangeDir ExtractDir(path)
  4349. cmd=StripDir(path)
  4350. host.execute cmd,"Building "+cmd
  4351. ChangeDir cd
  4352. EndIf
  4353. EndIf
  4354. ' print cmd
  4355. End Method
  4356. Method Save()
  4357. Local file$ = path
  4358. If host.IsTempPath(path)
  4359. file=RequestFile(LocalizeString("{{request_saveas_title}}"),FileTypeFilters,True,"")
  4360. If file="" Return False
  4361. If ExtractExt(file)="" file=file+".bmx"
  4362. dirty=True
  4363. EndIf
  4364. If dirty SaveSource(file)
  4365. Return True
  4366. End Method
  4367. ' common command interface
  4368. Method Invoke(command,argument:Object=Null)
  4369. Local file$,ex$
  4370. Local p,res
  4371. Select command
  4372. Case TOOLSHOW
  4373. host.SetCodeNode GetNode()
  4374. host.SetTitle path
  4375. ' simon was here If textarea Edit
  4376. If textarea ActivateGadget textarea
  4377. Case TOOLCLOSE
  4378. If dirty 'Or host.IsTempPath(path)
  4379. Invoke(TOOLSHOW)
  4380. p=Proceed(LocalizeString("{{request_savechanges}}").Replace("%1",name)) 'the current file?
  4381. If p=-1 Return True
  4382. If p=1
  4383. If Not Save() Return True
  4384. EndIf
  4385. EndIf
  4386. If codenode Then
  4387. codenode.Free()
  4388. codenode=Null
  4389. EndIf
  4390. 'Added just in case MaxGUI driver doesn't handle properly.
  4391. SetGadgetFilter textarea,Null,Null
  4392. 'Seb gone.
  4393. host.RemovePanel Self
  4394. FreeGadget(editmenu)
  4395. Case TOOLSAVE
  4396. Save
  4397. Case TOOLQUICKSAVE
  4398. file=path
  4399. If dirty SaveSource(file)
  4400. Case TOOLSAVEAS
  4401. file=path
  4402. If host.IsTempPath(path) file$=""
  4403. file=RequestFile(LocalizeString("{{request_saveas_title}}"),FileTypeFilters,True,file)
  4404. If file="" Return
  4405. ex$=ExtractExt(file)
  4406. If ex$=""
  4407. file=file+".bmx"
  4408. isbmx=True
  4409. Else
  4410. isbmx=(ex.ToLower()="bmx")
  4411. ishtml=(ex.ToLower()="html")
  4412. isc=(ex.ToLower()="c")
  4413. iscpp=(ex.ToLower()="cpp" Or ex.ToLower()="cxx")
  4414. EndIf
  4415. SaveSource(file$)
  4416. RefreshStyle()
  4417. GetNode().Refresh
  4418. SetDirty False
  4419. host.SetTitle path
  4420. Case TOOLGOTO
  4421. Local line=Int(String(argument))
  4422. SelectTextAreaText textarea,line-1,0,TEXTAREA_LINES
  4423. UpdateCursor
  4424. ActivateGadget textarea
  4425. Case TOOLFIND
  4426. Find
  4427. Case TOOLFINDNEXT
  4428. Return FindNext(String(argument))
  4429. Case TOOLREPLACE
  4430. Return FindReplace(String(argument))
  4431. Case TOOLBUILD
  4432. BuildSource host.quickenabled,host.debugenabled,host.threadedenabled,host.guienabled,False
  4433. Case TOOLRUN
  4434. BuildSource host.quickenabled,host.debugenabled,host.threadedenabled,host.guienabled,True
  4435. Case TOOLLOCK
  4436. SetLocked True
  4437. Case TOOLUNLOCK
  4438. SetLocked False
  4439. Case TOOLHELP
  4440. Help()
  4441. Case TOOLUNDO
  4442. Undo()
  4443. Case TOOLREDO
  4444. Redo()
  4445. Case TOOLREFRESH
  4446. RefreshStyle()
  4447. Case TOOLCUT
  4448. GadgetCut textarea
  4449. UpdateCursor()
  4450. UpdateCode()
  4451. Case TOOLCOPY
  4452. GadgetCopy textarea
  4453. Case TOOLPASTE
  4454. GadgetPaste textarea
  4455. UpdateCursor()
  4456. UpdateCode()
  4457. Case TOOLSELECTALL
  4458. SelectTextAreaText textarea
  4459. UpdateCursor()
  4460. Case TOOLINDENT
  4461. IndentCode()
  4462. Case TOOLOUTDENT
  4463. OutdentCode()
  4464. Case TOOLPRINT
  4465. GadgetPrint textarea
  4466. End Select
  4467. End Method
  4468. Function CreateEditMenu:TGadget()
  4469. Local edit:TGadget = CreateMenu("{{popup_edit}}",0,Null)
  4470. CreateMenu "{{popup_edit_quickhelp}}",MENUQUICKHELP,edit
  4471. CreateMenu "",0,edit
  4472. CreateMenu "{{popup_edit_cut}}",MENUCUT,edit
  4473. CreateMenu "{{popup_edit_copy}}",MENUCOPY,edit
  4474. CreateMenu "{{popup_edit_paste}}",MENUPASTE,edit
  4475. CreateMenu "",0,edit
  4476. CreateMenu "{{popup_edit_selectall}}",MENUSELECTALL,edit
  4477. CreateMenu "",0,edit
  4478. CreateMenu "{{popup_edit_blockindent}}",MENUINDENT,edit
  4479. CreateMenu "{{popup_edit_blockoutdent}}",MENUOUTDENT,edit
  4480. CreateMenu "",0,edit
  4481. CreateMenu "{{popup_edit_find}}",MENUFIND,edit
  4482. CreateMenu "{{popup_edit_findnext}}",MENUFINDNEXT,edit
  4483. CreateMenu "{{popup_edit_replace}}",MENUREPLACE,edit
  4484. CreateMenu "{{popup_edit_goto}}",MENUGOTO,edit
  4485. Return edit
  4486. End Function
  4487. Method MakePathTemp()
  4488. ' prepends "." to file name with code borrowed from SaveAs
  4489. Local file$=ExtractDir(path)+"/."+StripDir(path)
  4490. SaveSource(file$)
  4491. ' Refresh
  4492. GetNode().Refresh
  4493. ' setdirty False
  4494. host.SetTitle path
  4495. End Method
  4496. Function Create:TOpenCode(path$,host:TCodePlay)
  4497. Local code:TOpenCode
  4498. Local stream:TStream
  4499. Local isnew
  4500. If path
  4501. If FileType(path)<>FILETYPE_FILE
  4502. Return Null
  4503. EndIf
  4504. stream=ReadFile(path)
  4505. If Not stream
  4506. ' Notify "Open could not read from "+path
  4507. Return Null
  4508. EndIf
  4509. CloseFile stream
  4510. Else
  4511. TEMPCOUNT:+1
  4512. path=host.bmxpath+"/tmp/untitled"+TEMPCOUNT+".bmx"
  4513. isnew=True
  4514. EndIf
  4515. code=New TOpenCode
  4516. code.host=host
  4517. code.active=True
  4518. code.path=host.FullPath(path)
  4519. code.editmenu=CreateEditMenu()
  4520. codeplay.addpanel(code)
  4521. code.textarea=CreateTextArea(0,0,ClientWidth(code.panel),ClientHeight(code.panel),code.panel,0)
  4522. DelocalizeGadget code.textarea
  4523. SetGadgetFilter code.textarea,code.FilterKey,code
  4524. SetTextAreaText code.textarea,"~n"
  4525. SetGadgetLayout code.textarea,EDGE_ALIGNED,EDGE_ALIGNED,EDGE_ALIGNED,EDGE_ALIGNED
  4526. code.RefreshStyle()
  4527. If isnew
  4528. code.SaveSource path
  4529. code.filesrc="~n"
  4530. ActivateGadget code.textarea
  4531. Else
  4532. host.UpdateProgress "Reading Stream"
  4533. code.ReadSource(path)
  4534. EndIf
  4535. If ExtractExt(path).toLower()="bmx" code.isbmx=True
  4536. If ExtractExt(path).toLower()="c" code.isc=True
  4537. If ExtractExt(path).toLower()="cpp" code.iscpp=True
  4538. If ExtractExt(path).toLower()="cxx" code.iscpp=True
  4539. If ExtractExt(path).toLower()="html" code.ishtml=True
  4540. If ExtractExt(path).toLower()="htm" code.ishtml=True
  4541. code.UpdateCode False
  4542. code.filesrc=TextAreaText(code.textarea)
  4543. Return code
  4544. End Function
  4545. End Type
  4546. Type TRect
  4547. Field x,y,w,h
  4548. Method Set(xpos,ypos,width,height)
  4549. x=xpos;y=ypos;w=width;h=height
  4550. End Method
  4551. Method ToString$()
  4552. Return ""+x+","+y+","+w+","+h
  4553. End Method
  4554. Method FromString(s$)
  4555. Local p,q,r
  4556. p=s.Find(",")+1;If Not p Return
  4557. q=s.Find(",",p)+1;If Not q Return
  4558. r=s.Find(",",q)+1;If Not r Return
  4559. x=Int(s[..p-1])
  4560. y=Int(s[p..q-1])
  4561. w=Int(s[q..r-1])
  4562. h=Int(s[r..])
  4563. End Method
  4564. Method IsOutside(tx,ty,tw,th)
  4565. If x+w<=tx Or y+h<=ty Return True
  4566. If x>=tx+tw Or y>=ty+th Return True
  4567. End Method
  4568. End Type
  4569. Type TCodePlay
  4570. Const EDITMODE=1
  4571. Const DEBUGMODE=2
  4572. Field bmxpath$,bmkpath$
  4573. Field panels:TToolPanel[]
  4574. Field helppanel:THelpPanel
  4575. Field currentpanel:TToolPanel
  4576. Field output:TOutputPanel
  4577. Field lockedpanel:TToolPanel
  4578. Field activepanel:TToolPanel
  4579. Field cmdlinereq:TCmdLineRequester
  4580. Field cmdline$
  4581. 'Field syncmodsreq:TSyncModsRequester
  4582. Field gotoreq:TGotoRequester
  4583. Field findreq:TFindRequester
  4584. Field replacereq:TReplaceRequester
  4585. Field options:TOptionsRequester
  4586. ' Field progress:TProgressRequester
  4587. Field activerequesters:TList = New TList
  4588. Field projectreq:TProjectRequester
  4589. Field projectprops:TProjectProperties
  4590. Field searchreq:TSearchRequester
  4591. Field aboutreq:TAboutRequester
  4592. Field eventhandlers:TList=New TList
  4593. Field window:TGadget,menubar:TGadget,toolbar:TGadget,client:TGadget,tabbar:TGadget
  4594. Field split:TSplitter
  4595. Field debugtree:TDebugTree
  4596. Field root:TNode
  4597. Field helproot:TNode
  4598. Field projects:TProjects
  4599. Field coderoot:TNode
  4600. Field navbar:TNavBar
  4601. Field mode
  4602. Field debugcode:TOpenCode
  4603. Field quickenable:TGadget,quickenabled 'menu,state
  4604. Field debugenable:TGadget,debugenabled 'menu,state
  4605. Field threadedenable:TGadget,threadedenabled
  4606. Field guienable:TGadget,guienabled 'menu,state
  4607. Field quickhelp:TQuickHelp
  4608. Field running
  4609. Field recentmenu:TGadget
  4610. Field recentfiles:TList=New TList
  4611. Field recentmenus:TGadget[]
  4612. Field openlist:TList=New TList
  4613. Field openlock$
  4614. Field projlist:TList=New TList
  4615. Field winsize:TRect=New TRect
  4616. Field winmax,tooly,splitpos,debugview,navtab
  4617. Field progress,splitorientation
  4618. ?MacOS
  4619. Method RanlibMods()
  4620. Local cmd$=Quote( bmxpath+"/bin/bmk" )+" ranlibdir "+Quote( bmxpath+"/mod" )
  4621. system_ cmd
  4622. End Method
  4623. ?
  4624. Method CheckVersion$()
  4625. Local process:TProcess
  4626. Local bytes:Byte[]
  4627. Local cmd$,version$
  4628. cmd$=bmxpath+"/bin/bcc"
  4629. ?win32
  4630. cmd:+".exe"
  4631. ?
  4632. cmd=Quote(cmd)
  4633. process=CreateProcess(cmd$,HIDECONSOLE)
  4634. If process
  4635. Repeat
  4636. Delay 10
  4637. bytes=process.pipe.ReadPipe()
  4638. If bytes
  4639. version:+String.FromBytes(bytes,bytes.length)
  4640. EndIf
  4641. Until Not process.Status()
  4642. EndIf
  4643. If version=""
  4644. Notify "Unable to determine BlitzMax version.~n~nPlease reinstall BlitzMax to repair this problem."
  4645. End
  4646. EndIf
  4647. BCC_VERSION=version.Trim()
  4648. ' print "bcc version="+version
  4649. If version.find("(expired)")>-1 'Demo timed out
  4650. Notify "This demo version of BlitzMax has expired.~n~nPlease visit www.blitzbasic.com to buy the full version."
  4651. End
  4652. EndIf
  4653. If version.find("Demo Version")>-1 'Valid demo version
  4654. is_demo=True
  4655. Notify version+"~nTo purchase the full version please visit www.blitzbasic.com."
  4656. Notify ABOUTDEMO
  4657. EndIf
  4658. End Method
  4659. Method OpenProgress(message$)
  4660. ' progress.Open message
  4661. DisableGadget window
  4662. SetStatus message
  4663. progress=-1
  4664. End Method
  4665. Method CloseProgress()
  4666. ' progress.Hide
  4667. SetStatus ""
  4668. EnableGadget window
  4669. progress=0
  4670. End Method
  4671. Method UpdateProgress(message$,value=0) 'returns false if cancelled
  4672. ' Return progress.Update(message,value)
  4673. If progress
  4674. If progress/5<>value/5
  4675. SetStatus message+" "+value+"%"
  4676. progress=value
  4677. ' Pollsystem
  4678. EndIf
  4679. EndIf
  4680. End Method
  4681. Method FullPath$(path$)
  4682. If path[..8]="$BMXPATH" path=bmxpath+path[8..]
  4683. If Not path.Contains("::") Then path = RealPath(path)
  4684. ?win32
  4685. path=path.Replace("\","/")
  4686. ?
  4687. Return path
  4688. End Method
  4689. Method IsTempPath(path$)
  4690. If path[..bmxpath.length+5]=bmxpath+"/tmp/" Return True
  4691. End Method
  4692. Method AddDefaultProj(p$)
  4693. Local projdata:TList = New TList
  4694. projdata.AddLast p
  4695. projlist.AddLast projdata
  4696. End Method
  4697. Method ReadConfig()
  4698. Local stream:TStream
  4699. Local f$,p,a$,b$
  4700. ' defaults
  4701. Local wh=GadgetHeight(Desktop())-80'32
  4702. Local ww=wh
  4703. Local wx=(GadgetWidth(Desktop())-ww)/2
  4704. Local wy=(GadgetHeight(Desktop())-wh)/2
  4705. winsize.set( wx,wy,ww,wh )
  4706. quickenabled=False
  4707. debugenabled=True
  4708. threadedenabled=False
  4709. guienabled=True
  4710. splitpos=200;splitorientation = SPLIT_VERTICAL
  4711. ' read ini
  4712. stream=ReadFile(bmxpath+"/cfg/ide.ini")
  4713. If Not stream
  4714. AddDefaultProj "Samples|samples"
  4715. If Not is_demo
  4716. AddDefaultProj "Modules Source|mod"
  4717. AddDefaultProj "BlitzMax Source|src"
  4718. EndIf
  4719. Return
  4720. EndIf
  4721. options.read(stream)
  4722. options.Snapshot
  4723. Local projdata:TList
  4724. While Not stream.Eof()
  4725. f$=stream.ReadLine()
  4726. p=f.find("=")
  4727. If p=-1 Continue
  4728. a$=f[..p]
  4729. b$=f[p+1..]
  4730. Select a$
  4731. Case "ide_version"
  4732. Case "file_recent"
  4733. recentfiles.addlast b$
  4734. Case "file_open"
  4735. openlist.addlast b$
  4736. Case "prg_quick"
  4737. quickenabled=Int(b$)
  4738. Case "prg_debug"
  4739. debugenabled=Int(b$)
  4740. Case "prg_threaded"
  4741. threadedenabled=Int(b$)
  4742. Case "prg_gui"
  4743. guienabled=Int(b$)
  4744. Case "cmd_line"
  4745. cmdline=b$
  4746. Case "prg_locked"
  4747. openlock=b$
  4748. Case "win_size"
  4749. winsize.FromString(b$)
  4750. Case "win_max"
  4751. winmax=Int(b$)
  4752. Case "split_position"
  4753. splitpos=Int(b$)
  4754. Case "split_orientation"
  4755. splitorientation=Int(b$)
  4756. Case "proj_node"
  4757. projdata=New TList
  4758. projdata.AddLast b
  4759. projlist.AddLast projdata
  4760. Case "proj_data"
  4761. If projdata projdata.AddLast b
  4762. 'Case "sync_state"
  4763. 'syncmodsreq.FromString b$
  4764. End Select
  4765. Wend
  4766. stream.close()
  4767. End Method
  4768. Method WriteConfig()
  4769. Local panel:TToolPanel
  4770. Local node:TNode
  4771. Local f$
  4772. Local stream:TStream = WriteFile(bmxpath+"/cfg/ide.ini")
  4773. If Not stream Return
  4774. ' options
  4775. options.write(stream)
  4776. ' defaults
  4777. stream.WriteLine "[Defaults]"
  4778. stream.WriteLine "ide_version="+IDE_VERSION$
  4779. stream.WriteLine "prg_quick="+quickenabled
  4780. stream.WriteLine "prg_debug="+debugenabled
  4781. stream.WriteLine "prg_threaded="+threadedenabled
  4782. stream.WriteLine "prg_gui="+guienabled
  4783. stream.WriteLine "win_size="+winsize.ToString()
  4784. stream.WriteLine "win_max="+winmax
  4785. stream.WriteLine "split_position="+SplitterPosition(split)
  4786. stream.WriteLine "split_orientation="+SplitterOrientation(split)
  4787. stream.WriteLine "cmd_line="+cmdline
  4788. 'stream.WriteLine "sync_state="+syncmodsreq.ToString()
  4789. If lockedpanel stream.WriteLine "prg_locked="+lockedpanel.path
  4790. For f$=EachIn recentfiles
  4791. stream.WriteLine "file_recent="+f$
  4792. Next
  4793. For Local panel:TToolPanel = EachIn panels
  4794. f$=panel.path
  4795. If f$ And Not IsTempPath(f$) stream.WriteLine "file_open="+f$
  4796. Next
  4797. projects.write(stream)
  4798. stream.close
  4799. End Method
  4800. Method CloseAll(dontask,inccurrent=True) 'returns true if successful
  4801. Local count, cancel
  4802. For Local panel:TToolPanel = EachIn panels
  4803. If TOpenCode(panel) And (inccurrent Or currentpanel <> panel) count:+1
  4804. Next
  4805. If (Not count) Or dontask Or Confirm(LocalizeString("{{request_closeall}}"))
  4806. For Local panel:TToolPanel = EachIn panels[..] 'Use a copy of the original array for iterating.
  4807. If (inccurrent Or currentpanel <> panel) And panel.invoke(TOOLCLOSE) Then
  4808. cancel=True
  4809. Exit
  4810. EndIf
  4811. Next
  4812. Return Not cancel
  4813. EndIf
  4814. End Method
  4815. Method Quit()
  4816. WriteConfig()
  4817. If CloseAll(True) running=False
  4818. End Method
  4819. Method DebugExit()
  4820. If debugcode
  4821. debugtree.cancontinue = False
  4822. debugcode.Edit 'restore cursor etc.
  4823. debugcode=Null
  4824. EndIf
  4825. SetMode EDITMODE
  4826. RefreshToolbar()
  4827. End Method
  4828. Method DebugSource(path$,line,column)
  4829. Local code:TOpenCode
  4830. path=FullPath(path)
  4831. code=OpenSource(path)
  4832. If Not code Then
  4833. Notify(LocalizeString("{{loaderror_failed}}").Replace("%1",path), True)
  4834. Return
  4835. EndIf
  4836. If debugcode And debugcode<>code Then debugcode.Edit() 'restore cursor etc.
  4837. debugcode=code
  4838. debugcode.debug(line,column)
  4839. ActivateWindow window
  4840. PollSystem
  4841. End Method
  4842. Method SetMode(m)
  4843. If mode=m Return
  4844. ActivateWindow window
  4845. Select m
  4846. Case DEBUGMODE
  4847. navtab=navbar.SelectedView()
  4848. navbar.SelectView debugview
  4849. Case EDITMODE
  4850. navbar.SelectView navtab
  4851. End Select
  4852. mode=m
  4853. RefreshToolbar
  4854. End Method
  4855. Method RefreshMenu()
  4856. TOpenCode.RefreshHighlightingMsg()
  4857. UpdateWindowMenu window
  4858. EndMethod
  4859. Method RefreshToolbar()
  4860. Local i
  4861. ' sourceedit buttons
  4862. If THelpPanel(CurrentPanel)
  4863. DisableGadgetItem toolbar,TB_CLOSE
  4864. Else
  4865. EnableGadgetItem toolbar,TB_CLOSE
  4866. EndIf
  4867. If TOpenCode(CurrentPanel)
  4868. EnableGadgetItem toolbar,TB_SAVE
  4869. For i=TB_CUT To TB_FIND
  4870. EnableGadgetItem toolbar,i
  4871. Next
  4872. Else
  4873. DisableGadgetItem toolbar,TB_SAVE
  4874. For i=TB_CUT To TB_FIND
  4875. DisableGadgetItem toolbar,i
  4876. Next
  4877. EndIf
  4878. ' debug buttons
  4879. If mode = DEBUGMODE And debugtree.cancontinue Then
  4880. If GadgetItemIcon( toolbar, TB_BUILDRUN ) = TB_BUILDRUN Then
  4881. ModifyGadgetItem( toolbar, TB_BUILDRUN, "", GADGETITEM_LOCALIZED, TB_CONTINUE, "{{tb_continue}}" )
  4882. EndIf
  4883. Else
  4884. If GadgetItemIcon( toolbar, TB_BUILDRUN ) <> TB_BUILDRUN Then
  4885. ModifyGadgetItem( toolbar, TB_BUILDRUN, "", GADGETITEM_LOCALIZED, TB_BUILDRUN, "{{tb_buildrun}}" )
  4886. EndIf
  4887. EndIf
  4888. For i=TB_STEP To TB_STEPOUT
  4889. If mode=DEBUGMODE And debugtree.cancontinue Then
  4890. EnableGadgetItem toolbar,i
  4891. Else
  4892. DisableGadgetItem toolbar,i
  4893. EndIf
  4894. Next
  4895. ' stop button
  4896. If output And output.process
  4897. EnableGadgetItem toolbar,TB_STOP
  4898. Else
  4899. DisableGadgetItem toolbar,TB_STOP
  4900. EndIf
  4901. End Method
  4902. Method IsSourceOpen(path$)
  4903. Local p$ = FullPath(path)
  4904. For Local panel:TToolPanel = EachIn panels
  4905. If panel.path=p Return True
  4906. Next
  4907. End Method
  4908. Method OpenSource:TOpenCode(path$)
  4909. Local code:TOpenCode
  4910. Local ext$,p$
  4911. If path$="."
  4912. path$=RequestFile(LocalizeString("{{request_openfile}}"),FileTypeFilters )
  4913. If path$="" Return
  4914. EndIf
  4915. ' check if already open
  4916. p$=FullPath(path).ToLower()
  4917. For Local panel:TToolPanel = EachIn panels
  4918. If panel.path.ToLower()=p
  4919. SelectPanel panel
  4920. Return TOpenCode(panel)
  4921. EndIf
  4922. Next
  4923. ' open based on extension
  4924. ' Select ExtractExt(Upper(path$))
  4925. ' Case "BMX","TXT","BB","CPP","C","S","I","H","HTML","CSS","BAT","FS","VS","README",""
  4926. OpenProgress LocalizeString("{{msg_loading}}").Replace("%1",StripDir(path))
  4927. code=TOpenCode.Create(path,Self)
  4928. If code
  4929. AddRecent code.path
  4930. EndIf
  4931. CloseProgress
  4932. If code
  4933. ActivateGadget code.textarea
  4934. code.GetNode().Refresh
  4935. EndIf
  4936. Return code
  4937. ' end select
  4938. End Method
  4939. Method AddRecent(path$)
  4940. For Local f$ = EachIn recentfiles
  4941. If f$=path$ recentfiles.Remove(f$);Exit
  4942. Next
  4943. recentfiles.AddFirst(path$)
  4944. RefreshRecentFiles
  4945. UpdateWindowMenu window
  4946. End Method
  4947. Method RefreshRecentFiles()
  4948. Local n
  4949. For Local m:TGadget = EachIn recentmenus
  4950. FreeMenu m
  4951. Next
  4952. n=Min(recentfiles.count(),16)
  4953. recentmenus=New TGadget[n]
  4954. n=0
  4955. For Local f$ = EachIn recentfiles
  4956. recentmenus[n]=CreateMenu(f$,MENURECENT+n,recentmenu)
  4957. n:+1
  4958. If n=16 Exit
  4959. Next
  4960. End Method
  4961. Method BuildModules(buildall)
  4962. Local cmd$,out$,exe$
  4963. output.Stop
  4964. SaveAll
  4965. cmd$=quote(bmkpath)
  4966. cmd$:+" makemods "
  4967. If buildall cmd$:+"-a "
  4968. If threadedenabled cmd:+"-h "
  4969. Execute cmd,LocalizeString("{{output_msg_buildingmods}}")
  4970. End Method
  4971. Method ImportBB()
  4972. Local f$ = RequestFile(LocalizeString("{{request_importbb_title}}"),"bb" )
  4973. If Not f$ Return
  4974. Local cmd$ = Quote(bmkpath$)
  4975. cmd$:+" convertbb "
  4976. cmd$:+quote(FullPath(f$))
  4977. Execute cmd,LocalizeString("{{output_msg_converting}}").Replace("%1",StripExt(StripDir(f$)))
  4978. output.wait
  4979. OpenSource(StripExt(f$)+".bmx")
  4980. End Method
  4981. Method GetCommandLine$()
  4982. Return cmdline
  4983. End Method
  4984. Method SetCommandLine(text$)
  4985. cmdline=text
  4986. End Method
  4987. Method SetStatus(text$)
  4988. SetStatusText window,text
  4989. End Method
  4990. Method Execute(cmd$,mess$="",post$="",home=True,tool:TTool=Null)
  4991. If Not output output=TOutputPanel.Create(Self)
  4992. output.execute cmd$,mess$,post$,home,tool
  4993. End Method
  4994. Method SelectError(path$,column,line)
  4995. Local panel:TOpenCode,found
  4996. For panel=EachIn panels
  4997. If panel.path=path found=True;Exit
  4998. Next
  4999. If Not found panel=OpenSource(path)
  5000. If panel
  5001. SelectPanel panel
  5002. panel.Debug line,column
  5003. EndIf
  5004. End Method
  5005. Method ParseError(err$)
  5006. Local mess$,file$,p,q
  5007. Local line,column
  5008. ' bcc error
  5009. If err$[..13]="Compile Error"
  5010. err=err[14..]
  5011. p=err.find(EOL$)
  5012. If p=-1 p=err.length
  5013. mess=err[..p]
  5014. err=err[p+1..]
  5015. If err[..1]="["
  5016. p=err.find("]")
  5017. If p=-1 p=err.length
  5018. file$=err[1..p]
  5019. p=file.find(";")+1
  5020. If p=0 p=err.length
  5021. q=file.find(";",p)+1
  5022. If q=0 q=err.length
  5023. line=Int(file[p..q-1])
  5024. column=Int(file[q..])
  5025. file=FullPath(file[..p-1])
  5026. SelectError file,column,line
  5027. EndIf
  5028. Notify LocalizeString("{{output_error_compileerror}}").Replace("%1",mess)
  5029. SetStatus mess
  5030. Return
  5031. EndIf
  5032. ' gcc error
  5033. err=err.Replace(EOL+" "," ")
  5034. While err
  5035. p=err.find(EOL)
  5036. If p=-1 p:+err.length 'equiv. to p=err.length-1 ;-)
  5037. mess=err[..p]
  5038. err=err[p+1..]
  5039. p=0
  5040. Repeat
  5041. p=mess.Find(":",p)+1
  5042. If p=0 Exit
  5043. q=mess.Find(":",p)
  5044. If q<>-1
  5045. file=mess[..p-1]
  5046. line=Int(mess[p..q])
  5047. If line
  5048. mess=mess[q+1..]
  5049. SelectError file,column,line
  5050. Notify LocalizeString("{{output_error_compileerror}}").Replace("%1",mess)
  5051. Return
  5052. EndIf
  5053. p=q+1
  5054. EndIf
  5055. Forever
  5056. Wend
  5057. End Method
  5058. Method AddPanel(tabpanel:TToolPanel)
  5059. Local panel:TGadget,index
  5060. index=CountGadgetItems(tabbar)
  5061. If panels.length<=index panels=panels[..index+1]
  5062. AddGadgetItem(tabbar,tabpanel.name$,GADGETITEM_DEFAULT|GADGETITEM_LOCALIZED)
  5063. panel=CreatePanel(0,0,ClientWidth(tabbar),ClientHeight(tabbar),tabbar,0) 'name
  5064. SetGadgetLayout panel,EDGE_ALIGNED,EDGE_ALIGNED,EDGE_ALIGNED,EDGE_ALIGNED
  5065. tabpanel.panel=panel
  5066. tabpanel.index=index
  5067. panels[index]=tabpanel
  5068. SelectPanel tabpanel
  5069. AddHandler tabpanel
  5070. End Method
  5071. Method AddHandler(handler:TEventHandler)
  5072. eventhandlers.addlast handler
  5073. End Method
  5074. Method RemovePanel(tabpanel:TToolPanel)
  5075. Local p:TToolPanel[]
  5076. Local index
  5077. eventhandlers.remove tabpanel
  5078. ' unset debugcode
  5079. If debugcode=tabpanel debugcode=Null
  5080. ' activate next panel
  5081. If tabpanel=activepanel activepanel=helppanel
  5082. If tabpanel=lockedpanel lockedpanel=Null
  5083. If tabpanel=currentpanel
  5084. index=tabpanel.index+1
  5085. If index>=panels.length index=panels.length-2
  5086. SelectPanel panels[index]
  5087. EndIf
  5088. ' remove from array
  5089. p=panels
  5090. panels=panels[..panels.length-1]
  5091. For index=tabpanel.index To panels.length-1
  5092. panels[index]=p[index+1]
  5093. panels[index].index=index
  5094. Next
  5095. ' remove gadget - simon come here, placing before remove needs fix in fltk
  5096. FreeGadget tabpanel.panel
  5097. RemoveGadgetItem tabbar,tabpanel.index
  5098. tabpanel.panel=Null
  5099. End Method
  5100. Method HookRequester(req:TRequester)
  5101. If Not activerequesters.Contains(req) Then
  5102. If req.IsModal() Then
  5103. For Local tmpRequester:TRequester = EachIn activerequesters
  5104. DisableGadget tmpRequester.window
  5105. Next
  5106. DisableGadget window
  5107. EndIf
  5108. activerequesters.AddFirst(req)
  5109. EndIf
  5110. End Method
  5111. Method UnhookRequester(req:TRequester)
  5112. If activerequesters.Contains(req) Then
  5113. activerequesters.Remove(req)
  5114. If req.IsModal() Then
  5115. For Local tmpRequester:TRequester = EachIn activerequesters
  5116. EnableGadget tmpRequester.window
  5117. Next
  5118. EnableGadget window
  5119. EndIf
  5120. EndIf
  5121. EndMethod
  5122. Method SetTitle(title$="")
  5123. If title title=" - "+title
  5124. SetGadgetText window,"MaxIDE"+title
  5125. End Method
  5126. Method SelectPanel(panel:TToolPanel)
  5127. Local curr:TToolPanel = currentpanel
  5128. currentpanel=panel
  5129. If curr And curr<>currentpanel
  5130. SelectGadgetItem tabbar,panel.index
  5131. ShowGadget panel.panel
  5132. If panel.active activepanel=panel
  5133. HideGadget curr.panel
  5134. RefreshToolbar
  5135. EndIf
  5136. currentpanel.Invoke TOOLSHOW
  5137. End Method
  5138. Method RefreshPanel(panel:TToolPanel) 'call after a name change
  5139. ModifyGadgetItem( tabbar,panel.index,panel.name,GADGETITEM_LOCALIZED )
  5140. End Method
  5141. Function OutsideDesktop(winrect:TRect)
  5142. Local x,y,w,h
  5143. Local desk:TGadget = Desktop()
  5144. x=GadgetX(desk)
  5145. y=GadgetY(desk)
  5146. w=GadgetWidth(desk)
  5147. h=GadgetHeight(desk)
  5148. Return winrect.IsOutside(x,y,w,h)
  5149. End Function
  5150. Method SetCodeNode(code:TNode)
  5151. Local node:TNode
  5152. If coderoot.kids.count() node=TNode(coderoot.kids.First())
  5153. If node=code Return
  5154. If node node.Detach
  5155. If code
  5156. coderoot.Append code
  5157. coderoot.Refresh
  5158. coderoot.Open
  5159. code.Open
  5160. EndIf
  5161. End Method
  5162. Method Initialize()
  5163. Local open:TOpenCode, splash:TGadget
  5164. Local dir$,nomods,pname$,p
  5165. Local stream:TStream
  5166. Try
  5167. bmxpath=BlitzMaxPath()
  5168. Catch err$
  5169. Notify "Unable to determine BlitzMax installation directory."
  5170. End
  5171. EndTry
  5172. CreateDir bmxpath+"/tmp"
  5173. If FileType( bmxpath+"/tmp" )<>FILETYPE_DIR
  5174. Notify "Unable to create BlitzMax 'tmp' directory."
  5175. End
  5176. EndIf
  5177. ?Win32
  5178. CreateFile bmxpath+"/tmp/t.exe"
  5179. If FileType( bmxpath+"/tmp/t.exe" ) <> FILETYPE_FILE
  5180. Notify "Unable to write to BlitzMax installation directory.~n"+..
  5181. "Please run MaxIDE as administrator, or reinstall BlitzMax to a different directory."
  5182. End
  5183. EndIf
  5184. DeleteFile bmxpath+"/tmp/t.exe"
  5185. ?
  5186. bmkpath=bmxpath+"/bin/bmk"
  5187. ?Win32
  5188. bmkpath:+".exe"
  5189. ?
  5190. dir$=bmxpath+"/mod"
  5191. If FileType(dir)=FILETYPE_NONE
  5192. If Not CreateDir(dir)
  5193. Notify "Failed to create %1 directory:~n%2".Replace("%1","Module").Replace("%2",dir)
  5194. End
  5195. EndIf
  5196. nomods=True
  5197. EndIf
  5198. dir$=bmxpath+"/tmp"
  5199. If FileType(dir)=FILETYPE_NONE
  5200. If Not CreateDir(dir)
  5201. Notify "Failed to create %1 directory:~n%2".Replace("%1","Temp").Replace("%2",dir)
  5202. End
  5203. EndIf
  5204. EndIf
  5205. dir$=bmxpath+"/cfg"
  5206. If FileType(dir)=FILETYPE_NONE
  5207. If Not CreateDir(dir)
  5208. Notify "Failed to create %1 directory:~n%2".Replace("%1","Config").Replace("%2",dir)
  5209. End
  5210. EndIf
  5211. EndIf
  5212. CheckVersion()
  5213. splash=CreateWindow("MaxIDE",200,200,400,140,Null,WINDOW_CLIENTCOORDS|WINDOW_HIDDEN|WINDOW_CENTER)
  5214. Local panel:TGadget = CreatePanel(0,0,ClientWidth(splash),ClientHeight(splash),splash,0)
  5215. SetPanelColor panel,255,255,255;SetPanelPixmap panel, LoadPixmapPNG("incbin::splash.png"), PANELPIXMAP_FIT2
  5216. Local progress:TGadget = CreateProgBar(2,ClientHeight(panel)-22,ClientWidth(panel)-4,20,panel)
  5217. ShowGadget splash;PollSystem
  5218. window=CreateWindow("MaxIDE",20,20,760,540,Null,WINDOW_TITLEBAR|WINDOW_RESIZABLE|WINDOW_STATUS|WINDOW_HIDDEN|WINDOW_ACCEPTFILES|WINDOW_MENU)
  5219. ?Linux
  5220. SetGadgetPixmap(window, LoadPixmapPNG("incbin::window_icon.png"), GADGETPIXMAP_ICON )
  5221. ?
  5222. cmdlinereq=TCmdLineRequester.Create(Self)
  5223. 'syncmodsreq=TSyncModsRequester.Create(Self)
  5224. gotoreq=TGotoRequester.Create(Self)
  5225. findreq=TFindRequester.Create(Self)
  5226. replacereq=TReplaceRequester.Create(Self)
  5227. options=TOptionsRequester.Create(Self)
  5228. ' progress=TProgressRequester.Create(Self)
  5229. projectreq=TProjectRequester.Create(Self)
  5230. projectprops=TProjectProperties.Create(Self)
  5231. searchreq=TSearchRequester.Create(Self)
  5232. aboutreq=TAboutRequester.Create(Self)
  5233. UpdateProgBar progress, 0.1;PollSystem
  5234. ReadConfig()
  5235. toolbar=CreateToolbar("incbin::toolbar.png",0,0,0,0,window )
  5236. RemoveGadgetItem toolbar, TB_CONTINUE
  5237. Rem
  5238. SetToolbarTips toolbar, ["{{tb_new}}","{{tb_open}}","{{tb_close}}","{{tb_save}}","","{{tb_cut}}","{{tb_copy}}","{{tb_paste}}","{{tb_find}}","",..
  5239. "{{tb_build}}","{{tb_buildrun}}","{{tb_step}}","{{tb_stepin}}","{{tb_stepout}}","{{tb_stop}}","","{{tb_home}}","{{tb_back}}","{{tb_forward}}"]
  5240. End Rem
  5241. If Not options.showtoolbar Then HideGadget toolbar
  5242. If OutsideDesktop(winsize)
  5243. winsize.set(20,20,760,540)
  5244. EndIf
  5245. UpdateProgBar progress, 0.2;PollSystem
  5246. SetGadgetShape(window, winsize.x, winsize.y, winsize.w, winsize.h)
  5247. client=window
  5248. split=CreateSplitter(0,0,ClientWidth(client),ClientHeight(client),client,SPLIT_VERTICAL)
  5249. SetGadgetLayout(split,EDGE_ALIGNED,EDGE_ALIGNED,EDGE_ALIGNED,EDGE_ALIGNED)
  5250. tabbar=CreateTabber(0,0,ClientWidth(SplitterPanel(split,SPLITPANEL_MAIN)),ClientHeight(SplitterPanel(split,SPLITPANEL_MAIN)),SplitterPanel(split,SPLITPANEL_MAIN))
  5251. SetGadgetLayout(tabbar,EDGE_ALIGNED,EDGE_ALIGNED,EDGE_ALIGNED,EDGE_ALIGNED)
  5252. debugtree=TDebugTree.CreateDebugTree(Self)
  5253. root=TNode.CreateNode("{{navtab_home}}")
  5254. helproot=root.AddNode("{{navnode_help}}")
  5255. projects=TProjects.CreateProjects(Self)
  5256. root.Append projects
  5257. ' opencoderoot=root.AddNode("Open")
  5258. coderoot=TNode.CreateNode("{{navtab_code}}")
  5259. coderoot.Open()
  5260. navbar=TNavBar.Create(Self,SplitterPanel(split,SPLITPANEL_SIDEPANE))
  5261. navbar.AddView root
  5262. navbar.AddView coderoot
  5263. debugview=navbar.AddView(debugtree)
  5264. navbar.SelectView 0
  5265. helproot.Open
  5266. projects.Open
  5267. AddHandler navbar
  5268. SetMode EDITMODE
  5269. UpdateProgBar progress, 0.3;PollSystem
  5270. quickhelp=TQuickHelp.LoadCommandsTxt(bmxpath)
  5271. helppanel=THelpPanel.Create(Self)
  5272. output=TOutputPanel.Create(Self)
  5273. activepanel=helppanel
  5274. InitMenu
  5275. InitHotkeys
  5276. RefreshAll
  5277. UpdateProgBar progress, 0.4;PollSystem 'allow repaint
  5278. Local mkdocs
  5279. If FileType( bmxpath+"/docs/html/User Guide/index.html" )<>FILETYPE_FILE
  5280. CreateDir bmxpath+"/docs/html"
  5281. CreateFile bmxpath+"/docs/html/index.html"
  5282. mkdocs=True
  5283. EndIf
  5284. helppanel.Home()
  5285. UpdateProgBar progress, 0.5;PollSystem
  5286. ' scan projects in projlist
  5287. For Local pdata:TList = EachIn projlist
  5288. projects.AddProject pdata
  5289. Next
  5290. UpdateProgBar progress, 0.6;PollSystem
  5291. Local tmpProgValue# = 0.6
  5292. Local tmpProgStep#
  5293. 'open files from .ini restorelist
  5294. If options.restoreopenfiles
  5295. If Not openlist.IsEmpty() Then tmpProgStep = (0.3/openlist.Count())
  5296. For Local f$=EachIn openlist
  5297. open=OpenSource(f$)
  5298. If open And f$=openlock open.SetLocked(True)
  5299. tmpProgValue:+tmpProgStep;UpdateProgBar progress,tmpProgValue
  5300. Next
  5301. EndIf
  5302. tmpProgValue = 0.9
  5303. If AppArgs.length > 1 Then tmpProgStep = (0.1/(AppArgs.length-1)) Else tmpProgValue = 1.0
  5304. UpdateProgBar progress,tmpProgValue;PollSystem
  5305. ' open files specified in command line
  5306. For Local i:Int = 1 Until AppArgs.length
  5307. open=OpenSource(AppArgs[i])
  5308. tmpProgValue:+tmpProgStep;UpdateProgBar progress,tmpProgValue;PollSystem
  5309. Next
  5310. HideGadget splash;FreeGadget splash
  5311. PollSystem
  5312. SetSplitterPosition(split,splitpos);SetSplitterOrientation(split,splitorientation)
  5313. If winmax MaximizeWindow(window)
  5314. ShowGadget window
  5315. PollSystem
  5316. running=True
  5317. CreateTimer(TIMER_FREQUENCY)
  5318. 'If nomods syncmodsreq.Show
  5319. 'build docs if not there
  5320. If mkdocs
  5321. If Confirm( LocalizeString("{{loaderror_docsnotfound}}") ) And CloseAll( False ) DocMods
  5322. EndIf
  5323. End Method
  5324. Method DocMods()
  5325. Local cmd$=quote(bmxpath+"/bin/makedocs")
  5326. execute cmd,LocalizeString("{{output_msg_rebuildingdocs}}"),MENUTRIGGERSYNCDOCS
  5327. ?MacOS
  5328. RanLibMods()
  5329. ?
  5330. End Method
  5331. Method SyncDocs()
  5332. helppanel.SyncDocs()
  5333. quickhelp=TQuickHelp.LoadCommandsTxt(bmxpath)
  5334. helppanel.Home
  5335. End Method
  5336. Method InitMenu()
  5337. Local menu:TGadget,file:TGadget,edit:TGadget,program:TGadget,tools:TGadget
  5338. Local help:TGadget,buildoptions:TGadget
  5339. Local buildmods:TGadget,buildallmods:TGadget,syncmods:TGadget,docmods:TGadget
  5340. Local MENUMOD=MODIFIER_COMMAND
  5341. If options.systemkeys
  5342. MENUMOD=MODIFIER_CONTROL
  5343. EndIf
  5344. menu=WindowMenu(window)
  5345. file=CreateMenu("{{menu_file}}",0,menu)
  5346. CreateMenu "{{menu_file_new}}",MENUNEW,file,KEY_N,MENUMOD
  5347. CreateMenu "{{menu_file_open}}",MENUOPEN,file,KEY_O,MENUMOD
  5348. recentmenu=CreateMenu("{{menu_file_open_recent}}",0,file)
  5349. CreateMenu "",0,file
  5350. CreateMenu "{{menu_file_closetab}}",MENUCLOSE,file,KEY_W,MENUMOD
  5351. CreateMenu "{{menu_file_closealltabs}}",MENUCLOSEALL,file,KEY_W,MENUMOD|MODIFIER_SHIFT
  5352. CreateMenu "{{menu_file_closeothertabs}}",MENUCLOSEOTHERS,file,KEY_W,MENUMOD|MODIFIER_ALT
  5353. CreateMenu "",0,file
  5354. CreateMenu "{{menu_file_save}}",MENUSAVE,file,KEY_S,MENUMOD
  5355. CreateMenu "{{menu_file_saveas}}",MENUSAVEAS,file,KEY_S,MENUMOD|MODIFIER_SHIFT
  5356. CreateMenu "{{menu_file_saveall}}",MENUSAVEALL,file
  5357. CreateMenu "",0,file
  5358. If options.systemkeys
  5359. ?MacOS
  5360. CreateMenu "{{menu_file_nexttab}}",MENUNEXT,file,KEY_RIGHT,MENUMOD
  5361. CreateMenu "{{menu_file_prevtab}}",MENUPREV,file,KEY_LEFT,MENUMOD
  5362. ?Not MacOS
  5363. CreateMenu "{{menu_file_nexttab}}",MENUNEXT,file,KEY_RIGHT,MODIFIER_ALT
  5364. CreateMenu "{{menu_file_prevtab}}",MENUPREV,file,KEY_LEFT,MODIFIER_ALT
  5365. ?
  5366. Else
  5367. CreateMenu "{{menu_file_nexttab}}",MENUNEXT,file,KEY_RIGHT,MENUMOD
  5368. CreateMenu "{{menu_file_prevtab}}",MENUPREV,file,KEY_LEFT,MENUMOD
  5369. EndIf
  5370. CreateMenu "",0,file
  5371. CreateMenu "{{menu_file_importbb}}",MENUIMPORTBB,file
  5372. CreateMenu "",0,file
  5373. CreateMenu "{{menu_file_ideoptions}}",MENUOPTIONS,file
  5374. CreateMenu "{{menu_file_projectmanager}}",MENUPROJECTMANAGER,file
  5375. CreateMenu "",0,file
  5376. CreateMenu "{{menu_file_print}}",MENUPRINT,file,KEY_P,MENUMOD
  5377. ?Not MacOS
  5378. CreateMenu "",0,file
  5379. CreateMenu "{{menu_file_exit}}",MENUQUIT,file
  5380. ?
  5381. edit=CreateMenu("{{menu_edit}}",0,menu)
  5382. CreateMenu "{{menu_edit_undo}}",MENUUNDO,edit,KEY_Z,MENUMOD
  5383. ?MacOS
  5384. CreateMenu "{{menu_edit_redo}}",MENUREDO,edit,KEY_Z,MENUMOD|MODIFIER_SHIFT
  5385. ?Not MacOS
  5386. CreateMenu "{{menu_edit_redo}}",MENUREDO,edit,KEY_Y,MENUMOD
  5387. ?
  5388. CreateMenu "",0,edit
  5389. CreateMenu "{{menu_edit_cut}}",MENUCUT,edit,KEY_X,MENUMOD
  5390. CreateMenu "{{menu_edit_copy}}",MENUCOPY,edit,KEY_C,MENUMOD
  5391. CreateMenu "{{menu_edit_paste}}",MENUPASTE,edit,KEY_V,MENUMOD
  5392. CreateMenu "",0,edit
  5393. CreateMenu "{{menu_edit_selectall}}",MENUSELECTALL,edit,KEY_A,MENUMOD
  5394. CreateMenu "",0,edit
  5395. CreateMenu "{{menu_edit_blockindent}}",MENUINDENT,edit,KEY_CLOSEBRACKET,MENUMOD
  5396. CreateMenu "{{menu_edit_blockoutdent}}",MENUOUTDENT,edit,KEY_OPENBRACKET,MENUMOD
  5397. CreateMenu "",0,edit
  5398. CreateMenu "{{menu_edit_find}}",MENUFIND,edit,KEY_F,MENUMOD
  5399. ?MacOS
  5400. CreateMenu "{{menu_edit_findnext}}",MENUFINDNEXT,edit,KEY_G,MENUMOD
  5401. CreateMenu "{{menu_edit_replace}}",MENUREPLACE,edit,KEY_H,MENUMOD
  5402. CreateMenu "{{menu_edit_gotoline}}",MENUGOTO,edit,KEY_L,MENUMOD
  5403. ?Not MacOS
  5404. CreateMenu "{{menu_edit_findnext}}",MENUFINDNEXT,edit,KEY_F3
  5405. CreateMenu "{{menu_edit_replace}}",MENUREPLACE,edit,KEY_H,MENUMOD
  5406. CreateMenu "{{menu_edit_gotoline}}",MENUGOTO,edit,KEY_G,MENUMOD
  5407. ?
  5408. CreateMenu "",0,edit
  5409. CreateMenu "{{menu_edit_findinfiles}}",MENUFINDINFILES,edit,KEY_F,MENUMOD|MODIFIER_SHIFT
  5410. program=CreateMenu("{{menu_program}}",0,menu)
  5411. CreateMenu "{{menu_program_build}}",MENUBUILD,program,KEY_B,MENUMOD
  5412. CreateMenu "{{menu_program_buildandrun}}",MENURUN,program,KEY_R,MENUMOD
  5413. CreateMenu "{{menu_program_commandline}}",MENUCOMMANDLINE,program
  5414. CreateMenu "",0,program
  5415. CreateMenu "{{menu_program_step}}",MENUSTEP,program,KEY_F9
  5416. CreateMenu "{{menu_program_stepin}}",MENUSTEPIN,program,KEY_F10
  5417. CreateMenu "{{menu_program_stepout}}",MENUSTEPOUT,program,KEY_F11
  5418. CreateMenu "{{menu_program_terminate}}",MENUSTOP,program
  5419. buildoptions=CreateMenu("{{menu_program_buildoptions}}",0,program)
  5420. quickenable=CreateMenu("{{menu_program_buildoptions_quick}}",MENUQUICKENABLED,buildoptions)
  5421. debugenable=CreateMenu("{{menu_program_buildoptions_debug}}",MENUDEBUGENABLED,buildoptions)
  5422. If (FileType( BlitzMaxPath()+"/mod/brl.mod/blitz.mod/blitz_gc_ms.c" )=FILETYPE_FILE) ..
  5423. Or (FileType( BlitzMaxpath()+"/mod/brl.mod/blitz.mod/bdwgc" )=FILETYPE_DIR)
  5424. threadedenable=CreateMenu("{{menu_program_buildoptions_threaded}}",MENUTHREADEDENABLED,buildoptions)
  5425. EndIf
  5426. guienable=CreateMenu("{{menu_program_buildoptions_guiapp}}",MENUGUIENABLED,buildoptions)
  5427. CreateMenu "",0,program
  5428. CreateMenu "{{menu_program_lockbuildfile}}",MENULOCKBUILD,program
  5429. CreateMenu "{{menu_program_unlockbuildfile}}",MENUUNLOCKBUILD,program
  5430. CreateMenu "",0,program
  5431. 'syncmods=CreateMenu("{{menu_program_syncmods}}",MENUSYNCMODS,program)
  5432. 'CreateMenu "",0,program
  5433. buildmods=CreateMenu("{{menu_program_buildmods}}",MENUBUILDMODULES,program,KEY_D,MENUMOD)
  5434. buildallmods=CreateMenu("{{menu_program_rebuildallmods}}",MENUBUILDALLMODULES,program)
  5435. docmods=CreateMenu("{{menu_program_rebuilddocs}}",MENUDOCMODS,program)
  5436. help=CreateMenu("{{menu_help}}",0,menu)
  5437. CreateMenu "{{menu_help_home}}",MENUHOME,help
  5438. CreateMenu "{{menu_help_back}}",MENUBACK,help
  5439. CreateMenu "{{menu_help_forward}}",MENUFORWARD,help
  5440. CreateMenu "{{menu_help_quickhelp}}",MENUQUICKHELP,help,KEY_F1
  5441. CreateMenu "{{menu_help_aboutmaxide}}",MENUABOUT,help
  5442. If quickenabled CheckMenu quickenable
  5443. If debugenabled CheckMenu debugenable
  5444. If threadedenabled CheckMenu threadedenable
  5445. If guienabled CheckMenu guienable
  5446. ?Win32
  5447. Local mingw$=getenv_("MINGW")
  5448. If Not mingw
  5449. DisableMenu buildmods
  5450. DisableMenu buildallmods
  5451. EndIf
  5452. ?
  5453. ' If is_demo
  5454. ' DisableMenu syncmods
  5455. ' EndIf
  5456. RefreshRecentFiles
  5457. UpdateWindowMenu window
  5458. End Method
  5459. Method RunCode()
  5460. If mode=DEBUGMODE And debugtree.cancontinue
  5461. output.Go()
  5462. Return
  5463. EndIf
  5464. output.Stop()
  5465. SaveAll()
  5466. If lockedpanel
  5467. lockedpanel.invoke TOOLRUN
  5468. Else
  5469. activepanel.invoke TOOLRUN
  5470. EndIf
  5471. End Method
  5472. Method BuildCode()
  5473. output.Stop()
  5474. SaveAll()
  5475. If lockedpanel
  5476. lockedpanel.invoke TOOLBUILD
  5477. Else
  5478. activepanel.invoke TOOLBUILD
  5479. EndIf
  5480. End Method
  5481. Method AddEventHotKey(key,mods,id,data)
  5482. SetHotKeyEvent key,mods,CreateEvent(id,Null,data)
  5483. End Method
  5484. Method InitHotkeys()
  5485. AddEventHotKey KEY_F5,MODIFIER_NONE,EVENT_MENUACTION,MENURUN
  5486. AddEventHotKey KEY_F7,MODIFIER_NONE,EVENT_MENUACTION,MENUBUILD
  5487. End Method
  5488. Method SaveAll()
  5489. For Local panel:TToolPanel = EachIn panels
  5490. panel.invoke TOOLQUICKSAVE
  5491. Next
  5492. End Method
  5493. Method Restart()
  5494. If Confirm(LocalizeString("{{request_restart}}"))
  5495. Quit
  5496. EndIf
  5497. End Method
  5498. Method RefreshAll()
  5499. ' hide/show toolbar
  5500. If options.showtoolbar Then ShowGadget toolbar Else HideGadget toolbar
  5501. ' refresh panels
  5502. For Local panel:TToolPanel = EachIn panels
  5503. panel.invoke TOOLREFRESH
  5504. Next
  5505. ' refresh navbar
  5506. navbar.invoke TOOLREFRESH
  5507. End Method
  5508. Method SnapshotWindow()
  5509. If WindowMaximized(window)
  5510. winmax=True
  5511. Else
  5512. If Not WindowMinimized(window)
  5513. winmax=False
  5514. winsize.x=GadgetX(window)
  5515. winsize.y=GadgetY(window)
  5516. winsize.w=GadgetWidth(window)
  5517. winsize.h=GadgetHeight(window)
  5518. EndIf
  5519. EndIf
  5520. options.showtoolbar = Not GadgetHidden(toolbar)
  5521. End Method
  5522. Method OnMenu(menu,extra:Object=Null)
  5523. Local index
  5524. Local tool:TTool = TTool(extra)
  5525. If tool
  5526. tool.invoke(TOOLMENU,""+menu)
  5527. Return
  5528. EndIf
  5529. Select menu
  5530. Case MENUNEW
  5531. OpenSource ""
  5532. Case MENUOPEN
  5533. OpenSource "."
  5534. Case MENUCLOSE
  5535. currentpanel.invoke TOOLCLOSE
  5536. Case MENUCLOSEALL
  5537. CloseAll True
  5538. Case MENUCLOSEOTHERS
  5539. CloseAll True, False
  5540. Case MENUSAVE
  5541. currentpanel.invoke TOOLSAVE
  5542. Case MENUSAVEAS
  5543. currentpanel.invoke TOOLSAVEAS
  5544. Case MENUSAVEALL
  5545. SaveAll()
  5546. Case MENUPRINT
  5547. currentpanel.invoke TOOLPRINT
  5548. Case MENUQUIT
  5549. Quit()
  5550. Case MENUGOTO
  5551. gotoreq.Show()
  5552. Case MENUFIND
  5553. currentpanel.invoke TOOLFIND
  5554. Case MENUFINDNEXT
  5555. currentpanel.invoke TOOLFINDNEXT
  5556. Case MENUREPLACE
  5557. replacereq.Show()
  5558. Case MENUUNDO currentpanel.invoke TOOLUNDO
  5559. Case MENUREDO currentpanel.invoke TOOLREDO
  5560. Case MENUCUT currentpanel.invoke TOOLCUT
  5561. Case MENUCOPY currentpanel.invoke TOOLCOPY
  5562. Case MENUPASTE currentpanel.invoke TOOLPASTE
  5563. Case MENUSELECTALL currentpanel.invoke TOOLSELECTALL
  5564. Case MENUBUILD
  5565. BuildCode()
  5566. Case MENURUN
  5567. RunCode()
  5568. Case MENUBUILDMODULES
  5569. If CheckDemo() BuildModules False
  5570. Case MENUBUILDALLMODULES
  5571. If CheckDemo() BuildModules True
  5572. 'Case MENUSYNCMODS
  5573. ' If CheckDemo() And CloseAll(False) syncmodsreq.Show
  5574. Case MENUDOCMODS
  5575. If CheckDemo() And CloseAll(False) DocMods
  5576. Case MENUTRIGGERDOCMODS
  5577. DocMods()
  5578. Case MENUTRIGGERSYNCDOCS
  5579. SyncDocs()
  5580. Case MENUSTEP If output output.StepOver()
  5581. Case MENUSTEPIN If output output.StepIn()
  5582. Case MENUSTEPOUT If output output.StepOut()
  5583. Case MENUSTOP If output output.Stop()
  5584. Case MENULOCKBUILD
  5585. activepanel.invoke TOOLLOCK
  5586. Case MENUUNLOCKBUILD
  5587. If lockedpanel lockedpanel.invoke TOOLUNLOCK
  5588. Case MENUCOMMANDLINE cmdlinereq.Show
  5589. Case MENUQUICKENABLED
  5590. If quickenabled
  5591. quickenabled=False
  5592. UncheckMenu quickenable
  5593. Else
  5594. quickenabled=True
  5595. CheckMenu quickenable
  5596. EndIf
  5597. UpdateWindowMenu window
  5598. Case MENUDEBUGENABLED
  5599. If debugenabled
  5600. debugenabled=False
  5601. UncheckMenu debugenable
  5602. Else
  5603. debugenabled=True
  5604. CheckMenu debugenable
  5605. EndIf
  5606. UpdateWindowMenu window
  5607. Case MENUTHREADEDENABLED
  5608. If threadedenabled
  5609. threadedenabled=False
  5610. UncheckMenu threadedenable
  5611. Else
  5612. threadedenabled=True
  5613. CheckMenu threadedenable
  5614. EndIf
  5615. UpdateWindowMenu window
  5616. Case MENUGUIENABLED
  5617. If guienabled
  5618. guienabled=False
  5619. UncheckMenu guienable
  5620. Else
  5621. guienabled=True
  5622. CheckMenu guienable
  5623. EndIf
  5624. UpdateWindowMenu window
  5625. Case MENUIMPORTBB
  5626. ImportBB
  5627. Case MENUFINDINFILES
  5628. If activepanel Then searchreq.ShowWithPath( ExtractDir(activepanel.path) ) Else searchreq.Show()
  5629. Case MENUPROJECTMANAGER
  5630. projectreq.Open projects
  5631. Case MENUSHOWCONSOLE
  5632. If output Then output.Open()
  5633. Case MENUOPTIONS
  5634. options.Show()
  5635. Case MENUNEXT
  5636. If Not currentpanel Return
  5637. index=currentpanel.index+1
  5638. If index=panels.length index=0
  5639. SelectPanel panels[index]
  5640. Case MENUPREV
  5641. If Not currentpanel Return
  5642. index=currentpanel.index-1
  5643. If index<0 index=panels.length-1
  5644. SelectPanel panels[index]
  5645. Case MENUQUICKHELP
  5646. currentpanel.invoke TOOLHELP
  5647. Case MENUHOME
  5648. helppanel.Home()
  5649. SelectPanel helppanel
  5650. Case MENUBACK
  5651. helppanel.Back()
  5652. SelectPanel helppanel
  5653. Case MENUFORWARD
  5654. helppanel.Forward()
  5655. SelectPanel helppanel
  5656. Case MENUABOUT
  5657. aboutreq.Show()
  5658. 'Notify (ABOUT.Replace( "{bcc_version}",BCC_VERSION ))
  5659. Case MENUINDENT
  5660. currentpanel.invoke TOOLINDENT
  5661. Case MENUOUTDENT
  5662. currentpanel.invoke TOOLOUTDENT
  5663. Case MENUNEWVIEW
  5664. navbar.invoke TOOLNEWVIEW
  5665. End Select
  5666. If menu>=MENURECENT
  5667. Local f:String = String(recentfiles.ValueAtIndex(menu-MENURECENT))
  5668. If f$ OpenSource f$
  5669. EndIf
  5670. End Method
  5671. Method poll()
  5672. Local src:TGadget
  5673. Local event = WaitEvent()
  5674. If Not activerequesters.IsEmpty()
  5675. Select event
  5676. Case EVENT_MENUACTION
  5677. src = ActiveGadget()
  5678. If src And (GadgetClass(src) = GADGET_TEXTFIELD) Then
  5679. Select EventData()
  5680. Case MENUSELECTALL
  5681. ActivateGadget(src)
  5682. Case MENUCOPY
  5683. GadgetCopy(src)
  5684. Case MENUPASTE
  5685. GadgetPaste(src)
  5686. Case MENUCUT
  5687. GadgetCut(src)
  5688. EndSelect
  5689. Return
  5690. EndIf
  5691. src = Null
  5692. Case EVENT_MOUSEENTER,EVENT_MOUSELEAVE,EVENT_GADGETLOSTFOCUS
  5693. Return
  5694. End Select
  5695. 'DebugLog CurrentEvent.ToString()
  5696. For Local activerequester:TRequester = EachIn activerequesters
  5697. If activerequester.Poll() Then Return
  5698. Next
  5699. EndIf
  5700. For Local handler:TEventHandler = EachIn eventhandlers
  5701. handler.OnEvent()
  5702. Next
  5703. src = TGadget(EventSource())
  5704. Select event
  5705. Case EVENT_GADGETACTION
  5706. Select EventSource()
  5707. Case toolbar
  5708. Select EventData()
  5709. Case TB_NEW OpenSource ""
  5710. Case TB_OPEN OpenSource "."
  5711. Case TB_CLOSE currentpanel.invoke TOOLCLOSE
  5712. Case TB_SAVE currentpanel.invoke TOOLSAVE
  5713. Case TB_CUT currentpanel.invoke TOOLCUT
  5714. Case TB_COPY currentpanel.invoke TOOLCOPY
  5715. Case TB_PASTE currentpanel.invoke TOOLPASTE
  5716. Case TB_FIND currentpanel.invoke TOOLFIND
  5717. Case TB_BUILD BuildCode
  5718. Case TB_BUILDRUN RunCode
  5719. Case TB_STEP If output output.stepover
  5720. Case TB_STEPIN If output output.stepin
  5721. Case TB_STEPOUT If output output.stepout
  5722. Case TB_STOP If output output.Stop
  5723. Case TB_HOME helppanel.Home;SelectPanel helppanel
  5724. Case TB_BACK helppanel.Back;SelectPanel helppanel
  5725. Case TB_FORWARDS helppanel.Forward;SelectPanel helppanel
  5726. End Select
  5727. Case tabbar
  5728. Local index = EventData()
  5729. If index>=0 And index<panels.length
  5730. SelectPanel panels[index]
  5731. EndIf
  5732. End Select
  5733. Case EVENT_WINDOWACCEPT, EVENT_APPOPENFILE
  5734. OpenSource EventText()
  5735. Case EVENT_APPTERMINATE
  5736. Quit()
  5737. Case EVENT_WINDOWACTIVATE
  5738. If (src=window) Then SelectPanel currentpanel
  5739. Case EVENT_WINDOWCLOSE
  5740. If (src=window) Then Quit()
  5741. Case EVENT_WINDOWMOVE, EVENT_WINDOWSIZE
  5742. If (src=window) Then SnapshotWindow()
  5743. Case EVENT_MENUACTION
  5744. OnMenu EventData(),EventExtra()
  5745. EndSelect
  5746. EndMethod
  5747. EndType
  5748. Function CacheAndLoadText$(url:Object)
  5749. Local tmpResult$
  5750. Local tmpBytes:Byte[] = LoadByteArray(url)
  5751. url = CreateRamStream( tmpBytes, tmpBytes.length, True, False )
  5752. tmpResult = LoadText(url)
  5753. TRamStream(url).Close()
  5754. Return tmpResult
  5755. EndFunction