settings.py 39 KB

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