GRASS Programmer's Manual  6.5.svn(2012)-r51648
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Defines
settings.py
Go to the documentation of this file.
00001 """!
00002 @package core.settings
00003 
00004 @brief Default GUI settings
00005 
00006 List of classes:
00007  - settings::Settings
00008 
00009 Usage:
00010 @code
00011 from core.settings import UserSettings
00012 @endcode
00013 
00014 (C) 2007-2011 by the GRASS Development Team
00015 This program is free software under the GNU General Public License
00016 (>=v2). Read the file COPYING that comes with GRASS for details.
00017 
00018 @author Martin Landa <landa.martin gmail.com>
00019 """
00020 
00021 import os
00022 import sys
00023 import copy
00024 import types
00025 
00026 from core       import globalvar
00027 from core.gcmd  import GException, GError
00028 from core.utils import GetSettingsPath, PathJoin
00029 
00030 class Settings:
00031     """!Generic class where to store settings"""
00032     def __init__(self):
00033         # settings file
00034         self.filePath = os.path.join(GetSettingsPath(), 'wx')
00035         
00036         # key/value separator
00037         self.sep = ';'
00038         
00039         # define default settings
00040         self._defaultSettings()  # -> self.defaultSettings
00041         
00042         # read settings from the file
00043         self.userSettings = copy.deepcopy(self.defaultSettings)
00044         try:
00045             self.ReadSettingsFile()
00046         except GException, e:
00047             print >> sys.stderr, e.value
00048         
00049         # define internal settings
00050         self._internalSettings() # -> self.internalSettings
00051         
00052     def _defaultSettings(self):
00053         """!Define default settings
00054         """
00055         try:
00056             projFile = PathJoin(os.environ["GRASS_PROJSHARE"], 'epsg')
00057         except KeyError:
00058             projFile = ''
00059         
00060         self.defaultSettings = {
00061             #
00062             # general
00063             #
00064             'general': {
00065                 # use default window layout (layer manager, displays, ...)
00066                 'defWindowPos' : {
00067                     'enabled' : True,
00068                     'dim' : '0,0,%d,%d,%d,0,%d,%d' % \
00069                         (globalvar.GM_WINDOW_SIZE[0],
00070                          globalvar.GM_WINDOW_SIZE[1],
00071                          globalvar.GM_WINDOW_SIZE[0],
00072                          globalvar.MAP_WINDOW_SIZE[0],
00073                          globalvar.MAP_WINDOW_SIZE[1])
00074                     },
00075                 # workspace
00076                 'workspace' : {
00077                     'posDisplay' : {
00078                         'enabled' : False
00079                         },
00080                     'posManager' : {
00081                         'enabled' : False
00082                         },
00083                     },
00084                 },
00085             'manager' : {
00086                 # show opacity level widget
00087                 'changeOpacityLevel' : {
00088                     'enabled' : False
00089                     }, 
00090                 # ask when removing layer from layer tree
00091                 'askOnRemoveLayer' : {
00092                     'enabled' : True
00093                     },
00094                 # ask when quiting wxGUI or closing display
00095                 'askOnQuit' : {
00096                     'enabled' : True
00097                     },
00098                 # hide tabs
00099                 'hideTabs' : {
00100                     'search' : False,
00101                     'pyshell' : False,
00102                     },
00103                 'copySelectedTextToClipboard' : {
00104                     'enabled' : False
00105                     },
00106                 },
00107             #
00108             # appearance
00109             #
00110             'appearance': {
00111                 'outputfont' : {
00112                     'type' : 'Courier New',
00113                     'size': '10',
00114                     },
00115                 # expand/collapse element list
00116                 'elementListExpand' : {
00117                     'selection' : 0 
00118                     },
00119                 'menustyle' : {
00120                     'selection' : 1
00121                     },
00122                 'gSelectPopupHeight' : {
00123                     'value' : 200
00124                     },
00125                 'iconTheme' : {
00126                     'type' : 'grass2'
00127                     }, # grass2, grass, silk
00128                 },
00129             #
00130             # display
00131             #
00132             'display': {
00133                 'font' : {
00134                     'type' : '',
00135                     'encoding': 'ISO-8859-1',
00136                     },
00137                 'driver': {
00138                     'type': 'default'
00139                     },
00140                 'alignExtent' : {
00141                     'enabled' : True
00142                     },
00143                 'compResolution' : {
00144                     'enabled' : False
00145                     },
00146                 'autoRendering': {
00147                     'enabled' : True
00148                     },
00149                 'autoZooming' : {
00150                     'enabled' : False
00151                     },
00152                 'statusbarMode': {
00153                     'selection' : 0
00154                     },
00155                 'bgcolor': {
00156                     'color' : (255, 255, 255, 255),
00157                     },
00158                 'mouseWheelZoom' : {
00159                     'enabled' : True,
00160                     'selection' : 0,
00161                     },
00162                 },
00163             #
00164             # projection
00165             #
00166             'projection' : {
00167                 'statusbar' : {
00168                     'proj4'    : '',
00169                     'epsg'     : '',
00170                     'projFile' : projFile,
00171                     },
00172                 'format' : {
00173                     'll'  : 'DMS',
00174                     'precision' : 2,
00175                     },
00176                 },
00177             #
00178             # Attribute Table Manager
00179             #
00180             'atm' : {
00181                 'highlight' : {
00182                     'color' : (255, 255, 0, 255),
00183                     'width' : 2
00184                     },
00185                 'leftDbClick' : {
00186                     'selection' : 1 # draw selected
00187                     },
00188                 'askOnDeleteRec' : {
00189                     'enabled' : True
00190                     },
00191                 'keycolumn' : {
00192                     'value' : 'cat'
00193                     },
00194                 'encoding' : {
00195                     'value' : '',
00196                     }
00197                 },
00198             #
00199             # Command
00200             #
00201             'cmd': {
00202                 'overwrite' : {
00203                     'enabled' : False
00204                     },
00205                 'closeDlg' : {
00206                     'enabled' : False
00207                     },
00208                 'verbosity' : {
00209                     'selection' : 'grassenv'
00210                     },
00211                 # d.rast
00212                 'rasterOverlay' : {
00213                     'enabled' : True
00214                     },
00215                 'rasterColorTable' : {
00216                     'enabled'   : False,
00217                     'selection' : 'rainbow',
00218                     },
00219                 # d.vect
00220                 'showType': {
00221                     'point' : {
00222                         'enabled' : True
00223                         },
00224                     'line' : {
00225                         'enabled' : True
00226                         },
00227                     'centroid' : {
00228                         'enabled' : True
00229                         },
00230                     'boundary' : {
00231                         'enabled' : True
00232                         },
00233                     'area' : {
00234                         'enabled' : True
00235                         },
00236                     'face' : {
00237                         'enabled' : True
00238                         },
00239                     },
00240                 'addNewLayer' : {
00241                     'enabled' : True,
00242                     },
00243                 'interactiveInput' : {
00244                     'enabled' : True,
00245                     },
00246                 },
00247             #
00248             # vdigit
00249             #
00250             'vdigit' : {
00251                 # symbology
00252                 'symbol' : {
00253                     'newSegment' : {
00254                         'enabled' : None,
00255                         'color' : (255, 0, 0, 255)
00256                         }, # red
00257                     'newLine' : {
00258                         'enabled' : None,
00259                         'color' : (0, 86, 45, 255)
00260                         }, # dark green
00261                     'highlight' : {
00262                         'enabled' : None,
00263                         'color' : (255, 255, 0, 255)
00264                         }, # yellow
00265                     'highlightDupl' : {
00266                         'enabled' : None,
00267                         'color' : (255, 72, 0, 255)
00268                         }, # red
00269                     'point' : {
00270                         'enabled' : True,
00271                         'color' : (0, 0, 0, 255)
00272                         }, # black
00273                     'line' : {
00274                         'enabled' : True,
00275                         'color' : (0, 0, 0, 255)
00276                         }, # black
00277                     'boundaryNo' : {
00278                         'enabled' : True,
00279                         'color' : (126, 126, 126, 255)
00280                         }, # grey
00281                     'boundaryOne' : {
00282                         'enabled' : True,
00283                         'color' : (0, 255, 0, 255)
00284                         }, # green
00285                     'boundaryTwo' : {
00286                         'enabled' : True,
00287                         'color' : (255, 135, 0, 255)
00288                         }, # orange
00289                     'centroidIn' : {
00290                         'enabled' : True,
00291                         'color' : (0, 0, 255, 255)
00292                         }, # blue
00293                     'centroidOut' : {
00294                         'enabled' : True,
00295                         'color' : (165, 42, 42, 255)
00296                         }, # brown
00297                     'centroidDup' : {
00298                         'enabled' : True,
00299                         'color' : (156, 62, 206, 255)
00300                         }, # violet
00301                     'nodeOne' : {
00302                         'enabled' : True,
00303                         'color' : (255, 0, 0, 255)
00304                         }, # red
00305                     'nodeTwo' : {
00306                         'enabled' : True,
00307                         'color' : (0, 86, 45, 255)
00308                         }, # dark green
00309                     'vertex' : {
00310                         'enabled' : False,
00311                         'color' : (255, 20, 147, 255)
00312                         }, # deep pink
00313                     'area' : {
00314                         'enabled' : True,
00315                         'color' : (217, 255, 217, 255)
00316                         }, # green
00317                     'direction' : {
00318                         'enabled' : False,
00319                         'color' : (255, 0, 0, 255)
00320                         }, # red
00321                     },
00322                 # display
00323                 'lineWidth' : {
00324                     'value' : 2,
00325                     'units' : 'screen pixels'
00326                     },
00327                 # snapping
00328                 'snapping' : {
00329                     'value' : 10,
00330                     'units' : 'screen pixels'
00331                     },
00332                 'snapToVertex' : {
00333                     'enabled' : False
00334                     },
00335                 # digitize new record
00336                 'addRecord' : {
00337                     'enabled' : True
00338                     },
00339                 'layer' :{
00340                     'value' : 1
00341                     },
00342                 'category' : {
00343                     'value' : 1
00344                     },
00345                 'categoryMode' : {
00346                     'selection' : 0
00347                     },
00348                 # delete existing feature(s)
00349                 'delRecord' : {
00350                     'enabled' : True
00351                     },
00352                 # query tool
00353                 'query' : {
00354                     'selection' : 0,
00355                     'box' : True
00356                     },
00357                 'queryLength' : {
00358                     'than-selection' : 0,
00359                     'thresh' : 0
00360                     },
00361                 'queryDangle' : {
00362                     'than-selection' : 0,
00363                     'thresh' : 0
00364                     },
00365                 # select feature (point, line, centroid, boundary)
00366                 'selectType': {
00367                     'point' : {
00368                         'enabled' : True
00369                         },
00370                     'line' : {
00371                         'enabled' : True
00372                         },
00373                     'centroid' : {
00374                         'enabled' : True
00375                         },
00376                     'boundary' : {
00377                         'enabled' : True
00378                         },
00379                     },
00380                 'selectThresh' : {
00381                     'value' : 10,
00382                     'units' : 'screen pixels'
00383                     },
00384                 'checkForDupl' : {
00385                     'enabled' : False
00386                     },
00387                 'selectInside' : {
00388                     'enabled' : False
00389                     },
00390                 # exit
00391                 'saveOnExit' : {
00392                     'enabled' : False,
00393                     },
00394                 # break lines on intersection
00395                 'breakLines' : {
00396                     'enabled' : False,
00397                     },
00398                 },
00399             'profile': {
00400                 'raster0' : {
00401                     'pcolor' : (0, 0, 255, 255), # profile line color
00402                     'pwidth' : 1, # profile line width
00403                     'pstyle' : 'solid', # profile line pen style
00404                     },
00405                 'raster1' : {
00406                     'pcolor' : (255, 0, 0, 255), 
00407                     'pwidth' : 1, 
00408                     'pstyle' : 'solid', 
00409                     },
00410                 'raster2' : {
00411                     'pcolor' : (0, 255, 0, 255), 
00412                     'pwidth' : 1, 
00413                     'pstyle' : 'solid', 
00414                     },
00415                 'font' : {
00416                     'titleSize' : 12,
00417                     'axisSize' : 11,
00418                     'legendSize' : 10,
00419                     },
00420                 'marker' : {
00421                     'color' : (0, 0, 0, 255),
00422                     'fill' : 'transparent',
00423                     'size' : 2,
00424                     'type' : 'triangle',
00425                     'legend' : _('Segment break'),
00426                     },
00427                 'grid' : {
00428                     'color' : (200, 200, 200, 255),
00429                     'enabled' : True,
00430                     },
00431                 'x-axis' : {
00432                     'type' : 'auto', # axis format
00433                     'min' : 0, # axis min for custom axis range
00434                     'max': 0, # axis max for custom axis range
00435                     'log' : False,
00436                     },
00437                 'y-axis' : {
00438                     'type' : 'auto', # axis format
00439                     'min' : 0, # axis min for custom axis range
00440                     'max': 0, # axis max for custom axis range
00441                     'log' : False,
00442                     },
00443                 'legend' : {
00444                     'enabled' : True
00445                     },
00446                 },
00447             'gcpman' : {
00448                 'rms' : {
00449                     'highestonly' : True,
00450                     'sdfactor' : 1,
00451                     },
00452                 'symbol' : {
00453                     'color' : (0, 0, 255, 255),
00454                     'hcolor' : (255, 0, 0, 255),
00455                     'scolor' : (0, 255, 0, 255),
00456                     'ucolor' : (255, 165, 0, 255),
00457                     'unused' : True,
00458                     'size' : 8,
00459                     'width' : 2,
00460                     },
00461                 },
00462             'nviz' : {
00463                 'view' : {
00464                     'persp' : {
00465                         'value' : 20,
00466                         'step' : 2,
00467                         },
00468                     'position' : {
00469                         'x' : 0.84,
00470                         'y' : 0.16,
00471                         },
00472                     'twist' : {
00473                         'value' : 0,
00474                         },
00475                     'z-exag' : {
00476                         'min' : 0,
00477                         'max' : 10,
00478                         'value': 1,
00479                         },
00480                     'background' : {
00481                         'color' : (255, 255, 255, 255), # white
00482                         },
00483                     },
00484                 'fly' : {
00485                     'exag' : {
00486                         'move' : 5,
00487                         'turn' : 5,
00488                         }
00489                     },
00490                 'animation' : {
00491                     'fps' : 24,
00492                     'prefix' : _("animation")
00493                     },
00494                 'surface' : {
00495                     'shine': {
00496                         'map' : False,
00497                         'value' : 60.0,
00498                         },
00499                     'color' : {
00500                         'map' : True,
00501                         'value' : (100, 100, 100, 255), # constant: grey
00502                         },
00503                     'draw' : {
00504                         'wire-color' : (136, 136, 136, 255),
00505                         'mode' : 1, # fine
00506                         'style' : 1, # surface
00507                         'shading' : 1, # gouraud
00508                         'res-fine' : 6,
00509                         'res-coarse' : 9,
00510                         },
00511                     'position' : {
00512                         'x' : 0,
00513                         'y' : 0,
00514                         'z' : 0,
00515                         },
00516                     },
00517                 'constant' : {
00518                     'color' : (100, 100, 100, 255),
00519                     'value' : 0.0,
00520                     'transp' : 0,
00521                     'resolution': 6
00522                 },
00523                 'vector' : {
00524                     'lines' : {
00525                         'show' : False,
00526                         'width' : 2,
00527                         'color' : (0, 0, 255, 255), # blue
00528                         'flat' : False,
00529                         'height' : 0,
00530                         },
00531                     'points' : {
00532                         'show' : False,
00533                         'size' : 100,
00534                         'width' : 2,
00535                         'marker' : 2,
00536                         'color' : (0, 0, 255, 255), # blue
00537                         'height' : 0,
00538                         }
00539                     },
00540                 'volume' : {
00541                     'color' : {
00542                         'map' : True,
00543                         'value' : (100, 100, 100, 255), # constant: grey
00544                         },
00545                     'draw' : {
00546                         'mode'       : 0, # isosurfaces
00547                         'shading'    : 1, # gouraud
00548                         'resolution' : 3, # polygon resolution
00549                         },
00550                     'shine': {
00551                         'map' : False,
00552                         'value' : 60,
00553                         },
00554                     'topo': {
00555                         'map' : None,
00556                         'value' : 0.0
00557                         },
00558                     'transp': {
00559                         'map' : None,
00560                         'value': 0
00561                         },
00562                     'mask': {
00563                         'map' : None,
00564                         'value': ''
00565                         },
00566                     'slice_position': {
00567                         'x1' : 0,
00568                         'x2' : 1,
00569                         'y1' : 0,
00570                         'y2' : 1,
00571                         'z1' : 0,
00572                         'z2' : 1,
00573                         'axis' : 0,
00574                         }
00575                     },
00576                 'cplane' : {
00577                     'shading': 4,
00578                     'rotation':{
00579                         'rot': 0, 
00580                         'tilt': 0
00581                         }, 
00582                     'position':{
00583                         'x' : 0,
00584                         'y' : 0,
00585                         'z' : 0
00586                     }   
00587                 },
00588                 'light' : {
00589                     'position' : {
00590                         'x' : 0.68,
00591                         'y' : -0.68,
00592                         'z' : 80,
00593                         },
00594                     'bright'  : 80,
00595                     'color'   : (255, 255, 255, 255), # white
00596                     'ambient' : 20,
00597                     },
00598                 'fringe' : {
00599                     'elev'   : 55,
00600                     'color'  : (128, 128, 128, 255), # grey
00601                     },
00602                 'arrow': {
00603                     'color': (0, 0, 0),
00604                     },
00605                 'scalebar': {
00606                     'color': (0, 0, 0),
00607                     }
00608                 },
00609             'modeler' : {
00610                 'disabled': {
00611                     'color': (211, 211, 211, 255), # light grey
00612                     },
00613                 'action' : {
00614                     'color' : {
00615                         'valid'   :  (180, 234, 154, 255), # light green
00616                         'invalid' :  (255, 255, 255, 255), # white
00617                         'running' :  (255, 0, 0, 255),     # red
00618                         },
00619                     'size' : {
00620                         'width'  : 125,
00621                         'height' : 50,
00622                         },
00623                     'width': {
00624                         'parameterized' : 2,
00625                         'default'       : 1,
00626                         },
00627                     },
00628                 'data' : { 
00629                     'color': {
00630                         'raster'   : (215, 215, 248, 255), # light blue
00631                         'raster3d' : (215, 248, 215, 255), # light green
00632                         'vector'   : (248, 215, 215, 255), # light red
00633                         },
00634                     'size' : {
00635                         'width' : 175,
00636                         'height' : 50,
00637                         },
00638                     },
00639                 'loop' : {
00640                     'color' : {
00641                         'valid'   :  (234, 226, 154, 255), # light yellow
00642                         },
00643                     'size' : {
00644                         'width' : 175,
00645                         'height' : 40,
00646                         },
00647                     },
00648                 'if-else' : {
00649                     'size' : {
00650                         'width' : 150,
00651                         'height' : 40,
00652                         },
00653                     },
00654                 },
00655             }
00656 
00657         # quick fix, http://trac.osgeo.org/grass/ticket/1233
00658         # TODO
00659         if sys.platform == 'darwin':
00660             self.defaultSettings['general']['defWindowPos']['enabled'] = False
00661 
00662     def _internalSettings(self):
00663         """!Define internal settings (based on user settings)
00664         """
00665         self.internalSettings = {}
00666         for group in self.userSettings.keys():
00667             self.internalSettings[group] = {}
00668             for key in self.userSettings[group].keys():
00669                 self.internalSettings[group][key] = {}
00670 
00671         # self.internalSettings['general']["mapsetPath"]['value'] = self.GetMapsetPath()
00672         self.internalSettings['appearance']['elementListExpand']['choices'] = \
00673             (_("Collapse all except PERMANENT and current"),
00674              _("Collapse all except PERMANENT"),
00675              _("Collapse all except current"),
00676              _("Collapse all"),
00677              _("Expand all"))
00678         self.internalSettings['atm']['leftDbClick']['choices'] = (_('Edit selected record'),
00679                                                                   _('Display selected'))
00680         
00681         self.internalSettings['cmd']['verbosity']['choices'] = ('grassenv',
00682                                                                 'verbose',
00683                                                                 'quiet')
00684         
00685         self.internalSettings['appearance']['iconTheme']['choices'] = ('grass',
00686                                                                        'grass2',
00687                                                                        'silk')
00688         self.internalSettings['appearance']['menustyle']['choices'] = \
00689                    (_("Classic (labels only)"),
00690                     _("Combined (labels and module names)"),
00691                     _("Professional (module names only)"))
00692         self.internalSettings['appearance']['gSelectPopupHeight']['min'] = 50
00693         # there is also maxHeight given to TreeCtrlComboPopup.GetAdjustedSize
00694         self.internalSettings['appearance']['gSelectPopupHeight']['max'] = 1000
00695         
00696         self.internalSettings['display']['driver']['choices'] = ['default']
00697         self.internalSettings['display']['statusbarMode']['choices'] = None # set during MapFrame init
00698         self.internalSettings['display']['mouseWheelZoom']['choices'] = (_('Scroll forward to zoom in'),
00699                                                                          _('Scroll back to zoom in'))
00700 
00701         self.internalSettings['nviz']['view'] = {}
00702         self.internalSettings['nviz']['view']['twist'] = {}
00703         self.internalSettings['nviz']['view']['twist']['min'] = -180
00704         self.internalSettings['nviz']['view']['twist']['max'] = 180
00705         self.internalSettings['nviz']['view']['persp'] = {}
00706         self.internalSettings['nviz']['view']['persp']['min'] = 1
00707         self.internalSettings['nviz']['view']['persp']['max'] = 100
00708         self.internalSettings['nviz']['view']['height'] = {}
00709         self.internalSettings['nviz']['view']['height']['value'] = -1
00710         self.internalSettings['nviz']['view']['z-exag'] = {}
00711         self.internalSettings['nviz']['view']['z-exag']['original'] = 1
00712         self.internalSettings['nviz']['view']['rotation'] = None
00713         self.internalSettings['nviz']['view']['focus'] = {}
00714         self.internalSettings['nviz']['view']['focus']['x'] = -1
00715         self.internalSettings['nviz']['view']['focus']['y'] = -1
00716         self.internalSettings['nviz']['view']['focus']['z'] = -1
00717         self.internalSettings['nviz']['view']['dir'] = {}
00718         self.internalSettings['nviz']['view']['dir']['x'] = -1
00719         self.internalSettings['nviz']['view']['dir']['y'] = -1
00720         self.internalSettings['nviz']['view']['dir']['z'] = -1
00721         self.internalSettings['nviz']['view']['dir']['use'] = False
00722         
00723         for decor in ('arrow', 'scalebar'):
00724             self.internalSettings['nviz'][decor] = {}
00725             self.internalSettings['nviz'][decor]['position'] = {}
00726             self.internalSettings['nviz'][decor]['position']['x'] = 0
00727             self.internalSettings['nviz'][decor]['position']['y'] = 0
00728             self.internalSettings['nviz'][decor]['size'] = 100
00729         self.internalSettings['nviz']['vector'] = {}
00730         self.internalSettings['nviz']['vector']['points'] = {}
00731         self.internalSettings['nviz']['vector']['points']['marker'] = ("x",
00732                                                                        _("box"),
00733                                                                        _("sphere"),
00734                                                                        _("cube"),
00735                                                                        _("diamond"),
00736                                                                        _("dtree"),
00737                                                                        _("ctree"),
00738                                                                        _("aster"),
00739                                                                        _("gyro"),
00740                                                                        _("histogram"))
00741         self.internalSettings['vdigit']['bgmap'] = {}
00742         self.internalSettings['vdigit']['bgmap']['value'] = ''
00743         
00744     def ReadSettingsFile(self, settings = None):
00745         """!Reads settings file (mapset, location, gisdbase)"""
00746         if settings is None:
00747             settings = self.userSettings
00748         
00749         self._readFile(self.filePath, settings)
00750         
00751         # set environment variables
00752         font = self.Get(group = 'display', key = 'font', subkey = 'type')
00753         enc  = self.Get(group = 'display', key = 'font', subkey = 'encoding')
00754         if font:
00755             os.environ["GRASS_FONT"] = font
00756         if enc:
00757             os.environ["GRASS_ENCODING"] = enc
00758         
00759     def _readFile(self, filename, settings = None):
00760         """!Read settings from file to dict
00761 
00762         @param filename settings file path
00763         @param settings dict where to store settings (None for self.userSettings)
00764         """
00765         if settings is None:
00766             settings = self.userSettings
00767         
00768         if not os.path.exists(filename):
00769             # try alternative path
00770             filename = os.path.join(os.path.expanduser("~"), '.grasswx6')
00771             if not os.path.exists(filename):
00772                 return
00773         
00774         try:
00775             fd = open(filename, "r")
00776         except IOError:
00777             sys.stderr.write(_("Unable to read settings file <%s>\n") % filename)
00778             return
00779         
00780         try:
00781             line = ''
00782             for line in fd.readlines():
00783                 line = line.rstrip('%s' % os.linesep)
00784                 group, key = line.split(self.sep)[0:2]
00785                 kv = line.split(self.sep)[2:]
00786                 subkeyMaster = None
00787                 if len(kv) % 2 != 0: # multiple (e.g. nviz)
00788                     subkeyMaster = kv[0]
00789                     del kv[0]
00790                 idx = 0
00791                 while idx < len(kv):
00792                     if subkeyMaster:
00793                         subkey = [subkeyMaster, kv[idx]]
00794                     else:
00795                         subkey = kv[idx]
00796                     value = kv[idx+1]
00797                     value = self._parseValue(value, read = True)
00798                     self.Append(settings, group, key, subkey, value)
00799                     idx += 2
00800         except ValueError, e:
00801             print >> sys.stderr, _("Error: Reading settings from file <%(file)s> failed.\n"
00802                                    "\t\tDetails: %(detail)s\n"
00803                                    "\t\tLine: '%(line)s'\n") % { 'file' : filename,
00804                                                                  'detail' : e,
00805                                                                  'line' : line }
00806             fd.close()
00807         
00808         fd.close()
00809         
00810     def SaveToFile(self, settings = None):
00811         """!Save settings to the file"""
00812         if settings is None:
00813             settings = self.userSettings
00814         
00815         dirPath = GetSettingsPath()
00816         if not os.path.exists(dirPath):
00817             try:
00818                 os.mkdir(dirPath)
00819             except:
00820                 GError(_('Unable to create settings directory'))
00821                 return
00822         
00823         try:
00824             file = open(self.filePath, "w")
00825             for group in settings.keys():
00826                 for key in settings[group].keys():
00827                     subkeys = settings[group][key].keys()
00828                     file.write('%s%s%s%s' % (group, self.sep, key, self.sep))
00829                     for idx in range(len(subkeys)):
00830                         value = settings[group][key][subkeys[idx]]
00831                         if type(value) == types.DictType:
00832                             if idx > 0:
00833                                 file.write('%s%s%s%s%s' % (os.linesep, group, self.sep, key, self.sep))
00834                             file.write('%s%s' % (subkeys[idx], self.sep))
00835                             kvalues = settings[group][key][subkeys[idx]].keys()
00836                             srange = range(len(kvalues))
00837                             for sidx in srange:
00838                                 svalue = self._parseValue(settings[group][key][subkeys[idx]][kvalues[sidx]])
00839                                 file.write('%s%s%s' % (kvalues[sidx], self.sep,
00840                                                        svalue))
00841                                 if sidx < len(kvalues) - 1:
00842                                     file.write('%s' % self.sep)
00843                         else:
00844                             if idx > 0 and \
00845                                     type(settings[group][key][subkeys[idx - 1]]) == types.DictType:
00846                                 file.write('%s%s%s%s%s' % (os.linesep, group, self.sep, key, self.sep))
00847                             value = self._parseValue(settings[group][key][subkeys[idx]])
00848                             file.write('%s%s%s' % (subkeys[idx], self.sep, value))
00849                             if idx < len(subkeys) - 1 and \
00850                                     type(settings[group][key][subkeys[idx + 1]]) != types.DictType:
00851                                 file.write('%s' % self.sep)
00852                     file.write(os.linesep)
00853         except IOError, e:
00854             raise GException(e)
00855         except StandardError, e:
00856             raise GException(_('Writing settings to file <%(file)s> failed.'
00857                                '\n\nDetails: %(detail)s') % { 'file' : self.filePath,
00858                                                               'detail' : e })
00859         
00860         file.close()
00861         
00862     def _parseValue(self, value, read = False):
00863         """!Parse value to be store in settings file"""
00864         if read: # -> read settings (cast values)
00865             if value == 'True':
00866                 value = True
00867             elif value == 'False':
00868                 value = False
00869             elif value == 'None':
00870                 value = None
00871             elif ':' in value: # -> color
00872                 try:
00873                     value = tuple(map(int, value.split(':')))
00874                 except ValueError: # -> string
00875                     pass
00876             else:
00877                 try:
00878                     value = int(value)
00879                 except ValueError:
00880                     try:
00881                         value = float(value)
00882                     except ValueError:
00883                         pass
00884         else: # -> write settings
00885             if type(value) == type(()): # -> color
00886                 value = str(value[0]) + ':' +\
00887                     str(value[1]) + ':' + \
00888                     str(value[2])
00889                 
00890         return value
00891 
00892     def Get(self, group, key = None, subkey = None, internal = False):
00893         """!Get value by key/subkey
00894 
00895         Raise KeyError if key is not found
00896         
00897         @param group settings group
00898         @param key (value, None)
00899         @param subkey (value, list or None)
00900         @param internal use internal settings instead
00901 
00902         @return value
00903         """
00904         if internal is True:
00905             settings = self.internalSettings
00906         else:
00907             settings = self.userSettings
00908             
00909         try:
00910             if subkey is None:
00911                 if key is None:
00912                     return settings[group]
00913                 else:
00914                     return settings[group][key]
00915             else:
00916                 if type(subkey) == type(tuple()) or \
00917                         type(subkey) == type(list()):
00918                     return settings[group][key][subkey[0]][subkey[1]]
00919                 else:
00920                     return settings[group][key][subkey]  
00921 
00922         except KeyError:
00923             print >> sys.stderr, "Settings: unable to get value '%s:%s:%s'\n" % \
00924                 (group, key, subkey)
00925         
00926     def Set(self, group, value, key = None, subkey = None, internal = False):
00927         """!Set value of key/subkey
00928         
00929         Raise KeyError if group/key is not found
00930         
00931         @param group settings group
00932         @param key key (value, None)
00933         @param subkey subkey (value, list or None)
00934         @param value value
00935         @param internal use internal settings instead
00936         """
00937         if internal is True:
00938             settings = self.internalSettings
00939         else:
00940             settings = self.userSettings
00941         
00942         try:
00943             if subkey is None:
00944                 if key is None:
00945                     settings[group] = value
00946                 else:
00947                     settings[group][key] = value
00948             else:
00949                 if type(subkey) == type(tuple()) or \
00950                         type(subkey) == type(list()):
00951                     settings[group][key][subkey[0]][subkey[1]] = value
00952                 else:
00953                     settings[group][key][subkey] = value
00954         except KeyError:
00955             raise GException("%s '%s:%s:%s'" % (_("Unable to set "), group, key, subkey))
00956         
00957     def Append(self, dict, group, key, subkey, value):
00958         """!Set value of key/subkey
00959 
00960         Create group/key/subkey if not exists
00961         
00962         @param dict settings dictionary to use
00963         @param group settings group
00964         @param key key
00965         @param subkey subkey (value or list)
00966         @param value value
00967         """
00968         if group not in dict:
00969             dict[group] = {}
00970         
00971         if key not in dict[group]:
00972             dict[group][key] = {}
00973         
00974         if type(subkey) == types.ListType:
00975             # TODO: len(subkey) > 2
00976             if subkey[0] not in dict[group][key]:
00977                 dict[group][key][subkey[0]] = {}
00978             try:
00979                 dict[group][key][subkey[0]][subkey[1]] = value
00980             except TypeError:
00981                 print >> sys.stderr, _("Unable to parse settings '%s'") % value + \
00982                     ' (' + group + ':' + key + ':' + subkey[0] + ':' + subkey[1] + ')'
00983         else:
00984             try:
00985                 dict[group][key][subkey] = value
00986             except TypeError:
00987                 print >> sys.stderr, _("Unable to parse settings '%s'") % value + \
00988                     ' (' + group + ':' + key + ':' + subkey + ')'
00989         
00990     def GetDefaultSettings(self):
00991         """!Get default user settings"""
00992         return self.defaultSettings
00993 
00994     def Reset(self, key = None):
00995         """!Reset to default settings
00996 
00997         @key key in settings dict (None for all keys)
00998         """
00999         if not key:
01000             self.userSettings = copy.deepcopy(self.defaultSettings)
01001         else:
01002             self.userSettings[key] = copy.deepcopy(self.defaultSettings[key])
01003         
01004 UserSettings = Settings()