settings.py 44 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186
  1. """!
  2. @package core.settings
  3. @brief Default GUI settings
  4. List of classes:
  5. - settings::Settings
  6. Usage:
  7. @code
  8. from core.settings import UserSettings
  9. @endcode
  10. (C) 2007-2011 by the GRASS Development Team
  11. This program is free software under the GNU General Public License
  12. (>=v2). Read the file COPYING that comes with GRASS for details.
  13. @author Martin Landa <landa.martin gmail.com>
  14. @author Luca Delucchi <lucadeluge gmail.com> (language choice)
  15. """
  16. import os
  17. import sys
  18. import copy
  19. import types
  20. from core import globalvar
  21. from core.gcmd import GException, GError
  22. from core.utils import GetSettingsPath, PathJoin, rgb2str
  23. class Settings:
  24. """!Generic class where to store settings"""
  25. def __init__(self):
  26. # settings file
  27. self.filePath = os.path.join(GetSettingsPath(), 'wx')
  28. # key/value separator
  29. self.sep = ';'
  30. # define default settings
  31. self._defaultSettings() # -> self.defaultSettings
  32. # read settings from the file
  33. self.userSettings = copy.deepcopy(self.defaultSettings)
  34. try:
  35. self.ReadSettingsFile()
  36. except GException, e:
  37. print >> sys.stderr, e.value
  38. # define internal settings
  39. self._internalSettings() # -> self.internalSettings
  40. def _generateLocale(self):
  41. """!Generate locales
  42. """
  43. try:
  44. self.locs = os.listdir(os.path.join(os.environ['GISBASE'], 'locale'))
  45. self.locs.append('en') # GRASS doesn't ship EN po files
  46. self.locs.sort()
  47. # Add a default choice to not override system locale
  48. self.locs.insert(0, 'system')
  49. except:
  50. # No NLS
  51. self.locs = ['system']
  52. return 'system'
  53. def _defaultSettings(self):
  54. """!Define default settings
  55. """
  56. try:
  57. projFile = PathJoin(os.environ["GRASS_PROJSHARE"], 'epsg')
  58. except KeyError:
  59. projFile = ''
  60. id_loc = self._generateLocale()
  61. self.defaultSettings = {
  62. #
  63. # general
  64. #
  65. 'general': {
  66. # use default window layout (layer manager, displays, ...)
  67. 'defWindowPos' : {
  68. 'enabled' : True,
  69. 'dim' : '0,0,%d,%d,%d,0,%d,%d' % \
  70. (globalvar.GM_WINDOW_SIZE[0],
  71. globalvar.GM_WINDOW_SIZE[1],
  72. globalvar.GM_WINDOW_SIZE[0],
  73. globalvar.MAP_WINDOW_SIZE[0],
  74. globalvar.MAP_WINDOW_SIZE[1])
  75. },
  76. # workspace
  77. 'workspace' : {
  78. 'posDisplay' : {
  79. 'enabled' : False
  80. },
  81. 'posManager' : {
  82. 'enabled' : False
  83. },
  84. },
  85. },
  86. 'manager' : {
  87. # show opacity level widget
  88. 'changeOpacityLevel' : {
  89. 'enabled' : False
  90. },
  91. # ask when removing layer from layer tree
  92. 'askOnRemoveLayer' : {
  93. 'enabled' : True
  94. },
  95. # ask when quiting wxGUI or closing display
  96. 'askOnQuit' : {
  97. 'enabled' : True
  98. },
  99. # hide tabs
  100. 'hideTabs' : {
  101. 'search' : False,
  102. 'pyshell' : False,
  103. },
  104. 'copySelectedTextToClipboard' : {
  105. 'enabled' : False
  106. },
  107. },
  108. #
  109. # appearance
  110. #
  111. 'appearance': {
  112. 'outputfont' : {
  113. 'type' : 'Courier New',
  114. 'size': '10',
  115. },
  116. # expand/collapse element list
  117. 'elementListExpand' : {
  118. 'selection' : 0
  119. },
  120. 'menustyle' : {
  121. 'selection' : 1
  122. },
  123. 'gSelectPopupHeight' : {
  124. 'value' : 200
  125. },
  126. 'iconTheme' : {
  127. 'type' : 'grass'
  128. },
  129. 'commandNotebook' : {
  130. 'selection' : 2
  131. },
  132. },
  133. #
  134. # language
  135. #
  136. 'language': {
  137. 'locale': {
  138. 'lc_all' : id_loc
  139. }
  140. },
  141. #
  142. # display
  143. #
  144. 'display': {
  145. 'font' : {
  146. 'type' : '',
  147. 'encoding': 'ISO-8859-1',
  148. },
  149. 'driver': {
  150. 'type': 'cairo'
  151. },
  152. 'alignExtent' : {
  153. 'enabled' : True
  154. },
  155. 'compResolution' : {
  156. 'enabled' : False
  157. },
  158. 'autoRendering': {
  159. 'enabled' : True
  160. },
  161. 'autoZooming' : {
  162. 'enabled' : False
  163. },
  164. 'statusbarMode': {
  165. 'selection' : 0
  166. },
  167. 'bgcolor': {
  168. 'color' : (255, 255, 255, 255),
  169. },
  170. 'mouseWheelZoom' : {
  171. 'selection' : 1,
  172. },
  173. 'scrollDirection' : {
  174. 'selection' : 0,
  175. },
  176. 'nvizDepthBuffer' : {
  177. 'value' : 16,
  178. },
  179. },
  180. #
  181. # projection
  182. #
  183. 'projection' : {
  184. 'statusbar' : {
  185. 'proj4' : '',
  186. 'epsg' : '',
  187. 'projFile' : projFile,
  188. },
  189. 'format' : {
  190. 'll' : 'DMS',
  191. 'precision' : 2,
  192. },
  193. },
  194. #
  195. # Attribute Table Manager
  196. #
  197. 'atm' : {
  198. 'highlight' : {
  199. 'color' : (255, 255, 0, 255),
  200. 'width' : 2
  201. },
  202. 'leftDbClick' : {
  203. 'selection' : 1 # draw selected
  204. },
  205. 'askOnDeleteRec' : {
  206. 'enabled' : True
  207. },
  208. 'keycolumn' : {
  209. 'value' : 'cat'
  210. },
  211. 'encoding' : {
  212. 'value' : '',
  213. },
  214. 'fieldSeparator' : {
  215. 'value' : '|',
  216. }
  217. },
  218. #
  219. # Command
  220. #
  221. 'cmd': {
  222. 'overwrite' : {
  223. 'enabled' : False
  224. },
  225. 'closeDlg' : {
  226. 'enabled' : False
  227. },
  228. 'verbosity' : {
  229. 'selection' : 'grassenv'
  230. },
  231. 'addNewLayer' : {
  232. 'enabled' : True,
  233. },
  234. 'interactiveInput' : {
  235. 'enabled' : True,
  236. },
  237. },
  238. #
  239. # d.rast
  240. #
  241. 'rasterLayer': {
  242. 'opaque': {
  243. 'enabled' : False
  244. },
  245. 'colorTable': {
  246. 'enabled' : False,
  247. 'selection' : 'rainbow'
  248. },
  249. },
  250. #
  251. # d.vect
  252. #
  253. 'vectorLayer': {
  254. 'featureColor': {
  255. 'color' : (0, 0, 0),
  256. 'transparent' : {
  257. 'enabled': False
  258. }
  259. },
  260. 'areaFillColor': {
  261. 'color' : (200, 200, 200),
  262. 'transparent' : {
  263. 'enabled': False
  264. }
  265. },
  266. 'line': {
  267. 'width' : 0,
  268. },
  269. 'point': {
  270. 'symbol': 'basic/x',
  271. 'size' : 5,
  272. },
  273. 'showType': {
  274. 'point' : {
  275. 'enabled' : True
  276. },
  277. 'line' : {
  278. 'enabled' : True
  279. },
  280. 'centroid' : {
  281. 'enabled' : False
  282. },
  283. 'boundary' : {
  284. 'enabled' : False
  285. },
  286. 'area' : {
  287. 'enabled' : True
  288. },
  289. 'face' : {
  290. 'enabled' : True
  291. },
  292. },
  293. },
  294. #
  295. # vdigit
  296. #
  297. 'vdigit' : {
  298. # symbology
  299. 'symbol' : {
  300. 'newSegment' : {
  301. 'enabled' : None,
  302. 'color' : (255, 0, 0, 255)
  303. }, # red
  304. 'newLine' : {
  305. 'enabled' : None,
  306. 'color' : (0, 86, 45, 255)
  307. }, # dark green
  308. 'highlight' : {
  309. 'enabled' : None,
  310. 'color' : (255, 255, 0, 255)
  311. }, # yellow
  312. 'highlightDupl' : {
  313. 'enabled' : None,
  314. 'color' : (255, 72, 0, 255)
  315. }, # red
  316. 'point' : {
  317. 'enabled' : True,
  318. 'color' : (0, 0, 0, 255)
  319. }, # black
  320. 'line' : {
  321. 'enabled' : True,
  322. 'color' : (0, 0, 0, 255)
  323. }, # black
  324. 'boundaryNo' : {
  325. 'enabled' : True,
  326. 'color' : (126, 126, 126, 255)
  327. }, # grey
  328. 'boundaryOne' : {
  329. 'enabled' : True,
  330. 'color' : (0, 255, 0, 255)
  331. }, # green
  332. 'boundaryTwo' : {
  333. 'enabled' : True,
  334. 'color' : (255, 135, 0, 255)
  335. }, # orange
  336. 'centroidIn' : {
  337. 'enabled' : True,
  338. 'color' : (0, 0, 255, 255)
  339. }, # blue
  340. 'centroidOut' : {
  341. 'enabled' : True,
  342. 'color' : (165, 42, 42, 255)
  343. }, # brown
  344. 'centroidDup' : {
  345. 'enabled' : True,
  346. 'color' : (156, 62, 206, 255)
  347. }, # violet
  348. 'nodeOne' : {
  349. 'enabled' : True,
  350. 'color' : (255, 0, 0, 255)
  351. }, # red
  352. 'nodeTwo' : {
  353. 'enabled' : True,
  354. 'color' : (0, 86, 45, 255)
  355. }, # dark green
  356. 'vertex' : {
  357. 'enabled' : False,
  358. 'color' : (255, 20, 147, 255)
  359. }, # deep pink
  360. 'area' : {
  361. 'enabled' : True,
  362. 'color' : (217, 255, 217, 255)
  363. }, # green
  364. 'direction' : {
  365. 'enabled' : False,
  366. 'color' : (255, 0, 0, 255)
  367. }, # red
  368. },
  369. # display
  370. 'lineWidth' : {
  371. 'value' : 2,
  372. 'units' : 'screen pixels'
  373. },
  374. # snapping
  375. 'snapping' : {
  376. 'value' : 10,
  377. 'units' : 'screen pixels'
  378. },
  379. 'snapToVertex' : {
  380. 'enabled' : False
  381. },
  382. # digitize new record
  383. 'addRecord' : {
  384. 'enabled' : True
  385. },
  386. 'layer' :{
  387. 'value' : 1
  388. },
  389. 'category' : {
  390. 'value' : 1
  391. },
  392. 'categoryMode' : {
  393. 'selection' : 0
  394. },
  395. # delete existing feature(s)
  396. 'delRecord' : {
  397. 'enabled' : True
  398. },
  399. # query tool
  400. 'query' : {
  401. 'selection' : 0,
  402. 'box' : True
  403. },
  404. 'queryLength' : {
  405. 'than-selection' : 0,
  406. 'thresh' : 0
  407. },
  408. 'queryDangle' : {
  409. 'than-selection' : 0,
  410. 'thresh' : 0
  411. },
  412. # select feature (point, line, centroid, boundary)
  413. 'selectType': {
  414. 'point' : {
  415. 'enabled' : True
  416. },
  417. 'line' : {
  418. 'enabled' : True
  419. },
  420. 'centroid' : {
  421. 'enabled' : True
  422. },
  423. 'boundary' : {
  424. 'enabled' : True
  425. },
  426. },
  427. 'selectThresh' : {
  428. 'value' : 10,
  429. 'units' : 'screen pixels'
  430. },
  431. 'checkForDupl' : {
  432. 'enabled' : False
  433. },
  434. 'selectInside' : {
  435. 'enabled' : False
  436. },
  437. # exit
  438. 'saveOnExit' : {
  439. 'enabled' : False,
  440. },
  441. # break lines on intersection
  442. 'breakLines' : {
  443. 'enabled' : False,
  444. },
  445. # close boundary (snap to the first node)
  446. 'closeBoundary' : {
  447. 'enabled' : False,
  448. }
  449. },
  450. #
  451. # plots for profiles, histograms, and scatterplots
  452. #
  453. 'profile': {
  454. 'raster' : {
  455. 'pcolor' : (0, 0, 255, 255), # line color
  456. 'pwidth' : 1, # line width
  457. 'pstyle' : 'solid', # line pen style
  458. 'datatype' : 'cell', # raster type
  459. },
  460. 'font' : {
  461. 'titleSize' : 12,
  462. 'axisSize' : 11,
  463. 'legendSize' : 10,
  464. },
  465. 'marker' : {
  466. 'color' : (0, 0, 0, 255),
  467. 'fill' : 'transparent',
  468. 'size' : 2,
  469. 'type' : 'triangle',
  470. 'legend' : _('Segment break'),
  471. },
  472. 'grid' : {
  473. 'color' : (200, 200, 200, 255),
  474. 'enabled' : True,
  475. },
  476. 'x-axis' : {
  477. 'type' : 'auto', # axis format
  478. 'min' : 0, # axis min for custom axis range
  479. 'max': 0, # axis max for custom axis range
  480. 'log' : False,
  481. },
  482. 'y-axis' : {
  483. 'type' : 'auto', # axis format
  484. 'min' : 0, # axis min for custom axis range
  485. 'max': 0, # axis max for custom axis range
  486. 'log' : False,
  487. },
  488. 'legend' : {
  489. 'enabled' : True
  490. },
  491. },
  492. 'histogram': {
  493. 'raster' : {
  494. 'pcolor' : (0, 0, 255, 255), # line color
  495. 'pwidth' : 1, # line width
  496. 'pstyle' : 'solid', # line pen style
  497. 'datatype' : 'cell', # raster type
  498. },
  499. 'font' : {
  500. 'titleSize' : 12,
  501. 'axisSize' : 11,
  502. 'legendSize' : 10,
  503. },
  504. 'grid' : {
  505. 'color' : (200, 200, 200, 255),
  506. 'enabled' : True,
  507. },
  508. 'x-axis' : {
  509. 'type' : 'auto', # axis format
  510. 'min' : 0, # axis min for custom axis range
  511. 'max' : 0, # axis max for custom axis range
  512. 'log' : False,
  513. },
  514. 'y-axis' : {
  515. 'type' : 'auto', # axis format
  516. 'min' : 0, # axis min for custom axis range
  517. 'max' : 0, # axis max for custom axis range
  518. 'log' : False,
  519. },
  520. 'legend' : {
  521. 'enabled' : True
  522. },
  523. },
  524. 'scatter': {
  525. 'raster' : {
  526. 'pcolor' : (0, 0, 255, 255),
  527. 'pfill' : 'solid',
  528. 'psize' : 1,
  529. 'ptype' : 'dot',
  530. # FIXME: this is only a quick fix
  531. # using also names used in a base class for compatibility
  532. # probably used only for initialization
  533. # base should be rewritten to not require this
  534. 'pwidth' : 1, # required by wxplot/base, maybe useless here
  535. 'pstyle' : 'dot', # line pen style
  536. 'plegend' : _('Data point'),
  537. 0 : {'datatype' : 'CELL'},
  538. 1 : {'datatype' : 'CELL'},
  539. },
  540. 'font' : {
  541. 'titleSize' : 12,
  542. 'axisSize' : 11,
  543. 'legendSize' : 10,
  544. },
  545. 'grid' : {
  546. 'color' : (200, 200, 200, 255),
  547. 'enabled' : True,
  548. },
  549. 'x-axis' : {
  550. 'type' : 'auto', # axis format
  551. 'min' : 0, # axis min for custom axis range
  552. 'max' : 0, # axis max for custom axis range
  553. 'log' : False,
  554. },
  555. 'y-axis' : {
  556. 'type' : 'auto', # axis format
  557. 'min' : 0, # axis min for custom axis range
  558. 'max' : 0, # axis max for custom axis range
  559. 'log' : False,
  560. },
  561. 'legend' : {
  562. 'enabled' : True
  563. },
  564. },
  565. 'gcpman' : {
  566. 'rms' : {
  567. 'highestonly' : True,
  568. 'sdfactor' : 1,
  569. },
  570. 'symbol' : {
  571. 'color' : (0, 0, 255, 255),
  572. 'hcolor' : (255, 0, 0, 255),
  573. 'scolor' : (0, 255, 0, 255),
  574. 'ucolor' : (255, 165, 0, 255),
  575. 'unused' : True,
  576. 'size' : 8,
  577. 'width' : 2,
  578. },
  579. },
  580. 'nviz' : {
  581. 'view' : {
  582. 'persp' : {
  583. 'value' : 20,
  584. 'step' : 2,
  585. },
  586. 'position' : {
  587. 'x' : 0.84,
  588. 'y' : 0.16,
  589. },
  590. 'twist' : {
  591. 'value' : 0,
  592. },
  593. 'z-exag' : {
  594. 'min' : 0,
  595. 'max' : 10,
  596. 'value': 1,
  597. },
  598. 'background' : {
  599. 'color' : (255, 255, 255, 255), # white
  600. },
  601. },
  602. 'fly' : {
  603. 'exag' : {
  604. 'move' : 5,
  605. 'turn' : 5,
  606. }
  607. },
  608. 'animation' : {
  609. 'fps' : 24,
  610. 'prefix' : _("animation")
  611. },
  612. 'surface' : {
  613. 'shine': {
  614. 'map' : False,
  615. 'value' : 60.0,
  616. },
  617. 'color' : {
  618. 'map' : True,
  619. 'value' : (100, 100, 100, 255), # constant: grey
  620. },
  621. 'draw' : {
  622. 'wire-color' : (136, 136, 136, 255),
  623. 'mode' : 1, # fine
  624. 'style' : 1, # surface
  625. 'shading' : 1, # gouraud
  626. 'res-fine' : 6,
  627. 'res-coarse' : 9,
  628. },
  629. 'position' : {
  630. 'x' : 0,
  631. 'y' : 0,
  632. 'z' : 0,
  633. },
  634. },
  635. 'constant' : {
  636. 'color' : (100, 100, 100, 255),
  637. 'value' : 0.0,
  638. 'transp' : 0,
  639. 'resolution': 6
  640. },
  641. 'vector' : {
  642. 'lines' : {
  643. 'show' : False,
  644. 'width' : 2,
  645. 'color' : (0, 0, 255, 255), # blue
  646. 'flat' : False,
  647. 'height' : 0,
  648. 'rgbcolumn': None,
  649. 'sizecolumn': None,
  650. },
  651. 'points' : {
  652. 'show' : False,
  653. 'size' : 100,
  654. 'width' : 2,
  655. 'marker' : 2,
  656. 'color' : (0, 0, 255, 255), # blue
  657. 'height' : 0,
  658. 'rgbcolumn': None,
  659. 'sizecolumn': None,
  660. }
  661. },
  662. 'volume' : {
  663. 'color' : {
  664. 'map' : True,
  665. 'value' : (100, 100, 100, 255), # constant: grey
  666. },
  667. 'draw' : {
  668. 'mode' : 0, # isosurfaces
  669. 'shading' : 1, # gouraud
  670. 'resolution' : 3, # polygon resolution
  671. 'box' : False # draw wire box
  672. },
  673. 'shine': {
  674. 'map' : False,
  675. 'value' : 60,
  676. },
  677. 'topo': {
  678. 'map' : None,
  679. 'value' : 0.0
  680. },
  681. 'transp': {
  682. 'map' : None,
  683. 'value': 0
  684. },
  685. 'mask': {
  686. 'map' : None,
  687. 'value': ''
  688. },
  689. 'slice_position': {
  690. 'x1' : 0,
  691. 'x2' : 1,
  692. 'y1' : 0,
  693. 'y2' : 1,
  694. 'z1' : 0,
  695. 'z2' : 1,
  696. 'axis' : 0,
  697. }
  698. },
  699. 'cplane' : {
  700. 'shading': 4,
  701. 'rotation':{
  702. 'rot': 180,
  703. 'tilt': 0
  704. },
  705. 'position':{
  706. 'x' : 0,
  707. 'y' : 0,
  708. 'z' : 0
  709. }
  710. },
  711. 'light' : {
  712. 'position' : {
  713. 'x' : 0.68,
  714. 'y' : -0.68,
  715. 'z' : 80,
  716. },
  717. 'bright' : 80,
  718. 'color' : (255, 255, 255, 255), # white
  719. 'ambient' : 20,
  720. },
  721. 'fringe' : {
  722. 'elev' : 55,
  723. 'color' : (128, 128, 128, 255), # grey
  724. },
  725. 'arrow': {
  726. 'color': (0, 0, 0),
  727. },
  728. 'scalebar': {
  729. 'color': (0, 0, 0),
  730. }
  731. },
  732. 'modeler' : {
  733. 'disabled': {
  734. 'color': (211, 211, 211, 255), # light grey
  735. },
  736. 'action' : {
  737. 'color' : {
  738. 'valid' : (180, 234, 154, 255), # light green
  739. 'invalid' : (255, 255, 255, 255), # white
  740. 'running' : (255, 0, 0, 255), # red
  741. },
  742. 'size' : {
  743. 'width' : 125,
  744. 'height' : 50,
  745. },
  746. 'width': {
  747. 'parameterized' : 2,
  748. 'default' : 1,
  749. },
  750. },
  751. 'data' : {
  752. 'color': {
  753. 'raster' : (215, 215, 248, 255), # light blue
  754. 'raster3d' : (215, 248, 215, 255), # light green
  755. 'vector' : (248, 215, 215, 255), # light red
  756. },
  757. 'size' : {
  758. 'width' : 175,
  759. 'height' : 50,
  760. },
  761. },
  762. 'loop' : {
  763. 'color' : {
  764. 'valid' : (234, 226, 154, 255), # light yellow
  765. },
  766. 'size' : {
  767. 'width' : 175,
  768. 'height' : 40,
  769. },
  770. },
  771. 'if-else' : {
  772. 'size' : {
  773. 'width' : 150,
  774. 'height' : 40,
  775. },
  776. },
  777. },
  778. }
  779. # quick fix, http://trac.osgeo.org/grass/ticket/1233
  780. # TODO
  781. if sys.platform == 'darwin':
  782. self.defaultSettings['general']['defWindowPos']['enabled'] = False
  783. def _internalSettings(self):
  784. """!Define internal settings (based on user settings)
  785. """
  786. self.internalSettings = {}
  787. for group in self.userSettings.keys():
  788. self.internalSettings[group] = {}
  789. for key in self.userSettings[group].keys():
  790. self.internalSettings[group][key] = {}
  791. # self.internalSettings['general']["mapsetPath"]['value'] = self.GetMapsetPath()
  792. self.internalSettings['appearance']['elementListExpand']['choices'] = \
  793. (_("Collapse all except PERMANENT and current"),
  794. _("Collapse all except PERMANENT"),
  795. _("Collapse all except current"),
  796. _("Collapse all"),
  797. _("Expand all"))
  798. self.internalSettings['language']['locale']['choices'] = tuple(self.locs)
  799. self.internalSettings['atm']['leftDbClick']['choices'] = (_('Edit selected record'),
  800. _('Display selected'))
  801. self.internalSettings['cmd']['verbosity']['choices'] = ('grassenv',
  802. 'verbose',
  803. 'quiet')
  804. self.internalSettings['appearance']['iconTheme']['choices'] = ('grass',)
  805. self.internalSettings['appearance']['menustyle']['choices'] = \
  806. (_("Classic (labels only)"),
  807. _("Combined (labels and module names)"),
  808. _("Expert (module names only)"))
  809. self.internalSettings['appearance']['gSelectPopupHeight']['min'] = 50
  810. # there is also maxHeight given to TreeCtrlComboPopup.GetAdjustedSize
  811. self.internalSettings['appearance']['gSelectPopupHeight']['max'] = 1000
  812. self.internalSettings['appearance']['commandNotebook']['choices'] = \
  813. (_("Basic top"),
  814. _("Basic left"),
  815. _("Fancy green"),
  816. _("List left"))
  817. self.internalSettings['display']['driver']['choices'] = ['cairo', 'png']
  818. self.internalSettings['display']['statusbarMode']['choices'] = None # set during MapFrame init
  819. self.internalSettings['display']['mouseWheelZoom']['choices'] = (_('Zoom and recenter'),
  820. _('Zoom to mouse cursor'),
  821. _('Nothing'))
  822. self.internalSettings['display']['scrollDirection']['choices'] = (_('Scroll forward to zoom in'),
  823. _('Scroll back to zoom in'))
  824. self.internalSettings['nviz']['view'] = {}
  825. self.internalSettings['nviz']['view']['twist'] = {}
  826. self.internalSettings['nviz']['view']['twist']['min'] = -180
  827. self.internalSettings['nviz']['view']['twist']['max'] = 180
  828. self.internalSettings['nviz']['view']['persp'] = {}
  829. self.internalSettings['nviz']['view']['persp']['min'] = 1
  830. self.internalSettings['nviz']['view']['persp']['max'] = 100
  831. self.internalSettings['nviz']['view']['height'] = {}
  832. self.internalSettings['nviz']['view']['height']['value'] = -1
  833. self.internalSettings['nviz']['view']['z-exag'] = {}
  834. self.internalSettings['nviz']['view']['z-exag']['llRatio'] = 1
  835. self.internalSettings['nviz']['view']['rotation'] = None
  836. self.internalSettings['nviz']['view']['focus'] = {}
  837. self.internalSettings['nviz']['view']['focus']['x'] = -1
  838. self.internalSettings['nviz']['view']['focus']['y'] = -1
  839. self.internalSettings['nviz']['view']['focus']['z'] = -1
  840. self.internalSettings['nviz']['view']['dir'] = {}
  841. self.internalSettings['nviz']['view']['dir']['x'] = -1
  842. self.internalSettings['nviz']['view']['dir']['y'] = -1
  843. self.internalSettings['nviz']['view']['dir']['z'] = -1
  844. self.internalSettings['nviz']['view']['dir']['use'] = False
  845. for decor in ('arrow', 'scalebar'):
  846. self.internalSettings['nviz'][decor] = {}
  847. self.internalSettings['nviz'][decor]['position'] = {}
  848. self.internalSettings['nviz'][decor]['position']['x'] = 0
  849. self.internalSettings['nviz'][decor]['position']['y'] = 0
  850. self.internalSettings['nviz'][decor]['size'] = 100
  851. self.internalSettings['nviz']['vector'] = {}
  852. self.internalSettings['nviz']['vector']['points'] = {}
  853. self.internalSettings['nviz']['vector']['points']['marker'] = ("x",
  854. _("box"),
  855. _("sphere"),
  856. _("cube"),
  857. _("diamond"),
  858. _("aster"),
  859. _("gyro"),
  860. _("histogram"))
  861. self.internalSettings['vdigit']['bgmap'] = {}
  862. self.internalSettings['vdigit']['bgmap']['value'] = ''
  863. def ReadSettingsFile(self, settings = None):
  864. """!Reads settings file (mapset, location, gisdbase)"""
  865. if settings is None:
  866. settings = self.userSettings
  867. self._readFile(self.filePath, settings)
  868. # set environment variables
  869. font = self.Get(group = 'display', key = 'font', subkey = 'type')
  870. enc = self.Get(group = 'display', key = 'font', subkey = 'encoding')
  871. if font:
  872. os.environ["GRASS_FONT"] = font
  873. if enc:
  874. os.environ["GRASS_ENCODING"] = enc
  875. def _readFile(self, filename, settings = None):
  876. """!Read settings from file to dict
  877. @param filename settings file path
  878. @param settings dict where to store settings (None for self.userSettings)
  879. """
  880. if settings is None:
  881. settings = self.userSettings
  882. if not os.path.exists(filename):
  883. return
  884. try:
  885. fd = open(filename, "r")
  886. except IOError:
  887. sys.stderr.write(_("Unable to read settings file <%s>\n") % filename)
  888. return
  889. try:
  890. line = ''
  891. for line in fd.readlines():
  892. line = line.rstrip('%s' % os.linesep)
  893. group, key = line.split(self.sep)[0:2]
  894. kv = line.split(self.sep)[2:]
  895. subkeyMaster = None
  896. if len(kv) % 2 != 0: # multiple (e.g. nviz)
  897. subkeyMaster = kv[0]
  898. del kv[0]
  899. idx = 0
  900. while idx < len(kv):
  901. if subkeyMaster:
  902. subkey = [subkeyMaster, kv[idx]]
  903. else:
  904. subkey = kv[idx]
  905. value = kv[idx+1]
  906. value = self._parseValue(value, read = True)
  907. self.Append(settings, group, key, subkey, value)
  908. idx += 2
  909. except ValueError, e:
  910. print >> sys.stderr, _("Error: Reading settings from file <%(file)s> failed.\n"
  911. "\t\tDetails: %(detail)s\n"
  912. "\t\tLine: '%(line)s'\n") % { 'file' : filename,
  913. 'detail' : e,
  914. 'line' : line }
  915. fd.close()
  916. fd.close()
  917. def SaveToFile(self, settings = None):
  918. """!Save settings to the file"""
  919. if settings is None:
  920. settings = self.userSettings
  921. dirPath = GetSettingsPath()
  922. if not os.path.exists(dirPath):
  923. try:
  924. os.mkdir(dirPath)
  925. except:
  926. GError(_('Unable to create settings directory'))
  927. return
  928. try:
  929. file = open(self.filePath, "w")
  930. for group in settings.keys():
  931. for key in settings[group].keys():
  932. subkeys = settings[group][key].keys()
  933. file.write('%s%s%s%s' % (group, self.sep, key, self.sep))
  934. for idx in range(len(subkeys)):
  935. value = settings[group][key][subkeys[idx]]
  936. if type(value) == types.DictType:
  937. if idx > 0:
  938. file.write('%s%s%s%s%s' % (os.linesep, group, self.sep, key, self.sep))
  939. file.write('%s%s' % (subkeys[idx], self.sep))
  940. kvalues = settings[group][key][subkeys[idx]].keys()
  941. srange = range(len(kvalues))
  942. for sidx in srange:
  943. svalue = self._parseValue(settings[group][key][subkeys[idx]][kvalues[sidx]])
  944. file.write('%s%s%s' % (kvalues[sidx], self.sep,
  945. svalue))
  946. if sidx < len(kvalues) - 1:
  947. file.write('%s' % self.sep)
  948. else:
  949. if idx > 0 and \
  950. type(settings[group][key][subkeys[idx - 1]]) == types.DictType:
  951. file.write('%s%s%s%s%s' % (os.linesep, group, self.sep, key, self.sep))
  952. value = self._parseValue(settings[group][key][subkeys[idx]])
  953. file.write('%s%s%s' % (subkeys[idx], self.sep, value))
  954. if idx < len(subkeys) - 1 and \
  955. type(settings[group][key][subkeys[idx + 1]]) != types.DictType:
  956. file.write('%s' % self.sep)
  957. file.write(os.linesep)
  958. except IOError, e:
  959. raise GException(e)
  960. except StandardError, e:
  961. raise GException(_('Writing settings to file <%(file)s> failed.'
  962. '\n\nDetails: %(detail)s') % { 'file' : self.filePath,
  963. 'detail' : e })
  964. file.close()
  965. return self.filePath
  966. def _parseValue(self, value, read = False):
  967. """!Parse value to be store in settings file"""
  968. if read: # -> read settings (cast values)
  969. if value == 'True':
  970. value = True
  971. elif value == 'False':
  972. value = False
  973. elif value == 'None':
  974. value = None
  975. elif ':' in value: # -> color
  976. try:
  977. value = tuple(map(int, value.split(':')))
  978. except ValueError: # -> string
  979. pass
  980. else:
  981. try:
  982. value = int(value)
  983. except ValueError:
  984. try:
  985. value = float(value)
  986. except ValueError:
  987. pass
  988. else: # -> write settings
  989. if type(value) == type(()): # -> color
  990. value = str(value[0]) + ':' +\
  991. str(value[1]) + ':' + \
  992. str(value[2])
  993. return value
  994. def Get(self, group, key = None, subkey = None, internal = False):
  995. """!Get value by key/subkey
  996. Raise KeyError if key is not found
  997. @param group settings group
  998. @param key (value, None)
  999. @param subkey (value, list or None)
  1000. @param internal use internal settings instead
  1001. @return value
  1002. """
  1003. if internal is True:
  1004. settings = self.internalSettings
  1005. else:
  1006. settings = self.userSettings
  1007. try:
  1008. if subkey is None:
  1009. if key is None:
  1010. return settings[group]
  1011. else:
  1012. return settings[group][key]
  1013. else:
  1014. if type(subkey) == type(tuple()) or \
  1015. type(subkey) == type(list()):
  1016. return settings[group][key][subkey[0]][subkey[1]]
  1017. else:
  1018. return settings[group][key][subkey]
  1019. except KeyError:
  1020. print >> sys.stderr, "Settings: unable to get value '%s:%s:%s'\n" % \
  1021. (group, key, subkey)
  1022. def Set(self, group, value, key = None, subkey = None, internal = False):
  1023. """!Set value of key/subkey
  1024. Raise KeyError if group/key is not found
  1025. @param group settings group
  1026. @param key key (value, None)
  1027. @param subkey subkey (value, list or None)
  1028. @param value value
  1029. @param internal use internal settings instead
  1030. """
  1031. if internal is True:
  1032. settings = self.internalSettings
  1033. else:
  1034. settings = self.userSettings
  1035. try:
  1036. if subkey is None:
  1037. if key is None:
  1038. settings[group] = value
  1039. else:
  1040. settings[group][key] = value
  1041. else:
  1042. if type(subkey) == type(tuple()) or \
  1043. type(subkey) == type(list()):
  1044. settings[group][key][subkey[0]][subkey[1]] = value
  1045. else:
  1046. settings[group][key][subkey] = value
  1047. except KeyError:
  1048. raise GException("%s '%s:%s:%s'" % (_("Unable to set "), group, key, subkey))
  1049. def Append(self, dict, group, key, subkey, value, overwrite = True):
  1050. """!Set value of key/subkey
  1051. Create group/key/subkey if not exists
  1052. @param dict settings dictionary to use
  1053. @param group settings group
  1054. @param key key
  1055. @param subkey subkey (value or list)
  1056. @param value value
  1057. @param overwrite True to overwrite existing value
  1058. """
  1059. hasValue = True
  1060. if group not in dict:
  1061. dict[group] = {}
  1062. hasValue = False
  1063. if key not in dict[group]:
  1064. dict[group][key] = {}
  1065. hasValue = False
  1066. if type(subkey) == types.ListType:
  1067. # TODO: len(subkey) > 2
  1068. if subkey[0] not in dict[group][key]:
  1069. dict[group][key][subkey[0]] = {}
  1070. hasValue = False
  1071. if subkey[1] not in dict[group][key][subkey[0]]:
  1072. hasValue = False
  1073. try:
  1074. if overwrite or (not overwrite and not hasValue):
  1075. dict[group][key][subkey[0]][subkey[1]] = value
  1076. except TypeError:
  1077. print >> sys.stderr, _("Unable to parse settings '%s'") % value + \
  1078. ' (' + group + ':' + key + ':' + subkey[0] + ':' + subkey[1] + ')'
  1079. else:
  1080. if subkey not in dict[group][key]:
  1081. hasValue = False
  1082. try:
  1083. if overwrite or (not overwrite and not hasValue):
  1084. dict[group][key][subkey] = value
  1085. except TypeError:
  1086. print >> sys.stderr, _("Unable to parse settings '%s'") % value + \
  1087. ' (' + group + ':' + key + ':' + subkey + ')'
  1088. def GetDefaultSettings(self):
  1089. """!Get default user settings"""
  1090. return self.defaultSettings
  1091. def Reset(self, key = None):
  1092. """!Reset to default settings
  1093. @param key key in settings dict (None for all keys)
  1094. """
  1095. if not key:
  1096. self.userSettings = copy.deepcopy(self.defaultSettings)
  1097. else:
  1098. self.userSettings[key] = copy.deepcopy(self.defaultSettings[key])
  1099. UserSettings = Settings()
  1100. def GetDisplayVectSettings():
  1101. settings = list()
  1102. if not UserSettings.Get(group = 'vectorLayer', key = 'featureColor', subkey = ['transparent', 'enabled']):
  1103. featureColor = UserSettings.Get(group = 'vectorLayer', key = 'featureColor', subkey = 'color')
  1104. settings.append('color=%s' % rgb2str.get(featureColor, ':'.join(map(str,featureColor))))
  1105. else:
  1106. settings.append('color=none')
  1107. if not UserSettings.Get(group = 'vectorLayer', key = 'areaFillColor', subkey = ['transparent', 'enabled']):
  1108. fillColor = UserSettings.Get(group = 'vectorLayer', key = 'areaFillColor', subkey = 'color')
  1109. settings.append('fcolor=%s' % rgb2str.get(fillColor, ':'.join(map(str,fillColor))))
  1110. else:
  1111. settings.append('fcolor=none')
  1112. settings.append('width=%s' % UserSettings.Get(group = 'vectorLayer', key = 'line', subkey = 'width'))
  1113. settings.append('icon=%s' % UserSettings.Get(group = 'vectorLayer', key = 'point', subkey = 'symbol'))
  1114. settings.append('size=%s' % UserSettings.Get(group = 'vectorLayer', key = 'point', subkey = 'size'))
  1115. types = []
  1116. for ftype in ['point', 'line', 'boundary', 'centroid', 'area', 'face']:
  1117. if UserSettings.Get(group = 'vectorLayer', key = 'showType', subkey = [ftype, 'enabled']):
  1118. types.append(ftype)
  1119. settings.append('type=%s' % ','.join(types))
  1120. return settings