Changeset 66128
- Timestamp:
- Sep 6, 2015, 8:12:27 AM (9 years ago)
- Location:
- grass/trunk/gui/wxpython
- Files:
-
- 7 added
- 3 edited
- 1 moved
-
Makefile (modified) (3 diffs)
-
datacatalog (added)
-
datacatalog/Makefile (added)
-
datacatalog/__init__.py (added)
-
datacatalog/catalog.py (moved) (moved from grass/trunk/gui/wxpython/lmgr/datacatalog.py ) (5 diffs)
-
datacatalog/frame.py (added)
-
datacatalog/g.gui.datacatalog.html (added)
-
datacatalog/g.gui.datacatalog.py (added)
-
datacatalog/tree.py (added)
-
docs/wxGUI.components.html (modified) (1 diff)
-
lmgr/frame.py (modified) (1 diff)
Legend:
- Unmodified
- Added
- Removed
-
grass/trunk/gui/wxpython/Makefile
r65199 r66128 1 1 MODULE_TOPDIR = ../.. 2 2 3 SUBDIRS = docs animation mapswipe gmodeler rlisetup psmap dbmgr vdigit iclass gcp timeline tplot3 SUBDIRS = docs animation datacatalog mapswipe gmodeler rlisetup psmap dbmgr vdigit iclass gcp timeline tplot 4 4 EXTRA_CLEAN_FILES = menustrings.py build_ext.pyc xml/menudata.xml xml/module_tree_menudata.xml */*.pyc 5 5 … … 10 10 11 11 SRCFILES := $(wildcard icons/*.py scripts/*.py xml/*) \ 12 $(wildcard animation/* core/*.py d bmgr/* gcp/*.py gmodeler/* \12 $(wildcard animation/* core/*.py datacatalog/* dbmgr/* gcp/*.py gmodeler/* \ 13 13 gui_core/*.py iclass/* lmgr/*.py location_wizard/*.py mapwin/*.py mapdisp/*.py \ 14 14 mapswipe/* modules/*.py nviz/*.py psmap/* rdigit/* rlisetup/* timeline/* vdigit/* \ … … 19 19 $(patsubst %.py,$(DSTDIR)/%.pyc,$(filter %.py,$(SRCFILES))) 20 20 21 PYDSTDIRS := $(patsubst %,$(DSTDIR)/%,animation core d bmgr gcp gmodeler \21 PYDSTDIRS := $(patsubst %,$(DSTDIR)/%,animation core datacatalog dbmgr gcp gmodeler \ 22 22 gui_core iclass lmgr location_wizard mapwin mapdisp modules nviz psmap \ 23 23 mapswipe vdigit wxplot web_services rdigit rlisetup vnet timeline iscatt tplot) -
grass/trunk/gui/wxpython/datacatalog/catalog.py
r66127 r66128 1 1 """ 2 @package lmgr::datacatalog2 @package datacatalog::catalog 3 3 4 4 @brief Data catalog … … 6 6 Classes: 7 7 - datacatalog::DataCatalog 8 - datacatalog::LocationMapTree9 - datacatalog::DataCatalogTree10 11 @todo:12 - use gui_core/treeview.py13 8 14 9 (C) 2014 by Tereza Fiedlerova, and the GRASS Development Team … … 21 16 """ 22 17 23 import os 24 import sys 18 import wx 25 19 26 import wx27 import wx.gizmos as gizmos28 29 from core.gcmd import RunCommand, GError, GMessage30 from core.utils import GetListOfLocations, ListOfMapsets31 20 from core.gthread import gThread 32 21 from core.debug import Debug 33 from gui_core.dialogs import TextEntryDialog22 from datacatalog.tree import DataCatalogTree 34 23 35 24 from grass.pydispatch.signal import Signal 36 37 import grass.script as grass38 25 39 26 class DataCatalog(wx.Panel): … … 51 38 52 39 # tree with layers 53 self.tree = DataCatalogTree(self )40 self.tree = DataCatalogTree(self, giface=giface) 54 41 self.thread = gThread() 55 42 self._loaded = False … … 81 68 self._loaded = True 82 69 self.tree.ExpandCurrentLocation() 83 84 class LocationMapTree(wx.TreeCtrl):85 def __init__(self, parent, style=wx.TR_HIDE_ROOT | wx.TR_EDIT_LABELS |86 wx.TR_HAS_BUTTONS | wx.TR_FULL_ROW_HIGHLIGHT | wx.TR_COLUMN_LINES | wx.TR_SINGLE):87 """Location Map Tree constructor."""88 super(LocationMapTree, self).__init__(parent, id=wx.ID_ANY, style=style)89 self.showNotification = Signal('Tree.showNotification')90 self.parent = parent91 self.root = self.AddRoot('Catalog') # will not be displayed when we use TR_HIDE_ROOT flag92 93 self._initVariables()94 self.MakeBackup()95 96 wx.EVT_TREE_ITEM_RIGHT_CLICK(self, wx.ID_ANY, self.OnRightClick)97 98 self.Bind(wx.EVT_LEFT_DCLICK, self.OnDoubleClick)99 self.Bind(wx.EVT_KEY_DOWN, self.OnKeyDown)100 self.Bind(wx.EVT_KEY_UP, self.OnKeyUp)101 102 def _initTreeItems(self, locations = [], mapsets = []):103 """Add locations, mapsets and layers to the tree."""104 if not locations:105 locations = GetListOfLocations(self.gisdbase)106 if not mapsets:107 mapsets = ['*']108 109 first = True110 for loc in locations:111 location = loc112 if first:113 self.ChangeEnvironment(location, 'PERMANENT')114 first = False115 else:116 self.ChangeEnvironment(location)117 118 varloc = self.AppendItem(self.root, loc)119 # add all mapsets120 mapsets = ListOfMapsets()121 if mapsets:122 for mapset in mapsets:123 self.AppendItem(varloc, mapset)124 else:125 self.AppendItem(varloc, _("No mapsets readable"))126 continue127 128 # get list of all maps in location129 maplist = RunCommand('g.list', flags='mt', type='raster,raster_3d,vector', mapset=','.join(mapsets),130 quiet=True, read=True)131 maplist = maplist.splitlines()132 for ml in maplist:133 # parse134 parts1 = ml.split('/')135 parts2 = parts1[1].split('@')136 mapset = parts2[1]137 mlayer = parts2[0]138 ltype = parts1[0]139 140 # add mapset141 if self.itemExists(mapset, varloc) == False:142 varmapset = self.AppendItem(varloc, mapset)143 else:144 varmapset = self.getItemByName(mapset, varloc)145 146 # add type node if not exists147 if self.itemExists(ltype, varmapset) == False:148 vartype = self.AppendItem(varmapset, ltype)149 150 self.AppendItem(vartype, mlayer)151 152 self.RestoreBackup()153 Debug.msg(1, "Tree filled")154 155 def InitTreeItems(self):156 """Create popup menu for layers"""157 raise NotImplementedError()158 159 def _popupMenuLayer(self):160 """Create popup menu for layers"""161 raise NotImplementedError()162 163 def _popupMenuMapset(self):164 """Create popup menu for mapsets"""165 raise NotImplementedError()166 167 def _initVariables(self):168 """Init variables."""169 self.selected_layer = None170 self.selected_type = None171 self.selected_mapset = None172 self.selected_location = None173 174 self.gisdbase = grass.gisenv()['GISDBASE']175 self.ctrldown = False176 177 def GetControl(self):178 """Returns control itself."""179 return self180 181 def DefineItems(self, item0):182 """Set selected items."""183 self.selected_layer = None184 self.selected_type = None185 self.selected_mapset = None186 self.selected_location = None187 items = []188 item = item0189 while (self.GetItemParent(item)):190 items.insert(0,item)191 item = self.GetItemParent(item)192 193 self.selected_location = items[0]194 length = len(items)195 if (length > 1):196 self.selected_mapset = items[1]197 if (length > 2):198 self.selected_type = items[2]199 if (length > 3):200 self.selected_layer = items[3]201 202 def getItemByName(self, match, root):203 """Return match item from the root."""204 item, cookie = self.GetFirstChild(root)205 while item.IsOk():206 if self.GetItemText(item) == match:207 return item208 item, cookie = self.GetNextChild(root, cookie)209 return None210 211 def itemExists(self, match, root):212 """Return true if match item exists in the root item."""213 item, cookie = self.GetFirstChild(root)214 while item.IsOk():215 if self.GetItemText(item) == match:216 return True217 item, cookie = self.GetNextChild(root, cookie)218 return False219 220 def UpdateTree(self):221 """Update whole tree."""222 self.DeleteAllItems()223 self.root = self.AddRoot('Tree')224 self.AddTreeItems()225 label = "Tree updated."226 self.showNotification.emit(message=label)227 228 def OnSelChanged(self, event):229 self.selected_layer = None230 231 def OnRightClick(self, event):232 """Display popup menu."""233 self.DefineItems(event.GetItem())234 if(self.selected_layer):235 self._popupMenuLayer()236 elif(self.selected_mapset and self.selected_type==None):237 self._popupMenuMapset()238 239 def OnDoubleClick(self, event):240 """Double click"""241 Debug.msg(1, "Double CLICK")242 243 def OnKeyDown(self, event):244 """Set key event and check if control key is down"""245 keycode = event.GetKeyCode()246 if keycode == wx.WXK_CONTROL:247 self.ctrldown = True248 Debug.msg(1,"CONTROL ON")249 250 def OnKeyUp(self, event):251 """Check if control key is up"""252 keycode = event.GetKeyCode()253 if keycode == wx.WXK_CONTROL:254 self.ctrldown = False255 Debug.msg(1,"CONTROL OFF")256 257 def MakeBackup(self):258 """Make backup for case of change"""259 gisenv = grass.gisenv()260 self.glocation = gisenv['LOCATION_NAME']261 self.gmapset = gisenv['MAPSET']262 263 def RestoreBackup(self):264 """Restore backup"""265 stringl = 'LOCATION_NAME='+self.glocation266 RunCommand('g.gisenv', set=stringl)267 stringm = 'MAPSET='+self.gmapset268 RunCommand('g.gisenv', set=stringm)269 270 def ChangeEnvironment(self, location, mapset=None):271 """Change gisenv variables -> location, mapset"""272 stringl = 'LOCATION_NAME='+location273 RunCommand('g.gisenv', set=stringl)274 if mapset:275 stringm = 'MAPSET='+mapset276 RunCommand('g.gisenv', set=stringm)277 278 def ExpandCurrentLocation(self):279 """Expand current location"""280 location = grass.gisenv()['LOCATION_NAME']281 item = self.getItemByName(location, self.root)282 if item is not None:283 self.SelectItem(item)284 self.ExpandAllChildren(item)285 self.EnsureVisible(item)286 else:287 Debug.msg(1, "Location <%s> not found" % location)288 289 class DataCatalogTree(LocationMapTree):290 def __init__(self, parent):291 """Data Catalog Tree constructor."""292 super(DataCatalogTree, self).__init__(parent)293 294 self._initVariablesCatalog()295 296 wx.EVT_TREE_BEGIN_DRAG(self, wx.ID_ANY, self.OnBeginDrag)297 wx.EVT_TREE_END_DRAG(self, wx.ID_ANY, self.OnEndDrag)298 299 wx.EVT_TREE_END_LABEL_EDIT(self, wx.ID_ANY, self.OnEditLabel)300 wx.EVT_TREE_BEGIN_LABEL_EDIT(self, wx.ID_ANY, self.OnStartEditLabel)301 302 def _initVariablesCatalog(self):303 """Init variables."""304 self.copy_layer = None305 self.copy_type = None306 self.copy_mapset = None307 self.copy_location = None308 309 def InitTreeItems(self):310 """Add locations, mapsets and layers to the tree."""311 self._initTreeItems()312 313 def OnCopy(self, event):314 """Copy layer or mapset (just save it temporarily, copying is done by paste)"""315 self.copy_layer = self.selected_layer316 self.copy_type = self.selected_type317 self.copy_mapset = self.selected_mapset318 self.copy_location = self.selected_location319 label = "Layer "+self.GetItemText(self.copy_layer)+" copied to clipboard. You can paste it to selected mapset."320 self.showNotification.emit(message=label)321 322 def OnRename(self, event):323 """Rename levent with dialog"""324 if (self.selected_layer):325 self.old_name = self.GetItemText(self.selected_layer)326 self.new_name = self._getUserEntry(_('New name'), _('Rename map'), self.old_name)327 self.rename()328 329 def OnStartEditLabel(self, event):330 """Start label editing"""331 item = event.GetItem()332 self.DefineItems(item)333 Debug.msg(1, "Start label edit "+self.GetItemText(item))334 label = _("Editing") + " " + self.GetItemText(item)335 self.showNotification.emit(message=label)336 if (self.selected_layer == None):337 event.Veto()338 339 def OnEditLabel(self, event):340 """End label editing"""341 if (self.selected_layer):342 item = event.GetItem()343 self.old_name = self.GetItemText(item)344 Debug.msg(1, "End label edit "+self.old_name)345 wx.CallAfter(self.afterEdit, self, item)346 347 def afterEdit(pro, self, item):348 self.new_name = self.GetItemText(item)349 self.rename()350 351 def rename(self):352 """Rename layer"""353 if self.selected_layer and self.new_name:354 string = self.old_name+','+self.new_name355 self.ChangeEnvironment(self.GetItemText(self.selected_location), self.GetItemText(self.selected_mapset))356 renamed = 0357 label = _("Renaming") + " " + string + " ..."358 self.showNotification.emit(message=label)359 if (self.GetItemText(self.selected_type)=='vector'):360 renamed = RunCommand('g.rename', vector=string)361 elif (self.GetItemText(self.selected_type)=='raster'):362 renamed = RunCommand('g.rename', raster=string)363 else:364 renamed = RunCommand('g.rename', raster3d=string)365 if (renamed==0):366 self.SetItemText(self.selected_layer,self.new_name)367 label = "g.rename "+self.GetItemText(self.selected_type)+"="+string+" -- completed"368 self.showNotification.emit(message=label)369 Debug.msg(1,"LAYER RENAMED TO: "+self.new_name)370 self.RestoreBackup()371 372 def OnPaste(self, event):373 """Paste layer or mapset"""374 # copying between mapsets of one location375 if (self.copy_layer == None):376 return377 if (self.selected_location == self.copy_location and self.selected_mapset):378 if (self.selected_type != None):379 if (self.GetItemText(self.copy_type) != self.GetItemText(self.selected_type)): # copy raster to vector or vice versa380 GError(_("Failed to copy layer: invalid type."), parent = self)381 return382 self.new_name = self._getUserEntry(_('New name'), _('Copy map'),383 self.GetItemText(self.copy_layer) + '_copy')384 if not self.new_name:385 return386 if (self.GetItemText(self.copy_layer) == self.new_name):387 GMessage(_("Layer was not copied: new layer has the same name"), parent=self)388 return389 string = self.GetItemText(self.copy_layer)+'@'+self.GetItemText(self.copy_mapset)+','+self.new_name390 self.ChangeEnvironment(self.GetItemText(self.selected_location), self.GetItemText(self.selected_mapset))391 pasted = 0392 type = None393 label = _("Copying") + " " + string + " ..."394 self.showNotification.emit(message=label)395 if (self.GetItemText(self.copy_type)=='vector'):396 pasted = RunCommand('g.copy', vector=string)397 node = 'vector'398 elif (self.GetItemText(self.copy_type)=='raster'):399 pasted = RunCommand('g.copy', raster=string)400 node = 'raster'401 else:402 pasted = RunCommand('g.copy', raster_3d=string)403 node = 'raster_3d'404 if pasted == 0:405 if self.selected_type == None:406 self.selected_type = self.getItemByName(node, self.selected_mapset)407 if self.selected_type == None:408 # add type node if not exists409 self.selected_type = self.AppendItem(self.selected_mapset, node)410 self.AppendItem(self.selected_type,self.new_name)411 self.SortChildren(self.selected_type)412 Debug.msg(1,"COPIED TO: "+self.new_name)413 label = "g.copy "+self.GetItemText(self.copy_type)+"="+string+" -- completed" # generate this message (command) automatically?414 self.showNotification.emit(message=label)415 else:416 GError(_("Failed to copy layer: action is allowed only within the same location."),417 parent=self)418 419 # expand selected mapset420 self.ExpandAllChildren(self.selected_mapset)421 self.EnsureVisible(self.selected_mapset)422 423 self.RestoreBackup()424 425 426 def OnDelete(self, event):427 """Delete layer or mapset"""428 if (self.selected_layer):429 string = self.GetItemText(self.selected_layer)430 self.ChangeEnvironment(self.GetItemText(self.selected_location), self.GetItemText(self.selected_mapset))431 removed = 0432 # TODO: rewrite this that it will tell map type in the dialog433 if (self._confirmDialog(question=_('Do you really want to delete map <{m}>?').format(m=string),434 title=_('Delete map')) == wx.ID_YES):435 label = _("Deleting") + " " + string + " ..."436 self.showNotification.emit(message=label)437 if (self.GetItemText(self.selected_type)=='vector'):438 removed = RunCommand('g.remove', flags='f', type='vector',439 name=string)440 elif (self.GetItemText(self.selected_type)=='raster'):441 removed = RunCommand('g.remove', flags='f', type='raster',442 name=string)443 else:444 removed = RunCommand('g.remove', flags='f', type='raster_3d',445 name=string)446 if (removed==0):447 self.Delete(self.selected_layer)448 Debug.msg(1,"LAYER "+string+" DELETED")449 label = "g.remove -f type="+self.GetItemText(self.selected_type)+" name="+string+" -- completed" # generate this message (command) automatically?450 self.showNotification.emit(message=label)451 self.RestoreBackup()452 453 def OnDisplayLayer(self, event):454 """Display layer in current graphics view"""455 layerName = []456 if (self.GetItemText(self.selected_location) == self.glocation and self.selected_mapset):457 string = self.GetItemText(self.selected_layer)+'@'+self.GetItemText(self.selected_mapset)458 layerName.append(string)459 label = _("Displaying") + " " + string + " ..."460 self.showNotification.emit(message=label)461 label = "d."+self.GetItemText(self.selected_type)+" --q map="+string+" -- completed. Go to Map layers for further operations."462 if (self.GetItemText(self.selected_type)=='vector'):463 self.parent.parent.AddMaps(layerName, 'vector', True)464 elif (self.GetItemText(self.selected_type)=='raster'):465 self.parent.parent.AddMaps(layerName, 'raster', True)466 else:467 self.parent.parent.AddMaps(layerName, 'raster_3d', True)468 label = "d.rast --q map="+string+" -- completed. Go to 'Map layers' for further operations." # generate this message (command) automatically?469 self.showNotification.emit(message=label)470 Debug.msg(1,"LAYER "+self.GetItemText(self.selected_layer)+" DISPLAYED")471 else:472 GError(_("Failed to display layer: not in current mapset or invalid layer"),473 parent = self)474 475 def OnBeginDrag(self, event):476 """Just copy necessary data"""477 if (self.ctrldown):478 #cursor = wx.StockCursor(wx.CURSOR_HAND)479 #self.SetCursor(cursor)480 event.Allow()481 self.DefineItems(event.GetItem())482 self.OnCopy(event)483 Debug.msg(1,"DRAG")484 else:485 event.Veto()486 Debug.msg(1,"DRAGGING without ctrl key does nothing")487 488 def OnEndDrag(self, event):489 """Copy layer into target"""490 #cursor = wx.StockCursor(wx.CURSOR_ARROW)491 #self.SetCursor(cursor)492 if (event.GetItem()):493 self.DefineItems(event.GetItem())494 if (self.selected_location == self.copy_location and self.selected_mapset):495 event.Allow()496 self.OnPaste(event)497 self.ctrldown = False498 #cursor = wx.StockCursor(wx.CURSOR_DEFAULT)499 #self.SetCursor(cursor) # TODO: change cursor while dragging and then back, this is not working500 Debug.msg(1,"DROP DONE")501 else:502 event.Veto()503 504 def _getUserEntry(self, message, title, value):505 """Dialog for simple text entry"""506 dlg = TextEntryDialog(self, message, title)507 dlg.SetValue(value)508 if dlg.ShowModal() == wx.ID_OK:509 name = dlg.GetValue()510 else:511 name = None512 dlg.Destroy()513 514 return name515 516 def _confirmDialog(self, question, title):517 """Confirm dialog"""518 dlg = wx.MessageDialog(self, question, title, wx.YES_NO)519 res = dlg.ShowModal()520 dlg.Destroy()521 return res522 523 def _popupMenuLayer(self):524 """Create popup menu for layers"""525 menu = wx.Menu()526 527 item = wx.MenuItem(menu, wx.NewId(), _("&Copy"))528 menu.AppendItem(item)529 self.Bind(wx.EVT_MENU, self.OnCopy, item)530 531 item = wx.MenuItem(menu, wx.NewId(), _("&Paste"))532 menu.AppendItem(item)533 self.Bind(wx.EVT_MENU, self.OnPaste, item)534 535 item = wx.MenuItem(menu, wx.NewId(), _("&Delete"))536 menu.AppendItem(item)537 self.Bind(wx.EVT_MENU, self.OnDelete, item)538 539 item = wx.MenuItem(menu, wx.NewId(), _("&Rename"))540 menu.AppendItem(item)541 self.Bind(wx.EVT_MENU, self.OnRename, item)542 543 item = wx.MenuItem(menu, wx.NewId(), _("&Display layer"))544 menu.AppendItem(item)545 self.Bind(wx.EVT_MENU, self.OnDisplayLayer, item)546 547 self.PopupMenu(menu)548 menu.Destroy()549 550 def _popupMenuMapset(self):551 """Create popup menu for mapsets"""552 menu = wx.Menu()553 554 item = wx.MenuItem(menu, wx.NewId(), _("&Paste"))555 menu.AppendItem(item)556 self.Bind(wx.EVT_MENU, self.OnPaste, item)557 558 self.PopupMenu(menu)559 menu.Destroy()560 561 # testing...562 if __name__ == "__main__":563 class TestTree(LocationMapTree):564 def __init__(self, parent):565 """Test Tree constructor."""566 super(TestTree, self).__init__(parent, style=wx.TR_HIDE_ROOT | wx.TR_EDIT_LABELS |567 wx.TR_HAS_BUTTONS | wx.TR_FULL_ROW_HIGHLIGHT | wx.TR_COLUMN_LINES |568 wx.TR_MULTIPLE)569 570 def InitTreeItems(self):571 """Add locations, mapsets and layers to the tree."""572 gisenv = grass.gisenv()573 location = gisenv['LOCATION_NAME']574 mapset = gisenv['MAPSET']575 self._initTreeItems(locations=[location],576 mapsets=[mapset])577 578 self.ExpandAll()579 580 def _popupMenuLayer(self):581 """Create popup menu for layers"""582 pass583 584 def _popupMenuMapset(self):585 """Create popup menu for mapsets"""586 pass587 588 class TestFrame(wx.Frame):589 """Frame for testing purposes only."""590 def __init__(self, model=None):591 wx.Frame.__init__(self, None, title='Test tree')592 593 panel = wx.Panel(self)594 self.tree = TestTree(parent=self)595 self.tree.SetMinSize((300, 500))596 self.tree.InitTreeItems()597 598 szr = wx.BoxSizer(wx.VERTICAL)599 szr.Add(self.tree, 1, wx.ALIGN_CENTER)600 panel.SetSizerAndFit(szr)601 szr.SetSizeHints(self)602 603 def main():604 app = wx.App()605 frame = TestFrame()606 frame.Show()607 app.MainLoop()608 609 main() -
grass/trunk/gui/wxpython/docs/wxGUI.components.html
r60981 r66128 12 12 <li><a href="wxGUI.psmap.html">Cartographic Composer</a>, 13 13 available also as a command line tool <em><a href="g.gui.psmap.html">g.gui.psmap</a></em></li> 14 <li><a href="wxGUI.datacatalog.html">Data Catalog</a>, 15 available also as a command line tool <em><a href="g.gui.datacatalog.html">g.gui.datacatalog</a></em></li> 14 16 <li><a href="wxGUI.gmodeler.html">Graphical Modeler</a>, 15 17 available also as a command line tool <em><a href="g.gui.gmodeler.html">g.gui.gmodeler</a></em></li> -
grass/trunk/gui/wxpython/lmgr/frame.py
r65765 r66128 71 71 from lmgr.pyshell import PyShellWindow 72 72 from lmgr.giface import LayerManagerGrassInterface 73 from lmgr.datacatalogimport DataCatalog73 from datacatalog.catalog import DataCatalog 74 74 from gui_core.forms import GUI 75 75 from gcp.manager import GCPWizard
Note:
See TracChangeset
for help on using the changeset viewer.
