dialogs.py 245 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830183118321833183418351836183718381839184018411842184318441845184618471848184918501851185218531854185518561857185818591860186118621863186418651866186718681869187018711872187318741875187618771878187918801881188218831884188518861887188818891890189118921893189418951896189718981899190019011902190319041905190619071908190919101911191219131914191519161917191819191920192119221923192419251926192719281929193019311932193319341935193619371938193919401941194219431944194519461947194819491950195119521953195419551956195719581959196019611962196319641965196619671968196919701971197219731974197519761977197819791980198119821983198419851986198719881989199019911992199319941995199619971998199920002001200220032004200520062007200820092010201120122013201420152016201720182019202020212022202320242025202620272028202920302031203220332034203520362037203820392040204120422043204420452046204720482049205020512052205320542055205620572058205920602061206220632064206520662067206820692070207120722073207420752076207720782079208020812082208320842085208620872088208920902091209220932094209520962097209820992100210121022103210421052106210721082109211021112112211321142115211621172118211921202121212221232124212521262127212821292130213121322133213421352136213721382139214021412142214321442145214621472148214921502151215221532154215521562157215821592160216121622163216421652166216721682169217021712172217321742175217621772178217921802181218221832184218521862187218821892190219121922193219421952196219721982199220022012202220322042205220622072208220922102211221222132214221522162217221822192220222122222223222422252226222722282229223022312232223322342235223622372238223922402241224222432244224522462247224822492250225122522253225422552256225722582259226022612262226322642265226622672268226922702271227222732274227522762277227822792280228122822283228422852286228722882289229022912292229322942295229622972298229923002301230223032304230523062307230823092310231123122313231423152316231723182319232023212322232323242325232623272328232923302331233223332334233523362337233823392340234123422343234423452346234723482349235023512352235323542355235623572358235923602361236223632364236523662367236823692370237123722373237423752376237723782379238023812382238323842385238623872388238923902391239223932394239523962397239823992400240124022403240424052406240724082409241024112412241324142415241624172418241924202421242224232424242524262427242824292430243124322433243424352436243724382439244024412442244324442445244624472448244924502451245224532454245524562457245824592460246124622463246424652466246724682469247024712472247324742475247624772478247924802481248224832484248524862487248824892490249124922493249424952496249724982499250025012502250325042505250625072508250925102511251225132514251525162517251825192520252125222523252425252526252725282529253025312532253325342535253625372538253925402541254225432544254525462547254825492550255125522553255425552556255725582559256025612562256325642565256625672568256925702571257225732574257525762577257825792580258125822583258425852586258725882589259025912592259325942595259625972598259926002601260226032604260526062607260826092610261126122613261426152616261726182619262026212622262326242625262626272628262926302631263226332634263526362637263826392640264126422643264426452646264726482649265026512652265326542655265626572658265926602661266226632664266526662667266826692670267126722673267426752676267726782679268026812682268326842685268626872688268926902691269226932694269526962697269826992700270127022703270427052706270727082709271027112712271327142715271627172718271927202721272227232724272527262727272827292730273127322733273427352736273727382739274027412742274327442745274627472748274927502751275227532754275527562757275827592760276127622763276427652766276727682769277027712772277327742775277627772778277927802781278227832784278527862787278827892790279127922793279427952796279727982799280028012802280328042805280628072808280928102811281228132814281528162817281828192820282128222823282428252826282728282829283028312832283328342835283628372838283928402841284228432844284528462847284828492850285128522853285428552856285728582859286028612862286328642865286628672868286928702871287228732874287528762877287828792880288128822883288428852886288728882889289028912892289328942895289628972898289929002901290229032904290529062907290829092910291129122913291429152916291729182919292029212922292329242925292629272928292929302931293229332934293529362937293829392940294129422943294429452946294729482949295029512952295329542955295629572958295929602961296229632964296529662967296829692970297129722973297429752976297729782979298029812982298329842985298629872988298929902991299229932994299529962997299829993000300130023003300430053006300730083009301030113012301330143015301630173018301930203021302230233024302530263027302830293030303130323033303430353036303730383039304030413042304330443045304630473048304930503051305230533054305530563057305830593060306130623063306430653066306730683069307030713072307330743075307630773078307930803081308230833084308530863087308830893090309130923093309430953096309730983099310031013102310331043105310631073108310931103111311231133114311531163117311831193120312131223123312431253126312731283129313031313132313331343135313631373138313931403141314231433144314531463147314831493150315131523153315431553156315731583159316031613162316331643165316631673168316931703171317231733174317531763177317831793180318131823183318431853186318731883189319031913192319331943195319631973198319932003201320232033204320532063207320832093210321132123213321432153216321732183219322032213222322332243225322632273228322932303231323232333234323532363237323832393240324132423243324432453246324732483249325032513252325332543255325632573258325932603261326232633264326532663267326832693270327132723273327432753276327732783279328032813282328332843285328632873288328932903291329232933294329532963297329832993300330133023303330433053306330733083309331033113312331333143315331633173318331933203321332233233324332533263327332833293330333133323333333433353336333733383339334033413342334333443345334633473348334933503351335233533354335533563357335833593360336133623363336433653366336733683369337033713372337333743375337633773378337933803381338233833384338533863387338833893390339133923393339433953396339733983399340034013402340334043405340634073408340934103411341234133414341534163417341834193420342134223423342434253426342734283429343034313432343334343435343634373438343934403441344234433444344534463447344834493450345134523453345434553456345734583459346034613462346334643465346634673468346934703471347234733474347534763477347834793480348134823483348434853486348734883489349034913492349334943495349634973498349935003501350235033504350535063507350835093510351135123513351435153516351735183519352035213522352335243525352635273528352935303531353235333534353535363537353835393540354135423543354435453546354735483549355035513552355335543555355635573558355935603561356235633564356535663567356835693570357135723573357435753576357735783579358035813582358335843585358635873588358935903591359235933594359535963597359835993600360136023603360436053606360736083609361036113612361336143615361636173618361936203621362236233624362536263627362836293630363136323633363436353636363736383639364036413642364336443645364636473648364936503651365236533654365536563657365836593660366136623663366436653666366736683669367036713672367336743675367636773678367936803681368236833684368536863687368836893690369136923693369436953696369736983699370037013702370337043705370637073708370937103711371237133714371537163717371837193720372137223723372437253726372737283729373037313732373337343735373637373738373937403741374237433744374537463747374837493750375137523753375437553756375737583759376037613762376337643765376637673768376937703771377237733774377537763777377837793780378137823783378437853786378737883789379037913792379337943795379637973798379938003801380238033804380538063807380838093810381138123813381438153816381738183819382038213822382338243825382638273828382938303831383238333834383538363837383838393840384138423843384438453846384738483849385038513852385338543855385638573858385938603861386238633864386538663867386838693870387138723873387438753876387738783879388038813882388338843885388638873888388938903891389238933894389538963897389838993900390139023903390439053906390739083909391039113912391339143915391639173918391939203921392239233924392539263927392839293930393139323933393439353936393739383939394039413942394339443945394639473948394939503951395239533954395539563957395839593960396139623963396439653966396739683969397039713972397339743975397639773978397939803981398239833984398539863987398839893990399139923993399439953996399739983999400040014002400340044005400640074008400940104011401240134014401540164017401840194020402140224023402440254026402740284029403040314032403340344035403640374038403940404041404240434044404540464047404840494050405140524053405440554056405740584059406040614062406340644065406640674068406940704071407240734074407540764077407840794080408140824083408440854086408740884089409040914092409340944095409640974098409941004101410241034104410541064107410841094110411141124113411441154116411741184119412041214122412341244125412641274128412941304131413241334134413541364137413841394140414141424143414441454146414741484149415041514152415341544155415641574158415941604161416241634164416541664167416841694170417141724173417441754176417741784179418041814182418341844185418641874188418941904191419241934194419541964197419841994200420142024203420442054206420742084209421042114212421342144215421642174218421942204221422242234224422542264227422842294230423142324233423442354236423742384239424042414242424342444245424642474248424942504251425242534254425542564257425842594260426142624263426442654266426742684269427042714272427342744275427642774278427942804281428242834284428542864287428842894290429142924293429442954296429742984299430043014302430343044305430643074308430943104311431243134314431543164317431843194320432143224323432443254326432743284329433043314332433343344335433643374338433943404341434243434344434543464347434843494350435143524353435443554356435743584359436043614362436343644365436643674368436943704371437243734374437543764377437843794380438143824383438443854386438743884389439043914392439343944395439643974398439944004401440244034404440544064407440844094410441144124413441444154416441744184419442044214422442344244425442644274428442944304431443244334434443544364437443844394440444144424443444444454446444744484449445044514452445344544455445644574458445944604461446244634464446544664467446844694470447144724473447444754476447744784479448044814482448344844485448644874488448944904491449244934494449544964497449844994500450145024503450445054506450745084509451045114512451345144515451645174518451945204521452245234524452545264527452845294530453145324533453445354536453745384539454045414542454345444545454645474548454945504551455245534554455545564557455845594560456145624563456445654566456745684569457045714572457345744575457645774578457945804581458245834584458545864587458845894590459145924593459445954596459745984599460046014602460346044605460646074608460946104611461246134614461546164617461846194620462146224623462446254626462746284629463046314632463346344635463646374638463946404641464246434644464546464647464846494650465146524653465446554656465746584659466046614662466346644665466646674668466946704671467246734674467546764677467846794680468146824683468446854686468746884689469046914692469346944695469646974698469947004701470247034704470547064707470847094710471147124713471447154716471747184719472047214722472347244725472647274728472947304731473247334734473547364737473847394740474147424743474447454746474747484749475047514752475347544755475647574758475947604761476247634764476547664767476847694770477147724773477447754776477747784779478047814782478347844785478647874788478947904791479247934794479547964797479847994800480148024803480448054806480748084809481048114812481348144815481648174818481948204821482248234824482548264827482848294830483148324833483448354836483748384839484048414842484348444845484648474848484948504851485248534854485548564857485848594860486148624863486448654866486748684869487048714872487348744875487648774878487948804881488248834884488548864887488848894890489148924893489448954896489748984899490049014902490349044905490649074908490949104911491249134914491549164917491849194920492149224923492449254926492749284929493049314932493349344935493649374938493949404941494249434944494549464947494849494950495149524953495449554956495749584959496049614962496349644965496649674968496949704971497249734974497549764977497849794980498149824983498449854986498749884989499049914992499349944995499649974998499950005001500250035004500550065007500850095010501150125013501450155016501750185019502050215022502350245025502650275028502950305031503250335034503550365037503850395040504150425043504450455046504750485049505050515052505350545055505650575058505950605061506250635064506550665067506850695070507150725073507450755076507750785079508050815082508350845085508650875088508950905091509250935094509550965097509850995100510151025103510451055106510751085109511051115112511351145115511651175118511951205121512251235124512551265127512851295130513151325133513451355136513751385139514051415142514351445145514651475148514951505151515251535154515551565157515851595160516151625163516451655166516751685169517051715172517351745175517651775178517951805181518251835184518551865187518851895190519151925193519451955196519751985199520052015202520352045205520652075208520952105211521252135214521552165217521852195220522152225223522452255226522752285229523052315232523352345235523652375238523952405241524252435244524552465247524852495250525152525253525452555256525752585259526052615262526352645265526652675268526952705271527252735274527552765277527852795280528152825283528452855286528752885289529052915292529352945295529652975298529953005301530253035304530553065307530853095310531153125313531453155316531753185319532053215322532353245325532653275328532953305331533253335334533553365337533853395340534153425343534453455346534753485349535053515352535353545355535653575358535953605361536253635364536553665367536853695370537153725373537453755376537753785379538053815382538353845385538653875388538953905391539253935394539553965397539853995400540154025403540454055406540754085409541054115412541354145415541654175418541954205421542254235424542554265427542854295430543154325433543454355436543754385439544054415442544354445445544654475448544954505451545254535454545554565457545854595460546154625463546454655466546754685469547054715472547354745475547654775478547954805481548254835484548554865487548854895490549154925493549454955496549754985499550055015502550355045505550655075508550955105511551255135514551555165517551855195520552155225523552455255526552755285529553055315532553355345535553655375538553955405541554255435544554555465547554855495550555155525553555455555556555755585559556055615562556355645565556655675568556955705571557255735574557555765577557855795580558155825583558455855586558755885589559055915592559355945595559655975598559956005601560256035604560556065607560856095610561156125613561456155616561756185619562056215622562356245625562656275628562956305631563256335634563556365637563856395640564156425643564456455646564756485649565056515652565356545655565656575658565956605661566256635664566556665667566856695670567156725673567456755676567756785679568056815682568356845685568656875688568956905691569256935694569556965697569856995700570157025703570457055706570757085709571057115712571357145715571657175718571957205721572257235724572557265727572857295730573157325733573457355736573757385739574057415742574357445745574657475748574957505751575257535754575557565757575857595760576157625763576457655766576757685769577057715772577357745775577657775778577957805781578257835784578557865787578857895790579157925793579457955796579757985799580058015802580358045805580658075808580958105811581258135814581558165817581858195820582158225823582458255826582758285829583058315832583358345835583658375838583958405841584258435844584558465847584858495850585158525853585458555856585758585859586058615862586358645865586658675868586958705871587258735874587558765877587858795880588158825883588458855886588758885889589058915892589358945895589658975898589959005901590259035904590559065907590859095910591159125913591459155916591759185919592059215922592359245925592659275928592959305931593259335934593559365937593859395940594159425943594459455946594759485949595059515952595359545955595659575958595959605961596259635964596559665967596859695970597159725973597459755976597759785979598059815982598359845985598659875988598959905991599259935994599559965997599859996000600160026003600460056006600760086009601060116012601360146015601660176018601960206021602260236024602560266027602860296030603160326033603460356036603760386039604060416042604360446045604660476048604960506051605260536054605560566057605860596060606160626063606460656066606760686069607060716072607360746075607660776078607960806081608260836084608560866087608860896090609160926093609460956096609760986099610061016102610361046105610661076108610961106111611261136114611561166117611861196120612161226123612461256126612761286129613061316132613361346135613661376138613961406141614261436144614561466147614861496150615161526153615461556156615761586159616061616162616361646165616661676168616961706171617261736174617561766177617861796180618161826183618461856186618761886189619061916192619361946195619661976198619962006201620262036204620562066207620862096210621162126213621462156216621762186219622062216222622362246225622662276228622962306231623262336234623562366237623862396240624162426243624462456246624762486249625062516252625362546255625662576258625962606261626262636264626562666267626862696270627162726273627462756276627762786279628062816282628362846285628662876288628962906291629262936294629562966297629862996300630163026303630463056306630763086309631063116312631363146315631663176318631963206321632263236324632563266327632863296330633163326333633463356336633763386339634063416342634363446345634663476348634963506351635263536354635563566357635863596360636163626363636463656366636763686369637063716372637363746375637663776378637963806381638263836384638563866387638863896390639163926393639463956396639763986399640064016402640364046405640664076408640964106411641264136414641564166417641864196420642164226423642464256426642764286429643064316432643364346435643664376438643964406441644264436444644564466447644864496450645164526453645464556456645764586459646064616462646364646465646664676468646964706471647264736474647564766477647864796480648164826483648464856486648764886489649064916492649364946495649664976498649965006501650265036504650565066507650865096510651165126513651465156516651765186519652065216522652365246525652665276528652965306531653265336534653565366537653865396540654165426543654465456546654765486549655065516552655365546555655665576558655965606561656265636564656565666567656865696570657165726573657465756576657765786579658065816582658365846585658665876588658965906591659265936594659565966597659865996600660166026603660466056606660766086609661066116612661366146615661666176618661966206621662266236624662566266627662866296630663166326633663466356636663766386639664066416642664366446645664666476648664966506651665266536654665566566657665866596660666166626663666466656666666766686669667066716672667366746675667666776678667966806681668266836684668566866687668866896690669166926693669466956696669766986699670067016702670367046705670667076708670967106711671267136714671567166717671867196720672167226723672467256726672767286729673067316732673367346735673667376738673967406741674267436744674567466747674867496750675167526753675467556756
  1. """
  2. @package psmap.dialogs
  3. @brief dialogs for wxPsMap
  4. Classes:
  5. - dialogs::TCValidator
  6. - dialogs::PenStyleComboBox
  7. - dialogs::CheckListCtrl
  8. - dialogs::PsmapDialog
  9. - dialogs::PageSetupDialog
  10. - dialogs::MapDialog
  11. - dialogs::MapFramePanel
  12. - dialogs::RasterPanel
  13. - dialogs::VectorPanel
  14. - dialogs::RasterDialog
  15. - dialogs::MainVectorDialog
  16. - dialogs::VPropertiesDialog
  17. - dialogs::LegendDialog
  18. - dialogs::MapinfoDialog
  19. - dialogs::ScalebarDialog
  20. - dialogs::TextDialog
  21. - dialogs::ImageDialog
  22. - dialogs::NorthArrowDialog
  23. - dialogs::PointDialog
  24. - dialogs::RectangleDialog
  25. (C) 2011-2012 by Anna Kratochvilova, and the GRASS Development Team
  26. This program is free software under the GNU General Public License
  27. (>=v2). Read the file COPYING that comes with GRASS for details.
  28. @author Anna Kratochvilova <kratochanna gmail.com> (bachelor's project)
  29. @author Martin Landa <landa.martin gmail.com> (mentor)
  30. """
  31. import os
  32. import string
  33. import sys
  34. from copy import deepcopy
  35. import wx
  36. import wx.lib.agw.floatspin as fs
  37. from wx.lib.mixins.listctrl import ListCtrlAutoWidthMixin
  38. from core import globalvar
  39. if globalvar.wxPythonPhoenix:
  40. from wx import Validator
  41. else:
  42. from wx import PyValidator as Validator
  43. import grass.script as grass
  44. from core.utils import PilImageToWxImage
  45. from dbmgr.vinfo import VectorDBInfo
  46. from gui_core.gselect import Select
  47. from core.gcmd import RunCommand, GError, GMessage
  48. from gui_core.dialogs import SymbolDialog
  49. from gui_core.wrap import (
  50. BitmapButton,
  51. BitmapComboBox,
  52. BitmapFromImage,
  53. Button,
  54. CheckBox,
  55. Choice,
  56. ClientDC,
  57. ColourPickerCtrl,
  58. Dialog,
  59. DirBrowseButton,
  60. EmptyBitmap,
  61. ExpandoTextCtrl,
  62. FileBrowseButton,
  63. FloatSpin,
  64. ListBox,
  65. ListCtrl,
  66. Notebook,
  67. OwnerDrawnComboBox,
  68. Panel,
  69. RadioButton,
  70. Rect,
  71. ScrolledPanel,
  72. SpinCtrl,
  73. StaticBox,
  74. StaticText,
  75. TextCtrl,
  76. TextEntryDialog,
  77. EmptyImage,
  78. CheckListCtrlMixin,
  79. )
  80. from psmap.utils import *
  81. from psmap.instructions import *
  82. # grass.set_raise_on_error(True)
  83. PSMAP_COLORS = [
  84. "aqua",
  85. "black",
  86. "blue",
  87. "brown",
  88. "cyan",
  89. "gray",
  90. "grey",
  91. "green",
  92. "indigo",
  93. "magenta",
  94. "orange",
  95. "purple",
  96. "red",
  97. "violet",
  98. "white",
  99. "yellow",
  100. ]
  101. class TCValidator(Validator):
  102. """validates input in textctrls, combobox, taken from wxpython demo"""
  103. def __init__(self, flag=None):
  104. Validator.__init__(self)
  105. self.flag = flag
  106. self.Bind(wx.EVT_CHAR, self.OnChar)
  107. def Clone(self):
  108. return TCValidator(self.flag)
  109. def Validate(self, win):
  110. tc = self.GetWindow()
  111. val = tc.GetValue()
  112. if self.flag == "DIGIT_ONLY":
  113. for x in val:
  114. if x not in string.digits:
  115. return False
  116. return True
  117. def OnChar(self, event):
  118. key = event.GetKeyCode()
  119. if key < wx.WXK_SPACE or key == wx.WXK_DELETE or key > 255:
  120. event.Skip()
  121. return
  122. if self.flag == "DIGIT_ONLY" and chr(key) in string.digits + ".-":
  123. event.Skip()
  124. return
  125. # if self.flag == 'SCALE' and chr(key) in string.digits + ':':
  126. # event.Skip()
  127. # return
  128. if self.flag == "ZERO_AND_ONE_ONLY" and chr(key) in "01":
  129. event.Skip()
  130. return
  131. if not wx.Validator_IsSilent():
  132. wx.Bell()
  133. # Returning without calling even.Skip eats the event before it
  134. # gets to the text control
  135. return
  136. class PenStyleComboBox(OwnerDrawnComboBox):
  137. """Combo for selecting line style, taken from wxpython demo"""
  138. # Overridden from OwnerDrawnComboBox, called to draw each
  139. # item in the list
  140. def OnDrawItem(self, dc, rect, item, flags):
  141. if item == wx.NOT_FOUND:
  142. # painting the control, but there is no valid item selected yet
  143. return
  144. r = Rect(*rect) # make a copy
  145. r.Deflate(3, 5)
  146. penStyle = wx.SOLID
  147. if item == 1:
  148. penStyle = wx.LONG_DASH
  149. elif item == 2:
  150. penStyle = wx.DOT
  151. elif item == 3:
  152. penStyle = wx.DOT_DASH
  153. pen = wx.Pen(dc.GetTextForeground(), 3, penStyle)
  154. dc.SetPen(pen)
  155. # for painting the items in the popup
  156. dc.DrawText(
  157. self.GetString(item),
  158. r.x + 3,
  159. (r.y + 0) + ((r.height / 2) - dc.GetCharHeight()) / 2,
  160. )
  161. dc.DrawLine(
  162. r.x + 5,
  163. r.y + ((r.height / 4) * 3) + 1,
  164. r.x + r.width - 5,
  165. r.y + ((r.height / 4) * 3) + 1,
  166. )
  167. def OnDrawBackground(self, dc, rect, item, flags):
  168. """Overridden from OwnerDrawnComboBox, called for drawing the
  169. background area of each item."""
  170. # If the item is selected, or its item # iseven, or we are painting the
  171. # combo control itself, then use the default rendering.
  172. if item & 1 == 0 or flags & (
  173. OwnerDrawnComboBox.ODCB_PAINTING_CONTROL
  174. | OwnerDrawnComboBox.ODCB_PAINTING_SELECTED
  175. ):
  176. OwnerDrawnComboBox.OnDrawBackground(self, dc, rect, item, flags)
  177. return
  178. # Otherwise, draw every other background with different colour.
  179. bgCol = wx.Colour(240, 240, 250)
  180. dc.SetBrush(wx.Brush(bgCol))
  181. dc.SetPen(wx.Pen(bgCol))
  182. if globalvar.wxPythonPhoenix:
  183. dc.DrawRectangle(rect)
  184. else:
  185. dc.DrawRectangleRect(rect)
  186. def OnMeasureItem(self, item):
  187. """Overridden from OwnerDrawnComboBox, should return the height
  188. needed to display an item in the popup, or -1 for default"""
  189. return 30
  190. def OnMeasureItemWidth(self, item):
  191. """Overridden from OwnerDrawnComboBox. Callback for item width, or
  192. -1 for default/undetermined"""
  193. return -1 # default - will be measured from text width
  194. class CheckListCtrl(ListCtrl, CheckListCtrlMixin, ListCtrlAutoWidthMixin):
  195. """List control for managing order and labels of vector maps in legend"""
  196. def __init__(self, parent):
  197. ListCtrl.__init__(
  198. self,
  199. parent,
  200. id=wx.ID_ANY,
  201. style=wx.LC_REPORT
  202. | wx.LC_SINGLE_SEL
  203. | wx.BORDER_SUNKEN
  204. | wx.LC_VRULES
  205. | wx.LC_HRULES,
  206. )
  207. CheckListCtrlMixin.__init__(self)
  208. ListCtrlAutoWidthMixin.__init__(self)
  209. class PsmapDialog(Dialog):
  210. def __init__(self, parent, id, title, settings, env, apply=True):
  211. Dialog.__init__(
  212. self,
  213. parent=parent,
  214. id=wx.ID_ANY,
  215. title=title,
  216. size=wx.DefaultSize,
  217. style=wx.CAPTION | wx.MINIMIZE_BOX | wx.CLOSE_BOX,
  218. )
  219. self.apply = apply
  220. self.id = id
  221. self.env = env
  222. self.parent = parent
  223. self.instruction = settings
  224. self.objectType = None
  225. self.unitConv = UnitConversion(self)
  226. self.spinCtrlSize = (65, -1)
  227. self.Bind(wx.EVT_CLOSE, self.OnClose)
  228. def AddUnits(self, parent, dialogDict):
  229. parent.units = dict()
  230. parent.units["unitsLabel"] = StaticText(parent, id=wx.ID_ANY, label=_("Units:"))
  231. choices = self.unitConv.getPageUnitsNames()
  232. parent.units["unitsCtrl"] = Choice(parent, id=wx.ID_ANY, choices=choices)
  233. parent.units["unitsCtrl"].SetStringSelection(
  234. self.unitConv.findName(dialogDict["unit"])
  235. )
  236. def AddPosition(self, parent, dialogDict):
  237. if not hasattr(parent, "position"):
  238. parent.position = dict()
  239. parent.position["comment"] = StaticText(
  240. parent,
  241. id=wx.ID_ANY,
  242. label=_(
  243. "Position of the top left corner\nfrom the top left edge of the paper"
  244. ),
  245. )
  246. parent.position["xLabel"] = StaticText(parent, id=wx.ID_ANY, label=_("X:"))
  247. parent.position["yLabel"] = StaticText(parent, id=wx.ID_ANY, label=_("Y:"))
  248. parent.position["xCtrl"] = TextCtrl(
  249. parent,
  250. id=wx.ID_ANY,
  251. value=str(dialogDict["where"][0]),
  252. validator=TCValidator(flag="DIGIT_ONLY"),
  253. )
  254. parent.position["yCtrl"] = TextCtrl(
  255. parent,
  256. id=wx.ID_ANY,
  257. value=str(dialogDict["where"][1]),
  258. validator=TCValidator(flag="DIGIT_ONLY"),
  259. )
  260. if "unit" in dialogDict:
  261. x = self.unitConv.convert(
  262. value=dialogDict["where"][0], fromUnit="inch", toUnit=dialogDict["unit"]
  263. )
  264. y = self.unitConv.convert(
  265. value=dialogDict["where"][1], fromUnit="inch", toUnit=dialogDict["unit"]
  266. )
  267. parent.position["xCtrl"].SetValue("%5.3f" % x)
  268. parent.position["yCtrl"].SetValue("%5.3f" % y)
  269. def AddExtendedPosition(self, panel, gridBagSizer, dialogDict):
  270. """Add widgets for setting position relative to paper and to map"""
  271. panel.position = dict()
  272. positionLabel = StaticText(panel, id=wx.ID_ANY, label=_("Position is given:"))
  273. panel.position["toPaper"] = RadioButton(
  274. panel, id=wx.ID_ANY, label=_("relative to paper"), style=wx.RB_GROUP
  275. )
  276. panel.position["toMap"] = RadioButton(
  277. panel, id=wx.ID_ANY, label=_("by map coordinates")
  278. )
  279. panel.position["toPaper"].SetValue(dialogDict["XY"])
  280. panel.position["toMap"].SetValue(not dialogDict["XY"])
  281. gridBagSizer.Add(
  282. positionLabel,
  283. pos=(0, 0),
  284. span=(1, 3),
  285. flag=wx.ALIGN_CENTER_VERTICAL | wx.ALIGN_LEFT,
  286. border=0,
  287. )
  288. gridBagSizer.Add(
  289. panel.position["toPaper"],
  290. pos=(1, 0),
  291. flag=wx.ALIGN_CENTER_VERTICAL | wx.ALIGN_LEFT,
  292. border=0,
  293. )
  294. gridBagSizer.Add(
  295. panel.position["toMap"],
  296. pos=(1, 1),
  297. flag=wx.ALIGN_CENTER_VERTICAL | wx.ALIGN_LEFT,
  298. border=0,
  299. )
  300. # first box - paper coordinates
  301. box1 = StaticBox(parent=panel, id=wx.ID_ANY, label="")
  302. sizerP = wx.StaticBoxSizer(box1, wx.VERTICAL)
  303. self.gridBagSizerP = wx.GridBagSizer(hgap=5, vgap=5)
  304. self.AddPosition(parent=panel, dialogDict=dialogDict)
  305. panel.position["comment"].SetLabel(
  306. _("Position from the top left\nedge of the paper")
  307. )
  308. self.AddUnits(parent=panel, dialogDict=dialogDict)
  309. self.gridBagSizerP.Add(
  310. panel.units["unitsLabel"],
  311. pos=(0, 0),
  312. flag=wx.ALIGN_CENTER_VERTICAL,
  313. border=0,
  314. )
  315. self.gridBagSizerP.Add(
  316. panel.units["unitsCtrl"],
  317. pos=(0, 1),
  318. flag=wx.ALIGN_CENTER_VERTICAL,
  319. border=0,
  320. )
  321. self.gridBagSizerP.Add(
  322. panel.position["xLabel"],
  323. pos=(1, 0),
  324. flag=wx.ALIGN_CENTER_VERTICAL,
  325. border=0,
  326. )
  327. self.gridBagSizerP.Add(
  328. panel.position["xCtrl"], pos=(1, 1), flag=wx.ALIGN_CENTER_VERTICAL, border=0
  329. )
  330. self.gridBagSizerP.Add(
  331. panel.position["yLabel"],
  332. pos=(2, 0),
  333. flag=wx.ALIGN_CENTER_VERTICAL,
  334. border=0,
  335. )
  336. self.gridBagSizerP.Add(
  337. panel.position["yCtrl"], pos=(2, 1), flag=wx.ALIGN_CENTER_VERTICAL, border=0
  338. )
  339. self.gridBagSizerP.Add(
  340. panel.position["comment"],
  341. pos=(3, 0),
  342. span=(1, 2),
  343. flag=wx.ALIGN_BOTTOM,
  344. border=0,
  345. )
  346. self.gridBagSizerP.AddGrowableCol(1)
  347. self.gridBagSizerP.AddGrowableRow(3)
  348. sizerP.Add(self.gridBagSizerP, proportion=1, flag=wx.EXPAND | wx.ALL, border=5)
  349. gridBagSizer.Add(
  350. sizerP,
  351. pos=(2, 0),
  352. span=(1, 1),
  353. flag=wx.ALIGN_CENTER_HORIZONTAL | wx.EXPAND,
  354. border=0,
  355. )
  356. # second box - map coordinates
  357. box2 = StaticBox(parent=panel, id=wx.ID_ANY, label="")
  358. sizerM = wx.StaticBoxSizer(box2, wx.VERTICAL)
  359. self.gridBagSizerM = wx.GridBagSizer(hgap=5, vgap=5)
  360. eastingLabel = StaticText(panel, id=wx.ID_ANY, label="E:")
  361. northingLabel = StaticText(panel, id=wx.ID_ANY, label="N:")
  362. panel.position["eCtrl"] = TextCtrl(panel, id=wx.ID_ANY, value="")
  363. panel.position["nCtrl"] = TextCtrl(panel, id=wx.ID_ANY, value="")
  364. east, north = PaperMapCoordinates(
  365. mapInstr=self.instruction[self.mapId],
  366. x=dialogDict["where"][0],
  367. y=dialogDict["where"][1],
  368. paperToMap=True,
  369. env=self.env,
  370. )
  371. panel.position["eCtrl"].SetValue(str(east))
  372. panel.position["nCtrl"].SetValue(str(north))
  373. self.gridBagSizerM.Add(
  374. eastingLabel, pos=(0, 0), flag=wx.ALIGN_CENTER_VERTICAL, border=0
  375. )
  376. self.gridBagSizerM.Add(
  377. northingLabel, pos=(1, 0), flag=wx.ALIGN_CENTER_VERTICAL, border=0
  378. )
  379. self.gridBagSizerM.Add(
  380. panel.position["eCtrl"], pos=(0, 1), flag=wx.ALIGN_CENTER_VERTICAL, border=0
  381. )
  382. self.gridBagSizerM.Add(
  383. panel.position["nCtrl"], pos=(1, 1), flag=wx.ALIGN_CENTER_VERTICAL, border=0
  384. )
  385. self.gridBagSizerM.AddGrowableCol(0)
  386. self.gridBagSizerM.AddGrowableCol(1)
  387. sizerM.Add(self.gridBagSizerM, proportion=1, flag=wx.EXPAND | wx.ALL, border=5)
  388. gridBagSizer.Add(sizerM, pos=(2, 1), flag=wx.ALIGN_LEFT | wx.EXPAND, border=0)
  389. def AddFont(self, parent, dialogDict, color=True):
  390. parent.font = dict()
  391. ## parent.font['fontLabel'] = wx.StaticText(parent, id = wx.ID_ANY, label = _("Choose font:"))
  392. ## parent.font['fontCtrl'] = wx.FontPickerCtrl(parent, id = wx.ID_ANY)
  393. ##
  394. # parent.font['fontCtrl'].SetSelectedFont(
  395. # wx.FontFromNativeInfoString(dialogDict['font'] + " " + str(dialogDict['fontsize'])))
  396. # parent.font['fontCtrl'].SetMaxPointSize(50)
  397. ##
  398. # if color:
  399. ## parent.font['colorLabel'] = wx.StaticText(parent, id = wx.ID_ANY, label = _("Choose color:"))
  400. ## parent.font['colorCtrl'] = ColourPickerCtrl(parent, id = wx.ID_ANY, style=wx.FNTP_FONTDESC_AS_LABEL)
  401. # parent.font['colorCtrl'].SetColour(dialogDict['color'])
  402. # parent.font['colorCtrl'].SetColour(convertRGB(dialogDict['color']))
  403. parent.font["fontLabel"] = StaticText(parent, id=wx.ID_ANY, label=_("Font:"))
  404. parent.font["fontSizeLabel"] = StaticText(
  405. parent, id=wx.ID_ANY, label=_("Font size:")
  406. )
  407. fontChoices = [
  408. "Times-Roman",
  409. "Times-Italic",
  410. "Times-Bold",
  411. "Times-BoldItalic",
  412. "Helvetica",
  413. "Helvetica-Oblique",
  414. "Helvetica-Bold",
  415. "Helvetica-BoldOblique",
  416. "Courier",
  417. "Courier-Oblique",
  418. "Courier-Bold",
  419. "Courier-BoldOblique",
  420. ]
  421. parent.font["fontCtrl"] = Choice(parent, id=wx.ID_ANY, choices=fontChoices)
  422. if dialogDict["font"] in fontChoices:
  423. parent.font["fontCtrl"].SetStringSelection(dialogDict["font"])
  424. else:
  425. parent.font["fontCtrl"].SetStringSelection("Helvetica")
  426. parent.font["fontSizeCtrl"] = SpinCtrl(
  427. parent, id=wx.ID_ANY, min=4, max=50, initial=10
  428. )
  429. parent.font["fontSizeCtrl"].SetValue(dialogDict["fontsize"])
  430. if color:
  431. parent.font["colorLabel"] = StaticText(
  432. parent, id=wx.ID_ANY, label=_("Choose color:")
  433. )
  434. parent.font["colorCtrl"] = ColourPickerCtrl(parent, id=wx.ID_ANY)
  435. parent.font["colorCtrl"].SetColour(convertRGB(dialogDict["color"]))
  436. ## parent.font['colorLabel'] = wx.StaticText(parent, id = wx.ID_ANY, label = _("Color:"))
  437. # colorChoices = [ 'aqua', 'black', 'blue', 'brown', 'cyan', 'gray', 'green', 'indigo', 'magenta',\
  438. # 'orange', 'purple', 'red', 'violet', 'white', 'yellow']
  439. ## parent.colorCtrl = Choice(parent, id = wx.ID_ANY, choices = colorChoices)
  440. # parent.colorCtrl.SetStringSelection(parent.rLegendDict['color'])
  441. ## parent.font['colorCtrl'] = ColourPickerCtrl(parent, id = wx.ID_ANY)
  442. # parent.font['colorCtrl'].SetColour(dialogDict['color'])
  443. def OnApply(self, event):
  444. ok = self.update()
  445. if ok:
  446. self.parent.DialogDataChanged(id=self.id)
  447. return True
  448. else:
  449. return False
  450. def OnOK(self, event):
  451. """Apply changes, close dialog"""
  452. ok = self.OnApply(event)
  453. if ok:
  454. self.Close()
  455. def OnCancel(self, event):
  456. """Close dialog"""
  457. self.Close()
  458. def OnClose(self, event):
  459. """Destroy dialog and delete it from open dialogs"""
  460. if self.objectType:
  461. for each in self.objectType:
  462. if each in self.parent.openDialogs:
  463. del self.parent.openDialogs[each]
  464. event.Skip()
  465. self.Destroy()
  466. def _layout(self, panel):
  467. # buttons
  468. btnCancel = Button(self, wx.ID_CANCEL)
  469. btnOK = Button(self, wx.ID_OK)
  470. btnOK.SetDefault()
  471. if self.apply:
  472. btnApply = Button(self, wx.ID_APPLY)
  473. # bindigs
  474. btnOK.Bind(wx.EVT_BUTTON, self.OnOK)
  475. btnOK.SetToolTip(_("Close dialog and apply changes"))
  476. # btnCancel.Bind(wx.EVT_BUTTON, self.OnCancel)
  477. btnCancel.SetToolTip(_("Close dialog and ignore changes"))
  478. btnCancel.Bind(wx.EVT_BUTTON, self.OnCancel)
  479. if self.apply:
  480. btnApply.Bind(wx.EVT_BUTTON, self.OnApply)
  481. btnApply.SetToolTip(_("Apply changes"))
  482. # sizers
  483. btnSizer = wx.StdDialogButtonSizer()
  484. btnSizer.AddButton(btnCancel)
  485. if self.apply:
  486. btnSizer.AddButton(btnApply)
  487. btnSizer.AddButton(btnOK)
  488. btnSizer.Realize()
  489. mainSizer = wx.BoxSizer(wx.VERTICAL)
  490. mainSizer.Add(panel, proportion=1, flag=wx.EXPAND | wx.ALL, border=5)
  491. mainSizer.Add(btnSizer, proportion=0, flag=wx.EXPAND | wx.ALL, border=5)
  492. self.SetSizer(mainSizer)
  493. mainSizer.Layout()
  494. mainSizer.Fit(self)
  495. class PageSetupDialog(PsmapDialog):
  496. def __init__(self, parent, id, settings, env):
  497. PsmapDialog.__init__(
  498. self, parent=parent, id=id, title="Page setup", settings=settings, env=env
  499. )
  500. self.cat = [
  501. "Units",
  502. "Format",
  503. "Orientation",
  504. "Width",
  505. "Height",
  506. "Left",
  507. "Right",
  508. "Top",
  509. "Bottom",
  510. ]
  511. labels = [
  512. _("Units"),
  513. _("Format"),
  514. _("Orientation"),
  515. _("Width"),
  516. _("Height"),
  517. _("Left"),
  518. _("Right"),
  519. _("Top"),
  520. _("Bottom"),
  521. ]
  522. self.catsLabels = dict(zip(self.cat, labels))
  523. paperString = RunCommand("ps.map", flags="p", read=True, quiet=True)
  524. self.paperTable = self._toList(paperString)
  525. self.unitsList = self.unitConv.getPageUnitsNames()
  526. self.pageSetupDict = settings[id].GetInstruction()
  527. self._layout()
  528. if self.pageSetupDict:
  529. self.getCtrl("Units").SetStringSelection(
  530. self.unitConv.findName(self.pageSetupDict["Units"])
  531. )
  532. if self.pageSetupDict["Format"] == "custom":
  533. self.getCtrl("Format").SetSelection(
  534. self.getCtrl("Format").GetCount() - 1
  535. )
  536. else:
  537. self.getCtrl("Format").SetStringSelection(self.pageSetupDict["Format"])
  538. if self.pageSetupDict["Orientation"] == "Portrait":
  539. self.getCtrl("Orientation").SetSelection(0)
  540. else:
  541. self.getCtrl("Orientation").SetSelection(1)
  542. for item in self.cat[3:]:
  543. val = self.unitConv.convert(
  544. value=self.pageSetupDict[item],
  545. fromUnit="inch",
  546. toUnit=self.pageSetupDict["Units"],
  547. )
  548. self.getCtrl(item).SetValue("%4.3f" % val)
  549. if (
  550. self.getCtrl("Format").GetSelection()
  551. != self.getCtrl("Format").GetCount() - 1
  552. ): # custom
  553. self.getCtrl("Width").Disable()
  554. self.getCtrl("Height").Disable()
  555. else:
  556. self.getCtrl("Orientation").Disable()
  557. # events
  558. self.getCtrl("Units").Bind(wx.EVT_CHOICE, self.OnChoice)
  559. self.getCtrl("Format").Bind(wx.EVT_CHOICE, self.OnChoice)
  560. self.getCtrl("Orientation").Bind(wx.EVT_CHOICE, self.OnChoice)
  561. self.btnOk.Bind(wx.EVT_BUTTON, self.OnOK)
  562. def update(self):
  563. self.pageSetupDict["Units"] = self.unitConv.findUnit(
  564. self.getCtrl("Units").GetStringSelection()
  565. )
  566. self.pageSetupDict["Format"] = self.paperTable[
  567. self.getCtrl("Format").GetSelection()
  568. ]["Format"]
  569. if self.getCtrl("Orientation").GetSelection() == 0:
  570. self.pageSetupDict["Orientation"] = "Portrait"
  571. else:
  572. self.pageSetupDict["Orientation"] = "Landscape"
  573. for item in self.cat[3:]:
  574. self.pageSetupDict[item] = self.unitConv.convert(
  575. value=float(self.getCtrl(item).GetValue()),
  576. fromUnit=self.pageSetupDict["Units"],
  577. toUnit="inch",
  578. )
  579. def OnOK(self, event):
  580. try:
  581. self.update()
  582. except ValueError:
  583. wx.MessageBox(
  584. message=_("Literal is not allowed!"),
  585. caption=_("Invalid input"),
  586. style=wx.OK | wx.ICON_ERROR,
  587. )
  588. else:
  589. event.Skip()
  590. def _layout(self):
  591. size = (110, -1)
  592. # sizers
  593. mainSizer = wx.BoxSizer(wx.VERTICAL)
  594. pageBox = StaticBox(self, id=wx.ID_ANY, label=" %s " % _("Page size"))
  595. pageSizer = wx.StaticBoxSizer(pageBox, wx.VERTICAL)
  596. marginBox = StaticBox(self, id=wx.ID_ANY, label=" %s " % _("Margins"))
  597. marginSizer = wx.StaticBoxSizer(marginBox, wx.VERTICAL)
  598. horSizer = wx.BoxSizer(wx.HORIZONTAL)
  599. # staticText + choice
  600. choices = [
  601. self.unitsList,
  602. [item["Format"] for item in self.paperTable],
  603. [_("Portrait"), _("Landscape")],
  604. ]
  605. propor = [0, 1, 1]
  606. border = [5, 3, 3]
  607. self.hBoxDict = {}
  608. for i, item in enumerate(self.cat[:3]):
  609. hBox = wx.BoxSizer(wx.HORIZONTAL)
  610. stText = StaticText(self, id=wx.ID_ANY, label=self.catsLabels[item] + ":")
  611. choice = Choice(self, id=wx.ID_ANY, choices=choices[i], size=size)
  612. hBox.Add(
  613. stText,
  614. proportion=propor[i],
  615. flag=wx.ALIGN_CENTER_VERTICAL | wx.ALL,
  616. border=border[i],
  617. )
  618. hBox.Add(choice, proportion=0, flag=wx.ALL, border=border[i])
  619. if item == "Units":
  620. hBox.Add(size, 1)
  621. self.hBoxDict[item] = hBox
  622. # staticText + TextCtrl
  623. for item in self.cat[3:]:
  624. hBox = wx.BoxSizer(wx.HORIZONTAL)
  625. label = StaticText(self, id=wx.ID_ANY, label=self.catsLabels[item] + ":")
  626. textctrl = TextCtrl(self, id=wx.ID_ANY, size=size, value="")
  627. hBox.Add(
  628. label, proportion=1, flag=wx.ALIGN_CENTER_VERTICAL | wx.ALL, border=3
  629. )
  630. hBox.Add(textctrl, proportion=0, flag=wx.ALIGN_CENTRE | wx.ALL, border=3)
  631. self.hBoxDict[item] = hBox
  632. sizer = list([mainSizer] + [pageSizer] * 4 + [marginSizer] * 4)
  633. for i, item in enumerate(self.cat):
  634. sizer[i].Add(self.hBoxDict[item], 0, wx.GROW | wx.RIGHT | wx.LEFT, 5)
  635. # OK button
  636. btnSizer = wx.StdDialogButtonSizer()
  637. self.btnOk = Button(self, wx.ID_OK)
  638. self.btnOk.SetDefault()
  639. btnSizer.AddButton(self.btnOk)
  640. btn = Button(self, wx.ID_CANCEL)
  641. btnSizer.AddButton(btn)
  642. btnSizer.Realize()
  643. horSizer.Add(
  644. pageSizer, proportion=0, flag=wx.LEFT | wx.RIGHT | wx.BOTTOM, border=10
  645. )
  646. horSizer.Add(
  647. marginSizer,
  648. proportion=0,
  649. flag=wx.LEFT | wx.RIGHT | wx.BOTTOM | wx.EXPAND,
  650. border=10,
  651. )
  652. mainSizer.Add(horSizer, proportion=0, border=10)
  653. mainSizer.Add(btnSizer, proportion=0, flag=wx.ALIGN_RIGHT | wx.ALL, border=10)
  654. self.SetSizer(mainSizer)
  655. mainSizer.Fit(self)
  656. def OnChoice(self, event):
  657. currPaper = self.paperTable[self.getCtrl("Format").GetSelection()]
  658. currUnit = self.unitConv.findUnit(self.getCtrl("Units").GetStringSelection())
  659. currOrientIdx = self.getCtrl("Orientation").GetSelection()
  660. newSize = dict()
  661. for item in self.cat[3:]:
  662. newSize[item] = self.unitConv.convert(
  663. float(currPaper[item]), fromUnit="inch", toUnit=currUnit
  664. )
  665. enable = True
  666. if currPaper["Format"] != _("custom"):
  667. if currOrientIdx == 1: # portrait
  668. newSize["Width"], newSize["Height"] = (
  669. newSize["Height"],
  670. newSize["Width"],
  671. )
  672. for item in self.cat[3:]:
  673. self.getCtrl(item).ChangeValue("%4.3f" % newSize[item])
  674. enable = False
  675. self.getCtrl("Width").Enable(enable)
  676. self.getCtrl("Height").Enable(enable)
  677. self.getCtrl("Orientation").Enable(not enable)
  678. def getCtrl(self, item):
  679. return self.hBoxDict[item].GetItem(1).GetWindow()
  680. def _toList(self, paperStr):
  681. sizeList = list()
  682. for line in paperStr.strip().split("\n"):
  683. d = dict(zip([self.cat[1]] + self.cat[3:], line.split()))
  684. sizeList.append(d)
  685. d = {}.fromkeys([self.cat[1]] + self.cat[3:], 100)
  686. d.update(Format=_("custom"))
  687. sizeList.append(d)
  688. return sizeList
  689. class MapDialog(PsmapDialog):
  690. """Dialog for map frame settings and optionally raster and vector map selection"""
  691. def __init__(self, parent, id, settings, env, rect=None, notebook=False):
  692. PsmapDialog.__init__(
  693. self, parent=parent, id=id, title="", settings=settings, env=env
  694. )
  695. self.isNotebook = notebook
  696. if self.isNotebook:
  697. self.objectType = ("mapNotebook",)
  698. else:
  699. self.objectType = ("map",)
  700. # notebook
  701. if self.isNotebook:
  702. self.notebook = Notebook(parent=self, id=wx.ID_ANY, style=wx.BK_DEFAULT)
  703. self.mPanel = MapFramePanel(
  704. parent=self.notebook,
  705. id=self.id[0],
  706. settings=self.instruction,
  707. env=env,
  708. rect=rect,
  709. notebook=True,
  710. )
  711. self.id[0] = self.mPanel.getId()
  712. self.rPanel = RasterPanel(
  713. parent=self.notebook,
  714. id=self.id[1],
  715. settings=self.instruction,
  716. env=env,
  717. notebook=True,
  718. )
  719. self.id[1] = self.rPanel.getId()
  720. self.vPanel = VectorPanel(
  721. parent=self.notebook,
  722. id=self.id[2],
  723. settings=self.instruction,
  724. env=env,
  725. notebook=True,
  726. )
  727. self.id[2] = self.vPanel.getId()
  728. self._layout(self.notebook)
  729. self.SetTitle(_("Map settings"))
  730. else:
  731. self.mPanel = MapFramePanel(
  732. parent=self,
  733. id=self.id[0],
  734. settings=self.instruction,
  735. env=env,
  736. rect=rect,
  737. notebook=False,
  738. )
  739. self.id[0] = self.mPanel.getId()
  740. self._layout(self.mPanel)
  741. self.SetTitle(_("Map frame settings"))
  742. def OnApply(self, event):
  743. """Apply changes"""
  744. if self.isNotebook:
  745. okV = self.vPanel.update()
  746. okR = self.rPanel.update()
  747. if okV and self.id[2] in self.instruction:
  748. self.parent.DialogDataChanged(id=self.id[2])
  749. if okR and self.id[1] in self.instruction:
  750. self.parent.DialogDataChanged(id=self.id[1])
  751. if not okR or not okV:
  752. return False
  753. ok = self.mPanel.update()
  754. if ok:
  755. self.parent.DialogDataChanged(id=self.id[0])
  756. return True
  757. return False
  758. def OnCancel(self, event):
  759. """Close dialog and remove tmp red box"""
  760. self.parent.canvas.pdcTmp.RemoveId(self.parent.canvas.idZoomBoxTmp)
  761. self.parent.canvas.Refresh()
  762. self.Close()
  763. def updateDialog(self):
  764. """Update raster and vector information"""
  765. if self.mPanel.scaleChoice.GetSelection() == 0:
  766. if self.mPanel.rasterTypeRadio.GetValue():
  767. if "raster" in self.parent.openDialogs:
  768. if (
  769. self.parent.openDialogs[
  770. "raster"
  771. ].rPanel.rasterYesRadio.GetValue()
  772. and self.parent.openDialogs[
  773. "raster"
  774. ].rPanel.rasterSelect.GetValue()
  775. == self.mPanel.select.GetValue()
  776. ):
  777. self.mPanel.drawMap.SetValue(True)
  778. else:
  779. self.mPanel.drawMap.SetValue(False)
  780. else:
  781. if "vector" in self.parent.openDialogs:
  782. found = False
  783. for each in self.parent.openDialogs["vector"].vPanel.vectorList:
  784. if each[0] == self.mPanel.select.GetValue():
  785. found = True
  786. self.mPanel.drawMap.SetValue(found)
  787. class MapFramePanel(Panel):
  788. """Panel with map (scale, region, border) settings"""
  789. def __init__(self, parent, id, settings, env, rect, notebook=True):
  790. Panel.__init__(self, parent, id=wx.ID_ANY, style=wx.TAB_TRAVERSAL)
  791. self.id = id
  792. self.instruction = settings
  793. self.env = env
  794. if notebook:
  795. self.book = parent
  796. self.book.AddPage(page=self, text=_("Map frame"))
  797. self.mapDialog = self.book.GetParent()
  798. else:
  799. self.mapDialog = parent
  800. if self.id is not None:
  801. self.mapFrameDict = self.instruction[self.id].GetInstruction()
  802. else:
  803. self.id = NewId()
  804. mapFrame = MapFrame(self.id, env=self.env)
  805. self.mapFrameDict = mapFrame.GetInstruction()
  806. self.mapFrameDict["rect"] = rect
  807. self._layout()
  808. self.scale = [None] * 4
  809. self.center = [None] * 4
  810. self.selectedMap = self.mapFrameDict["map"]
  811. self.selectedRegion = self.mapFrameDict["region"]
  812. self.scaleType = self.mapFrameDict["scaleType"]
  813. self.mapType = self.mapFrameDict["mapType"]
  814. self.scaleChoice.SetSelection(self.mapFrameDict["scaleType"])
  815. if self.instruction[self.id]:
  816. self.drawMap.SetValue(self.mapFrameDict["drawMap"])
  817. else:
  818. self.drawMap.SetValue(True)
  819. if self.mapFrameDict["scaleType"] == 0 and self.mapFrameDict["map"]:
  820. self.select.SetValue(self.mapFrameDict["map"])
  821. if self.mapFrameDict["mapType"] == "raster":
  822. self.rasterTypeRadio.SetValue(True)
  823. self.vectorTypeRadio.SetValue(False)
  824. else:
  825. self.rasterTypeRadio.SetValue(False)
  826. self.vectorTypeRadio.SetValue(True)
  827. elif self.mapFrameDict["scaleType"] == 1 and self.mapFrameDict["region"]:
  828. self.select.SetValue(self.mapFrameDict["region"])
  829. self.OnMap(None)
  830. self.scale[self.mapFrameDict["scaleType"]] = self.mapFrameDict["scale"]
  831. self.center[self.mapFrameDict["scaleType"]] = self.mapFrameDict["center"]
  832. self.OnScaleChoice(None)
  833. self.OnElementType(None)
  834. self.OnBorder(None)
  835. def _layout(self):
  836. """Do layout"""
  837. border = wx.BoxSizer(wx.VERTICAL)
  838. box = StaticBox(parent=self, id=wx.ID_ANY, label=" %s " % _("Map frame"))
  839. sizer = wx.StaticBoxSizer(box, wx.HORIZONTAL)
  840. gridBagSizer = wx.GridBagSizer(hgap=5, vgap=5)
  841. # scale options
  842. frameText = StaticText(self, id=wx.ID_ANY, label=_("Map frame options:"))
  843. scaleChoices = [
  844. _("fit frame to match selected map"),
  845. _("fit frame to match saved region"),
  846. _("fit frame to match current computational region"),
  847. _("fixed scale and map center"),
  848. ]
  849. self.scaleChoice = Choice(self, id=wx.ID_ANY, choices=scaleChoices)
  850. gridBagSizer.Add(frameText, pos=(0, 0), flag=wx.ALIGN_CENTER_VERTICAL, border=0)
  851. gridBagSizer.Add(
  852. self.scaleChoice,
  853. pos=(1, 0),
  854. flag=wx.ALIGN_CENTER_VERTICAL | wx.EXPAND,
  855. border=0,
  856. )
  857. # map and region selection
  858. self.staticBox = StaticBox(
  859. parent=self, id=wx.ID_ANY, label=" %s " % _("Map selection")
  860. )
  861. sizerM = wx.StaticBoxSizer(self.staticBox, wx.HORIZONTAL)
  862. self.mapSizer = wx.GridBagSizer(hgap=5, vgap=5)
  863. self.rasterTypeRadio = RadioButton(
  864. self, id=wx.ID_ANY, label=" %s " % _("raster"), style=wx.RB_GROUP
  865. )
  866. self.vectorTypeRadio = RadioButton(
  867. self, id=wx.ID_ANY, label=" %s " % _("vector")
  868. )
  869. self.drawMap = CheckBox(self, id=wx.ID_ANY, label="add selected map")
  870. self.mapOrRegionText = [_("Map:"), _("Region:")]
  871. dc = ClientDC(self) # determine size of labels
  872. width = max(
  873. dc.GetTextExtent(self.mapOrRegionText[0])[0],
  874. dc.GetTextExtent(self.mapOrRegionText[1])[0],
  875. )
  876. self.mapText = StaticText(
  877. self, id=wx.ID_ANY, label=self.mapOrRegionText[0], size=(width, -1)
  878. )
  879. self.select = Select(
  880. self,
  881. id=wx.ID_ANY,
  882. size=globalvar.DIALOG_GSELECT_SIZE,
  883. type="raster",
  884. multiple=False,
  885. updateOnPopup=True,
  886. onPopup=None,
  887. )
  888. self.mapSizer.Add(
  889. self.rasterTypeRadio, pos=(0, 1), flag=wx.ALIGN_CENTER_VERTICAL, border=0
  890. )
  891. self.mapSizer.Add(
  892. self.vectorTypeRadio, pos=(0, 2), flag=wx.ALIGN_CENTER_VERTICAL, border=0
  893. )
  894. self.mapSizer.Add(
  895. self.drawMap,
  896. pos=(0, 3),
  897. flag=wx.ALIGN_CENTER_VERTICAL | wx.ALIGN_RIGHT,
  898. border=0,
  899. )
  900. self.mapSizer.Add(
  901. self.mapText, pos=(1, 0), flag=wx.ALIGN_CENTER_VERTICAL, border=0
  902. )
  903. self.mapSizer.Add(
  904. self.select,
  905. pos=(1, 1),
  906. span=(1, 3),
  907. flag=wx.ALIGN_CENTER_VERTICAL,
  908. border=0,
  909. )
  910. sizerM.Add(self.mapSizer, proportion=1, flag=wx.EXPAND | wx.ALL, border=5)
  911. gridBagSizer.Add(
  912. sizerM, pos=(2, 0), flag=wx.ALIGN_CENTER_VERTICAL | wx.EXPAND, border=0
  913. )
  914. # map scale and center
  915. boxC = StaticBox(
  916. parent=self, id=wx.ID_ANY, label=" %s " % _("Map scale and center")
  917. )
  918. sizerC = wx.StaticBoxSizer(boxC, wx.HORIZONTAL)
  919. self.centerSizer = wx.FlexGridSizer(rows=2, cols=5, hgap=5, vgap=5)
  920. centerText = StaticText(self, id=wx.ID_ANY, label=_("Center:"))
  921. self.eastingText = StaticText(self, id=wx.ID_ANY, label=_("E:"))
  922. self.northingText = StaticText(self, id=wx.ID_ANY, label=_("N:"))
  923. self.eastingTextCtrl = TextCtrl(
  924. self,
  925. id=wx.ID_ANY,
  926. style=wx.TE_RIGHT,
  927. validator=TCValidator(flag="DIGIT_ONLY"),
  928. )
  929. self.northingTextCtrl = TextCtrl(
  930. self,
  931. id=wx.ID_ANY,
  932. style=wx.TE_RIGHT,
  933. validator=TCValidator(flag="DIGIT_ONLY"),
  934. )
  935. scaleText = StaticText(self, id=wx.ID_ANY, label=_("Scale:"))
  936. scalePrefixText = StaticText(self, id=wx.ID_ANY, label=_("1 :"))
  937. self.scaleTextCtrl = TextCtrl(
  938. self,
  939. id=wx.ID_ANY,
  940. value="",
  941. style=wx.TE_RIGHT,
  942. validator=TCValidator("DIGIT_ONLY"),
  943. )
  944. self.centerSizer.Add(
  945. centerText,
  946. proportion=0,
  947. flag=wx.ALIGN_CENTER_VERTICAL | wx.RIGHT,
  948. border=10,
  949. )
  950. self.centerSizer.Add(
  951. self.eastingText,
  952. proportion=0,
  953. flag=wx.ALIGN_CENTER_VERTICAL | wx.ALIGN_RIGHT,
  954. border=0,
  955. )
  956. self.centerSizer.Add(
  957. self.eastingTextCtrl, proportion=0, flag=wx.ALIGN_CENTER_VERTICAL, border=0
  958. )
  959. self.centerSizer.Add(
  960. self.northingText,
  961. proportion=0,
  962. flag=wx.ALIGN_CENTER_VERTICAL | wx.ALIGN_RIGHT,
  963. border=0,
  964. )
  965. self.centerSizer.Add(
  966. self.northingTextCtrl, proportion=0, flag=wx.ALIGN_CENTER_VERTICAL, border=0
  967. )
  968. self.centerSizer.Add(
  969. scaleText, proportion=0, flag=wx.ALIGN_CENTER_VERTICAL | wx.RIGHT, border=10
  970. )
  971. self.centerSizer.Add(
  972. scalePrefixText,
  973. proportion=0,
  974. flag=wx.ALIGN_CENTER_VERTICAL | wx.ALIGN_RIGHT,
  975. border=0,
  976. )
  977. self.centerSizer.Add(
  978. self.scaleTextCtrl, proportion=0, flag=wx.ALIGN_CENTER_VERTICAL, border=0
  979. )
  980. sizerC.Add(self.centerSizer, proportion=1, flag=wx.EXPAND | wx.ALL, border=5)
  981. gridBagSizer.Add(
  982. sizerC, pos=(3, 0), flag=wx.ALIGN_CENTER_VERTICAL | wx.EXPAND, border=0
  983. )
  984. # resolution
  985. flexSizer = wx.FlexGridSizer(rows=1, cols=2, hgap=5, vgap=5)
  986. resolutionText = StaticText(
  987. self, id=wx.ID_ANY, label=_("Map max resolution (dpi):")
  988. )
  989. self.resolutionSpin = SpinCtrl(self, id=wx.ID_ANY, min=1, max=1000, initial=300)
  990. flexSizer.Add(
  991. resolutionText, proportion=0, flag=wx.ALIGN_CENTER_VERTICAL, border=0
  992. )
  993. flexSizer.Add(
  994. self.resolutionSpin, proportion=0, flag=wx.ALIGN_CENTER_VERTICAL, border=0
  995. )
  996. self.resolutionSpin.SetValue(self.mapFrameDict["resolution"])
  997. gridBagSizer.Add(
  998. flexSizer, pos=(4, 0), flag=wx.ALIGN_CENTER_VERTICAL | wx.EXPAND, border=0
  999. )
  1000. sizer.Add(gridBagSizer, proportion=1, flag=wx.EXPAND | wx.ALL, border=5)
  1001. border.Add(sizer, proportion=0, flag=wx.ALL | wx.EXPAND, border=5)
  1002. # border
  1003. # GTC Line around legend or map frame
  1004. box = StaticBox(parent=self, id=wx.ID_ANY, label=" %s " % _("Border"))
  1005. sizer = wx.StaticBoxSizer(box, wx.HORIZONTAL)
  1006. gridBagSizer = wx.GridBagSizer(hgap=5, vgap=5)
  1007. self.borderCheck = CheckBox(
  1008. self, id=wx.ID_ANY, label=(_("draw border around map frame"))
  1009. )
  1010. if self.mapFrameDict["border"] == "y":
  1011. self.borderCheck.SetValue(True)
  1012. else:
  1013. self.borderCheck.SetValue(False)
  1014. self.borderColorText = StaticText(self, id=wx.ID_ANY, label=_("border color:"))
  1015. self.borderWidthText = StaticText(
  1016. self, id=wx.ID_ANY, label=_("border width (pts):")
  1017. )
  1018. self.borderColourPicker = ColourPickerCtrl(self, id=wx.ID_ANY)
  1019. self.borderWidthCtrl = SpinCtrl(self, id=wx.ID_ANY, min=1, max=100, initial=1)
  1020. if self.mapFrameDict["border"] == "y":
  1021. self.borderWidthCtrl.SetValue(int(self.mapFrameDict["width"]))
  1022. self.borderColourPicker.SetColour(convertRGB(self.mapFrameDict["color"]))
  1023. gridBagSizer.Add(
  1024. self.borderCheck,
  1025. pos=(0, 0),
  1026. span=(1, 2),
  1027. flag=wx.ALIGN_CENTER_VERTICAL | wx.EXPAND,
  1028. border=0,
  1029. )
  1030. gridBagSizer.Add(
  1031. self.borderColorText, pos=(1, 1), flag=wx.ALIGN_CENTER_VERTICAL, border=0
  1032. )
  1033. gridBagSizer.Add(
  1034. self.borderWidthText, pos=(2, 1), flag=wx.ALIGN_CENTER_VERTICAL, border=0
  1035. )
  1036. gridBagSizer.Add(
  1037. self.borderColourPicker,
  1038. pos=(1, 2),
  1039. flag=wx.ALIGN_CENTER_VERTICAL | wx.EXPAND,
  1040. border=0,
  1041. )
  1042. gridBagSizer.Add(
  1043. self.borderWidthCtrl,
  1044. pos=(2, 2),
  1045. flag=wx.ALIGN_CENTER_VERTICAL | wx.EXPAND,
  1046. border=0,
  1047. )
  1048. sizer.Add(gridBagSizer, proportion=1, flag=wx.EXPAND | wx.ALL, border=5)
  1049. border.Add(sizer, proportion=0, flag=wx.ALL | wx.EXPAND, border=5)
  1050. self.SetSizer(border)
  1051. self.Fit()
  1052. if projInfo()["proj"] == "ll":
  1053. self.scaleChoice.SetItems(self.scaleChoice.GetItems()[0:3])
  1054. boxC.Hide()
  1055. for each in self.centerSizer.GetChildren():
  1056. each.GetWindow().Hide()
  1057. # bindings
  1058. self.scaleChoice.Bind(wx.EVT_CHOICE, self.OnScaleChoice)
  1059. self.Bind(wx.EVT_RADIOBUTTON, self.OnElementType, self.vectorTypeRadio)
  1060. self.Bind(wx.EVT_RADIOBUTTON, self.OnElementType, self.rasterTypeRadio)
  1061. self.Bind(wx.EVT_CHECKBOX, self.OnBorder, self.borderCheck)
  1062. def OnMap(self, event):
  1063. """Selected map or region changing"""
  1064. if self.select.GetValue():
  1065. self.selected = self.select.GetValue()
  1066. else:
  1067. self.selected = None
  1068. if self.scaleChoice.GetSelection() == 0:
  1069. self.selectedMap = self.selected
  1070. if self.rasterTypeRadio.GetValue():
  1071. mapType = "raster"
  1072. else:
  1073. mapType = "vector"
  1074. self.scale[0], self.center[0], foo = AutoAdjust(
  1075. self,
  1076. scaleType=0,
  1077. map=self.selected,
  1078. mapType=mapType,
  1079. rect=self.mapFrameDict["rect"],
  1080. env=self.env,
  1081. )
  1082. # self.center[0] = self.RegionCenter(self.RegionDict(scaleType = 0))
  1083. elif self.scaleChoice.GetSelection() == 1:
  1084. self.selectedRegion = self.selected
  1085. self.scale[1], self.center[1], foo = AutoAdjust(
  1086. self,
  1087. scaleType=1,
  1088. region=self.selected,
  1089. rect=self.mapFrameDict["rect"],
  1090. env=self.env,
  1091. )
  1092. # self.center[1] = self.RegionCenter(self.RegionDict(scaleType = 1))
  1093. elif self.scaleChoice.GetSelection() == 2:
  1094. self.scale[2], self.center[2], foo = AutoAdjust(
  1095. self, scaleType=2, rect=self.mapFrameDict["rect"], env=self.env
  1096. )
  1097. # self.center[2] = self.RegionCenter(self.RegionDict(scaleType = 2))
  1098. else:
  1099. self.scale[3] = None
  1100. self.center[3] = None
  1101. self.OnScaleChoice(None)
  1102. def OnScaleChoice(self, event):
  1103. """Selected scale type changing"""
  1104. scaleType = self.scaleChoice.GetSelection()
  1105. if self.scaleType != scaleType:
  1106. self.scaleType = scaleType
  1107. self.select.SetValue("")
  1108. if scaleType in (0, 1): # automatic - region from raster map, saved region
  1109. if scaleType == 0:
  1110. # set map selection
  1111. self.rasterTypeRadio.Show()
  1112. self.vectorTypeRadio.Show()
  1113. self.drawMap.Show()
  1114. self.staticBox.SetLabel(" %s " % _("Map selection"))
  1115. if self.rasterTypeRadio.GetValue():
  1116. stype = "raster"
  1117. else:
  1118. stype = "vector"
  1119. self.select.SetElementList(type=stype)
  1120. self.mapText.SetLabel(self.mapOrRegionText[0])
  1121. self.select.SetToolTip(
  1122. _(
  1123. "Region is set to match this map,\nraster or vector map must be added later"
  1124. )
  1125. )
  1126. if scaleType == 1:
  1127. # set region selection
  1128. self.rasterTypeRadio.Hide()
  1129. self.vectorTypeRadio.Hide()
  1130. self.drawMap.Hide()
  1131. self.staticBox.SetLabel(" %s " % _("Region selection"))
  1132. stype = "region"
  1133. self.select.SetElementList(type=stype)
  1134. self.mapText.SetLabel(self.mapOrRegionText[1])
  1135. self.select.SetToolTip("")
  1136. for each in self.mapSizer.GetChildren():
  1137. each.GetWindow().Enable()
  1138. for each in self.centerSizer.GetChildren():
  1139. each.GetWindow().Disable()
  1140. if self.scale[scaleType]:
  1141. self.scaleTextCtrl.SetValue("%.0f" % (1 / self.scale[scaleType]))
  1142. if self.center[scaleType]:
  1143. self.eastingTextCtrl.SetValue(str(self.center[scaleType][0]))
  1144. self.northingTextCtrl.SetValue(str(self.center[scaleType][1]))
  1145. elif scaleType == 2:
  1146. for each in self.mapSizer.GetChildren():
  1147. each.GetWindow().Disable()
  1148. for each in self.centerSizer.GetChildren():
  1149. each.GetWindow().Disable()
  1150. if self.scale[scaleType]:
  1151. self.scaleTextCtrl.SetValue("%.0f" % (1 / self.scale[scaleType]))
  1152. if self.center[scaleType]:
  1153. self.eastingTextCtrl.SetValue(str(self.center[scaleType][0]))
  1154. self.northingTextCtrl.SetValue(str(self.center[scaleType][1]))
  1155. else: # fixed
  1156. for each in self.mapSizer.GetChildren():
  1157. each.GetWindow().Disable()
  1158. for each in self.centerSizer.GetChildren():
  1159. each.GetWindow().Enable()
  1160. if self.scale[scaleType]:
  1161. self.scaleTextCtrl.SetValue("%.0f" % (1 / self.scale[scaleType]))
  1162. if self.center[scaleType]:
  1163. self.eastingTextCtrl.SetValue(str(self.center[scaleType][0]))
  1164. self.northingTextCtrl.SetValue(str(self.center[scaleType][1]))
  1165. def OnElementType(self, event):
  1166. """Changes data in map selection tree ctrl popup"""
  1167. if self.rasterTypeRadio.GetValue():
  1168. mapType = "raster"
  1169. else:
  1170. mapType = "vector"
  1171. self.select.SetElementList(type=mapType)
  1172. if self.mapType != mapType and event is not None:
  1173. self.mapType = mapType
  1174. self.select.SetValue("")
  1175. self.mapType = mapType
  1176. def OnBorder(self, event):
  1177. """Enables/disable the part relating to border of map frame"""
  1178. for each in (
  1179. self.borderColorText,
  1180. self.borderWidthText,
  1181. self.borderColourPicker,
  1182. self.borderWidthCtrl,
  1183. ):
  1184. each.Enable(self.borderCheck.GetValue())
  1185. def getId(self):
  1186. """Returns id of raster map"""
  1187. return self.id
  1188. def update(self):
  1189. """Save changes"""
  1190. mapFrameDict = dict(self.mapFrameDict)
  1191. # resolution
  1192. mapFrameDict["resolution"] = self.resolutionSpin.GetValue()
  1193. # scale
  1194. scaleType = self.scaleType
  1195. mapFrameDict["scaleType"] = scaleType
  1196. if mapFrameDict["scaleType"] == 0:
  1197. if self.select.GetValue():
  1198. mapFrameDict["drawMap"] = self.drawMap.GetValue()
  1199. mapFrameDict["map"] = self.select.GetValue()
  1200. mapFrameDict["mapType"] = self.mapType
  1201. mapFrameDict["region"] = None
  1202. if mapFrameDict["drawMap"]:
  1203. if mapFrameDict["mapType"] == "raster":
  1204. mapFile = grass.find_file(mapFrameDict["map"], element="cell")
  1205. if mapFile["file"] == "":
  1206. GMessage("Raster %s not found" % mapFrameDict["map"])
  1207. return False
  1208. raster = self.instruction.FindInstructionByType("raster")
  1209. if raster:
  1210. raster["raster"] = mapFrameDict["map"]
  1211. else:
  1212. raster = Raster(NewId(), env=self.env)
  1213. raster["raster"] = mapFrameDict["map"]
  1214. raster["isRaster"] = True
  1215. self.instruction.AddInstruction(raster)
  1216. elif mapFrameDict["mapType"] == "vector":
  1217. mapFile = grass.find_file(mapFrameDict["map"], element="vector")
  1218. if mapFile["file"] == "":
  1219. GMessage("Vector %s not found" % mapFrameDict["map"])
  1220. return False
  1221. vector = self.instruction.FindInstructionByType("vector")
  1222. isAdded = False
  1223. if vector:
  1224. for each in vector["list"]:
  1225. if each[0] == mapFrameDict["map"]:
  1226. isAdded = True
  1227. if not isAdded:
  1228. topoInfo = grass.vector_info_topo(map=mapFrameDict["map"])
  1229. if topoInfo:
  1230. if bool(topoInfo["areas"]):
  1231. topoType = "areas"
  1232. elif bool(topoInfo["lines"]):
  1233. topoType = "lines"
  1234. else:
  1235. topoType = "points"
  1236. label = "(".join(mapFrameDict["map"].split("@")) + ")"
  1237. if not vector:
  1238. vector = Vector(NewId(), env=self.env)
  1239. vector["list"] = []
  1240. self.instruction.AddInstruction(vector)
  1241. id = NewId()
  1242. vector["list"].insert(
  1243. 0, [mapFrameDict["map"], topoType, id, 1, label]
  1244. )
  1245. vProp = VProperties(id, topoType, env=self.env)
  1246. vProp["name"], vProp["label"], vProp["lpos"] = (
  1247. mapFrameDict["map"],
  1248. label,
  1249. 1,
  1250. )
  1251. self.instruction.AddInstruction(vProp)
  1252. else:
  1253. return False
  1254. self.scale[0], self.center[0], self.rectAdjusted = AutoAdjust(
  1255. self,
  1256. scaleType=0,
  1257. map=mapFrameDict["map"],
  1258. env=self.env,
  1259. mapType=self.mapType,
  1260. rect=self.mapFrameDict["rect"],
  1261. )
  1262. if self.rectAdjusted:
  1263. mapFrameDict["rect"] = self.rectAdjusted
  1264. else:
  1265. mapFrameDict["rect"] = self.mapFrameDict["rect"]
  1266. mapFrameDict["scale"] = self.scale[0]
  1267. mapFrameDict["center"] = self.center[0]
  1268. # set region
  1269. if self.mapType == "raster":
  1270. self.env["GRASS_REGION"] = grass.region_env(
  1271. raster=mapFrameDict["map"], env=self.env
  1272. )
  1273. if self.mapType == "vector":
  1274. raster = self.instruction.FindInstructionByType("raster")
  1275. if raster:
  1276. rasterId = raster.id
  1277. else:
  1278. rasterId = None
  1279. if rasterId:
  1280. self.env["GRASS_REGION"] = grass.region_env(
  1281. vector=mapFrameDict["map"],
  1282. raster=self.instruction[rasterId]["raster"],
  1283. env=self.env,
  1284. )
  1285. else:
  1286. self.env["GRASS_REGION"] = grass.region_env(
  1287. vector=mapFrameDict["map"], env=self.env
  1288. )
  1289. else:
  1290. wx.MessageBox(
  1291. message=_("No map selected!"),
  1292. caption=_("Invalid input"),
  1293. style=wx.OK | wx.ICON_ERROR,
  1294. )
  1295. return False
  1296. elif mapFrameDict["scaleType"] == 1:
  1297. if self.select.GetValue():
  1298. mapFrameDict["drawMap"] = False
  1299. mapFrameDict["map"] = None
  1300. mapFrameDict["mapType"] = None
  1301. mapFrameDict["region"] = self.select.GetValue()
  1302. self.scale[1], self.center[1], self.rectAdjusted = AutoAdjust(
  1303. self,
  1304. scaleType=1,
  1305. region=mapFrameDict["region"],
  1306. rect=self.mapFrameDict["rect"],
  1307. env=self.env,
  1308. )
  1309. if self.rectAdjusted:
  1310. mapFrameDict["rect"] = self.rectAdjusted
  1311. else:
  1312. mapFrameDict["rect"] = self.mapFrameDict["rect"]
  1313. mapFrameDict["scale"] = self.scale[1]
  1314. mapFrameDict["center"] = self.center[1]
  1315. # set region
  1316. self.env["GRASS_REGION"] = grass.region_env(
  1317. region=mapFrameDict["region"], env=self.env
  1318. )
  1319. else:
  1320. wx.MessageBox(
  1321. message=_("No region selected!"),
  1322. caption=_("Invalid input"),
  1323. style=wx.OK | wx.ICON_ERROR,
  1324. )
  1325. return False
  1326. elif scaleType == 2:
  1327. mapFrameDict["drawMap"] = False
  1328. mapFrameDict["map"] = None
  1329. mapFrameDict["mapType"] = None
  1330. mapFrameDict["region"] = None
  1331. self.scale[2], self.center[2], self.rectAdjusted = AutoAdjust(
  1332. self, scaleType=2, rect=self.mapFrameDict["rect"], env=self.env
  1333. )
  1334. if self.rectAdjusted:
  1335. mapFrameDict["rect"] = self.rectAdjusted
  1336. else:
  1337. mapFrameDict["rect"] = self.mapFrameDict["rect"]
  1338. mapFrameDict["scale"] = self.scale[2]
  1339. mapFrameDict["center"] = self.center[2]
  1340. region = grass.region(env=None)
  1341. raster = self.instruction.FindInstructionByType("raster")
  1342. if raster:
  1343. rasterId = raster.id
  1344. else:
  1345. rasterId = None
  1346. if rasterId: # because of resolution
  1347. self.env["GRASS_REGION"] = grass.region_env(
  1348. n=region["n"],
  1349. s=region["s"],
  1350. e=region["e"],
  1351. w=region["w"],
  1352. raster=self.instruction[rasterId]["raster"],
  1353. env=self.env,
  1354. )
  1355. else:
  1356. self.env["GRASS_REGION"] = grass.region_env(
  1357. n=region["n"],
  1358. s=region["s"],
  1359. e=region["e"],
  1360. w=region["w"],
  1361. env=self.env,
  1362. )
  1363. elif scaleType == 3:
  1364. mapFrameDict["drawMap"] = False
  1365. mapFrameDict["map"] = None
  1366. mapFrameDict["mapType"] = None
  1367. mapFrameDict["region"] = None
  1368. mapFrameDict["rect"] = self.mapFrameDict["rect"]
  1369. try:
  1370. scaleNumber = float(self.scaleTextCtrl.GetValue())
  1371. centerE = float(self.eastingTextCtrl.GetValue())
  1372. centerN = float(self.northingTextCtrl.GetValue())
  1373. except (ValueError, SyntaxError):
  1374. wx.MessageBox(
  1375. message=_("Invalid scale or map center!"),
  1376. caption=_("Invalid input"),
  1377. style=wx.OK | wx.ICON_ERROR,
  1378. )
  1379. return False
  1380. mapFrameDict["scale"] = 1 / scaleNumber
  1381. mapFrameDict["center"] = centerE, centerN
  1382. ComputeSetRegion(self, mapDict=mapFrameDict, env=self.env)
  1383. # check resolution
  1384. SetResolution(
  1385. dpi=mapFrameDict["resolution"],
  1386. width=mapFrameDict["rect"].width,
  1387. height=mapFrameDict["rect"].height,
  1388. env=self.env,
  1389. )
  1390. # border
  1391. if self.borderCheck.GetValue():
  1392. mapFrameDict["border"] = "y"
  1393. else:
  1394. mapFrameDict["border"] = "n"
  1395. if mapFrameDict["border"] == "y":
  1396. mapFrameDict["width"] = self.borderWidthCtrl.GetValue()
  1397. mapFrameDict["color"] = convertRGB(self.borderColourPicker.GetColour())
  1398. if self.id not in self.instruction:
  1399. mapFrame = MapFrame(self.id, env=self.env)
  1400. self.instruction.AddInstruction(mapFrame)
  1401. self.instruction[self.id].SetInstruction(mapFrameDict)
  1402. if self.id not in self.mapDialog.parent.objectId:
  1403. self.mapDialog.parent.objectId.insert(
  1404. 0, self.id
  1405. ) # map frame is drawn first
  1406. return True
  1407. class RasterPanel(Panel):
  1408. """Panel for raster map settings"""
  1409. def __init__(self, parent, id, settings, env, notebook=True):
  1410. Panel.__init__(self, parent, id=wx.ID_ANY, style=wx.TAB_TRAVERSAL)
  1411. self.instruction = settings
  1412. self.env = env
  1413. if notebook:
  1414. self.book = parent
  1415. self.book.AddPage(page=self, text=_("Raster map"))
  1416. self.mainDialog = self.book.GetParent()
  1417. else:
  1418. self.mainDialog = parent
  1419. if id:
  1420. self.id = id
  1421. self.rasterDict = self.instruction[self.id].GetInstruction()
  1422. else:
  1423. self.id = NewId()
  1424. raster = Raster(self.id, env=self.env)
  1425. self.rasterDict = raster.GetInstruction()
  1426. self._layout()
  1427. self.OnRaster(None)
  1428. def _layout(self):
  1429. """Do layout"""
  1430. border = wx.BoxSizer(wx.VERTICAL)
  1431. # choose raster map
  1432. box = StaticBox(
  1433. parent=self, id=wx.ID_ANY, label=" %s " % _("Choose raster map")
  1434. )
  1435. sizer = wx.StaticBoxSizer(box, wx.VERTICAL)
  1436. gridBagSizer = wx.GridBagSizer(hgap=5, vgap=5)
  1437. self.rasterNoRadio = RadioButton(
  1438. self, id=wx.ID_ANY, label=_("no raster map"), style=wx.RB_GROUP
  1439. )
  1440. self.rasterYesRadio = RadioButton(self, id=wx.ID_ANY, label=_("raster:"))
  1441. self.rasterSelect = Select(
  1442. self,
  1443. id=wx.ID_ANY,
  1444. size=globalvar.DIALOG_GSELECT_SIZE,
  1445. type="raster",
  1446. multiple=False,
  1447. updateOnPopup=True,
  1448. onPopup=None,
  1449. )
  1450. if self.rasterDict["isRaster"]:
  1451. self.rasterYesRadio.SetValue(True)
  1452. self.rasterNoRadio.SetValue(False)
  1453. self.rasterSelect.SetValue(self.rasterDict["raster"])
  1454. else:
  1455. self.rasterYesRadio.SetValue(False)
  1456. self.rasterNoRadio.SetValue(True)
  1457. mapId = self.instruction.FindInstructionByType("map").id
  1458. if (
  1459. self.instruction[mapId]["map"]
  1460. and self.instruction[mapId]["mapType"] == "raster"
  1461. ):
  1462. # raster map from map frame dialog if possible
  1463. self.rasterSelect.SetValue(self.instruction[mapId]["map"])
  1464. else:
  1465. self.rasterSelect.SetValue("")
  1466. gridBagSizer.Add(
  1467. self.rasterNoRadio,
  1468. pos=(0, 0),
  1469. span=(1, 2),
  1470. flag=wx.ALIGN_CENTER_VERTICAL,
  1471. border=0,
  1472. )
  1473. gridBagSizer.Add(
  1474. self.rasterYesRadio, pos=(1, 0), flag=wx.ALIGN_CENTER_VERTICAL, border=0
  1475. )
  1476. gridBagSizer.Add(
  1477. self.rasterSelect,
  1478. pos=(1, 1),
  1479. flag=wx.ALIGN_CENTER_VERTICAL | wx.EXPAND,
  1480. border=0,
  1481. )
  1482. sizer.Add(gridBagSizer, proportion=1, flag=wx.EXPAND | wx.ALL, border=5)
  1483. border.Add(sizer, proportion=0, flag=wx.ALL | wx.EXPAND, border=5)
  1484. # self.rasterSelect.GetTextCtrl().Bind(wx.EVT_TEXT, self.OnRaster)
  1485. self.Bind(wx.EVT_RADIOBUTTON, self.OnRaster, self.rasterNoRadio)
  1486. self.Bind(wx.EVT_RADIOBUTTON, self.OnRaster, self.rasterYesRadio)
  1487. self.SetSizer(border)
  1488. self.Fit()
  1489. def OnRaster(self, event):
  1490. """Enable/disable raster selection"""
  1491. self.rasterSelect.Enable(self.rasterYesRadio.GetValue())
  1492. def update(self):
  1493. # draw raster
  1494. mapInstr = self.instruction.FindInstructionByType("map")
  1495. if not mapInstr: # no map frame
  1496. GMessage(message=_("Please, create map frame first."))
  1497. return
  1498. if self.rasterNoRadio.GetValue() or not self.rasterSelect.GetValue():
  1499. self.rasterDict["isRaster"] = False
  1500. self.rasterDict["raster"] = None
  1501. mapInstr["drawMap"] = False
  1502. if self.id in self.instruction:
  1503. del self.instruction[self.id]
  1504. else:
  1505. self.rasterDict["isRaster"] = True
  1506. self.rasterDict["raster"] = self.rasterSelect.GetValue()
  1507. if self.rasterDict["raster"] != mapInstr["drawMap"]:
  1508. mapInstr["drawMap"] = False
  1509. raster = self.instruction.FindInstructionByType("raster")
  1510. if not raster:
  1511. raster = Raster(self.id, env=self.env)
  1512. self.instruction.AddInstruction(raster)
  1513. self.instruction[self.id].SetInstruction(self.rasterDict)
  1514. else:
  1515. self.instruction[raster.id].SetInstruction(self.rasterDict)
  1516. if "map" in self.mainDialog.parent.openDialogs:
  1517. self.mainDialog.parent.openDialogs["map"].updateDialog()
  1518. return True
  1519. def getId(self):
  1520. return self.id
  1521. class VectorPanel(Panel):
  1522. """Panel for vector maps settings"""
  1523. def __init__(self, parent, id, settings, env, notebook=True):
  1524. Panel.__init__(self, parent, id=wx.ID_ANY, style=wx.TAB_TRAVERSAL)
  1525. self.parent = parent
  1526. self.env = env
  1527. self.instruction = settings
  1528. self.tmpDialogDict = {}
  1529. vectors = self.instruction.FindInstructionByType("vProperties", list=True)
  1530. for vector in vectors:
  1531. self.tmpDialogDict[vector.id] = dict(
  1532. self.instruction[vector.id].GetInstruction()
  1533. )
  1534. if id:
  1535. self.id = id
  1536. self.vectorList = deepcopy(self.instruction[id]["list"])
  1537. else:
  1538. self.id = NewId()
  1539. self.vectorList = []
  1540. vLegend = self.instruction.FindInstructionByType("vectorLegend")
  1541. if vLegend:
  1542. self.vLegendId = vLegend.id
  1543. else:
  1544. self.vLegendId = None
  1545. self._layout()
  1546. if notebook:
  1547. self.parent.AddPage(page=self, text=_("Vector maps"))
  1548. self.parent = self.parent.GetParent()
  1549. def _layout(self):
  1550. """Do layout"""
  1551. border = wx.BoxSizer(wx.VERTICAL)
  1552. # choose vector map
  1553. box = StaticBox(parent=self, id=wx.ID_ANY, label=" %s " % _("Add map"))
  1554. sizer = wx.StaticBoxSizer(box, wx.VERTICAL)
  1555. gridBagSizer = wx.GridBagSizer(hgap=5, vgap=5)
  1556. text = StaticText(self, id=wx.ID_ANY, label=_("Map:"))
  1557. self.select = Select(
  1558. self,
  1559. id=wx.ID_ANY, # size = globalvar.DIALOG_GSELECT_SIZE,
  1560. type="vector",
  1561. multiple=False,
  1562. updateOnPopup=True,
  1563. onPopup=None,
  1564. )
  1565. topologyTypeTr = [_("points"), _("lines"), _("areas")]
  1566. self.topologyTypeList = ["points", "lines", "areas"]
  1567. self.vectorType = wx.RadioBox(
  1568. self,
  1569. id=wx.ID_ANY,
  1570. label=" %s " % _("Data Type"),
  1571. choices=topologyTypeTr,
  1572. majorDimension=3,
  1573. style=wx.RA_SPECIFY_COLS,
  1574. )
  1575. self.AddVector = Button(self, id=wx.ID_ANY, label=_("Add"))
  1576. gridBagSizer.Add(text, pos=(0, 0), flag=wx.ALIGN_CENTER_VERTICAL, border=0)
  1577. gridBagSizer.Add(
  1578. self.select,
  1579. pos=(0, 1),
  1580. span=(1, 2),
  1581. flag=wx.ALIGN_CENTER_VERTICAL,
  1582. border=0,
  1583. )
  1584. gridBagSizer.Add(self.vectorType, pos=(1, 1), flag=wx.ALIGN_CENTER, border=0)
  1585. gridBagSizer.Add(
  1586. self.AddVector, pos=(1, 2), flag=wx.ALIGN_BOTTOM | wx.ALIGN_RIGHT, border=0
  1587. )
  1588. sizer.Add(gridBagSizer, proportion=1, flag=wx.EXPAND | wx.ALL, border=5)
  1589. border.Add(sizer, proportion=0, flag=wx.ALL | wx.EXPAND, border=5)
  1590. # manage vector layers
  1591. box = StaticBox(
  1592. parent=self, id=wx.ID_ANY, label=" %s " % _("Manage vector maps")
  1593. )
  1594. sizer = wx.StaticBoxSizer(box, wx.VERTICAL)
  1595. gridBagSizer = wx.GridBagSizer(hgap=5, vgap=5)
  1596. text = StaticText(
  1597. self, id=wx.ID_ANY, label=_("The topmost vector map overlaps the others")
  1598. )
  1599. self.listbox = ListBox(
  1600. self, id=wx.ID_ANY, choices=[], style=wx.LB_SINGLE | wx.LB_NEEDED_SB
  1601. )
  1602. self.btnUp = Button(self, id=wx.ID_ANY, label=_("Up"))
  1603. self.btnDown = Button(self, id=wx.ID_ANY, label=_("Down"))
  1604. self.btnDel = Button(self, id=wx.ID_ANY, label=_("Delete"))
  1605. self.btnProp = Button(self, id=wx.ID_ANY, label=_("Properties..."))
  1606. self.updateListBox(selected=0)
  1607. gridBagSizer.Add(text, pos=(0, 0), flag=wx.ALIGN_CENTER_VERTICAL, border=0)
  1608. gridBagSizer.Add(
  1609. self.listbox,
  1610. pos=(1, 0),
  1611. span=(4, 1),
  1612. flag=wx.ALIGN_CENTER_VERTICAL | wx.EXPAND,
  1613. border=0,
  1614. )
  1615. gridBagSizer.Add(
  1616. self.btnUp, pos=(1, 1), flag=wx.ALIGN_CENTER_VERTICAL | wx.EXPAND, border=0
  1617. )
  1618. gridBagSizer.Add(
  1619. self.btnDown,
  1620. pos=(2, 1),
  1621. flag=wx.ALIGN_CENTER_VERTICAL | wx.EXPAND,
  1622. border=0,
  1623. )
  1624. gridBagSizer.Add(
  1625. self.btnDel, pos=(3, 1), flag=wx.ALIGN_CENTER_VERTICAL | wx.EXPAND, border=0
  1626. )
  1627. gridBagSizer.Add(
  1628. self.btnProp,
  1629. pos=(4, 1),
  1630. flag=wx.ALIGN_CENTER_VERTICAL | wx.EXPAND,
  1631. border=0,
  1632. )
  1633. gridBagSizer.AddGrowableCol(0, 2)
  1634. gridBagSizer.AddGrowableCol(1, 1)
  1635. sizer.Add(gridBagSizer, proportion=0, flag=wx.ALL, border=5)
  1636. border.Add(sizer, proportion=0, flag=wx.ALL | wx.EXPAND, border=5)
  1637. self.Bind(wx.EVT_BUTTON, self.OnAddVector, self.AddVector)
  1638. self.Bind(wx.EVT_BUTTON, self.OnDelete, self.btnDel)
  1639. self.Bind(wx.EVT_BUTTON, self.OnUp, self.btnUp)
  1640. self.Bind(wx.EVT_BUTTON, self.OnDown, self.btnDown)
  1641. self.Bind(wx.EVT_BUTTON, self.OnProperties, self.btnProp)
  1642. self.select.GetTextCtrl().Bind(wx.EVT_TEXT, self.OnVector)
  1643. self.SetSizer(border)
  1644. self.Fit()
  1645. self.Bind(wx.EVT_LISTBOX_DCLICK, self.OnProperties, self.listbox)
  1646. def OnVector(self, event):
  1647. """Gets info about toplogy and enables/disables choices point/line/area"""
  1648. vmap = self.select.GetValue()
  1649. try:
  1650. topoInfo = grass.vector_info_topo(map=vmap)
  1651. except grass.ScriptError:
  1652. return
  1653. if topoInfo:
  1654. self.vectorType.EnableItem(2, bool(topoInfo["areas"]))
  1655. self.vectorType.EnableItem(
  1656. 1, bool(topoInfo["boundaries"]) or bool(topoInfo["lines"])
  1657. )
  1658. self.vectorType.EnableItem(
  1659. 0, bool(topoInfo["centroids"] or bool(topoInfo["points"]))
  1660. )
  1661. for item in range(2, -1, -1):
  1662. if self.vectorType.IsItemEnabled(item):
  1663. self.vectorType.SetSelection(item)
  1664. break
  1665. self.AddVector.SetFocus()
  1666. def OnAddVector(self, event):
  1667. """Adds vector map to list"""
  1668. vmap = self.select.GetValue()
  1669. if vmap:
  1670. mapname = vmap.split("@")[0]
  1671. try:
  1672. mapset = "(" + vmap.split("@")[1] + ")"
  1673. except IndexError:
  1674. mapset = ""
  1675. idx = self.vectorType.GetSelection()
  1676. ttype = self.topologyTypeList[idx]
  1677. record = "%s - %s" % (vmap, ttype)
  1678. id = NewId()
  1679. lpos = 1
  1680. label = mapname + mapset
  1681. self.vectorList.insert(0, [vmap, ttype, id, lpos, label])
  1682. self.reposition()
  1683. self.listbox.InsertItems([record], 0)
  1684. vector = VProperties(id, ttype, env=self.env)
  1685. self.tmpDialogDict[id] = vector.GetInstruction()
  1686. self.tmpDialogDict[id]["name"] = vmap
  1687. self.listbox.SetSelection(0)
  1688. self.listbox.EnsureVisible(0)
  1689. self.btnProp.SetFocus()
  1690. self.enableButtons()
  1691. def OnDelete(self, event):
  1692. """Deletes vector map from the list"""
  1693. if self.listbox.GetSelections():
  1694. pos = self.listbox.GetSelection()
  1695. id = self.vectorList[pos][2]
  1696. del self.vectorList[pos]
  1697. del self.tmpDialogDict[id]
  1698. for i in range(pos, len(self.vectorList)):
  1699. if self.vectorList[i][3]: # can be 0
  1700. self.vectorList[i][3] -= 1
  1701. if pos < len(self.vectorList) - 1:
  1702. selected = pos
  1703. else:
  1704. selected = len(self.vectorList) - 1
  1705. self.updateListBox(selected=selected)
  1706. if self.listbox.IsEmpty():
  1707. self.enableButtons(False)
  1708. def OnUp(self, event):
  1709. """Moves selected map to top"""
  1710. if self.listbox.GetSelections():
  1711. pos = self.listbox.GetSelection()
  1712. if pos:
  1713. self.vectorList.insert(pos - 1, self.vectorList.pop(pos))
  1714. if not self.vLegendId:
  1715. self.reposition()
  1716. if pos > 0:
  1717. self.updateListBox(selected=(pos - 1))
  1718. else:
  1719. self.updateListBox(selected=0)
  1720. def OnDown(self, event):
  1721. """Moves selected map to bottom"""
  1722. if self.listbox.GetSelections():
  1723. pos = self.listbox.GetSelection()
  1724. if pos != len(self.vectorList) - 1:
  1725. self.vectorList.insert(pos + 1, self.vectorList.pop(pos))
  1726. if not self.vLegendId:
  1727. self.reposition()
  1728. if pos < len(self.vectorList) - 1:
  1729. self.updateListBox(selected=(pos + 1))
  1730. else:
  1731. self.updateListBox(selected=len(self.vectorList) - 1)
  1732. def OnProperties(self, event):
  1733. """Opens vector map properties dialog"""
  1734. if self.listbox.GetSelections():
  1735. pos = self.listbox.GetSelection()
  1736. id = self.vectorList[pos][2]
  1737. dlg = VPropertiesDialog(
  1738. self,
  1739. id=id,
  1740. settings=self.instruction,
  1741. env=self.env,
  1742. vectors=self.vectorList,
  1743. tmpSettings=self.tmpDialogDict[id],
  1744. )
  1745. dlg.ShowModal()
  1746. self.parent.FindWindowById(wx.ID_OK).SetFocus()
  1747. def enableButtons(self, enable=True):
  1748. """Enable/disable up, down, properties, delete buttons"""
  1749. self.btnUp.Enable(enable)
  1750. self.btnDown.Enable(enable)
  1751. self.btnProp.Enable(enable)
  1752. self.btnDel.Enable(enable)
  1753. def updateListBox(self, selected=None):
  1754. mapList = ["%s - %s" % (item[0], item[1]) for item in self.vectorList]
  1755. self.listbox.Set(mapList)
  1756. if self.listbox.IsEmpty():
  1757. self.enableButtons(False)
  1758. else:
  1759. self.enableButtons(True)
  1760. if selected is not None:
  1761. self.listbox.SetSelection(selected)
  1762. self.listbox.EnsureVisible(selected)
  1763. def reposition(self):
  1764. """Update position in legend, used only if there is no vlegend yet"""
  1765. for i in range(len(self.vectorList)):
  1766. if self.vectorList[i][3]:
  1767. self.vectorList[i][3] = i + 1
  1768. def getId(self):
  1769. return self.id
  1770. def update(self):
  1771. vectors = self.instruction.FindInstructionByType("vProperties", list=True)
  1772. for vector in vectors:
  1773. del self.instruction[vector.id]
  1774. if self.id in self.instruction:
  1775. del self.instruction[self.id]
  1776. if len(self.vectorList) > 0:
  1777. vector = Vector(self.id, env=self.env)
  1778. self.instruction.AddInstruction(vector)
  1779. vector.SetInstruction({"list": deepcopy(self.vectorList)})
  1780. # save new vectors
  1781. for item in self.vectorList:
  1782. id = item[2]
  1783. vLayer = VProperties(id, item[1], env=self.env)
  1784. self.instruction.AddInstruction(vLayer)
  1785. vLayer.SetInstruction(self.tmpDialogDict[id])
  1786. vLayer["name"] = item[0]
  1787. vLayer["label"] = item[4]
  1788. vLayer["lpos"] = item[3]
  1789. else:
  1790. if self.id in self.instruction:
  1791. del self.instruction[self.id]
  1792. if "map" in self.parent.parent.openDialogs:
  1793. self.parent.parent.openDialogs["map"].updateDialog()
  1794. return True
  1795. class RasterDialog(PsmapDialog):
  1796. def __init__(self, parent, id, settings, env):
  1797. PsmapDialog.__init__(
  1798. self,
  1799. parent=parent,
  1800. id=id,
  1801. title=_("Raster map settings"),
  1802. settings=settings,
  1803. env=env,
  1804. )
  1805. self.objectType = ("raster",)
  1806. self.rPanel = RasterPanel(
  1807. parent=self,
  1808. id=self.id,
  1809. settings=self.instruction,
  1810. notebook=False,
  1811. env=self.env,
  1812. )
  1813. self.id = self.rPanel.getId()
  1814. self._layout(self.rPanel)
  1815. def update(self):
  1816. ok = self.rPanel.update()
  1817. if ok:
  1818. return True
  1819. return False
  1820. def OnApply(self, event):
  1821. ok = self.update()
  1822. if not ok:
  1823. return False
  1824. if self.id in self.instruction:
  1825. self.parent.DialogDataChanged(id=self.id)
  1826. else:
  1827. mapId = self.instruction.FindInstructionByType("map").id
  1828. self.parent.DialogDataChanged(id=mapId)
  1829. return True
  1830. def updateDialog(self):
  1831. """Update information (not used)"""
  1832. pass
  1833. # if 'map' in self.parent.openDialogs:
  1834. # if self.parent.openDialogs['map'].mPanel.rasterTypeRadio.GetValue()\
  1835. # and self.parent.openDialogs['map'].mPanel.select.GetValue():
  1836. # if self.parent.openDialogs['map'].mPanel.drawMap.IsChecked():
  1837. # self.rPanel.rasterSelect.SetValue(self.parent.openDialogs['map'].mPanel.select.GetValue())
  1838. class MainVectorDialog(PsmapDialog):
  1839. def __init__(self, parent, id, settings, env):
  1840. PsmapDialog.__init__(
  1841. self,
  1842. parent=parent,
  1843. id=id,
  1844. title=_("Vector maps settings"),
  1845. settings=settings,
  1846. env=env,
  1847. )
  1848. self.objectType = ("vector",)
  1849. self.vPanel = VectorPanel(
  1850. parent=self, id=self.id, settings=self.instruction, env=env, notebook=False
  1851. )
  1852. self.id = self.vPanel.getId()
  1853. self._layout(self.vPanel)
  1854. def update(self):
  1855. self.vPanel.update()
  1856. def OnApply(self, event):
  1857. self.update()
  1858. if self.id in self.instruction:
  1859. self.parent.DialogDataChanged(id=self.id)
  1860. else:
  1861. mapId = self.instruction.FindInstructionByType("map").id
  1862. self.parent.DialogDataChanged(id=mapId)
  1863. return True
  1864. def updateDialog(self):
  1865. """Update information (not used)"""
  1866. pass
  1867. class VPropertiesDialog(PsmapDialog):
  1868. def __init__(self, parent, id, settings, vectors, tmpSettings, env):
  1869. PsmapDialog.__init__(
  1870. self,
  1871. parent=parent,
  1872. id=id,
  1873. title="",
  1874. settings=settings,
  1875. env=env,
  1876. apply=False,
  1877. )
  1878. vectorList = vectors
  1879. self.vPropertiesDict = tmpSettings
  1880. # determine map and its type
  1881. for item in vectorList:
  1882. if id == item[2]:
  1883. self.vectorName = item[0]
  1884. self.type = item[1]
  1885. self.SetTitle(_("%s properties") % self.vectorName)
  1886. # vector map info
  1887. self.connection = True
  1888. try:
  1889. self.mapDBInfo = VectorDBInfo(self.vectorName)
  1890. self.layers = self.mapDBInfo.layers.keys()
  1891. except grass.ScriptError:
  1892. self.connection = False
  1893. self.layers = []
  1894. if not self.layers:
  1895. self.connection = False
  1896. self.layers = []
  1897. self.currLayer = self.vPropertiesDict["layer"]
  1898. # path to symbols, patterns
  1899. gisbase = os.getenv("GISBASE")
  1900. self.symbolPath = os.path.join(gisbase, "etc", "symbol")
  1901. self.symbols = []
  1902. for dir in os.listdir(self.symbolPath):
  1903. for symbol in os.listdir(os.path.join(self.symbolPath, dir)):
  1904. self.symbols.append(os.path.join(dir, symbol))
  1905. self.patternPath = os.path.join(gisbase, "etc", "paint", "patterns")
  1906. # notebook
  1907. notebook = Notebook(parent=self, id=wx.ID_ANY, style=wx.BK_DEFAULT)
  1908. self.DSpanel = self._DataSelectionPanel(notebook)
  1909. self.EnableLayerSelection(enable=self.connection)
  1910. selectPanel = {
  1911. "points": [self._ColorsPointAreaPanel, self._StylePointPanel],
  1912. "lines": [self._ColorsLinePanel, self._StyleLinePanel],
  1913. "areas": [self._ColorsPointAreaPanel, self._StyleAreaPanel],
  1914. }
  1915. self.ColorsPanel = selectPanel[self.type][0](notebook)
  1916. self.OnOutline(None)
  1917. if self.type in ("points", "areas"):
  1918. self.OnFill(None)
  1919. self.OnColor(None)
  1920. self.StylePanel = selectPanel[self.type][1](notebook)
  1921. if self.type == "points":
  1922. self.OnSize(None)
  1923. self.OnRotation(None)
  1924. self.OnSymbology(None)
  1925. if self.type == "areas":
  1926. self.OnPattern(None)
  1927. self._layout(notebook)
  1928. def _DataSelectionPanel(self, notebook):
  1929. panel = Panel(
  1930. parent=notebook, id=wx.ID_ANY, size=(-1, -1), style=wx.TAB_TRAVERSAL
  1931. )
  1932. notebook.AddPage(page=panel, text=_("Data selection"))
  1933. border = wx.BoxSizer(wx.VERTICAL)
  1934. # data type
  1935. self.checkType1 = self.checkType2 = None
  1936. if self.type in ("lines", "points"):
  1937. box = StaticBox(
  1938. parent=panel, id=wx.ID_ANY, label=" %s " % _("Feature type")
  1939. )
  1940. sizer = wx.StaticBoxSizer(box, wx.HORIZONTAL)
  1941. gridBagSizer = wx.GridBagSizer(hgap=5, vgap=5)
  1942. if self.type == "points":
  1943. label = (_("points"), _("centroids"))
  1944. else:
  1945. label = (_("lines"), _("boundaries"))
  1946. if self.type == "points":
  1947. name = ("point", "centroid")
  1948. else:
  1949. name = ("line", "boundary")
  1950. self.checkType1 = CheckBox(
  1951. panel, id=wx.ID_ANY, label=label[0], name=name[0]
  1952. )
  1953. self.checkType2 = CheckBox(
  1954. panel, id=wx.ID_ANY, label=label[1], name=name[1]
  1955. )
  1956. self.checkType1.SetValue(self.vPropertiesDict["type"].find(name[0]) >= 0)
  1957. self.checkType2.SetValue(self.vPropertiesDict["type"].find(name[1]) >= 0)
  1958. gridBagSizer.Add(
  1959. self.checkType1, pos=(0, 0), flag=wx.ALIGN_CENTER_VERTICAL, border=0
  1960. )
  1961. gridBagSizer.Add(
  1962. self.checkType2, pos=(0, 1), flag=wx.ALIGN_CENTER_VERTICAL, border=0
  1963. )
  1964. sizer.Add(gridBagSizer, proportion=1, flag=wx.EXPAND | wx.ALL, border=5)
  1965. border.Add(sizer, proportion=0, flag=wx.ALL | wx.EXPAND, border=5)
  1966. # layer selection
  1967. box = StaticBox(parent=panel, id=wx.ID_ANY, label=" %s " % _("Layer selection"))
  1968. sizer = wx.StaticBoxSizer(box, wx.HORIZONTAL)
  1969. self.gridBagSizerL = wx.GridBagSizer(hgap=5, vgap=5)
  1970. self.warning = StaticText(panel, id=wx.ID_ANY, label="")
  1971. if not self.connection:
  1972. self.warning = StaticText(
  1973. panel,
  1974. id=wx.ID_ANY,
  1975. label=_("Database connection is not defined in DB file."),
  1976. )
  1977. text = StaticText(panel, id=wx.ID_ANY, label=_("Select layer:"))
  1978. self.layerChoice = Choice(
  1979. panel,
  1980. id=wx.ID_ANY,
  1981. choices=[str(each) for each in self.layers],
  1982. size=self.spinCtrlSize,
  1983. )
  1984. self.layerChoice.SetStringSelection(self.currLayer)
  1985. if self.connection:
  1986. table = self.mapDBInfo.layers[int(self.currLayer)]["table"]
  1987. else:
  1988. table = ""
  1989. self.radioWhere = RadioButton(
  1990. panel,
  1991. id=wx.ID_ANY,
  1992. label="SELECT * FROM %s WHERE" % table,
  1993. style=wx.RB_GROUP,
  1994. )
  1995. self.textCtrlWhere = TextCtrl(panel, id=wx.ID_ANY, value="")
  1996. if self.connection:
  1997. cols = self.mapDBInfo.GetColumns(
  1998. self.mapDBInfo.layers[int(self.currLayer)]["table"]
  1999. )
  2000. else:
  2001. cols = []
  2002. self.choiceColumns = Choice(panel, id=wx.ID_ANY, choices=cols)
  2003. self.radioCats = RadioButton(panel, id=wx.ID_ANY, label="Choose categories ")
  2004. self.textCtrlCats = TextCtrl(panel, id=wx.ID_ANY, value="")
  2005. self.textCtrlCats.SetToolTip(_("list of categories (e.g. 1,3,5-7)"))
  2006. if "cats" in self.vPropertiesDict:
  2007. self.radioCats.SetValue(True)
  2008. self.textCtrlCats.SetValue(self.vPropertiesDict["cats"])
  2009. if "where" in self.vPropertiesDict:
  2010. self.radioWhere.SetValue(True)
  2011. where = self.vPropertiesDict["where"].strip().split(" ", 1)
  2012. self.choiceColumns.SetStringSelection(where[0])
  2013. self.textCtrlWhere.SetValue(where[1])
  2014. row = 0
  2015. if not self.connection:
  2016. self.gridBagSizerL.Add(
  2017. self.warning,
  2018. pos=(0, 0),
  2019. span=(1, 3),
  2020. flag=wx.ALIGN_CENTER_VERTICAL,
  2021. border=0,
  2022. )
  2023. row = 1
  2024. self.gridBagSizerL.Add(
  2025. text, pos=(0 + row, 0), flag=wx.ALIGN_CENTER_VERTICAL, border=0
  2026. )
  2027. self.gridBagSizerL.Add(
  2028. self.layerChoice,
  2029. pos=(0 + row, 1),
  2030. flag=wx.ALIGN_CENTER_VERTICAL | wx.EXPAND,
  2031. border=0,
  2032. )
  2033. self.gridBagSizerL.Add(
  2034. self.radioWhere, pos=(1 + row, 0), flag=wx.ALIGN_CENTER_VERTICAL, border=0
  2035. )
  2036. self.gridBagSizerL.Add(
  2037. self.choiceColumns,
  2038. pos=(1 + row, 1),
  2039. flag=wx.ALIGN_CENTER_VERTICAL,
  2040. border=0,
  2041. )
  2042. self.gridBagSizerL.Add(
  2043. self.textCtrlWhere,
  2044. pos=(1 + row, 2),
  2045. flag=wx.ALIGN_CENTER_VERTICAL,
  2046. border=0,
  2047. )
  2048. self.gridBagSizerL.Add(
  2049. self.radioCats, pos=(2 + row, 0), flag=wx.ALIGN_CENTER_VERTICAL, border=0
  2050. )
  2051. self.gridBagSizerL.Add(
  2052. self.textCtrlCats,
  2053. pos=(2 + row, 1),
  2054. span=(1, 2),
  2055. flag=wx.ALIGN_CENTER_VERTICAL | wx.EXPAND,
  2056. border=0,
  2057. )
  2058. sizer.Add(self.gridBagSizerL, proportion=1, flag=wx.EXPAND | wx.ALL, border=5)
  2059. border.Add(sizer, proportion=0, flag=wx.ALL | wx.EXPAND, border=5)
  2060. # mask
  2061. box = StaticBox(parent=panel, id=wx.ID_ANY, label=" %s " % _("Mask"))
  2062. sizer = wx.StaticBoxSizer(box, wx.HORIZONTAL)
  2063. self.mask = CheckBox(panel, id=wx.ID_ANY, label=_("Use current mask"))
  2064. if self.vPropertiesDict["masked"] == "y":
  2065. self.mask.SetValue(True)
  2066. else:
  2067. self.mask.SetValue(False)
  2068. sizer.Add(self.mask, proportion=1, flag=wx.EXPAND | wx.ALL, border=5)
  2069. border.Add(sizer, proportion=0, flag=wx.ALL | wx.EXPAND, border=5)
  2070. self.Bind(wx.EVT_CHOICE, self.OnLayer, self.layerChoice)
  2071. panel.SetSizer(border)
  2072. panel.Fit()
  2073. return panel
  2074. def _ColorsPointAreaPanel(self, notebook):
  2075. panel = Panel(
  2076. parent=notebook, id=wx.ID_ANY, size=(-1, -1), style=wx.TAB_TRAVERSAL
  2077. )
  2078. notebook.AddPage(page=panel, text=_("Colors"))
  2079. border = wx.BoxSizer(wx.VERTICAL)
  2080. # colors - outline
  2081. box = StaticBox(parent=panel, id=wx.ID_ANY, label=" %s " % _("Outline"))
  2082. sizer = wx.StaticBoxSizer(box, wx.HORIZONTAL)
  2083. self.gridBagSizerO = wx.GridBagSizer(hgap=5, vgap=2)
  2084. self.outlineCheck = CheckBox(panel, id=wx.ID_ANY, label=_("draw outline"))
  2085. self.outlineCheck.SetValue(self.vPropertiesDict["color"] != "none")
  2086. widthText = StaticText(panel, id=wx.ID_ANY, label=_("Width (pts):"))
  2087. self.widthSpin = FloatSpin(
  2088. panel,
  2089. id=wx.ID_ANY,
  2090. min_val=0,
  2091. max_val=30,
  2092. increment=0.5,
  2093. value=1,
  2094. style=fs.FS_RIGHT,
  2095. )
  2096. self.widthSpin.SetFormat("%f")
  2097. self.widthSpin.SetDigits(2)
  2098. if self.vPropertiesDict["color"] is None:
  2099. self.vPropertiesDict["color"] = "none"
  2100. if self.vPropertiesDict["color"] != "none":
  2101. self.widthSpin.SetValue(self.vPropertiesDict["width"])
  2102. else:
  2103. self.widthSpin.SetValue(1)
  2104. colorText = StaticText(panel, id=wx.ID_ANY, label=_("Color:"))
  2105. self.colorPicker = ColourPickerCtrl(panel, id=wx.ID_ANY)
  2106. if self.vPropertiesDict["color"] != "none":
  2107. self.colorPicker.SetColour(convertRGB(self.vPropertiesDict["color"]))
  2108. else:
  2109. self.colorPicker.SetColour(convertRGB("black"))
  2110. self.gridBagSizerO.Add(
  2111. self.outlineCheck,
  2112. pos=(0, 0),
  2113. span=(1, 2),
  2114. flag=wx.ALIGN_CENTER_VERTICAL,
  2115. border=0,
  2116. )
  2117. self.gridBagSizerO.Add(
  2118. widthText, pos=(1, 1), flag=wx.ALIGN_CENTER_VERTICAL, border=0
  2119. )
  2120. self.gridBagSizerO.Add(
  2121. self.widthSpin,
  2122. pos=(1, 2),
  2123. flag=wx.ALIGN_CENTER_VERTICAL | wx.EXPAND,
  2124. border=0,
  2125. )
  2126. self.gridBagSizerO.Add(
  2127. colorText, pos=(2, 1), flag=wx.ALIGN_CENTER_VERTICAL, border=0
  2128. )
  2129. self.gridBagSizerO.Add(
  2130. self.colorPicker, pos=(2, 2), flag=wx.ALIGN_CENTER_VERTICAL, border=0
  2131. )
  2132. sizer.Add(self.gridBagSizerO, proportion=1, flag=wx.EXPAND | wx.ALL, border=5)
  2133. border.Add(sizer, proportion=0, flag=wx.ALL | wx.EXPAND, border=5)
  2134. self.Bind(wx.EVT_CHECKBOX, self.OnOutline, self.outlineCheck)
  2135. # colors - fill
  2136. box = StaticBox(parent=panel, id=wx.ID_ANY, label=" %s " % _("Fill"))
  2137. sizer = wx.StaticBoxSizer(box, wx.HORIZONTAL)
  2138. self.gridBagSizerF = wx.GridBagSizer(hgap=5, vgap=2)
  2139. self.fillCheck = CheckBox(panel, id=wx.ID_ANY, label=_("fill color"))
  2140. self.fillCheck.SetValue(
  2141. self.vPropertiesDict["fcolor"] != "none"
  2142. or self.vPropertiesDict["rgbcolumn"] is not None
  2143. )
  2144. self.colorPickerRadio = RadioButton(
  2145. panel, id=wx.ID_ANY, label=_("choose color:"), style=wx.RB_GROUP
  2146. )
  2147. # set choose color option if there is no db connection
  2148. if self.connection:
  2149. self.colorPickerRadio.SetValue(not self.vPropertiesDict["rgbcolumn"])
  2150. else:
  2151. self.colorPickerRadio.SetValue(False)
  2152. self.fillColorPicker = ColourPickerCtrl(panel, id=wx.ID_ANY)
  2153. if self.vPropertiesDict["fcolor"] != "none":
  2154. self.fillColorPicker.SetColour(convertRGB(self.vPropertiesDict["fcolor"]))
  2155. else:
  2156. self.fillColorPicker.SetColour(convertRGB("red"))
  2157. self.colorColRadio = RadioButton(
  2158. panel, id=wx.ID_ANY, label=_("color from map table column:")
  2159. )
  2160. self.colorColChoice = self.getColsChoice(parent=panel)
  2161. if self.connection:
  2162. if self.vPropertiesDict["rgbcolumn"]:
  2163. self.colorColRadio.SetValue(True)
  2164. self.colorColChoice.SetStringSelection(
  2165. self.vPropertiesDict["rgbcolumn"]
  2166. )
  2167. else:
  2168. self.colorColRadio.SetValue(False)
  2169. self.colorColChoice.SetSelection(0)
  2170. self.colorColChoice.Enable(self.connection)
  2171. self.colorColRadio.Enable(self.connection)
  2172. self.gridBagSizerF.Add(
  2173. self.fillCheck,
  2174. pos=(0, 0),
  2175. span=(1, 2),
  2176. flag=wx.ALIGN_CENTER_VERTICAL,
  2177. border=0,
  2178. )
  2179. self.gridBagSizerF.Add(
  2180. self.colorPickerRadio, pos=(1, 1), flag=wx.ALIGN_CENTER_VERTICAL, border=0
  2181. )
  2182. self.gridBagSizerF.Add(
  2183. self.fillColorPicker, pos=(1, 2), flag=wx.ALIGN_CENTER_VERTICAL, border=0
  2184. )
  2185. self.gridBagSizerF.Add(
  2186. self.colorColRadio, pos=(2, 1), flag=wx.ALIGN_CENTER_VERTICAL, border=0
  2187. )
  2188. self.gridBagSizerF.Add(
  2189. self.colorColChoice,
  2190. pos=(2, 2),
  2191. flag=wx.ALIGN_CENTER_VERTICAL | wx.EXPAND,
  2192. border=0,
  2193. )
  2194. sizer.Add(self.gridBagSizerF, proportion=1, flag=wx.EXPAND | wx.ALL, border=5)
  2195. border.Add(sizer, proportion=0, flag=wx.ALL | wx.EXPAND, border=5)
  2196. self.Bind(wx.EVT_CHECKBOX, self.OnFill, self.fillCheck)
  2197. self.Bind(wx.EVT_RADIOBUTTON, self.OnColor, self.colorColRadio)
  2198. self.Bind(wx.EVT_RADIOBUTTON, self.OnColor, self.colorPickerRadio)
  2199. panel.SetSizer(border)
  2200. panel.Fit()
  2201. return panel
  2202. def _ColorsLinePanel(self, notebook):
  2203. panel = Panel(
  2204. parent=notebook, id=wx.ID_ANY, size=(-1, -1), style=wx.TAB_TRAVERSAL
  2205. )
  2206. notebook.AddPage(page=panel, text=_("Colors"))
  2207. border = wx.BoxSizer(wx.VERTICAL)
  2208. # colors - outline
  2209. box = StaticBox(parent=panel, id=wx.ID_ANY, label=" %s " % _("Outline"))
  2210. sizer = wx.StaticBoxSizer(box, wx.HORIZONTAL)
  2211. self.gridBagSizerO = wx.GridBagSizer(hgap=5, vgap=2)
  2212. if self.vPropertiesDict["hcolor"] is None:
  2213. self.vPropertiesDict["hcolor"] = "none"
  2214. if self.vPropertiesDict["color"] is None:
  2215. self.vPropertiesDict["color"] = "none"
  2216. self.outlineCheck = CheckBox(panel, id=wx.ID_ANY, label=_("draw outline"))
  2217. self.outlineCheck.SetValue(self.vPropertiesDict["hcolor"] != "none")
  2218. self.outlineCheck.SetToolTip(_("No effect for fill color from table column"))
  2219. widthText = StaticText(panel, id=wx.ID_ANY, label=_("Width (pts):"))
  2220. self.outWidthSpin = FloatSpin(
  2221. panel,
  2222. id=wx.ID_ANY,
  2223. min_val=0,
  2224. max_val=30,
  2225. increment=0.5,
  2226. value=1,
  2227. style=fs.FS_RIGHT,
  2228. )
  2229. self.outWidthSpin.SetFormat("%f")
  2230. self.outWidthSpin.SetDigits(1)
  2231. if self.vPropertiesDict["hcolor"] != "none":
  2232. self.outWidthSpin.SetValue(self.vPropertiesDict["hwidth"])
  2233. else:
  2234. self.outWidthSpin.SetValue(1)
  2235. colorText = StaticText(panel, id=wx.ID_ANY, label=_("Color:"))
  2236. self.colorPicker = ColourPickerCtrl(panel, id=wx.ID_ANY)
  2237. if self.vPropertiesDict["hcolor"] != "none":
  2238. self.colorPicker.SetColour(convertRGB(self.vPropertiesDict["hcolor"]))
  2239. else:
  2240. self.colorPicker.SetColour(convertRGB("black"))
  2241. self.gridBagSizerO.Add(
  2242. self.outlineCheck,
  2243. pos=(0, 0),
  2244. span=(1, 2),
  2245. flag=wx.ALIGN_CENTER_VERTICAL,
  2246. border=0,
  2247. )
  2248. self.gridBagSizerO.Add(
  2249. widthText, pos=(1, 1), flag=wx.ALIGN_CENTER_VERTICAL, border=0
  2250. )
  2251. self.gridBagSizerO.Add(
  2252. self.outWidthSpin,
  2253. pos=(1, 2),
  2254. flag=wx.ALIGN_CENTER_VERTICAL | wx.EXPAND,
  2255. border=0,
  2256. )
  2257. self.gridBagSizerO.Add(
  2258. colorText, pos=(2, 1), flag=wx.ALIGN_CENTER_VERTICAL, border=0
  2259. )
  2260. self.gridBagSizerO.Add(
  2261. self.colorPicker, pos=(2, 2), flag=wx.ALIGN_CENTER_VERTICAL, border=0
  2262. )
  2263. sizer.Add(self.gridBagSizerO, proportion=1, flag=wx.EXPAND | wx.ALL, border=5)
  2264. border.Add(sizer, proportion=0, flag=wx.ALL | wx.EXPAND, border=5)
  2265. self.Bind(wx.EVT_CHECKBOX, self.OnOutline, self.outlineCheck)
  2266. # colors - fill
  2267. box = StaticBox(parent=panel, id=wx.ID_ANY, label=" %s " % _("Fill"))
  2268. sizer = wx.StaticBoxSizer(box, wx.HORIZONTAL)
  2269. self.gridBagSizerF = wx.GridBagSizer(hgap=5, vgap=2)
  2270. fillText = StaticText(panel, id=wx.ID_ANY, label=_("Color of lines:"))
  2271. self.colorPickerRadio = RadioButton(
  2272. panel, id=wx.ID_ANY, label=_("choose color:"), style=wx.RB_GROUP
  2273. )
  2274. # set choose color option if there is no db connection
  2275. if self.connection:
  2276. self.colorPickerRadio.SetValue(not self.vPropertiesDict["rgbcolumn"])
  2277. else:
  2278. self.colorPickerRadio.SetValue(False)
  2279. self.fillColorPicker = ColourPickerCtrl(panel, id=wx.ID_ANY)
  2280. if self.vPropertiesDict["color"] != "none":
  2281. self.fillColorPicker.SetColour(convertRGB(self.vPropertiesDict["color"]))
  2282. else:
  2283. self.fillColorPicker.SetColour(convertRGB("black"))
  2284. self.colorColRadio = RadioButton(
  2285. panel, id=wx.ID_ANY, label=_("color from map table column:")
  2286. )
  2287. self.colorColChoice = self.getColsChoice(parent=panel)
  2288. if self.connection:
  2289. if self.vPropertiesDict["rgbcolumn"]:
  2290. self.colorColRadio.SetValue(True)
  2291. self.colorColChoice.SetStringSelection(
  2292. self.vPropertiesDict["rgbcolumn"]
  2293. )
  2294. else:
  2295. self.colorColRadio.SetValue(False)
  2296. self.colorColChoice.SetSelection(0)
  2297. self.colorColChoice.Enable(self.connection)
  2298. self.colorColRadio.Enable(self.connection)
  2299. self.gridBagSizerF.Add(
  2300. fillText, pos=(0, 0), span=(1, 2), flag=wx.ALIGN_CENTER_VERTICAL, border=0
  2301. )
  2302. self.gridBagSizerF.Add(
  2303. self.colorPickerRadio, pos=(1, 1), flag=wx.ALIGN_CENTER_VERTICAL, border=0
  2304. )
  2305. self.gridBagSizerF.Add(
  2306. self.fillColorPicker, pos=(1, 2), flag=wx.ALIGN_CENTER_VERTICAL, border=0
  2307. )
  2308. self.gridBagSizerF.Add(
  2309. self.colorColRadio, pos=(2, 1), flag=wx.ALIGN_CENTER_VERTICAL, border=0
  2310. )
  2311. self.gridBagSizerF.Add(
  2312. self.colorColChoice,
  2313. pos=(2, 2),
  2314. flag=wx.ALIGN_CENTER_VERTICAL | wx.EXPAND,
  2315. border=0,
  2316. )
  2317. sizer.Add(self.gridBagSizerF, proportion=1, flag=wx.EXPAND | wx.ALL, border=5)
  2318. border.Add(sizer, proportion=0, flag=wx.ALL | wx.EXPAND, border=5)
  2319. self.Bind(wx.EVT_RADIOBUTTON, self.OnColor, self.colorColRadio)
  2320. self.Bind(wx.EVT_RADIOBUTTON, self.OnColor, self.colorPickerRadio)
  2321. panel.SetSizer(border)
  2322. panel.Fit()
  2323. return panel
  2324. def _StylePointPanel(self, notebook):
  2325. panel = Panel(
  2326. parent=notebook, id=wx.ID_ANY, size=(-1, -1), style=wx.TAB_TRAVERSAL
  2327. )
  2328. notebook.AddPage(page=panel, text=_("Size and style"))
  2329. border = wx.BoxSizer(wx.VERTICAL)
  2330. # symbology
  2331. box = StaticBox(parent=panel, id=wx.ID_ANY, label=" %s " % _("Symbology"))
  2332. sizer = wx.StaticBoxSizer(box, wx.HORIZONTAL)
  2333. gridBagSizer = wx.GridBagSizer(hgap=5, vgap=5)
  2334. self.symbolRadio = RadioButton(
  2335. panel, id=wx.ID_ANY, label=_("symbol:"), style=wx.RB_GROUP
  2336. )
  2337. self.symbolRadio.SetValue(bool(self.vPropertiesDict["symbol"]))
  2338. self.symbolName = StaticText(panel, id=wx.ID_ANY)
  2339. self.symbolName.SetLabel(self.vPropertiesDict["symbol"])
  2340. bitmap = wx.Bitmap(
  2341. os.path.join(globalvar.SYMBDIR, self.vPropertiesDict["symbol"]) + ".png"
  2342. )
  2343. self.symbolButton = BitmapButton(panel, id=wx.ID_ANY, bitmap=bitmap)
  2344. self.epsRadio = RadioButton(panel, id=wx.ID_ANY, label=_("eps file:"))
  2345. self.epsRadio.SetValue(bool(self.vPropertiesDict["eps"]))
  2346. self.epsFileCtrl = FileBrowseButton(
  2347. panel,
  2348. id=wx.ID_ANY,
  2349. labelText="",
  2350. buttonText=_("Browse"),
  2351. toolTip=_("Type filename or click browse to choose file"),
  2352. dialogTitle=_("Choose a file"),
  2353. startDirectory="",
  2354. initialValue="",
  2355. fileMask="Encapsulated PostScript (*.eps)|*.eps|All files (*.*)|*.*",
  2356. fileMode=wx.FD_OPEN,
  2357. )
  2358. if not self.vPropertiesDict["eps"]:
  2359. self.epsFileCtrl.SetValue("")
  2360. else: # eps chosen
  2361. self.epsFileCtrl.SetValue(self.vPropertiesDict["eps"])
  2362. gridBagSizer.Add(
  2363. self.symbolRadio, pos=(0, 0), flag=wx.ALIGN_CENTER_VERTICAL, border=0
  2364. )
  2365. gridBagSizer.Add(
  2366. self.symbolName,
  2367. pos=(0, 1),
  2368. flag=wx.ALIGN_CENTER_VERTICAL | wx.LEFT,
  2369. border=10,
  2370. )
  2371. gridBagSizer.Add(self.symbolButton, pos=(0, 2), flag=wx.ALIGN_RIGHT, border=0)
  2372. gridBagSizer.Add(
  2373. self.epsRadio, pos=(1, 0), flag=wx.ALIGN_CENTER_VERTICAL, border=0
  2374. )
  2375. gridBagSizer.Add(
  2376. self.epsFileCtrl,
  2377. pos=(1, 1),
  2378. span=(1, 2),
  2379. flag=wx.ALIGN_CENTER_VERTICAL | wx.EXPAND,
  2380. border=0,
  2381. )
  2382. gridBagSizer.AddGrowableCol(1)
  2383. gridBagSizer.AddGrowableCol(2)
  2384. sizer.Add(gridBagSizer, proportion=1, flag=wx.EXPAND | wx.ALL, border=5)
  2385. border.Add(sizer, proportion=0, flag=wx.ALL | wx.EXPAND, border=5)
  2386. self.Bind(wx.EVT_BUTTON, self.OnSymbolSelection, self.symbolButton)
  2387. self.Bind(wx.EVT_RADIOBUTTON, self.OnSymbology, self.symbolRadio)
  2388. self.Bind(wx.EVT_RADIOBUTTON, self.OnSymbology, self.epsRadio)
  2389. # size
  2390. box = StaticBox(parent=panel, id=wx.ID_ANY, label=" %s " % _("Size"))
  2391. sizer = wx.StaticBoxSizer(box, wx.HORIZONTAL)
  2392. gridBagSizer = wx.GridBagSizer(hgap=5, vgap=5)
  2393. self.sizeRadio = RadioButton(
  2394. panel, id=wx.ID_ANY, label=_("size:"), style=wx.RB_GROUP
  2395. )
  2396. self.sizeSpin = SpinCtrl(panel, id=wx.ID_ANY, min=1, max=50, initial=1)
  2397. self.sizecolumnRadio = RadioButton(
  2398. panel, id=wx.ID_ANY, label=_("size from map table column:")
  2399. )
  2400. self.sizeColChoice = self.getColsChoice(panel)
  2401. self.scaleText = StaticText(panel, id=wx.ID_ANY, label=_("scale:"))
  2402. self.scaleSpin = SpinCtrl(panel, id=wx.ID_ANY, min=1, max=25, initial=1)
  2403. self.sizeRadio.SetValue(self.vPropertiesDict["size"] is not None)
  2404. self.sizecolumnRadio.SetValue(bool(self.vPropertiesDict["sizecolumn"]))
  2405. if self.vPropertiesDict["size"]:
  2406. self.sizeSpin.SetValue(self.vPropertiesDict["size"])
  2407. else:
  2408. self.sizeSpin.SetValue(5)
  2409. if self.vPropertiesDict["sizecolumn"]:
  2410. self.scaleSpin.SetValue(self.vPropertiesDict["scale"])
  2411. self.sizeColChoice.SetStringSelection(self.vPropertiesDict["sizecolumn"])
  2412. else:
  2413. self.scaleSpin.SetValue(1)
  2414. self.sizeColChoice.SetSelection(0)
  2415. if not self.connection:
  2416. for each in (
  2417. self.sizecolumnRadio,
  2418. self.sizeColChoice,
  2419. self.scaleSpin,
  2420. self.scaleText,
  2421. ):
  2422. each.Disable()
  2423. gridBagSizer.Add(
  2424. self.sizeRadio, pos=(0, 0), flag=wx.ALIGN_CENTER_VERTICAL, border=0
  2425. )
  2426. gridBagSizer.Add(
  2427. self.sizeSpin, pos=(0, 1), flag=wx.ALIGN_CENTER_VERTICAL, border=0
  2428. )
  2429. gridBagSizer.Add(
  2430. self.sizecolumnRadio, pos=(1, 0), flag=wx.ALIGN_CENTER_VERTICAL, border=0
  2431. )
  2432. gridBagSizer.Add(
  2433. self.sizeColChoice,
  2434. pos=(1, 1),
  2435. flag=wx.ALIGN_CENTER_VERTICAL | wx.EXPAND,
  2436. border=0,
  2437. )
  2438. gridBagSizer.Add(
  2439. self.scaleText,
  2440. pos=(2, 0),
  2441. flag=wx.ALIGN_CENTER_VERTICAL | wx.ALIGN_RIGHT,
  2442. border=0,
  2443. )
  2444. gridBagSizer.Add(
  2445. self.scaleSpin, pos=(2, 1), flag=wx.ALIGN_CENTER_VERTICAL, border=0
  2446. )
  2447. gridBagSizer.AddGrowableCol(0)
  2448. sizer.Add(gridBagSizer, proportion=1, flag=wx.EXPAND | wx.ALL, border=5)
  2449. border.Add(sizer, proportion=0, flag=wx.ALL | wx.EXPAND, border=5)
  2450. self.Bind(wx.EVT_RADIOBUTTON, self.OnSize, self.sizeRadio)
  2451. self.Bind(wx.EVT_RADIOBUTTON, self.OnSize, self.sizecolumnRadio)
  2452. # rotation
  2453. box = StaticBox(parent=panel, id=wx.ID_ANY, label=" %s " % _("Rotation"))
  2454. sizer = wx.StaticBoxSizer(box, wx.HORIZONTAL)
  2455. gridBagSizer = wx.GridBagSizer(hgap=5, vgap=5)
  2456. self.rotateCheck = CheckBox(panel, id=wx.ID_ANY, label=_("rotate symbols:"))
  2457. self.rotateRadio = RadioButton(
  2458. panel,
  2459. id=wx.ID_ANY,
  2460. label=_("counterclockwise in degrees:"),
  2461. style=wx.RB_GROUP,
  2462. )
  2463. self.rotateSpin = SpinCtrl(panel, id=wx.ID_ANY, min=0, max=360, initial=0)
  2464. self.rotatecolumnRadio = RadioButton(
  2465. panel, id=wx.ID_ANY, label=_("from map table column:")
  2466. )
  2467. self.rotateColChoice = self.getColsChoice(panel)
  2468. self.rotateCheck.SetValue(self.vPropertiesDict["rotation"])
  2469. self.rotateRadio.SetValue(self.vPropertiesDict["rotate"] is not None)
  2470. self.rotatecolumnRadio.SetValue(bool(self.vPropertiesDict["rotatecolumn"]))
  2471. if self.vPropertiesDict["rotate"]:
  2472. self.rotateSpin.SetValue(self.vPropertiesDict["rotate"])
  2473. else:
  2474. self.rotateSpin.SetValue(0)
  2475. if self.vPropertiesDict["rotatecolumn"]:
  2476. self.rotateColChoice.SetStringSelection(
  2477. self.vPropertiesDict["rotatecolumn"]
  2478. )
  2479. else:
  2480. self.rotateColChoice.SetSelection(0)
  2481. gridBagSizer.Add(
  2482. self.rotateCheck,
  2483. pos=(0, 0),
  2484. span=(1, 2),
  2485. flag=wx.ALIGN_CENTER_VERTICAL,
  2486. border=0,
  2487. )
  2488. gridBagSizer.Add(
  2489. self.rotateRadio, pos=(1, 1), flag=wx.ALIGN_CENTER_VERTICAL, border=0
  2490. )
  2491. gridBagSizer.Add(
  2492. self.rotateSpin, pos=(1, 2), flag=wx.ALIGN_CENTER_VERTICAL, border=0
  2493. )
  2494. gridBagSizer.Add(
  2495. self.rotatecolumnRadio, pos=(2, 1), flag=wx.ALIGN_CENTER_VERTICAL, border=0
  2496. )
  2497. gridBagSizer.Add(
  2498. self.rotateColChoice,
  2499. pos=(2, 2),
  2500. flag=wx.ALIGN_CENTER_VERTICAL | wx.EXPAND,
  2501. border=0,
  2502. )
  2503. gridBagSizer.AddGrowableCol(1)
  2504. sizer.Add(gridBagSizer, proportion=1, flag=wx.EXPAND | wx.ALL, border=5)
  2505. border.Add(sizer, proportion=0, flag=wx.ALL | wx.EXPAND, border=5)
  2506. self.Bind(wx.EVT_CHECKBOX, self.OnRotation, self.rotateCheck)
  2507. self.Bind(wx.EVT_RADIOBUTTON, self.OnRotationType, self.rotateRadio)
  2508. self.Bind(wx.EVT_RADIOBUTTON, self.OnRotationType, self.rotatecolumnRadio)
  2509. panel.SetSizer(border)
  2510. panel.Fit()
  2511. return panel
  2512. def _StyleLinePanel(self, notebook):
  2513. panel = Panel(
  2514. parent=notebook, id=wx.ID_ANY, size=(-1, -1), style=wx.TAB_TRAVERSAL
  2515. )
  2516. notebook.AddPage(page=panel, text=_("Size and style"))
  2517. border = wx.BoxSizer(wx.VERTICAL)
  2518. # width
  2519. box = StaticBox(parent=panel, id=wx.ID_ANY, label=" %s " % _("Width"))
  2520. sizer = wx.StaticBoxSizer(box, wx.HORIZONTAL)
  2521. gridBagSizer = wx.GridBagSizer(hgap=5, vgap=5)
  2522. widthText = StaticText(panel, id=wx.ID_ANY, label=_("Set width (pts):"))
  2523. self.widthSpin = FloatSpin(
  2524. panel,
  2525. id=wx.ID_ANY,
  2526. min_val=0,
  2527. max_val=30,
  2528. increment=0.5,
  2529. value=1,
  2530. style=fs.FS_RIGHT,
  2531. )
  2532. self.widthSpin.SetFormat("%f")
  2533. self.widthSpin.SetDigits(1)
  2534. self.cwidthCheck = CheckBox(
  2535. panel, id=wx.ID_ANY, label=_("multiply width by category value")
  2536. )
  2537. if self.vPropertiesDict["width"]:
  2538. self.widthSpin.SetValue(self.vPropertiesDict["width"])
  2539. self.cwidthCheck.SetValue(False)
  2540. else:
  2541. self.widthSpin.SetValue(self.vPropertiesDict["cwidth"])
  2542. self.cwidthCheck.SetValue(True)
  2543. gridBagSizer.Add(widthText, pos=(0, 0), flag=wx.ALIGN_CENTER_VERTICAL, border=0)
  2544. gridBagSizer.Add(
  2545. self.widthSpin, pos=(0, 1), flag=wx.ALIGN_CENTER_VERTICAL, border=0
  2546. )
  2547. gridBagSizer.Add(
  2548. self.cwidthCheck,
  2549. pos=(1, 0),
  2550. span=(1, 2),
  2551. flag=wx.ALIGN_CENTER_VERTICAL,
  2552. border=0,
  2553. )
  2554. sizer.Add(gridBagSizer, proportion=1, flag=wx.EXPAND | wx.ALL, border=5)
  2555. border.Add(sizer, proportion=0, flag=wx.ALL | wx.EXPAND, border=5)
  2556. # style
  2557. box = StaticBox(parent=panel, id=wx.ID_ANY, label=" %s " % _("Line style"))
  2558. sizer = wx.StaticBoxSizer(box, wx.HORIZONTAL)
  2559. gridBagSizer = wx.GridBagSizer(hgap=5, vgap=5)
  2560. styleText = StaticText(panel, id=wx.ID_ANY, label=_("Choose line style:"))
  2561. penStyles = ["solid", "dashed", "dotted", "dashdotted"]
  2562. self.styleCombo = PenStyleComboBox(
  2563. panel, choices=penStyles, validator=TCValidator(flag="ZERO_AND_ONE_ONLY")
  2564. )
  2565. # self.styleCombo = wx.ComboBox(panel, id = wx.ID_ANY,
  2566. ## choices = ["solid", "dashed", "dotted", "dashdotted"],
  2567. # validator = TCValidator(flag = 'ZERO_AND_ONE_ONLY'))
  2568. # self.styleCombo.SetToolTipString(_("It's possible to enter a series of 0's and 1's too. "\
  2569. ## "The first block of repeated zeros or ones represents 'draw', "\
  2570. ## "the second block represents 'blank'. An even number of blocks "\
  2571. # "will repeat the pattern, an odd number of blocks will alternate the pattern."))
  2572. linecapText = StaticText(panel, id=wx.ID_ANY, label=_("Choose linecap:"))
  2573. self.linecapChoice = Choice(
  2574. panel, id=wx.ID_ANY, choices=["butt", "round", "extended_butt"]
  2575. )
  2576. self.styleCombo.SetValue(self.vPropertiesDict["style"])
  2577. self.linecapChoice.SetStringSelection(self.vPropertiesDict["linecap"])
  2578. gridBagSizer.Add(styleText, pos=(0, 0), flag=wx.ALIGN_CENTER_VERTICAL, border=0)
  2579. gridBagSizer.Add(
  2580. self.styleCombo,
  2581. pos=(0, 1),
  2582. flag=wx.ALIGN_CENTER_VERTICAL | wx.EXPAND,
  2583. border=0,
  2584. )
  2585. gridBagSizer.Add(
  2586. linecapText, pos=(1, 0), flag=wx.ALIGN_CENTER_VERTICAL, border=0
  2587. )
  2588. gridBagSizer.Add(
  2589. self.linecapChoice,
  2590. pos=(1, 1),
  2591. flag=wx.ALIGN_CENTER_VERTICAL | wx.EXPAND,
  2592. border=0,
  2593. )
  2594. sizer.Add(gridBagSizer, proportion=1, flag=wx.EXPAND | wx.ALL, border=5)
  2595. border.Add(sizer, proportion=0, flag=wx.ALL | wx.EXPAND, border=5)
  2596. panel.SetSizer(border)
  2597. panel.Fit()
  2598. return panel
  2599. def _StyleAreaPanel(self, notebook):
  2600. panel = Panel(
  2601. parent=notebook, id=wx.ID_ANY, size=(-1, -1), style=wx.TAB_TRAVERSAL
  2602. )
  2603. notebook.AddPage(page=panel, text=_("Size and style"))
  2604. border = wx.BoxSizer(wx.VERTICAL)
  2605. # pattern
  2606. box = StaticBox(parent=panel, id=wx.ID_ANY, label=" %s " % _("Pattern"))
  2607. sizer = wx.StaticBoxSizer(box, wx.HORIZONTAL)
  2608. gridBagSizer = wx.GridBagSizer(hgap=5, vgap=5)
  2609. self.patternCheck = CheckBox(panel, id=wx.ID_ANY, label=_("use pattern:"))
  2610. self.patFileCtrl = FileBrowseButton(
  2611. panel,
  2612. id=wx.ID_ANY,
  2613. labelText=_("Choose pattern file:"),
  2614. buttonText=_("Browse"),
  2615. toolTip=_("Type filename or click browse to choose file"),
  2616. dialogTitle=_("Choose a file"),
  2617. startDirectory=self.patternPath,
  2618. initialValue="",
  2619. fileMask="Encapsulated PostScript (*.eps)|*.eps|All files (*.*)|*.*",
  2620. fileMode=wx.FD_OPEN,
  2621. )
  2622. self.patWidthText = StaticText(
  2623. panel, id=wx.ID_ANY, label=_("pattern line width (pts):")
  2624. )
  2625. self.patWidthSpin = SpinCtrl(panel, id=wx.ID_ANY, min=1, max=25, initial=1)
  2626. self.patScaleText = StaticText(
  2627. panel, id=wx.ID_ANY, label=_("pattern scale factor:")
  2628. )
  2629. self.patScaleSpin = SpinCtrl(panel, id=wx.ID_ANY, min=1, max=25, initial=1)
  2630. self.patternCheck.SetValue(bool(self.vPropertiesDict["pat"]))
  2631. if self.patternCheck.GetValue():
  2632. self.patFileCtrl.SetValue(self.vPropertiesDict["pat"])
  2633. self.patWidthSpin.SetValue(self.vPropertiesDict["pwidth"])
  2634. self.patScaleSpin.SetValue(self.vPropertiesDict["scale"])
  2635. gridBagSizer.Add(
  2636. self.patternCheck, pos=(0, 0), flag=wx.ALIGN_CENTER_VERTICAL, border=0
  2637. )
  2638. gridBagSizer.Add(
  2639. self.patFileCtrl,
  2640. pos=(1, 0),
  2641. span=(1, 2),
  2642. flag=wx.ALIGN_CENTER_VERTICAL | wx.EXPAND,
  2643. border=0,
  2644. )
  2645. gridBagSizer.Add(
  2646. self.patWidthText, pos=(2, 0), flag=wx.ALIGN_CENTER_VERTICAL, border=0
  2647. )
  2648. gridBagSizer.Add(
  2649. self.patWidthSpin, pos=(2, 1), flag=wx.ALIGN_CENTER_VERTICAL, border=0
  2650. )
  2651. gridBagSizer.Add(
  2652. self.patScaleText, pos=(3, 0), flag=wx.ALIGN_CENTER_VERTICAL, border=0
  2653. )
  2654. gridBagSizer.Add(
  2655. self.patScaleSpin, pos=(3, 1), flag=wx.ALIGN_CENTER_VERTICAL, border=0
  2656. )
  2657. gridBagSizer.AddGrowableCol(1)
  2658. sizer.Add(gridBagSizer, proportion=1, flag=wx.EXPAND | wx.ALL, border=5)
  2659. border.Add(sizer, proportion=0, flag=wx.ALL | wx.EXPAND, border=5)
  2660. self.Bind(wx.EVT_CHECKBOX, self.OnPattern, self.patternCheck)
  2661. panel.SetSizer(border)
  2662. panel.Fit()
  2663. return panel
  2664. def OnLayer(self, event):
  2665. """Change columns on layer change"""
  2666. if self.layerChoice.GetStringSelection() == self.currLayer:
  2667. return
  2668. self.currLayer = self.layerChoice.GetStringSelection()
  2669. if self.connection:
  2670. cols = self.mapDBInfo.GetColumns(
  2671. self.mapDBInfo.layers[int(self.currLayer)]["table"]
  2672. )
  2673. else:
  2674. cols = []
  2675. self.choiceColumns.SetItems(cols)
  2676. self.choiceColumns.SetSelection(0)
  2677. if self.type in ("points", "lines"):
  2678. self.colorColChoice.SetItems(cols)
  2679. self.colorColChoice.SetSelection(0)
  2680. def OnOutline(self, event):
  2681. for widget in self.gridBagSizerO.GetChildren():
  2682. if widget.GetWindow() != self.outlineCheck:
  2683. widget.GetWindow().Enable(self.outlineCheck.GetValue())
  2684. def OnFill(self, event):
  2685. enable = self.fillCheck.GetValue()
  2686. self.colorColChoice.Enable(enable)
  2687. self.colorColRadio.Enable(enable)
  2688. self.fillColorPicker.Enable(enable)
  2689. self.colorPickerRadio.Enable(enable)
  2690. if enable:
  2691. self.OnColor(None)
  2692. if not self.connection:
  2693. self.colorColChoice.Disable()
  2694. self.colorColRadio.Disable()
  2695. def OnColor(self, event):
  2696. self.colorColChoice.Enable(self.colorColRadio.GetValue())
  2697. self.fillColorPicker.Enable(self.colorPickerRadio.GetValue())
  2698. def OnSize(self, event):
  2699. self.sizeSpin.Enable(self.sizeRadio.GetValue())
  2700. self.sizeColChoice.Enable(self.sizecolumnRadio.GetValue())
  2701. self.scaleText.Enable(self.sizecolumnRadio.GetValue())
  2702. self.scaleSpin.Enable(self.sizecolumnRadio.GetValue())
  2703. def OnRotation(self, event):
  2704. for each in (
  2705. self.rotateRadio,
  2706. self.rotatecolumnRadio,
  2707. self.rotateColChoice,
  2708. self.rotateSpin,
  2709. ):
  2710. if self.rotateCheck.GetValue():
  2711. each.Enable()
  2712. self.OnRotationType(event=None)
  2713. else:
  2714. each.Disable()
  2715. def OnRotationType(self, event):
  2716. self.rotateSpin.Enable(self.rotateRadio.GetValue())
  2717. self.rotateColChoice.Enable(self.rotatecolumnRadio.GetValue())
  2718. def OnPattern(self, event):
  2719. for each in (
  2720. self.patFileCtrl,
  2721. self.patWidthText,
  2722. self.patWidthSpin,
  2723. self.patScaleText,
  2724. self.patScaleSpin,
  2725. ):
  2726. each.Enable(self.patternCheck.GetValue())
  2727. def OnSymbology(self, event):
  2728. useSymbol = self.symbolRadio.GetValue()
  2729. self.symbolButton.Enable(useSymbol)
  2730. self.symbolName.Enable(useSymbol)
  2731. self.epsFileCtrl.Enable(not useSymbol)
  2732. def OnSymbolSelection(self, event):
  2733. dlg = SymbolDialog(
  2734. self, symbolPath=globalvar.SYMBDIR, currentSymbol=self.symbolName.GetLabel()
  2735. )
  2736. if dlg.ShowModal() == wx.ID_OK:
  2737. img = dlg.GetSelectedSymbolPath()
  2738. name = dlg.GetSelectedSymbolName()
  2739. self.symbolButton.SetBitmapLabel(wx.Bitmap(img + ".png"))
  2740. self.symbolName.SetLabel(name)
  2741. dlg.Destroy()
  2742. def EnableLayerSelection(self, enable=True):
  2743. for widget in self.gridBagSizerL.GetChildren():
  2744. if widget.GetWindow() != self.warning:
  2745. widget.GetWindow().Enable(enable)
  2746. def getColsChoice(self, parent):
  2747. """Returns a Choice with table columns"""
  2748. if self.connection:
  2749. cols = self.mapDBInfo.GetColumns(
  2750. self.mapDBInfo.layers[int(self.currLayer)]["table"]
  2751. )
  2752. else:
  2753. cols = []
  2754. choice = Choice(parent=parent, id=wx.ID_ANY, choices=cols)
  2755. return choice
  2756. def update(self):
  2757. # feature type
  2758. if self.type in ("lines", "points"):
  2759. featureType = None
  2760. if self.checkType1.GetValue():
  2761. featureType = self.checkType1.GetName()
  2762. if self.checkType2.GetValue():
  2763. featureType += " or " + self.checkType2.GetName()
  2764. elif self.checkType2.GetValue():
  2765. featureType = self.checkType2.GetName()
  2766. if featureType:
  2767. self.vPropertiesDict["type"] = featureType
  2768. # is connection
  2769. self.vPropertiesDict["connection"] = self.connection
  2770. if self.connection:
  2771. self.vPropertiesDict["layer"] = self.layerChoice.GetStringSelection()
  2772. if self.radioCats.GetValue() and not self.textCtrlCats.IsEmpty():
  2773. self.vPropertiesDict["cats"] = self.textCtrlCats.GetValue()
  2774. elif self.radioWhere.GetValue() and not self.textCtrlWhere.IsEmpty():
  2775. self.vPropertiesDict["where"] = (
  2776. self.choiceColumns.GetStringSelection()
  2777. + " "
  2778. + self.textCtrlWhere.GetValue()
  2779. )
  2780. # mask
  2781. if self.mask.GetValue():
  2782. self.vPropertiesDict["masked"] = "y"
  2783. else:
  2784. self.vPropertiesDict["masked"] = "n"
  2785. # colors
  2786. if self.type in ("points", "areas"):
  2787. if self.outlineCheck.GetValue():
  2788. self.vPropertiesDict["color"] = convertRGB(self.colorPicker.GetColour())
  2789. self.vPropertiesDict["width"] = self.widthSpin.GetValue()
  2790. else:
  2791. self.vPropertiesDict["color"] = "none"
  2792. if self.fillCheck.GetValue():
  2793. if self.colorPickerRadio.GetValue():
  2794. self.vPropertiesDict["fcolor"] = convertRGB(
  2795. self.fillColorPicker.GetColour()
  2796. )
  2797. self.vPropertiesDict["rgbcolumn"] = None
  2798. if self.colorColRadio.GetValue():
  2799. # this color is taken in case of no record in rgb column
  2800. self.vPropertiesDict["fcolor"] = "none"
  2801. self.vPropertiesDict[
  2802. "rgbcolumn"
  2803. ] = self.colorColChoice.GetStringSelection()
  2804. else:
  2805. self.vPropertiesDict["fcolor"] = "none"
  2806. if self.type == "lines":
  2807. # hcolor only when no rgbcolumn
  2808. # and self.fillCheck.GetValue() and self.colorColRadio.GetValue():
  2809. if self.outlineCheck.GetValue():
  2810. self.vPropertiesDict["hcolor"] = convertRGB(
  2811. self.colorPicker.GetColour()
  2812. )
  2813. self.vPropertiesDict["hwidth"] = self.outWidthSpin.GetValue()
  2814. else:
  2815. self.vPropertiesDict["hcolor"] = "none"
  2816. if self.colorPickerRadio.GetValue():
  2817. self.vPropertiesDict["color"] = convertRGB(
  2818. self.fillColorPicker.GetColour()
  2819. )
  2820. self.vPropertiesDict["rgbcolumn"] = None
  2821. if self.colorColRadio.GetValue():
  2822. # this color is taken in case of no record in rgb column
  2823. self.vPropertiesDict["color"] = "none"
  2824. self.vPropertiesDict[
  2825. "rgbcolumn"
  2826. ] = self.colorColChoice.GetStringSelection()
  2827. #
  2828. # size and style
  2829. #
  2830. if self.type == "points":
  2831. # symbols
  2832. if self.symbolRadio.GetValue():
  2833. self.vPropertiesDict["symbol"] = self.symbolName.GetLabel()
  2834. self.vPropertiesDict["eps"] = None
  2835. else:
  2836. self.vPropertiesDict["eps"] = self.epsFileCtrl.GetValue()
  2837. # size
  2838. if self.sizeRadio.GetValue():
  2839. self.vPropertiesDict["size"] = self.sizeSpin.GetValue()
  2840. self.vPropertiesDict["sizecolumn"] = None
  2841. self.vPropertiesDict["scale"] = None
  2842. else:
  2843. self.vPropertiesDict[
  2844. "sizecolumn"
  2845. ] = self.sizeColChoice.GetStringSelection()
  2846. self.vPropertiesDict["scale"] = self.scaleSpin.GetValue()
  2847. self.vPropertiesDict["size"] = None
  2848. # rotation
  2849. self.vPropertiesDict["rotate"] = None
  2850. self.vPropertiesDict["rotatecolumn"] = None
  2851. self.vPropertiesDict["rotation"] = False
  2852. if self.rotateCheck.GetValue():
  2853. self.vPropertiesDict["rotation"] = True
  2854. if self.rotateRadio.GetValue():
  2855. self.vPropertiesDict["rotate"] = self.rotateSpin.GetValue()
  2856. else:
  2857. self.vPropertiesDict[
  2858. "rotatecolumn"
  2859. ] = self.rotateColChoice.GetStringSelection()
  2860. if self.type == "areas":
  2861. # pattern
  2862. self.vPropertiesDict["pat"] = None
  2863. if self.patternCheck.GetValue() and bool(self.patFileCtrl.GetValue()):
  2864. self.vPropertiesDict["pat"] = self.patFileCtrl.GetValue()
  2865. self.vPropertiesDict["pwidth"] = self.patWidthSpin.GetValue()
  2866. self.vPropertiesDict["scale"] = self.patScaleSpin.GetValue()
  2867. if self.type == "lines":
  2868. # width
  2869. if self.cwidthCheck.GetValue():
  2870. self.vPropertiesDict["cwidth"] = self.widthSpin.GetValue()
  2871. self.vPropertiesDict["width"] = None
  2872. else:
  2873. self.vPropertiesDict["width"] = self.widthSpin.GetValue()
  2874. self.vPropertiesDict["cwidth"] = None
  2875. # line style
  2876. if self.styleCombo.GetValue():
  2877. self.vPropertiesDict["style"] = self.styleCombo.GetValue()
  2878. else:
  2879. self.vPropertiesDict["style"] = "solid"
  2880. self.vPropertiesDict["linecap"] = self.linecapChoice.GetStringSelection()
  2881. def OnOK(self, event):
  2882. self.update()
  2883. event.Skip()
  2884. class LegendDialog(PsmapDialog):
  2885. def __init__(self, parent, id, settings, page, env):
  2886. PsmapDialog.__init__(
  2887. self,
  2888. parent=parent,
  2889. id=id,
  2890. title="Legend settings",
  2891. settings=settings,
  2892. env=env,
  2893. )
  2894. self.objectType = ("rasterLegend", "vectorLegend")
  2895. self.instruction = settings
  2896. map = self.instruction.FindInstructionByType("map")
  2897. if map:
  2898. self.mapId = map.id
  2899. else:
  2900. self.mapId = None
  2901. vector = self.instruction.FindInstructionByType("vector")
  2902. if vector:
  2903. self.vectorId = vector.id
  2904. else:
  2905. self.vectorId = None
  2906. raster = self.instruction.FindInstructionByType("raster")
  2907. if raster:
  2908. self.rasterId = raster.id
  2909. else:
  2910. self.rasterId = None
  2911. self.pageId = self.instruction.FindInstructionByType("page").id
  2912. currPage = self.instruction[self.pageId].GetInstruction()
  2913. # raster legend
  2914. if self.id[0] is not None:
  2915. self.rasterLegend = self.instruction[self.id[0]]
  2916. self.rLegendDict = self.rasterLegend.GetInstruction()
  2917. else:
  2918. self.id[0] = NewId()
  2919. self.rasterLegend = RasterLegend(self.id[0], env=self.env)
  2920. self.rLegendDict = self.rasterLegend.GetInstruction()
  2921. self.rLegendDict["where"] = currPage["Left"], currPage["Top"]
  2922. # vector legend
  2923. if self.id[1] is not None:
  2924. self.vLegendDict = self.instruction[self.id[1]].GetInstruction()
  2925. else:
  2926. self.id[1] = NewId()
  2927. vectorLegend = VectorLegend(self.id[1], env=self.env)
  2928. self.vLegendDict = vectorLegend.GetInstruction()
  2929. self.vLegendDict["where"] = currPage["Left"], currPage["Top"]
  2930. if self.rasterId:
  2931. self.currRaster = self.instruction[self.rasterId]["raster"]
  2932. else:
  2933. self.currRaster = None
  2934. # notebook
  2935. self.notebook = Notebook(parent=self, id=wx.ID_ANY, style=wx.BK_DEFAULT)
  2936. self.panelRaster = self._rasterLegend(self.notebook)
  2937. self.panelVector = self._vectorLegend(self.notebook)
  2938. self.OnRaster(None)
  2939. self.OnRange(None)
  2940. self.OnIsLegend(None)
  2941. self.OnSpan(None)
  2942. self.OnBorder(None)
  2943. self._layout(self.notebook)
  2944. self.notebook.ChangeSelection(page)
  2945. self.notebook.Bind(wx.EVT_NOTEBOOK_PAGE_CHANGING, self.OnPageChanging)
  2946. def OnPageChanging(self, event):
  2947. """Workaround to scroll up to see the checkbox"""
  2948. wx.CallAfter(
  2949. self.FindWindowByName("rasterPanel").ScrollChildIntoView,
  2950. self.FindWindowByName("showRLegend"),
  2951. )
  2952. wx.CallAfter(
  2953. self.FindWindowByName("vectorPanel").ScrollChildIntoView,
  2954. self.FindWindowByName("showVLegend"),
  2955. )
  2956. def _rasterLegend(self, notebook):
  2957. panel = ScrolledPanel(
  2958. parent=notebook, id=wx.ID_ANY, size=(-1, 500), style=wx.TAB_TRAVERSAL
  2959. )
  2960. panel.SetupScrolling(scroll_x=False, scroll_y=True)
  2961. panel.SetName("rasterPanel")
  2962. notebook.AddPage(page=panel, text=_("Raster legend"))
  2963. border = wx.BoxSizer(wx.VERTICAL)
  2964. # is legend
  2965. self.isRLegend = CheckBox(panel, id=wx.ID_ANY, label=_("Show raster legend"))
  2966. self.isRLegend.SetValue(self.rLegendDict["rLegend"])
  2967. self.isRLegend.SetName("showRLegend")
  2968. border.Add(self.isRLegend, proportion=0, flag=wx.ALL | wx.EXPAND, border=5)
  2969. # choose raster
  2970. box = StaticBox(parent=panel, id=wx.ID_ANY, label=" %s " % _("Source raster"))
  2971. sizer = wx.StaticBoxSizer(box, wx.VERTICAL)
  2972. flexSizer = wx.FlexGridSizer(cols=2, hgap=5, vgap=5)
  2973. self.rasterDefault = RadioButton(
  2974. panel, id=wx.ID_ANY, label=_("current raster"), style=wx.RB_GROUP
  2975. )
  2976. self.rasterOther = RadioButton(panel, id=wx.ID_ANY, label=_("select raster"))
  2977. self.rasterDefault.SetValue(self.rLegendDict["rasterDefault"])
  2978. self.rasterOther.SetValue(not self.rLegendDict["rasterDefault"])
  2979. rasterType = getRasterType(map=self.currRaster)
  2980. self.rasterCurrent = StaticText(
  2981. panel,
  2982. id=wx.ID_ANY,
  2983. label=_("%(rast)s: type %(type)s")
  2984. % {"rast": self.currRaster, "type": rasterType},
  2985. )
  2986. self.rasterSelect = Select(
  2987. panel,
  2988. id=wx.ID_ANY,
  2989. size=globalvar.DIALOG_GSELECT_SIZE,
  2990. type="raster",
  2991. multiple=False,
  2992. updateOnPopup=True,
  2993. onPopup=None,
  2994. )
  2995. if not self.rLegendDict["rasterDefault"]:
  2996. self.rasterSelect.SetValue(self.rLegendDict["raster"])
  2997. else:
  2998. self.rasterSelect.SetValue("")
  2999. flexSizer.Add(
  3000. self.rasterDefault, proportion=0, flag=wx.ALIGN_CENTER_VERTICAL, border=0
  3001. )
  3002. flexSizer.Add(
  3003. self.rasterCurrent,
  3004. proportion=0,
  3005. flag=wx.ALIGN_CENTER_VERTICAL | wx.LEFT,
  3006. border=10,
  3007. )
  3008. flexSizer.Add(
  3009. self.rasterOther, proportion=0, flag=wx.ALIGN_CENTER_VERTICAL, border=0
  3010. )
  3011. flexSizer.Add(
  3012. self.rasterSelect,
  3013. proportion=0,
  3014. flag=wx.ALIGN_CENTER_VERTICAL | wx.ALIGN_RIGHT,
  3015. border=0,
  3016. )
  3017. flexSizer.AddGrowableCol(1)
  3018. sizer.Add(flexSizer, proportion=1, flag=wx.ALL | wx.EXPAND, border=1)
  3019. border.Add(sizer, proportion=0, flag=wx.ALL | wx.EXPAND, border=5)
  3020. # type of legend
  3021. box = StaticBox(parent=panel, id=wx.ID_ANY, label=" %s " % _("Type of legend"))
  3022. sizer = wx.StaticBoxSizer(box, wx.VERTICAL)
  3023. vbox = wx.BoxSizer(wx.VERTICAL)
  3024. self.discrete = RadioButton(
  3025. parent=panel,
  3026. id=wx.ID_ANY,
  3027. label=" %s " % _("discrete legend (categorical maps)"),
  3028. style=wx.RB_GROUP,
  3029. )
  3030. self.continuous = RadioButton(
  3031. parent=panel,
  3032. id=wx.ID_ANY,
  3033. label=" %s " % _("continuous color gradient legend (floating point map)"),
  3034. )
  3035. vbox.Add(self.discrete, proportion=1, flag=wx.EXPAND | wx.ALL, border=0)
  3036. vbox.Add(self.continuous, proportion=1, flag=wx.EXPAND | wx.ALL, border=0)
  3037. sizer.Add(vbox, proportion=1, flag=wx.ALL | wx.EXPAND, border=1)
  3038. border.Add(sizer, proportion=0, flag=wx.ALL | wx.EXPAND, border=5)
  3039. # size, position and font
  3040. self.sizePositionFont(legendType="raster", parent=panel, mainSizer=border)
  3041. # advanced settings
  3042. box = StaticBox(
  3043. parent=panel, id=wx.ID_ANY, label=" %s " % _("Advanced legend settings")
  3044. )
  3045. sizer = wx.StaticBoxSizer(box, wx.VERTICAL)
  3046. gridBagSizer = wx.GridBagSizer(hgap=5, vgap=5)
  3047. # no data
  3048. self.nodata = CheckBox(panel, id=wx.ID_ANY, label=_('draw "no data" box'))
  3049. if self.rLegendDict["nodata"] == "y":
  3050. self.nodata.SetValue(True)
  3051. else:
  3052. self.nodata.SetValue(False)
  3053. # tickbar
  3054. self.ticks = CheckBox(
  3055. panel, id=wx.ID_ANY, label=_("draw ticks across color table")
  3056. )
  3057. if self.rLegendDict["tickbar"] == "y":
  3058. self.ticks.SetValue(True)
  3059. else:
  3060. self.ticks.SetValue(False)
  3061. # range
  3062. if self.rasterId and self.instruction[self.rasterId]["raster"]:
  3063. rinfo = grass.raster_info(self.instruction[self.rasterId]["raster"])
  3064. self.minim, self.maxim = rinfo["min"], rinfo["max"]
  3065. else:
  3066. self.minim, self.maxim = 0, 0
  3067. self.range = CheckBox(panel, id=wx.ID_ANY, label=_("range"))
  3068. self.range.SetValue(self.rLegendDict["range"])
  3069. self.minText = StaticText(panel, id=wx.ID_ANY, label="min (%s)" % self.minim)
  3070. self.maxText = StaticText(panel, id=wx.ID_ANY, label="max (%s)" % self.maxim)
  3071. self.min = TextCtrl(panel, id=wx.ID_ANY, value=str(self.rLegendDict["min"]))
  3072. self.max = TextCtrl(panel, id=wx.ID_ANY, value=str(self.rLegendDict["max"]))
  3073. gridBagSizer.Add(
  3074. self.nodata,
  3075. pos=(0, 0),
  3076. span=(1, 5),
  3077. flag=wx.ALIGN_CENTER_VERTICAL,
  3078. border=0,
  3079. )
  3080. gridBagSizer.Add(
  3081. self.ticks, pos=(1, 0), span=(1, 5), flag=wx.ALIGN_CENTER_VERTICAL, border=0
  3082. )
  3083. gridBagSizer.Add(
  3084. self.range, pos=(2, 0), flag=wx.ALIGN_CENTER_VERTICAL, border=0
  3085. )
  3086. gridBagSizer.Add(
  3087. self.minText,
  3088. pos=(2, 1),
  3089. flag=wx.ALIGN_CENTER_VERTICAL | wx.ALIGN_RIGHT,
  3090. border=0,
  3091. )
  3092. gridBagSizer.Add(self.min, pos=(2, 2), flag=wx.ALIGN_CENTER_VERTICAL, border=0)
  3093. gridBagSizer.Add(
  3094. self.maxText,
  3095. pos=(2, 3),
  3096. flag=wx.ALIGN_CENTER_VERTICAL | wx.ALIGN_RIGHT,
  3097. border=0,
  3098. )
  3099. gridBagSizer.Add(self.max, pos=(2, 4), flag=wx.ALIGN_CENTER_VERTICAL, border=0)
  3100. sizer.Add(gridBagSizer, proportion=0, border=0)
  3101. border.Add(sizer, proportion=0, flag=wx.ALL | wx.EXPAND, border=5)
  3102. panel.SetSizer(border)
  3103. panel.Fit()
  3104. # bindings
  3105. self.Bind(wx.EVT_RADIOBUTTON, self.OnRaster, self.rasterDefault)
  3106. self.Bind(wx.EVT_RADIOBUTTON, self.OnRaster, self.rasterOther)
  3107. self.Bind(wx.EVT_CHECKBOX, self.OnIsLegend, self.isRLegend)
  3108. self.Bind(wx.EVT_RADIOBUTTON, self.OnDiscrete, self.discrete)
  3109. self.Bind(wx.EVT_RADIOBUTTON, self.OnDiscrete, self.continuous)
  3110. ## self.Bind(wx.EVT_CHECKBOX, self.OnDefaultSize, panel.defaultSize)
  3111. self.Bind(wx.EVT_CHECKBOX, self.OnRange, self.range)
  3112. self.rasterSelect.GetTextCtrl().Bind(wx.EVT_TEXT, self.OnRaster)
  3113. return panel
  3114. def _vectorLegend(self, notebook):
  3115. panel = ScrolledPanel(
  3116. parent=notebook, id=wx.ID_ANY, size=(-1, 500), style=wx.TAB_TRAVERSAL
  3117. )
  3118. panel.SetupScrolling(scroll_x=False, scroll_y=True)
  3119. panel.SetName("vectorPanel")
  3120. notebook.AddPage(page=panel, text=_("Vector legend"))
  3121. border = wx.BoxSizer(wx.VERTICAL)
  3122. # is legend
  3123. self.isVLegend = CheckBox(panel, id=wx.ID_ANY, label=_("Show vector legend"))
  3124. self.isVLegend.SetValue(self.vLegendDict["vLegend"])
  3125. self.isVLegend.SetName("showVLegend")
  3126. border.Add(self.isVLegend, proportion=0, flag=wx.ALL | wx.EXPAND, border=5)
  3127. # vector maps, their order, labels
  3128. box = StaticBox(
  3129. parent=panel, id=wx.ID_ANY, label=" %s " % _("Source vector maps")
  3130. )
  3131. sizer = wx.StaticBoxSizer(box, wx.VERTICAL)
  3132. gridBagSizer = wx.GridBagSizer(hgap=5, vgap=5)
  3133. vectorText = StaticText(
  3134. panel, id=wx.ID_ANY, label=_("Choose vector maps and their order in legend")
  3135. )
  3136. self.vectorListCtrl = CheckListCtrl(panel)
  3137. self.vectorListCtrl.InsertColumn(0, _("Vector map"))
  3138. self.vectorListCtrl.InsertColumn(1, _("Label"))
  3139. if self.vectorId:
  3140. vectors = sorted(
  3141. self.instruction[self.vectorId]["list"], key=lambda x: x[3]
  3142. )
  3143. for vector in vectors:
  3144. index = self.vectorListCtrl.InsertItem(
  3145. self.vectorListCtrl.GetItemCount(), vector[0].split("@")[0]
  3146. )
  3147. self.vectorListCtrl.SetItem(index, 1, vector[4])
  3148. self.vectorListCtrl.SetItemData(index, index)
  3149. self.vectorListCtrl.CheckItem(index, True)
  3150. if vector[3] == 0:
  3151. self.vectorListCtrl.CheckItem(index, False)
  3152. if not self.vectorId:
  3153. self.vectorListCtrl.SetColumnWidth(0, 100)
  3154. else:
  3155. self.vectorListCtrl.SetColumnWidth(0, wx.LIST_AUTOSIZE)
  3156. self.vectorListCtrl.SetColumnWidth(1, wx.LIST_AUTOSIZE)
  3157. self.btnUp = Button(panel, id=wx.ID_ANY, label=_("Up"))
  3158. self.btnDown = Button(panel, id=wx.ID_ANY, label=_("Down"))
  3159. self.btnLabel = Button(panel, id=wx.ID_ANY, label=_("Edit label"))
  3160. gridBagSizer.Add(
  3161. vectorText, pos=(0, 0), span=(1, 2), flag=wx.ALIGN_CENTER_VERTICAL, border=0
  3162. )
  3163. gridBagSizer.Add(
  3164. self.vectorListCtrl,
  3165. pos=(1, 0),
  3166. span=(3, 1),
  3167. flag=wx.ALIGN_CENTER_VERTICAL | wx.EXPAND,
  3168. border=0,
  3169. )
  3170. gridBagSizer.Add(
  3171. self.btnUp, pos=(1, 1), flag=wx.ALIGN_CENTER_VERTICAL, border=0
  3172. )
  3173. gridBagSizer.Add(
  3174. self.btnDown, pos=(2, 1), flag=wx.ALIGN_CENTER_VERTICAL, border=0
  3175. )
  3176. gridBagSizer.Add(
  3177. self.btnLabel, pos=(3, 1), flag=wx.ALIGN_CENTER_VERTICAL, border=0
  3178. )
  3179. gridBagSizer.AddGrowableCol(0, 3)
  3180. gridBagSizer.AddGrowableCol(1, 1)
  3181. sizer.Add(gridBagSizer, proportion=0, flag=wx.EXPAND, border=0)
  3182. border.Add(sizer, proportion=0, flag=wx.ALL | wx.EXPAND, border=5)
  3183. # size, position and font
  3184. self.sizePositionFont(legendType="vector", parent=panel, mainSizer=border)
  3185. # border
  3186. # GTC Line around legend or map frame
  3187. box = StaticBox(parent=panel, id=wx.ID_ANY, label=" %s " % _("Border"))
  3188. sizer = wx.StaticBoxSizer(box, wx.VERTICAL)
  3189. flexGridSizer = wx.FlexGridSizer(cols=2, hgap=5, vgap=5)
  3190. self.borderCheck = CheckBox(
  3191. panel, id=wx.ID_ANY, label=_("draw border around legend")
  3192. )
  3193. self.borderColorCtrl = ColourPickerCtrl(
  3194. panel, id=wx.ID_ANY, style=wx.FNTP_FONTDESC_AS_LABEL
  3195. )
  3196. if self.vLegendDict["border"] == "none":
  3197. self.borderColorCtrl.SetColour(wx.BLACK)
  3198. self.borderCheck.SetValue(False)
  3199. else:
  3200. self.borderColorCtrl.SetColour(convertRGB(self.vLegendDict["border"]))
  3201. self.borderCheck.SetValue(True)
  3202. flexGridSizer.Add(
  3203. self.borderCheck, proportion=0, flag=wx.ALIGN_CENTER_VERTICAL, border=0
  3204. )
  3205. flexGridSizer.Add(
  3206. self.borderColorCtrl, proportion=0, flag=wx.ALIGN_CENTER_VERTICAL, border=0
  3207. )
  3208. sizer.Add(flexGridSizer, proportion=1, flag=wx.ALL | wx.EXPAND, border=1)
  3209. border.Add(sizer, proportion=0, flag=wx.ALL | wx.EXPAND, border=5)
  3210. self.Bind(wx.EVT_BUTTON, self.OnUp, self.btnUp)
  3211. self.Bind(wx.EVT_BUTTON, self.OnDown, self.btnDown)
  3212. self.Bind(wx.EVT_BUTTON, self.OnEditLabel, self.btnLabel)
  3213. self.Bind(wx.EVT_CHECKBOX, self.OnIsLegend, self.isVLegend)
  3214. self.Bind(wx.EVT_CHECKBOX, self.OnSpan, panel.spanRadio)
  3215. self.Bind(wx.EVT_CHECKBOX, self.OnBorder, self.borderCheck)
  3216. self.Bind(wx.EVT_FONTPICKER_CHANGED, self.OnFont, panel.font["fontCtrl"])
  3217. panel.SetSizer(border)
  3218. panel.Fit()
  3219. return panel
  3220. def sizePositionFont(self, legendType, parent, mainSizer):
  3221. """Insert widgets for size, position and font control"""
  3222. if legendType == "raster":
  3223. legendDict = self.rLegendDict
  3224. else:
  3225. legendDict = self.vLegendDict
  3226. panel = parent
  3227. border = mainSizer
  3228. # size and position
  3229. box = StaticBox(
  3230. parent=panel, id=wx.ID_ANY, label=" %s " % _("Size and position")
  3231. )
  3232. sizer = wx.StaticBoxSizer(box, wx.VERTICAL)
  3233. # unit
  3234. self.AddUnits(parent=panel, dialogDict=legendDict)
  3235. unitBox = wx.BoxSizer(wx.HORIZONTAL)
  3236. unitBox.Add(
  3237. panel.units["unitsLabel"],
  3238. proportion=0,
  3239. flag=wx.ALIGN_CENTER_VERTICAL | wx.LEFT,
  3240. border=10,
  3241. )
  3242. unitBox.Add(panel.units["unitsCtrl"], proportion=1, flag=wx.ALL, border=5)
  3243. sizer.Add(unitBox, proportion=0, border=0)
  3244. hBox = wx.BoxSizer(wx.HORIZONTAL)
  3245. posBox = StaticBox(parent=panel, id=wx.ID_ANY, label=" %s " % _("Position"))
  3246. posSizer = wx.StaticBoxSizer(posBox, wx.VERTICAL)
  3247. sizeBox = StaticBox(parent=panel, id=wx.ID_ANY, label=" %s " % _("Size"))
  3248. sizeSizer = wx.StaticBoxSizer(sizeBox, wx.VERTICAL)
  3249. posGridBagSizer = wx.GridBagSizer(hgap=10, vgap=5)
  3250. # position
  3251. self.AddPosition(parent=panel, dialogDict=legendDict)
  3252. posGridBagSizer.Add(
  3253. panel.position["xLabel"],
  3254. pos=(0, 0),
  3255. flag=wx.ALIGN_CENTER_VERTICAL,
  3256. border=0,
  3257. )
  3258. posGridBagSizer.Add(
  3259. panel.position["xCtrl"], pos=(0, 1), flag=wx.ALIGN_CENTER_VERTICAL, border=0
  3260. )
  3261. posGridBagSizer.Add(
  3262. panel.position["yLabel"],
  3263. pos=(1, 0),
  3264. flag=wx.ALIGN_CENTER_VERTICAL,
  3265. border=0,
  3266. )
  3267. posGridBagSizer.Add(
  3268. panel.position["yCtrl"], pos=(1, 1), flag=wx.ALIGN_CENTER_VERTICAL, border=0
  3269. )
  3270. posGridBagSizer.Add(
  3271. panel.position["comment"],
  3272. pos=(2, 0),
  3273. span=(1, 2),
  3274. flag=wx.ALIGN_BOTTOM,
  3275. border=0,
  3276. )
  3277. posGridBagSizer.AddGrowableRow(2)
  3278. posSizer.Add(posGridBagSizer, proportion=1, flag=wx.EXPAND | wx.ALL, border=5)
  3279. # size
  3280. width = StaticText(panel, id=wx.ID_ANY, label=_("Width:"))
  3281. if legendDict["width"]:
  3282. w = self.unitConv.convert(
  3283. value=float(legendDict["width"]),
  3284. fromUnit="inch",
  3285. toUnit=legendDict["unit"],
  3286. )
  3287. else:
  3288. w = ""
  3289. panel.widthCtrl = TextCtrl(
  3290. panel, id=wx.ID_ANY, value=str(w), validator=TCValidator("DIGIT_ONLY")
  3291. )
  3292. panel.widthCtrl.SetToolTip(
  3293. _("Leave the edit field empty, to use default values.")
  3294. )
  3295. if legendType == "raster":
  3296. ## panel.defaultSize = wx.CheckBox(panel, id = wx.ID_ANY, label = _("Use default size"))
  3297. # panel.defaultSize.SetValue(legendDict['defaultSize'])
  3298. panel.heightOrColumnsLabel = StaticText(
  3299. panel, id=wx.ID_ANY, label=_("Height:")
  3300. )
  3301. if legendDict["height"]:
  3302. h = self.unitConv.convert(
  3303. value=float(legendDict["height"]),
  3304. fromUnit="inch",
  3305. toUnit=legendDict["unit"],
  3306. )
  3307. else:
  3308. h = ""
  3309. panel.heightOrColumnsCtrl = TextCtrl(
  3310. panel, id=wx.ID_ANY, value=str(h), validator=TCValidator("DIGIT_ONLY")
  3311. )
  3312. self.rSizeGBSizer = wx.GridBagSizer(hgap=5, vgap=5)
  3313. ## self.rSizeGBSizer.Add(panel.defaultSize, pos = (0,0), span = (1,2), flag = wx.ALIGN_CENTER_VERTICAL, border = 0)
  3314. self.rSizeGBSizer.Add(
  3315. width, pos=(0, 0), flag=wx.ALIGN_CENTER_VERTICAL, border=0
  3316. )
  3317. self.rSizeGBSizer.Add(
  3318. panel.widthCtrl, pos=(0, 1), flag=wx.ALIGN_CENTER_VERTICAL, border=0
  3319. )
  3320. self.rSizeGBSizer.Add(
  3321. panel.heightOrColumnsLabel,
  3322. pos=(1, 0),
  3323. flag=wx.ALIGN_CENTER_VERTICAL,
  3324. border=0,
  3325. )
  3326. self.rSizeGBSizer.Add(
  3327. panel.heightOrColumnsCtrl,
  3328. pos=(1, 1),
  3329. flag=wx.ALIGN_CENTER_VERTICAL,
  3330. border=0,
  3331. )
  3332. sizeSizer.Add(
  3333. self.rSizeGBSizer, proportion=1, flag=wx.EXPAND | wx.ALL, border=5
  3334. )
  3335. if legendType == "vector":
  3336. panel.widthCtrl.SetToolTip(
  3337. _("Width of the color symbol (for lines)\nin front of the legend text")
  3338. )
  3339. # columns
  3340. minVect, maxVect = 0, 0
  3341. if self.vectorId:
  3342. minVect = 1
  3343. maxVect = min(10, len(self.instruction[self.vectorId]["list"]))
  3344. cols = StaticText(panel, id=wx.ID_ANY, label=_("Columns:"))
  3345. panel.colsCtrl = SpinCtrl(
  3346. panel,
  3347. id=wx.ID_ANY,
  3348. value="",
  3349. min=minVect,
  3350. max=maxVect,
  3351. initial=legendDict["cols"],
  3352. )
  3353. # span
  3354. panel.spanRadio = CheckBox(panel, id=wx.ID_ANY, label=_("column span:"))
  3355. panel.spanTextCtrl = TextCtrl(panel, id=wx.ID_ANY, value="")
  3356. panel.spanTextCtrl.SetToolTip(
  3357. _(
  3358. "Column separation distance between the left edges\n"
  3359. "of two columns in a multicolumn legend"
  3360. )
  3361. )
  3362. if legendDict["span"]:
  3363. panel.spanRadio.SetValue(True)
  3364. s = self.unitConv.convert(
  3365. value=float(legendDict["span"]),
  3366. fromUnit="inch",
  3367. toUnit=legendDict["unit"],
  3368. )
  3369. panel.spanTextCtrl.SetValue(str(s))
  3370. else:
  3371. panel.spanRadio.SetValue(False)
  3372. self.vSizeGBSizer = wx.GridBagSizer(hgap=5, vgap=5)
  3373. self.vSizeGBSizer.Add(
  3374. width, pos=(0, 0), flag=wx.ALIGN_CENTER_VERTICAL, border=0
  3375. )
  3376. self.vSizeGBSizer.Add(
  3377. panel.widthCtrl, pos=(0, 1), flag=wx.ALIGN_CENTER_VERTICAL, border=0
  3378. )
  3379. self.vSizeGBSizer.Add(
  3380. cols, pos=(1, 0), flag=wx.ALIGN_CENTER_VERTICAL, border=0
  3381. )
  3382. self.vSizeGBSizer.Add(
  3383. panel.colsCtrl, pos=(1, 1), flag=wx.ALIGN_CENTER_VERTICAL, border=0
  3384. )
  3385. self.vSizeGBSizer.Add(
  3386. panel.spanRadio, pos=(2, 0), flag=wx.ALIGN_CENTER_VERTICAL, border=0
  3387. )
  3388. self.vSizeGBSizer.Add(
  3389. panel.spanTextCtrl, pos=(2, 1), flag=wx.ALIGN_CENTER_VERTICAL, border=0
  3390. )
  3391. self.vSizeGBSizer.AddGrowableCol(1)
  3392. sizeSizer.Add(
  3393. self.vSizeGBSizer, proportion=1, flag=wx.EXPAND | wx.ALL, border=5
  3394. )
  3395. hBox.Add(posSizer, proportion=1, flag=wx.EXPAND | wx.ALL, border=3)
  3396. hBox.Add(sizeSizer, proportion=1, flag=wx.EXPAND | wx.ALL, border=3)
  3397. sizer.Add(hBox, proportion=0, flag=wx.EXPAND, border=0)
  3398. border.Add(sizer, proportion=0, flag=wx.ALL | wx.EXPAND, border=5)
  3399. # font
  3400. box = StaticBox(parent=panel, id=wx.ID_ANY, label=" %s " % _("Font settings"))
  3401. fontSizer = wx.StaticBoxSizer(box, wx.VERTICAL)
  3402. flexSizer = wx.FlexGridSizer(cols=2, hgap=5, vgap=5)
  3403. if legendType == "raster":
  3404. self.AddFont(parent=panel, dialogDict=legendDict, color=True)
  3405. else:
  3406. self.AddFont(parent=panel, dialogDict=legendDict, color=False)
  3407. flexSizer.Add(
  3408. panel.font["fontLabel"],
  3409. proportion=0,
  3410. flag=wx.ALIGN_CENTER_VERTICAL,
  3411. border=0,
  3412. )
  3413. flexSizer.Add(
  3414. panel.font["fontCtrl"],
  3415. proportion=0,
  3416. flag=wx.ALIGN_CENTER_VERTICAL,
  3417. border=0,
  3418. )
  3419. flexSizer.Add(
  3420. panel.font["fontSizeLabel"],
  3421. proportion=0,
  3422. flag=wx.ALIGN_CENTER_VERTICAL,
  3423. border=0,
  3424. )
  3425. flexSizer.Add(
  3426. panel.font["fontSizeCtrl"],
  3427. proportion=0,
  3428. flag=wx.ALIGN_CENTER_VERTICAL,
  3429. border=0,
  3430. )
  3431. if legendType == "raster":
  3432. flexSizer.Add(
  3433. panel.font["colorLabel"],
  3434. proportion=0,
  3435. flag=wx.ALIGN_CENTER_VERTICAL,
  3436. border=0,
  3437. )
  3438. flexSizer.Add(
  3439. panel.font["colorCtrl"],
  3440. proportion=0,
  3441. flag=wx.ALIGN_CENTER_VERTICAL,
  3442. border=0,
  3443. )
  3444. flexSizer.AddGrowableCol(1)
  3445. fontSizer.Add(flexSizer, proportion=1, flag=wx.ALL | wx.EXPAND, border=1)
  3446. border.Add(fontSizer, proportion=0, flag=wx.ALL | wx.EXPAND, border=5)
  3447. # some enable/disable methods
  3448. def OnIsLegend(self, event):
  3449. """Enables and disables controls, it depends if raster or vector legend is checked"""
  3450. page = self.notebook.GetSelection()
  3451. if page == 0 or event is None:
  3452. children = self.panelRaster.GetChildren()
  3453. if self.isRLegend.GetValue():
  3454. for i, widget in enumerate(children):
  3455. widget.Enable()
  3456. self.OnRaster(None)
  3457. self.OnRange(None)
  3458. self.OnDiscrete(None)
  3459. else:
  3460. for widget in children:
  3461. if widget.GetName() != "showRLegend":
  3462. widget.Disable()
  3463. if page == 1 or event is None:
  3464. children = self.panelVector.GetChildren()
  3465. if self.isVLegend.GetValue():
  3466. for i, widget in enumerate(children):
  3467. widget.Enable()
  3468. self.OnSpan(None)
  3469. self.OnBorder(None)
  3470. else:
  3471. for widget in children:
  3472. if widget.GetName() != "showVLegend":
  3473. widget.Disable()
  3474. def OnRaster(self, event):
  3475. if self.rasterDefault.GetValue(): # default
  3476. self.rasterSelect.Disable()
  3477. type = getRasterType(self.currRaster)
  3478. else: # select raster
  3479. self.rasterSelect.Enable()
  3480. map = self.rasterSelect.GetValue()
  3481. type = getRasterType(map)
  3482. if type == "CELL":
  3483. self.discrete.SetValue(True)
  3484. elif type in ("FCELL", "DCELL"):
  3485. self.continuous.SetValue(True)
  3486. if event is None:
  3487. if self.rLegendDict["discrete"] == "y":
  3488. self.discrete.SetValue(True)
  3489. elif self.rLegendDict["discrete"] == "n":
  3490. self.continuous.SetValue(True)
  3491. self.OnDiscrete(None)
  3492. def OnDiscrete(self, event):
  3493. """Change control according to the type of legend"""
  3494. enabledSize = self.panelRaster.heightOrColumnsCtrl.IsEnabled()
  3495. self.panelRaster.heightOrColumnsCtrl.Destroy()
  3496. if self.discrete.GetValue():
  3497. self.panelRaster.heightOrColumnsLabel.SetLabel(_("Columns:"))
  3498. self.panelRaster.heightOrColumnsCtrl = SpinCtrl(
  3499. self.panelRaster,
  3500. id=wx.ID_ANY,
  3501. value="",
  3502. min=1,
  3503. max=10,
  3504. initial=self.rLegendDict["cols"],
  3505. )
  3506. self.panelRaster.heightOrColumnsCtrl.Enable(enabledSize)
  3507. self.nodata.Enable()
  3508. self.range.Disable()
  3509. self.min.Disable()
  3510. self.max.Disable()
  3511. self.minText.Disable()
  3512. self.maxText.Disable()
  3513. self.ticks.Disable()
  3514. else:
  3515. self.panelRaster.heightOrColumnsLabel.SetLabel(_("Height:"))
  3516. if self.rLegendDict["height"]:
  3517. h = self.unitConv.convert(
  3518. value=float(self.rLegendDict["height"]),
  3519. fromUnit="inch",
  3520. toUnit=self.rLegendDict["unit"],
  3521. )
  3522. else:
  3523. h = ""
  3524. self.panelRaster.heightOrColumnsCtrl = TextCtrl(
  3525. self.panelRaster,
  3526. id=wx.ID_ANY,
  3527. value=str(h),
  3528. validator=TCValidator("DIGIT_ONLY"),
  3529. )
  3530. self.panelRaster.heightOrColumnsCtrl.Enable(enabledSize)
  3531. self.nodata.Disable()
  3532. self.range.Enable()
  3533. if self.range.GetValue():
  3534. self.minText.Enable()
  3535. self.maxText.Enable()
  3536. self.min.Enable()
  3537. self.max.Enable()
  3538. self.ticks.Enable()
  3539. self.rSizeGBSizer.Add(
  3540. self.panelRaster.heightOrColumnsCtrl,
  3541. pos=(1, 1),
  3542. flag=wx.ALIGN_CENTER_VERTICAL,
  3543. border=0,
  3544. )
  3545. self.panelRaster.Layout()
  3546. self.panelRaster.Fit()
  3547. def OnRange(self, event):
  3548. if not self.range.GetValue():
  3549. self.min.Disable()
  3550. self.max.Disable()
  3551. self.minText.Disable()
  3552. self.maxText.Disable()
  3553. else:
  3554. self.min.Enable()
  3555. self.max.Enable()
  3556. self.minText.Enable()
  3557. self.maxText.Enable()
  3558. def OnUp(self, event):
  3559. """Moves selected map up, changes order in vector legend"""
  3560. if self.vectorListCtrl.GetFirstSelected() != -1:
  3561. pos = self.vectorListCtrl.GetFirstSelected()
  3562. if pos:
  3563. idx1 = self.vectorListCtrl.GetItemData(pos) - 1
  3564. idx2 = self.vectorListCtrl.GetItemData(pos - 1) + 1
  3565. self.vectorListCtrl.SetItemData(pos, idx1)
  3566. self.vectorListCtrl.SetItemData(pos - 1, idx2)
  3567. self.vectorListCtrl.SortItems(cmp)
  3568. if pos > 0:
  3569. selected = pos - 1
  3570. else:
  3571. selected = 0
  3572. self.vectorListCtrl.Select(selected)
  3573. def OnDown(self, event):
  3574. """Moves selected map down, changes order in vector legend"""
  3575. if self.vectorListCtrl.GetFirstSelected() != -1:
  3576. pos = self.vectorListCtrl.GetFirstSelected()
  3577. if pos != self.vectorListCtrl.GetItemCount() - 1:
  3578. idx1 = self.vectorListCtrl.GetItemData(pos) + 1
  3579. idx2 = self.vectorListCtrl.GetItemData(pos + 1) - 1
  3580. self.vectorListCtrl.SetItemData(pos, idx1)
  3581. self.vectorListCtrl.SetItemData(pos + 1, idx2)
  3582. self.vectorListCtrl.SortItems(cmp)
  3583. if pos < self.vectorListCtrl.GetItemCount() - 1:
  3584. selected = pos + 1
  3585. else:
  3586. selected = self.vectorListCtrl.GetItemCount() - 1
  3587. self.vectorListCtrl.Select(selected)
  3588. def OnEditLabel(self, event):
  3589. """Change legend label of vector map"""
  3590. if self.vectorListCtrl.GetFirstSelected() != -1:
  3591. idx = self.vectorListCtrl.GetFirstSelected()
  3592. default = self.vectorListCtrl.GetItem(idx, 1).GetText()
  3593. dlg = TextEntryDialog(
  3594. self,
  3595. message=_("Edit legend label:"),
  3596. caption=_("Edit label"),
  3597. value=default,
  3598. style=wx.OK | wx.CANCEL | wx.CENTRE,
  3599. )
  3600. if dlg.ShowModal() == wx.ID_OK:
  3601. new = dlg.GetValue()
  3602. self.vectorListCtrl.SetItem(idx, 1, new)
  3603. dlg.Destroy()
  3604. def OnSpan(self, event):
  3605. self.panelVector.spanTextCtrl.Enable(self.panelVector.spanRadio.GetValue())
  3606. def OnFont(self, event):
  3607. """Changes default width according to fontsize, width [inch] = fontsize[pt]/24"""
  3608. ## fontsize = self.panelVector.font['fontCtrl'].GetSelectedFont().GetPointSize()
  3609. fontsize = self.panelVector.font["fontSizeCtrl"].GetValue()
  3610. unit = self.unitConv.findUnit(
  3611. self.panelVector.units["unitsCtrl"].GetStringSelection()
  3612. )
  3613. w = fontsize / 24.0
  3614. width = self.unitConv.convert(value=w, fromUnit="inch", toUnit=unit)
  3615. self.panelVector.widthCtrl.SetValue("%3.2f" % width)
  3616. def OnBorder(self, event):
  3617. """Enables/disables colorPickerCtrl for border"""
  3618. self.borderColorCtrl.Enable(self.borderCheck.GetValue())
  3619. def updateRasterLegend(self):
  3620. """Save information from raster legend dialog to dictionary"""
  3621. # is raster legend
  3622. if not self.isRLegend.GetValue():
  3623. self.rLegendDict["rLegend"] = False
  3624. else:
  3625. self.rLegendDict["rLegend"] = True
  3626. # units
  3627. currUnit = self.unitConv.findUnit(
  3628. self.panelRaster.units["unitsCtrl"].GetStringSelection()
  3629. )
  3630. self.rLegendDict["unit"] = currUnit
  3631. # raster
  3632. if self.rasterDefault.GetValue():
  3633. self.rLegendDict["rasterDefault"] = True
  3634. self.rLegendDict["raster"] = self.currRaster
  3635. else:
  3636. self.rLegendDict["rasterDefault"] = False
  3637. self.rLegendDict["raster"] = self.rasterSelect.GetValue()
  3638. if self.rLegendDict["rLegend"] and not self.rLegendDict["raster"]:
  3639. wx.MessageBox(
  3640. message=_("No raster map selected!"),
  3641. caption=_("No raster"),
  3642. style=wx.OK | wx.ICON_ERROR,
  3643. )
  3644. return False
  3645. if self.rLegendDict["raster"]:
  3646. # type and range of map
  3647. rasterType = getRasterType(self.rLegendDict["raster"])
  3648. if rasterType is None:
  3649. return False
  3650. self.rLegendDict["type"] = rasterType
  3651. # discrete
  3652. if self.discrete.GetValue():
  3653. self.rLegendDict["discrete"] = "y"
  3654. else:
  3655. self.rLegendDict["discrete"] = "n"
  3656. # font
  3657. self.rLegendDict["font"] = self.panelRaster.font[
  3658. "fontCtrl"
  3659. ].GetStringSelection()
  3660. self.rLegendDict["fontsize"] = self.panelRaster.font[
  3661. "fontSizeCtrl"
  3662. ].GetValue()
  3663. color = self.panelRaster.font["colorCtrl"].GetColour()
  3664. self.rLegendDict["color"] = convertRGB(color)
  3665. # position
  3666. x = self.unitConv.convert(
  3667. value=float(self.panelRaster.position["xCtrl"].GetValue()),
  3668. fromUnit=currUnit,
  3669. toUnit="inch",
  3670. )
  3671. y = self.unitConv.convert(
  3672. value=float(self.panelRaster.position["yCtrl"].GetValue()),
  3673. fromUnit=currUnit,
  3674. toUnit="inch",
  3675. )
  3676. self.rLegendDict["where"] = (x, y)
  3677. # estimated size
  3678. width = self.panelRaster.widthCtrl.GetValue()
  3679. try:
  3680. width = float(width)
  3681. width = self.unitConv.convert(
  3682. value=width, fromUnit=currUnit, toUnit="inch"
  3683. )
  3684. except ValueError:
  3685. width = None
  3686. self.rLegendDict["width"] = width
  3687. if self.rLegendDict["discrete"] == "n":
  3688. height = self.panelRaster.heightOrColumnsCtrl.GetValue()
  3689. try:
  3690. height = float(height)
  3691. height = self.unitConv.convert(
  3692. value=height, fromUnit=currUnit, toUnit="inch"
  3693. )
  3694. except ValueError:
  3695. height = None
  3696. self.rLegendDict["height"] = height
  3697. else:
  3698. cols = self.panelRaster.heightOrColumnsCtrl.GetValue()
  3699. self.rLegendDict["cols"] = cols
  3700. drawHeight = self.rasterLegend.EstimateHeight(
  3701. raster=self.rLegendDict["raster"],
  3702. discrete=self.rLegendDict["discrete"],
  3703. fontsize=self.rLegendDict["fontsize"],
  3704. cols=self.rLegendDict["cols"],
  3705. height=self.rLegendDict["height"],
  3706. )
  3707. drawWidth = self.rasterLegend.EstimateWidth(
  3708. raster=self.rLegendDict["raster"],
  3709. discrete=self.rLegendDict["discrete"],
  3710. fontsize=self.rLegendDict["fontsize"],
  3711. cols=self.rLegendDict["cols"],
  3712. width=self.rLegendDict["width"],
  3713. paperInstr=self.instruction[self.pageId],
  3714. )
  3715. self.rLegendDict["rect"] = Rect2D(
  3716. x=x, y=y, width=drawWidth, height=drawHeight
  3717. )
  3718. # no data
  3719. if self.rLegendDict["discrete"] == "y":
  3720. if self.nodata.GetValue():
  3721. self.rLegendDict["nodata"] = "y"
  3722. else:
  3723. self.rLegendDict["nodata"] = "n"
  3724. # tickbar
  3725. elif self.rLegendDict["discrete"] == "n":
  3726. if self.ticks.GetValue():
  3727. self.rLegendDict["tickbar"] = "y"
  3728. else:
  3729. self.rLegendDict["tickbar"] = "n"
  3730. # range
  3731. if self.range.GetValue():
  3732. self.rLegendDict["range"] = True
  3733. self.rLegendDict["min"] = self.min.GetValue()
  3734. self.rLegendDict["max"] = self.max.GetValue()
  3735. else:
  3736. self.rLegendDict["range"] = False
  3737. if not self.id[0] in self.instruction:
  3738. rasterLegend = RasterLegend(self.id[0], env=self.env)
  3739. self.instruction.AddInstruction(rasterLegend)
  3740. self.instruction[self.id[0]].SetInstruction(self.rLegendDict)
  3741. if self.id[0] not in self.parent.objectId:
  3742. self.parent.objectId.append(self.id[0])
  3743. return True
  3744. def updateVectorLegend(self):
  3745. """Save information from vector legend dialog to dictionary"""
  3746. vector = self.instruction.FindInstructionByType("vector")
  3747. if vector:
  3748. self.vectorId = vector.id
  3749. else:
  3750. self.vectorId = None
  3751. # is vector legend
  3752. if not self.isVLegend.GetValue():
  3753. self.vLegendDict["vLegend"] = False
  3754. else:
  3755. self.vLegendDict["vLegend"] = True
  3756. if self.vLegendDict["vLegend"] and self.vectorId is not None:
  3757. # labels
  3758. # reindex order
  3759. idx = 1
  3760. for item in range(self.vectorListCtrl.GetItemCount()):
  3761. if self.vectorListCtrl.IsItemChecked(item):
  3762. self.vectorListCtrl.SetItemData(item, idx)
  3763. idx += 1
  3764. else:
  3765. self.vectorListCtrl.SetItemData(item, 0)
  3766. if idx == 1:
  3767. self.vLegendDict["vLegend"] = False
  3768. else:
  3769. vList = self.instruction[self.vectorId]["list"]
  3770. for i, vector in enumerate(vList):
  3771. item = self.vectorListCtrl.FindItem(
  3772. start=-1, str=vector[0].split("@")[0]
  3773. )
  3774. vList[i][3] = self.vectorListCtrl.GetItemData(item)
  3775. vList[i][4] = self.vectorListCtrl.GetItem(item, 1).GetText()
  3776. vmaps = self.instruction.FindInstructionByType("vProperties", list=True)
  3777. for vmap, vector in zip(vmaps, vList):
  3778. self.instruction[vmap.id]["lpos"] = vector[3]
  3779. self.instruction[vmap.id]["label"] = vector[4]
  3780. # units
  3781. currUnit = self.unitConv.findUnit(
  3782. self.panelVector.units["unitsCtrl"].GetStringSelection()
  3783. )
  3784. self.vLegendDict["unit"] = currUnit
  3785. # position
  3786. x = self.unitConv.convert(
  3787. value=float(self.panelVector.position["xCtrl"].GetValue()),
  3788. fromUnit=currUnit,
  3789. toUnit="inch",
  3790. )
  3791. y = self.unitConv.convert(
  3792. value=float(self.panelVector.position["yCtrl"].GetValue()),
  3793. fromUnit=currUnit,
  3794. toUnit="inch",
  3795. )
  3796. self.vLegendDict["where"] = (x, y)
  3797. # font
  3798. self.vLegendDict["font"] = self.panelVector.font[
  3799. "fontCtrl"
  3800. ].GetStringSelection()
  3801. self.vLegendDict["fontsize"] = self.panelVector.font[
  3802. "fontSizeCtrl"
  3803. ].GetValue()
  3804. dc = ClientDC(self)
  3805. dc.SetFont(
  3806. wx.Font(
  3807. pointSize=self.vLegendDict["fontsize"],
  3808. family=wx.FONTFAMILY_DEFAULT,
  3809. style=wx.FONTSTYLE_NORMAL,
  3810. weight=wx.FONTWEIGHT_NORMAL,
  3811. )
  3812. )
  3813. # size
  3814. width = self.unitConv.convert(
  3815. value=float(self.panelVector.widthCtrl.GetValue()),
  3816. fromUnit=currUnit,
  3817. toUnit="inch",
  3818. )
  3819. self.vLegendDict["width"] = width
  3820. self.vLegendDict["cols"] = self.panelVector.colsCtrl.GetValue()
  3821. if (
  3822. self.panelVector.spanRadio.GetValue()
  3823. and self.panelVector.spanTextCtrl.GetValue()
  3824. ):
  3825. self.vLegendDict["span"] = self.panelVector.spanTextCtrl.GetValue()
  3826. else:
  3827. self.vLegendDict["span"] = None
  3828. # size estimation
  3829. vectors = self.instruction[self.vectorId]["list"]
  3830. labels = [vector[4] for vector in vectors if vector[3] != 0]
  3831. extent = dc.GetTextExtent(max(labels, key=len))
  3832. wExtent = self.unitConv.convert(
  3833. value=extent[0], fromUnit="pixel", toUnit="inch"
  3834. )
  3835. hExtent = self.unitConv.convert(
  3836. value=extent[1], fromUnit="pixel", toUnit="inch"
  3837. )
  3838. w = (width + wExtent) * self.vLegendDict["cols"]
  3839. h = len(labels) * hExtent / self.vLegendDict["cols"]
  3840. h *= 1.1
  3841. self.vLegendDict["rect"] = Rect2D(x, y, w, h)
  3842. # border
  3843. if self.borderCheck.GetValue():
  3844. color = self.borderColorCtrl.GetColour()
  3845. self.vLegendDict["border"] = convertRGB(color)
  3846. else:
  3847. self.vLegendDict["border"] = "none"
  3848. if not self.id[1] in self.instruction:
  3849. vectorLegend = VectorLegend(self.id[1], env=self.env)
  3850. self.instruction.AddInstruction(vectorLegend)
  3851. self.instruction[self.id[1]].SetInstruction(self.vLegendDict)
  3852. if self.id[1] not in self.parent.objectId:
  3853. self.parent.objectId.append(self.id[1])
  3854. return True
  3855. def update(self):
  3856. okR = self.updateRasterLegend()
  3857. okV = self.updateVectorLegend()
  3858. if okR and okV:
  3859. return True
  3860. return False
  3861. def updateDialog(self):
  3862. """Update legend coordinates after moving"""
  3863. # raster legend
  3864. if "rect" in self.rLegendDict:
  3865. x, y = self.rLegendDict["rect"][:2]
  3866. currUnit = self.unitConv.findUnit(
  3867. self.panelRaster.units["unitsCtrl"].GetStringSelection()
  3868. )
  3869. x = self.unitConv.convert(value=x, fromUnit="inch", toUnit=currUnit)
  3870. y = self.unitConv.convert(value=y, fromUnit="inch", toUnit=currUnit)
  3871. self.panelRaster.position["xCtrl"].SetValue("%5.3f" % x)
  3872. self.panelRaster.position["yCtrl"].SetValue("%5.3f" % y)
  3873. # update name and type of raster
  3874. raster = self.instruction.FindInstructionByType("raster")
  3875. if raster:
  3876. self.rasterId = raster.id
  3877. else:
  3878. self.rasterId = None
  3879. if raster:
  3880. currRaster = raster["raster"]
  3881. else:
  3882. currRaster = None
  3883. rasterType = getRasterType(map=currRaster)
  3884. self.rasterCurrent.SetLabel(
  3885. _("%(rast)s: type %(type)s") % {"rast": currRaster, "type": str(rasterType)}
  3886. )
  3887. # vector legend
  3888. if "rect" in self.vLegendDict:
  3889. x, y = self.vLegendDict["rect"][:2]
  3890. currUnit = self.unitConv.findUnit(
  3891. self.panelVector.units["unitsCtrl"].GetStringSelection()
  3892. )
  3893. x = self.unitConv.convert(value=x, fromUnit="inch", toUnit=currUnit)
  3894. y = self.unitConv.convert(value=y, fromUnit="inch", toUnit=currUnit)
  3895. self.panelVector.position["xCtrl"].SetValue("%5.3f" % x)
  3896. self.panelVector.position["yCtrl"].SetValue("%5.3f" % y)
  3897. # update vector maps
  3898. if self.instruction.FindInstructionByType("vector"):
  3899. vectors = sorted(
  3900. self.instruction.FindInstructionByType("vector")["list"],
  3901. key=lambda x: x[3],
  3902. )
  3903. self.vectorListCtrl.DeleteAllItems()
  3904. for vector in vectors:
  3905. index = self.vectorListCtrl.InsertItem(
  3906. self.vectorListCtrl.GetItemCount(), vector[0].split("@")[0]
  3907. )
  3908. self.vectorListCtrl.SetItem(index, 1, vector[4])
  3909. self.vectorListCtrl.SetItemData(index, index)
  3910. self.vectorListCtrl.CheckItem(index, True)
  3911. if vector[3] == 0:
  3912. self.vectorListCtrl.CheckItem(index, False)
  3913. self.panelVector.colsCtrl.SetRange(
  3914. 1,
  3915. min(10, len(self.instruction.FindInstructionByType("vector")["list"])),
  3916. )
  3917. self.panelVector.colsCtrl.SetValue(1)
  3918. else:
  3919. self.vectorListCtrl.DeleteAllItems()
  3920. self.panelVector.colsCtrl.SetRange(0, 0)
  3921. self.panelVector.colsCtrl.SetValue(0)
  3922. class MapinfoDialog(PsmapDialog):
  3923. def __init__(self, parent, id, settings, env):
  3924. PsmapDialog.__init__(
  3925. self,
  3926. parent=parent,
  3927. id=id,
  3928. title=_("Mapinfo settings"),
  3929. settings=settings,
  3930. env=env,
  3931. )
  3932. self.objectType = ("mapinfo",)
  3933. if self.id is not None:
  3934. self.mapinfo = self.instruction[self.id]
  3935. self.mapinfoDict = self.mapinfo.GetInstruction()
  3936. else:
  3937. self.id = NewId()
  3938. self.mapinfo = Mapinfo(self.id, env=self.env)
  3939. self.mapinfoDict = self.mapinfo.GetInstruction()
  3940. page = self.instruction.FindInstructionByType("page").GetInstruction()
  3941. self.mapinfoDict["where"] = page["Left"], page["Top"]
  3942. self.panel = self._mapinfoPanel()
  3943. self._layout(self.panel)
  3944. self.OnIsBackground(None)
  3945. self.OnIsBorder(None)
  3946. def _mapinfoPanel(self):
  3947. panel = Panel(parent=self, id=wx.ID_ANY, size=(-1, -1), style=wx.TAB_TRAVERSAL)
  3948. # panel.SetupScrolling(scroll_x = False, scroll_y = True)
  3949. border = wx.BoxSizer(wx.VERTICAL)
  3950. # position
  3951. box = StaticBox(parent=panel, id=wx.ID_ANY, label=" %s " % _("Position"))
  3952. sizer = wx.StaticBoxSizer(box, wx.VERTICAL)
  3953. gridBagSizer = wx.GridBagSizer(hgap=5, vgap=5)
  3954. self.AddPosition(parent=panel, dialogDict=self.mapinfoDict)
  3955. self.AddUnits(parent=panel, dialogDict=self.mapinfoDict)
  3956. gridBagSizer.Add(
  3957. panel.units["unitsLabel"],
  3958. pos=(0, 0),
  3959. flag=wx.ALIGN_CENTER_VERTICAL,
  3960. border=0,
  3961. )
  3962. gridBagSizer.Add(
  3963. panel.units["unitsCtrl"],
  3964. pos=(0, 1),
  3965. flag=wx.ALIGN_CENTER_VERTICAL,
  3966. border=0,
  3967. )
  3968. gridBagSizer.Add(
  3969. panel.position["xLabel"],
  3970. pos=(1, 0),
  3971. flag=wx.ALIGN_CENTER_VERTICAL,
  3972. border=0,
  3973. )
  3974. gridBagSizer.Add(
  3975. panel.position["xCtrl"], pos=(1, 1), flag=wx.ALIGN_CENTER_VERTICAL, border=0
  3976. )
  3977. gridBagSizer.Add(
  3978. panel.position["yLabel"],
  3979. pos=(2, 0),
  3980. flag=wx.ALIGN_CENTER_VERTICAL,
  3981. border=0,
  3982. )
  3983. gridBagSizer.Add(
  3984. panel.position["yCtrl"], pos=(2, 1), flag=wx.ALIGN_CENTER_VERTICAL, border=0
  3985. )
  3986. gridBagSizer.Add(
  3987. panel.position["comment"],
  3988. pos=(3, 0),
  3989. span=(1, 2),
  3990. flag=wx.ALIGN_BOTTOM,
  3991. border=0,
  3992. )
  3993. gridBagSizer.AddGrowableCol(1)
  3994. sizer.Add(gridBagSizer, proportion=1, flag=wx.EXPAND | wx.ALL, border=5)
  3995. border.Add(sizer, proportion=0, flag=wx.ALL | wx.EXPAND, border=5)
  3996. # font
  3997. box = StaticBox(parent=panel, id=wx.ID_ANY, label=" %s " % _("Font settings"))
  3998. sizer = wx.StaticBoxSizer(box, wx.VERTICAL)
  3999. gridBagSizer = wx.GridBagSizer(hgap=5, vgap=5)
  4000. # creates font color too, used below
  4001. self.AddFont(parent=panel, dialogDict=self.mapinfoDict)
  4002. gridBagSizer.Add(
  4003. panel.font["fontLabel"], pos=(0, 0), flag=wx.ALIGN_CENTER_VERTICAL, border=0
  4004. )
  4005. gridBagSizer.Add(
  4006. panel.font["fontCtrl"], pos=(0, 1), flag=wx.ALIGN_CENTER_VERTICAL, border=0
  4007. )
  4008. gridBagSizer.Add(
  4009. panel.font["fontSizeLabel"],
  4010. pos=(1, 0),
  4011. flag=wx.ALIGN_CENTER_VERTICAL,
  4012. border=0,
  4013. )
  4014. gridBagSizer.Add(
  4015. panel.font["fontSizeCtrl"],
  4016. pos=(1, 1),
  4017. flag=wx.ALIGN_CENTER_VERTICAL,
  4018. border=0,
  4019. )
  4020. gridBagSizer.Add(
  4021. panel.font["colorLabel"],
  4022. pos=(2, 0),
  4023. flag=wx.ALIGN_CENTER_VERTICAL,
  4024. border=0,
  4025. )
  4026. gridBagSizer.Add(
  4027. panel.font["colorCtrl"], pos=(2, 1), flag=wx.ALIGN_CENTER_VERTICAL, border=0
  4028. )
  4029. gridBagSizer.AddGrowableCol(1)
  4030. sizer.Add(gridBagSizer, proportion=1, flag=wx.ALL | wx.EXPAND, border=1)
  4031. border.Add(sizer, proportion=0, flag=wx.ALL | wx.EXPAND, border=5)
  4032. # colors
  4033. box = StaticBox(parent=panel, id=wx.ID_ANY, label=" %s " % _("Color settings"))
  4034. sizer = wx.StaticBoxSizer(box, wx.VERTICAL)
  4035. flexSizer = wx.FlexGridSizer(cols=2, hgap=5, vgap=5)
  4036. self.colors = {}
  4037. self.colors["borderCtrl"] = CheckBox(
  4038. panel, id=wx.ID_ANY, label=_("use border color:")
  4039. )
  4040. self.colors["backgroundCtrl"] = CheckBox(
  4041. panel, id=wx.ID_ANY, label=_("use background color:")
  4042. )
  4043. self.colors["borderColor"] = ColourPickerCtrl(panel, id=wx.ID_ANY)
  4044. self.colors["backgroundColor"] = ColourPickerCtrl(panel, id=wx.ID_ANY)
  4045. if self.mapinfoDict["border"] is None:
  4046. self.mapinfoDict["border"] = "none"
  4047. if self.mapinfoDict["border"] != "none":
  4048. self.colors["borderCtrl"].SetValue(True)
  4049. self.colors["borderColor"].SetColour(convertRGB(self.mapinfoDict["border"]))
  4050. else:
  4051. self.colors["borderCtrl"].SetValue(False)
  4052. self.colors["borderColor"].SetColour(convertRGB("black"))
  4053. if self.mapinfoDict["background"] is None:
  4054. self.mapinfoDict["background"] == "none"
  4055. if self.mapinfoDict["background"] != "none":
  4056. self.colors["backgroundCtrl"].SetValue(True)
  4057. self.colors["backgroundColor"].SetColour(
  4058. convertRGB(self.mapinfoDict["background"])
  4059. )
  4060. else:
  4061. self.colors["backgroundCtrl"].SetValue(False)
  4062. self.colors["backgroundColor"].SetColour(convertRGB("white"))
  4063. flexSizer.Add(
  4064. self.colors["borderCtrl"],
  4065. proportion=0,
  4066. flag=wx.ALIGN_CENTER_VERTICAL,
  4067. border=0,
  4068. )
  4069. flexSizer.Add(
  4070. self.colors["borderColor"],
  4071. proportion=0,
  4072. flag=wx.ALIGN_CENTER_VERTICAL,
  4073. border=0,
  4074. )
  4075. flexSizer.Add(
  4076. self.colors["backgroundCtrl"],
  4077. proportion=0,
  4078. flag=wx.ALIGN_CENTER_VERTICAL,
  4079. border=0,
  4080. )
  4081. flexSizer.Add(
  4082. self.colors["backgroundColor"],
  4083. proportion=0,
  4084. flag=wx.ALIGN_CENTER_VERTICAL,
  4085. border=0,
  4086. )
  4087. flexSizer.AddGrowableCol(1)
  4088. sizer.Add(flexSizer, proportion=1, flag=wx.ALL | wx.EXPAND, border=1)
  4089. border.Add(sizer, proportion=0, flag=wx.ALL | wx.EXPAND, border=5)
  4090. panel.SetSizer(border)
  4091. self.Bind(wx.EVT_CHECKBOX, self.OnIsBorder, self.colors["borderCtrl"])
  4092. self.Bind(wx.EVT_CHECKBOX, self.OnIsBackground, self.colors["backgroundCtrl"])
  4093. return panel
  4094. def OnIsBackground(self, event):
  4095. if self.colors["backgroundCtrl"].GetValue():
  4096. self.colors["backgroundColor"].Enable()
  4097. self.update()
  4098. else:
  4099. self.colors["backgroundColor"].Disable()
  4100. def OnIsBorder(self, event):
  4101. if self.colors["borderCtrl"].GetValue():
  4102. self.colors["borderColor"].Enable()
  4103. self.update()
  4104. else:
  4105. self.colors["borderColor"].Disable()
  4106. def update(self):
  4107. # units
  4108. currUnit = self.unitConv.findUnit(
  4109. self.panel.units["unitsCtrl"].GetStringSelection()
  4110. )
  4111. self.mapinfoDict["unit"] = currUnit
  4112. # position
  4113. if self.panel.position["xCtrl"].GetValue():
  4114. x = self.panel.position["xCtrl"].GetValue()
  4115. else:
  4116. x = self.mapinfoDict["where"][0]
  4117. if self.panel.position["yCtrl"].GetValue():
  4118. y = self.panel.position["yCtrl"].GetValue()
  4119. else:
  4120. y = self.mapinfoDict["where"][1]
  4121. x = self.unitConv.convert(
  4122. value=float(self.panel.position["xCtrl"].GetValue()),
  4123. fromUnit=currUnit,
  4124. toUnit="inch",
  4125. )
  4126. y = self.unitConv.convert(
  4127. value=float(self.panel.position["yCtrl"].GetValue()),
  4128. fromUnit=currUnit,
  4129. toUnit="inch",
  4130. )
  4131. self.mapinfoDict["where"] = (x, y)
  4132. # font
  4133. self.mapinfoDict["font"] = self.panel.font["fontCtrl"].GetStringSelection()
  4134. self.mapinfoDict["fontsize"] = self.panel.font["fontSizeCtrl"].GetValue()
  4135. # colors
  4136. color = self.panel.font["colorCtrl"].GetColour()
  4137. self.mapinfoDict["color"] = convertRGB(color)
  4138. if self.colors["backgroundCtrl"].GetValue():
  4139. background = self.colors["backgroundColor"].GetColour()
  4140. self.mapinfoDict["background"] = convertRGB(background)
  4141. else:
  4142. self.mapinfoDict["background"] = "none"
  4143. if self.colors["borderCtrl"].GetValue():
  4144. border = self.colors["borderColor"].GetColour()
  4145. self.mapinfoDict["border"] = convertRGB(border)
  4146. else:
  4147. self.mapinfoDict["border"] = "none"
  4148. # estimation of size
  4149. self.mapinfoDict["rect"] = self.mapinfo.EstimateRect(self.mapinfoDict)
  4150. if self.id not in self.instruction:
  4151. mapinfo = Mapinfo(self.id, env=self.env)
  4152. self.instruction.AddInstruction(mapinfo)
  4153. self.instruction[self.id].SetInstruction(self.mapinfoDict)
  4154. if self.id not in self.parent.objectId:
  4155. self.parent.objectId.append(self.id)
  4156. self.updateDialog()
  4157. return True
  4158. def updateDialog(self):
  4159. """Update mapinfo coordinates, after moving"""
  4160. x, y = self.mapinfoDict["where"]
  4161. currUnit = self.unitConv.findUnit(
  4162. self.panel.units["unitsCtrl"].GetStringSelection()
  4163. )
  4164. x = self.unitConv.convert(value=x, fromUnit="inch", toUnit=currUnit)
  4165. y = self.unitConv.convert(value=y, fromUnit="inch", toUnit=currUnit)
  4166. self.panel.position["xCtrl"].SetValue("%5.3f" % x)
  4167. self.panel.position["yCtrl"].SetValue("%5.3f" % y)
  4168. class ScalebarDialog(PsmapDialog):
  4169. """Dialog for scale bar"""
  4170. def __init__(self, parent, id, settings, env):
  4171. PsmapDialog.__init__(
  4172. self,
  4173. parent=parent,
  4174. id=id,
  4175. title="Scale bar settings",
  4176. settings=settings,
  4177. env=env,
  4178. )
  4179. self.objectType = ("scalebar",)
  4180. if self.id is not None:
  4181. self.scalebar = self.instruction[id]
  4182. self.scalebarDict = self.scalebar.GetInstruction()
  4183. else:
  4184. self.id = NewId()
  4185. self.scalebar = Scalebar(self.id, env=self.env)
  4186. self.scalebarDict = self.scalebar.GetInstruction()
  4187. page = self.instruction.FindInstructionByType("page").GetInstruction()
  4188. self.scalebarDict["where"] = page["Left"], page["Top"]
  4189. self.panel = self._scalebarPanel()
  4190. self._layout(self.panel)
  4191. self.mapUnit = projInfo()["units"].lower()
  4192. if projInfo()["proj"] == "xy":
  4193. self.mapUnit = "meters"
  4194. if self.mapUnit not in self.unitConv.getAllUnits():
  4195. self.mapUnit = "meters"
  4196. def _scalebarPanel(self):
  4197. panel = Panel(parent=self, id=wx.ID_ANY, style=wx.TAB_TRAVERSAL)
  4198. border = wx.BoxSizer(wx.VERTICAL)
  4199. #
  4200. # position
  4201. #
  4202. box = StaticBox(parent=panel, id=wx.ID_ANY, label=" %s " % _("Position"))
  4203. sizer = wx.StaticBoxSizer(box, wx.VERTICAL)
  4204. gridBagSizer = wx.GridBagSizer(hgap=5, vgap=5)
  4205. self.AddUnits(parent=panel, dialogDict=self.scalebarDict)
  4206. self.AddPosition(parent=panel, dialogDict=self.scalebarDict)
  4207. if self.scalebarDict[
  4208. "rect"
  4209. ]: # set position, ref point is center and not left top corner
  4210. x = self.unitConv.convert(
  4211. value=self.scalebarDict["where"][0]
  4212. - self.scalebarDict["rect"].Get()[2] / 2,
  4213. fromUnit="inch",
  4214. toUnit=self.scalebarDict["unit"],
  4215. )
  4216. y = self.unitConv.convert(
  4217. value=self.scalebarDict["where"][1]
  4218. - self.scalebarDict["rect"].Get()[3] / 2,
  4219. fromUnit="inch",
  4220. toUnit=self.scalebarDict["unit"],
  4221. )
  4222. panel.position["xCtrl"].SetValue("%5.3f" % x)
  4223. panel.position["yCtrl"].SetValue("%5.3f" % y)
  4224. gridBagSizer.Add(
  4225. panel.units["unitsLabel"],
  4226. pos=(0, 0),
  4227. flag=wx.ALIGN_CENTER_VERTICAL,
  4228. border=0,
  4229. )
  4230. gridBagSizer.Add(
  4231. panel.units["unitsCtrl"],
  4232. pos=(0, 1),
  4233. flag=wx.ALIGN_CENTER_VERTICAL,
  4234. border=0,
  4235. )
  4236. gridBagSizer.Add(
  4237. panel.position["xLabel"],
  4238. pos=(1, 0),
  4239. flag=wx.ALIGN_CENTER_VERTICAL,
  4240. border=0,
  4241. )
  4242. gridBagSizer.Add(
  4243. panel.position["xCtrl"], pos=(1, 1), flag=wx.ALIGN_CENTER_VERTICAL, border=0
  4244. )
  4245. gridBagSizer.Add(
  4246. panel.position["yLabel"],
  4247. pos=(2, 0),
  4248. flag=wx.ALIGN_CENTER_VERTICAL,
  4249. border=0,
  4250. )
  4251. gridBagSizer.Add(
  4252. panel.position["yCtrl"], pos=(2, 1), flag=wx.ALIGN_CENTER_VERTICAL, border=0
  4253. )
  4254. gridBagSizer.Add(
  4255. panel.position["comment"],
  4256. pos=(3, 0),
  4257. span=(1, 2),
  4258. flag=wx.ALIGN_BOTTOM,
  4259. border=0,
  4260. )
  4261. gridBagSizer.AddGrowableCol(1)
  4262. sizer.Add(gridBagSizer, proportion=1, flag=wx.EXPAND | wx.ALL, border=5)
  4263. border.Add(sizer, proportion=0, flag=wx.ALL | wx.EXPAND, border=5)
  4264. #
  4265. # size
  4266. #
  4267. box = StaticBox(parent=panel, id=wx.ID_ANY, label=" %s " % _("Size"))
  4268. sizer = wx.StaticBoxSizer(box, wx.VERTICAL)
  4269. gridBagSizer = wx.GridBagSizer(hgap=5, vgap=5)
  4270. lengthText = StaticText(panel, id=wx.ID_ANY, label=_("Length:"))
  4271. heightText = StaticText(panel, id=wx.ID_ANY, label=_("Height:"))
  4272. self.lengthTextCtrl = TextCtrl(
  4273. panel, id=wx.ID_ANY, validator=TCValidator("DIGIT_ONLY")
  4274. )
  4275. self.lengthTextCtrl.SetToolTip(_("Scalebar length is given in map units"))
  4276. self.heightTextCtrl = TextCtrl(
  4277. panel, id=wx.ID_ANY, validator=TCValidator("DIGIT_ONLY")
  4278. )
  4279. self.heightTextCtrl.SetToolTip(_("Scalebar height is real height on paper"))
  4280. choices = [_("default")] + self.unitConv.getMapUnitsNames()
  4281. self.unitsLength = Choice(panel, id=wx.ID_ANY, choices=choices)
  4282. choices = self.unitConv.getPageUnitsNames()
  4283. self.unitsHeight = Choice(panel, id=wx.ID_ANY, choices=choices)
  4284. # set values
  4285. unitName = self.unitConv.findName(self.scalebarDict["unitsLength"])
  4286. if unitName:
  4287. self.unitsLength.SetStringSelection(unitName)
  4288. else:
  4289. if self.scalebarDict["unitsLength"] == "auto":
  4290. self.unitsLength.SetSelection(0)
  4291. elif self.scalebarDict["unitsLength"] == "nautmiles":
  4292. self.unitsLength.SetStringSelection(
  4293. self.unitConv.findName("nautical miles")
  4294. )
  4295. self.unitsHeight.SetStringSelection(
  4296. self.unitConv.findName(self.scalebarDict["unitsHeight"])
  4297. )
  4298. if self.scalebarDict["length"]:
  4299. self.lengthTextCtrl.SetValue(str(self.scalebarDict["length"]))
  4300. else: # estimate default
  4301. reg = grass.region(env=self.env)
  4302. w = int((reg["e"] - reg["w"]) / 3)
  4303. w = round(w, -len(str(w)) + 2) # 12345 -> 12000
  4304. self.lengthTextCtrl.SetValue(str(w))
  4305. h = self.unitConv.convert(
  4306. value=self.scalebarDict["height"],
  4307. fromUnit="inch",
  4308. toUnit=self.scalebarDict["unitsHeight"],
  4309. )
  4310. self.heightTextCtrl.SetValue(str(h))
  4311. gridBagSizer.Add(
  4312. lengthText, pos=(0, 0), flag=wx.ALIGN_CENTER_VERTICAL, border=0
  4313. )
  4314. gridBagSizer.Add(
  4315. self.lengthTextCtrl, pos=(0, 1), flag=wx.ALIGN_CENTER_VERTICAL, border=0
  4316. )
  4317. gridBagSizer.Add(
  4318. self.unitsLength,
  4319. pos=(0, 2),
  4320. flag=wx.ALIGN_CENTER_VERTICAL | wx.EXPAND,
  4321. border=0,
  4322. )
  4323. gridBagSizer.Add(
  4324. heightText, pos=(1, 0), flag=wx.ALIGN_CENTER_VERTICAL, border=0
  4325. )
  4326. gridBagSizer.Add(
  4327. self.heightTextCtrl, pos=(1, 1), flag=wx.ALIGN_CENTER_VERTICAL, border=0
  4328. )
  4329. gridBagSizer.Add(
  4330. self.unitsHeight,
  4331. pos=(1, 2),
  4332. flag=wx.ALIGN_CENTER_VERTICAL | wx.EXPAND,
  4333. border=0,
  4334. )
  4335. gridBagSizer.AddGrowableCol(1)
  4336. sizer.Add(gridBagSizer, proportion=1, flag=wx.EXPAND | wx.ALL, border=5)
  4337. border.Add(sizer, proportion=0, flag=wx.ALL | wx.EXPAND, border=5)
  4338. #
  4339. # style
  4340. #
  4341. box = StaticBox(parent=panel, id=wx.ID_ANY, label=" %s " % _("Style"))
  4342. sizer = wx.StaticBoxSizer(box, wx.VERTICAL)
  4343. gridBagSizer = wx.GridBagSizer(hgap=5, vgap=5)
  4344. sbTypeText = StaticText(panel, id=wx.ID_ANY, label=_("Type:"))
  4345. self.sbCombo = BitmapComboBox(panel, style=wx.CB_READONLY)
  4346. # only temporary, images must be moved away
  4347. imagePath = os.path.join(globalvar.IMGDIR, "scalebar-fancy.png"), os.path.join(
  4348. globalvar.IMGDIR, "scalebar-simple.png"
  4349. )
  4350. for item, path in zip(["fancy", "simple"], imagePath):
  4351. if not os.path.exists(path):
  4352. bitmap = EmptyBitmap(0, 0)
  4353. else:
  4354. bitmap = wx.Bitmap(path)
  4355. self.sbCombo.Append(item="", bitmap=bitmap, clientData=item[0])
  4356. # self.sbCombo.Append(item = 'simple', bitmap = wx.Bitmap("./images/scalebar-simple.png"), clientData = 's')
  4357. if self.scalebarDict["scalebar"] == "f":
  4358. self.sbCombo.SetSelection(0)
  4359. elif self.scalebarDict["scalebar"] == "s":
  4360. self.sbCombo.SetSelection(1)
  4361. sbSegmentsText = StaticText(panel, id=wx.ID_ANY, label=_("Number of segments:"))
  4362. self.sbSegmentsCtrl = SpinCtrl(panel, id=wx.ID_ANY, min=1, max=30, initial=4)
  4363. self.sbSegmentsCtrl.SetValue(self.scalebarDict["segment"])
  4364. sbLabelsText1 = StaticText(panel, id=wx.ID_ANY, label=_("Label every "))
  4365. sbLabelsText2 = StaticText(panel, id=wx.ID_ANY, label=_("segments"))
  4366. self.sbLabelsCtrl = SpinCtrl(panel, id=wx.ID_ANY, min=1, max=30, initial=1)
  4367. self.sbLabelsCtrl.SetValue(self.scalebarDict["numbers"])
  4368. # font
  4369. fontsizeText = StaticText(panel, id=wx.ID_ANY, label=_("Font size:"))
  4370. self.fontsizeCtrl = SpinCtrl(panel, id=wx.ID_ANY, min=4, max=30, initial=10)
  4371. self.fontsizeCtrl.SetValue(self.scalebarDict["fontsize"])
  4372. self.backgroundCheck = CheckBox(
  4373. panel, id=wx.ID_ANY, label=_("transparent text background")
  4374. )
  4375. if self.scalebarDict["background"] == "y":
  4376. self.backgroundCheck.SetValue(False)
  4377. else:
  4378. self.backgroundCheck.SetValue(True)
  4379. gridBagSizer.Add(
  4380. sbTypeText, pos=(0, 0), flag=wx.ALIGN_CENTER_VERTICAL, border=0
  4381. )
  4382. gridBagSizer.Add(
  4383. self.sbCombo,
  4384. pos=(0, 1),
  4385. span=(1, 2),
  4386. flag=wx.ALIGN_CENTER_VERTICAL | wx.EXPAND,
  4387. border=0,
  4388. )
  4389. gridBagSizer.Add(
  4390. sbSegmentsText, pos=(1, 0), flag=wx.ALIGN_CENTER_VERTICAL, border=0
  4391. )
  4392. gridBagSizer.Add(
  4393. self.sbSegmentsCtrl, pos=(1, 1), flag=wx.ALIGN_CENTER_VERTICAL, border=0
  4394. )
  4395. gridBagSizer.Add(
  4396. sbLabelsText1, pos=(2, 0), flag=wx.ALIGN_CENTER_VERTICAL, border=0
  4397. )
  4398. gridBagSizer.Add(
  4399. self.sbLabelsCtrl, pos=(2, 1), flag=wx.ALIGN_CENTER_VERTICAL, border=0
  4400. )
  4401. gridBagSizer.Add(
  4402. sbLabelsText2, pos=(2, 2), flag=wx.ALIGN_CENTER_VERTICAL, border=0
  4403. )
  4404. gridBagSizer.Add(
  4405. fontsizeText, pos=(3, 0), flag=wx.ALIGN_CENTER_VERTICAL, border=0
  4406. )
  4407. gridBagSizer.Add(
  4408. self.fontsizeCtrl, pos=(3, 1), flag=wx.ALIGN_CENTER_VERTICAL, border=0
  4409. )
  4410. gridBagSizer.Add(
  4411. self.backgroundCheck,
  4412. pos=(4, 0),
  4413. span=(1, 3),
  4414. flag=wx.ALIGN_CENTER_VERTICAL,
  4415. border=0,
  4416. )
  4417. sizer.Add(gridBagSizer, proportion=1, border=5)
  4418. border.Add(sizer, proportion=0, flag=wx.ALL | wx.EXPAND, border=5)
  4419. panel.SetSizer(border)
  4420. return panel
  4421. def update(self):
  4422. """Save information from dialog"""
  4423. # units
  4424. currUnit = self.unitConv.findUnit(
  4425. self.panel.units["unitsCtrl"].GetStringSelection()
  4426. )
  4427. self.scalebarDict["unit"] = currUnit
  4428. # position
  4429. if self.panel.position["xCtrl"].GetValue():
  4430. x = self.panel.position["xCtrl"].GetValue()
  4431. else:
  4432. x = self.scalebarDict["where"][0]
  4433. if self.panel.position["yCtrl"].GetValue():
  4434. y = self.panel.position["yCtrl"].GetValue()
  4435. else:
  4436. y = self.scalebarDict["where"][1]
  4437. x = self.unitConv.convert(
  4438. value=float(self.panel.position["xCtrl"].GetValue()),
  4439. fromUnit=currUnit,
  4440. toUnit="inch",
  4441. )
  4442. y = self.unitConv.convert(
  4443. value=float(self.panel.position["yCtrl"].GetValue()),
  4444. fromUnit=currUnit,
  4445. toUnit="inch",
  4446. )
  4447. # style
  4448. self.scalebarDict["scalebar"] = self.sbCombo.GetClientData(
  4449. self.sbCombo.GetSelection()
  4450. )
  4451. self.scalebarDict["segment"] = self.sbSegmentsCtrl.GetValue()
  4452. self.scalebarDict["numbers"] = self.sbLabelsCtrl.GetValue()
  4453. self.scalebarDict["fontsize"] = self.fontsizeCtrl.GetValue()
  4454. if self.backgroundCheck.GetValue():
  4455. self.scalebarDict["background"] = "n"
  4456. else:
  4457. self.scalebarDict["background"] = "y"
  4458. # size
  4459. # height
  4460. self.scalebarDict["unitsHeight"] = self.unitConv.findUnit(
  4461. self.unitsHeight.GetStringSelection()
  4462. )
  4463. try:
  4464. height = float(self.heightTextCtrl.GetValue())
  4465. height = self.unitConv.convert(
  4466. value=height, fromUnit=self.scalebarDict["unitsHeight"], toUnit="inch"
  4467. )
  4468. except (ValueError, SyntaxError):
  4469. height = 0.1 # default in inch
  4470. self.scalebarDict["height"] = height
  4471. # length
  4472. if self.unitsLength.GetSelection() == 0:
  4473. selected = "auto"
  4474. else:
  4475. selected = self.unitConv.findUnit(self.unitsLength.GetStringSelection())
  4476. if selected == "nautical miles":
  4477. selected = "nautmiles"
  4478. self.scalebarDict["unitsLength"] = selected
  4479. try:
  4480. length = float(self.lengthTextCtrl.GetValue())
  4481. except (ValueError, SyntaxError):
  4482. wx.MessageBox(
  4483. message=_("Length of scale bar is not defined"),
  4484. caption=_("Invalid input"),
  4485. style=wx.OK | wx.ICON_ERROR,
  4486. )
  4487. return False
  4488. self.scalebarDict["length"] = length
  4489. # estimation of size
  4490. map = self.instruction.FindInstructionByType("map")
  4491. if not map:
  4492. map = self.instruction.FindInstructionByType("initMap")
  4493. mapId = map.id
  4494. rectSize = self.scalebar.EstimateSize(
  4495. scalebarDict=self.scalebarDict, scale=self.instruction[mapId]["scale"]
  4496. )
  4497. self.scalebarDict["rect"] = Rect2D(
  4498. x=x, y=y, width=rectSize[0], height=rectSize[1]
  4499. )
  4500. self.scalebarDict["where"] = self.scalebarDict["rect"].GetCentre()
  4501. if self.id not in self.instruction:
  4502. scalebar = Scalebar(self.id, env=self.env)
  4503. self.instruction.AddInstruction(scalebar)
  4504. self.instruction[self.id].SetInstruction(self.scalebarDict)
  4505. if self.id not in self.parent.objectId:
  4506. self.parent.objectId.append(self.id)
  4507. return True
  4508. def updateDialog(self):
  4509. """Update scalebar coordinates, after moving"""
  4510. x, y = self.scalebarDict["rect"][:2]
  4511. currUnit = self.unitConv.findUnit(
  4512. self.panel.units["unitsCtrl"].GetStringSelection()
  4513. )
  4514. x = self.unitConv.convert(value=x, fromUnit="inch", toUnit=currUnit)
  4515. y = self.unitConv.convert(value=y, fromUnit="inch", toUnit=currUnit)
  4516. self.panel.position["xCtrl"].SetValue("%5.3f" % x)
  4517. self.panel.position["yCtrl"].SetValue("%5.3f" % y)
  4518. class TextDialog(PsmapDialog):
  4519. def __init__(self, parent, id, settings, env):
  4520. PsmapDialog.__init__(
  4521. self,
  4522. parent=parent,
  4523. id=id,
  4524. title="Text settings",
  4525. settings=settings,
  4526. env=env,
  4527. )
  4528. self.objectType = ("text",)
  4529. if self.id is not None:
  4530. self.textDict = self.instruction[id].GetInstruction()
  4531. else:
  4532. self.id = NewId()
  4533. text = Text(self.id, env=self.env)
  4534. self.textDict = text.GetInstruction()
  4535. page = self.instruction.FindInstructionByType("page").GetInstruction()
  4536. self.textDict["where"] = page["Left"], page["Top"]
  4537. map = self.instruction.FindInstructionByType("map")
  4538. if not map:
  4539. map = self.instruction.FindInstructionByType("initMap")
  4540. self.mapId = map.id
  4541. self.textDict["east"], self.textDict["north"] = PaperMapCoordinates(
  4542. mapInstr=map,
  4543. x=self.textDict["where"][0],
  4544. y=self.textDict["where"][1],
  4545. paperToMap=True,
  4546. env=self.env,
  4547. )
  4548. notebook = Notebook(parent=self, id=wx.ID_ANY, style=wx.BK_DEFAULT)
  4549. self.textPanel = self._textPanel(notebook)
  4550. self.positionPanel = self._positionPanel(notebook)
  4551. self.OnBackground(None)
  4552. self.OnHighlight(None)
  4553. self.OnBorder(None)
  4554. self.OnPositionType(None)
  4555. self.OnRotation(None)
  4556. self._layout(notebook)
  4557. def _textPanel(self, notebook):
  4558. panel = Panel(parent=notebook, id=wx.ID_ANY, style=wx.TAB_TRAVERSAL)
  4559. notebook.AddPage(page=panel, text=_("Text"))
  4560. border = wx.BoxSizer(wx.VERTICAL)
  4561. # text entry
  4562. box = StaticBox(parent=panel, id=wx.ID_ANY, label=" %s " % _("Text"))
  4563. sizer = wx.StaticBoxSizer(box, wx.HORIZONTAL)
  4564. textLabel = StaticText(panel, id=wx.ID_ANY, label=_("Enter text:"))
  4565. self.textCtrl = ExpandoTextCtrl(
  4566. panel, id=wx.ID_ANY, value=self.textDict["text"]
  4567. )
  4568. sizer.Add(
  4569. textLabel, proportion=0, flag=wx.ALIGN_CENTER_VERTICAL | wx.ALL, border=5
  4570. )
  4571. sizer.Add(
  4572. self.textCtrl,
  4573. proportion=1,
  4574. flag=wx.ALIGN_CENTER_VERTICAL | wx.ALL,
  4575. border=5,
  4576. )
  4577. border.Add(sizer, proportion=0, flag=wx.ALL | wx.EXPAND, border=5)
  4578. # font
  4579. box = StaticBox(parent=panel, id=wx.ID_ANY, label=" %s " % _("Font settings"))
  4580. sizer = wx.StaticBoxSizer(box, wx.VERTICAL)
  4581. flexGridSizer = wx.FlexGridSizer(rows=3, cols=2, hgap=5, vgap=5)
  4582. self.AddFont(parent=panel, dialogDict=self.textDict)
  4583. flexGridSizer.Add(
  4584. panel.font["fontLabel"],
  4585. proportion=0,
  4586. flag=wx.ALIGN_CENTER_VERTICAL,
  4587. border=0,
  4588. )
  4589. flexGridSizer.Add(
  4590. panel.font["fontCtrl"],
  4591. proportion=0,
  4592. flag=wx.ALIGN_CENTER_VERTICAL,
  4593. border=0,
  4594. )
  4595. flexGridSizer.Add(
  4596. panel.font["fontSizeLabel"],
  4597. proportion=0,
  4598. flag=wx.ALIGN_CENTER_VERTICAL,
  4599. border=0,
  4600. )
  4601. flexGridSizer.Add(
  4602. panel.font["fontSizeCtrl"],
  4603. proportion=0,
  4604. flag=wx.ALIGN_CENTER_VERTICAL,
  4605. border=0,
  4606. )
  4607. flexGridSizer.Add(
  4608. panel.font["colorLabel"],
  4609. proportion=0,
  4610. flag=wx.ALIGN_CENTER_VERTICAL,
  4611. border=0,
  4612. )
  4613. flexGridSizer.Add(
  4614. panel.font["colorCtrl"],
  4615. proportion=0,
  4616. flag=wx.ALIGN_CENTER_VERTICAL,
  4617. border=0,
  4618. )
  4619. flexGridSizer.AddGrowableCol(1)
  4620. sizer.Add(flexGridSizer, proportion=1, flag=wx.ALL | wx.EXPAND, border=1)
  4621. border.Add(sizer, proportion=0, flag=wx.ALL | wx.EXPAND, border=5)
  4622. # text effects
  4623. box = StaticBox(parent=panel, id=wx.ID_ANY, label=" %s " % _("Text effects"))
  4624. sizer = wx.StaticBoxSizer(box, wx.VERTICAL)
  4625. gridBagSizer = wx.GridBagSizer(hgap=5, vgap=5)
  4626. self.effect = {}
  4627. self.effect["backgroundCtrl"] = CheckBox(
  4628. panel, id=wx.ID_ANY, label=_("text background")
  4629. )
  4630. self.effect["backgroundColor"] = ColourPickerCtrl(panel, id=wx.ID_ANY)
  4631. self.effect["highlightCtrl"] = CheckBox(
  4632. panel, id=wx.ID_ANY, label=_("highlight")
  4633. )
  4634. self.effect["highlightColor"] = ColourPickerCtrl(panel, id=wx.ID_ANY)
  4635. self.effect["highlightWidth"] = SpinCtrl(
  4636. panel, id=wx.ID_ANY, size=self.spinCtrlSize, min=0, max=5, initial=1
  4637. )
  4638. self.effect["highlightWidthLabel"] = StaticText(
  4639. panel, id=wx.ID_ANY, label=_("Width (pts):")
  4640. )
  4641. self.effect["borderCtrl"] = CheckBox(
  4642. panel, id=wx.ID_ANY, label=_("text border")
  4643. )
  4644. self.effect["borderColor"] = ColourPickerCtrl(panel, id=wx.ID_ANY)
  4645. self.effect["borderWidth"] = SpinCtrl(
  4646. panel, id=wx.ID_ANY, size=self.spinCtrlSize, min=1, max=25, initial=1
  4647. )
  4648. self.effect["borderWidthLabel"] = StaticText(
  4649. panel, id=wx.ID_ANY, label=_("Width (pts):")
  4650. )
  4651. # set values
  4652. if self.textDict["background"] is None:
  4653. self.textDict["background"] = "none"
  4654. if self.textDict["background"] != "none":
  4655. self.effect["backgroundCtrl"].SetValue(True)
  4656. self.effect["backgroundColor"].SetColour(
  4657. convertRGB(self.textDict["background"])
  4658. )
  4659. else:
  4660. self.effect["backgroundCtrl"].SetValue(False)
  4661. self.effect["backgroundColor"].SetColour(convertRGB("white"))
  4662. if self.textDict["hcolor"] is None:
  4663. self.textDict["hcolor"] = "none"
  4664. if self.textDict["hcolor"] != "none":
  4665. self.effect["highlightCtrl"].SetValue(True)
  4666. self.effect["highlightColor"].SetColour(convertRGB(self.textDict["hcolor"]))
  4667. else:
  4668. self.effect["highlightCtrl"].SetValue(False)
  4669. self.effect["highlightColor"].SetColour(convertRGB("grey"))
  4670. self.effect["highlightWidth"].SetValue(int(float(self.textDict["hwidth"])))
  4671. if self.textDict["border"] is None:
  4672. self.textDict["border"] = "none"
  4673. if self.textDict["border"] != "none":
  4674. self.effect["borderCtrl"].SetValue(True)
  4675. self.effect["borderColor"].SetColour(convertRGB(self.textDict["border"]))
  4676. else:
  4677. self.effect["borderCtrl"].SetValue(False)
  4678. self.effect["borderColor"].SetColour(convertRGB("black"))
  4679. self.effect["borderWidth"].SetValue(int(float(self.textDict["width"])))
  4680. gridBagSizer.Add(
  4681. self.effect["backgroundCtrl"],
  4682. pos=(0, 0),
  4683. flag=wx.ALIGN_CENTER_VERTICAL,
  4684. border=0,
  4685. )
  4686. gridBagSizer.Add(
  4687. self.effect["backgroundColor"],
  4688. pos=(0, 1),
  4689. flag=wx.ALIGN_CENTER_VERTICAL,
  4690. border=0,
  4691. )
  4692. gridBagSizer.Add(
  4693. self.effect["highlightCtrl"],
  4694. pos=(1, 0),
  4695. flag=wx.ALIGN_CENTER_VERTICAL,
  4696. border=0,
  4697. )
  4698. gridBagSizer.Add(
  4699. self.effect["highlightColor"],
  4700. pos=(1, 1),
  4701. flag=wx.ALIGN_CENTER_VERTICAL,
  4702. border=0,
  4703. )
  4704. gridBagSizer.Add(
  4705. self.effect["highlightWidthLabel"],
  4706. pos=(1, 2),
  4707. flag=wx.ALIGN_CENTER_VERTICAL,
  4708. border=0,
  4709. )
  4710. gridBagSizer.Add(
  4711. self.effect["highlightWidth"],
  4712. pos=(1, 3),
  4713. flag=wx.ALIGN_CENTER_VERTICAL,
  4714. border=0,
  4715. )
  4716. gridBagSizer.Add(
  4717. self.effect["borderCtrl"],
  4718. pos=(2, 0),
  4719. flag=wx.ALIGN_CENTER_VERTICAL,
  4720. border=0,
  4721. )
  4722. gridBagSizer.Add(
  4723. self.effect["borderColor"],
  4724. pos=(2, 1),
  4725. flag=wx.ALIGN_CENTER_VERTICAL,
  4726. border=0,
  4727. )
  4728. gridBagSizer.Add(
  4729. self.effect["borderWidthLabel"],
  4730. pos=(2, 2),
  4731. flag=wx.ALIGN_CENTER_VERTICAL,
  4732. border=0,
  4733. )
  4734. gridBagSizer.Add(
  4735. self.effect["borderWidth"],
  4736. pos=(2, 3),
  4737. flag=wx.ALIGN_CENTER_VERTICAL,
  4738. border=0,
  4739. )
  4740. sizer.Add(gridBagSizer, proportion=1, flag=wx.ALL | wx.EXPAND, border=1)
  4741. border.Add(sizer, proportion=0, flag=wx.ALL | wx.EXPAND, border=5)
  4742. self.Bind(ExpandoTextCtrl.EVT_ETC_LAYOUT_NEEDED, self.OnRefit, self.textCtrl)
  4743. self.Bind(wx.EVT_CHECKBOX, self.OnBackground, self.effect["backgroundCtrl"])
  4744. self.Bind(wx.EVT_CHECKBOX, self.OnHighlight, self.effect["highlightCtrl"])
  4745. self.Bind(wx.EVT_CHECKBOX, self.OnBorder, self.effect["borderCtrl"])
  4746. panel.SetSizer(border)
  4747. panel.Fit()
  4748. return panel
  4749. def _positionPanel(self, notebook):
  4750. panel = Panel(parent=notebook, id=wx.ID_ANY, style=wx.TAB_TRAVERSAL)
  4751. notebook.AddPage(page=panel, text=_("Position"))
  4752. border = wx.BoxSizer(wx.VERTICAL)
  4753. box = StaticBox(parent=panel, id=wx.ID_ANY, label=" %s " % _("Position"))
  4754. sizer = wx.StaticBoxSizer(box, wx.HORIZONTAL)
  4755. gridBagSizer = wx.GridBagSizer(hgap=5, vgap=5)
  4756. # Position
  4757. self.AddExtendedPosition(panel, gridBagSizer, self.textDict)
  4758. # offset
  4759. box3 = StaticBox(parent=panel, id=wx.ID_ANY, label=" %s " % _("Offset"))
  4760. sizerO = wx.StaticBoxSizer(box3, wx.VERTICAL)
  4761. gridBagSizerO = wx.GridBagSizer(hgap=5, vgap=5)
  4762. self.xoffLabel = StaticText(panel, id=wx.ID_ANY, label=_("horizontal (pts):"))
  4763. self.yoffLabel = StaticText(panel, id=wx.ID_ANY, label=_("vertical (pts):"))
  4764. self.xoffCtrl = SpinCtrl(
  4765. panel, id=wx.ID_ANY, size=(50, -1), min=-50, max=50, initial=0
  4766. )
  4767. self.yoffCtrl = SpinCtrl(
  4768. panel, id=wx.ID_ANY, size=(50, -1), min=-50, max=50, initial=0
  4769. )
  4770. self.xoffCtrl.SetValue(self.textDict["xoffset"])
  4771. self.yoffCtrl.SetValue(self.textDict["yoffset"])
  4772. gridBagSizerO.Add(
  4773. self.xoffLabel, pos=(0, 0), flag=wx.ALIGN_CENTER_VERTICAL, border=0
  4774. )
  4775. gridBagSizerO.Add(
  4776. self.yoffLabel, pos=(1, 0), flag=wx.ALIGN_CENTER_VERTICAL, border=0
  4777. )
  4778. gridBagSizerO.Add(
  4779. self.xoffCtrl, pos=(0, 1), flag=wx.ALIGN_CENTER_VERTICAL, border=0
  4780. )
  4781. gridBagSizerO.Add(
  4782. self.yoffCtrl, pos=(1, 1), flag=wx.ALIGN_CENTER_VERTICAL, border=0
  4783. )
  4784. sizerO.Add(gridBagSizerO, proportion=1, flag=wx.EXPAND | wx.ALL, border=5)
  4785. gridBagSizer.Add(
  4786. sizerO, pos=(3, 0), flag=wx.ALIGN_CENTER_HORIZONTAL | wx.EXPAND, border=0
  4787. )
  4788. # reference point
  4789. box = StaticBox(
  4790. parent=panel, id=wx.ID_ANY, label=" %s " % _(" Reference point")
  4791. )
  4792. sizerR = wx.StaticBoxSizer(box, wx.VERTICAL)
  4793. flexSizer = wx.FlexGridSizer(rows=3, cols=3, hgap=5, vgap=5)
  4794. ref = []
  4795. for row in ["upper", "center", "lower"]:
  4796. for col in ["left", "center", "right"]:
  4797. ref.append(row + " " + col)
  4798. self.radio = [
  4799. RadioButton(panel, id=wx.ID_ANY, label="", style=wx.RB_GROUP, name=ref[0])
  4800. ]
  4801. self.radio[0].SetValue(False)
  4802. flexSizer.Add(self.radio[0], proportion=0, flag=wx.ALIGN_CENTER, border=0)
  4803. for i in range(1, 9):
  4804. self.radio.append(RadioButton(panel, id=wx.ID_ANY, label="", name=ref[i]))
  4805. self.radio[-1].SetValue(False)
  4806. flexSizer.Add(self.radio[-1], proportion=0, flag=wx.ALIGN_CENTER, border=0)
  4807. self.FindWindowByName(self.textDict["ref"]).SetValue(True)
  4808. flexSizer.AddGrowableCol(0)
  4809. flexSizer.AddGrowableCol(1)
  4810. flexSizer.AddGrowableCol(2)
  4811. sizerR.Add(flexSizer, proportion=1, flag=wx.EXPAND, border=0)
  4812. gridBagSizer.Add(sizerR, pos=(3, 1), flag=wx.ALIGN_LEFT | wx.EXPAND, border=0)
  4813. gridBagSizer.AddGrowableCol(0)
  4814. gridBagSizer.AddGrowableCol(1)
  4815. sizer.Add(
  4816. gridBagSizer, proportion=1, flag=wx.ALIGN_CENTER_VERTICAL | wx.ALL, border=5
  4817. )
  4818. border.Add(sizer, proportion=0, flag=wx.ALL | wx.EXPAND, border=5)
  4819. # rotation
  4820. box = StaticBox(parent=panel, id=wx.ID_ANY, label=" %s " % _("Text rotation"))
  4821. sizer = wx.StaticBoxSizer(box, wx.HORIZONTAL)
  4822. self.rotCtrl = CheckBox(
  4823. panel, id=wx.ID_ANY, label=_("rotate text (counterclockwise)")
  4824. )
  4825. self.rotValue = SpinCtrl(
  4826. panel, wx.ID_ANY, size=(50, -1), min=0, max=360, initial=0
  4827. )
  4828. if self.textDict["rotate"]:
  4829. self.rotValue.SetValue(int(self.textDict["rotate"]))
  4830. self.rotCtrl.SetValue(True)
  4831. else:
  4832. self.rotValue.SetValue(0)
  4833. self.rotCtrl.SetValue(False)
  4834. sizer.Add(
  4835. self.rotCtrl,
  4836. proportion=0,
  4837. flag=wx.ALIGN_CENTER_VERTICAL | wx.ALIGN_LEFT | wx.ALL,
  4838. border=5,
  4839. )
  4840. sizer.Add(
  4841. self.rotValue,
  4842. proportion=0,
  4843. flag=wx.ALIGN_CENTER_VERTICAL | wx.ALIGN_LEFT | wx.ALL,
  4844. border=5,
  4845. )
  4846. border.Add(sizer, proportion=0, flag=wx.ALL | wx.EXPAND, border=5)
  4847. panel.SetSizer(border)
  4848. panel.Fit()
  4849. self.Bind(wx.EVT_RADIOBUTTON, self.OnPositionType, panel.position["toPaper"])
  4850. self.Bind(wx.EVT_RADIOBUTTON, self.OnPositionType, panel.position["toMap"])
  4851. self.Bind(wx.EVT_CHECKBOX, self.OnRotation, self.rotCtrl)
  4852. return panel
  4853. def OnRefit(self, event):
  4854. self.Fit()
  4855. def OnRotation(self, event):
  4856. if self.rotCtrl.GetValue():
  4857. self.rotValue.Enable()
  4858. else:
  4859. self.rotValue.Disable()
  4860. def OnPositionType(self, event):
  4861. if self.positionPanel.position["toPaper"].GetValue():
  4862. for widget in self.gridBagSizerP.GetChildren():
  4863. widget.GetWindow().Enable()
  4864. for widget in self.gridBagSizerM.GetChildren():
  4865. widget.GetWindow().Disable()
  4866. else:
  4867. for widget in self.gridBagSizerM.GetChildren():
  4868. widget.GetWindow().Enable()
  4869. for widget in self.gridBagSizerP.GetChildren():
  4870. widget.GetWindow().Disable()
  4871. def OnBackground(self, event):
  4872. if self.effect["backgroundCtrl"].GetValue():
  4873. self.effect["backgroundColor"].Enable()
  4874. self.update()
  4875. else:
  4876. self.effect["backgroundColor"].Disable()
  4877. def OnHighlight(self, event):
  4878. if self.effect["highlightCtrl"].GetValue():
  4879. self.effect["highlightColor"].Enable()
  4880. self.effect["highlightWidth"].Enable()
  4881. self.effect["highlightWidthLabel"].Enable()
  4882. self.update()
  4883. else:
  4884. self.effect["highlightColor"].Disable()
  4885. self.effect["highlightWidth"].Disable()
  4886. self.effect["highlightWidthLabel"].Disable()
  4887. def OnBorder(self, event):
  4888. if self.effect["borderCtrl"].GetValue():
  4889. self.effect["borderColor"].Enable()
  4890. self.effect["borderWidth"].Enable()
  4891. self.effect["borderWidthLabel"].Enable()
  4892. self.update()
  4893. else:
  4894. self.effect["borderColor"].Disable()
  4895. self.effect["borderWidth"].Disable()
  4896. self.effect["borderWidthLabel"].Disable()
  4897. def update(self):
  4898. # text
  4899. self.textDict["text"] = self.textCtrl.GetValue()
  4900. if not self.textDict["text"]:
  4901. wx.MessageBox(_("No text entered!"), _("Error"))
  4902. return False
  4903. # font
  4904. self.textDict["font"] = self.textPanel.font["fontCtrl"].GetStringSelection()
  4905. self.textDict["fontsize"] = self.textPanel.font["fontSizeCtrl"].GetValue()
  4906. color = self.textPanel.font["colorCtrl"].GetColour()
  4907. self.textDict["color"] = convertRGB(color)
  4908. # effects
  4909. if self.effect["backgroundCtrl"].GetValue():
  4910. background = self.effect["backgroundColor"].GetColour()
  4911. self.textDict["background"] = convertRGB(background)
  4912. else:
  4913. self.textDict["background"] = "none"
  4914. if self.effect["borderCtrl"].GetValue():
  4915. border = self.effect["borderColor"].GetColour()
  4916. self.textDict["border"] = convertRGB(border)
  4917. else:
  4918. self.textDict["border"] = "none"
  4919. self.textDict["width"] = self.effect["borderWidth"].GetValue()
  4920. if self.effect["highlightCtrl"].GetValue():
  4921. highlight = self.effect["highlightColor"].GetColour()
  4922. self.textDict["hcolor"] = convertRGB(highlight)
  4923. else:
  4924. self.textDict["hcolor"] = "none"
  4925. self.textDict["hwidth"] = self.effect["highlightWidth"].GetValue()
  4926. # offset
  4927. self.textDict["xoffset"] = self.xoffCtrl.GetValue()
  4928. self.textDict["yoffset"] = self.yoffCtrl.GetValue()
  4929. # position
  4930. if self.positionPanel.position["toPaper"].GetValue():
  4931. self.textDict["XY"] = True
  4932. currUnit = self.unitConv.findUnit(
  4933. self.positionPanel.units["unitsCtrl"].GetStringSelection()
  4934. )
  4935. self.textDict["unit"] = currUnit
  4936. if self.positionPanel.position["xCtrl"].GetValue():
  4937. x = self.positionPanel.position["xCtrl"].GetValue()
  4938. else:
  4939. x = self.textDict["where"][0]
  4940. if self.positionPanel.position["yCtrl"].GetValue():
  4941. y = self.positionPanel.position["yCtrl"].GetValue()
  4942. else:
  4943. y = self.textDict["where"][1]
  4944. x = self.unitConv.convert(value=float(x), fromUnit=currUnit, toUnit="inch")
  4945. y = self.unitConv.convert(value=float(y), fromUnit=currUnit, toUnit="inch")
  4946. self.textDict["where"] = x, y
  4947. self.textDict["east"], self.textDict["north"] = PaperMapCoordinates(
  4948. self.instruction[self.mapId], x, y, paperToMap=True, env=self.env
  4949. )
  4950. else:
  4951. self.textDict["XY"] = False
  4952. if self.positionPanel.position["eCtrl"].GetValue():
  4953. self.textDict["east"] = self.positionPanel.position["eCtrl"].GetValue()
  4954. else:
  4955. self.textDict["east"] = self.textDict["east"]
  4956. if self.positionPanel.position["nCtrl"].GetValue():
  4957. self.textDict["north"] = self.positionPanel.position["nCtrl"].GetValue()
  4958. else:
  4959. self.textDict["north"] = self.textDict["north"]
  4960. self.textDict["where"] = PaperMapCoordinates(
  4961. mapInstr=self.instruction[self.mapId],
  4962. x=float(self.textDict["east"]),
  4963. y=float(self.textDict["north"]),
  4964. paperToMap=False,
  4965. env=self.env,
  4966. )
  4967. # rotation
  4968. if self.rotCtrl.GetValue():
  4969. self.textDict["rotate"] = self.rotValue.GetValue()
  4970. else:
  4971. self.textDict["rotate"] = None
  4972. # reference point
  4973. for radio in self.radio:
  4974. if radio.GetValue():
  4975. self.textDict["ref"] = radio.GetName()
  4976. if self.id not in self.instruction:
  4977. text = Text(self.id, env=self.env)
  4978. self.instruction.AddInstruction(text)
  4979. self.instruction[self.id].SetInstruction(self.textDict)
  4980. if self.id not in self.parent.objectId:
  4981. self.parent.objectId.append(self.id)
  4982. # self.updateDialog()
  4983. return True
  4984. def updateDialog(self):
  4985. """Update text coordinates, after moving"""
  4986. # XY coordinates
  4987. x, y = self.textDict["where"][:2]
  4988. currUnit = self.unitConv.findUnit(
  4989. self.positionPanel.units["unitsCtrl"].GetStringSelection()
  4990. )
  4991. x = self.unitConv.convert(value=x, fromUnit="inch", toUnit=currUnit)
  4992. y = self.unitConv.convert(value=y, fromUnit="inch", toUnit=currUnit)
  4993. self.positionPanel.position["xCtrl"].SetValue("%5.3f" % x)
  4994. self.positionPanel.position["yCtrl"].SetValue("%5.3f" % y)
  4995. # EN coordinates
  4996. e, n = self.textDict["east"], self.textDict["north"]
  4997. self.positionPanel.position["eCtrl"].SetValue(str(self.textDict["east"]))
  4998. self.positionPanel.position["nCtrl"].SetValue(str(self.textDict["north"]))
  4999. class ImageDialog(PsmapDialog):
  5000. """Dialog for setting image properties.
  5001. It's base dialog for North Arrow dialog.
  5002. """
  5003. def __init__(self, parent, id, settings, env, imagePanelName=_("Image")):
  5004. PsmapDialog.__init__(
  5005. self,
  5006. parent=parent,
  5007. id=id,
  5008. title="Image settings",
  5009. settings=settings,
  5010. env=env,
  5011. )
  5012. self.objectType = ("image",)
  5013. if self.id is not None:
  5014. self.imageObj = self.instruction[self.id]
  5015. self.imageDict = self.instruction[id].GetInstruction()
  5016. else:
  5017. self.id = NewId()
  5018. self.imageObj = self._newObject()
  5019. self.imageDict = self.imageObj.GetInstruction()
  5020. page = self.instruction.FindInstructionByType("page").GetInstruction()
  5021. self.imageDict["where"] = page["Left"], page["Top"]
  5022. map = self.instruction.FindInstructionByType("map")
  5023. if not map:
  5024. map = self.instruction.FindInstructionByType("initMap")
  5025. self.mapId = map.id
  5026. self.imageDict["east"], self.imageDict["north"] = PaperMapCoordinates(
  5027. mapInstr=map,
  5028. x=self.imageDict["where"][0],
  5029. y=self.imageDict["where"][1],
  5030. paperToMap=True,
  5031. env=self.env,
  5032. )
  5033. notebook = Notebook(parent=self, id=wx.ID_ANY, style=wx.BK_DEFAULT)
  5034. self.imagePanelName = imagePanelName
  5035. self.imagePanel = self._imagePanel(notebook)
  5036. self.positionPanel = self._positionPanel(notebook)
  5037. self.OnPositionType(None)
  5038. if self.imageDict["epsfile"]:
  5039. self.imagePanel.image["dir"].SetValue(
  5040. os.path.dirname(self.imageDict["epsfile"])
  5041. )
  5042. else:
  5043. self.imagePanel.image["dir"].SetValue(self._getImageDirectory())
  5044. self.OnDirChanged(None)
  5045. self._layout(notebook)
  5046. def _newObject(self):
  5047. """Create corresponding instruction object"""
  5048. return Image(self.id, self.instruction, env=self.env)
  5049. def _imagePanel(self, notebook):
  5050. panel = Panel(
  5051. parent=notebook, id=wx.ID_ANY, size=(-1, -1), style=wx.TAB_TRAVERSAL
  5052. )
  5053. notebook.AddPage(page=panel, text=self.imagePanelName)
  5054. border = wx.BoxSizer(wx.VERTICAL)
  5055. #
  5056. # choose image
  5057. #
  5058. box = StaticBox(parent=panel, id=wx.ID_ANY, label=" %s " % _("Image"))
  5059. sizer = wx.StaticBoxSizer(box, wx.VERTICAL)
  5060. # choose directory
  5061. panel.image = {}
  5062. if self.imageDict["epsfile"]:
  5063. startDir = os.path.dirname(self.imageDict["epsfile"])
  5064. else:
  5065. startDir = self._getImageDirectory()
  5066. dir = DirBrowseButton(
  5067. parent=panel,
  5068. id=wx.ID_ANY,
  5069. labelText=_("Choose a directory:"),
  5070. dialogTitle=_("Choose a directory with images"),
  5071. buttonText=_("Browse"),
  5072. startDirectory=startDir,
  5073. changeCallback=self.OnDirChanged,
  5074. )
  5075. panel.image["dir"] = dir
  5076. sizer.Add(dir, proportion=0, flag=wx.EXPAND, border=0)
  5077. # image list
  5078. hSizer = wx.BoxSizer(wx.HORIZONTAL)
  5079. imageList = ListBox(parent=panel, id=wx.ID_ANY)
  5080. panel.image["list"] = imageList
  5081. imageList.Bind(wx.EVT_LISTBOX, self.OnImageSelectionChanged)
  5082. hSizer.Add(imageList, proportion=1, flag=wx.EXPAND | wx.RIGHT, border=10)
  5083. # image preview
  5084. vSizer = wx.BoxSizer(wx.VERTICAL)
  5085. self.previewSize = (150, 150)
  5086. img = EmptyImage(*self.previewSize)
  5087. panel.image["preview"] = wx.StaticBitmap(panel, wx.ID_ANY, BitmapFromImage(img))
  5088. vSizer.Add(
  5089. panel.image["preview"], proportion=0, flag=wx.EXPAND | wx.BOTTOM, border=5
  5090. )
  5091. panel.image["sizeInfo"] = StaticText(parent=panel, id=wx.ID_ANY)
  5092. vSizer.Add(
  5093. panel.image["sizeInfo"], proportion=0, flag=wx.ALIGN_CENTER, border=0
  5094. )
  5095. hSizer.Add(vSizer, proportion=0, flag=wx.EXPAND, border=0)
  5096. sizer.Add(hSizer, proportion=1, flag=wx.EXPAND | wx.ALL, border=3)
  5097. epsInfo = StaticText(
  5098. parent=panel, id=wx.ID_ANY, label=_("Note: only EPS format supported")
  5099. )
  5100. sizer.Add(epsInfo, proportion=0, flag=wx.ALL, border=3)
  5101. border.Add(sizer, proportion=0, flag=wx.ALL | wx.EXPAND, border=5)
  5102. #
  5103. # rotation
  5104. #
  5105. box = StaticBox(
  5106. parent=panel, id=wx.ID_ANY, label=" %s " % _("Scale And Rotation")
  5107. )
  5108. sizer = wx.StaticBoxSizer(box, wx.VERTICAL)
  5109. gridSizer = wx.GridBagSizer(hgap=5, vgap=5)
  5110. scaleLabel = StaticText(parent=panel, id=wx.ID_ANY, label=_("Scale:"))
  5111. panel.image["scale"] = FloatSpin(
  5112. panel,
  5113. id=wx.ID_ANY,
  5114. min_val=0,
  5115. max_val=50,
  5116. increment=0.5,
  5117. value=1,
  5118. style=fs.FS_RIGHT,
  5119. )
  5120. panel.image["scale"].SetFormat("%f")
  5121. panel.image["scale"].SetDigits(1)
  5122. if self.imageDict["scale"]:
  5123. value = float(self.imageDict["scale"])
  5124. else:
  5125. value = 0
  5126. panel.image["scale"].SetValue(value)
  5127. gridSizer.Add(scaleLabel, pos=(0, 0), flag=wx.ALIGN_CENTER_VERTICAL)
  5128. gridSizer.Add(panel.image["scale"], pos=(0, 1), flag=wx.ALIGN_CENTER_VERTICAL)
  5129. rotLabel = StaticText(
  5130. parent=panel, id=wx.ID_ANY, label=_("Rotation angle (deg):")
  5131. )
  5132. panel.image["rotate"] = FloatSpin(
  5133. panel,
  5134. id=wx.ID_ANY,
  5135. min_val=0,
  5136. max_val=360,
  5137. increment=0.5,
  5138. value=0,
  5139. style=fs.FS_RIGHT,
  5140. )
  5141. panel.image["rotate"].SetFormat("%f")
  5142. panel.image["rotate"].SetDigits(1)
  5143. panel.image["rotate"].SetToolTip(_("Counterclockwise rotation in degrees"))
  5144. if self.imageDict["rotate"]:
  5145. panel.image["rotate"].SetValue(int(self.imageDict["rotate"]))
  5146. else:
  5147. panel.image["rotate"].SetValue(0)
  5148. gridSizer.Add(rotLabel, pos=(1, 0), flag=wx.ALIGN_CENTER_VERTICAL, border=0)
  5149. gridSizer.Add(panel.image["rotate"], pos=(1, 1), flag=wx.ALIGN_CENTER_VERTICAL)
  5150. self._addConvergence(panel=panel, gridBagSizer=gridSizer)
  5151. sizer.Add(gridSizer, proportion=0, flag=wx.EXPAND | wx.ALL, border=5)
  5152. border.Add(sizer, proportion=0, flag=wx.ALL | wx.EXPAND, border=5)
  5153. panel.SetSizer(border)
  5154. panel.Fit()
  5155. return panel
  5156. def _positionPanel(self, notebook):
  5157. panel = Panel(
  5158. parent=notebook, id=wx.ID_ANY, size=(-1, -1), style=wx.TAB_TRAVERSAL
  5159. )
  5160. notebook.AddPage(page=panel, text=_("Position"))
  5161. border = wx.BoxSizer(wx.VERTICAL)
  5162. #
  5163. # set position
  5164. #
  5165. box = StaticBox(parent=panel, id=wx.ID_ANY, label=" %s " % _("Position"))
  5166. sizer = wx.StaticBoxSizer(box, wx.VERTICAL)
  5167. gridBagSizer = wx.GridBagSizer(hgap=5, vgap=5)
  5168. self.AddExtendedPosition(panel, gridBagSizer, self.imageDict)
  5169. self.Bind(wx.EVT_RADIOBUTTON, self.OnPositionType, panel.position["toPaper"])
  5170. self.Bind(wx.EVT_RADIOBUTTON, self.OnPositionType, panel.position["toMap"])
  5171. gridBagSizer.AddGrowableCol(0)
  5172. gridBagSizer.AddGrowableCol(1)
  5173. sizer.Add(gridBagSizer, proportion=1, flag=wx.ALL, border=5)
  5174. border.Add(sizer, proportion=0, flag=wx.ALL | wx.EXPAND, border=5)
  5175. panel.SetSizer(border)
  5176. panel.Fit()
  5177. return panel
  5178. def OnDirChanged(self, event):
  5179. """Image directory changed"""
  5180. path = self.imagePanel.image["dir"].GetValue()
  5181. try:
  5182. files = os.listdir(path)
  5183. except OSError: # no such directory
  5184. files = []
  5185. imageList = []
  5186. # no setter for startDirectory?
  5187. try:
  5188. self.imagePanel.image["dir"].startDirectory = path
  5189. except AttributeError: # for sure
  5190. pass
  5191. for file in files:
  5192. if os.path.splitext(file)[1].lower() == ".eps":
  5193. imageList.append(file)
  5194. imageList.sort()
  5195. self.imagePanel.image["list"].SetItems(imageList)
  5196. if self.imageDict["epsfile"]:
  5197. file = os.path.basename(self.imageDict["epsfile"])
  5198. self.imagePanel.image["list"].SetStringSelection(file)
  5199. elif imageList:
  5200. self.imagePanel.image["list"].SetSelection(0)
  5201. self.OnImageSelectionChanged(None)
  5202. def OnPositionType(self, event):
  5203. if self.positionPanel.position["toPaper"].GetValue():
  5204. for widget in self.gridBagSizerP.GetChildren():
  5205. widget.GetWindow().Enable()
  5206. for widget in self.gridBagSizerM.GetChildren():
  5207. widget.GetWindow().Disable()
  5208. else:
  5209. for widget in self.gridBagSizerM.GetChildren():
  5210. widget.GetWindow().Enable()
  5211. for widget in self.gridBagSizerP.GetChildren():
  5212. widget.GetWindow().Disable()
  5213. def _getImageDirectory(self):
  5214. """Default image directory"""
  5215. return os.getcwd()
  5216. def _addConvergence(self, panel, gridBagSizer):
  5217. pass
  5218. def OnImageSelectionChanged(self, event):
  5219. """Image selected, show preview and size"""
  5220. if not self.imagePanel.image[
  5221. "dir"
  5222. ]: # event is emitted when closing dialog an it causes error
  5223. return
  5224. if not havePILImage:
  5225. self.DrawWarningText(_("PIL\nmissing"))
  5226. return
  5227. imageName = self.imagePanel.image["list"].GetStringSelection()
  5228. if not imageName:
  5229. self.ClearPreview()
  5230. return
  5231. basePath = self.imagePanel.image["dir"].GetValue()
  5232. file = os.path.join(basePath, imageName)
  5233. if not os.path.exists(file):
  5234. return
  5235. if os.path.splitext(file)[1].lower() == ".eps":
  5236. try:
  5237. pImg = PILImage.open(file)
  5238. if sys.platform == "win32":
  5239. import types
  5240. pImg.load = types.MethodType(loadPSForWindows, pImg)
  5241. img = PilImageToWxImage(pImg)
  5242. except IOError as e:
  5243. GError(message=_("Unable to read file %s") % file)
  5244. self.ClearPreview()
  5245. return
  5246. self.SetSizeInfoLabel(img)
  5247. img = self.ScaleToPreview(img)
  5248. bitmap = img.ConvertToBitmap()
  5249. self.DrawBitmap(bitmap)
  5250. else:
  5251. # TODO: read other formats and convert by PIL to eps
  5252. pass
  5253. def ScaleToPreview(self, img):
  5254. """Scale image to preview size"""
  5255. w = img.GetWidth()
  5256. h = img.GetHeight()
  5257. if w <= self.previewSize[0] and h <= self.previewSize[1]:
  5258. return img
  5259. if w > h:
  5260. newW = self.previewSize[0]
  5261. newH = self.previewSize[0] * h / w
  5262. else:
  5263. newH = self.previewSize[0]
  5264. newW = self.previewSize[0] * w / h
  5265. return img.Scale(newW, newH, wx.IMAGE_QUALITY_HIGH)
  5266. def DrawWarningText(self, warning):
  5267. """Draw text on preview window"""
  5268. buffer = EmptyBitmap(*self.previewSize)
  5269. dc = wx.MemoryDC()
  5270. dc.SelectObject(buffer)
  5271. dc.SetBrush(wx.Brush(wx.Colour(250, 250, 250)))
  5272. dc.Clear()
  5273. extent = dc.GetTextExtent(warning)
  5274. posX = self.previewSize[0] / 2 - extent[0] / 2
  5275. posY = self.previewSize[1] / 2 - extent[1] / 2
  5276. dc.DrawText(warning, posX, posY)
  5277. self.imagePanel.image["preview"].SetBitmap(buffer)
  5278. dc.SelectObject(wx.NullBitmap)
  5279. def DrawBitmap(self, bitmap):
  5280. """Draw bitmap, center it if smaller than preview size"""
  5281. if (
  5282. bitmap.GetWidth() <= self.previewSize[0]
  5283. and bitmap.GetHeight() <= self.previewSize[1]
  5284. ):
  5285. buffer = EmptyBitmap(*self.previewSize)
  5286. dc = wx.MemoryDC()
  5287. dc.SelectObject(buffer)
  5288. dc.SetBrush(dc.GetBrush())
  5289. dc.Clear()
  5290. posX = self.previewSize[0] // 2 - bitmap.GetWidth() // 2
  5291. posY = self.previewSize[1] // 2 - bitmap.GetHeight() // 2
  5292. dc.DrawBitmap(bitmap, posX, posY)
  5293. self.imagePanel.image["preview"].SetBitmap(buffer)
  5294. dc.SelectObject(wx.NullBitmap)
  5295. else:
  5296. self.imagePanel.image["preview"].SetBitmap(bitmap)
  5297. self.imagePanel.Refresh()
  5298. def SetSizeInfoLabel(self, image):
  5299. """Update image size label"""
  5300. self.imagePanel.image["sizeInfo"].SetLabel(
  5301. _("size: %(width)s x %(height)s pts")
  5302. % {"width": image.GetWidth(), "height": image.GetHeight()}
  5303. )
  5304. self.imagePanel.image["sizeInfo"].GetContainingSizer().Layout()
  5305. def ClearPreview(self):
  5306. """Clear preview window"""
  5307. buffer = EmptyBitmap(*self.previewSize)
  5308. dc = wx.MemoryDC()
  5309. dc.SelectObject(buffer)
  5310. dc.SetBrush(wx.WHITE_BRUSH)
  5311. dc.Clear()
  5312. dc.SelectObject(wx.NullBitmap)
  5313. mask = wx.Mask(buffer, wx.WHITE)
  5314. buffer.SetMask(mask)
  5315. self.imagePanel.image["preview"].SetBitmap(buffer)
  5316. def update(self):
  5317. # epsfile
  5318. selected = self.imagePanel.image["list"].GetStringSelection()
  5319. basePath = self.imagePanel.image["dir"].GetValue()
  5320. if not selected:
  5321. GMessage(parent=self, message=_("No image selected."))
  5322. return False
  5323. self.imageDict["epsfile"] = os.path.join(basePath, selected)
  5324. # position
  5325. if self.positionPanel.position["toPaper"].GetValue():
  5326. self.imageDict["XY"] = True
  5327. currUnit = self.unitConv.findUnit(
  5328. self.positionPanel.units["unitsCtrl"].GetStringSelection()
  5329. )
  5330. self.imageDict["unit"] = currUnit
  5331. if self.positionPanel.position["xCtrl"].GetValue():
  5332. x = self.positionPanel.position["xCtrl"].GetValue()
  5333. else:
  5334. x = self.imageDict["where"][0]
  5335. if self.positionPanel.position["yCtrl"].GetValue():
  5336. y = self.positionPanel.position["yCtrl"].GetValue()
  5337. else:
  5338. y = self.imageDict["where"][1]
  5339. x = self.unitConv.convert(value=float(x), fromUnit=currUnit, toUnit="inch")
  5340. y = self.unitConv.convert(value=float(y), fromUnit=currUnit, toUnit="inch")
  5341. self.imageDict["where"] = x, y
  5342. else:
  5343. self.imageDict["XY"] = False
  5344. if self.positionPanel.position["eCtrl"].GetValue():
  5345. e = self.positionPanel.position["eCtrl"].GetValue()
  5346. else:
  5347. self.imageDict["east"] = self.imageDict["east"]
  5348. if self.positionPanel.position["nCtrl"].GetValue():
  5349. n = self.positionPanel.position["nCtrl"].GetValue()
  5350. else:
  5351. self.imageDict["north"] = self.imageDict["north"]
  5352. x, y = PaperMapCoordinates(
  5353. mapInstr=self.instruction[self.mapId],
  5354. x=float(self.imageDict["east"]),
  5355. y=float(self.imageDict["north"]),
  5356. paperToMap=False,
  5357. env=self.env,
  5358. )
  5359. # rotation
  5360. rot = self.imagePanel.image["rotate"].GetValue()
  5361. if rot == 0:
  5362. self.imageDict["rotate"] = None
  5363. else:
  5364. self.imageDict["rotate"] = rot
  5365. # scale
  5366. self.imageDict["scale"] = self.imagePanel.image["scale"].GetValue()
  5367. # scale
  5368. w, h = self.imageObj.GetImageOrigSize(self.imageDict["epsfile"])
  5369. if self.imageDict["rotate"]:
  5370. self.imageDict["size"] = BBoxAfterRotation(w, h, self.imageDict["rotate"])
  5371. else:
  5372. self.imageDict["size"] = w, h
  5373. w = self.unitConv.convert(
  5374. value=self.imageDict["size"][0], fromUnit="point", toUnit="inch"
  5375. )
  5376. h = self.unitConv.convert(
  5377. value=self.imageDict["size"][1], fromUnit="point", toUnit="inch"
  5378. )
  5379. self.imageDict["rect"] = Rect2D(
  5380. x=x,
  5381. y=y,
  5382. width=w * self.imageDict["scale"],
  5383. height=h * self.imageDict["scale"],
  5384. )
  5385. if self.id not in self.instruction:
  5386. image = self._newObject()
  5387. self.instruction.AddInstruction(image)
  5388. self.instruction[self.id].SetInstruction(self.imageDict)
  5389. if self.id not in self.parent.objectId:
  5390. self.parent.objectId.append(self.id)
  5391. return True
  5392. def updateDialog(self):
  5393. """Update text coordinates, after moving"""
  5394. # XY coordinates
  5395. x, y = self.imageDict["where"][:2]
  5396. currUnit = self.unitConv.findUnit(
  5397. self.positionPanel.units["unitsCtrl"].GetStringSelection()
  5398. )
  5399. x = self.unitConv.convert(value=x, fromUnit="inch", toUnit=currUnit)
  5400. y = self.unitConv.convert(value=y, fromUnit="inch", toUnit=currUnit)
  5401. self.positionPanel.position["xCtrl"].SetValue("%5.3f" % x)
  5402. self.positionPanel.position["yCtrl"].SetValue("%5.3f" % y)
  5403. # EN coordinates
  5404. e, n = self.imageDict["east"], self.imageDict["north"]
  5405. self.positionPanel.position["eCtrl"].SetValue(str(self.imageDict["east"]))
  5406. self.positionPanel.position["nCtrl"].SetValue(str(self.imageDict["north"]))
  5407. class NorthArrowDialog(ImageDialog):
  5408. def __init__(self, parent, id, settings, env):
  5409. ImageDialog.__init__(
  5410. self,
  5411. parent=parent,
  5412. id=id,
  5413. settings=settings,
  5414. imagePanelName=_("North Arrow"),
  5415. env=env,
  5416. )
  5417. self.objectType = ("northArrow",)
  5418. self.SetTitle(_("North Arrow settings"))
  5419. def _newObject(self):
  5420. return NorthArrow(self.id, self.instruction, env=self.env)
  5421. def _getImageDirectory(self):
  5422. gisbase = os.getenv("GISBASE")
  5423. return os.path.join(gisbase, "etc", "paint", "decorations")
  5424. def _addConvergence(self, panel, gridBagSizer):
  5425. convergence = Button(parent=panel, id=wx.ID_ANY, label=_("Compute convergence"))
  5426. gridBagSizer.Add(
  5427. convergence, pos=(1, 2), flag=wx.ALIGN_CENTER_VERTICAL | wx.EXPAND
  5428. )
  5429. convergence.Bind(wx.EVT_BUTTON, self.OnConvergence)
  5430. panel.image["convergence"] = convergence
  5431. def OnConvergence(self, event):
  5432. ret = RunCommand("g.region", read=True, flags="nug", env=self.env)
  5433. if ret:
  5434. convergence = float(ret.strip().split("=")[1])
  5435. if convergence < 0:
  5436. self.imagePanel.image["rotate"].SetValue(abs(convergence))
  5437. else:
  5438. self.imagePanel.image["rotate"].SetValue(360 - convergence)
  5439. class PointDialog(PsmapDialog):
  5440. """Dialog for setting point properties."""
  5441. def __init__(
  5442. self, parent, id, settings, env, coordinates=None, pointPanelName=_("Point")
  5443. ):
  5444. PsmapDialog.__init__(
  5445. self,
  5446. parent=parent,
  5447. id=id,
  5448. title="Point settings",
  5449. settings=settings,
  5450. env=env,
  5451. )
  5452. self.objectType = ("point",)
  5453. if self.id is not None:
  5454. self.pointObj = self.instruction[self.id]
  5455. self.pointDict = self.instruction[id].GetInstruction()
  5456. else:
  5457. self.id = NewId()
  5458. self.pointObj = Point(self.id, env=self.env)
  5459. self.pointDict = self.pointObj.GetInstruction()
  5460. self.pointDict["where"] = coordinates
  5461. self.defaultDict = self.pointObj.defaultInstruction
  5462. mapObj = self.instruction.FindInstructionByType("map")
  5463. if not mapObj:
  5464. mapObj = self.instruction.FindInstructionByType("initMap")
  5465. self.mapId = mapObj.id
  5466. self.pointDict["east"], self.pointDict["north"] = PaperMapCoordinates(
  5467. mapInstr=mapObj,
  5468. x=self.pointDict["where"][0],
  5469. y=self.pointDict["where"][1],
  5470. paperToMap=True,
  5471. env=self.env,
  5472. )
  5473. notebook = Notebook(parent=self, id=wx.ID_ANY, style=wx.BK_DEFAULT)
  5474. self.pointPanelName = pointPanelName
  5475. self.pointPanel = self._pointPanel(notebook)
  5476. self.positionPanel = self._positionPanel(notebook)
  5477. self.OnPositionType(None)
  5478. self._layout(notebook)
  5479. def _pointPanel(self, notebook):
  5480. panel = Panel(
  5481. parent=notebook, id=wx.ID_ANY, size=(-1, -1), style=wx.TAB_TRAVERSAL
  5482. )
  5483. notebook.AddPage(page=panel, text=self.pointPanelName)
  5484. border = wx.BoxSizer(wx.VERTICAL)
  5485. #
  5486. # choose image
  5487. #
  5488. box = StaticBox(parent=panel, id=wx.ID_ANY, label=" %s " % _("Symbol"))
  5489. sizer = wx.StaticBoxSizer(box, wx.HORIZONTAL)
  5490. gridSizer = wx.GridBagSizer(hgap=5, vgap=5)
  5491. gridSizer.Add(
  5492. StaticText(parent=panel, id=wx.ID_ANY, label=_("Select symbol:")),
  5493. pos=(0, 0),
  5494. flag=wx.ALIGN_CENTER_VERTICAL,
  5495. )
  5496. self.symbolLabel = StaticText(
  5497. parent=panel, id=wx.ID_ANY, label=self.pointDict["symbol"]
  5498. )
  5499. gridSizer.Add(self.symbolLabel, pos=(0, 1), flag=wx.ALIGN_CENTER_VERTICAL)
  5500. bitmap = wx.Bitmap(
  5501. os.path.join(globalvar.SYMBDIR, self.pointDict["symbol"]) + ".png"
  5502. )
  5503. self.symbolButton = BitmapButton(panel, id=wx.ID_ANY, bitmap=bitmap)
  5504. self.symbolButton.Bind(wx.EVT_BUTTON, self.OnSymbolSelection)
  5505. gridSizer.Add(self.symbolButton, pos=(0, 2), flag=wx.ALIGN_CENTER_VERTICAL)
  5506. self.noteLabel = StaticText(
  5507. parent=panel,
  5508. id=wx.ID_ANY,
  5509. label=_(
  5510. "Note: Selected symbol is not displayed\n"
  5511. "in draft mode (only in preview mode)"
  5512. ),
  5513. )
  5514. gridSizer.Add(
  5515. self.noteLabel, pos=(1, 0), span=(1, 2), flag=wx.ALIGN_CENTER_VERTICAL
  5516. )
  5517. gridSizer.AddGrowableCol(1)
  5518. sizer.Add(gridSizer, proportion=1, flag=wx.EXPAND | wx.ALL, border=5)
  5519. border.Add(sizer, proportion=0, flag=wx.ALL | wx.EXPAND, border=5)
  5520. #
  5521. # outline/fill color
  5522. #
  5523. # outline
  5524. box = StaticBox(parent=panel, id=wx.ID_ANY, label=" %s " % _("Color"))
  5525. sizer = wx.StaticBoxSizer(box, wx.VERTICAL)
  5526. gridSizer = wx.GridBagSizer(hgap=5, vgap=5)
  5527. outlineLabel = StaticText(parent=panel, id=wx.ID_ANY, label=_("Outline color:"))
  5528. self.outlineColorCtrl = ColourPickerCtrl(panel, id=wx.ID_ANY)
  5529. self.outlineTranspCtrl = CheckBox(panel, id=wx.ID_ANY, label=_("transparent"))
  5530. if self.pointDict["color"] != "none":
  5531. self.outlineTranspCtrl.SetValue(False)
  5532. self.outlineColorCtrl.SetColour(convertRGB(self.pointDict["color"]))
  5533. else:
  5534. self.outlineTranspCtrl.SetValue(True)
  5535. self.outlineColorCtrl.SetColour(convertRGB(self.defaultDict["color"]))
  5536. gridSizer.Add(outlineLabel, pos=(0, 0), flag=wx.ALIGN_CENTER_VERTICAL)
  5537. gridSizer.Add(self.outlineColorCtrl, pos=(0, 1), flag=wx.ALIGN_CENTER_VERTICAL)
  5538. gridSizer.Add(self.outlineTranspCtrl, pos=(0, 2), flag=wx.ALIGN_CENTER_VERTICAL)
  5539. fillLabel = StaticText(parent=panel, id=wx.ID_ANY, label=_("Fill color:"))
  5540. self.fillColorCtrl = ColourPickerCtrl(panel, id=wx.ID_ANY)
  5541. self.fillTranspCtrl = CheckBox(panel, id=wx.ID_ANY, label=_("transparent"))
  5542. if self.pointDict["fcolor"] != "none":
  5543. self.fillTranspCtrl.SetValue(False)
  5544. self.fillColorCtrl.SetColour(convertRGB(self.pointDict["fcolor"]))
  5545. else:
  5546. self.fillTranspCtrl.SetValue(True)
  5547. self.fillColorCtrl.SetColour(convertRGB(self.defaultDict["fcolor"]))
  5548. gridSizer.Add(fillLabel, pos=(1, 0), flag=wx.ALIGN_CENTER_VERTICAL)
  5549. gridSizer.Add(self.fillColorCtrl, pos=(1, 1), flag=wx.ALIGN_CENTER_VERTICAL)
  5550. gridSizer.Add(self.fillTranspCtrl, pos=(1, 2), flag=wx.ALIGN_CENTER_VERTICAL)
  5551. sizer.Add(gridSizer, proportion=0, flag=wx.EXPAND | wx.ALL, border=5)
  5552. border.Add(sizer, proportion=0, flag=wx.ALL | wx.EXPAND, border=5)
  5553. #
  5554. # size and rotation
  5555. #
  5556. # size
  5557. box = StaticBox(
  5558. parent=panel, id=wx.ID_ANY, label=" %s " % _("Size and Rotation")
  5559. )
  5560. sizer = wx.StaticBoxSizer(box, wx.VERTICAL)
  5561. gridSizer = wx.GridBagSizer(hgap=5, vgap=5)
  5562. sizeLabel = StaticText(parent=panel, id=wx.ID_ANY, label=_("Size (pt):"))
  5563. self.sizeCtrl = SpinCtrl(panel, id=wx.ID_ANY, size=self.spinCtrlSize)
  5564. self.sizeCtrl.SetToolTip(_("Symbol size in points"))
  5565. self.sizeCtrl.SetValue(self.pointDict["size"])
  5566. gridSizer.Add(sizeLabel, pos=(0, 0), flag=wx.ALIGN_CENTER_VERTICAL)
  5567. gridSizer.Add(self.sizeCtrl, pos=(0, 1), flag=wx.ALIGN_CENTER_VERTICAL)
  5568. # rotation
  5569. rotLabel = StaticText(
  5570. parent=panel, id=wx.ID_ANY, label=_("Rotation angle (deg):")
  5571. )
  5572. self.rotCtrl = FloatSpin(
  5573. panel,
  5574. id=wx.ID_ANY,
  5575. min_val=-360,
  5576. max_val=360,
  5577. increment=1,
  5578. value=0,
  5579. style=fs.FS_RIGHT,
  5580. )
  5581. self.rotCtrl.SetFormat("%f")
  5582. self.rotCtrl.SetDigits(1)
  5583. self.rotCtrl.SetToolTip(_("Counterclockwise rotation in degrees"))
  5584. self.rotCtrl.SetValue(float(self.pointDict["rotate"]))
  5585. gridSizer.Add(rotLabel, pos=(1, 0), flag=wx.ALIGN_CENTER_VERTICAL, border=0)
  5586. gridSizer.Add(self.rotCtrl, pos=(1, 1), flag=wx.ALIGN_CENTER_VERTICAL)
  5587. sizer.Add(gridSizer, proportion=0, flag=wx.EXPAND | wx.ALL, border=5)
  5588. border.Add(sizer, proportion=0, flag=wx.ALL | wx.EXPAND, border=5)
  5589. panel.SetSizer(border)
  5590. panel.Fit()
  5591. return panel
  5592. def _positionPanel(self, notebook):
  5593. panel = Panel(
  5594. parent=notebook, id=wx.ID_ANY, size=(-1, -1), style=wx.TAB_TRAVERSAL
  5595. )
  5596. notebook.AddPage(page=panel, text=_("Position"))
  5597. border = wx.BoxSizer(wx.VERTICAL)
  5598. #
  5599. # set position
  5600. #
  5601. box = StaticBox(parent=panel, id=wx.ID_ANY, label=" %s " % _("Position"))
  5602. sizer = wx.StaticBoxSizer(box, wx.VERTICAL)
  5603. gridBagSizer = wx.GridBagSizer(hgap=5, vgap=5)
  5604. self.AddExtendedPosition(panel, gridBagSizer, self.pointDict)
  5605. self.Bind(wx.EVT_RADIOBUTTON, self.OnPositionType, panel.position["toPaper"])
  5606. self.Bind(wx.EVT_RADIOBUTTON, self.OnPositionType, panel.position["toMap"])
  5607. gridBagSizer.AddGrowableCol(0)
  5608. gridBagSizer.AddGrowableCol(1)
  5609. sizer.Add(gridBagSizer, proportion=1, flag=wx.ALL, border=5)
  5610. border.Add(sizer, proportion=0, flag=wx.ALL | wx.EXPAND, border=5)
  5611. panel.SetSizer(border)
  5612. panel.Fit()
  5613. return panel
  5614. def OnPositionType(self, event):
  5615. if self.positionPanel.position["toPaper"].GetValue():
  5616. for widget in self.gridBagSizerP.GetChildren():
  5617. widget.GetWindow().Enable()
  5618. for widget in self.gridBagSizerM.GetChildren():
  5619. widget.GetWindow().Disable()
  5620. else:
  5621. for widget in self.gridBagSizerM.GetChildren():
  5622. widget.GetWindow().Enable()
  5623. for widget in self.gridBagSizerP.GetChildren():
  5624. widget.GetWindow().Disable()
  5625. def OnSymbolSelection(self, event):
  5626. dlg = SymbolDialog(
  5627. self,
  5628. symbolPath=globalvar.SYMBDIR,
  5629. currentSymbol=self.symbolLabel.GetLabel(),
  5630. )
  5631. if dlg.ShowModal() == wx.ID_OK:
  5632. img = dlg.GetSelectedSymbolPath()
  5633. name = dlg.GetSelectedSymbolName()
  5634. self.symbolButton.SetBitmapLabel(wx.Bitmap(img + ".png"))
  5635. self.symbolLabel.SetLabel(name)
  5636. dlg.Destroy()
  5637. def update(self):
  5638. # symbol
  5639. self.pointDict["symbol"] = self.symbolLabel.GetLabel()
  5640. # position
  5641. if self.positionPanel.position["toPaper"].GetValue():
  5642. self.pointDict["XY"] = True
  5643. currUnit = self.unitConv.findUnit(
  5644. self.positionPanel.units["unitsCtrl"].GetStringSelection()
  5645. )
  5646. self.pointDict["unit"] = currUnit
  5647. if self.positionPanel.position["xCtrl"].GetValue():
  5648. x = self.positionPanel.position["xCtrl"].GetValue()
  5649. else:
  5650. x = self.pointDict["where"][0]
  5651. if self.positionPanel.position["yCtrl"].GetValue():
  5652. y = self.positionPanel.position["yCtrl"].GetValue()
  5653. else:
  5654. y = self.pointDict["where"][1]
  5655. x = self.unitConv.convert(value=float(x), fromUnit=currUnit, toUnit="inch")
  5656. y = self.unitConv.convert(value=float(y), fromUnit=currUnit, toUnit="inch")
  5657. self.pointDict["where"] = x, y
  5658. else:
  5659. self.pointDict["XY"] = False
  5660. if self.positionPanel.position["eCtrl"].GetValue():
  5661. e = self.positionPanel.position["eCtrl"].GetValue()
  5662. else:
  5663. self.pointDict["east"] = self.pointDict["east"]
  5664. if self.positionPanel.position["nCtrl"].GetValue():
  5665. n = self.positionPanel.position["nCtrl"].GetValue()
  5666. else:
  5667. self.pointDict["north"] = self.pointDict["north"]
  5668. x, y = PaperMapCoordinates(
  5669. mapInstr=self.instruction[self.mapId],
  5670. x=float(self.pointDict["east"]),
  5671. y=float(self.pointDict["north"]),
  5672. paperToMap=False,
  5673. env=self.env,
  5674. )
  5675. # rotation
  5676. self.pointDict["rotate"] = self.rotCtrl.GetValue()
  5677. # size
  5678. self.pointDict["size"] = self.sizeCtrl.GetValue()
  5679. w = h = self.unitConv.convert(
  5680. value=self.pointDict["size"], fromUnit="point", toUnit="inch"
  5681. )
  5682. # outline color
  5683. if self.outlineTranspCtrl.GetValue():
  5684. self.pointDict["color"] = "none"
  5685. else:
  5686. self.pointDict["color"] = convertRGB(self.outlineColorCtrl.GetColour())
  5687. # fill color
  5688. if self.fillTranspCtrl.GetValue():
  5689. self.pointDict["fcolor"] = "none"
  5690. else:
  5691. self.pointDict["fcolor"] = convertRGB(self.fillColorCtrl.GetColour())
  5692. self.pointDict["rect"] = Rect2D(x=x - w / 2, y=y - h / 2, width=w, height=h)
  5693. if self.id not in self.instruction:
  5694. point = Point(self.id, env=self.env)
  5695. self.instruction.AddInstruction(point)
  5696. self.instruction[self.id].SetInstruction(self.pointDict)
  5697. if self.id not in self.parent.objectId:
  5698. self.parent.objectId.append(self.id)
  5699. return True
  5700. def updateDialog(self):
  5701. """Update text coordinates, after moving"""
  5702. # XY coordinates
  5703. x, y = self.pointDict["where"][:2]
  5704. currUnit = self.unitConv.findUnit(
  5705. self.positionPanel.units["unitsCtrl"].GetStringSelection()
  5706. )
  5707. x = self.unitConv.convert(value=x, fromUnit="inch", toUnit=currUnit)
  5708. y = self.unitConv.convert(value=y, fromUnit="inch", toUnit=currUnit)
  5709. self.positionPanel.position["xCtrl"].SetValue("%5.3f" % x)
  5710. self.positionPanel.position["yCtrl"].SetValue("%5.3f" % y)
  5711. # EN coordinates
  5712. e, n = self.pointDict["east"], self.pointDict["north"]
  5713. self.positionPanel.position["eCtrl"].SetValue(str(self.pointDict["east"]))
  5714. self.positionPanel.position["nCtrl"].SetValue(str(self.pointDict["north"]))
  5715. class RectangleDialog(PsmapDialog):
  5716. def __init__(self, parent, id, settings, env, type="rectangle", coordinates=None):
  5717. """
  5718. :param coordinates: begin and end point coordinate (wx.Point, wx.Point)
  5719. """
  5720. if type == "rectangle":
  5721. title = _("Rectangle settings")
  5722. else:
  5723. title = _("Line settings")
  5724. PsmapDialog.__init__(
  5725. self, parent=parent, id=id, title=title, settings=settings, env=env
  5726. )
  5727. self.objectType = (type,)
  5728. if self.id is not None:
  5729. self.rectObj = self.instruction[self.id]
  5730. self.rectDict = self.rectObj.GetInstruction()
  5731. else:
  5732. self.id = NewId()
  5733. if type == "rectangle":
  5734. self.rectObj = Rectangle(self.id, env=self.env)
  5735. else:
  5736. self.rectObj = Line(self.id, env=self.env)
  5737. self.rectDict = self.rectObj.GetInstruction()
  5738. self.rectDict["rect"] = Rect2DPP(coordinates[0], coordinates[1])
  5739. self.rectDict["where"] = coordinates
  5740. self.defaultDict = self.rectObj.defaultInstruction
  5741. self.panel = self._rectPanel()
  5742. self._layout(self.panel)
  5743. def _rectPanel(self):
  5744. panel = Panel(parent=self, id=wx.ID_ANY, style=wx.TAB_TRAVERSAL)
  5745. border = wx.BoxSizer(wx.VERTICAL)
  5746. # color
  5747. box = StaticBox(parent=panel, id=wx.ID_ANY, label=" %s " % _("Color"))
  5748. sizer = wx.StaticBoxSizer(box, wx.VERTICAL)
  5749. gridSizer = wx.GridBagSizer(hgap=5, vgap=5)
  5750. outlineLabel = StaticText(parent=panel, id=wx.ID_ANY, label=_("Outline color:"))
  5751. self.outlineColorCtrl = ColourPickerCtrl(panel, id=wx.ID_ANY)
  5752. self.outlineTranspCtrl = CheckBox(panel, id=wx.ID_ANY, label=_("transparent"))
  5753. if self.rectDict["color"] != "none":
  5754. self.outlineTranspCtrl.SetValue(False)
  5755. self.outlineColorCtrl.SetColour(convertRGB(self.rectDict["color"]))
  5756. else:
  5757. self.outlineTranspCtrl.SetValue(True)
  5758. self.outlineColorCtrl.SetColour(convertRGB(self.defaultDict["color"]))
  5759. # transparent outline makes sense only for rectangle
  5760. if self.objectType == ("line",):
  5761. self.outlineTranspCtrl.Hide()
  5762. gridSizer.Add(outlineLabel, pos=(0, 0), flag=wx.ALIGN_CENTER_VERTICAL)
  5763. gridSizer.Add(self.outlineColorCtrl, pos=(0, 1), flag=wx.ALIGN_CENTER_VERTICAL)
  5764. gridSizer.Add(self.outlineTranspCtrl, pos=(0, 2), flag=wx.ALIGN_CENTER_VERTICAL)
  5765. # fill color only in rectangle
  5766. if self.objectType == ("rectangle",):
  5767. fillLabel = StaticText(parent=panel, id=wx.ID_ANY, label=_("Fill color:"))
  5768. self.fillColorCtrl = ColourPickerCtrl(panel, id=wx.ID_ANY)
  5769. self.fillTranspCtrl = CheckBox(panel, id=wx.ID_ANY, label=_("transparent"))
  5770. if self.rectDict["fcolor"] != "none":
  5771. self.fillTranspCtrl.SetValue(False)
  5772. self.fillColorCtrl.SetColour(convertRGB(self.rectDict["fcolor"]))
  5773. else:
  5774. self.fillTranspCtrl.SetValue(True)
  5775. self.fillColorCtrl.SetColour(wx.WHITE)
  5776. gridSizer.Add(fillLabel, pos=(1, 0), flag=wx.ALIGN_CENTER_VERTICAL)
  5777. gridSizer.Add(self.fillColorCtrl, pos=(1, 1), flag=wx.ALIGN_CENTER_VERTICAL)
  5778. gridSizer.Add(
  5779. self.fillTranspCtrl, pos=(1, 2), flag=wx.ALIGN_CENTER_VERTICAL
  5780. )
  5781. sizer.Add(gridSizer, proportion=1, flag=wx.EXPAND | wx.ALL, border=5)
  5782. border.Add(sizer, proportion=0, flag=wx.ALL | wx.EXPAND, border=5)
  5783. gridSizer = wx.GridBagSizer(hgap=5, vgap=5)
  5784. # width
  5785. box = StaticBox(parent=panel, id=wx.ID_ANY, label=" %s " % _("Line style"))
  5786. sizer = wx.StaticBoxSizer(box, wx.VERTICAL)
  5787. widthLabel = StaticText(parent=panel, id=wx.ID_ANY, label=_("Line width:"))
  5788. self.widthCtrl = FloatSpin(
  5789. panel,
  5790. id=wx.ID_ANY,
  5791. min_val=0,
  5792. max_val=50,
  5793. increment=1,
  5794. value=0,
  5795. style=fs.FS_RIGHT,
  5796. )
  5797. self.widthCtrl.SetFormat("%f")
  5798. self.widthCtrl.SetDigits(1)
  5799. self.widthCtrl.SetToolTip(_("Line width in points"))
  5800. self.widthCtrl.SetValue(float(self.rectDict["width"]))
  5801. gridSizer.Add(widthLabel, pos=(0, 0), flag=wx.ALIGN_CENTER_VERTICAL)
  5802. gridSizer.Add(self.widthCtrl, pos=(0, 1), flag=wx.ALIGN_CENTER_VERTICAL)
  5803. sizer.Add(gridSizer, proportion=1, flag=wx.EXPAND | wx.ALL, border=5)
  5804. border.Add(sizer, proportion=0, flag=wx.ALL | wx.EXPAND, border=5)
  5805. panel.SetSizer(border)
  5806. return panel
  5807. def update(self):
  5808. mapInstr = self.instruction.FindInstructionByType("map")
  5809. if not mapInstr:
  5810. mapInstr = self.instruction.FindInstructionByType("initMap")
  5811. self.mapId = mapInstr.id
  5812. point1 = self.rectDict["where"][0]
  5813. point2 = self.rectDict["where"][1]
  5814. self.rectDict["east1"], self.rectDict["north1"] = PaperMapCoordinates(
  5815. mapInstr=mapInstr, x=point1[0], y=point1[1], paperToMap=True, env=self.env
  5816. )
  5817. self.rectDict["east2"], self.rectDict["north2"] = PaperMapCoordinates(
  5818. mapInstr=mapInstr, x=point2[0], y=point2[1], paperToMap=True, env=self.env
  5819. )
  5820. # width
  5821. self.rectDict["width"] = self.widthCtrl.GetValue()
  5822. # outline color
  5823. if self.outlineTranspCtrl.GetValue():
  5824. self.rectDict["color"] = "none"
  5825. else:
  5826. self.rectDict["color"] = convertRGB(self.outlineColorCtrl.GetColour())
  5827. # fill color
  5828. if self.objectType == ("rectangle",):
  5829. if self.fillTranspCtrl.GetValue():
  5830. self.rectDict["fcolor"] = "none"
  5831. else:
  5832. self.rectDict["fcolor"] = convertRGB(self.fillColorCtrl.GetColour())
  5833. if self.id not in self.instruction:
  5834. if self.objectType == ("rectangle",):
  5835. rect = Rectangle(self.id, env=self.env)
  5836. else:
  5837. rect = Line(self.id, env=self.env)
  5838. self.instruction.AddInstruction(rect)
  5839. self.instruction[self.id].SetInstruction(self.rectDict)
  5840. if self.id not in self.parent.objectId:
  5841. self.parent.objectId.append(self.id)
  5842. self.updateDialog()
  5843. return True
  5844. def updateDialog(self):
  5845. """Update text coordinates, after moving"""
  5846. pass
  5847. class LabelsDialog(PsmapDialog):
  5848. def __init__(self, parent, id, settings, env):
  5849. PsmapDialog.__init__(
  5850. self,
  5851. parent=parent,
  5852. id=id,
  5853. title=_("Vector labels"),
  5854. settings=settings,
  5855. env=env,
  5856. )
  5857. self.objectType = ("labels",)
  5858. if self.id is not None:
  5859. self.labels = self.instruction[self.id]
  5860. else:
  5861. self.id = NewId()
  5862. self.labels = Labels(self.id, env=self.env)
  5863. self.labelsDict = self.labels.GetInstruction()
  5864. self.panel = self._labelPanel()
  5865. self._layout(self.panel)
  5866. def _labelPanel(self):
  5867. panel = Panel(parent=self, id=wx.ID_ANY, style=wx.TAB_TRAVERSAL)
  5868. border = wx.BoxSizer(wx.VERTICAL)
  5869. box = StaticBox(
  5870. parent=panel,
  5871. id=wx.ID_ANY,
  5872. label=" %s " % _("Vector label files created beforehand by v.label module"),
  5873. )
  5874. sizer = wx.StaticBoxSizer(box, wx.VERTICAL)
  5875. self.select = Select(
  5876. parent=panel, multiple=True, type="label", fullyQualified=False
  5877. )
  5878. self.select.SetValue(",".join(self.labelsDict["labels"]))
  5879. self.select.SetFocus()
  5880. sizer.Add(self.select, proportion=1, flag=wx.EXPAND | wx.ALL, border=5)
  5881. helpText = StaticText(
  5882. panel, id=wx.ID_ANY, label=_("You can select multiple label files.")
  5883. )
  5884. helpText.SetForegroundColour(
  5885. wx.SystemSettings.GetColour(wx.SYS_COLOUR_GRAYTEXT)
  5886. )
  5887. sizer.Add(helpText, proportion=0, flag=wx.EXPAND | wx.LEFT | wx.RIGHT, border=5)
  5888. border.Add(sizer, proportion=1, flag=wx.EXPAND | wx.ALL, border=5)
  5889. panel.SetSizer(border)
  5890. return panel
  5891. def update(self):
  5892. value = self.select.GetValue()
  5893. if not value:
  5894. self.labelsDict["labels"] = []
  5895. else:
  5896. self.labelsDict["labels"] = value.split(",")
  5897. if self.id not in self.instruction:
  5898. labels = Labels(self.id, env=self.env)
  5899. self.instruction.AddInstruction(labels)
  5900. self.instruction[self.id].SetInstruction(self.labelsDict)
  5901. return True