settings.py 43 KB

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