settings.py 46 KB

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