settings.py 45 KB

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