GRASS Programmer's Manual
6.4.2(2012)
|
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)