def main(): tree = TreeModel(DictNode) root = tree.root n1 = tree.AppendNode(parent=root, data={"label": "node1"}) n2 = tree.AppendNode(parent=root, data={"label": "node2"}) n3 = tree.AppendNode(parent=root, data={"label": "node3"}) # pylint: disable=W0612 n11 = tree.AppendNode(parent=n1, data={"label": "node11", "xxx": "A"}) n12 = tree.AppendNode(parent=n1, data={"label": "node12", "xxx": "B"}) # pylint: disable=W0612 n21 = tree.AppendNode(parent=n2, data={"label": "node21", "xxx": "A"}) # pylint: disable=W0612 n111 = tree.AppendNode(parent=n11, data={"label": "node111", "xxx": "A"}) # pylint: disable=W0612 app = wx.App() frame = TreeFrame(model=tree) # frame.tree.Select(n111) frame.Show() app.MainLoop()
def main(): tree = TreeModel(DictNode) root = tree.root n1 = tree.AppendNode(parent=root, label='node1') n2 = tree.AppendNode(parent=root, label='node2') n3 = tree.AppendNode(parent=root, label='node3') # pylint: disable=W0612 n11 = tree.AppendNode(parent=n1, label='node11', data={'xxx': 'A'}) n12 = tree.AppendNode(parent=n1, label='node12', data={'xxx': 'B'}) # pylint: disable=W0612 n21 = tree.AppendNode(parent=n2, label='node21', data={'xxx': 'A'}) # pylint: disable=W0612 n111 = tree.AppendNode(parent=n11, label='node111', data={'xxx': 'A'}) # pylint: disable=W0612 app = wx.App() frame = TreeFrame(model=tree) # frame.tree.Select(n111) frame.Show() app.MainLoop()
class MenuTreeModelBuilder: """Abstract menu data class""" def __init__(self, filename, expandAddons=True): self.menustyle = UserSettings.Get(group='appearance', key='menustyle', subkey='selection') xmlTree = etree.parse(filename) if expandAddons: expAddons(xmlTree) self.model = TreeModel(ModuleNode) self._createModel(xmlTree) def _createModel(self, xmlTree): root = xmlTree.getroot() menubar = root.findall('menubar')[0] menus = menubar.findall('menu') for m in menus: self._createMenu(m, self.model.root) def _createMenu(self, menu, node): label = _(menu.find('label').text) items = menu.find('items') node = self.model.AppendNode(parent=node, label=label) for item in items: self._createItem(item, node) def _createItem(self, item, node): if item.tag == 'separator': data = dict(label='', description='', handler='', command='', keywords='', shortcut='', wxId='', icon='') self.model.AppendNode(parent=node, label='', data=data) elif item.tag == 'menuitem': origLabel = _(item.find('label').text) handler = item.find('handler').text desc = item.find('help') # optional gcmd = item.find('command') # optional keywords = item.find('keywords') # optional shortcut = item.find('shortcut') # optional wxId = item.find('id') # optional icon = item.find('icon') # optional if gcmd is not None: gcmd = gcmd.text else: gcmd = "" if desc.text: desc = _(desc.text) else: desc = "" if keywords is None or keywords.text is None: keywords = "" else: keywords = keywords.text if shortcut is not None: shortcut = shortcut.text else: shortcut = "" if wxId is not None: wxId = eval('wx.' + wxId.text) else: wxId = wx.ID_ANY if icon is not None: icon = icon.text else: icon = '' label = origLabel if gcmd: if self.menustyle == 1: label += ' [' + gcmd + ']' elif self.menustyle == 2: label = ' [' + gcmd + ']' data = dict( label=origLabel, description=desc, handler=handler, command=gcmd, keywords=keywords, shortcut=shortcut, wxId=wxId, icon=icon) self.model.AppendNode(parent=node, label=label, data=data) elif item.tag == 'menu': self._createMenu(item, node) else: raise ValueError(_("Unknow tag %s") % item.tag) def GetModel(self, separators=False): """Returns copy of model with or without separators (for menu or for search tree). """ if separators: return copy.deepcopy(self.model) else: model = copy.deepcopy(self.model) removeSeparators(model) return model def PrintTree(self, fh): for child in self.model.root.children: printTree(node=child, fh=fh) def PrintStrings(self, fh): """Print menu strings to file (used for localization) :param fh: file descriptor """ className = str(self.__class__).split('.', 1)[1] fh.write('menustrings_%s = [\n' % className) for child in self.model.root.children: printStrings(child, fh) fh.write(' \'\']\n') def PrintCommands(self, fh): printCommands(self.model.root, fh, itemSep=' | ', menuSep=' > ')
class MenuTreeModelBuilder: """Abstract menu data class""" # TODO: message_handler=GError is just for backwards compatibility # message_handler=GError should be replaced by None def __init__(self, filename, expandAddons=True, message_handler=GError): self.menustyle = UserSettings.Get( group="appearance", key="menustyle", subkey="selection" ) xmlTree = etree.parse(filename) if expandAddons: expAddons(xmlTree) for message in getToolboxMessages(): message_handler(message) clearToolboxMessages() self.model = TreeModel(ModuleNode) self._createModel(xmlTree) def _createModel(self, xmlTree): root = xmlTree.getroot() menubar = root.findall("menubar")[0] menus = menubar.findall("menu") for m in menus: self._createMenu(m, self.model.root) def _createMenu(self, menu, node): label = _(menu.find("label").text) items = menu.find("items") node = self.model.AppendNode(parent=node, label=label) for item in items: self._createItem(item, node) def _createItem(self, item, node): if item.tag == "separator": data = dict( label="", description="", handler="", command="", keywords="", shortcut="", wxId="", icon="", ) self.model.AppendNode(parent=node, label="", data=data) elif item.tag == "menuitem": origLabel = _(item.find("label").text) handler = item.find("handler").text desc = item.find("help") # optional gcmd = item.find("command") # optional keywords = item.find("keywords") # optional shortcut = item.find("shortcut") # optional wxId = item.find("id") # optional icon = item.find("icon") # optional if gcmd is not None: gcmd = gcmd.text else: gcmd = "" if desc.text: desc = _(desc.text) else: desc = "" if keywords is None or keywords.text is None: keywords = "" else: keywords = keywords.text if shortcut is not None: shortcut = shortcut.text else: shortcut = "" if wxId is not None: wxId = eval("wx." + wxId.text) else: wxId = wx.ID_ANY if icon is not None: icon = icon.text else: icon = "" label = origLabel if gcmd: if self.menustyle == 1: label += " [" + gcmd + "]" elif self.menustyle == 2: label = " [" + gcmd + "]" data = dict( label=origLabel, description=desc, handler=handler, command=gcmd, keywords=keywords, shortcut=shortcut, wxId=wxId, icon=icon, ) self.model.AppendNode(parent=node, label=label, data=data) elif item.tag == "menu": self._createMenu(item, node) else: raise ValueError(_("Unknow tag %s") % item.tag) def GetModel(self, separators=False): """Returns copy of model with or without separators (for menu or for search tree). """ if separators: return copy.deepcopy(self.model) else: model = copy.deepcopy(self.model) removeSeparators(model) return model def PrintTree(self, fh): for child in self.model.root.children: printTree(node=child, fh=fh) def PrintStrings(self, fh): """Print menu strings to file (used for localization) :param fh: file descriptor """ className = self.__class__.__name__ fh.write("menustrings_%s = [\n" % className) for child in self.model.root.children: printStrings(child, fh) fh.write(" '']\n") def PrintCommands(self, fh): printCommands(self.model.root, fh, itemSep=" | ", menuSep=" > ")
class LocationMapTree(TreeView): def __init__(self, parent, model=None, style=wx.TR_HIDE_ROOT | wx.TR_EDIT_LABELS | wx.TR_LINES_AT_ROOT | wx.TR_HAS_BUTTONS | wx.TR_FULL_ROW_HIGHLIGHT | wx.TR_SINGLE): """Location Map Tree constructor.""" self._model = TreeModel(DataCatalogNode) self._orig_model = self._model super(LocationMapTree, self).__init__(parent=parent, model=self._model, id=wx.ID_ANY, style=style) self.showNotification = Signal('Tree.showNotification') self.changeMapset = Signal('Tree.changeMapset') self.changeLocation = Signal('Tree.changeLocation') self.parent = parent self.contextMenu.connect(self.OnRightClick) self.itemActivated.connect(self.OnDoubleClick) self._initVariables() def _initTreeItems(self, locations=None, mapsets=None): """Add locations, mapsets and layers to the tree. Runs in multiple processes. Saves resulting data and error.""" # mapsets param currently unused genv = gisenv() if not locations: locations = GetListOfLocations(genv['GISDBASE']) loc_count = proc_count = 0 queue_list = [] proc_list = [] loc_list = [] nprocs = 4 try: nprocs = cpu_count() except NotImplementedError: nprocs = 4 results = dict() errors = [] location_nodes = [] nlocations = len(locations) grassdata_node = self._model.AppendNode( parent=self._model.root, label=_('GRASS locations in {0}').format(genv['GISDBASE']), data=dict(type='grassdata')) for location in locations: results[location] = dict() varloc = self._model.AppendNode(parent=grassdata_node, label=location, data=dict(type='location', name=location)) location_nodes.append(varloc) loc_count += 1 Debug.msg( 3, "Scanning location <{0}> ({1}/{2})".format( location, loc_count, nlocations)) q = Queue() p = Process(target=getLocationTree, args=(genv['GISDBASE'], location, q)) p.start() queue_list.append(q) proc_list.append(p) loc_list.append(location) proc_count += 1 # Wait for all running processes if proc_count == nprocs or loc_count == nlocations: Debug.msg(4, "Process subresults") for i in range(len(loc_list)): maps, error = queue_list[i].get() proc_list[i].join() if error: errors.append(error) for key in sorted(maps.keys()): mapset_node = self._model.AppendNode( parent=location_nodes[i], label=key, data=dict(type='mapset', name=key)) self._populateMapsetItem(mapset_node, maps[key]) proc_count = 0 proc_list = [] queue_list = [] loc_list = [] location_nodes = [] if errors: wx.CallAfter(GWarning, '\n'.join(errors)) Debug.msg(1, "Tree filled") self.RefreshItems() def InitTreeItems(self): """Load locations, mapsets and layers in the tree.""" raise NotImplementedError() def ReloadTreeItems(self): """Reload locations, mapsets and layers in the tree.""" self._orig_model = self._model self._model.RemoveNode(self._model.root) self.InitTreeItems() def ReloadCurrentMapset(self): """Reload current mapset tree only.""" def get_first_child(node): try: child = mapsetItem.children[0] except IndexError: child = None return child genv = gisenv() locationItem, mapsetItem = self.GetCurrentLocationMapsetNode() if not locationItem or not mapsetItem: return if mapsetItem.children: node = get_first_child(mapsetItem) while node: self._model.RemoveNode(node) node = get_first_child(mapsetItem) q = Queue() p = Process(target=getLocationTree, args=(genv['GISDBASE'], locationItem.data['name'], q, mapsetItem.data['name'])) p.start() maps, error = q.get() if error: raise CalledModuleError(error) self._populateMapsetItem(mapsetItem, maps[mapsetItem.data['name']]) self._orig_model = copy.deepcopy(self._model) self.RefreshNode(mapsetItem) self.RefreshItems() def _populateMapsetItem(self, mapset_node, data): for elem in data: if data[elem]: element_node = self._model.AppendNode(parent=mapset_node, label=elem, data=dict(type='element', name=elem)) for layer in data[elem]: self._model.AppendNode(parent=element_node, label=layer, data=dict(type=elem, name=layer)) def _popupMenuLayer(self): """Create popup menu for layers""" raise NotImplementedError() def _popupMenuMapset(self): """Create popup menu for mapsets""" raise NotImplementedError() def _popupMenuElement(self): """Create popup menu for elements""" raise NotImplementedError() def _initVariables(self): """Init variables.""" self.selected_layer = None self.selected_type = None self.selected_mapset = None self.selected_location = None def GetControl(self): """Returns control itself.""" return self def DefineItems(self, item): """Set selected items.""" self.selected_layer = None self.selected_type = None self.selected_mapset = None self.selected_location = None type = item.data['type'] if type in ('raster', 'raster_3d', 'vector'): self.selected_layer = item type = 'element' item = item.parent if type == 'element': self.selected_type = item type = 'mapset' item = item.parent if type == 'mapset': self.selected_mapset = item type = 'location' item = item.parent if type == 'location': self.selected_location = item def OnSelChanged(self, event): self.selected_layer = None def OnRightClick(self, node): """Display popup menu.""" self.DefineItems(node) if self.selected_layer: self._popupMenuLayer() elif self.selected_mapset and not self.selected_type: self._popupMenuMapset() elif self.selected_type: self._popupMenuElement() def OnDoubleClick(self, node): """Expand/Collapse node.""" if self.IsNodeExpanded(node): self.CollapseNode(node, recursive=False) else: self.ExpandNode(node, recursive=False) def ExpandCurrentLocation(self): """Expand current location""" location = gscript.gisenv()['LOCATION_NAME'] item = self._model.SearchNodes(name=location, type='location') if item: self.Select(item[0], select=True) self.ExpandNode(item[0], recursive=False) else: Debug.msg(1, "Location <%s> not found" % location) def GetCurrentLocationMapsetNode(self): """Get current mapset node""" genv = gisenv() location = genv['LOCATION_NAME'] mapset = genv['MAPSET'] locationItem = self._model.SearchNodes(name=location, type='location') if not locationItem: return None, None mapsetItem = self._model.SearchNodes(parent=locationItem[0], name=mapset, type='mapset') if not mapsetItem: return locationItem[0], None return locationItem[0], mapsetItem[0] def ExpandCurrentMapset(self): """Expand current mapset""" locationItem, mapsetItem = self.GetCurrentLocationMapsetNode() if mapsetItem: self.Select(mapsetItem, select=True) self.ExpandNode(mapsetItem, recursive=True)