settings.py 44 KB

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