settings.py 43 KB

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