settings.py 38 KB

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