settings.py 39 KB

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