settings.py 42 KB

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