GRASS Programmer's Manual
6.4.2(2012)
|
00001 """! 00002 @package gdialogs.py 00003 00004 @brief Various dialogs used in wxGUI. 00005 00006 List of classes: 00007 - ElementDialog 00008 - LocationDialog 00009 - MapsetDialog 00010 - NewVectorDialog 00011 - SavedRegion 00012 - DecorationDialog 00013 - TextLayerDialog 00014 - AddMapLayersDialog 00015 - ImportDialog 00016 - GdalImportDialog 00017 - DxfImportDialog 00018 - LayersList (used by MultiImport) 00019 - SetOpacityDialog 00020 - StaticWrapText 00021 - ImageSizeDialog 00022 00023 (C) 2008-2011 by the GRASS Development Team 00024 00025 This program is free software under the GNU General Public 00026 License (>=v2). Read the file COPYING that comes with GRASS 00027 for details. 00028 00029 @author Martin Landa <landa.martin gmail.com> 00030 """ 00031 00032 import os 00033 import sys 00034 import re 00035 from bisect import bisect 00036 00037 import wx 00038 import wx.lib.filebrowsebutton as filebrowse 00039 import wx.lib.mixins.listctrl as listmix 00040 00041 from grass.script import core as grass 00042 from grass.script import task as gtask 00043 00044 import gcmd 00045 import globalvar 00046 import gselect 00047 import menuform 00048 import utils 00049 from debug import Debug 00050 from preferences import globalSettings as UserSettings 00051 00052 class ElementDialog(wx.Dialog): 00053 def __init__(self, parent, title, label, id = wx.ID_ANY, 00054 etype = False, style = wx.DEFAULT_DIALOG_STYLE | wx.RESIZE_BORDER, 00055 **kwargs): 00056 """!General dialog to choose given element (location, mapset, vector map, etc.) 00057 00058 @param parent window 00059 @param title window title 00060 @param label element label 00061 @param etype show also ElementSelect 00062 """ 00063 wx.Dialog.__init__(self, parent, id, title, style = style, **kwargs) 00064 00065 self.etype = etype 00066 self.label = label 00067 00068 self.panel = wx.Panel(parent = self, id = wx.ID_ANY) 00069 00070 self.btnCancel = wx.Button(parent = self.panel, id = wx.ID_CANCEL) 00071 self.btnOK = wx.Button(parent = self.panel, id = wx.ID_OK) 00072 self.btnOK.SetDefault() 00073 self.btnOK.Enable(False) 00074 00075 if self.etype: 00076 self.typeSelect = gselect.ElementSelect(parent = self.panel, 00077 size = globalvar.DIALOG_GSELECT_SIZE) 00078 self.typeSelect.Bind(wx.EVT_CHOICE, self.OnType) 00079 00080 self.element = None # must be defined 00081 00082 self.__layout() 00083 00084 def PostInit(self): 00085 self.element.SetFocus() 00086 self.element.Bind(wx.EVT_TEXT, self.OnElement) 00087 00088 def OnType(self, event): 00089 """!Select element type""" 00090 if not self.etype: 00091 return 00092 evalue = self.typeSelect.GetValue(event.GetString()) 00093 self.element.SetType(evalue) 00094 00095 def OnElement(self, event): 00096 """!Name for vector map layer given""" 00097 if len(event.GetString()) > 0: 00098 self.btnOK.Enable(True) 00099 else: 00100 self.btnOK.Enable(False) 00101 00102 def __layout(self): 00103 """!Do layout""" 00104 self.sizer = wx.BoxSizer(wx.VERTICAL) 00105 00106 self.dataSizer = wx.BoxSizer(wx.VERTICAL) 00107 00108 if self.etype: 00109 self.dataSizer.Add(item = wx.StaticText(parent = self.panel, id = wx.ID_ANY, 00110 label = _("Type of element:")), 00111 proportion=0, flag=wx.ALL, border=1) 00112 self.dataSizer.Add(item = self.typeSelect, 00113 proportion=0, flag=wx.ALL, border=1) 00114 00115 self.dataSizer.Add(item = wx.StaticText(parent = self.panel, id = wx.ID_ANY, 00116 label = self.label), 00117 proportion=0, flag=wx.ALL, border=1) 00118 00119 # buttons 00120 btnSizer = wx.StdDialogButtonSizer() 00121 btnSizer.AddButton(self.btnCancel) 00122 btnSizer.AddButton(self.btnOK) 00123 btnSizer.Realize() 00124 00125 self.sizer.Add(item=self.dataSizer, proportion=1, 00126 flag=wx.EXPAND | wx.ALL | wx.ALIGN_CENTER, border=5) 00127 00128 self.sizer.Add(item=btnSizer, proportion=0, 00129 flag=wx.EXPAND | wx.ALL | wx.ALIGN_CENTER, border=5) 00130 00131 def GetElement(self): 00132 """!Return (mapName, overwrite)""" 00133 return self.element.GetValue() 00134 00135 def GetType(self): 00136 """!Get element type""" 00137 return self.element.tcp.GetType() 00138 00139 class LocationDialog(ElementDialog): 00140 """!Dialog used to select location""" 00141 def __init__(self, parent, title = _("Select GRASS location and mapset"), id = wx.ID_ANY): 00142 ElementDialog.__init__(self, parent, title, label = _("Name of GRASS location:")) 00143 00144 self.element = gselect.LocationSelect(parent = self.panel, id = wx.ID_ANY, 00145 size = globalvar.DIALOG_GSELECT_SIZE) 00146 00147 self.element1 = gselect.MapsetSelect(parent = self.panel, id = wx.ID_ANY, 00148 size = globalvar.DIALOG_GSELECT_SIZE, 00149 setItems = False) 00150 00151 self.PostInit() 00152 00153 self.__Layout() 00154 self.SetMinSize(self.GetSize()) 00155 00156 def __Layout(self): 00157 """!Do layout""" 00158 self.dataSizer.Add(self.element, proportion=0, 00159 flag=wx.EXPAND | wx.ALL, border=1) 00160 00161 self.dataSizer.Add(wx.StaticText(parent = self.panel, id = wx.ID_ANY, 00162 label = _("Name of mapset:")), proportion=0, 00163 flag=wx.EXPAND | wx.ALL, border=1) 00164 00165 self.dataSizer.Add(self.element1, proportion=0, 00166 flag=wx.EXPAND | wx.ALL, border=1) 00167 00168 self.panel.SetSizer(self.sizer) 00169 self.sizer.Fit(self) 00170 00171 def OnElement(self, event): 00172 """!Select mapset given location name""" 00173 location = event.GetString() 00174 00175 if location: 00176 dbase = grass.gisenv()['GISDBASE'] 00177 self.element1.SetItems(utils.GetListOfMapsets(dbase, location, selectable = True)) 00178 self.element1.SetSelection(0) 00179 mapset = self.element1.GetStringSelection() 00180 00181 if location and mapset: 00182 self.btnOK.Enable(True) 00183 else: 00184 self.btnOK.Enable(False) 00185 00186 def GetValues(self): 00187 """!Get location, mapset""" 00188 return (self.GetElement(), self.element1.GetStringSelection()) 00189 00190 class MapsetDialog(ElementDialog): 00191 """!Dialog used to select mapset""" 00192 def __init__(self, parent, title = _("Select mapset in GRASS location"), 00193 location = None, id = wx.ID_ANY): 00194 ElementDialog.__init__(self, parent, title, label = _("Name of mapset:")) 00195 if location: 00196 self.SetTitle(self.GetTitle() + ' <%s>' % location) 00197 else: 00198 self.SetTitle(self.GetTitle() + ' <%s>' % grass.gisenv()['LOCATION_NAME']) 00199 00200 self.element = gselect.MapsetSelect(parent = self.panel, id = wx.ID_ANY, 00201 size = globalvar.DIALOG_GSELECT_SIZE) 00202 00203 self.PostInit() 00204 00205 self.__Layout() 00206 self.SetMinSize(self.GetSize()) 00207 00208 def __Layout(self): 00209 """!Do layout""" 00210 self.dataSizer.Add(self.element, proportion=0, 00211 flag=wx.EXPAND | wx.ALL, border=1) 00212 00213 self.panel.SetSizer(self.sizer) 00214 self.sizer.Fit(self) 00215 00216 def GetMapset(self): 00217 return self.GetElement() 00218 00219 class NewVectorDialog(ElementDialog): 00220 def __init__(self, parent, id = wx.ID_ANY, title = _('Create new vector map'), 00221 disableAdd = False, disableTable = False, 00222 style=wx.DEFAULT_DIALOG_STYLE | wx.RESIZE_BORDER, *kwargs): 00223 """!Dialog for creating new vector map 00224 00225 @param parent parent window 00226 @param id window id 00227 @param title window title 00228 @param disableAdd disable 'add layer' checkbox 00229 @param disableTable disable 'create table' checkbox 00230 @param style window style 00231 @param kwargs other argumentes for ElementDialog 00232 00233 @return dialog instance 00234 """ 00235 ElementDialog.__init__(self, parent, title, label = _("Name for new vector map:")) 00236 00237 self.element = gselect.Select(parent = self.panel, id = wx.ID_ANY, size = globalvar.DIALOG_GSELECT_SIZE, 00238 type = 'vector', mapsets = [grass.gisenv()['MAPSET'],]) 00239 00240 self.table = wx.CheckBox(parent = self.panel, id = wx.ID_ANY, 00241 label = _("Create attribute table")) 00242 self.table.SetValue(True) 00243 if disableTable: 00244 self.table.Enable(False) 00245 00246 self.keycol = wx.TextCtrl(parent = self.panel, id = wx.ID_ANY, 00247 size = globalvar.DIALOG_SPIN_SIZE) 00248 self.keycol.SetValue(UserSettings.Get(group = 'atm', key = 'keycolumn', subkey = 'value')) 00249 if disableTable: 00250 self.keycol.Enable(False) 00251 00252 self.addbox = wx.CheckBox(parent = self.panel, 00253 label = _('Add created map into layer tree'), style = wx.NO_BORDER) 00254 if disableAdd: 00255 self.addbox.SetValue(True) 00256 self.addbox.Enable(False) 00257 else: 00258 self.addbox.SetValue(UserSettings.Get(group = 'cmd', key = 'addNewLayer', subkey = 'enabled')) 00259 00260 self.table.Bind(wx.EVT_CHECKBOX, self.OnTable) 00261 00262 self.PostInit() 00263 00264 self._layout() 00265 self.SetMinSize(self.GetSize()) 00266 00267 def OnMapName(self, event): 00268 """!Name for vector map layer given""" 00269 self.OnElement(event) 00270 00271 def OnTable(self, event): 00272 self.keycol.Enable(event.IsChecked()) 00273 00274 def _layout(self): 00275 """!Do layout""" 00276 self.dataSizer.Add(self.element, proportion = 0, 00277 flag = wx.EXPAND | wx.ALL, border = 1) 00278 00279 self.dataSizer.Add(self.table, proportion = 0, 00280 flag = wx.EXPAND | wx.ALL, border = 1) 00281 00282 keySizer = wx.BoxSizer(wx.HORIZONTAL) 00283 keySizer.Add(item = wx.StaticText(parent = self.panel, label = _("Key column:")), 00284 proportion = 0, 00285 flag = wx.ALIGN_CENTER_VERTICAL) 00286 keySizer.AddSpacer(10) 00287 keySizer.Add(item = self.keycol, proportion = 0, 00288 flag = wx.ALIGN_RIGHT) 00289 self.dataSizer.Add(item = keySizer, proportion = 1, 00290 flag = wx.EXPAND | wx.ALL, border = 1) 00291 00292 self.dataSizer.AddSpacer(5) 00293 00294 self.dataSizer.Add(item = self.addbox, proportion = 0, 00295 flag = wx.EXPAND | wx.ALL, border = 1) 00296 00297 self.panel.SetSizer(self.sizer) 00298 self.sizer.Fit(self) 00299 00300 def GetName(self, full = False): 00301 """!Get name of vector map to be created 00302 00303 @param full True to get fully qualified name 00304 """ 00305 name = self.GetElement() 00306 if full: 00307 if '@' in name: 00308 return name 00309 else: 00310 return name + '@' + grass.gisenv()['MAPSET'] 00311 00312 return name.split('@', 1)[0] 00313 00314 def GetKey(self): 00315 """!Get key column name""" 00316 return self.keycol.GetValue() 00317 00318 def IsChecked(self, key): 00319 """!Get dialog properties 00320 00321 @param key window key ('add', 'table') 00322 00323 @return True/False 00324 @return None on error 00325 """ 00326 if key == 'add': 00327 return self.addbox.IsChecked() 00328 elif key == 'table': 00329 return self.table.IsChecked() 00330 00331 return None 00332 00333 def CreateNewVector(parent, cmd, title = _('Create new vector map'), 00334 exceptMap = None, log = None, disableAdd = False, disableTable = False): 00335 """!Create new vector map layer 00336 00337 @param cmd (prog, **kwargs) 00338 @param title window title 00339 @param exceptMap list of maps to be excepted 00340 @param log 00341 @param disableAdd disable 'add layer' checkbox 00342 @param disableTable disable 'create table' checkbox 00343 00344 @return dialog instance 00345 @return None on error 00346 """ 00347 dlg = NewVectorDialog(parent, title = title, 00348 disableAdd = disableAdd, disableTable = disableTable) 00349 00350 if dlg.ShowModal() != wx.ID_OK: 00351 dlg.Destroy() 00352 return None 00353 00354 outmap = dlg.GetName() 00355 key = dlg.GetKey() 00356 if outmap == exceptMap: 00357 gcmd.GError(parent = parent, 00358 message = _("Unable to create vector map <%s>.") % outmap) 00359 dlg.Destroy() 00360 return None 00361 if dlg.table.IsEnabled() and not key: 00362 gcmd.GError(parent = parent, 00363 message = _("Invalid or empty key column.\n" 00364 "Unable to create vector map <%s>.") % outmap) 00365 dlg.Destroy() 00366 return 00367 00368 if outmap == '': # should not happen 00369 dlg.Destroy() 00370 return None 00371 00372 # update cmd -> output name defined 00373 cmd[1][cmd[2]] = outmap 00374 00375 listOfVectors = grass.list_grouped('vect')[grass.gisenv()['MAPSET']] 00376 00377 overwrite = False 00378 if not UserSettings.Get(group = 'cmd', key = 'overwrite', subkey = 'enabled') and \ 00379 outmap in listOfVectors: 00380 dlgOw = wx.MessageDialog(parent, message = _("Vector map <%s> already exists " 00381 "in the current mapset. " 00382 "Do you want to overwrite it?") % outmap, 00383 caption = _("Overwrite?"), 00384 style = wx.YES_NO | wx.YES_DEFAULT | wx.ICON_QUESTION) 00385 if dlgOw.ShowModal() == wx.ID_YES: 00386 overwrite = True 00387 else: 00388 dlgOw.Destroy() 00389 dlg.Destroy() 00390 return None 00391 00392 if UserSettings.Get(group = 'cmd', key = 'overwrite', subkey = 'enabled'): 00393 overwrite = True 00394 00395 ret = gcmd.RunCommand(prog = cmd[0], 00396 parent = parent, 00397 overwrite = overwrite, 00398 **cmd[1]) 00399 if ret != 0: 00400 dlg.Destroy() 00401 return None 00402 00403 # create attribute table 00404 if dlg.table.IsEnabled() and dlg.table.IsChecked(): 00405 sql = 'CREATE TABLE %s (%s INTEGER)' % (outmap, key) 00406 00407 gcmd.RunCommand('db.connect', 00408 flags = 'c') 00409 00410 Debug.msg(1, "SQL: %s" % sql) 00411 gcmd.RunCommand('db.execute', 00412 quiet = True, 00413 parent = parent, 00414 stdin = sql) 00415 00416 gcmd.RunCommand('v.db.connect', 00417 quiet = True, 00418 parent = parent, 00419 map = outmap, 00420 table = outmap, 00421 key = key, 00422 layer = '1') 00423 00424 # return fully qualified map name 00425 if '@' not in outmap: 00426 outmap += '@' + grass.gisenv()['MAPSET'] 00427 00428 if log: 00429 log.WriteLog(_("New vector map <%s> created") % outmap) 00430 00431 return dlg 00432 00433 class SavedRegion(wx.Dialog): 00434 def __init__(self, parent, id = wx.ID_ANY, title="", loadsave='load', 00435 **kwargs): 00436 """!Loading and saving of display extents to saved region file 00437 00438 @param loadsave load or save region? 00439 """ 00440 wx.Dialog.__init__(self, parent, id, title, **kwargs) 00441 00442 self.loadsave = loadsave 00443 self.wind = '' 00444 00445 sizer = wx.BoxSizer(wx.VERTICAL) 00446 00447 box = wx.BoxSizer(wx.HORIZONTAL) 00448 label = wx.StaticText(parent=self, id=wx.ID_ANY) 00449 box.Add(item=label, proportion=0, flag=wx.ALIGN_CENTRE | wx.ALL, border=5) 00450 if loadsave == 'load': 00451 label.SetLabel(_("Load region:")) 00452 selection = gselect.Select(parent=self, id=wx.ID_ANY, size=globalvar.DIALOG_GSELECT_SIZE, 00453 type='windows') 00454 elif loadsave == 'save': 00455 label.SetLabel(_("Save region:")) 00456 selection = gselect.Select(parent=self, id=wx.ID_ANY, size=globalvar.DIALOG_GSELECT_SIZE, 00457 type='windows', mapsets = [grass.gisenv()['MAPSET']]) 00458 00459 box.Add(item=selection, proportion=0, flag=wx.ALIGN_CENTRE | wx.ALL, border=5) 00460 selection.SetFocus() 00461 selection.Bind(wx.EVT_TEXT, self.OnRegion) 00462 00463 sizer.Add(item=box, proportion=0, flag=wx.GROW|wx.ALIGN_CENTER_VERTICAL|wx.ALL, 00464 border=5) 00465 00466 line = wx.StaticLine(parent=self, id=wx.ID_ANY, size=(20, -1), style=wx.LI_HORIZONTAL) 00467 sizer.Add(item=line, proportion=0, 00468 flag=wx.GROW|wx.ALIGN_CENTER_VERTICAL|wx.LEFT|wx.RIGHT, border=5) 00469 00470 btnsizer = wx.StdDialogButtonSizer() 00471 00472 btn = wx.Button(parent = self, id = wx.ID_OK) 00473 btn.SetDefault() 00474 btnsizer.AddButton(btn) 00475 00476 btn = wx.Button(parent = self, id = wx.ID_CANCEL) 00477 btnsizer.AddButton(btn) 00478 btnsizer.Realize() 00479 00480 sizer.Add(item=btnsizer, proportion=0, flag=wx.ALIGN_RIGHT | wx.ALL, border=5) 00481 00482 self.SetSizer(sizer) 00483 sizer.Fit(self) 00484 self.Layout() 00485 00486 def OnRegion(self, event): 00487 self.wind = event.GetString() 00488 00489 class DecorationDialog(wx.Dialog): 00490 """ 00491 Controls setting options and displaying/hiding map overlay decorations 00492 """ 00493 def __init__(self, parent, ovlId, title, cmd, name=None, 00494 pos=wx.DefaultPosition, size=wx.DefaultSize, style=wx.DEFAULT_DIALOG_STYLE, 00495 checktxt='', ctrltxt=''): 00496 00497 wx.Dialog.__init__(self, parent, wx.ID_ANY, title, pos, size, style) 00498 00499 self.ovlId = ovlId # PseudoDC id 00500 self.cmd = cmd 00501 self.name = name # overlay name 00502 self.parent = parent # MapFrame 00503 00504 sizer = wx.BoxSizer(wx.VERTICAL) 00505 00506 box = wx.BoxSizer(wx.HORIZONTAL) 00507 self.chkbox = wx.CheckBox(parent=self, id=wx.ID_ANY, label=checktxt) 00508 if self.parent.Map.GetOverlay(self.ovlId) is None: 00509 self.chkbox.SetValue(True) 00510 else: 00511 self.chkbox.SetValue(self.parent.MapWindow.overlays[self.ovlId]['layer'].IsActive()) 00512 box.Add(item=self.chkbox, proportion=0, 00513 flag=wx.ALIGN_CENTRE|wx.ALL, border=5) 00514 sizer.Add(item=box, proportion=0, 00515 flag=wx.GROW|wx.ALIGN_CENTER_VERTICAL|wx.ALL, border=5) 00516 00517 box = wx.BoxSizer(wx.HORIZONTAL) 00518 optnbtn = wx.Button(parent=self, id=wx.ID_ANY, label=_("Set options")) 00519 box.Add(item=optnbtn, proportion=0, flag=wx.ALIGN_CENTRE|wx.ALL, border=5) 00520 sizer.Add(item=box, proportion=0, 00521 flag=wx.GROW|wx.ALIGN_CENTER_VERTICAL|wx.ALL, border=5) 00522 00523 box = wx.BoxSizer(wx.HORIZONTAL) 00524 label = wx.StaticText(parent=self, id=wx.ID_ANY, 00525 label=_("Drag %s with mouse in pointer mode to position.\n" 00526 "Double-click to change options." % ctrltxt)) 00527 if self.name == 'legend': 00528 label.SetLabel(label.GetLabel() + _('\nDefine raster map name for legend in ' 00529 'properties dialog.')) 00530 box.Add(item=label, proportion=0, 00531 flag=wx.ALIGN_CENTRE|wx.ALL, border=5) 00532 sizer.Add(item=box, proportion=0, 00533 flag=wx.GROW|wx.ALIGN_CENTER_VERTICAL|wx.ALL, border=5) 00534 00535 line = wx.StaticLine(parent=self, id=wx.ID_ANY, size=(20,-1), style=wx.LI_HORIZONTAL) 00536 sizer.Add(item=line, proportion=0, 00537 flag=wx.GROW|wx.ALIGN_CENTER_VERTICAL|wx.ALL, border=5) 00538 00539 # buttons 00540 btnsizer = wx.StdDialogButtonSizer() 00541 00542 self.btnOK = wx.Button(parent=self, id=wx.ID_OK) 00543 self.btnOK.SetDefault() 00544 if self.name == 'legend': 00545 self.btnOK.Enable(False) 00546 btnsizer.AddButton(self.btnOK) 00547 00548 btnCancel = wx.Button(parent=self, id=wx.ID_CANCEL) 00549 btnsizer.AddButton(btnCancel) 00550 btnsizer.Realize() 00551 00552 sizer.Add(item=btnsizer, proportion=0, 00553 flag=wx.EXPAND | wx.ALIGN_CENTER_VERTICAL | wx.ALL, border=5) 00554 00555 # 00556 # bindings 00557 # 00558 self.Bind(wx.EVT_BUTTON, self.OnOptions, optnbtn) 00559 self.Bind(wx.EVT_BUTTON, self.OnCancel, btnCancel) 00560 self.Bind(wx.EVT_BUTTON, self.OnOK, self.btnOK) 00561 00562 self.SetSizer(sizer) 00563 sizer.Fit(self) 00564 00565 # create overlay if doesn't exist 00566 self._CreateOverlay() 00567 00568 if len(self.parent.MapWindow.overlays[self.ovlId]['cmd']) > 1: 00569 mapName, found = utils.GetLayerNameFromCmd(self.parent.MapWindow.overlays[self.ovlId]['cmd']) 00570 if self.parent.MapWindow.overlays[self.ovlId]['propwin'] is None and mapName: 00571 # build properties dialog 00572 menuform.GUI(parent = self.parent, show = False).ParseCommand(cmd=self.cmd, 00573 completed=(self.GetOptData, self.name, '')) 00574 00575 if found: 00576 # enable 'OK' button 00577 self.btnOK.Enable() 00578 if name == 'legend': 00579 # set title 00580 self.SetTitle(_('Legend of raster map <%s>') % \ 00581 mapName) 00582 00583 def _CreateOverlay(self): 00584 if not self.parent.Map.GetOverlay(self.ovlId): 00585 overlay = self.parent.Map.AddOverlay(id=self.ovlId, type=self.name, 00586 command=self.cmd, 00587 l_active=False, l_render=False, l_hidden=True) 00588 00589 self.parent.MapWindow.overlays[self.ovlId] = {} 00590 self.parent.MapWindow.overlays[self.ovlId] = { 'layer' : overlay, 00591 'params' : None, 00592 'propwin' : None, 00593 'cmd' : self.cmd, 00594 'coords': (10, 10), 00595 'pdcType': 'image' } 00596 else: 00597 if self.parent.MapWindow.overlays[self.ovlId]['propwin'] == None: 00598 return 00599 00600 self.parent.MapWindow.overlays[self.ovlId]['propwin'].get_dcmd = self.GetOptData 00601 00602 00603 def OnOptions(self, event): 00604 """ self.SetSizer(sizer) 00605 sizer.Fit(self) 00606 00607 Sets option for decoration map overlays 00608 """ 00609 if self.parent.MapWindow.overlays[self.ovlId]['propwin'] is None: 00610 # build properties dialog 00611 menuform.GUI(parent = self.parent).ParseCommand(cmd=self.cmd, 00612 completed=(self.GetOptData, self.name, '')) 00613 00614 else: 00615 if self.parent.MapWindow.overlays[self.ovlId]['propwin'].IsShown(): 00616 self.parent.MapWindow.overlays[self.ovlId]['propwin'].SetFocus() 00617 else: 00618 self.parent.MapWindow.overlays[self.ovlId]['propwin'].Show() 00619 00620 def OnCancel(self, event): 00621 """!Cancel dialog""" 00622 self.parent.dialogs['barscale'] = None 00623 00624 self.Destroy() 00625 00626 def OnOK(self, event): 00627 """!Button 'OK' pressed""" 00628 # enable or disable overlay 00629 self.parent.Map.GetOverlay(self.ovlId).SetActive(self.chkbox.IsChecked()) 00630 00631 # update map 00632 self.parent.MapWindow.UpdateMap() 00633 00634 # close dialog 00635 self.OnCancel(None) 00636 00637 def GetOptData(self, dcmd, layer, params, propwin): 00638 """!Process decoration layer data""" 00639 # update layer data 00640 if params: 00641 self.parent.MapWindow.overlays[self.ovlId]['params'] = params 00642 if dcmd: 00643 self.parent.MapWindow.overlays[self.ovlId]['cmd'] = dcmd 00644 self.parent.MapWindow.overlays[self.ovlId]['propwin'] = propwin 00645 00646 # change parameters for item in layers list in render.Map 00647 # "Use mouse..." (-m) flag causes GUI freeze and is pointless here, trac #119 00648 00649 try: 00650 self.parent.MapWindow.overlays[self.ovlId]['cmd'].remove('-m') 00651 except ValueError: 00652 pass 00653 00654 self.parent.Map.ChangeOverlay(id=self.ovlId, type=self.name, 00655 command=self.parent.MapWindow.overlays[self.ovlId]['cmd'], 00656 l_active=self.parent.MapWindow.overlays[self.ovlId]['layer'].IsActive(), 00657 l_render=False, l_hidden=True) 00658 if self.name == 'legend': 00659 if params and not self.btnOK.IsEnabled(): 00660 self.btnOK.Enable() 00661 00662 class TextLayerDialog(wx.Dialog): 00663 """ 00664 Controls setting options and displaying/hiding map overlay decorations 00665 """ 00666 00667 def __init__(self, parent, ovlId, title, name='text', 00668 pos=wx.DefaultPosition, size=wx.DefaultSize, style=wx.DEFAULT_DIALOG_STYLE): 00669 00670 wx.Dialog.__init__(self, parent, wx.ID_ANY, title, pos, size, style) 00671 from wx.lib.expando import ExpandoTextCtrl, EVT_ETC_LAYOUT_NEEDED 00672 00673 self.ovlId = ovlId 00674 self.parent = parent 00675 00676 if self.ovlId in self.parent.MapWindow.textdict.keys(): 00677 self.currText = self.parent.MapWindow.textdict[self.ovlId]['text'] 00678 self.currFont = self.parent.MapWindow.textdict[self.ovlId]['font'] 00679 self.currClr = self.parent.MapWindow.textdict[self.ovlId]['color'] 00680 self.currRot = self.parent.MapWindow.textdict[self.ovlId]['rotation'] 00681 self.currCoords = self.parent.MapWindow.textdict[self.ovlId]['coords'] 00682 else: 00683 self.currClr = wx.BLACK 00684 self.currText = '' 00685 self.currFont = self.GetFont() 00686 self.currRot = 0.0 00687 self.currCoords = [10, 10, 10, 10] 00688 00689 self.sizer = wx.BoxSizer(wx.VERTICAL) 00690 box = wx.GridBagSizer(vgap=5, hgap=5) 00691 00692 # show/hide 00693 self.chkbox = wx.CheckBox(parent=self, id=wx.ID_ANY, \ 00694 label = _('Show text object')) 00695 if self.parent.Map.GetOverlay(self.ovlId) is None: 00696 self.chkbox.SetValue(True) 00697 else: 00698 self.chkbox.SetValue(self.parent.MapWindow.overlays[self.ovlId]['layer'].IsActive()) 00699 box.Add(item=self.chkbox, span=(1,2), 00700 flag=wx.ALIGN_LEFT|wx.ALL, border=5, 00701 pos=(0, 0)) 00702 00703 # text entry 00704 label = wx.StaticText(parent=self, id=wx.ID_ANY, label=_("Enter text:")) 00705 box.Add(item=label, 00706 flag=wx.ALIGN_CENTER_VERTICAL, 00707 pos=(1, 0)) 00708 00709 self.textentry = ExpandoTextCtrl(parent=self, id=wx.ID_ANY, value="", size=(300,-1)) 00710 self.textentry.SetFont(self.currFont) 00711 self.textentry.SetForegroundColour(self.currClr) 00712 self.textentry.SetValue(self.currText) 00713 # get rid of unneeded scrollbar when text box first opened 00714 self.textentry.SetClientSize((300,-1)) 00715 00716 box.Add(item=self.textentry, 00717 pos=(1, 1)) 00718 00719 # rotation 00720 label = wx.StaticText(parent=self, id=wx.ID_ANY, label=_("Rotation:")) 00721 box.Add(item=label, 00722 flag=wx.ALIGN_CENTER_VERTICAL, 00723 pos=(2, 0)) 00724 self.rotation = wx.SpinCtrl(parent=self, id=wx.ID_ANY, value="", pos=(30, 50), 00725 size=(75,-1), style=wx.SP_ARROW_KEYS) 00726 self.rotation.SetRange(-360, 360) 00727 self.rotation.SetValue(int(self.currRot)) 00728 box.Add(item=self.rotation, 00729 flag=wx.ALIGN_RIGHT, 00730 pos=(2, 1)) 00731 00732 # font 00733 fontbtn = wx.Button(parent=self, id=wx.ID_ANY, label=_("Set font")) 00734 box.Add(item=fontbtn, 00735 flag=wx.ALIGN_RIGHT, 00736 pos=(3, 1)) 00737 00738 self.sizer.Add(item=box, proportion=1, 00739 flag=wx.ALL, border=10) 00740 00741 # note 00742 box = wx.BoxSizer(wx.HORIZONTAL) 00743 label = wx.StaticText(parent=self, id=wx.ID_ANY, 00744 label=_("Drag text with mouse in pointer mode " 00745 "to position.\nDouble-click to change options")) 00746 box.Add(item=label, proportion=0, 00747 flag=wx.ALIGN_CENTRE | wx.ALL, border=5) 00748 self.sizer.Add(item=box, proportion=0, 00749 flag=wx.EXPAND | wx.ALIGN_CENTER_VERTICAL | wx.ALIGN_CENTER | wx.ALL, border=5) 00750 00751 line = wx.StaticLine(parent=self, id=wx.ID_ANY, 00752 size=(20,-1), style=wx.LI_HORIZONTAL) 00753 self.sizer.Add(item=line, proportion=0, 00754 flag=wx.EXPAND | wx.ALIGN_CENTRE | wx.ALL, border=5) 00755 00756 btnsizer = wx.StdDialogButtonSizer() 00757 00758 btn = wx.Button(parent=self, id=wx.ID_OK) 00759 btn.SetDefault() 00760 btnsizer.AddButton(btn) 00761 00762 btn = wx.Button(parent=self, id=wx.ID_CANCEL) 00763 btnsizer.AddButton(btn) 00764 btnsizer.Realize() 00765 00766 self.sizer.Add(item=btnsizer, proportion=0, 00767 flag=wx.EXPAND | wx.ALL | wx.ALIGN_CENTER, border=5) 00768 00769 self.SetSizer(self.sizer) 00770 self.sizer.Fit(self) 00771 00772 # bindings 00773 self.Bind(EVT_ETC_LAYOUT_NEEDED, self.OnRefit, self.textentry) 00774 self.Bind(wx.EVT_BUTTON, self.OnSelectFont, fontbtn) 00775 self.Bind(wx.EVT_TEXT, self.OnText, self.textentry) 00776 self.Bind(wx.EVT_SPINCTRL, self.OnRotation, self.rotation) 00777 00778 def OnRefit(self, event): 00779 """!Resize text entry to match text""" 00780 self.sizer.Fit(self) 00781 00782 def OnText(self, event): 00783 """!Change text string""" 00784 self.currText = event.GetString() 00785 00786 def OnRotation(self, event): 00787 """!Change rotation""" 00788 self.currRot = event.GetInt() 00789 00790 event.Skip() 00791 00792 def OnSelectFont(self, event): 00793 """!Change font""" 00794 data = wx.FontData() 00795 data.EnableEffects(True) 00796 data.SetColour(self.currClr) # set colour 00797 data.SetInitialFont(self.currFont) 00798 00799 dlg = wx.FontDialog(self, data) 00800 00801 if dlg.ShowModal() == wx.ID_OK: 00802 data = dlg.GetFontData() 00803 self.currFont = data.GetChosenFont() 00804 self.currClr = data.GetColour() 00805 00806 self.textentry.SetFont(self.currFont) 00807 self.textentry.SetForegroundColour(self.currClr) 00808 00809 self.Layout() 00810 00811 dlg.Destroy() 00812 00813 def GetValues(self): 00814 """!Get text properties""" 00815 return { 'text' : self.currText, 00816 'font' : self.currFont, 00817 'color' : self.currClr, 00818 'rotation' : self.currRot, 00819 'coords' : self.currCoords, 00820 'active' : self.chkbox.IsChecked() } 00821 00822 class AddMapLayersDialog(wx.Dialog): 00823 """!Add selected map layers (raster, vector) into layer tree""" 00824 def __init__(self, parent, title, style=wx.DEFAULT_DIALOG_STYLE | wx.RESIZE_BORDER): 00825 wx.Dialog.__init__(self, parent=parent, id=wx.ID_ANY, title=title, style=style) 00826 00827 self.parent = parent # GMFrame 00828 00829 # 00830 # dialog body 00831 # 00832 self.bodySizer = self.__createDialogBody() 00833 # update list of layer to be loaded 00834 self.map_layers = [] # list of map layers (full list type/mapset) 00835 self.LoadMapLayers(self.layerType.GetStringSelection()[:4], 00836 self.mapset.GetStringSelection()) 00837 # 00838 # buttons 00839 # 00840 btnCancel = wx.Button(parent = self, id = wx.ID_CANCEL) 00841 btnOk = wx.Button(parent = self, id = wx.ID_OK, label = _("&Add")) 00842 btnOk.SetDefault() 00843 btnOk.SetToolTipString(_("Add selected map layers to current display")) 00844 00845 # 00846 # sizers & do layout 00847 # 00848 btnSizer = wx.StdDialogButtonSizer() 00849 btnSizer.AddButton(btnCancel) 00850 btnSizer.AddButton(btnOk) 00851 btnSizer.Realize() 00852 00853 mainSizer = wx.BoxSizer(wx.VERTICAL) 00854 mainSizer.Add(item=self.bodySizer, proportion=1, 00855 flag=wx.EXPAND | wx.ALL, border=5) 00856 mainSizer.Add(item=btnSizer, proportion=0, 00857 flag=wx.EXPAND | wx.ALL | wx.ALIGN_CENTER, border=5) 00858 00859 self.SetSizer(mainSizer) 00860 mainSizer.Fit(self) 00861 00862 # set dialog min size 00863 self.SetMinSize(self.GetSize()) 00864 00865 def __createDialogBody(self): 00866 bodySizer = wx.GridBagSizer(vgap=3, hgap=3) 00867 bodySizer.AddGrowableCol(1) 00868 bodySizer.AddGrowableRow(3) 00869 00870 # layer type 00871 bodySizer.Add(item=wx.StaticText(parent=self, label=_("Map layer type:")), 00872 flag=wx.ALIGN_CENTER_VERTICAL, 00873 pos=(0,0)) 00874 00875 self.layerType = wx.Choice(parent=self, id=wx.ID_ANY, 00876 choices=['raster', 'vector'], size=(100,-1)) 00877 self.layerType.SetSelection(0) 00878 bodySizer.Add(item=self.layerType, 00879 pos=(0,1)) 00880 00881 # select toggle 00882 self.toggle = wx.CheckBox(parent=self, id=wx.ID_ANY, 00883 label=_("Select toggle")) 00884 self.toggle.SetValue(True) 00885 bodySizer.Add(item=self.toggle, 00886 flag=wx.ALIGN_CENTER_VERTICAL, 00887 pos=(0,2)) 00888 00889 # mapset filter 00890 bodySizer.Add(item=wx.StaticText(parent=self, label=_("Mapset:")), 00891 flag=wx.ALIGN_CENTER_VERTICAL, 00892 pos=(1,0)) 00893 00894 self.mapset = gselect.MapsetSelect(parent = self) 00895 self.mapset.SetStringSelection(grass.gisenv()['MAPSET']) 00896 bodySizer.Add(item=self.mapset, 00897 pos=(1,1), span=(1, 2)) 00898 00899 # map name filter 00900 bodySizer.Add(item=wx.StaticText(parent=self, label=_("Filter:")), 00901 flag=wx.ALIGN_CENTER_VERTICAL, 00902 pos=(2,0)) 00903 00904 self.filter = wx.TextCtrl(parent=self, id=wx.ID_ANY, 00905 value="", 00906 size=(250,-1)) 00907 bodySizer.Add(item=self.filter, 00908 flag=wx.EXPAND, 00909 pos=(2,1), span=(1, 2)) 00910 00911 # layer list 00912 bodySizer.Add(item=wx.StaticText(parent=self, label=_("List of maps:")), 00913 flag=wx.ALIGN_CENTER_VERTICAL | wx.ALIGN_TOP, 00914 pos=(3,0)) 00915 self.layers = wx.CheckListBox(parent=self, id=wx.ID_ANY, 00916 size=(250, 100), 00917 choices=[]) 00918 bodySizer.Add(item=self.layers, 00919 flag=wx.EXPAND, 00920 pos=(3,1), span=(1, 2)) 00921 00922 # bindings 00923 self.layerType.Bind(wx.EVT_CHOICE, self.OnChangeParams) 00924 self.mapset.Bind(wx.EVT_COMBOBOX, self.OnChangeParams) 00925 self.layers.Bind(wx.EVT_RIGHT_DOWN, self.OnMenu) 00926 self.filter.Bind(wx.EVT_TEXT, self.OnFilter) 00927 self.toggle.Bind(wx.EVT_CHECKBOX, self.OnToggle) 00928 return bodySizer 00929 00930 def LoadMapLayers(self, type, mapset): 00931 """!Load list of map layers 00932 00933 @param type layer type ('raster' or 'vector') 00934 @param mapset mapset name 00935 """ 00936 self.map_layers = grass.mlist_grouped(type = type)[mapset] 00937 self.layers.Set(self.map_layers) 00938 00939 # check all items by default 00940 for item in range(self.layers.GetCount()): 00941 self.layers.Check(item) 00942 00943 def OnChangeParams(self, event): 00944 """!Filter parameters changed by user""" 00945 # update list of layer to be loaded 00946 self.LoadMapLayers(self.layerType.GetStringSelection()[:4], 00947 self.mapset.GetStringSelection()) 00948 00949 event.Skip() 00950 00951 def OnMenu(self, event): 00952 """!Table description area, context menu""" 00953 if not hasattr(self, "popupID1"): 00954 self.popupDataID1 = wx.NewId() 00955 self.popupDataID2 = wx.NewId() 00956 self.popupDataID3 = wx.NewId() 00957 00958 self.Bind(wx.EVT_MENU, self.OnSelectAll, id=self.popupDataID1) 00959 self.Bind(wx.EVT_MENU, self.OnSelectInvert, id=self.popupDataID2) 00960 self.Bind(wx.EVT_MENU, self.OnDeselectAll, id=self.popupDataID3) 00961 00962 # generate popup-menu 00963 menu = wx.Menu() 00964 menu.Append(self.popupDataID1, _("Select all")) 00965 menu.Append(self.popupDataID2, _("Invert selection")) 00966 menu.Append(self.popupDataID3, _("Deselect all")) 00967 00968 self.PopupMenu(menu) 00969 menu.Destroy() 00970 00971 def OnSelectAll(self, event): 00972 """!Select all map layer from list""" 00973 for item in range(self.layers.GetCount()): 00974 self.layers.Check(item, True) 00975 00976 def OnSelectInvert(self, event): 00977 """!Invert current selection""" 00978 for item in range(self.layers.GetCount()): 00979 if self.layers.IsChecked(item): 00980 self.layers.Check(item, False) 00981 else: 00982 self.layers.Check(item, True) 00983 00984 def OnDeselectAll(self, event): 00985 """!Select all map layer from list""" 00986 for item in range(self.layers.GetCount()): 00987 self.layers.Check(item, False) 00988 00989 def OnFilter(self, event): 00990 """!Apply filter for map names""" 00991 if len(event.GetString()) == 0: 00992 self.layers.Set(self.map_layers) 00993 return 00994 00995 list = [] 00996 for layer in self.map_layers: 00997 try: 00998 if re.compile('^' + event.GetString()).search(layer): 00999 list.append(layer) 01000 except: 01001 pass 01002 01003 self.layers.Set(list) 01004 self.OnSelectAll(None) 01005 01006 event.Skip() 01007 01008 def OnToggle(self, event): 01009 """!Select toggle (check or uncheck all layers)""" 01010 check = event.Checked() 01011 for item in range(self.layers.GetCount()): 01012 self.layers.Check(item, check) 01013 01014 event.Skip() 01015 01016 def GetMapLayers(self): 01017 """!Return list of checked map layers""" 01018 layerNames = [] 01019 for indx in self.layers.GetSelections(): 01020 # layers.append(self.layers.GetStringSelec(indx)) 01021 pass 01022 01023 # return fully qualified map names 01024 mapset = self.mapset.GetStringSelection() 01025 for item in range(self.layers.GetCount()): 01026 if not self.layers.IsChecked(item): 01027 continue 01028 layerNames.append(self.layers.GetString(item) + '@' + mapset) 01029 01030 return layerNames 01031 01032 def GetLayerType(self): 01033 """!Get selected layer type""" 01034 return self.layerType.GetStringSelection() 01035 01036 class ImportDialog(wx.Dialog): 01037 """!Dialog for bulk import of various data (base class)""" 01038 def __init__(self, parent, itype, 01039 id = wx.ID_ANY, title = _("Multiple import"), 01040 style = wx.DEFAULT_DIALOG_STYLE | wx.RESIZE_BORDER): 01041 self.parent = parent # GMFrame 01042 self.importType = itype 01043 self.options = dict() # list of options 01044 01045 self.commandId = -1 # id of running command 01046 01047 wx.Dialog.__init__(self, parent, id, title, style=style, 01048 name = "MultiImportDialog") 01049 01050 self.panel = wx.Panel(parent=self, id=wx.ID_ANY) 01051 01052 self.layerBox = wx.StaticBox(parent=self.panel, id=wx.ID_ANY, 01053 label=_(" List of %s layers ") % self.importType.upper()) 01054 01055 # 01056 # list of layers 01057 # 01058 self.list = LayersList(self.panel) 01059 self.list.LoadData() 01060 01061 self.optionBox = wx.StaticBox(parent=self.panel, id=wx.ID_ANY, 01062 label="%s" % _("Options")) 01063 01064 cmd = self._getCommand() 01065 task = gtask.parse_interface(cmd) 01066 for f in task.get_options()['flags']: 01067 name = f.get('name', '') 01068 desc = f.get('label', '') 01069 if not desc: 01070 desc = f.get('description', '') 01071 if not name and not desc: 01072 continue 01073 if cmd == 'r.in.gdal' and name not in ('o', 'e', 'l', 'k'): 01074 continue 01075 elif cmd == 'r.external' and name not in ('o', 'e', 'r', 'h', 'v'): 01076 continue 01077 elif cmd == 'v.in.ogr' and name not in ('c', 'z', 't', 'o', 'r', 'e', 'w'): 01078 continue 01079 elif cmd == 'v.external' and name not in ('b'): 01080 continue 01081 elif cmd == 'v.in.dxf' and name not in ('e', 't', 'b', 'f', 'i'): 01082 continue 01083 self.options[name] = wx.CheckBox(parent = self.panel, id = wx.ID_ANY, 01084 label = desc) 01085 01086 01087 self.overwrite = wx.CheckBox(parent=self.panel, id=wx.ID_ANY, 01088 label=_("Allow output files to overwrite existing files")) 01089 self.overwrite.SetValue(UserSettings.Get(group='cmd', key='overwrite', subkey='enabled')) 01090 01091 self.add = wx.CheckBox(parent=self.panel, id=wx.ID_ANY) 01092 01093 # 01094 # buttons 01095 # 01096 # cancel 01097 self.btn_cancel = wx.Button(parent=self.panel, id=wx.ID_CANCEL) 01098 self.btn_cancel.SetToolTipString(_("Close dialog")) 01099 self.btn_cancel.Bind(wx.EVT_BUTTON, self.OnCancel) 01100 # run 01101 self.btn_run = wx.Button(parent=self.panel, id=wx.ID_OK, label = _("&Import")) 01102 self.btn_run.SetToolTipString(_("Import selected layers")) 01103 self.btn_run.SetDefault() 01104 self.btn_run.Enable(False) 01105 self.btn_run.Bind(wx.EVT_BUTTON, self.OnRun) 01106 # run command dialog 01107 self.btn_cmd = wx.Button(parent = self.panel, id = wx.ID_ANY, 01108 label = _("Command dialog")) 01109 self.btn_cmd.Bind(wx.EVT_BUTTON, self.OnCmdDialog) 01110 01111 def doLayout(self): 01112 """!Do layout""" 01113 dialogSizer = wx.BoxSizer(wx.VERTICAL) 01114 01115 # dsn input 01116 dialogSizer.Add(item = self.dsnInput, proportion = 0, 01117 flag = wx.EXPAND) 01118 01119 # 01120 # list of DXF layers 01121 # 01122 layerSizer = wx.StaticBoxSizer(self.layerBox, wx.HORIZONTAL) 01123 01124 layerSizer.Add(item=self.list, proportion=1, 01125 flag=wx.ALL | wx.EXPAND, border=5) 01126 01127 dialogSizer.Add(item=layerSizer, proportion=1, 01128 flag=wx.LEFT | wx.RIGHT | wx.BOTTOM | wx.EXPAND, border=5) 01129 01130 # options 01131 optionSizer = wx.StaticBoxSizer(self.optionBox, wx.VERTICAL) 01132 for key in self.options.keys(): 01133 optionSizer.Add(item=self.options[key], proportion=0) 01134 01135 dialogSizer.Add(item=optionSizer, proportion=0, 01136 flag=wx.LEFT | wx.RIGHT | wx.BOTTOM | wx.EXPAND, border=5) 01137 01138 dialogSizer.Add(item=self.overwrite, proportion=0, 01139 flag=wx.LEFT | wx.RIGHT | wx.BOTTOM, border=5) 01140 01141 dialogSizer.Add(item=self.add, proportion=0, 01142 flag=wx.LEFT | wx.RIGHT | wx.BOTTOM, border=5) 01143 01144 # 01145 # buttons 01146 # 01147 btnsizer = wx.BoxSizer(orient=wx.HORIZONTAL) 01148 01149 btnsizer.Add(item=self.btn_cmd, proportion=0, 01150 flag=wx.ALL | wx.ALIGN_CENTER, 01151 border=10) 01152 01153 btnsizer.Add(item=self.btn_run, proportion=0, 01154 flag=wx.ALL | wx.ALIGN_CENTER, 01155 border=10) 01156 01157 btnsizer.Add(item=self.btn_cancel, proportion=0, 01158 flag=wx.ALL | wx.ALIGN_CENTER, 01159 border=10) 01160 01161 dialogSizer.Add(item=btnsizer, proportion=0, 01162 flag=wx.ALIGN_CENTER) 01163 01164 # dialogSizer.SetSizeHints(self.panel) 01165 self.panel.SetAutoLayout(True) 01166 self.panel.SetSizer(dialogSizer) 01167 dialogSizer.Fit(self.panel) 01168 01169 # auto-layout seems not work here - FIXME 01170 size = wx.Size(globalvar.DIALOG_GSELECT_SIZE[0] + 225, 550) 01171 self.SetMinSize(size) 01172 self.SetSize((size.width, size.height + 100)) 01173 width = self.GetSize()[0] 01174 self.list.SetColumnWidth(col=1, width=width/2 - 50) 01175 self.Layout() 01176 01177 def _getCommand(self): 01178 """!Get command""" 01179 return '' 01180 01181 def OnCancel(self, event=None): 01182 """!Close dialog""" 01183 self.Close() 01184 01185 def OnRun(self, event): 01186 """!Import/Link data (each layes as separate vector map)""" 01187 pass 01188 01189 def OnCmdDialog(self, event): 01190 """!Show command dialog""" 01191 pass 01192 01193 def AddLayers(self, returncode, cmd = None): 01194 """!Add imported/linked layers into layer tree""" 01195 if not self.add.IsChecked() or returncode != 0: 01196 return 01197 01198 self.commandId += 1 01199 maptree = self.parent.curr_page.maptree 01200 layer, output = self.list.GetLayers()[self.commandId] 01201 01202 if '@' not in output: 01203 name = output + '@' + grass.gisenv()['MAPSET'] 01204 else: 01205 name = output 01206 01207 # add imported layers into layer tree 01208 if self.importType == 'gdal': 01209 cmd = ['d.rast', 01210 'map=%s' % name] 01211 if UserSettings.Get(group='cmd', key='rasterOverlay', subkey='enabled'): 01212 cmd.append('-o') 01213 01214 item = maptree.AddLayer(ltype = 'raster', 01215 lname = name, lchecked = False, 01216 lcmd = cmd) 01217 else: 01218 item = maptree.AddLayer(ltype = 'vector', 01219 lname = name, lchecked = False, 01220 lcmd = ['d.vect', 01221 'map=%s' % name]) 01222 01223 maptree.mapdisplay.MapWindow.ZoomToMap() 01224 01225 def OnAbort(self, event): 01226 """!Abort running import 01227 01228 @todo not yet implemented 01229 """ 01230 pass 01231 01232 class GdalImportDialog(ImportDialog): 01233 """!Dialog for bulk import of various raster/vector data""" 01234 def __init__(self, parent, ogr = False, link = False): 01235 self.link = link 01236 self.ogr = ogr 01237 01238 if ogr: 01239 ImportDialog.__init__(self, parent, itype = 'ogr') 01240 if link: 01241 self.SetTitle(_("Link external vector data")) 01242 else: 01243 self.SetTitle(_("Import vector data")) 01244 else: 01245 ImportDialog.__init__(self, parent, itype = 'gdal') 01246 if link: 01247 self.SetTitle(_("Link external raster data")) 01248 else: 01249 self.SetTitle(_("Import raster data")) 01250 01251 self.dsnInput = gselect.GdalSelect(parent = self, panel = self.panel, ogr = ogr) 01252 01253 if link: 01254 self.add.SetLabel(_("Add linked layers into layer tree")) 01255 else: 01256 self.add.SetLabel(_("Add imported layers into layer tree")) 01257 01258 self.add.SetValue(UserSettings.Get(group='cmd', key='addNewLayer', subkey='enabled')) 01259 01260 if link: 01261 self.btn_run.SetLabel(_("&Link")) 01262 self.btn_run.SetToolTipString(_("Link selected layers")) 01263 if ogr: 01264 self.btn_cmd.SetToolTipString(_('Open %s dialog') % 'v.external') 01265 else: 01266 self.btn_cmd.SetToolTipString(_('Open %s dialog') % 'r.external') 01267 else: 01268 self.btn_run.SetLabel(_("&Import")) 01269 self.btn_run.SetToolTipString(_("Import selected layers")) 01270 if ogr: 01271 self.btn_cmd.SetToolTipString(_('Open %s dialog') % 'v.in.ogr') 01272 else: 01273 self.btn_cmd.SetToolTipString(_('Open %s dialog') % 'r.in.gdal') 01274 01275 self.doLayout() 01276 01277 def OnRun(self, event): 01278 """!Import/Link data (each layes as separate vector map)""" 01279 self.commandId = -1 01280 data = self.list.GetLayers() 01281 if not data: 01282 gcmd.GMessage(parent = self, 01283 message = _("No layers marked for import.\nOperation canceled.")) 01284 return 01285 01286 dsn = self.dsnInput.GetDsn() 01287 ext = self.dsnInput.GetFormatExt() 01288 01289 for layer, output in data: 01290 if self.importType == 'ogr': 01291 if ext and layer.rfind(ext) > -1: 01292 layer = layer.replace('.' + ext, '') 01293 if self.link: 01294 cmd = ['v.external', 01295 'dsn=%s' % dsn, 01296 'output=%s' % output, 01297 'layer=%s' % layer] 01298 else: 01299 cmd = ['v.in.ogr', 01300 'dsn=%s' % dsn, 01301 'layer=%s' % layer, 01302 'output=%s' % output] 01303 else: # gdal 01304 if self.dsnInput.GetType() == 'dir': 01305 idsn = os.path.join(dsn, layer) 01306 else: 01307 idsn = dsn 01308 01309 if self.link: 01310 cmd = ['r.external', 01311 'input=%s' % idsn, 01312 'output=%s' % output] 01313 else: 01314 cmd = ['r.in.gdal', 01315 'input=%s' % idsn, 01316 'output=%s' % output] 01317 01318 if self.overwrite.IsChecked(): 01319 cmd.append('--overwrite') 01320 01321 for key in self.options.keys(): 01322 if self.options[key].IsChecked(): 01323 cmd.append('-%s' % key) 01324 01325 if UserSettings.Get(group='cmd', key='overwrite', subkey='enabled'): 01326 cmd.append('--overwrite') 01327 01328 # run in Layer Manager 01329 self.parent.goutput.RunCmd(cmd, switchPage = True, 01330 onDone = self.AddLayers) 01331 01332 def _getCommand(self): 01333 """!Get command""" 01334 if self.link: 01335 if self.ogr: 01336 return 'v.external' 01337 else: 01338 return 'r.external' 01339 else: 01340 if self.ogr: 01341 return 'v.in.ogr' 01342 else: 01343 return 'r.in.gdal' 01344 01345 return '' 01346 01347 def OnCmdDialog(self, event): 01348 """!Show command dialog""" 01349 name = self._getCommand() 01350 menuform.GUI(parent = self, modal = True).ParseCommand(cmd = [name]) 01351 01352 class DxfImportDialog(ImportDialog): 01353 """!Dialog for bulk import of DXF layers""" 01354 def __init__(self, parent): 01355 ImportDialog.__init__(self, parent, itype = 'dxf', 01356 title = _("Import DXF layers")) 01357 01358 self.dsnInput = filebrowse.FileBrowseButton(parent=self.panel, id=wx.ID_ANY, 01359 size=globalvar.DIALOG_GSELECT_SIZE, labelText='', 01360 dialogTitle=_('Choose DXF file to import'), 01361 buttonText=_('Browse'), 01362 startDirectory=os.getcwd(), fileMode=0, 01363 changeCallback=self.OnSetDsn, 01364 fileMask="DXF File (*.dxf)|*.dxf") 01365 01366 self.add.SetLabel(_("Add imported layers into layer tree")) 01367 01368 self.add.SetValue(UserSettings.Get(group='cmd', key='addNewLayer', subkey='enabled')) 01369 01370 self.doLayout() 01371 01372 def _getCommand(self): 01373 """!Get command""" 01374 return 'v.in.dxf' 01375 01376 def OnRun(self, event): 01377 """!Import/Link data (each layes as separate vector map)""" 01378 data = self.list.GetLayers() 01379 01380 # hide dialog 01381 self.Hide() 01382 01383 inputDxf = self.dsnInput.GetValue() 01384 01385 for layer, output in data: 01386 cmd = ['v.in.dxf', 01387 'input=%s' % inputDxf, 01388 'layers=%s' % layer, 01389 'output=%s' % output] 01390 01391 for key in self.options.keys(): 01392 if self.options[key].IsChecked(): 01393 cmd.append('-%s' % key) 01394 01395 if self.overwrite.IsChecked() or \ 01396 UserSettings.Get(group='cmd', key='overwrite', subkey='enabled'): 01397 cmd.append('--overwrite') 01398 01399 # run in Layer Manager 01400 self.parent.goutput.RunCmd(cmd, switchPage=True, 01401 onDone = self.AddLayers) 01402 01403 self.OnCancel() 01404 01405 def OnSetDsn(self, event): 01406 """!Input DXF file defined, update list of layer widget""" 01407 path = event.GetString() 01408 if not path: 01409 return 01410 01411 data = list() 01412 ret = gcmd.RunCommand('v.in.dxf', 01413 quiet = True, 01414 parent = self, 01415 read = True, 01416 flags = 'l', 01417 input = path) 01418 if not ret: 01419 self.list.LoadData() 01420 self.btn_run.Enable(False) 01421 return 01422 01423 for line in ret.splitlines(): 01424 layerId = line.split(':')[0].split(' ')[1] 01425 layerName = line.split(':')[1].strip() 01426 grassName = utils.GetValidLayerName(layerName) 01427 data.append((layerId, layerName.strip(), grassName.strip())) 01428 01429 self.list.LoadData(data) 01430 if len(data) > 0: 01431 self.btn_run.Enable(True) 01432 else: 01433 self.btn_run.Enable(False) 01434 01435 def OnCmdDialog(self, event): 01436 """!Show command dialog""" 01437 menuform.GUI(parent = self, modal = True).ParseCommand(cmd = ['v.in.dxf']) 01438 01439 class LayersList(wx.ListCtrl, listmix.ListCtrlAutoWidthMixin, 01440 listmix.CheckListCtrlMixin, listmix.TextEditMixin): 01441 """!List of layers to be imported (dxf, shp...)""" 01442 def __init__(self, parent, pos = wx.DefaultPosition, 01443 log = None): 01444 self.parent = parent 01445 01446 wx.ListCtrl.__init__(self, parent, wx.ID_ANY, 01447 style=wx.LC_REPORT) 01448 listmix.CheckListCtrlMixin.__init__(self) 01449 self.log = log 01450 01451 # setup mixins 01452 listmix.ListCtrlAutoWidthMixin.__init__(self) 01453 listmix.TextEditMixin.__init__(self) 01454 01455 self.InsertColumn(0, _('Layer id')) 01456 self.InsertColumn(1, _('Layer name')) 01457 self.InsertColumn(2, _('Name for GRASS map (editable)')) 01458 01459 self.Bind(wx.EVT_COMMAND_RIGHT_CLICK, self.OnPopupMenu) #wxMSW 01460 self.Bind(wx.EVT_RIGHT_UP, self.OnPopupMenu) #wxGTK 01461 01462 def LoadData(self, data=None): 01463 """!Load data into list""" 01464 if data is None: 01465 return 01466 01467 self.DeleteAllItems() 01468 01469 for id, name, grassName in data: 01470 index = self.InsertStringItem(sys.maxint, str(id)) 01471 self.SetStringItem(index, 1, "%s" % str(name)) 01472 self.SetStringItem(index, 2, "%s" % str(grassName)) 01473 01474 if len(data) == 1: 01475 self.CheckItem(0, True) 01476 01477 self.SetColumnWidth(col = 0, width = wx.LIST_AUTOSIZE_USEHEADER) 01478 01479 def OnPopupMenu(self, event): 01480 """!Show popup menu""" 01481 if self.GetItemCount() < 1: 01482 return 01483 01484 if not hasattr(self, "popupDataID1"): 01485 self.popupDataID1 = wx.NewId() 01486 self.popupDataID2 = wx.NewId() 01487 01488 self.Bind(wx.EVT_MENU, self.OnSelectAll, id=self.popupDataID1) 01489 self.Bind(wx.EVT_MENU, self.OnSelectNone, id=self.popupDataID2) 01490 01491 # generate popup-menu 01492 menu = wx.Menu() 01493 menu.Append(self.popupDataID1, _("Select all")) 01494 menu.Append(self.popupDataID2, _("Deselect all")) 01495 01496 self.PopupMenu(menu) 01497 menu.Destroy() 01498 01499 def OnSelectAll(self, event): 01500 """!Select all items""" 01501 item = -1 01502 01503 while True: 01504 item = self.GetNextItem(item) 01505 if item == -1: 01506 break 01507 self.CheckItem(item, True) 01508 01509 event.Skip() 01510 01511 def OnSelectNone(self, event): 01512 """!Deselect items""" 01513 item = -1 01514 01515 while True: 01516 item = self.GetNextItem(item, wx.LIST_STATE_SELECTED) 01517 if item == -1: 01518 break 01519 self.CheckItem(item, False) 01520 01521 event.Skip() 01522 01523 def OnLeftDown(self, event): 01524 """!Allow editing only output name 01525 01526 Code taken from TextEditMixin class. 01527 """ 01528 x, y = event.GetPosition() 01529 01530 colLocs = [0] 01531 loc = 0 01532 for n in range(self.GetColumnCount()): 01533 loc = loc + self.GetColumnWidth(n) 01534 colLocs.append(loc) 01535 01536 col = bisect(colLocs, x + self.GetScrollPos(wx.HORIZONTAL)) - 1 01537 01538 if col == 2: 01539 listmix.TextEditMixin.OnLeftDown(self, event) 01540 else: 01541 event.Skip() 01542 01543 def GetLayers(self): 01544 """!Get list of layers (layer name, output name)""" 01545 data = [] 01546 item = -1 01547 while True: 01548 item = self.GetNextItem(item) 01549 if item == -1: 01550 break 01551 if self.IsChecked(item): 01552 # layer / output name 01553 data.append((self.GetItem(item, 1).GetText(), 01554 self.GetItem(item, 2).GetText())) 01555 01556 return data 01557 01558 class SetOpacityDialog(wx.Dialog): 01559 """!Set opacity of map layers""" 01560 def __init__(self, parent, id=wx.ID_ANY, title=_("Set Map Layer Opacity"), 01561 size=wx.DefaultSize, pos=wx.DefaultPosition, 01562 style=wx.DEFAULT_DIALOG_STYLE, opacity=100): 01563 01564 self.parent = parent # GMFrame 01565 self.opacity = opacity # current opacity 01566 01567 super(SetOpacityDialog, self).__init__(parent, id=id, pos=pos, 01568 size=size, style=style, title=title) 01569 01570 panel = wx.Panel(parent=self, id=wx.ID_ANY) 01571 01572 sizer = wx.BoxSizer(wx.VERTICAL) 01573 01574 box = wx.GridBagSizer(vgap=5, hgap=5) 01575 self.value = wx.Slider(panel, id=wx.ID_ANY, value=self.opacity, 01576 style=wx.SL_HORIZONTAL | wx.SL_AUTOTICKS | \ 01577 wx.SL_TOP | wx.SL_LABELS, 01578 minValue=0, maxValue=100, 01579 size=(350, -1)) 01580 01581 box.Add(item=self.value, 01582 flag=wx.ALIGN_CENTRE, pos=(0, 0), span=(1, 2)) 01583 box.Add(item=wx.StaticText(parent=panel, id=wx.ID_ANY, 01584 label=_("transparent")), 01585 pos=(1, 0)) 01586 box.Add(item=wx.StaticText(parent=panel, id=wx.ID_ANY, 01587 label=_("opaque")), 01588 flag=wx.ALIGN_RIGHT, 01589 pos=(1, 1)) 01590 01591 sizer.Add(item=box, proportion=0, 01592 flag=wx.EXPAND | wx.ALIGN_CENTER_VERTICAL | wx.ALL, border=5) 01593 01594 line = wx.StaticLine(parent=panel, id=wx.ID_ANY, 01595 style=wx.LI_HORIZONTAL) 01596 sizer.Add(item=line, proportion=0, 01597 flag=wx.EXPAND | wx.ALIGN_CENTER_VERTICAL | wx.ALL, border=5) 01598 01599 # buttons 01600 btnsizer = wx.StdDialogButtonSizer() 01601 01602 btnOK = wx.Button(parent=panel, id=wx.ID_OK) 01603 btnOK.SetDefault() 01604 btnsizer.AddButton(btnOK) 01605 01606 btnCancel = wx.Button(parent=panel, id=wx.ID_CANCEL) 01607 btnsizer.AddButton(btnCancel) 01608 btnsizer.Realize() 01609 01610 sizer.Add(item=btnsizer, proportion=0, 01611 flag=wx.EXPAND | wx.ALIGN_CENTER_VERTICAL | wx.ALL, border=5) 01612 01613 panel.SetSizer(sizer) 01614 sizer.Fit(panel) 01615 01616 self.SetSize(self.GetBestSize()) 01617 01618 self.Layout() 01619 01620 def GetOpacity(self): 01621 """!Button 'OK' pressed""" 01622 # return opacity value 01623 opacity = float(self.value.GetValue()) / 100 01624 return opacity 01625 01626 def GetImageHandlers(image): 01627 """!Get list of supported image handlers""" 01628 lext = list() 01629 ltype = list() 01630 for h in image.GetHandlers(): 01631 lext.append(h.GetExtension()) 01632 01633 filetype = '' 01634 if 'png' in lext: 01635 filetype += "PNG file (*.png)|*.png|" 01636 ltype.append({ 'type' : wx.BITMAP_TYPE_PNG, 01637 'ext' : 'png' }) 01638 filetype += "BMP file (*.bmp)|*.bmp|" 01639 ltype.append({ 'type' : wx.BITMAP_TYPE_BMP, 01640 'ext' : 'bmp' }) 01641 if 'gif' in lext: 01642 filetype += "GIF file (*.gif)|*.gif|" 01643 ltype.append({ 'type' : wx.BITMAP_TYPE_GIF, 01644 'ext' : 'gif' }) 01645 01646 if 'jpg' in lext: 01647 filetype += "JPG file (*.jpg)|*.jpg|" 01648 ltype.append({ 'type' : wx.BITMAP_TYPE_JPEG, 01649 'ext' : 'jpg' }) 01650 01651 if 'pcx' in lext: 01652 filetype += "PCX file (*.pcx)|*.pcx|" 01653 ltype.append({ 'type' : wx.BITMAP_TYPE_PCX, 01654 'ext' : 'pcx' }) 01655 01656 if 'pnm' in lext: 01657 filetype += "PNM file (*.pnm)|*.pnm|" 01658 ltype.append({ 'type' : wx.BITMAP_TYPE_PNM, 01659 'ext' : 'pnm' }) 01660 01661 if 'tif' in lext: 01662 filetype += "TIF file (*.tif)|*.tif|" 01663 ltype.append({ 'type' : wx.BITMAP_TYPE_TIF, 01664 'ext' : 'tif' }) 01665 01666 if 'xpm' in lext: 01667 filetype += "XPM file (*.xpm)|*.xpm" 01668 ltype.append({ 'type' : wx.BITMAP_TYPE_XPM, 01669 'ext' : 'xpm' }) 01670 01671 return filetype, ltype 01672 01673 class StaticWrapText(wx.StaticText): 01674 """!A Static Text field that wraps its text to fit its width, 01675 enlarging its height if necessary. 01676 """ 01677 def __init__(self, parent, id = wx.ID_ANY, label = '', *args, **kwds): 01678 self.parent = parent 01679 self.originalLabel = label 01680 01681 wx.StaticText.__init__(self, parent, id, label = '', *args, **kwds) 01682 01683 self.SetLabel(label) 01684 self.Bind(wx.EVT_SIZE, self.OnResize) 01685 01686 def SetLabel(self, label): 01687 self.originalLabel = label 01688 self.wrappedSize = None 01689 self.OnResize(None) 01690 01691 def OnResize(self, event): 01692 if not getattr(self, "resizing", False): 01693 self.resizing = True 01694 newSize = wx.Size(self.parent.GetSize().width - 50, 01695 self.GetSize().height) 01696 if self.wrappedSize != newSize: 01697 wx.StaticText.SetLabel(self, self.originalLabel) 01698 self.Wrap(newSize.width) 01699 self.wrappedSize = newSize 01700 01701 self.SetSize(self.wrappedSize) 01702 del self.resizing 01703 01704 class ImageSizeDialog(wx.Dialog): 01705 """!Set size for saved graphic file""" 01706 def __init__(self, parent, id = wx.ID_ANY, title=_("Set image size"), 01707 style = wx.DEFAULT_DIALOG_STYLE, **kwargs): 01708 self.parent = parent 01709 01710 wx.Dialog.__init__(self, parent, id = id, style=style, title=title, **kwargs) 01711 01712 self.panel = wx.Panel(parent = self, id = wx.ID_ANY) 01713 01714 self.box = wx.StaticBox(parent = self.panel, id = wx.ID_ANY, 01715 label = ' % s' % _("Image size")) 01716 01717 size = self.parent.GetWindow().GetClientSize() 01718 self.width = wx.SpinCtrl(parent = self.panel, id = wx.ID_ANY, 01719 style = wx.SP_ARROW_KEYS) 01720 self.width.SetRange(20, 1e6) 01721 self.width.SetValue(size.width) 01722 wx.CallAfter(self.width.SetFocus) 01723 self.height = wx.SpinCtrl(parent = self.panel, id = wx.ID_ANY, 01724 style = wx.SP_ARROW_KEYS) 01725 self.height.SetRange(20, 1e6) 01726 self.height.SetValue(size.height) 01727 self.template = wx.Choice(parent = self.panel, id = wx.ID_ANY, 01728 size = (125, -1), 01729 choices = [ "", 01730 "640x480", 01731 "800x600", 01732 "1024x768", 01733 "1280x960", 01734 "1600x1200", 01735 "1920x1440" ]) 01736 01737 self.btnOK = wx.Button(parent = self.panel, id = wx.ID_OK) 01738 self.btnOK.SetDefault() 01739 self.btnCancel = wx.Button(parent = self.panel, id = wx.ID_CANCEL) 01740 01741 self.template.Bind(wx.EVT_CHOICE, self.OnTemplate) 01742 01743 self._layout() 01744 self.SetSize(self.GetBestSize()) 01745 01746 def _layout(self): 01747 """!Do layout""" 01748 sizer = wx.BoxSizer(wx.VERTICAL) 01749 01750 # body 01751 box = wx.StaticBoxSizer(self.box, wx.HORIZONTAL) 01752 fbox = wx.FlexGridSizer(cols = 2, vgap = 5, hgap = 5) 01753 fbox.Add(item = wx.StaticText(parent = self.panel, id = wx.ID_ANY, 01754 label = _("Width:")), 01755 flag = wx.ALIGN_CENTER_VERTICAL) 01756 fbox.Add(item = self.width) 01757 fbox.Add(item = wx.StaticText(parent = self.panel, id = wx.ID_ANY, 01758 label = _("Height:")), 01759 flag = wx.ALIGN_CENTER_VERTICAL) 01760 fbox.Add(item = self.height) 01761 fbox.Add(item = wx.StaticText(parent = self.panel, id = wx.ID_ANY, 01762 label = _("Template:")), 01763 flag = wx.ALIGN_CENTER_VERTICAL) 01764 fbox.Add(item = self.template) 01765 01766 box.Add(item = fbox, proportion = 1, 01767 flag = wx.EXPAND | wx.ALL, border = 5) 01768 sizer.Add(item = box, proportion = 1, 01769 flag=wx.EXPAND | wx.ALL, border = 3) 01770 01771 # buttons 01772 btnsizer = wx.StdDialogButtonSizer() 01773 btnsizer.AddButton(self.btnOK) 01774 btnsizer.AddButton(self.btnCancel) 01775 btnsizer.Realize() 01776 01777 sizer.Add(item = btnsizer, proportion = 0, 01778 flag = wx.EXPAND | wx.ALIGN_RIGHT | wx.ALL, border=5) 01779 01780 self.panel.SetSizer(sizer) 01781 sizer.Fit(self.panel) 01782 self.Layout() 01783 01784 def GetValues(self): 01785 """!Get width/height values""" 01786 return self.width.GetValue(), self.height.GetValue() 01787 01788 def OnTemplate(self, event): 01789 """!Template selected""" 01790 sel = event.GetString() 01791 if not sel: 01792 width, height = self.parent.GetWindow().GetClientSize() 01793 else: 01794 width, height = map(int, sel.split('x')) 01795 self.width.SetValue(width) 01796 self.height.SetValue(height) 01797