settings.py 40 KB

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