settings.py 44 KB

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