preferences.py 70 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824
  1. """
  2. @package preferences
  3. @brief User preferences dialog
  4. Sets default display font, etc.
  5. Classes:
  6. - PreferencesDialog
  7. - DefaultFontDialog
  8. - MapsetAccess
  9. (C) 2007-2009 by the GRASS Development Team
  10. This program is free software under the GNU General Public
  11. License (>=v2). Read the file COPYING that comes with GRASS
  12. for details.
  13. @author Michael Barton (Arizona State University)
  14. Martin Landa <landa.martin gmail.com>
  15. """
  16. import os
  17. import sys
  18. import copy
  19. import stat
  20. if os.name in ('posix', 'mac'):
  21. import pwd
  22. import wx
  23. import wx.lib.filebrowsebutton as filebrowse
  24. import wx.lib.colourselect as csel
  25. import wx.lib.mixins.listctrl as listmix
  26. from wx.lib.wordwrap import wordwrap
  27. import grass
  28. import gcmd
  29. import utils
  30. import globalvar
  31. from debug import Debug as Debug
  32. class Settings:
  33. """Generic class where to store settings"""
  34. def __init__(self):
  35. #
  36. # settings filename
  37. #
  38. self.fileName = ".grasswx7"
  39. self.filePath = None
  40. #
  41. # key/value separator
  42. #
  43. self.sep = ';'
  44. #
  45. # default settings
  46. #
  47. self.defaultSettings = {
  48. #
  49. # general
  50. #
  51. 'general': {
  52. # use default window layout (layer manager, displays, ...)
  53. 'defWindowPos' : {
  54. 'enabled' : False,
  55. 'dim' : ''
  56. },
  57. # expand/collapse element list
  58. 'elementListExpand' : {
  59. 'selection' : 0
  60. },
  61. },
  62. 'manager' : {
  63. # show opacity level widget
  64. 'changeOpacityLevel' : {
  65. 'enabled' : False
  66. },
  67. # ask when removing layer from layer tree
  68. 'askOnRemoveLayer' : {
  69. 'enabled' : True
  70. },
  71. # ask when quiting wxGUI or closing display
  72. 'askOnQuit' : {
  73. 'enabled' : True
  74. },
  75. },
  76. #
  77. # display
  78. #
  79. 'display': {
  80. 'font' : {
  81. 'type' : '',
  82. 'encoding': 'ISO-8859-1',
  83. },
  84. 'driver': {
  85. 'type': 'cairo'
  86. },
  87. 'compResolution' : {
  88. 'enabled' : False
  89. },
  90. 'autoRendering': {
  91. 'enabled' : False
  92. },
  93. 'statusbarMode': {
  94. 'selection' : 0
  95. },
  96. 'bgcolor': {
  97. 'color' : (255, 255, 255, 255),
  98. }
  99. },
  100. #
  101. # advanced
  102. #
  103. 'advanced' : {
  104. 'settingsFile' : {
  105. 'type' : 'home'
  106. }, # home, gisdbase, location, mapset
  107. 'iconTheme' : {
  108. 'type' : 'grass2'
  109. }, # grass2, grass, silk
  110. },
  111. #
  112. # Attribute Table Manager
  113. #
  114. 'atm' : {
  115. 'highlight' : {
  116. 'color' : (255, 255, 0, 255),
  117. 'width' : 2
  118. },
  119. 'leftDbClick' : {
  120. 'selection' : 1 # draw selected
  121. },
  122. 'askOnDeleteRec' : {
  123. 'enabled' : True
  124. },
  125. 'keycolumn' : {
  126. 'value' : 'cat'
  127. },
  128. 'encoding' : {
  129. 'value' : '',
  130. }
  131. },
  132. #
  133. # Command
  134. #
  135. 'cmd': {
  136. 'overwrite' : {
  137. 'enabled' : False
  138. },
  139. 'closeDlg' : {
  140. 'enabled' : False
  141. },
  142. 'verbosity' : {
  143. 'selection' : 'grassenv'
  144. },
  145. # d.rast
  146. 'rasterOpaque' : {
  147. 'enabled' : False
  148. },
  149. # d.vect
  150. 'showType': {
  151. 'point' : {
  152. 'enabled' : True
  153. },
  154. 'line' : {
  155. 'enabled' : True
  156. },
  157. 'centroid' : {
  158. 'enabled' : True
  159. },
  160. 'boundary' : {
  161. 'enabled' : True
  162. },
  163. 'area' : {
  164. 'enabled' : True
  165. },
  166. 'face' : {
  167. 'enabled' : True
  168. },
  169. },
  170. 'addNewLayer' : {
  171. 'enabled' : False
  172. },
  173. },
  174. #
  175. # Workspace
  176. #
  177. 'workspace' : {
  178. 'posDisplay' : {
  179. 'enabled' : False
  180. },
  181. 'posManager' : {
  182. 'enabled' : False
  183. },
  184. },
  185. #
  186. # vdigit
  187. #
  188. 'vdigit' : {
  189. # symbology
  190. 'symbol' : {
  191. 'highlight' : {
  192. 'enabled' : None,
  193. 'color' : (255, 255, 0, 255)
  194. }, # yellow
  195. 'highlightDupl' : {
  196. 'enabled' : None,
  197. 'color' : (255, 72, 0, 255)
  198. }, # red
  199. 'point' : {
  200. 'enabled' : True,
  201. 'color' : (0, 0, 0, 255)
  202. }, # black
  203. 'line' : {
  204. 'enabled' : True,
  205. 'color' : (0, 0, 0, 255)
  206. }, # black
  207. 'boundaryNo' : {
  208. 'enabled' : True,
  209. 'color' : (126, 126, 126, 255)
  210. }, # grey
  211. 'boundaryOne' : {
  212. 'enabled' : True,
  213. 'color' : (0, 255, 0, 255)
  214. }, # green
  215. 'boundaryTwo' : {
  216. 'enabled' : True,
  217. 'color' : (255, 135, 0, 255)
  218. }, # orange
  219. 'centroidIn' : {
  220. 'enabled' : True,
  221. 'color' : (0, 0, 255, 255)
  222. }, # blue
  223. 'centroidOut' : {
  224. 'enabled' : True,
  225. 'color' : (165, 42, 42, 255)
  226. }, # brown
  227. 'centroidDup' : {
  228. 'enabled' : True,
  229. 'color' : (156, 62, 206, 255)
  230. }, # violet
  231. 'nodeOne' : {
  232. 'enabled' : True,
  233. 'color' : (255, 0, 0, 255)
  234. }, # red
  235. 'nodeTwo' : {
  236. 'enabled' : True,
  237. 'color' : (0, 86, 45, 255)
  238. }, # dark green
  239. 'vertex' : {
  240. 'enabled' : False,
  241. 'color' : (255, 20, 147, 255)
  242. }, # deep pink
  243. 'area' : {
  244. 'enabled' : False,
  245. 'color' : (217, 255, 217, 255)
  246. }, # green
  247. 'direction' : {
  248. 'enabled' : False,
  249. 'color' : (255, 0, 0, 255)
  250. }, # red
  251. },
  252. # display
  253. 'lineWidth' : {
  254. 'value' : 2,
  255. 'units' : 'screen pixels'
  256. },
  257. # snapping
  258. 'snapping' : {
  259. 'value' : 10,
  260. 'units' : 'screen pixels'
  261. },
  262. 'snapToVertex' : {
  263. 'enabled' : False
  264. },
  265. # digitize new record
  266. 'addRecord' : {
  267. 'enabled' : True
  268. },
  269. 'layer' :{
  270. 'value' : 1
  271. },
  272. 'category' : {
  273. 'value' : 1
  274. },
  275. 'categoryMode' : {
  276. 'selection' : 0
  277. },
  278. # delete existing feature(s)
  279. 'delRecord' : {
  280. 'enabled' : True
  281. },
  282. # query tool
  283. 'query' : {
  284. 'selection' : 0,
  285. 'box' : True
  286. },
  287. 'queryLength' : {
  288. 'than-selection' : 0,
  289. 'thresh' : 0
  290. },
  291. 'queryDangle' : {
  292. 'than-selection' : 0,
  293. 'thresh' : 0
  294. },
  295. # select feature (point, line, centroid, boundary)
  296. 'selectType': {
  297. 'point' : {
  298. 'enabled' : True
  299. },
  300. 'line' : {
  301. 'enabled' : True
  302. },
  303. 'centroid' : {
  304. 'enabled' : True
  305. },
  306. 'boundary' : {
  307. 'enabled' : True
  308. },
  309. },
  310. 'selectThresh' : {
  311. 'value' : 10,
  312. 'units' : 'screen pixels'
  313. },
  314. 'checkForDupl' : {
  315. 'enabled' : False
  316. },
  317. 'selectInside' : {
  318. 'enabled' : False
  319. },
  320. # exit
  321. 'saveOnExit' : {
  322. 'enabled' : False,
  323. },
  324. # break lines on intersection
  325. 'breakLines' : {
  326. 'enabled' : False,
  327. },
  328. },
  329. 'profile': {
  330. 'raster0' : {
  331. 'pcolor' : (0, 0, 255, 255), # profile line color
  332. 'pwidth' : 1, # profile line width
  333. 'pstyle' : 'solid', # profile line pen style
  334. },
  335. 'raster1' : {
  336. 'pcolor' : (255, 0, 0, 255),
  337. 'pwidth' : 1,
  338. 'pstyle' : 'solid',
  339. },
  340. 'raster2' : {
  341. 'pcolor' : (0, 255, 0, 255),
  342. 'pwidth' : 1,
  343. 'pstyle' : 'solid',
  344. },
  345. 'font' : {
  346. 'titleSize' : 12,
  347. 'axisSize' : 11,
  348. 'legendSize' : 10,
  349. },
  350. 'marker' : {
  351. 'color' : (0, 0, 0, 255),
  352. 'fill' : 'transparent',
  353. 'size' : 2,
  354. 'type' : 'triangle',
  355. 'legend' : _('Segment break'),
  356. },
  357. 'grid' : {
  358. 'color' : (200, 200, 200, 255),
  359. 'enabled' : True,
  360. },
  361. 'x-axis' : {
  362. 'type' : 'auto', # axis format
  363. 'min' : 0, # axis min for custom axis range
  364. 'max': 0, # axis max for custom axis range
  365. 'log' : False,
  366. },
  367. 'y-axis' : {
  368. 'type' : 'auto', # axis format
  369. 'min' : 0, # axis min for custom axis range
  370. 'max': 0, # axis max for custom axis range
  371. 'log' : False,
  372. },
  373. 'legend' : {
  374. 'enabled' : True
  375. },
  376. },
  377. 'georect' : {
  378. 'symbol' : {
  379. 'color' : (0, 0, 255, 255),
  380. 'width' : 2,
  381. },
  382. },
  383. 'nviz' : {
  384. 'view' : {
  385. 'persp' : {
  386. 'value' : 40,
  387. 'step' : 5,
  388. },
  389. 'pos' : {
  390. 'x' : 0.85,
  391. 'y' : 0.85,
  392. },
  393. 'height' : {
  394. 'step' : 100,
  395. },
  396. 'twist' : {
  397. 'value' : 0,
  398. 'step' : 5,
  399. },
  400. 'z-exag' : {
  401. 'value': 1,
  402. 'step' : 1,
  403. },
  404. },
  405. 'surface' : {
  406. 'shine': {
  407. 'map' : False,
  408. 'value' : 60.0,
  409. },
  410. 'color' : {
  411. 'map' : True,
  412. 'value' : (0, 0, 0, 255), # constant: black
  413. },
  414. 'draw' : {
  415. 'wire-color' : (136, 136, 136, 255),
  416. 'mode' : 1, # fine
  417. 'style' : 1, # surface
  418. 'shading' : 1, # gouraud
  419. 'res-fine' : 6,
  420. 'res-coarse' : 9,
  421. },
  422. 'position' : {
  423. 'x' : 0,
  424. 'y' : 0,
  425. 'z' : 0,
  426. },
  427. },
  428. 'vector' : {
  429. 'lines' : {
  430. 'show' : False,
  431. 'width' : 2,
  432. 'color' : (0, 0, 255, 255), # blue
  433. 'flat' : False,
  434. 'height' : 0,
  435. },
  436. 'points' : {
  437. 'show' : False,
  438. 'size' : 100,
  439. 'width' : 2,
  440. 'marker' : 2,
  441. 'color' : (0, 0, 255, 255), # blue
  442. 'height' : 0,
  443. }
  444. },
  445. 'volume' : {
  446. 'color' : {
  447. 'map' : True,
  448. 'value' : (0, 0, 0, 255), # constant: black
  449. },
  450. 'draw' : {
  451. 'mode' : 0, # isosurfaces
  452. 'shading' : 1, # gouraud
  453. 'resolution' : 3, # polygon resolution
  454. },
  455. 'shine': {
  456. 'map' : False,
  457. 'value' : 60.0,
  458. },
  459. },
  460. 'settings': {
  461. 'general' : {
  462. 'bgcolor' : (255, 255, 255, 255), # white
  463. },
  464. },
  465. },
  466. }
  467. #
  468. # user settings
  469. #
  470. self.userSettings = copy.deepcopy(self.defaultSettings)
  471. try:
  472. self.ReadSettingsFile()
  473. except gcmd.SettingsError, e:
  474. print >> sys.stderr, e.message
  475. #
  476. # internal settings (based on user settings)
  477. #
  478. self.internalSettings = {}
  479. for group in self.userSettings.keys():
  480. self.internalSettings[group] = {}
  481. for key in self.userSettings[group].keys():
  482. self.internalSettings[group][key] = {}
  483. # self.internalSettings['general']["mapsetPath"]['value'] = self.GetMapsetPath()
  484. self.internalSettings['general']['elementListExpand']['choices'] = (_("Collapse all except PERMANENT and current"),
  485. _("Collapse all except PERMANENT"),
  486. _("Collapse all"),
  487. _("Expand all"))
  488. self.internalSettings['atm']['leftDbClick']['choices'] = (_('Edit selected record'),
  489. _('Display selected'))
  490. self.internalSettings['advanced']['settingsFile']['choices'] = ('home',
  491. 'gisdbase',
  492. 'location',
  493. 'mapset')
  494. self.internalSettings['advanced']['iconTheme']['choices'] = ('grass',
  495. 'grass2',
  496. 'silk')
  497. self.internalSettings['cmd']['verbosity']['choices'] = ('grassenv',
  498. 'verbose',
  499. 'quiet')
  500. self.internalSettings['display']['driver']['choices'] = ['cairo', 'png']
  501. self.internalSettings['display']['statusbarMode']['choices'] = globalvar.MAP_DISPLAY_STATUSBAR_MODE
  502. self.internalSettings['nviz']['view'] = {}
  503. self.internalSettings['nviz']['view']['twist'] = {}
  504. self.internalSettings['nviz']['view']['twist']['min'] = -180
  505. self.internalSettings['nviz']['view']['twist']['max'] = 180
  506. self.internalSettings['nviz']['view']['persp'] = {}
  507. self.internalSettings['nviz']['view']['persp']['min'] = 1
  508. self.internalSettings['nviz']['view']['persp']['max'] = 100
  509. self.internalSettings['nviz']['view']['height'] = {}
  510. self.internalSettings['nviz']['view']['height']['value'] = -1
  511. self.internalSettings['nviz']['vector'] = {}
  512. self.internalSettings['nviz']['vector']['points'] = {}
  513. self.internalSettings['nviz']['vector']['points']['marker'] = ("x",
  514. _("box"),
  515. _("sphere"),
  516. _("cube"),
  517. _("diamond"),
  518. _("dtree"),
  519. _("ctree"),
  520. _("aster"),
  521. _("gyro"),
  522. _("histogram"))
  523. self.internalSettings['vdigit']['bgmap'] = {}
  524. self.internalSettings['vdigit']['bgmap']['value'] = ''
  525. def ReadSettingsFile(self, settings=None):
  526. """Reads settings file (mapset, location, gisdbase)"""
  527. if settings is None:
  528. settings = self.userSettings
  529. # look for settings file
  530. # -> mapser
  531. # -> location
  532. # -> gisdbase
  533. gisenv = grass.gisenv()
  534. gisdbase = gisenv['GISDBASE']
  535. location_name = gisenv['LOCATION_NAME']
  536. mapset_name = gisenv['MAPSET']
  537. mapset_file = os.path.join(gisdbase, location_name, mapset_name, self.fileName)
  538. location_file = os.path.join(gisdbase, location_name, self.fileName)
  539. gisdbase_file = os.path.join(gisdbase, self.fileName)
  540. home_file = os.path.join(os.path.expanduser("~"), self.fileName) # MS Windows fix ?
  541. if os.path.isfile(mapset_file):
  542. self.filePath = mapset_file
  543. elif os.path.isfile(location_file):
  544. self.filePath = location_file
  545. elif os.path.isfile(gisdbase_file):
  546. self.filePath = gisdbase_file
  547. elif os.path.isfile(home_file):
  548. self.filePath = home_file
  549. if self.filePath:
  550. self.__ReadFile(self.filePath, settings)
  551. # set environment variables
  552. os.environ["GRASS_FONT"] = self.Get(group='display',
  553. key='font', subkey='type')
  554. os.environ["GRASS_ENCODING"] = self.Get(group='display',
  555. key='font', subkey='encoding')
  556. def __ReadFile(self, filename, settings=None):
  557. """Read settings from file to dict"""
  558. if settings is None:
  559. settings = self.userSettings
  560. try:
  561. file = open(filename, "r")
  562. line = ''
  563. for line in file.readlines():
  564. line = line.rstrip('%s' % os.linesep)
  565. group, key = line.split(self.sep)[0:2]
  566. kv = line.split(self.sep)[2:]
  567. subkeyMaster = None
  568. if len(kv) % 2 != 0: # multiple (e.g. nviz)
  569. subkeyMaster = kv[0]
  570. del kv[0]
  571. idx = 0
  572. while idx < len(kv):
  573. if subkeyMaster:
  574. subkey = [subkeyMaster, kv[idx]]
  575. else:
  576. subkey = kv[idx]
  577. value = kv[idx+1]
  578. value = self.__parseValue(value, read=True)
  579. self.Append(settings, group, key, subkey, value)
  580. idx += 2
  581. except ValueError, e:
  582. print >> sys.stderr, _("Error: Reading settings from file <%(file)s> failed.\n"
  583. " Details: %(detail)s\n"
  584. " Line: '%(line)s'") % { 'file' : filename,
  585. 'detail' : e,
  586. 'line' : line }
  587. file.close()
  588. file.close()
  589. def SaveToFile(self, settings=None):
  590. """Save settings to the file"""
  591. if settings is None:
  592. settings = self.userSettings
  593. loc = self.Get(group='advanced', key='settingsFile', subkey='type')
  594. home = os.path.expanduser("~") # MS Windows fix ?
  595. gisenv = grass.gisenv()
  596. gisdbase = gisenv['GISDBASE']
  597. location_name = gisenv['LOCATION_NAME']
  598. mapset_name = gisenv['MAPSET']
  599. filePath = None
  600. if loc == 'home':
  601. filePath = os.path.join(home, self.fileName)
  602. elif loc == 'gisdbase':
  603. filePath = os.path.join(gisdbase, self.fileName)
  604. elif loc == 'location':
  605. filePath = os.path.join(gisdbase, location_name, self.fileName)
  606. elif loc == 'mapset':
  607. filePath = os.path.join(gisdbase, location_name, mapset_name, self.fileName)
  608. if filePath is None:
  609. raise gcmd.SettingsError(_('Uknown settings file location.'))
  610. try:
  611. file = open(filePath, "w")
  612. for group in settings.keys():
  613. for key in settings[group].keys():
  614. file.write('%s%s%s%s' % (group, self.sep, key, self.sep))
  615. subkeys = settings[group][key].keys()
  616. for idx in range(len(subkeys)):
  617. value = settings[group][key][subkeys[idx]]
  618. if type(value) == type({}):
  619. if idx > 0:
  620. file.write('%s%s%s%s%s' % (os.linesep, group, self.sep, key, self.sep))
  621. file.write('%s%s' % (subkeys[idx], self.sep))
  622. kvalues = settings[group][key][subkeys[idx]].keys()
  623. srange = range(len(kvalues))
  624. for sidx in srange:
  625. svalue = self.__parseValue(settings[group][key][subkeys[idx]][kvalues[sidx]])
  626. file.write('%s%s%s' % (kvalues[sidx], self.sep,
  627. svalue))
  628. if sidx < len(kvalues) - 1:
  629. file.write('%s' % self.sep)
  630. else:
  631. value = self.__parseValue(settings[group][key][subkeys[idx]])
  632. file.write('%s%s%s' % (subkeys[idx], self.sep, value))
  633. if idx < len(subkeys) - 1:
  634. file.write('%s' % self.sep)
  635. file.write('%s' % os.linesep)
  636. except IOError, e:
  637. raise gcmd.SettingsError(message=e)
  638. except StandardError, e:
  639. raise gcmd.SettingsError(message=_('Writing settings to file <%(file)s> failed.'
  640. '\n\nDetails: %(detail)s') % { 'file' : filePath,
  641. 'detail' : e })
  642. file.close()
  643. return filePath
  644. def __parseValue(self, value, read=False):
  645. """Parse value to be store in settings file"""
  646. if read: # -> read settings (cast values)
  647. if value == 'True':
  648. value = True
  649. elif value == 'False':
  650. value = False
  651. elif value == 'None':
  652. value = None
  653. elif ':' in value: # -> color
  654. value = tuple(map(int, value.split(':')))
  655. else:
  656. try:
  657. value = int(value)
  658. except ValueError:
  659. try:
  660. value = float(value)
  661. except ValueError:
  662. pass
  663. else: # -> write settings
  664. if type(value) == type(()): # -> color
  665. value = str(value[0]) + ':' +\
  666. str(value[1]) + ':' + \
  667. str(value[2])
  668. return value
  669. def Get(self, group, key=None, subkey=None, internal=False):
  670. """Get value by key/subkey
  671. Raise KeyError if key is not found
  672. @param group settings group
  673. @param key (value, None)
  674. @param subkey (value, list or None)
  675. @param internal use internal settings instead
  676. @return value
  677. """
  678. if internal is True:
  679. settings = self.internalSettings
  680. else:
  681. settings = self.userSettings
  682. try:
  683. if subkey is None:
  684. if key is None:
  685. return settings[group]
  686. else:
  687. return settings[group][key]
  688. else:
  689. if type(subkey) == type([]) or \
  690. type(subkey) == type(()):
  691. return settings[group][key][subkey[0]][subkey[1]]
  692. else:
  693. return settings[group][key][subkey]
  694. except KeyError:
  695. #raise gcmd.SettingsError("%s %s:%s:%s." % (_("Unable to get value"),
  696. # group, key, subkey))
  697. print >> sys.stderr, "Settings: unable to get value '%s:%s:%s'\n" % \
  698. (group, key, subkey)
  699. def Set(self, group, value, key=None, subkey=None, internal=False):
  700. """Set value of key/subkey
  701. Raise KeyError if group/key is not found
  702. @param group settings group
  703. @param key key (value, None)
  704. @param subkey subkey (value, list or None)
  705. @param value value
  706. @param internal use internal settings instead
  707. """
  708. if internal is True:
  709. settings = self.internalSettings
  710. else:
  711. settings = self.userSettings
  712. try:
  713. if subkey is None:
  714. if key is None:
  715. settings[group] = value
  716. else:
  717. settings[group][key] = value
  718. else:
  719. if type(subkey) == type([]):
  720. settings[group][key][subkey[0]][subkey[1]] = value
  721. else:
  722. settings[group][key][subkey] = value
  723. except KeyError:
  724. raise gcmd.SettingsError("%s '%s:%s:%s'" % (_("Unable to set "), group, key, subkey))
  725. def Append(self, dict, group, key, subkey, value):
  726. """Set value of key/subkey
  727. Create group/key/subkey if not exists
  728. @param dict settings dictionary to use
  729. @param group settings group
  730. @param key key
  731. @param subkey subkey (value or list)
  732. @param value value
  733. """
  734. if not dict.has_key(group):
  735. dict[group] = {}
  736. if not dict[group].has_key(key):
  737. dict[group][key] = {}
  738. if type(subkey) == type([]):
  739. # TODO: len(subkey) > 2
  740. if not dict[group][key].has_key(subkey[0]):
  741. dict[group][key][subkey[0]] = {}
  742. dict[group][key][subkey[0]][subkey[1]] = value
  743. else:
  744. dict[group][key][subkey] = value
  745. def GetDefaultSettings(self):
  746. """Get default user settings"""
  747. return self.defaultSettings
  748. globalSettings = Settings()
  749. class PreferencesDialog(wx.Dialog):
  750. """User preferences dialog"""
  751. def __init__(self, parent, title=_("User GUI settings"),
  752. settings=globalSettings,
  753. style=wx.DEFAULT_DIALOG_STYLE | wx.RESIZE_BORDER):
  754. self.parent = parent # GMFrame
  755. self.title = title
  756. wx.Dialog.__init__(self, parent=parent, id=wx.ID_ANY, title=title,
  757. style=style, size=(-1, -1))
  758. self.settings = settings
  759. # notebook
  760. notebook = wx.Notebook(parent=self, id=wx.ID_ANY, style=wx.BK_DEFAULT)
  761. # dict for window ids
  762. self.winId = {}
  763. # create notebook pages
  764. self.__CreateGeneralPage(notebook)
  765. self.__CreateDisplayPage(notebook)
  766. self.__CreateCmdPage(notebook)
  767. self.__CreateAttributeManagerPage(notebook)
  768. self.__CreateWorkspacePage(notebook)
  769. self.__CreateAdvancedPage(notebook)
  770. # buttons
  771. btnDefault = wx.Button(self, wx.ID_ANY, _("Set to default"))
  772. btnSave = wx.Button(self, wx.ID_SAVE)
  773. btnApply = wx.Button(self, wx.ID_APPLY)
  774. btnCancel = wx.Button(self, wx.ID_CANCEL)
  775. btnSave.SetDefault()
  776. # bindigs
  777. btnDefault.Bind(wx.EVT_BUTTON, self.OnDefault)
  778. btnDefault.SetToolTipString(_("Revert settings to default and apply changes"))
  779. btnApply.Bind(wx.EVT_BUTTON, self.OnApply)
  780. btnApply.SetToolTipString(_("Apply changes for the current session"))
  781. btnSave.Bind(wx.EVT_BUTTON, self.OnSave)
  782. btnSave.SetToolTipString(_("Apply and save changes to user settings file (default for next sessions)"))
  783. btnSave.SetDefault()
  784. btnCancel.Bind(wx.EVT_BUTTON, self.OnCancel)
  785. btnCancel.SetToolTipString(_("Close dialog and ignore changes"))
  786. # sizers
  787. btnSizer = wx.BoxSizer(wx.HORIZONTAL)
  788. btnSizer.Add(item=btnDefault, proportion=1,
  789. flag=wx.ALL, border=5)
  790. btnStdSizer = wx.StdDialogButtonSizer()
  791. btnStdSizer.AddButton(btnCancel)
  792. btnStdSizer.AddButton(btnSave)
  793. btnStdSizer.AddButton(btnApply)
  794. btnStdSizer.Realize()
  795. mainSizer = wx.BoxSizer(wx.VERTICAL)
  796. mainSizer.Add(item=notebook, proportion=1, flag=wx.EXPAND | wx.ALL, border=5)
  797. mainSizer.Add(item=btnSizer, proportion=0,
  798. flag=wx.EXPAND, border=0)
  799. mainSizer.Add(item=btnStdSizer, proportion=0,
  800. flag=wx.EXPAND | wx.ALL | wx.ALIGN_RIGHT, border=5)
  801. self.SetSizer(mainSizer)
  802. mainSizer.Fit(self)
  803. self.SetMinSize(self.GetBestSize())
  804. self.SetSize((500, 375))
  805. def __CreateGeneralPage(self, notebook):
  806. """Create notebook page for general settings"""
  807. panel = wx.Panel(parent=notebook, id=wx.ID_ANY)
  808. notebook.AddPage(page=panel, text=_("General"))
  809. border = wx.BoxSizer(wx.VERTICAL)
  810. box = wx.StaticBox (parent=panel, id=wx.ID_ANY, label=" %s " % _("General settings"))
  811. sizer = wx.StaticBoxSizer(box, wx.VERTICAL)
  812. gridSizer = wx.GridBagSizer (hgap=3, vgap=3)
  813. gridSizer.AddGrowableCol(0)
  814. #
  815. # expand element list
  816. #
  817. row = 0
  818. gridSizer.Add(item=wx.StaticText(parent=panel, id=wx.ID_ANY,
  819. label=_("Element list:")),
  820. flag=wx.ALIGN_LEFT |
  821. wx.ALIGN_CENTER_VERTICAL,
  822. pos=(row, 0))
  823. elementList = wx.Choice(parent=panel, id=wx.ID_ANY,
  824. choices=self.settings.Get(group='general', key='elementListExpand',
  825. subkey='choices', internal=True),
  826. name="GetSelection")
  827. elementList.SetSelection(self.settings.Get(group='general', key='elementListExpand',
  828. subkey='selection'))
  829. self.winId['general:elementListExpand:selection'] = elementList.GetId()
  830. gridSizer.Add(item=elementList,
  831. flag=wx.ALIGN_RIGHT |
  832. wx.ALIGN_CENTER_VERTICAL,
  833. pos=(row, 1))
  834. #
  835. # default window layout
  836. #
  837. row += 1
  838. defaultPos = wx.CheckBox(parent=panel, id=wx.ID_ANY,
  839. label=_("Save current window layout as default"),
  840. name='IsChecked')
  841. defaultPos.SetValue(self.settings.Get(group='general', key='defWindowPos', subkey='enabled'))
  842. defaultPos.SetToolTip(wx.ToolTip (_("Save current position and size of Layer Manager window and opened "
  843. "Map Display window(s) and use as default for next sessions.")))
  844. self.winId['general:defWindowPos:enabled'] = defaultPos.GetId()
  845. gridSizer.Add(item=defaultPos,
  846. pos=(row, 0), span=(1, 2))
  847. sizer.Add(item=gridSizer, proportion=1, flag=wx.ALL | wx.EXPAND, border=5)
  848. border.Add(item=sizer, proportion=0, flag=wx.ALL | wx.EXPAND, border=3)
  849. #
  850. # Layer Manager settings
  851. #
  852. box = wx.StaticBox (parent=panel, id=wx.ID_ANY, label=" %s " % _("Layer Manager settings"))
  853. sizer = wx.StaticBoxSizer(box, wx.VERTICAL)
  854. gridSizer = wx.GridBagSizer (hgap=3, vgap=3)
  855. gridSizer.AddGrowableCol(0)
  856. #
  857. # ask when removing map layer from layer tree
  858. #
  859. row = 0
  860. askOnRemoveLayer = wx.CheckBox(parent=panel, id=wx.ID_ANY,
  861. label=_("Ask when removing map layer from layer tree"),
  862. name='IsChecked')
  863. askOnRemoveLayer.SetValue(self.settings.Get(group='manager', key='askOnRemoveLayer', subkey='enabled'))
  864. self.winId['manager:askOnRemoveLayer:enabled'] = askOnRemoveLayer.GetId()
  865. gridSizer.Add(item=askOnRemoveLayer,
  866. pos=(row, 0), span=(1, 2))
  867. row += 1
  868. askOnQuit = wx.CheckBox(parent=panel, id=wx.ID_ANY,
  869. label=_("Ask when quiting wxGUI or closing display"),
  870. name='IsChecked')
  871. askOnQuit.SetValue(self.settings.Get(group='manager', key='askOnQuit', subkey='enabled'))
  872. self.winId['manager:askOnQuit:enabled'] = askOnQuit.GetId()
  873. gridSizer.Add(item=askOnQuit,
  874. pos=(row, 0), span=(1, 2))
  875. sizer.Add(item=gridSizer, proportion=1, flag=wx.ALL | wx.EXPAND, border=5)
  876. border.Add(item=sizer, proportion=0, flag=wx.LEFT | wx.RIGHT | wx.BOTTOM | wx.EXPAND, border=3)
  877. panel.SetSizer(border)
  878. return panel
  879. def __CreateDisplayPage(self, notebook):
  880. """Create notebook page for display settings"""
  881. panel = wx.Panel(parent=notebook, id=wx.ID_ANY)
  882. notebook.AddPage(page=panel, text=_("Display"))
  883. border = wx.BoxSizer(wx.VERTICAL)
  884. box = wx.StaticBox (parent=panel, id=wx.ID_ANY, label=" %s " % _("Font settings"))
  885. sizer = wx.StaticBoxSizer(box, wx.VERTICAL)
  886. gridSizer = wx.GridBagSizer (hgap=3, vgap=3)
  887. gridSizer.AddGrowableCol(0)
  888. #
  889. # font settings
  890. #
  891. row = 0
  892. gridSizer.Add(item=wx.StaticText(parent=panel, id=wx.ID_ANY,
  893. label=_("Default font for GRASS displays:")),
  894. flag=wx.ALIGN_LEFT |
  895. wx.ALIGN_CENTER_VERTICAL,
  896. pos=(row, 0))
  897. fontButton = wx.Button(parent=panel, id=wx.ID_ANY,
  898. label=_("Set font"), size=(100, -1))
  899. gridSizer.Add(item=fontButton,
  900. flag=wx.ALIGN_RIGHT |
  901. wx.ALIGN_CENTER_VERTICAL,
  902. pos=(row, 1))
  903. sizer.Add(item=gridSizer, proportion=1, flag=wx.ALL | wx.EXPAND, border=5)
  904. border.Add(item=sizer, proportion=0, flag=wx.ALL | wx.EXPAND, border=3)
  905. box = wx.StaticBox (parent=panel, id=wx.ID_ANY, label=" %s " % _("Default display settings"))
  906. sizer = wx.StaticBoxSizer(box, wx.VERTICAL)
  907. gridSizer = wx.GridBagSizer (hgap=3, vgap=3)
  908. gridSizer.AddGrowableCol(0)
  909. #
  910. # display driver
  911. #
  912. row = 0
  913. gridSizer.Add(item=wx.StaticText(parent=panel, id=wx.ID_ANY,
  914. label=_("Display driver:")),
  915. flag=wx.ALIGN_LEFT |
  916. wx.ALIGN_CENTER_VERTICAL,
  917. pos=(row, 0))
  918. listOfDrivers = self.settings.Get(group='display', key='driver', subkey='choices', internal=True)
  919. driver = wx.Choice(parent=panel, id=wx.ID_ANY, size=(150, -1),
  920. choices=listOfDrivers,
  921. name="GetStringSelection")
  922. driver.SetStringSelection(self.settings.Get(group='display', key='driver', subkey='type'))
  923. self.winId['display:driver:type'] = driver.GetId()
  924. gridSizer.Add(item=driver,
  925. flag=wx.ALIGN_RIGHT,
  926. pos=(row, 1))
  927. #
  928. # Statusbar mode
  929. #
  930. row += 1
  931. gridSizer.Add(item=wx.StaticText(parent=panel, id=wx.ID_ANY,
  932. label=_("Statusbar mode:")),
  933. flag=wx.ALIGN_LEFT |
  934. wx.ALIGN_CENTER_VERTICAL,
  935. pos=(row, 0))
  936. listOfModes = self.settings.Get(group='display', key='statusbarMode', subkey='choices', internal=True)
  937. statusbarMode = wx.Choice(parent=panel, id=wx.ID_ANY, size=(150, -1),
  938. choices=listOfModes,
  939. name="GetSelection")
  940. statusbarMode.SetSelection(self.settings.Get(group='display', key='statusbarMode', subkey='selection'))
  941. self.winId['display:statusbarMode:selection'] = statusbarMode.GetId()
  942. gridSizer.Add(item=statusbarMode,
  943. flag=wx.ALIGN_RIGHT,
  944. pos=(row, 1))
  945. #
  946. # Background color
  947. #
  948. row += 1
  949. gridSizer.Add(item=wx.StaticText(parent=panel, id=wx.ID_ANY,
  950. label=_("Background color:")),
  951. flag=wx.ALIGN_LEFT |
  952. wx.ALIGN_CENTER_VERTICAL,
  953. pos=(row, 0))
  954. bgColor = csel.ColourSelect(parent=panel, id=wx.ID_ANY,
  955. colour=self.settings.Get(group='display', key='bgcolor', subkey='color'),
  956. size=(35, 35))
  957. bgColor.SetName('GetColour')
  958. self.winId['display:bgcolor:color'] = bgColor.GetId()
  959. gridSizer.Add(item=bgColor,
  960. flag=wx.ALIGN_RIGHT,
  961. pos=(row, 1))
  962. #
  963. # Use computation resolution
  964. #
  965. row += 1
  966. compResolution = wx.CheckBox(parent=panel, id=wx.ID_ANY,
  967. label=_("Constrain display resolution to computational settings"),
  968. name="IsChecked")
  969. compResolution.SetValue(self.settings.Get(group='display', key='compResolution', subkey='enabled'))
  970. self.winId['display:compResolution:enabled'] = compResolution.GetId()
  971. gridSizer.Add(item=compResolution,
  972. pos=(row, 0), span=(1, 2))
  973. #
  974. # auto-rendering
  975. #
  976. row += 1
  977. autoRendering = wx.CheckBox(parent=panel, id=wx.ID_ANY,
  978. label=_("Enable auto-rendering"),
  979. name="IsChecked")
  980. autoRendering.SetValue(self.settings.Get(group='display', key='autoRendering', subkey='enabled'))
  981. self.winId['display:autoRendering:enabled'] = autoRendering.GetId()
  982. gridSizer.Add(item=autoRendering,
  983. pos=(row, 0), span=(1, 2))
  984. sizer.Add(item=gridSizer, proportion=1, flag=wx.ALL | wx.EXPAND, border=5)
  985. border.Add(item=sizer, proportion=0, flag=wx.LEFT | wx.RIGHT | wx.BOTTOM | wx.EXPAND, border=3)
  986. panel.SetSizer(border)
  987. # bindings
  988. fontButton.Bind(wx.EVT_BUTTON, self.OnSetFont)
  989. return panel
  990. def __CreateCmdPage(self, notebook):
  991. """Create notebook page for commad dialog settings"""
  992. panel = wx.Panel(parent=notebook, id=wx.ID_ANY)
  993. notebook.AddPage(page=panel, text=_("Command"))
  994. border = wx.BoxSizer(wx.VERTICAL)
  995. box = wx.StaticBox (parent=panel, id=wx.ID_ANY, label=" %s " % _("Command dialog settings"))
  996. sizer = wx.StaticBoxSizer(box, wx.VERTICAL)
  997. gridSizer = wx.GridBagSizer (hgap=3, vgap=3)
  998. gridSizer.AddGrowableCol(0)
  999. #
  1000. # command dialog settings
  1001. #
  1002. row = 0
  1003. # overwrite
  1004. overwrite = wx.CheckBox(parent=panel, id=wx.ID_ANY,
  1005. label=_("Allow output files to overwrite existing files"),
  1006. name="IsChecked")
  1007. overwrite.SetValue(self.settings.Get(group='cmd', key='overwrite', subkey='enabled'))
  1008. self.winId['cmd:overwrite:enabled'] = overwrite.GetId()
  1009. gridSizer.Add(item=overwrite,
  1010. pos=(row, 0), span=(1, 2))
  1011. row += 1
  1012. # close
  1013. close = wx.CheckBox(parent=panel, id=wx.ID_ANY,
  1014. label=_("Close dialog on finish"),
  1015. name="IsChecked")
  1016. close.SetValue(self.settings.Get(group='cmd', key='closeDlg', subkey='enabled'))
  1017. self.winId['cmd:closeDlg:enabled'] = close.GetId()
  1018. gridSizer.Add(item=close,
  1019. pos=(row, 0), span=(1, 2))
  1020. row += 1
  1021. # add layer
  1022. add = wx.CheckBox(parent=panel, id=wx.ID_ANY,
  1023. label=_("Add created map into layer tree"),
  1024. name="IsChecked")
  1025. add.SetValue(self.settings.Get(group='cmd', key='addNewLayer', subkey='enabled'))
  1026. self.winId['cmd:addNewLayer:enabled'] = add.GetId()
  1027. gridSizer.Add(item=add,
  1028. pos=(row, 0), span=(1, 2))
  1029. row += 1
  1030. # verbosity
  1031. gridSizer.Add(item=wx.StaticText(parent=panel, id=wx.ID_ANY,
  1032. label=_("Verbosity level:")),
  1033. flag=wx.ALIGN_LEFT |
  1034. wx.ALIGN_CENTER_VERTICAL,
  1035. pos=(row, 0))
  1036. verbosity = wx.Choice(parent=panel, id=wx.ID_ANY, size=(200, -1),
  1037. choices=self.settings.Get(group='cmd', key='verbosity', subkey='choices', internal=True),
  1038. name="GetStringSelection")
  1039. verbosity.SetStringSelection(self.settings.Get(group='cmd', key='verbosity', subkey='selection'))
  1040. self.winId['cmd:verbosity:selection'] = verbosity.GetId()
  1041. gridSizer.Add(item=verbosity,
  1042. pos=(row, 1))
  1043. sizer.Add(item=gridSizer, proportion=1, flag=wx.ALL | wx.EXPAND, border=5)
  1044. border.Add(item=sizer, proportion=0, flag=wx.ALL | wx.EXPAND, border=3)
  1045. #
  1046. # raster settings
  1047. #
  1048. box = wx.StaticBox (parent=panel, id=wx.ID_ANY, label=" %s " % _("Raster settings"))
  1049. sizer = wx.StaticBoxSizer(box, wx.VERTICAL)
  1050. gridSizer = wx.GridBagSizer (hgap=3, vgap=3)
  1051. gridSizer.AddGrowableCol(0)
  1052. #
  1053. # raster overlay
  1054. #
  1055. row = 0
  1056. rasterOpaque = wx.CheckBox(parent=panel, id=wx.ID_ANY,
  1057. label=_("Make null cells opaque"),
  1058. name='IsChecked')
  1059. rasterOpaque.SetValue(self.settings.Get(group='cmd', key='rasterOpaque', subkey='enabled'))
  1060. self.winId['cmd:rasterOpaque:enabled'] = rasterOpaque.GetId()
  1061. gridSizer.Add(item=rasterOpaque,
  1062. pos=(row, 0), span=(1, 2))
  1063. sizer.Add(item=gridSizer, proportion=1, flag=wx.ALL | wx.EXPAND, border=5)
  1064. border.Add(item=sizer, proportion=0, flag=wx.LEFT | wx.RIGHT | wx.BOTTOM | wx.EXPAND, border=3)
  1065. #
  1066. # vector settings
  1067. #
  1068. box = wx.StaticBox (parent=panel, id=wx.ID_ANY, label=" %s " % _("Vector settings"))
  1069. sizer = wx.StaticBoxSizer(box, wx.VERTICAL)
  1070. gridSizer = wx.FlexGridSizer (cols=7, hgap=3, vgap=3)
  1071. gridSizer.Add(item=wx.StaticText(parent=panel, id=wx.ID_ANY,
  1072. label=_("Display:")),
  1073. flag=wx.ALIGN_CENTER_VERTICAL)
  1074. for type in ('point', 'line', 'centroid', 'boundary',
  1075. 'area', 'face'):
  1076. chkbox = wx.CheckBox(parent=panel, label=type)
  1077. checked = self.settings.Get(group='cmd', key='showType',
  1078. subkey=[type, 'enabled'])
  1079. chkbox.SetValue(checked)
  1080. self.winId['cmd:showType:%s:enabled' % type] = chkbox.GetId()
  1081. gridSizer.Add(item=chkbox)
  1082. sizer.Add(item=gridSizer, proportion=1, flag=wx.ALL | wx.EXPAND, border=5)
  1083. border.Add(item=sizer, proportion=0, flag=wx.LEFT | wx.RIGHT | wx.BOTTOM | wx.EXPAND, border=3)
  1084. panel.SetSizer(border)
  1085. return panel
  1086. def __CreateAttributeManagerPage(self, notebook):
  1087. """Create notebook page for 'Attribute Table Manager' settings"""
  1088. panel = wx.Panel(parent=notebook, id=wx.ID_ANY)
  1089. notebook.AddPage(page=panel, text=_("Attributes"))
  1090. pageSizer = wx.BoxSizer(wx.VERTICAL)
  1091. #
  1092. # highlighting
  1093. #
  1094. highlightBox = wx.StaticBox(parent=panel, id=wx.ID_ANY,
  1095. label=" %s " % _("Highlighting"))
  1096. highlightSizer = wx.StaticBoxSizer(highlightBox, wx.VERTICAL)
  1097. flexSizer = wx.FlexGridSizer (cols=2, hgap=5, vgap=5)
  1098. flexSizer.AddGrowableCol(0)
  1099. label = wx.StaticText(parent=panel, id=wx.ID_ANY, label="Color")
  1100. hlColor = csel.ColourSelect(parent=panel, id=wx.ID_ANY,
  1101. colour=self.settings.Get(group='atm', key='highlight', subkey='color'),
  1102. size=(35, 35))
  1103. hlColor.SetName('GetColour')
  1104. self.winId['atm:highlight:color'] = hlColor.GetId()
  1105. flexSizer.Add(label, proportion=0, flag=wx.ALIGN_CENTER_VERTICAL)
  1106. flexSizer.Add(hlColor, proportion=0, flag=wx.ALIGN_RIGHT | wx.FIXED_MINSIZE)
  1107. label = wx.StaticText(parent=panel, id=wx.ID_ANY, label=_("Line width (in pixels)"))
  1108. hlWidth = wx.SpinCtrl(parent=panel, id=wx.ID_ANY, size=(50, -1),
  1109. initial=self.settings.Get(group='atm', key='highlight',subkey='width'),
  1110. min=1, max=1e6)
  1111. self.winId['atm:highlight:width'] = hlWidth.GetId()
  1112. flexSizer.Add(label, proportion=0, flag=wx.ALIGN_CENTER_VERTICAL)
  1113. flexSizer.Add(hlWidth, proportion=0, flag=wx.ALIGN_RIGHT | wx.FIXED_MINSIZE)
  1114. highlightSizer.Add(item=flexSizer,
  1115. proportion=0,
  1116. flag=wx.ALL | wx.EXPAND,
  1117. border=5)
  1118. pageSizer.Add(item=highlightSizer,
  1119. proportion=0,
  1120. flag=wx.ALL | wx.EXPAND,
  1121. border=5)
  1122. #
  1123. # data browser related settings
  1124. #
  1125. dataBrowserBox = wx.StaticBox(parent=panel, id=wx.ID_ANY,
  1126. label=" %s " % _("Data browser"))
  1127. dataBrowserSizer = wx.StaticBoxSizer(dataBrowserBox, wx.VERTICAL)
  1128. flexSizer = wx.FlexGridSizer (cols=2, hgap=5, vgap=5)
  1129. flexSizer.AddGrowableCol(0)
  1130. label = wx.StaticText(parent=panel, id=wx.ID_ANY, label=_("Left mouse double click"))
  1131. leftDbClick = wx.Choice(parent=panel, id=wx.ID_ANY,
  1132. choices=self.settings.Get(group='atm', key='leftDbClick', subkey='choices', internal=True),
  1133. name="GetSelection")
  1134. leftDbClick.SetSelection(self.settings.Get(group='atm', key='leftDbClick', subkey='selection'))
  1135. self.winId['atm:leftDbClick:selection'] = leftDbClick.GetId()
  1136. flexSizer.Add(label, proportion=0, flag=wx.ALIGN_CENTER_VERTICAL)
  1137. flexSizer.Add(leftDbClick, proportion=0, flag=wx.ALIGN_RIGHT | wx.FIXED_MINSIZE)
  1138. # encoding
  1139. label = wx.StaticText(parent=panel, id=wx.ID_ANY, label=_("Encoding"))
  1140. encoding = wx.TextCtrl(parent=panel, id=wx.ID_ANY,
  1141. value=self.settings.Get(group='atm', key='encoding', subkey='value'),
  1142. name="GetValue", size=(200, -1))
  1143. self.winId['atm:encoding:value'] = encoding.GetId()
  1144. flexSizer.Add(label, proportion=0, flag=wx.ALIGN_CENTER_VERTICAL)
  1145. flexSizer.Add(encoding, proportion=0, flag=wx.ALIGN_RIGHT | wx.FIXED_MINSIZE)
  1146. # ask on delete record
  1147. askOnDeleteRec = wx.CheckBox(parent=panel, id=wx.ID_ANY,
  1148. label=_("Ask when deleting data record(s) from table"),
  1149. name='IsChecked')
  1150. askOnDeleteRec.SetValue(self.settings.Get(group='atm', key='askOnDeleteRec', subkey='enabled'))
  1151. self.winId['atm:askOnDeleteRec:enabled'] = askOnDeleteRec.GetId()
  1152. flexSizer.Add(askOnDeleteRec, proportion=0)
  1153. dataBrowserSizer.Add(item=flexSizer,
  1154. proportion=0,
  1155. flag=wx.ALL | wx.EXPAND,
  1156. border=5)
  1157. pageSizer.Add(item=dataBrowserSizer,
  1158. proportion=0,
  1159. flag=wx.LEFT | wx.RIGHT | wx.BOTTOM | wx.EXPAND,
  1160. border=3)
  1161. #
  1162. # create table
  1163. #
  1164. createTableBox = wx.StaticBox(parent=panel, id=wx.ID_ANY,
  1165. label=" %s " % _("Create table"))
  1166. createTableSizer = wx.StaticBoxSizer(createTableBox, wx.VERTICAL)
  1167. flexSizer = wx.FlexGridSizer (cols=2, hgap=5, vgap=5)
  1168. flexSizer.AddGrowableCol(0)
  1169. label = wx.StaticText(parent=panel, id=wx.ID_ANY,
  1170. label=_("Key column"))
  1171. keyColumn = wx.TextCtrl(parent=panel, id=wx.ID_ANY,
  1172. size=(250, -1))
  1173. keyColumn.SetValue(self.settings.Get(group='atm', key='keycolumn', subkey='value'))
  1174. self.winId['atm:keycolumn:value'] = keyColumn.GetId()
  1175. flexSizer.Add(label, proportion=0, flag=wx.ALIGN_CENTER_VERTICAL)
  1176. flexSizer.Add(keyColumn, proportion=0, flag=wx.ALIGN_RIGHT | wx.FIXED_MINSIZE)
  1177. createTableSizer.Add(item=flexSizer,
  1178. proportion=0,
  1179. flag=wx.ALL | wx.EXPAND,
  1180. border=5)
  1181. pageSizer.Add(item=createTableSizer,
  1182. proportion=0,
  1183. flag=wx.LEFT | wx.RIGHT | wx.BOTTOM | wx.EXPAND,
  1184. border=3)
  1185. panel.SetSizer(pageSizer)
  1186. return panel
  1187. def __CreateWorkspacePage(self, notebook):
  1188. """Create notebook page for workspace settings"""
  1189. panel = wx.Panel(parent=notebook, id=wx.ID_ANY)
  1190. notebook.AddPage(page=panel, text=_("Workspace"))
  1191. border = wx.BoxSizer(wx.VERTICAL)
  1192. box = wx.StaticBox (parent=panel, id=wx.ID_ANY, label=" %s " % _("Loading workspace"))
  1193. sizer = wx.StaticBoxSizer(box, wx.VERTICAL)
  1194. gridSizer = wx.GridBagSizer (hgap=3, vgap=3)
  1195. gridSizer.AddGrowableCol(0)
  1196. row = 0
  1197. #
  1198. # positioning
  1199. #
  1200. posDisplay = wx.CheckBox(parent=panel, id=wx.ID_ANY,
  1201. label=_("Suppress positioning Map Display Window(s)"),
  1202. name='IsChecked')
  1203. posDisplay.SetValue(self.settings.Get(group='workspace', key='posDisplay', subkey='enabled'))
  1204. self.winId['workspace:posDisplay:enabled'] = posDisplay.GetId()
  1205. gridSizer.Add(item=posDisplay,
  1206. pos=(row, 0), span=(1, 2))
  1207. row +=1
  1208. posManager = wx.CheckBox(parent=panel, id=wx.ID_ANY,
  1209. label=_("Suppress positioning Layer Manager window"),
  1210. name='IsChecked')
  1211. posManager.SetValue(self.settings.Get(group='workspace', key='posManager', subkey='enabled'))
  1212. self.winId['workspace:posManager:enabled'] = posManager.GetId()
  1213. gridSizer.Add(item=posManager,
  1214. pos=(row, 0), span=(1, 2))
  1215. sizer.Add(item=gridSizer, proportion=1, flag=wx.ALL | wx.EXPAND, border=5)
  1216. border.Add(item=sizer, proportion=0, flag=wx.ALL | wx.EXPAND, border=3)
  1217. panel.SetSizer(border)
  1218. return panel
  1219. def __CreateAdvancedPage(self, notebook):
  1220. """Create notebook page for advanced settings"""
  1221. panel = wx.Panel(parent=notebook, id=wx.ID_ANY)
  1222. notebook.AddPage(page=panel, text=_("Advanced"))
  1223. border = wx.BoxSizer(wx.VERTICAL)
  1224. box = wx.StaticBox (parent=panel, id=wx.ID_ANY, label=" %s " % _("Advanced settings"))
  1225. sizer = wx.StaticBoxSizer(box, wx.VERTICAL)
  1226. gridSizer = wx.GridBagSizer (hgap=3, vgap=3)
  1227. gridSizer.AddGrowableCol(0)
  1228. row = 0
  1229. #
  1230. # place where to store settings
  1231. #
  1232. gridSizer.Add(item=wx.StaticText(parent=panel, id=wx.ID_ANY,
  1233. label=_("Place where to store settings:")),
  1234. flag=wx.ALIGN_LEFT |
  1235. wx.ALIGN_CENTER_VERTICAL,
  1236. pos=(row, 0))
  1237. settingsFile = wx.Choice(parent=panel, id=wx.ID_ANY, size=(125, -1),
  1238. choices=self.settings.Get(group='advanced', key='settingsFile',
  1239. subkey='choices', internal=True),
  1240. name='GetStringSelection')
  1241. settingsFile.SetStringSelection(self.settings.Get(group='advanced', key='settingsFile', subkey='type'))
  1242. self.winId['advanced:settingsFile:type'] = settingsFile.GetId()
  1243. gridSizer.Add(item=settingsFile,
  1244. flag=wx.ALIGN_RIGHT |
  1245. wx.ALIGN_CENTER_VERTICAL,
  1246. pos=(row, 1))
  1247. row += 1
  1248. #
  1249. # icon theme
  1250. #
  1251. gridSizer.Add(item=wx.StaticText(parent=panel, id=wx.ID_ANY,
  1252. label=_("Icon theme:")),
  1253. flag=wx.ALIGN_LEFT |
  1254. wx.ALIGN_CENTER_VERTICAL,
  1255. pos=(row, 0))
  1256. iconTheme = wx.Choice(parent=panel, id=wx.ID_ANY, size=(125, -1),
  1257. choices=self.settings.Get(group='advanced', key='iconTheme',
  1258. subkey='choices', internal=True),
  1259. name="GetStringSelection")
  1260. iconTheme.SetStringSelection(self.settings.Get(group='advanced', key='iconTheme', subkey='type'))
  1261. self.winId['advanced:iconTheme:type'] = iconTheme.GetId()
  1262. gridSizer.Add(item=iconTheme,
  1263. flag=wx.ALIGN_RIGHT |
  1264. wx.ALIGN_CENTER_VERTICAL,
  1265. pos=(row, 1))
  1266. row += 1
  1267. gridSizer.Add(item=wx.StaticText(parent=panel, id=wx.ID_ANY,
  1268. label=_("Note: To change icon theme, "
  1269. "you must save settings and restart the GUI.")),
  1270. flag=wx.ALIGN_CENTER_VERTICAL,
  1271. pos=(row, 0), span=(1, 2))
  1272. sizer.Add(item=gridSizer, proportion=1, flag=wx.ALL | wx.EXPAND, border=5)
  1273. border.Add(item=sizer, proportion=1, flag=wx.ALL | wx.EXPAND, border=3)
  1274. panel.SetSizer(border)
  1275. return panel
  1276. def OnSetFont(self, event):
  1277. """'Set font' button pressed"""
  1278. dlg = DefaultFontDialog(parent=self, id=wx.ID_ANY,
  1279. title=_('Select default display font'),
  1280. style=wx.DEFAULT_DIALOG_STYLE)
  1281. if dlg.ShowModal() == wx.ID_OK:
  1282. # set default font and encoding environmental variables
  1283. if dlg.font:
  1284. os.environ["GRASS_FONT"] = dlg.font
  1285. self.settings.Set(group='display', value=dlg.font,
  1286. key='font', subkey='type')
  1287. if dlg.encoding and \
  1288. dlg.encoding != "ISO-8859-1":
  1289. os.environ["GRASS_ENCODING"] = dlg.encoding
  1290. self.settings.Set(group='display', value=dlg.encoding,
  1291. key='font', subkey='encoding')
  1292. dlg.Destroy()
  1293. event.Skip()
  1294. def OnSave(self, event):
  1295. """Button 'Save' pressed"""
  1296. if self.__UpdateSettings():
  1297. file = self.settings.SaveToFile()
  1298. self.parent.goutput.WriteLog(_('Settings saved to file \'%s\'.') % file)
  1299. self.Close()
  1300. def OnApply(self, event):
  1301. """Button 'Apply' pressed"""
  1302. if self.__UpdateSettings():
  1303. self.Close()
  1304. def OnCancel(self, event):
  1305. """Button 'Cancel' pressed"""
  1306. self.Close()
  1307. def OnDefault(self, event):
  1308. """Button 'Set to default' pressed"""
  1309. self.settings.userSettings = copy.deepcopy(self.settings.defaultSettings)
  1310. # update widgets
  1311. for gks in self.winId.keys():
  1312. try:
  1313. group, key, subkey = gks.split(':')
  1314. value = self.settings.Get(group, key, subkey)
  1315. except ValueError:
  1316. group, key, subkey, subkey1 = gks.split(':')
  1317. value = self.settings.Get(group, key, [subkey, subkey1])
  1318. win = self.FindWindowById(self.winId[gks])
  1319. if win.GetName() in ('GetValue', 'IsChecked'):
  1320. value = win.SetValue(value)
  1321. elif win.GetName() == 'GetSelection':
  1322. value = win.SetSelection(value)
  1323. elif win.GetName() == 'GetStringSelection':
  1324. value = win.SetStringSelection(value)
  1325. else:
  1326. value = win.SetValue(value)
  1327. def __UpdateSettings(self):
  1328. """Update user settings"""
  1329. for item in self.winId.keys():
  1330. try:
  1331. group, key, subkey = item.split(':')
  1332. subkey1 = None
  1333. except ValueError:
  1334. group, key, subkey, subkey1 = item.split(':')
  1335. id = self.winId[item]
  1336. win = self.FindWindowById(id)
  1337. if win.GetName() == 'GetValue':
  1338. value = win.GetValue()
  1339. elif win.GetName() == 'GetSelection':
  1340. value = win.GetSelection()
  1341. elif win.GetName() == 'IsChecked':
  1342. value = win.IsChecked()
  1343. elif win.GetName() == 'GetStringSelection':
  1344. value = win.GetStringSelection()
  1345. elif win.GetName() == 'GetColour':
  1346. value = tuple(win.GetValue())
  1347. else:
  1348. value = win.GetValue()
  1349. if key == 'keycolumn' and value == '':
  1350. wx.MessageBox(parent=self,
  1351. message=_("Key column cannot be empty string."),
  1352. caption=_("Error"), style=wx.OK | wx.ICON_ERROR)
  1353. win.SetValue(self.settings.Get(group='atm', key='keycolumn', subkey='value'))
  1354. return False
  1355. if subkey1:
  1356. self.settings.Set(group, value, key, [subkey, subkey1])
  1357. else:
  1358. self.settings.Set(group, value, key, subkey)
  1359. #
  1360. # update default window dimension
  1361. #
  1362. if self.settings.Get(group='general', key='defWindowPos', subkey='enabled') is True:
  1363. dim = ''
  1364. # layer manager
  1365. pos = self.parent.GetPosition()
  1366. size = self.parent.GetSize()
  1367. dim = '%d,%d,%d,%d' % (pos[0], pos[1], size[0], size[1])
  1368. # opened displays
  1369. for page in range(0, self.parent.gm_cb.GetPageCount()):
  1370. pos = self.parent.gm_cb.GetPage(page).maptree.mapdisplay.GetPosition()
  1371. size = self.parent.gm_cb.GetPage(page).maptree.mapdisplay.GetSize()
  1372. dim += ',%d,%d,%d,%d' % (pos[0], pos[1], size[0], size[1])
  1373. self.settings.Set(group='general', key='defWindowPos', subkey='dim', value=dim)
  1374. else:
  1375. self.settings.Set(group='general', key='defWindowPos', subkey='dim', value='')
  1376. return True
  1377. class DefaultFontDialog(wx.Dialog):
  1378. """
  1379. Opens a file selection dialog to select default font
  1380. to use in all GRASS displays
  1381. """
  1382. def __init__(self, parent, id, title,
  1383. pos=wx.DefaultPosition, size=wx.DefaultSize,
  1384. style=wx.DEFAULT_DIALOG_STYLE,
  1385. settings=globalSettings):
  1386. self.settings = settings
  1387. wx.Dialog.__init__(self, parent, id, title, pos, size, style)
  1388. panel = wx.Panel(parent=self, id=wx.ID_ANY)
  1389. if "GRASS_FONT" in os.environ:
  1390. self.font = os.environ["GRASS_FONT"]
  1391. else:
  1392. self.font = self.settings.Get(group='display',
  1393. key='font', subkey='type')
  1394. self.fontlist = self.GetFonts()
  1395. self.encoding = self.settings.Get(group='display',
  1396. key='font', subkey='encoding')
  1397. border = wx.BoxSizer(wx.VERTICAL)
  1398. box = wx.StaticBox (parent=panel, id=wx.ID_ANY, label=" %s " % _("Font settings"))
  1399. sizer = wx.StaticBoxSizer(box, wx.VERTICAL)
  1400. gridSizer = wx.GridBagSizer (hgap=5, vgap=5)
  1401. gridSizer.AddGrowableCol(0)
  1402. label = wx.StaticText(parent=panel, id=wx.ID_ANY,
  1403. label=_("Select font:"))
  1404. gridSizer.Add(item=label,
  1405. flag=wx.ALIGN_TOP,
  1406. pos=(0,0))
  1407. self.fontlb = wx.ListBox(parent=panel, id=wx.ID_ANY, pos=wx.DefaultPosition,
  1408. choices=self.fontlist,
  1409. style=wx.LB_SINGLE|wx.LB_SORT)
  1410. self.Bind(wx.EVT_LISTBOX, self.EvtListBox, self.fontlb)
  1411. self.Bind(wx.EVT_LISTBOX_DCLICK, self.EvtListBoxDClick, self.fontlb)
  1412. if self.font:
  1413. self.fontlb.SetStringSelection(self.font, True)
  1414. gridSizer.Add(item=self.fontlb,
  1415. flag=wx.EXPAND, pos=(0, 1))
  1416. label = wx.StaticText(parent=panel, id=wx.ID_ANY,
  1417. label=("Character encoding:"))
  1418. gridSizer.Add(item=label,
  1419. flag=wx.ALIGN_CENTER_VERTICAL,
  1420. pos=(1, 0))
  1421. self.textentry = wx.TextCtrl(parent=panel, id=wx.ID_ANY,
  1422. value=self.encoding)
  1423. gridSizer.Add(item=self.textentry,
  1424. flag=wx.EXPAND, pos=(1, 1))
  1425. self.textentry.Bind(wx.EVT_TEXT, self.OnEncoding)
  1426. sizer.Add(item=gridSizer, proportion=1,
  1427. flag=wx.EXPAND | wx.ALL,
  1428. border=5)
  1429. border.Add(item=sizer, proportion=1,
  1430. flag=wx.ALL | wx.EXPAND, border=3)
  1431. btnsizer = wx.StdDialogButtonSizer()
  1432. btn = wx.Button(parent=panel, id=wx.ID_OK)
  1433. btn.SetDefault()
  1434. btnsizer.AddButton(btn)
  1435. btn = wx.Button(parent=panel, id=wx.ID_CANCEL)
  1436. btnsizer.AddButton(btn)
  1437. btnsizer.Realize()
  1438. border.Add(item=btnsizer, proportion=0,
  1439. flag=wx.EXPAND | wx.ALIGN_RIGHT | wx.ALL, border=5)
  1440. panel.SetAutoLayout(True)
  1441. panel.SetSizer(border)
  1442. border.Fit(self)
  1443. self.Layout()
  1444. def EvtRadioBox(self, event):
  1445. if event.GetInt() == 0:
  1446. self.fonttype = 'grassfont'
  1447. elif event.GetInt() == 1:
  1448. self.fonttype = 'truetype'
  1449. self.fontlist = self.GetFonts(self.fonttype)
  1450. self.fontlb.SetItems(self.fontlist)
  1451. def OnEncoding(self, event):
  1452. self.encoding = event.GetString()
  1453. def EvtListBox(self, event):
  1454. self.font = event.GetString()
  1455. event.Skip()
  1456. def EvtListBoxDClick(self, event):
  1457. self.font = event.GetString()
  1458. event.Skip()
  1459. def GetFonts(self):
  1460. """
  1461. parses fonts directory or fretypecap file to get a list of fonts for the listbox
  1462. """
  1463. fontlist = []
  1464. cmd = ["d.font", "-l"]
  1465. ret = gcmd.RunCommand('d.font',
  1466. read = True,
  1467. flags = 'l')
  1468. if not ret:
  1469. return fontlist
  1470. dfonts = ret.splitlines()
  1471. dfonts.sort(lambda x,y: cmp(x.lower(), y.lower()))
  1472. for item in range(len(dfonts)):
  1473. # ignore duplicate fonts and those starting with #
  1474. if not dfonts[item].startswith('#') and \
  1475. dfonts[item] != dfonts[item-1]:
  1476. fontlist.append(dfonts[item])
  1477. return fontlist
  1478. class MapsetAccess(wx.Dialog):
  1479. """
  1480. Controls setting options and displaying/hiding map overlay decorations
  1481. """
  1482. def __init__(self, parent, id, title=_('Set/unset access to mapsets in current location'),
  1483. pos=wx.DefaultPosition, size=(350, 400),
  1484. style=wx.DEFAULT_DIALOG_STYLE|wx.RESIZE_BORDER):
  1485. wx.Dialog.__init__(self, parent, id, title, pos, size, style)
  1486. self.all_mapsets = utils.ListOfMapsets(all=True)
  1487. self.accessible_mapsets = utils.ListOfMapsets(all=False)
  1488. self.curr_mapset = grass.gisenv()['MAPSET']
  1489. # make a checklistbox from available mapsets and check those that are active
  1490. sizer = wx.BoxSizer(wx.VERTICAL)
  1491. label = wx.StaticText(parent=self, id=wx.ID_ANY,
  1492. label=_("Check mapset to make it accessible, uncheck it to hide it.%s"
  1493. "Note: PERMANENT and current mapset are always accessible.") % os.linesep)
  1494. sizer.Add(item=label, proportion=0,
  1495. flag=wx.ALL, border=5)
  1496. self.mapsetlb = CheckListMapset(parent=self)
  1497. self.mapsetlb.LoadData()
  1498. sizer.Add(item=self.mapsetlb, proportion=1,
  1499. flag=wx.ALL | wx.EXPAND, border=5)
  1500. # check all accessible mapsets
  1501. for mset in self.accessible_mapsets:
  1502. self.mapsetlb.CheckItem(self.all_mapsets.index(mset), True)
  1503. # dialog buttons
  1504. line = wx.StaticLine(parent=self, id=wx.ID_ANY,
  1505. style=wx.LI_HORIZONTAL)
  1506. sizer.Add(item=line, proportion=0,
  1507. flag=wx.EXPAND | wx.ALIGN_CENTRE | wx.ALL, border=5)
  1508. btnsizer = wx.StdDialogButtonSizer()
  1509. okbtn = wx.Button(self, wx.ID_OK)
  1510. okbtn.SetDefault()
  1511. btnsizer.AddButton(okbtn)
  1512. cancelbtn = wx.Button(self, wx.ID_CANCEL)
  1513. btnsizer.AddButton(cancelbtn)
  1514. btnsizer.Realize()
  1515. sizer.Add(item=btnsizer, proportion=0,
  1516. flag=wx.EXPAND | wx.ALIGN_RIGHT | wx.ALL, border=5)
  1517. # do layout
  1518. self.Layout()
  1519. self.SetSizer(sizer)
  1520. sizer.Fit(self)
  1521. self.SetMinSize(size)
  1522. def GetMapsets(self):
  1523. """Get list of checked mapsets"""
  1524. ms = []
  1525. i = 0
  1526. for mset in self.all_mapsets:
  1527. if self.mapsetlb.IsChecked(i):
  1528. ms.append(mset)
  1529. i += 1
  1530. return ms
  1531. class CheckListMapset(wx.ListCtrl, listmix.ListCtrlAutoWidthMixin, listmix.CheckListCtrlMixin):
  1532. """List of mapset/owner/group"""
  1533. def __init__(self, parent, pos=wx.DefaultPosition,
  1534. log=None):
  1535. self.parent = parent
  1536. wx.ListCtrl.__init__(self, parent, wx.ID_ANY,
  1537. style=wx.LC_REPORT)
  1538. listmix.CheckListCtrlMixin.__init__(self)
  1539. self.log = log
  1540. # setup mixins
  1541. listmix.ListCtrlAutoWidthMixin.__init__(self)
  1542. def LoadData(self):
  1543. """Load data into list"""
  1544. self.InsertColumn(0, _('Mapset'))
  1545. self.InsertColumn(1, _('Owner'))
  1546. self.InsertColumn(2, _('Group'))
  1547. gisenv = grass.gisenv()
  1548. locationPath = os.path.join(gisenv['GISDBASE'], gisenv['LOCATION_NAME'])
  1549. ret = grass.read_command('g.mapsets',
  1550. flags = 'l')
  1551. print ret
  1552. mapsets = []
  1553. if ret:
  1554. mapsets = ret.splitlines()
  1555. for mapset in mapsets:
  1556. index = self.InsertStringItem(sys.maxint, mapset)
  1557. mapsetPath = os.path.join(locationPath,
  1558. mapset)
  1559. stat_info = os.stat(mapsetPath)
  1560. if os.name in ('posix', 'mac'):
  1561. self.SetStringItem(index, 1, "%s" % pwd.getpwuid(stat_info.st_uid)[0])
  1562. # FIXME: get group name
  1563. self.SetStringItem(index, 2, "%-8s" % stat_info.st_gid)
  1564. else:
  1565. # FIXME: no pwd under MS Windows (owner: 0, group: 0)
  1566. self.SetStringItem(index, 1, "%-8s" % stat_info.st_uid)
  1567. self.SetStringItem(index, 2, "%-8s" % stat_info.st_gid)
  1568. self.SetColumnWidth(col=0, width=wx.LIST_AUTOSIZE)
  1569. self.SetColumnWidth(col=1, width=wx.LIST_AUTOSIZE)
  1570. def OnCheckItem(self, index, flag):
  1571. """Mapset checked/unchecked"""
  1572. mapset = self.parent.all_mapsets[index]
  1573. if mapset == 'PERMANENT' or mapset == self.parent.curr_mapset:
  1574. self.CheckItem(index, True)