GRASS Programmer's Manual  6.4.2(2012)
preferences.py
Go to the documentation of this file.
00001 """!
00002 @package preferences
00003 
00004 @brief User preferences dialog
00005 
00006 Sets default display font, etc.
00007 If you want to add some value to settings you have to add default value 
00008 to defaultSettings and set constraints in internalSettings in Settings class.
00009 Everything can be used in PreferencesDialog.
00010 
00011 Classes:
00012  - Settings
00013  - PreferencesBaseDialog
00014  - PreferencesDialog
00015  - DefaultFontDialog
00016  - MapsetAccess
00017  - NvizPreferencesDialog
00018 
00019 (C) 2007-2011 by the GRASS Development Team
00020 This program is free software under the GNU General Public
00021 License (>=v2). Read the file COPYING that comes with GRASS
00022 for details.
00023 
00024 @author Michael Barton (Arizona State University)
00025 @author Martin Landa <landa.martin gmail.com>
00026 @author Vaclav Petras <wenzeslaus gmail.com> (menu customization)
00027 """
00028 
00029 import os
00030 import sys
00031 import copy
00032 import stat
00033 import types
00034 try:
00035     import pwd
00036     havePwd = True
00037 except ImportError:
00038     havePwd = False
00039 
00040 ### i18N
00041 import gettext
00042 gettext.install('grasswxpy', os.path.join(os.getenv("GISBASE"), 'locale'), unicode = True)
00043 
00044 import wx
00045 import wx.lib.filebrowsebutton as filebrowse
00046 import wx.lib.colourselect as csel
00047 import wx.lib.mixins.listctrl as listmix
00048 
00049 from grass.script import core as grass
00050 
00051 import gcmd
00052 import utils
00053 import globalvar
00054 from debug import Debug as Debug
00055 
00056 from wx.lib.newevent import NewEvent
00057 
00058 wxSettingsChanged, EVT_SETTINGS_CHANGED = NewEvent()
00059 
00060 class Settings:
00061     """!Generic class where to store settings"""
00062     def __init__(self):
00063         # settings file
00064         self.filePath = os.path.join(utils.GetSettingsPath(), 'wx')
00065         
00066         # key/value separator
00067         self.sep = ';'
00068         
00069         try:
00070             projFile = utils.PathJoin(os.environ["GRASS_PROJSHARE"], 'epsg')
00071         except KeyError:
00072             projFile = ''
00073         
00074         #
00075         # default settings
00076         #
00077         self.defaultSettings = {
00078             #
00079             # general
00080             #
00081             'general': {
00082                 # use default window layout (layer manager, displays, ...)
00083                 'defWindowPos' : {
00084                     'enabled' : True,
00085                     'dim' : '0,0,%d,%d,%d,0,%d,%d' % \
00086                         (globalvar.GM_WINDOW_SIZE[0],
00087                          globalvar.GM_WINDOW_SIZE[1],
00088                          globalvar.GM_WINDOW_SIZE[0],
00089                          globalvar.MAP_WINDOW_SIZE[0],
00090                          globalvar.MAP_WINDOW_SIZE[1])
00091                     },
00092                 # workspace
00093                 'workspace' : {
00094                     'posDisplay' : {
00095                         'enabled' : False
00096                         },
00097                     'posManager' : {
00098                         'enabled' : False
00099                         },
00100                     },
00101                 },
00102             'manager' : {
00103                 # show opacity level widget
00104                 'changeOpacityLevel' : {
00105                     'enabled' : False
00106                     }, 
00107                 # ask when removing layer from layer tree
00108                 'askOnRemoveLayer' : {
00109                     'enabled' : True
00110                     },
00111                 # ask when quiting wxGUI or closing display
00112                 'askOnQuit' : {
00113                     'enabled' : True
00114                     },
00115                 # hide tabs
00116                 'hideTabs' : {
00117                     'search' : False,
00118                     'pyshell' : False,
00119                     },
00120                 'copySelectedTextToClipboard' : {
00121                     'enabled' : False
00122                     },
00123                 },
00124             #
00125             # appearance
00126             #
00127             'appearance': {
00128                 'outputfont' : {
00129                     'type' : 'Courier New',
00130                     'size': '10',
00131                     },
00132                 # expand/collapse element list
00133                 'elementListExpand' : {
00134                     'selection' : 0 
00135                     },
00136                 'menustyle' : {
00137                     'selection' : 1
00138                     },
00139                 'gSelectPopupHeight' : {
00140                     'value' : 200
00141                     },
00142                 'iconTheme' : {
00143                     'type' : 'grass2'
00144                     }, # grass2, grass, silk
00145                 },
00146             #
00147             # display
00148             #
00149             'display': {
00150                 'font' : {
00151                     'type' : '',
00152                     'encoding': 'ISO-8859-1',
00153                     },
00154                 'driver': {
00155                     'type': 'default'
00156                     },
00157                 'compResolution' : {
00158                     'enabled' : False
00159                     },
00160                 'autoRendering': {
00161                     'enabled' : True
00162                     },
00163                 'autoZooming' : {
00164                     'enabled' : False
00165                     },
00166                 'statusbarMode': {
00167                     'selection' : 0
00168                     },
00169                 'bgcolor': {
00170                     'color' : (255, 255, 255, 255),
00171                     },
00172                 },
00173             #
00174             # projection
00175             #
00176             'projection' : {
00177                 'statusbar' : {
00178                     'proj4'    : '',
00179                     'epsg'     : '',
00180                     'projFile' : projFile,
00181                     },
00182                 'format' : {
00183                     'll'  : 'DMS',
00184                     'precision' : 2,
00185                     },
00186                 },
00187             #
00188             # Attribute Table Manager
00189             #
00190             'atm' : {
00191                 'highlight' : {
00192                     'color' : (255, 255, 0, 255),
00193                     'width' : 2
00194                     },
00195                 'leftDbClick' : {
00196                     'selection' : 1 # draw selected
00197                     },
00198                 'askOnDeleteRec' : {
00199                     'enabled' : True
00200                     },
00201                 'keycolumn' : {
00202                     'value' : 'cat'
00203                     },
00204                 'encoding' : {
00205                     'value' : '',
00206                     }
00207                 },
00208             #
00209             # Command
00210             #
00211             'cmd': {
00212                 'overwrite' : {
00213                     'enabled' : False
00214                     },
00215                 'closeDlg' : {
00216                     'enabled' : False
00217                     },
00218                 'verbosity' : {
00219                     'selection' : 'grassenv'
00220                     },
00221                 # d.rast
00222                 'rasterOverlay' : {
00223                     'enabled' : True
00224                     },
00225                 'rasterColorTable' : {
00226                     'enabled'   : False,
00227                     'selection' : 'rainbow',
00228                     },
00229                 # d.vect
00230                 'showType': {
00231                     'point' : {
00232                         'enabled' : True
00233                         },
00234                     'line' : {
00235                         'enabled' : True
00236                         },
00237                     'centroid' : {
00238                         'enabled' : True
00239                         },
00240                     'boundary' : {
00241                         'enabled' : True
00242                         },
00243                     'area' : {
00244                         'enabled' : True
00245                         },
00246                     'face' : {
00247                         'enabled' : True
00248                         },
00249                     },
00250                 'addNewLayer' : {
00251                     'enabled' : True,
00252                     },
00253                 'interactiveInput' : {
00254                     'enabled' : True,
00255                     },
00256                 },
00257             #
00258             # vdigit
00259             #
00260             'vdigit' : {
00261                 # symbology
00262                 'symbol' : {
00263                     'highlight' : {
00264                         'enabled' : None,
00265                         'color' : (255, 255, 0, 255)
00266                         }, # yellow
00267                     'highlightDupl' : {
00268                         'enabled' : None,
00269                         'color' : (255, 72, 0, 255)
00270                         }, # red
00271                     'point' : {
00272                         'enabled' : True,
00273                         'color' : (0, 0, 0, 255)
00274                         }, # black
00275                     'line' : {
00276                         'enabled' : True,
00277                         'color' : (0, 0, 0, 255)
00278                         }, # black
00279                     'boundaryNo' : {
00280                         'enabled' : True,
00281                         'color' : (126, 126, 126, 255)
00282                         }, # grey
00283                     'boundaryOne' : {
00284                         'enabled' : True,
00285                         'color' : (0, 255, 0, 255)
00286                         }, # green
00287                     'boundaryTwo' : {
00288                         'enabled' : True,
00289                         'color' : (255, 135, 0, 255)
00290                         }, # orange
00291                     'centroidIn' : {
00292                         'enabled' : True,
00293                         'color' : (0, 0, 255, 255)
00294                         }, # blue
00295                     'centroidOut' : {
00296                         'enabled' : True,
00297                         'color' : (165, 42, 42, 255)
00298                         }, # brown
00299                     'centroidDup' : {
00300                         'enabled' : True,
00301                         'color' : (156, 62, 206, 255)
00302                         }, # violet
00303                     'nodeOne' : {
00304                         'enabled' : True,
00305                         'color' : (255, 0, 0, 255)
00306                         }, # red
00307                     'nodeTwo' : {
00308                         'enabled' : True,
00309                         'color' : (0, 86, 45, 255)
00310                         }, # dark green
00311                     'vertex' : {
00312                         'enabled' : False,
00313                         'color' : (255, 20, 147, 255)
00314                         }, # deep pink
00315                     'area' : {
00316                         'enabled' : False,
00317                         'color' : (217, 255, 217, 255)
00318                         }, # green
00319                     'direction' : {
00320                         'enabled' : False,
00321                         'color' : (255, 0, 0, 255)
00322                         }, # red
00323                     },
00324                 # display
00325                 'lineWidth' : {
00326                     'value' : 2,
00327                     'units' : 'screen pixels'
00328                     },
00329                 # snapping
00330                 'snapping' : {
00331                     'value' : 10,
00332                     'units' : 'screen pixels'
00333                     },
00334                 'snapToVertex' : {
00335                     'enabled' : False
00336                     },
00337                 # digitize new record
00338                 'addRecord' : {
00339                     'enabled' : True
00340                     },
00341                 'layer' :{
00342                     'value' : 1
00343                     },
00344                 'category' : {
00345                     'value' : 1
00346                     },
00347                 'categoryMode' : {
00348                     'selection' : 0
00349                     },
00350                 # delete existing feature(s)
00351                 'delRecord' : {
00352                     'enabled' : True
00353                     },
00354                 # query tool
00355                 'query' : {
00356                     'selection' : 0,
00357                     'box' : True
00358                     },
00359                 'queryLength' : {
00360                     'than-selection' : 0,
00361                     'thresh' : 0
00362                     },
00363                 'queryDangle' : {
00364                     'than-selection' : 0,
00365                     'thresh' : 0
00366                     },
00367                 # select feature (point, line, centroid, boundary)
00368                 'selectType': {
00369                     'point' : {
00370                         'enabled' : True
00371                         },
00372                     'line' : {
00373                         'enabled' : True
00374                         },
00375                     'centroid' : {
00376                         'enabled' : True
00377                         },
00378                     'boundary' : {
00379                         'enabled' : True
00380                         },
00381                     },
00382                 'selectThresh' : {
00383                     'value' : 10,
00384                     'units' : 'screen pixels'
00385                     },
00386                 'checkForDupl' : {
00387                     'enabled' : False
00388                     },
00389                 'selectInside' : {
00390                     'enabled' : False
00391                     },
00392                 # exit
00393                 'saveOnExit' : {
00394                     'enabled' : False,
00395                     },
00396                 # break lines on intersection
00397                 'breakLines' : {
00398                     'enabled' : False,
00399                     },
00400                 },
00401             'profile': {
00402                 'raster0' : {
00403                     'pcolor' : (0, 0, 255, 255), # profile line color
00404                     'pwidth' : 1, # profile line width
00405                     'pstyle' : 'solid', # profile line pen style
00406                     },
00407                 'raster1' : {
00408                     'pcolor' : (255, 0, 0, 255), 
00409                     'pwidth' : 1, 
00410                     'pstyle' : 'solid', 
00411                     },
00412                 'raster2' : {
00413                     'pcolor' : (0, 255, 0, 255), 
00414                     'pwidth' : 1, 
00415                     'pstyle' : 'solid', 
00416                     },
00417                 'font' : {
00418                     'titleSize' : 12,
00419                     'axisSize' : 11,
00420                     'legendSize' : 10,
00421                     },
00422                 'marker' : {
00423                     'color' : (0, 0, 0, 255),
00424                     'fill' : 'transparent',
00425                     'size' : 2,
00426                     'type' : 'triangle',
00427                     'legend' : _('Segment break'),
00428                     },
00429                 'grid' : {
00430                     'color' : (200, 200, 200, 255),
00431                     'enabled' : True,
00432                     },
00433                 'x-axis' : {
00434                     'type' : 'auto', # axis format
00435                     'min' : 0, # axis min for custom axis range
00436                     'max': 0, # axis max for custom axis range
00437                     'log' : False,
00438                     },
00439                 'y-axis' : {
00440                     'type' : 'auto', # axis format
00441                     'min' : 0, # axis min for custom axis range
00442                     'max': 0, # axis max for custom axis range
00443                     'log' : False,
00444                     },
00445                 'legend' : {
00446                     'enabled' : True
00447                     },
00448                 },
00449             'gcpman' : {
00450                 'rms' : {
00451                     'highestonly' : True,
00452                     'sdfactor' : 1,
00453                     },
00454                 'symbol' : {
00455                     'color' : (0, 0, 255, 255),
00456                     'hcolor' : (255, 0, 0, 255),
00457                     'scolor' : (0, 255, 0, 255),
00458                     'ucolor' : (255, 165, 0, 255),
00459                     'unused' : True,
00460                     'size' : 8,
00461                     'width' : 2,
00462                     },
00463                 },
00464             'georect' : {
00465                 'symbol' : {
00466                     'color' : (0, 0, 255, 255),
00467                     'width' : 2,
00468                     },
00469                 },
00470             'nviz' : {
00471                 'view' : {
00472                     'persp' : {
00473                         'value' : 20,
00474                         'step' : 5,
00475                         },
00476                     'position' : {
00477                         'x' : 0.84,
00478                         'y' : 0.16,
00479                         },
00480                     'height' : {
00481                         'step' : 100,
00482                         },
00483                     'twist' : {
00484                         'value' : 0,
00485                         'step' : 5,
00486                         },
00487                     'z-exag' : {
00488                         'step' : 1,
00489                         },
00490                     'background' : {
00491                         'color' : (255, 255, 255, 255), # white
00492                         },
00493                     },
00494                 'surface' : {
00495                     'shine': {
00496                         'map' : False,
00497                         'value' : 60.0,
00498                         },
00499                     'color' : {
00500                         'map' : True,
00501                         'value' : (0, 0, 0, 255), # constant: black
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                 'vector' : {
00518                     'lines' : {
00519                         'show' : False,
00520                         'width' : 2,
00521                         'color' : (0, 0, 255, 255), # blue
00522                         'flat' : False,
00523                         'height' : 0,
00524                         },
00525                     'points' : {
00526                         'show' : False,
00527                         'size' : 100,
00528                         'width' : 2,
00529                         'marker' : 2,
00530                         'color' : (0, 0, 255, 255), # blue
00531                         'height' : 0,
00532                         }
00533                     },
00534                 'volume' : {
00535                     'color' : {
00536                         'map' : True,
00537                         'value' : (0, 0, 0, 255), # constant: black
00538                         },
00539                     'draw' : {
00540                         'mode'       : 0, # isosurfaces
00541                         'shading'    : 1, # gouraud
00542                         'resolution' : 3, # polygon resolution
00543                         },
00544                     'shine': {
00545                         'map' : False,
00546                         'value' : 60,
00547                         },
00548                     },
00549                 'light' : {
00550                     'position' : {
00551                         'x' : 0.68,
00552                         'y' : 0.68,
00553                         'z' : 80,
00554                         },
00555                     'bright'  : 80,
00556                     'color'   : (255, 255, 255, 255), # white
00557                     'ambient' : 20,
00558                     },
00559                 'fringe' : {
00560                     'elev'   : 55,
00561                     'color'  : (128, 128, 128, 255), # grey
00562                     },
00563                 },
00564             'modeler' : {
00565                 'disabled': {
00566                     'color': (211, 211, 211, 255), # light grey
00567                     },
00568                 'action' : {
00569                     'color' : {
00570                         'valid'   :  (180, 234, 154, 255), # light green
00571                         'invalid' :  (255, 255, 255, 255), # white
00572                         'running' :  (255, 0, 0, 255),     # red
00573                         },
00574                     'size' : {
00575                         'width'  : 100,
00576                         'height' : 50,
00577                         },
00578                     'width': {
00579                         'parameterized' : 2,
00580                         'default'       : 1,
00581                         },
00582                     },
00583                 'data' : { 
00584                     'color': {
00585                         'raster'   : (215, 215, 248, 255), # light blue
00586                         'raster3d' : (215, 248, 215, 255), # light green
00587                         'vector'   : (248, 215, 215, 255), # light red
00588                         },
00589                     'size' : {
00590                         'width' : 175,
00591                         'height' : 50,
00592                         },
00593                     },
00594                 'loop' : {
00595                     'color' : {
00596                         'valid'   :  (234, 226, 154, 255), # light yellow
00597                         },
00598                     'size' : {
00599                         'width' : 175,
00600                         'height' : 40,
00601                         },
00602                     },
00603                 'if-else' : {
00604                     'size' : {
00605                         'width' : 150,
00606                         'height' : 40,
00607                         },
00608                     },
00609                 },
00610             }
00611 
00612         # quick fix, http://trac.osgeo.org/grass/ticket/1233
00613         # TODO
00614         if sys.platform == 'darwin':
00615             self.defaultSettings['general']['defWindowPos']['enabled'] = False
00616         
00617         #
00618         # user settings
00619         #
00620         self.userSettings = copy.deepcopy(self.defaultSettings)
00621         try:
00622             self.ReadSettingsFile()
00623         except gcmd.GException, e:
00624             print >> sys.stderr, e.value
00625 
00626         #
00627         # internal settings (based on user settings)
00628         #
00629         self.internalSettings = {}
00630         for group in self.userSettings.keys():
00631             self.internalSettings[group] = {}
00632             for key in self.userSettings[group].keys():
00633                 self.internalSettings[group][key] = {}
00634 
00635         # self.internalSettings['general']["mapsetPath"]['value'] = self.GetMapsetPath()
00636         self.internalSettings['appearance']['elementListExpand']['choices'] = \
00637             (_("Collapse all except PERMANENT and current"),
00638              _("Collapse all except PERMANENT"),
00639              _("Collapse all except current"),
00640              _("Collapse all"),
00641              _("Expand all"))
00642         self.internalSettings['atm']['leftDbClick']['choices'] = (_('Edit selected record'),
00643                                                                   _('Display selected'))
00644         
00645         self.internalSettings['cmd']['verbosity']['choices'] = ('grassenv',
00646                                                                 'verbose',
00647                                                                 'quiet')
00648         
00649         self.internalSettings['appearance']['iconTheme']['choices'] = ('grass',
00650                                                                        'grass2',
00651                                                                        'silk')
00652         self.internalSettings['appearance']['menustyle']['choices'] = \
00653                    (_("Classic (labels only)"),
00654                     _("Combined (labels and module names)"),
00655                     _("Professional (module names only)"))
00656         self.internalSettings['appearance']['gSelectPopupHeight']['min'] = 50
00657         # there is also maxHeight given to TreeCtrlComboPopup.GetAdjustedSize
00658         self.internalSettings['appearance']['gSelectPopupHeight']['max'] = 1000
00659         
00660         self.internalSettings['display']['driver']['choices'] = ['default']
00661         self.internalSettings['display']['statusbarMode']['choices'] = globalvar.MAP_DISPLAY_STATUSBAR_MODE
00662 
00663         self.internalSettings['nviz']['view'] = {}
00664         self.internalSettings['nviz']['view']['twist'] = {}
00665         self.internalSettings['nviz']['view']['twist']['min'] = -180
00666         self.internalSettings['nviz']['view']['twist']['max'] = 180
00667         self.internalSettings['nviz']['view']['persp'] = {}
00668         self.internalSettings['nviz']['view']['persp']['min'] = 1
00669         self.internalSettings['nviz']['view']['persp']['max'] = 100
00670         self.internalSettings['nviz']['view']['height'] = {}
00671         self.internalSettings['nviz']['view']['height']['value'] = -1
00672         self.internalSettings['nviz']['vector'] = {}
00673         self.internalSettings['nviz']['vector']['points'] = {}
00674         self.internalSettings['nviz']['vector']['points']['marker'] = ("x",
00675                                                                        _("box"),
00676                                                                        _("sphere"),
00677                                                                        _("cube"),
00678                                                                        _("diamond"),
00679                                                                        _("dtree"),
00680                                                                        _("ctree"),
00681                                                                        _("aster"),
00682                                                                        _("gyro"),
00683                                                                        _("histogram"))
00684         self.internalSettings['vdigit']['bgmap'] = {}
00685         self.internalSettings['vdigit']['bgmap']['value'] = ''
00686         
00687     def ReadSettingsFile(self, settings = None):
00688         """!Reads settings file (mapset, location, gisdbase)"""
00689         if settings is None:
00690             settings = self.userSettings
00691         
00692         self._readFile(self.filePath, settings)
00693         
00694         # set environment variables
00695         font = self.Get(group = 'display', key = 'font', subkey = 'type')
00696         enc  = self.Get(group = 'display', key = 'font', subkey = 'encoding')
00697         if font:
00698             os.environ["GRASS_FONT"] = font
00699         if enc:
00700             os.environ["GRASS_ENCODING"] = enc
00701         
00702     def _readFile(self, filename, settings = None):
00703         """!Read settings from file to dict
00704 
00705         @param filename settings file path
00706         @param settings dict where to store settings (None for self.userSettings)
00707         """
00708         if settings is None:
00709             settings = self.userSettings
00710         
00711         if not os.path.exists(filename):
00712             # try alternative path
00713             filename = os.path.join(os.path.expanduser("~"), '.grasswx6')
00714             if not os.path.exists(filename):
00715                 return
00716         
00717         try:
00718             fd = open(filename, "r")
00719         except IOError:
00720             sys.stderr.write(_("Unable to read settings file <%s>\n") % filename)
00721             return
00722         
00723         try:
00724             line = ''
00725             for line in fd.readlines():
00726                 line = line.rstrip('%s' % os.linesep)
00727                 group, key = line.split(self.sep)[0:2]
00728                 kv = line.split(self.sep)[2:]
00729                 subkeyMaster = None
00730                 if len(kv) % 2 != 0: # multiple (e.g. nviz)
00731                     subkeyMaster = kv[0]
00732                     del kv[0]
00733                 idx = 0
00734                 while idx < len(kv):
00735                     if subkeyMaster:
00736                         subkey = [subkeyMaster, kv[idx]]
00737                     else:
00738                         subkey = kv[idx]
00739                     value = kv[idx+1]
00740                     value = self._parseValue(value, read = True)
00741                     self.Append(settings, group, key, subkey, value)
00742                     idx += 2
00743         except ValueError, e:
00744             print >> sys.stderr, _("Error: Reading settings from file <%(file)s> failed.\n"
00745                                    "\t\tDetails: %(detail)s\n"
00746                                    "\t\tLine: '%(line)s'\n") % { 'file' : filename,
00747                                                                  'detail' : e,
00748                                                                  'line' : line }
00749             fd.close()
00750         
00751         fd.close()
00752         
00753     def SaveToFile(self, settings = None):
00754         """!Save settings to the file"""
00755         if settings is None:
00756             settings = self.userSettings
00757         
00758         dirPath = utils.GetSettingsPath()
00759         if not os.path.exists(dirPath):
00760             try:
00761                 os.mkdir(dirPath)
00762             except:
00763                 gcmd.GError(_('Unable to create settings directory'))
00764                 return
00765         
00766         try:
00767             file = open(self.filePath, "w")
00768             for group in settings.keys():
00769                 for key in settings[group].keys():
00770                     subkeys = settings[group][key].keys()
00771                     file.write('%s%s%s%s' % (group, self.sep, key, self.sep))
00772                     for idx in range(len(subkeys)):
00773                         value = settings[group][key][subkeys[idx]]
00774                         if type(value) == types.DictType:
00775                             if idx > 0:
00776                                 file.write('%s%s%s%s%s' % (os.linesep, group, self.sep, key, self.sep))
00777                             file.write('%s%s' % (subkeys[idx], self.sep))
00778                             kvalues = settings[group][key][subkeys[idx]].keys()
00779                             srange = range(len(kvalues))
00780                             for sidx in srange:
00781                                 svalue = self._parseValue(settings[group][key][subkeys[idx]][kvalues[sidx]])
00782                                 file.write('%s%s%s' % (kvalues[sidx], self.sep,
00783                                                        svalue))
00784                                 if sidx < len(kvalues) - 1:
00785                                     file.write('%s' % self.sep)
00786                         else:
00787                             if idx > 0 and \
00788                                     type(settings[group][key][subkeys[idx - 1]]) == types.DictType:
00789                                 file.write('%s%s%s%s%s' % (os.linesep, group, self.sep, key, self.sep))
00790                             value = self._parseValue(settings[group][key][subkeys[idx]])
00791                             file.write('%s%s%s' % (subkeys[idx], self.sep, value))
00792                             if idx < len(subkeys) - 1 and \
00793                                     type(settings[group][key][subkeys[idx + 1]]) != types.DictType:
00794                                 file.write('%s' % self.sep)
00795                     file.write(os.linesep)
00796         except IOError, e:
00797             raise gcmd.GException(e)
00798         except StandardError, e:
00799             raise gcmd.GException(_('Writing settings to file <%(file)s> failed.'
00800                                     '\n\nDetails: %(detail)s') % { 'file' : self.filePath,
00801                                                                    'detail' : e })
00802         
00803         file.close()
00804         
00805     def _parseValue(self, value, read = False):
00806         """!Parse value to be store in settings file"""
00807         if read: # -> read settings (cast values)
00808             if value == 'True':
00809                 value = True
00810             elif value == 'False':
00811                 value = False
00812             elif value == 'None':
00813                 value = None
00814             elif ':' in value: # -> color
00815                 try:
00816                     value = tuple(map(int, value.split(':')))
00817                 except ValueError: # -> string
00818                     pass
00819             else:
00820                 try:
00821                     value = int(value)
00822                 except ValueError:
00823                     try:
00824                         value = float(value)
00825                     except ValueError:
00826                         pass
00827         else: # -> write settings
00828             if type(value) == type(()): # -> color
00829                 value = str(value[0]) + ':' +\
00830                     str(value[1]) + ':' + \
00831                     str(value[2])
00832                 
00833         return value
00834 
00835     def Get(self, group, key = None, subkey = None, internal = False):
00836         """!Get value by key/subkey
00837 
00838         Raise KeyError if key is not found
00839         
00840         @param group settings group
00841         @param key (value, None)
00842         @param subkey (value, list or None)
00843         @param internal use internal settings instead
00844 
00845         @return value
00846         """
00847         if internal is True:
00848             settings = self.internalSettings
00849         else:
00850             settings = self.userSettings
00851             
00852         try:
00853             if subkey is None:
00854                 if key is None:
00855                     return settings[group]
00856                 else:
00857                     return settings[group][key]
00858             else:
00859                 if type(subkey) == type(tuple()) or \
00860                         type(subkey) == type(list()):
00861                     return settings[group][key][subkey[0]][subkey[1]]
00862                 else:
00863                     return settings[group][key][subkey]  
00864 
00865         except KeyError:
00866             print >> sys.stderr, "Settings: unable to get value '%s:%s:%s'\n" % \
00867                 (group, key, subkey)
00868         
00869     def Set(self, group, value, key = None, subkey = None, internal = False):
00870         """!Set value of key/subkey
00871         
00872         Raise KeyError if group/key is not found
00873         
00874         @param group settings group
00875         @param key key (value, None)
00876         @param subkey subkey (value, list or None)
00877         @param value value
00878         @param internal use internal settings instead
00879         """
00880         if internal is True:
00881             settings = self.internalSettings
00882         else:
00883             settings = self.userSettings
00884         
00885         try:
00886             if subkey is None:
00887                 if key is None:
00888                     settings[group] = value
00889                 else:
00890                     settings[group][key] = value
00891             else:
00892                 if type(subkey) == type(tuple()) or \
00893                         type(subkey) == type(list()):
00894                     settings[group][key][subkey[0]][subkey[1]] = value
00895                 else:
00896                     settings[group][key][subkey] = value
00897         except KeyError:
00898             raise gcmd.GException("%s '%s:%s:%s'" % (_("Unable to set "), group, key, subkey))
00899         
00900     def Append(self, dict, group, key, subkey, value):
00901         """!Set value of key/subkey
00902 
00903         Create group/key/subkey if not exists
00904         
00905         @param dict settings dictionary to use
00906         @param group settings group
00907         @param key key
00908         @param subkey subkey (value or list)
00909         @param value value
00910         """
00911         if group not in dict:
00912             dict[group] = {}
00913         
00914         if key not in dict[group]:
00915             dict[group][key] = {}
00916         
00917         if type(subkey) == types.ListType:
00918             # TODO: len(subkey) > 2
00919             if subkey[0] not in dict[group][key]:
00920                 dict[group][key][subkey[0]] = {}
00921             try:
00922                 dict[group][key][subkey[0]][subkey[1]] = value
00923             except TypeError:
00924                 print >> sys.stderr, _("Unable to parse settings '%s'") % value + \
00925                     ' (' + group + ':' + key + ':' + subkey[0] + ':' + subkey[1] + ')'
00926         else:
00927             try:
00928                 dict[group][key][subkey] = value
00929             except TypeError:
00930                 print >> sys.stderr, _("Unable to parse settings '%s'") % value + \
00931                     ' (' + group + ':' + key + ':' + subkey + ')'
00932         
00933     def GetDefaultSettings(self):
00934         """!Get default user settings"""
00935         return self.defaultSettings
00936 
00937 globalSettings = Settings()
00938 
00939 class PreferencesBaseDialog(wx.Dialog):
00940     """!Base preferences dialog"""
00941     def __init__(self, parent, settings, title = _("User settings"),
00942                  size = (500, 375),
00943                  style = wx.DEFAULT_DIALOG_STYLE | wx.RESIZE_BORDER):
00944         self.parent = parent # ModelerFrame
00945         self.title  = title
00946         self.size   = size
00947         self.settings = settings
00948         
00949         wx.Dialog.__init__(self, parent = parent, id = wx.ID_ANY, title = title,
00950                            style = style)
00951         
00952         # notebook
00953         self.notebook = wx.Notebook(parent = self, id = wx.ID_ANY, style = wx.BK_DEFAULT)
00954         
00955         # dict for window ids
00956         self.winId = {}
00957         
00958         # create notebook pages
00959         
00960         # buttons
00961         self.btnDefault = wx.Button(self, wx.ID_ANY, _("Set to default"))
00962         self.btnSave = wx.Button(self, wx.ID_SAVE)
00963         self.btnApply = wx.Button(self, wx.ID_APPLY)
00964         self.btnCancel = wx.Button(self, wx.ID_CANCEL)
00965         self.btnSave.SetDefault()
00966         
00967         # bindigs
00968         self.btnDefault.Bind(wx.EVT_BUTTON, self.OnDefault)
00969         self.btnDefault.SetToolTipString(_("Revert settings to default and apply changes"))
00970         self.btnApply.Bind(wx.EVT_BUTTON, self.OnApply)
00971         self.btnApply.SetToolTipString(_("Apply changes for the current session"))
00972         self.btnSave.Bind(wx.EVT_BUTTON, self.OnSave)
00973         self.btnSave.SetToolTipString(_("Apply and save changes to user settings file (default for next sessions)"))
00974         self.btnSave.SetDefault()
00975         self.btnCancel.Bind(wx.EVT_BUTTON, self.OnCancel)
00976         self.btnCancel.SetToolTipString(_("Close dialog and ignore changes"))
00977 
00978         self.Bind(wx.EVT_CLOSE, self.OnCloseWindow)
00979 
00980         self._layout()
00981         
00982     def _layout(self):
00983         """!Layout window"""
00984         # sizers
00985         btnSizer = wx.BoxSizer(wx.HORIZONTAL)
00986         btnSizer.Add(item = self.btnDefault, proportion = 1,
00987                      flag = wx.ALL, border = 5)
00988         btnStdSizer = wx.StdDialogButtonSizer()
00989         btnStdSizer.AddButton(self.btnCancel)
00990         btnStdSizer.AddButton(self.btnSave)
00991         btnStdSizer.AddButton(self.btnApply)
00992         btnStdSizer.Realize()
00993         
00994         mainSizer = wx.BoxSizer(wx.VERTICAL)
00995         mainSizer.Add(item = self.notebook, proportion = 1, flag = wx.EXPAND | wx.ALL, border = 5)
00996         mainSizer.Add(item = btnSizer, proportion = 0,
00997                       flag = wx.EXPAND, border = 0)
00998         mainSizer.Add(item = btnStdSizer, proportion = 0,
00999                       flag = wx.EXPAND | wx.ALL | wx.ALIGN_RIGHT, border = 5)
01000         
01001         self.SetSizer(mainSizer)
01002         mainSizer.Fit(self)
01003         
01004     def OnDefault(self, event):
01005         """!Button 'Set to default' pressed"""
01006         self.settings.userSettings = copy.deepcopy(self.settings.defaultSettings)
01007         
01008         # update widgets
01009         for gks in self.winId.keys():
01010             try:
01011                 group, key, subkey = gks.split(':')
01012                 value = self.settings.Get(group, key, subkey)
01013             except ValueError:
01014                 group, key, subkey, subkey1 = gks.split(':')
01015                 value = self.settings.Get(group, key, [subkey, subkey1])
01016             win = self.FindWindowById(self.winId[gks])
01017             if win.GetName() in ('GetValue', 'IsChecked'):
01018                 value = win.SetValue(value)
01019             elif win.GetName() == 'GetSelection':
01020                 value = win.SetSelection(value)
01021             elif win.GetName() == 'GetStringSelection':
01022                 value = win.SetStringSelection(value)
01023             else:
01024                 value = win.SetValue(value)
01025         
01026     def OnApply(self, event):
01027         """!Button 'Apply' pressed
01028         Posts event EVT_SETTINGS_CHANGED.
01029         """
01030         if self._updateSettings():
01031             self.parent.goutput.WriteLog(_('Settings applied to current session but not saved'))
01032             event = wxSettingsChanged()
01033             wx.PostEvent(self, event)
01034             self.Close()
01035 
01036     def OnCloseWindow(self, event):
01037         self.Hide()
01038         
01039     def OnCancel(self, event):
01040         """!Button 'Cancel' pressed"""
01041         self.Close()
01042         
01043     def OnSave(self, event):
01044         """!Button 'Save' pressed
01045         Posts event EVT_SETTINGS_CHANGED.
01046         """
01047         if self._updateSettings():
01048             self.settings.SaveToFile()
01049             self.parent.goutput.WriteLog(_('Settings saved to file \'%s\'.') % self.settings.filePath)
01050             event = wxSettingsChanged()
01051             wx.PostEvent(self, event)
01052             self.Close()
01053 
01054     def _updateSettings(self):
01055         """!Update user settings"""
01056         for item in self.winId.keys():
01057             try:
01058                 group, key, subkey = item.split(':')
01059                 subkey1 = None
01060             except ValueError:
01061                 group, key, subkey, subkey1 = item.split(':')
01062             
01063             id = self.winId[item]
01064             win = self.FindWindowById(id)
01065             if win.GetName() == 'GetValue':
01066                 value = win.GetValue()
01067             elif win.GetName() == 'GetSelection':
01068                 value = win.GetSelection()
01069             elif win.GetName() == 'IsChecked':
01070                 value = win.IsChecked()
01071             elif win.GetName() == 'GetStringSelection':
01072                 value = win.GetStringSelection()
01073             elif win.GetName() == 'GetColour':
01074                 value = tuple(win.GetValue())
01075             else:
01076                 value = win.GetValue()
01077 
01078             if key == 'keycolumn' and value == '':
01079                 wx.MessageBox(parent = self,
01080                               message = _("Key column cannot be empty string."),
01081                               caption = _("Error"), style = wx.OK | wx.ICON_ERROR)
01082                 win.SetValue(self.settings.Get(group = 'atm', key = 'keycolumn', subkey = 'value'))
01083                 return False
01084 
01085             if subkey1:
01086                 self.settings.Set(group, value, key, [subkey, subkey1])
01087             else:
01088                 self.settings.Set(group, value, key, subkey)
01089         
01090         if self.parent.GetName() == 'Modeler':
01091             return True
01092         
01093         #
01094         # update default window dimension
01095         #
01096         if self.settings.Get(group = 'general', key = 'defWindowPos', subkey = 'enabled') is True:
01097             dim = ''
01098             # layer manager
01099             pos = self.parent.GetPosition()
01100             size = self.parent.GetSize()
01101             dim = '%d,%d,%d,%d' % (pos[0], pos[1], size[0], size[1])
01102             # opened displays
01103             for page in range(0, self.parent.gm_cb.GetPageCount()):
01104                 pos = self.parent.gm_cb.GetPage(page).maptree.mapdisplay.GetPosition()
01105                 size = self.parent.gm_cb.GetPage(page).maptree.mapdisplay.GetSize()
01106 
01107                 dim += ',%d,%d,%d,%d' % (pos[0], pos[1], size[0], size[1])
01108 
01109             self.settings.Set(group = 'general', key = 'defWindowPos', subkey = 'dim', value = dim)
01110         else:
01111             self.settings.Set(group = 'general', key = 'defWindowPos', subkey = 'dim', value = '')
01112 
01113         return True
01114 
01115 class PreferencesDialog(PreferencesBaseDialog):
01116     """!User preferences dialog"""
01117     def __init__(self, parent, title = _("GUI Settings"),
01118                  settings = globalSettings):
01119         
01120         PreferencesBaseDialog.__init__(self, parent = parent, title = title,
01121                                        settings = settings)
01122         
01123         # create notebook pages
01124         self._createGeneralPage(self.notebook)
01125         self._createAppearancePage(self.notebook)
01126         self._createDisplayPage(self.notebook)
01127         self._createCmdPage(self.notebook)
01128         self._createAttributeManagerPage(self.notebook)
01129         self._createProjectionPage(self.notebook)
01130         
01131         self.SetMinSize(self.GetBestSize())
01132         self.SetSize(self.size)
01133         
01134     def _createGeneralPage(self, notebook):
01135         """!Create notebook page for general settings"""
01136         panel = wx.Panel(parent = notebook, id = wx.ID_ANY)
01137         notebook.AddPage(page = panel, text = _("General"))
01138         
01139         border = wx.BoxSizer(wx.VERTICAL)
01140         #
01141         # Layer Manager settings
01142         #
01143         box   = wx.StaticBox (parent = panel, id = wx.ID_ANY, label = " %s " % _("Layer Manager settings"))
01144         sizer = wx.StaticBoxSizer(box, wx.VERTICAL)
01145 
01146         gridSizer = wx.GridBagSizer (hgap = 3, vgap = 3)
01147         gridSizer.AddGrowableCol(0)
01148         
01149         #
01150         # ask when removing map layer from layer tree
01151         #
01152         row = 0
01153         askOnRemoveLayer = wx.CheckBox(parent = panel, id = wx.ID_ANY,
01154                                        label = _("Ask when removing map layer from layer tree"),
01155                                        name = 'IsChecked')
01156         askOnRemoveLayer.SetValue(self.settings.Get(group = 'manager', key = 'askOnRemoveLayer', subkey = 'enabled'))
01157         self.winId['manager:askOnRemoveLayer:enabled'] = askOnRemoveLayer.GetId()
01158         
01159         gridSizer.Add(item = askOnRemoveLayer,
01160                       pos = (row, 0), span = (1, 2))
01161         
01162         row += 1
01163         askOnQuit = wx.CheckBox(parent = panel, id = wx.ID_ANY,
01164                                 label = _("Ask when quiting wxGUI or closing display"),
01165                                 name = 'IsChecked')
01166         askOnQuit.SetValue(self.settings.Get(group = 'manager', key = 'askOnQuit', subkey = 'enabled'))
01167         self.winId['manager:askOnQuit:enabled'] = askOnQuit.GetId()
01168         
01169         gridSizer.Add(item = askOnQuit,
01170                       pos = (row, 0), span = (1, 2))
01171 
01172         row += 1
01173         hideSearch = wx.CheckBox(parent = panel, id = wx.ID_ANY,
01174                                  label = _("Hide '%s' tab (requires GUI restart)") % _("Search module"),
01175                                  name = 'IsChecked')
01176         hideSearch.SetValue(self.settings.Get(group = 'manager', key = 'hideTabs', subkey = 'search'))
01177         self.winId['manager:hideTabs:search'] = hideSearch.GetId()
01178         
01179         gridSizer.Add(item = hideSearch,
01180                       pos = (row, 0), span = (1, 2))
01181         
01182         row += 1
01183         hidePyShell = wx.CheckBox(parent = panel, id = wx.ID_ANY,
01184                                   label = _("Hide '%s' tab (requires GUI restart)") % _("Python shell"),
01185                                   name = 'IsChecked')
01186         hidePyShell.SetValue(self.settings.Get(group = 'manager', key = 'hideTabs', subkey = 'pyshell'))
01187         self.winId['manager:hideTabs:pyshell'] = hidePyShell.GetId()
01188         
01189         gridSizer.Add(item = hidePyShell,
01190                       pos = (row, 0), span = (1, 2))
01191         
01192         #
01193         # Selected text is copied to clipboard
01194         #
01195         row += 1
01196         copySelectedTextToClipboard = wx.CheckBox(parent = panel, id = wx.ID_ANY,
01197                                                   label = _("Automatically copy selected text to clipboard (in Command console)"),
01198                                                   name = 'IsChecked')
01199         copySelectedTextToClipboard.SetValue(self.settings.Get(group = 'manager', key = 'copySelectedTextToClipboard', subkey = 'enabled'))
01200         self.winId['manager:copySelectedTextToClipboard:enabled'] = copySelectedTextToClipboard.GetId()
01201         
01202         gridSizer.Add(item = copySelectedTextToClipboard,
01203                       pos = (row, 0), span = (1, 2))
01204         
01205         sizer.Add(item = gridSizer, proportion = 1, flag = wx.ALL | wx.EXPAND, border = 5)
01206         border.Add(item = sizer, proportion = 0, flag = wx.ALL | wx.EXPAND, border = 3)
01207         
01208         #
01209         # workspace
01210         #
01211         box   = wx.StaticBox (parent = panel, id = wx.ID_ANY, label = " %s " % _("Workspace settings"))
01212         sizer = wx.StaticBoxSizer(box, wx.VERTICAL)
01213         
01214         gridSizer = wx.GridBagSizer (hgap = 3, vgap = 3)
01215         gridSizer.AddGrowableCol(0)
01216         
01217         row = 0
01218         posDisplay = wx.CheckBox(parent = panel, id = wx.ID_ANY,
01219                                  label = _("Suppress positioning Map Display Window(s)"),
01220                                  name = 'IsChecked')
01221         posDisplay.SetValue(self.settings.Get(group = 'general', key = 'workspace',
01222                                               subkey = ['posDisplay', 'enabled']))
01223         self.winId['general:workspace:posDisplay:enabled'] = posDisplay.GetId()
01224         
01225         gridSizer.Add(item = posDisplay,
01226                       pos = (row, 0), span = (1, 2))
01227         
01228         row += 1 
01229         
01230         posManager = wx.CheckBox(parent = panel, id = wx.ID_ANY,
01231                                  label = _("Suppress positioning Layer Manager window"),
01232                                  name = 'IsChecked')
01233         posManager.SetValue(self.settings.Get(group = 'general', key = 'workspace',
01234                                               subkey = ['posManager', 'enabled']))
01235         self.winId['general:workspace:posManager:enabled'] = posManager.GetId()
01236         
01237         gridSizer.Add(item = posManager,
01238                       pos = (row, 0), span = (1, 2))
01239         
01240         row += 1
01241         defaultPos = wx.CheckBox(parent = panel, id = wx.ID_ANY,
01242                                  label = _("Save current window layout as default"),
01243                                  name = 'IsChecked')
01244         defaultPos.SetValue(self.settings.Get(group = 'general', key = 'defWindowPos', subkey = 'enabled'))
01245         defaultPos.SetToolTip(wx.ToolTip (_("Save current position and size of Layer Manager window and opened "
01246                                             "Map Display window(s) and use as default for next sessions.")))
01247         self.winId['general:defWindowPos:enabled'] = defaultPos.GetId()
01248         
01249         gridSizer.Add(item = defaultPos,
01250                       pos = (row, 0), span = (1, 2))
01251         
01252         sizer.Add(item = gridSizer, proportion = 1, flag = wx.ALL | wx.EXPAND, border = 5)
01253         border.Add(item = sizer, proportion = 0, flag = wx.ALL | wx.EXPAND, border = 3)
01254         
01255         panel.SetSizer(border)
01256         
01257         return panel
01258     
01259 
01260         panel.SetSizer(border)
01261         
01262         return panel
01263 
01264     def _createAppearancePage(self, notebook):
01265         """!Create notebook page for display settings"""
01266    
01267         panel = wx.Panel(parent = notebook, id = wx.ID_ANY)
01268         notebook.AddPage(page = panel, text = _("Appearance"))
01269 
01270         border = wx.BoxSizer(wx.VERTICAL)
01271 
01272         box   = wx.StaticBox (parent = panel, id = wx.ID_ANY, label = " %s " % _("Font settings"))
01273         sizer = wx.StaticBoxSizer(box, wx.VERTICAL)
01274 
01275         gridSizer = wx.GridBagSizer (hgap = 3, vgap = 3)
01276         gridSizer.AddGrowableCol(0)
01277 
01278         #
01279         # font settings
01280         #
01281         sizer.Add(item = gridSizer, proportion = 1, flag = wx.ALL | wx.EXPAND, border = 5)
01282         border.Add(item = sizer, proportion = 0, flag = wx.ALL | wx.EXPAND, border = 3)
01283 
01284         row = 0
01285         gridSizer.Add(item = wx.StaticText(parent = panel, id = wx.ID_ANY,
01286                                          label = _("Font for command output:")),
01287                       flag = wx.ALIGN_LEFT |
01288                       wx.ALIGN_CENTER_VERTICAL,
01289                       pos = (row, 0))
01290         outfontButton = wx.Button(parent = panel, id = wx.ID_ANY,
01291                                label = _("Set font"), size = (100, -1))
01292         gridSizer.Add(item = outfontButton,
01293                       flag = wx.ALIGN_RIGHT |
01294                       wx.ALIGN_CENTER_VERTICAL,
01295                       pos = (row, 1))
01296 
01297         #
01298         # appearence
01299         #
01300         box   = wx.StaticBox (parent = panel, id = wx.ID_ANY, label = " %s " % _("Appearance settings"))
01301         sizer = wx.StaticBoxSizer(box, wx.VERTICAL)
01302 
01303         gridSizer  =  wx.GridBagSizer (hgap = 3, vgap = 3)
01304         gridSizer.AddGrowableCol(0)
01305 
01306         #
01307         # element list
01308         #
01309         row = 0
01310         gridSizer.Add(item = wx.StaticText(parent = panel, id = wx.ID_ANY,
01311                                            label = _("Element list:")),
01312                       flag = wx.ALIGN_LEFT |
01313                       wx.ALIGN_CENTER_VERTICAL,
01314                       pos = (row, 0))
01315         elementList = wx.Choice(parent = panel, id = wx.ID_ANY, size = (325, -1),
01316                                 choices = self.settings.Get(group = 'appearance', key = 'elementListExpand',
01317                                                             subkey = 'choices', internal = True),
01318                                 name = "GetSelection")
01319         elementList.SetSelection(self.settings.Get(group = 'appearance', key = 'elementListExpand',
01320                                                    subkey = 'selection'))
01321         self.winId['appearance:elementListExpand:selection'] = elementList.GetId()
01322 
01323         gridSizer.Add(item = elementList,
01324                       flag = wx.ALIGN_RIGHT |
01325                       wx.ALIGN_CENTER_VERTICAL,
01326                       pos = (row, 1))
01327         
01328         #
01329         # menu style
01330         #
01331         row += 1
01332         gridSizer.Add(item = wx.StaticText(parent = panel, id = wx.ID_ANY,
01333                                            label = _("Menu style (requires GUI restart):")),
01334                       flag = wx.ALIGN_LEFT |
01335                       wx.ALIGN_CENTER_VERTICAL,
01336                       pos = (row, 0))
01337         listOfStyles = self.settings.Get(group = 'appearance', key = 'menustyle',
01338                                          subkey = 'choices', internal = True)
01339         
01340         menuItemText = wx.Choice(parent = panel, id = wx.ID_ANY, size = (325, -1),
01341                                  choices = listOfStyles,
01342                                  name = "GetSelection")
01343         menuItemText.SetSelection(self.settings.Get(group = 'appearance', key = 'menustyle', subkey = 'selection'))
01344         
01345         self.winId['appearance:menustyle:selection'] = menuItemText.GetId()
01346         
01347         gridSizer.Add(item = menuItemText,
01348                       flag = wx.ALIGN_RIGHT,
01349                       pos = (row, 1))
01350         
01351         #
01352         # gselect.TreeCtrlComboPopup height
01353         #
01354         row += 1
01355         
01356         gridSizer.Add(item = wx.StaticText(parent = panel, id = wx.ID_ANY,
01357                                          label = _("Height of map selection popup window (in pixels):")),
01358                       flag = wx.ALIGN_LEFT |
01359                       wx.ALIGN_CENTER_VERTICAL,
01360                       pos = (row, 0))
01361         min = self.settings.Get(group = 'appearance', key = 'gSelectPopupHeight', subkey = 'min', internal = True)
01362         max = self.settings.Get(group = 'appearance', key = 'gSelectPopupHeight', subkey = 'max', internal = True)
01363         value = self.settings.Get(group = 'appearance', key = 'gSelectPopupHeight', subkey = 'value')
01364         
01365         popupHeightSpin = wx.SpinCtrl(parent = panel, id = wx.ID_ANY, size = (100, -1))
01366         popupHeightSpin.SetRange(min,max)
01367         popupHeightSpin.SetValue(value)
01368         
01369         self.winId['appearance:gSelectPopupHeight:value'] = popupHeightSpin.GetId()
01370         
01371         gridSizer.Add(item = popupHeightSpin,
01372                       flag = wx.ALIGN_RIGHT,
01373                       pos = (row, 1))
01374         
01375         
01376         #
01377         # icon theme
01378         #
01379         row += 1
01380         gridSizer.Add(item = wx.StaticText(parent = panel, id = wx.ID_ANY,
01381                                            label = _("Icon theme (requires GUI restart):")),
01382                       flag = wx.ALIGN_LEFT |
01383                       wx.ALIGN_CENTER_VERTICAL,
01384                       pos = (row, 0))
01385         iconTheme = wx.Choice(parent = panel, id = wx.ID_ANY, size = (100, -1),
01386                               choices = self.settings.Get(group = 'appearance', key = 'iconTheme',
01387                                                         subkey = 'choices', internal = True),
01388                               name = "GetStringSelection")
01389         iconTheme.SetStringSelection(self.settings.Get(group = 'appearance', key = 'iconTheme', subkey = 'type'))
01390         self.winId['appearance:iconTheme:type'] = iconTheme.GetId()
01391 
01392         gridSizer.Add(item = iconTheme,
01393                       flag = wx.ALIGN_RIGHT |
01394                       wx.ALIGN_CENTER_VERTICAL,
01395                       pos = (row, 1))
01396         
01397         sizer.Add(item = gridSizer, proportion = 1, flag = wx.ALL | wx.EXPAND, border = 5)
01398         border.Add(item = sizer, proportion = 0, flag = wx.LEFT | wx.RIGHT | wx.BOTTOM | wx.EXPAND, border = 3)
01399         
01400         panel.SetSizer(border)
01401                 
01402         # bindings
01403         outfontButton.Bind(wx.EVT_BUTTON, self.OnSetOutputFont)
01404         
01405         return panel
01406     
01407     def _createDisplayPage(self, notebook):
01408         """!Create notebook page for display settings"""
01409    
01410         panel = wx.Panel(parent = notebook, id = wx.ID_ANY)
01411         notebook.AddPage(page = panel, text = _("Map Display"))
01412 
01413         border = wx.BoxSizer(wx.VERTICAL)
01414 
01415         box   = wx.StaticBox (parent = panel, id = wx.ID_ANY, label = " %s " % _("Font settings"))
01416         sizer = wx.StaticBoxSizer(box, wx.VERTICAL)
01417 
01418         gridSizer = wx.GridBagSizer (hgap = 3, vgap = 3)
01419         gridSizer.AddGrowableCol(0)
01420 
01421         #
01422         # font settings
01423         #
01424         row = 0
01425         gridSizer.Add(item = wx.StaticText(parent = panel, id = wx.ID_ANY,
01426                                          label = _("Default font for GRASS displays:")),
01427                       flag = wx.ALIGN_LEFT |
01428                       wx.ALIGN_CENTER_VERTICAL,
01429                       pos = (row, 0))
01430         fontButton = wx.Button(parent = panel, id = wx.ID_ANY,
01431                                label = _("Set font"), size = (100, -1))
01432         gridSizer.Add(item = fontButton,
01433                       flag = wx.ALIGN_RIGHT |
01434                       wx.ALIGN_CENTER_VERTICAL,
01435                       pos = (row, 1))
01436 
01437         sizer.Add(item = gridSizer, proportion = 1, flag = wx.ALL | wx.EXPAND, border = 5)
01438         border.Add(item = sizer, proportion = 0, flag = wx.ALL | wx.EXPAND, border = 3)
01439 
01440         #
01441         # display settings
01442         #
01443         box   = wx.StaticBox (parent = panel, id = wx.ID_ANY, label = " %s " % _("Default display settings"))
01444         sizer = wx.StaticBoxSizer(box, wx.VERTICAL)
01445 
01446         gridSizer = wx.GridBagSizer (hgap = 3, vgap = 3)
01447         gridSizer.AddGrowableCol(0)
01448 
01449         
01450         #
01451         # display driver
01452         #
01453         row = 0
01454         gridSizer.Add(item = wx.StaticText(parent = panel, id = wx.ID_ANY,
01455                                          label = _("Display driver:")),
01456                       flag = wx.ALIGN_LEFT |
01457                       wx.ALIGN_CENTER_VERTICAL,
01458                       pos=(row, 0))
01459         listOfDrivers = self.settings.Get(group='display', key='driver', subkey='choices', internal=True)
01460         # check if cairo is available
01461         if 'cairo' not in listOfDrivers:
01462             for line in gcmd.RunCommand('d.mon',
01463                                         flags = 'l',
01464                                         read = True).splitlines():
01465                 if 'cairo' in line:
01466                     listOfDrivers.append('cairo')
01467                     break
01468         
01469         driver = wx.Choice(parent=panel, id=wx.ID_ANY, size=(150, -1),
01470                            choices=listOfDrivers,
01471                            name="GetStringSelection")
01472         driver.SetStringSelection(self.settings.Get(group='display', key='driver', subkey='type'))
01473         self.winId['display:driver:type'] = driver.GetId()
01474 
01475         gridSizer.Add(item = driver,
01476                       flag = wx.ALIGN_RIGHT,
01477                       pos = (row, 1))
01478 
01479 
01480         #
01481         # Statusbar mode
01482         #
01483         row += 1
01484         gridSizer.Add(item = wx.StaticText(parent = panel, id = wx.ID_ANY,
01485                                          label = _("Statusbar mode:")),
01486                       flag = wx.ALIGN_LEFT |
01487                       wx.ALIGN_CENTER_VERTICAL,
01488                       pos = (row, 0))
01489         listOfModes = self.settings.Get(group = 'display', key = 'statusbarMode', subkey = 'choices', internal = True)
01490         statusbarMode = wx.Choice(parent = panel, id = wx.ID_ANY, size = (150, -1),
01491                                   choices = listOfModes,
01492                                   name = "GetSelection")
01493         statusbarMode.SetSelection(self.settings.Get(group = 'display', key = 'statusbarMode', subkey = 'selection'))
01494         self.winId['display:statusbarMode:selection'] = statusbarMode.GetId()
01495 
01496         gridSizer.Add(item = statusbarMode,
01497                       flag = wx.ALIGN_RIGHT,
01498                       pos = (row, 1))
01499 
01500         #
01501         # Background color
01502         #
01503         row += 1
01504         gridSizer.Add(item = wx.StaticText(parent = panel, id = wx.ID_ANY,
01505                                          label = _("Background color:")),
01506                       flag = wx.ALIGN_LEFT |
01507                       wx.ALIGN_CENTER_VERTICAL,
01508                       pos = (row, 0))
01509         bgColor = csel.ColourSelect(parent = panel, id = wx.ID_ANY,
01510                                     colour = self.settings.Get(group = 'display', key = 'bgcolor', subkey = 'color'),
01511                                     size = globalvar.DIALOG_COLOR_SIZE)
01512         bgColor.SetName('GetColour')
01513         self.winId['display:bgcolor:color'] = bgColor.GetId()
01514         
01515         gridSizer.Add(item = bgColor,
01516                       flag = wx.ALIGN_RIGHT,
01517                       pos = (row, 1))
01518         
01519         #
01520         # Use computation resolution
01521         #
01522         row += 1
01523         compResolution = wx.CheckBox(parent = panel, id = wx.ID_ANY,
01524                                     label = _("Constrain display resolution to computational settings"),
01525                                     name = "IsChecked")
01526         compResolution.SetValue(self.settings.Get(group = 'display', key = 'compResolution', subkey = 'enabled'))
01527         self.winId['display:compResolution:enabled'] = compResolution.GetId()
01528 
01529         gridSizer.Add(item = compResolution,
01530                       pos = (row, 0), span = (1, 2))
01531 
01532         #
01533         # auto-rendering
01534         #
01535         row += 1
01536         autoRendering = wx.CheckBox(parent = panel, id = wx.ID_ANY,
01537                                     label = _("Enable auto-rendering"),
01538                                     name = "IsChecked")
01539         autoRendering.SetValue(self.settings.Get(group = 'display', key = 'autoRendering', subkey = 'enabled'))
01540         self.winId['display:autoRendering:enabled'] = autoRendering.GetId()
01541 
01542         gridSizer.Add(item = autoRendering,
01543                       pos = (row, 0), span = (1, 2))
01544         
01545         #
01546         # auto-zoom
01547         #
01548         row += 1
01549         autoZooming = wx.CheckBox(parent = panel, id = wx.ID_ANY,
01550                                   label = _("Enable auto-zooming to selected map layer"),
01551                                   name = "IsChecked")
01552         autoZooming.SetValue(self.settings.Get(group = 'display', key = 'autoZooming', subkey = 'enabled'))
01553         self.winId['display:autoZooming:enabled'] = autoZooming.GetId()
01554 
01555         gridSizer.Add(item = autoZooming,
01556                       pos = (row, 0), span = (1, 2))
01557 
01558         sizer.Add(item = gridSizer, proportion = 1, flag = wx.ALL | wx.EXPAND, border = 5)
01559         border.Add(item = sizer, proportion = 0, flag = wx.LEFT | wx.RIGHT | wx.BOTTOM | wx.EXPAND, border = 3)
01560         
01561         panel.SetSizer(border)
01562                 
01563         # bindings
01564         fontButton.Bind(wx.EVT_BUTTON, self.OnSetFont)
01565         
01566         return panel
01567 
01568     def _createCmdPage(self, notebook):
01569         """!Create notebook page for commad dialog settings"""
01570         panel = wx.Panel(parent = notebook, id = wx.ID_ANY)
01571         notebook.AddPage(page = panel, text = _("Command"))
01572         
01573         border = wx.BoxSizer(wx.VERTICAL)
01574         box   = wx.StaticBox (parent = panel, id = wx.ID_ANY, label = " %s " % _("Command dialog settings"))
01575         sizer = wx.StaticBoxSizer(box, wx.VERTICAL)
01576         
01577         gridSizer = wx.GridBagSizer (hgap = 3, vgap = 3)
01578         gridSizer.AddGrowableCol(0)
01579         
01580         #
01581         # command dialog settings
01582         #
01583         row = 0
01584         # overwrite
01585         overwrite = wx.CheckBox(parent = panel, id = wx.ID_ANY,
01586                                 label = _("Allow output files to overwrite existing files"),
01587                                 name = "IsChecked")
01588         overwrite.SetValue(self.settings.Get(group = 'cmd', key = 'overwrite', subkey = 'enabled'))
01589         self.winId['cmd:overwrite:enabled'] = overwrite.GetId()
01590         
01591         gridSizer.Add(item = overwrite,
01592                       pos = (row, 0), span = (1, 2))
01593         row += 1
01594         # close
01595         close = wx.CheckBox(parent = panel, id = wx.ID_ANY,
01596                             label = _("Close dialog when command is successfully finished"),
01597                             name = "IsChecked")
01598         close.SetValue(self.settings.Get(group = 'cmd', key = 'closeDlg', subkey = 'enabled'))
01599         self.winId['cmd:closeDlg:enabled'] = close.GetId()
01600         
01601         gridSizer.Add(item = close,
01602                       pos = (row, 0), span = (1, 2))
01603         row += 1
01604         # add layer
01605         add = wx.CheckBox(parent = panel, id = wx.ID_ANY,
01606                           label = _("Add created map into layer tree"),
01607                           name = "IsChecked")
01608         add.SetValue(self.settings.Get(group = 'cmd', key = 'addNewLayer', subkey = 'enabled'))
01609         self.winId['cmd:addNewLayer:enabled'] = add.GetId()
01610     
01611         gridSizer.Add(item = add,
01612                       pos = (row, 0), span = (1, 2))
01613         
01614         row += 1
01615         # interactive input
01616         interactive = wx.CheckBox(parent = panel, id = wx.ID_ANY,
01617                                   label = _("Allow interactive input"),
01618                                   name = "IsChecked")
01619         interactive.SetValue(self.settings.Get(group = 'cmd', key = 'interactiveInput', subkey = 'enabled'))
01620         self.winId['cmd:interactiveInput:enabled'] = interactive.GetId()
01621         gridSizer.Add(item = interactive,
01622                       pos = (row, 0), span = (1, 2))
01623         
01624         row += 1
01625         # verbosity
01626         gridSizer.Add(item = wx.StaticText(parent = panel, id = wx.ID_ANY,
01627                                          label = _("Verbosity level:")),
01628                       flag = wx.ALIGN_LEFT |
01629                       wx.ALIGN_CENTER_VERTICAL,
01630                       pos = (row, 0))
01631         verbosity = wx.Choice(parent = panel, id = wx.ID_ANY, size = (200, -1),
01632                               choices = self.settings.Get(group = 'cmd', key = 'verbosity', subkey = 'choices', internal = True),
01633                               name = "GetStringSelection")
01634         verbosity.SetStringSelection(self.settings.Get(group = 'cmd', key = 'verbosity', subkey = 'selection'))
01635         self.winId['cmd:verbosity:selection'] = verbosity.GetId()
01636         
01637         gridSizer.Add(item = verbosity,
01638                       pos = (row, 1))
01639         
01640         sizer.Add(item = gridSizer, proportion = 1, flag = wx.ALL | wx.EXPAND, border = 5)
01641         border.Add(item = sizer, proportion = 0, flag = wx.ALL | wx.EXPAND, border = 3)
01642         
01643         #
01644         # raster settings
01645         #
01646         box   = wx.StaticBox (parent = panel, id = wx.ID_ANY, label = " %s " % _("Raster settings"))
01647         sizer = wx.StaticBoxSizer(box, wx.VERTICAL)
01648         
01649         gridSizer = wx.GridBagSizer (hgap = 3, vgap = 3)
01650         gridSizer.AddGrowableCol(0)
01651         
01652         #
01653         # raster overlay
01654         #
01655         row = 0
01656         rasterOverlay = wx.CheckBox(parent=panel, id=wx.ID_ANY,
01657                                     label=_("Overlay raster maps"),
01658                                     name='IsChecked')
01659         rasterOverlay.SetValue(self.settings.Get(group='cmd', key='rasterOverlay', subkey='enabled'))
01660         self.winId['cmd:rasterOverlay:enabled'] = rasterOverlay.GetId()
01661         
01662         gridSizer.Add(item=rasterOverlay,
01663                       pos=(row, 0), span=(1, 2))
01664         
01665         # default color table
01666         row += 1
01667         rasterCTCheck = wx.CheckBox(parent = panel, id = wx.ID_ANY,
01668                                     label = _("Default color table"),
01669                                     name = 'IsChecked')
01670         rasterCTCheck.SetValue(self.settings.Get(group = 'cmd', key = 'rasterColorTable', subkey = 'enabled'))
01671         self.winId['cmd:rasterColorTable:enabled'] = rasterCTCheck.GetId()
01672         rasterCTCheck.Bind(wx.EVT_CHECKBOX, self.OnCheckColorTable)
01673         
01674         gridSizer.Add(item = rasterCTCheck,
01675                       pos = (row, 0))
01676         
01677         rasterCTName = wx.Choice(parent = panel, id = wx.ID_ANY, size = (200, -1),
01678                                choices = utils.GetColorTables(),
01679                                name = "GetStringSelection")
01680         rasterCTName.SetStringSelection(self.settings.Get(group = 'cmd', key = 'rasterColorTable', subkey = 'selection'))
01681         self.winId['cmd:rasterColorTable:selection'] = rasterCTName.GetId()
01682         if not rasterCTCheck.IsChecked():
01683             rasterCTName.Enable(False)
01684         
01685         gridSizer.Add(item = rasterCTName,
01686                       pos = (row, 1))
01687         
01688         sizer.Add(item = gridSizer, proportion = 1, flag = wx.ALL | wx.EXPAND, border = 5)
01689         border.Add(item = sizer, proportion = 0, flag = wx.LEFT | wx.RIGHT | wx.BOTTOM | wx.EXPAND, border = 3)
01690         
01691         #
01692         # vector settings
01693         #
01694         box   = wx.StaticBox (parent = panel, id = wx.ID_ANY, label = " %s " % _("Vector settings"))
01695         sizer = wx.StaticBoxSizer(box, wx.VERTICAL)
01696         
01697         gridSizer = wx.FlexGridSizer (cols = 7, hgap = 3, vgap = 3)
01698         
01699         gridSizer.Add(item = wx.StaticText(parent = panel, id = wx.ID_ANY,
01700                                          label = _("Display:")),
01701                       flag = wx.ALIGN_CENTER_VERTICAL)
01702         
01703         for type in ('point', 'line', 'centroid', 'boundary',
01704                      'area', 'face'):
01705             chkbox = wx.CheckBox(parent = panel, label = type)
01706             checked = self.settings.Get(group = 'cmd', key = 'showType',
01707                                         subkey = [type, 'enabled'])
01708             chkbox.SetValue(checked)
01709             self.winId['cmd:showType:%s:enabled' % type] = chkbox.GetId()
01710             gridSizer.Add(item = chkbox)
01711 
01712         sizer.Add(item = gridSizer, proportion = 1, flag = wx.ALL | wx.EXPAND, border = 5)
01713         border.Add(item = sizer, proportion = 0, flag = wx.LEFT | wx.RIGHT | wx.BOTTOM | wx.EXPAND, border = 3)
01714         
01715         panel.SetSizer(border)
01716         
01717         return panel
01718 
01719     def _createAttributeManagerPage(self, notebook):
01720         """!Create notebook page for 'Attribute Table Manager' settings"""
01721         panel = wx.Panel(parent = notebook, id = wx.ID_ANY)
01722         notebook.AddPage(page = panel, text = _("Attributes"))
01723 
01724         pageSizer = wx.BoxSizer(wx.VERTICAL)
01725 
01726         #
01727         # highlighting
01728         #
01729         highlightBox = wx.StaticBox(parent = panel, id = wx.ID_ANY,
01730                                     label = " %s " % _("Highlighting"))
01731         highlightSizer = wx.StaticBoxSizer(highlightBox, wx.VERTICAL)
01732 
01733         flexSizer = wx.FlexGridSizer (cols = 2, hgap = 5, vgap = 5)
01734         flexSizer.AddGrowableCol(0)
01735         
01736         label = wx.StaticText(parent = panel, id = wx.ID_ANY, label = _("Color:"))
01737         hlColor = csel.ColourSelect(parent = panel, id = wx.ID_ANY,
01738                                     colour = self.settings.Get(group = 'atm', key = 'highlight', subkey = 'color'),
01739                                     size = globalvar.DIALOG_COLOR_SIZE)
01740         hlColor.SetName('GetColour')
01741         self.winId['atm:highlight:color'] = hlColor.GetId()
01742 
01743         flexSizer.Add(label, proportion = 0, flag = wx.ALIGN_CENTER_VERTICAL)
01744         flexSizer.Add(hlColor, proportion = 0, flag = wx.ALIGN_RIGHT | wx.FIXED_MINSIZE)
01745 
01746         label = wx.StaticText(parent = panel, id = wx.ID_ANY, label = _("Line width (in pixels):"))
01747         hlWidth = wx.SpinCtrl(parent = panel, id = wx.ID_ANY, size = (50, -1),
01748                               initial = self.settings.Get(group = 'atm', key = 'highlight',subkey = 'width'),
01749                               min = 1, max = 1e6)
01750         self.winId['atm:highlight:width'] = hlWidth.GetId()
01751 
01752         flexSizer.Add(label, proportion = 0, flag = wx.ALIGN_CENTER_VERTICAL)
01753         flexSizer.Add(hlWidth, proportion = 0, flag = wx.ALIGN_RIGHT | wx.FIXED_MINSIZE)
01754 
01755         highlightSizer.Add(item = flexSizer,
01756                            proportion = 0,
01757                            flag = wx.ALL | wx.EXPAND,
01758                            border = 5)
01759 
01760         pageSizer.Add(item = highlightSizer,
01761                       proportion = 0,
01762                       flag = wx.ALL | wx.EXPAND,
01763                       border = 5)
01764 
01765         #
01766         # data browser related settings
01767         #
01768         dataBrowserBox = wx.StaticBox(parent = panel, id = wx.ID_ANY,
01769                                     label = " %s " % _("Data browser"))
01770         dataBrowserSizer = wx.StaticBoxSizer(dataBrowserBox, wx.VERTICAL)
01771 
01772         flexSizer = wx.FlexGridSizer (cols = 2, hgap = 5, vgap = 5)
01773         flexSizer.AddGrowableCol(0)
01774         label = wx.StaticText(parent = panel, id = wx.ID_ANY, label = _("Left mouse double click:"))
01775         leftDbClick = wx.Choice(parent = panel, id = wx.ID_ANY,
01776                                 choices = self.settings.Get(group = 'atm', key = 'leftDbClick', subkey = 'choices', internal = True),
01777                                 name = "GetSelection")
01778         leftDbClick.SetSelection(self.settings.Get(group = 'atm', key = 'leftDbClick', subkey = 'selection'))
01779         self.winId['atm:leftDbClick:selection'] = leftDbClick.GetId()
01780 
01781         flexSizer.Add(label, proportion = 0, flag = wx.ALIGN_CENTER_VERTICAL)
01782         flexSizer.Add(leftDbClick, proportion = 0, flag = wx.ALIGN_RIGHT | wx.FIXED_MINSIZE)
01783 
01784         # encoding
01785         label = wx.StaticText(parent = panel, id = wx.ID_ANY,
01786                               label = _("Encoding (e.g. utf-8, ascii, iso8859-1, koi8-r):"))
01787         encoding = wx.TextCtrl(parent = panel, id = wx.ID_ANY,
01788                                value = self.settings.Get(group = 'atm', key = 'encoding', subkey = 'value'),
01789                                name = "GetValue", size = (200, -1))
01790         self.winId['atm:encoding:value'] = encoding.GetId()
01791 
01792         flexSizer.Add(label, proportion = 0, flag = wx.ALIGN_CENTER_VERTICAL)
01793         flexSizer.Add(encoding, proportion = 0, flag = wx.ALIGN_RIGHT | wx.FIXED_MINSIZE)
01794 
01795         # ask on delete record
01796         askOnDeleteRec = wx.CheckBox(parent = panel, id = wx.ID_ANY,
01797                                      label = _("Ask when deleting data record(s) from table"),
01798                                      name = 'IsChecked')
01799         askOnDeleteRec.SetValue(self.settings.Get(group = 'atm', key = 'askOnDeleteRec', subkey = 'enabled'))
01800         self.winId['atm:askOnDeleteRec:enabled'] = askOnDeleteRec.GetId()
01801 
01802         flexSizer.Add(askOnDeleteRec, proportion = 0)
01803 
01804         dataBrowserSizer.Add(item = flexSizer,
01805                            proportion = 0,
01806                            flag = wx.ALL | wx.EXPAND,
01807                            border = 5)
01808 
01809         pageSizer.Add(item = dataBrowserSizer,
01810                       proportion = 0,
01811                       flag = wx.LEFT | wx.RIGHT | wx.BOTTOM | wx.EXPAND,
01812                       border = 3)
01813 
01814         #
01815         # create table
01816         #
01817         createTableBox = wx.StaticBox(parent = panel, id = wx.ID_ANY,
01818                                     label = " %s " % _("Create table"))
01819         createTableSizer = wx.StaticBoxSizer(createTableBox, wx.VERTICAL)
01820 
01821         flexSizer = wx.FlexGridSizer (cols = 2, hgap = 5, vgap = 5)
01822         flexSizer.AddGrowableCol(0)
01823 
01824         label = wx.StaticText(parent = panel, id = wx.ID_ANY,
01825                               label = _("Key column:"))
01826         keyColumn = wx.TextCtrl(parent = panel, id = wx.ID_ANY,
01827                                 size = (250, -1))
01828         keyColumn.SetValue(self.settings.Get(group = 'atm', key = 'keycolumn', subkey = 'value'))
01829         self.winId['atm:keycolumn:value'] = keyColumn.GetId()
01830         
01831         flexSizer.Add(label, proportion = 0, flag = wx.ALIGN_CENTER_VERTICAL)
01832         flexSizer.Add(keyColumn, proportion = 0, flag = wx.ALIGN_RIGHT | wx.FIXED_MINSIZE)
01833 
01834         createTableSizer.Add(item = flexSizer,
01835                              proportion = 0,
01836                              flag = wx.ALL | wx.EXPAND,
01837                              border = 5)
01838 
01839         pageSizer.Add(item = createTableSizer,
01840                       proportion = 0,
01841                       flag = wx.LEFT | wx.RIGHT | wx.BOTTOM | wx.EXPAND,
01842                       border = 3)
01843         
01844         panel.SetSizer(pageSizer)
01845 
01846         return panel
01847 
01848     def _createProjectionPage(self, notebook):
01849         """!Create notebook page for workspace settings"""
01850         panel = wx.Panel(parent = notebook, id = wx.ID_ANY)
01851         notebook.AddPage(page = panel, text = _("Projection"))
01852         
01853         border = wx.BoxSizer(wx.VERTICAL)
01854         
01855         #
01856         # projections statusbar settings
01857         #
01858         box   = wx.StaticBox (parent = panel, id = wx.ID_ANY, label = " %s " % _("Projection statusbar settings"))
01859         sizer = wx.StaticBoxSizer(box, wx.VERTICAL)
01860 
01861         gridSizer = wx.GridBagSizer (hgap = 3, vgap = 3)
01862         gridSizer.AddGrowableCol(1)
01863 
01864         # epsg
01865         row = 0
01866         label = wx.StaticText(parent = panel, id = wx.ID_ANY,
01867                               label = _("EPSG code:"))
01868         epsgCode = wx.ComboBox(parent = panel, id = wx.ID_ANY,
01869                                name = "GetValue",
01870                                size = (150, -1))
01871         self.epsgCodeDict = dict()
01872         epsgCode.SetValue(str(self.settings.Get(group = 'projection', key = 'statusbar', subkey = 'epsg')))
01873         self.winId['projection:statusbar:epsg'] = epsgCode.GetId()
01874         
01875         gridSizer.Add(item = label,
01876                       pos = (row, 0),
01877                       flag = wx.ALIGN_CENTER_VERTICAL)
01878         gridSizer.Add(item = epsgCode,
01879                       pos = (row, 1), span = (1, 2))
01880         
01881         # proj
01882         row += 1
01883         label = wx.StaticText(parent = panel, id = wx.ID_ANY,
01884                               label = _("Proj.4 string (required):"))
01885         projString = wx.TextCtrl(parent = panel, id = wx.ID_ANY,
01886                                  value = self.settings.Get(group = 'projection', key = 'statusbar', subkey = 'proj4'),
01887                                  name = "GetValue", size = (400, -1))
01888         self.winId['projection:statusbar:proj4'] = projString.GetId()
01889 
01890         gridSizer.Add(item = label,
01891                       pos = (row, 0),
01892                       flag  =  wx.ALIGN_CENTER_VERTICAL)
01893         gridSizer.Add(item = projString,
01894                       pos = (row, 1), span = (1, 2),
01895                       flag = wx.ALIGN_CENTER_VERTICAL)
01896         
01897         # epsg file
01898         row += 1
01899         label = wx.StaticText(parent = panel, id = wx.ID_ANY,
01900                               label = _("EPSG file:"))
01901         projFile = wx.TextCtrl(parent = panel, id = wx.ID_ANY,
01902                                value  =  self.settings.Get(group = 'projection', key = 'statusbar', subkey = 'projFile'),
01903                                name = "GetValue", size = (400, -1))
01904         self.winId['projection:statusbar:projFile'] = projFile.GetId()
01905         gridSizer.Add(item = label,
01906                       pos = (row, 0),
01907                       flag  =  wx.ALIGN_CENTER_VERTICAL)
01908         gridSizer.Add(item = projFile,
01909                       pos = (row, 1),
01910                       flag  =  wx.ALIGN_CENTER_VERTICAL)
01911         
01912         # note + button
01913         row += 1
01914         note = wx.StaticText(parent = panel, id = wx.ID_ANY,
01915                              label = _("Load EPSG codes (be patient), enter EPSG code or "
01916                                        "insert Proj.4 string directly."))
01917         gridSizer.Add(item = note,
01918                       span = (1, 2),
01919                       pos = (row, 0))
01920 
01921         row += 1
01922         epsgLoad = wx.Button(parent = panel, id = wx.ID_ANY,
01923                              label = _("&Load EPSG codes"))
01924         gridSizer.Add(item = epsgLoad,
01925                       flag = wx.ALIGN_RIGHT,
01926                       pos = (row, 1))
01927         
01928         sizer.Add(item = gridSizer, proportion = 1, flag = wx.ALL | wx.EXPAND, border = 5)
01929         border.Add(item = sizer, proportion = 0, flag = wx.ALL | wx.EXPAND, border = 3)
01930 
01931         #
01932         # format
01933         #
01934         box   = wx.StaticBox (parent = panel, id = wx.ID_ANY, label = " %s " % _("Coordinates format"))
01935         sizer = wx.StaticBoxSizer(box, wx.VERTICAL)
01936         
01937         gridSizer = wx.GridBagSizer (hgap = 3, vgap = 3)
01938         gridSizer.AddGrowableCol(2)
01939 
01940         row = 0
01941         # ll format
01942         ll = wx.RadioBox(parent = panel, id = wx.ID_ANY,
01943                          label = " %s " % _("LL projections"),
01944                          choices = ["DMS", "DEG"],
01945                          name = "GetStringSelection")
01946         self.winId['projection:format:ll'] = ll.GetId()
01947         if self.settings.Get(group = 'projection', key = 'format', subkey = 'll') == 'DMS':
01948             ll.SetSelection(0)
01949         else:
01950             ll.SetSelection(1)
01951         
01952         # precision
01953         precision =  wx.SpinCtrl(parent = panel, id = wx.ID_ANY,
01954                                  min = 0, max = 12,
01955                                  name = "GetValue")
01956         precision.SetValue(int(self.settings.Get(group = 'projection', key = 'format', subkey = 'precision')))
01957         self.winId['projection:format:precision'] = precision.GetId()
01958                 
01959         gridSizer.Add(item = ll,
01960                       pos = (row, 0))
01961         gridSizer.Add(item = wx.StaticText(parent = panel, id = wx.ID_ANY,
01962                                          label = _("Precision:")),
01963                       flag = wx.ALIGN_CENTER_VERTICAL | wx.ALIGN_RIGHT | wx.LEFT,
01964                       border = 20,
01965                       pos = (row, 1))
01966         gridSizer.Add(item = precision,
01967                       flag = wx.ALIGN_CENTER_VERTICAL,
01968                       pos = (row, 2))
01969         
01970         
01971         sizer.Add(item = gridSizer, proportion = 1, flag = wx.ALL | wx.EXPAND, border = 5)
01972         border.Add(item = sizer, proportion = 0, flag = wx.LEFT | wx.RIGHT | wx.BOTTOM | wx.EXPAND, border = 3)
01973         
01974         panel.SetSizer(border)
01975 
01976         # bindings
01977         epsgLoad.Bind(wx.EVT_BUTTON, self.OnLoadEpsgCodes)
01978         epsgCode.Bind(wx.EVT_COMBOBOX, self.OnSetEpsgCode)
01979         epsgCode.Bind(wx.EVT_TEXT_ENTER, self.OnSetEpsgCode)
01980         
01981         return panel
01982 
01983     def OnCheckColorTable(self, event):
01984         """!Set/unset default color table"""
01985         win = self.FindWindowById(self.winId['cmd:rasterColorTable:selection'])
01986         if event.IsChecked():
01987             win.Enable()
01988         else:
01989             win.Enable(False)
01990         
01991     def OnLoadEpsgCodes(self, event):
01992         """!Load EPSG codes from the file"""
01993         win = self.FindWindowById(self.winId['projection:statusbar:projFile'])
01994         path = win.GetValue()
01995 
01996         self.epsgCodeDict = utils.ReadEpsgCodes(path)
01997         list = self.FindWindowById(self.winId['projection:statusbar:epsg'])
01998         if type(self.epsgCodeDict) == type(''):
01999             wx.MessageBox(parent = self,
02000                           message = _("Unable to read EPSG codes: %s") % self.epsgCodeDict,
02001                           caption = _("Error"),  style = wx.OK | wx.ICON_ERROR | wx.CENTRE)
02002             self.epsgCodeDict = dict()
02003             list.SetItems([])
02004             list.SetValue('')
02005             self.FindWindowById(self.winId['projection:statusbar:proj4']).SetValue('')
02006             return
02007         
02008         choices = map(str, self.epsgCodeDict.keys())
02009 
02010         list.SetItems(choices)
02011         try:
02012             code = int(list.GetValue())
02013         except ValueError:
02014             code = -1
02015         win = self.FindWindowById(self.winId['projection:statusbar:proj4'])
02016         if code in self.epsgCodeDict:
02017             win.SetValue(self.epsgCodeDict[code][1])
02018         else:
02019             list.SetSelection(0)
02020             code = int(list.GetStringSelection())
02021             win.SetValue(self.epsgCodeDict[code][1])
02022     
02023     def OnSetEpsgCode(self, event):
02024         """!EPSG code selected"""
02025         winCode = self.FindWindowById(event.GetId())
02026         win = self.FindWindowById(self.winId['projection:statusbar:proj4'])
02027         if not self.epsgCodeDict:
02028             wx.MessageBox(parent = self,
02029                           message = _("EPSG code %s not found") % event.GetString(),
02030                           caption = _("Error"),  style = wx.OK | wx.ICON_ERROR | wx.CENTRE)
02031             winCode.SetValue('')
02032             win.SetValue('')
02033         
02034         try:
02035             code = int(event.GetString())
02036         except ValueError:
02037             wx.MessageBox(parent = self,
02038                           message = _("EPSG code %s not found") % str(code),
02039                           caption = _("Error"),  style = wx.OK | wx.ICON_ERROR | wx.CENTRE)
02040             winCode.SetValue('')
02041             win.SetValue('')
02042         
02043         
02044         try:
02045             win.SetValue(self.epsgCodeDict[code][1].replace('<>', '').strip())
02046         except KeyError:
02047             wx.MessageBox(parent = self,
02048                           message = _("EPSG code %s not found") % str(code),
02049                           caption = _("Error"),  style = wx.OK | wx.ICON_ERROR | wx.CENTRE)
02050             winCode.SetValue('')
02051             win.SetValue('')
02052         
02053     def OnSetFont(self, event):
02054         """'Set font' button pressed"""
02055         dlg = DefaultFontDialog(parent = self,
02056                                 title = _('Select default display font'),
02057                                 style = wx.DEFAULT_DIALOG_STYLE,
02058                                 type = 'font')
02059         
02060         if dlg.ShowModal() == wx.ID_OK:
02061             # set default font and encoding environmental variables
02062             if dlg.font:
02063                 os.environ["GRASS_FONT"] = dlg.font
02064                 self.settings.Set(group = 'display', value = dlg.font,
02065                                   key = 'font', subkey = 'type')
02066 
02067             if dlg.encoding and \
02068                     dlg.encoding != "ISO-8859-1":
02069                 os.environ["GRASS_ENCODING"] = dlg.encoding
02070                 self.settings.Set(group = 'display', value = dlg.encoding,
02071                                   key = 'font', subkey = 'encoding')
02072                 
02073         dlg.Destroy()
02074         
02075         event.Skip()
02076 
02077     def OnSetOutputFont(self, event):
02078         """'Set output font' button pressed
02079         """
02080         dlg = DefaultFontDialog(parent = self,
02081                                 title = _('Select output font'),
02082                                 style = wx.DEFAULT_DIALOG_STYLE,
02083                                 type = 'outputfont')
02084         
02085         if dlg.ShowModal() == wx.ID_OK:
02086             # set output font and font size variables
02087             if dlg.font:
02088                 self.settings.Set(group = 'appearance', value = dlg.font,
02089                                   key = 'outputfont', subkey = 'type')
02090                 
02091                 self.settings.Set(group = 'appearance', value = dlg.fontsize,
02092                                   key = 'outputfont', subkey = 'size')
02093         
02094 # Standard font dialog broken for Mac in OS X 10.6
02095 #        type = self.settings.Get(group = 'display', key = 'outputfont', subkey = 'type')   
02096                            
02097 #        size = self.settings.Get(group = 'display', key = 'outputfont', subkey = 'size')
02098 #        if size == None or size == 0: size = 10
02099 #        size = float(size)
02100         
02101 #        data = wx.FontData()
02102 #        data.EnableEffects(True)
02103 #        data.SetInitialFont(wx.Font(pointSize = size, family = wx.FONTFAMILY_MODERN, faceName = type, style = wx.NORMAL, weight = 0))
02104 
02105 #        dlg = wx.FontDialog(self, data)
02106 
02107 #        if dlg.ShowModal() == wx.ID_OK:
02108 #            data = dlg.GetFontData()
02109 #            font = data.GetChosenFont()
02110 
02111 #            self.settings.Set(group = 'display', value = font.GetFaceName(),
02112 #                                  key = 'outputfont', subkey = 'type')
02113 #            self.settings.Set(group = 'display', value = font.GetPointSize(),
02114 #                                  key = 'outputfont', subkey = 'size')
02115                 
02116         dlg.Destroy()
02117 
02118         event.Skip()
02119 
02120 class DefaultFontDialog(wx.Dialog):
02121     """
02122     Opens a file selection dialog to select default font
02123     to use in all GRASS displays
02124     """
02125     def __init__(self, parent, title, id = wx.ID_ANY,
02126                  style = wx.DEFAULT_DIALOG_STYLE |
02127                  wx.RESIZE_BORDER,
02128                  settings = globalSettings,
02129                  type = 'font'):
02130         
02131         self.settings = settings
02132         self.type = type
02133         
02134         wx.Dialog.__init__(self, parent, id, title, style = style)
02135 
02136         panel = wx.Panel(parent = self, id = wx.ID_ANY)
02137         
02138         self.fontlist = self.GetFonts()
02139         
02140         border = wx.BoxSizer(wx.VERTICAL)
02141         box   = wx.StaticBox (parent = panel, id = wx.ID_ANY, label = " %s " % _("Font settings"))
02142         sizer = wx.StaticBoxSizer(box, wx.VERTICAL)
02143 
02144         gridSizer = wx.GridBagSizer (hgap = 5, vgap = 5)
02145         gridSizer.AddGrowableCol(0)
02146 
02147         label = wx.StaticText(parent = panel, id = wx.ID_ANY,
02148                               label = _("Select font:"))
02149         gridSizer.Add(item = label,
02150                       flag = wx.ALIGN_TOP,
02151                       pos = (0,0))
02152         
02153         self.fontlb = wx.ListBox(parent = panel, id = wx.ID_ANY, pos = wx.DefaultPosition,
02154                                  choices = self.fontlist,
02155                                  style = wx.LB_SINGLE|wx.LB_SORT)
02156         self.Bind(wx.EVT_LISTBOX, self.EvtListBox, self.fontlb)
02157         self.Bind(wx.EVT_LISTBOX_DCLICK, self.EvtListBoxDClick, self.fontlb)
02158 
02159         gridSizer.Add(item = self.fontlb,
02160                 flag = wx.EXPAND, pos = (1, 0))
02161 
02162         if self.type == 'font':
02163             if "GRASS_FONT" in os.environ:
02164                 self.font = os.environ["GRASS_FONT"]
02165             else:
02166                 self.font = self.settings.Get(group = 'display',
02167                                               key = 'font', subkey = 'type')
02168             self.encoding = self.settings.Get(group = 'display',
02169                                           key = 'font', subkey = 'encoding')
02170 
02171             label = wx.StaticText(parent = panel, id = wx.ID_ANY,
02172                                   label = _("Character encoding:"))
02173             gridSizer.Add(item = label,
02174                           flag = wx.ALIGN_CENTER_VERTICAL,
02175                           pos = (2, 0))
02176 
02177             self.textentry = wx.TextCtrl(parent = panel, id = wx.ID_ANY,
02178                                          value = self.encoding)
02179             gridSizer.Add(item = self.textentry,
02180                     flag = wx.EXPAND, pos = (3, 0))
02181 
02182             self.textentry.Bind(wx.EVT_TEXT, self.OnEncoding)
02183 
02184         elif self.type == 'outputfont':
02185             self.font = self.settings.Get(group = 'appearance',
02186                                               key = 'outputfont', subkey = 'type')
02187             self.fontsize = self.settings.Get(group = 'appearance',
02188                                           key = 'outputfont', subkey = 'size')
02189             label = wx.StaticText(parent = panel, id = wx.ID_ANY,
02190                               label = _("Font size:"))
02191             gridSizer.Add(item = label,
02192                       flag = wx.ALIGN_CENTER_VERTICAL,
02193                       pos = (2, 0))
02194                       
02195             self.spin = wx.SpinCtrl(parent = panel, id = wx.ID_ANY)
02196             if self.fontsize:
02197                 self.spin.SetValue(int(self.fontsize))
02198             self.spin.Bind(wx.EVT_SPINCTRL, self.OnSizeSpin)
02199             self.spin.Bind(wx.EVT_TEXT, self.OnSizeSpin)
02200             gridSizer.Add(item = self.spin,
02201                       flag = wx.ALIGN_CENTER_VERTICAL,
02202                       pos = (3, 0))
02203 
02204         else: 
02205             return
02206 
02207         if self.font:
02208             self.fontlb.SetStringSelection(self.font, True)
02209 
02210         sizer.Add(item = gridSizer, proportion = 1,
02211                   flag = wx.EXPAND | wx.ALL,
02212                   border = 5)
02213 
02214         border.Add(item = sizer, proportion = 1,
02215                    flag = wx.ALL | wx.EXPAND, border = 3)
02216         
02217         btnsizer = wx.StdDialogButtonSizer()
02218 
02219         btn = wx.Button(parent = panel, id = wx.ID_OK)
02220         btn.SetDefault()
02221         btnsizer.AddButton(btn)
02222 
02223         btn = wx.Button(parent = panel, id = wx.ID_CANCEL)
02224         btnsizer.AddButton(btn)
02225         btnsizer.Realize()
02226 
02227         border.Add(item = btnsizer, proportion = 0,
02228                    flag = wx.EXPAND | wx.ALIGN_RIGHT | wx.ALL, border = 5)
02229         
02230         panel.SetAutoLayout(True)
02231         panel.SetSizer(border)
02232         border.Fit(self)
02233         
02234         self.Layout()
02235         
02236     def EvtRadioBox(self, event):
02237         if event.GetInt() == 0:
02238             self.fonttype = 'grassfont'
02239         elif event.GetInt() == 1:
02240             self.fonttype = 'truetype'
02241 
02242         self.fontlist = self.GetFonts(self.fonttype)
02243         self.fontlb.SetItems(self.fontlist)
02244 
02245     def OnEncoding(self, event):
02246         self.encoding = event.GetString()
02247 
02248     def EvtListBox(self, event):
02249         self.font = event.GetString()
02250         event.Skip()
02251 
02252     def EvtListBoxDClick(self, event):
02253         self.font = event.GetString()
02254         event.Skip()
02255         
02256     def OnSizeSpin(self, event):
02257         self.fontsize = self.spin.GetValue()
02258         event.Skip()
02259     
02260     def GetFonts(self):
02261         """
02262         parses fonts directory or fretypecap file to get a list of fonts for the listbox
02263         """
02264         fontlist = []
02265 
02266         cmd = ["d.font", "-l"]
02267 
02268         ret = gcmd.RunCommand('d.font',
02269                               read = True,
02270                               flags = 'l')
02271 
02272         if not ret:
02273             return fontlist
02274 
02275         dfonts = ret.splitlines()
02276         dfonts.sort(lambda x,y: cmp(x.lower(), y.lower()))
02277         for item in range(len(dfonts)):
02278            # ignore duplicate fonts and those starting with #
02279            if not dfonts[item].startswith('#') and \
02280                   dfonts[item] != dfonts[item-1]:
02281               fontlist.append(dfonts[item])
02282 
02283         return fontlist
02284 
02285 class MapsetAccess(wx.Dialog):
02286     """!Controls setting options and displaying/hiding map overlay
02287     decorations
02288     """
02289     def __init__(self, parent, id = wx.ID_ANY,
02290                  title = _('Manage access to mapsets'),
02291                  size  =  (350, 400),
02292                  style  =  wx.DEFAULT_DIALOG_STYLE | wx.RESIZE_BORDER, **kwargs):
02293         
02294         wx.Dialog.__init__(self, parent, id, title, size = size, style = style, **kwargs)
02295 
02296         self.all_mapsets_ordered = utils.ListOfMapsets(get = 'ordered')
02297         self.accessible_mapsets  = utils.ListOfMapsets(get = 'accessible')
02298         self.curr_mapset = grass.gisenv()['MAPSET']
02299 
02300         # make a checklistbox from available mapsets and check those that are active
02301         sizer = wx.BoxSizer(wx.VERTICAL)
02302 
02303         label = wx.StaticText(parent = self, id = wx.ID_ANY,
02304                               label = _("Check a mapset to make it accessible, uncheck it to hide it.\n"
02305                                         "  Notes:\n"
02306                                         "    - The current mapset is always accessible.\n"
02307                                         "    - You may only write to the current mapset.\n"
02308                                         "    - You may only write to mapsets which you own."))
02309         
02310         sizer.Add(item = label, proportion = 0,
02311                   flag = wx.ALL, border = 5)
02312 
02313         self.mapsetlb = CheckListMapset(parent = self)
02314         self.mapsetlb.LoadData()
02315         
02316         sizer.Add(item = self.mapsetlb, proportion = 1,
02317                   flag = wx.ALL | wx.EXPAND, border = 5)
02318 
02319         # check all accessible mapsets
02320         for mset in self.accessible_mapsets:
02321             self.mapsetlb.CheckItem(self.all_mapsets_ordered.index(mset), True)
02322 
02323         # FIXME (howto?): grey-out current mapset
02324         #self.mapsetlb.Enable(0, False)
02325 
02326         # dialog buttons
02327         line = wx.StaticLine(parent = self, id = wx.ID_ANY,
02328                              style = wx.LI_HORIZONTAL)
02329         sizer.Add(item = line, proportion = 0,
02330                   flag = wx.EXPAND | wx.ALIGN_CENTRE | wx.ALL, border = 5)
02331 
02332         btnsizer = wx.StdDialogButtonSizer()
02333         okbtn = wx.Button(self, wx.ID_OK)
02334         okbtn.SetDefault()
02335         btnsizer.AddButton(okbtn)
02336 
02337         cancelbtn = wx.Button(self, wx.ID_CANCEL)
02338         btnsizer.AddButton(cancelbtn)
02339         btnsizer.Realize()
02340 
02341         sizer.Add(item = btnsizer, proportion = 0,
02342                   flag = wx.EXPAND | wx.ALIGN_RIGHT | wx.ALL, border = 5)
02343 
02344         # do layout
02345         self.Layout()
02346         self.SetSizer(sizer)
02347         sizer.Fit(self)
02348 
02349         self.SetMinSize(size)
02350         
02351     def GetMapsets(self):
02352         """!Get list of checked mapsets"""
02353         ms = []
02354         i = 0
02355         for mset in self.all_mapsets_ordered:
02356             if self.mapsetlb.IsChecked(i):
02357                 ms.append(mset)
02358             i += 1
02359 
02360         return ms
02361 
02362 class CheckListMapset(wx.ListCtrl, listmix.ListCtrlAutoWidthMixin, listmix.CheckListCtrlMixin):
02363     """!List of mapset/owner/group"""
02364     def __init__(self, parent, pos = wx.DefaultPosition,
02365                  log = None):
02366         self.parent = parent
02367         
02368         wx.ListCtrl.__init__(self, parent, wx.ID_ANY,
02369                              style = wx.LC_REPORT)
02370         listmix.CheckListCtrlMixin.__init__(self)
02371         self.log = log
02372 
02373         # setup mixins
02374         listmix.ListCtrlAutoWidthMixin.__init__(self)
02375 
02376     def LoadData(self):
02377         """!Load data into list"""
02378         self.InsertColumn(0, _('Mapset'))
02379         self.InsertColumn(1, _('Owner'))
02380         ### self.InsertColumn(2, _('Group'))
02381         gisenv = grass.gisenv()
02382         locationPath = os.path.join(gisenv['GISDBASE'], gisenv['LOCATION_NAME'])
02383 
02384         for mapset in self.parent.all_mapsets_ordered:
02385             index = self.InsertStringItem(sys.maxint, mapset)
02386             mapsetPath = os.path.join(locationPath,
02387                                       mapset)
02388             stat_info = os.stat(mapsetPath)
02389             if havePwd:
02390                 self.SetStringItem(index, 1, "%s" % pwd.getpwuid(stat_info.st_uid)[0])
02391                 # FIXME: get group name
02392                 ### self.SetStringItem(index, 2, "%-8s" % stat_info.st_gid) 
02393             else:
02394                 # FIXME: no pwd under MS Windows (owner: 0, group: 0)
02395                 self.SetStringItem(index, 1, "%-8s" % stat_info.st_uid)
02396                 ### self.SetStringItem(index, 2, "%-8s" % stat_info.st_gid)
02397                 
02398         self.SetColumnWidth(col = 0, width = wx.LIST_AUTOSIZE)
02399         ### self.SetColumnWidth(col = 1, width = wx.LIST_AUTOSIZE)
02400         
02401     def OnCheckItem(self, index, flag):
02402         """!Mapset checked/unchecked"""
02403         mapset = self.parent.all_mapsets_ordered[index]
02404         if mapset == self.parent.curr_mapset:
02405             self.CheckItem(index, True)
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines