settings.py 40 KB

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