settings.py 40 KB

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