plugin_tree_model.py
Go to the documentation of this file.
00001 #!/usr/bin/env python
00002 
00003 import bisect
00004 
00005 import QtCore
00006 
00007 import rospy
00008 import rospkg
00009 
00010 from python_qt_binding.QtCore import Qt, QObject, QAbstractItemModel
00011 
00012 from vigir_pluginlib_msgs.msg import PluginState, PluginDescription
00013 
00014 
00015 # Tree Model for Plugins
00016 class PluginTreeModel(QtCore.QAbstractItemModel):
00017 
00018     def __init__(self, parent=None, *args):
00019         super(PluginTreeModel, self).__init__(parent)
00020         self._root_item = PluginTreeItem()
00021         self._plugin_states = []
00022 
00023     def clear(self):
00024         self._root_item.clear()
00025 
00026     def columnCount(self, parent=QtCore.QModelIndex()):
00027         if parent.isValid():
00028             return parent.internalPointer().columnCount()
00029         else:
00030             return self._root_item.columnCount()
00031 
00032     def rowCount(self, parent=QtCore.QModelIndex()):
00033         if parent.isValid():
00034             return parent.internalPointer().childCount()
00035         else:
00036             return self._root_item.childCount()
00037 
00038     def headerData(self, section, orientation, role):
00039         if orientation == QtCore.Qt.Horizontal and role == QtCore.Qt.DisplayRole:
00040             if section == 0:
00041                 return 'Class'
00042             elif section == 1:
00043                 return 'Name'
00044         return None
00045 
00046     def insertRows(self, row, count, parent=QtCore.QModelIndex()):
00047         parent_item = self.getItem(parent)
00048 
00049         self.beginInsertRows(parent, row, row + count - 1)
00050         success = parent_item.insertChildren(row, count)
00051         self.endInsertRows()
00052 
00053         return success
00054 
00055     def removeRows(self, row, count, parent=QtCore.QModelIndex()):
00056         parent_item = self.getItem(parent)
00057 
00058         self.beginRemoveRows(parent, row, row + count - 1)
00059         success = parent_item.removeChildren(row, count)
00060         self.endRemoveRows()
00061 
00062         # remove empty branch
00063         if success and parent_item.parentItem() and not parent_item.childCount():
00064             return self.removeRows(parent_item.childNumber(), 1)
00065 
00066         return success
00067 
00068     def addBranch(self, base_class):
00069         # check if branch already does exist
00070         branch = self.findBranch(base_class)
00071         if branch.isValid():
00072             return branch
00073 
00074         state = PluginState()
00075         state.description.base_class.data = base_class
00076 
00077         # add new branch
00078         temp_list = [child.getPluginState().description.base_class.data for child in self._root_item.childs()]
00079         position = bisect.bisect(temp_list, base_class)
00080 
00081         if self.insertRows(position, 1):
00082             branch_item = self._root_item.child(position)
00083             branch_item.setData(state)
00084             return self.index(position, 0)
00085 
00086         return QtCore.QModelIndex()
00087 
00088     def addItem(self, state):
00089         # search for branch with type_class
00090         branch = self.addBranch(state.description.base_class.data)
00091         branch_item = self.getItem(branch)
00092 
00093         # check if child already does exist
00094         child = self.findChild(state.description, branch)
00095         if child.isValid():
00096             return child
00097 
00098         # add new item to branch
00099         entry = (state.description.type_class.data, state.description.name.data)
00100         temp_list = [(child.getPluginState().description.type_class.data, child.getPluginState().description.name.data) for child in branch_item.childs()]
00101         position = bisect.bisect(temp_list, entry)
00102 
00103         if self.insertRows(position, 1, branch):
00104             child_item = branch_item.child(position)
00105             child_item.setData(state)
00106             return self.index(position, 0, branch)
00107 
00108         return QtCore.QModelIndex()
00109 
00110     def getItem(self, index=QtCore.QModelIndex()):
00111         if index.isValid():
00112             return index.internalPointer()
00113         else:
00114             return self._root_item
00115 
00116     def setData(self, data):
00117         self.clear()
00118         self.updateData(data)
00119 
00120     def updateData(self, data):
00121         # update empty entries to keep UI tidy
00122         for state in data:
00123             if not state.description.base_class.data:
00124                 state.description.base_class.data = 'Unknown'
00125             if not state.description.type_class.data:
00126                 state.description.type_class.data = 'Unknown'
00127 
00128         # collect entries which does not exist in recent update anymore
00129         rows = []
00130         for branch_item in self._root_item.childs():
00131             branch_index = self.index(branch_item.childNumber(), 0)
00132             for child_item in branch_item.childs():
00133                 result = filter(lambda state: state.description == child_item.getPluginState().description, data)
00134                 if not result:
00135                     rows.append((child_item.childNumber(), branch_index))
00136 
00137         # remove obsolete entries, TODO: check for branch!
00138         rows.sort(reverse=True)
00139         for row in rows:
00140             self.removeRows(row[0], 1, row[1])
00141 
00142         # adding entries
00143         for state in data:
00144             # adding new entries
00145             self.addItem(state)
00146 
00147     def data(self, index, role):
00148         if not index.isValid():
00149             return None
00150         elif role == QtCore.Qt.DisplayRole:
00151             return index.internalPointer().data(index.column())
00152         else:
00153             return None
00154 
00155     def flags(self, index=QtCore.QModelIndex()):
00156         if index.isValid():
00157             return QtCore.Qt.ItemIsEnabled | QtCore.Qt.ItemIsSelectable | super(PluginTreeModel, self).flags(index) #QtCore.Qt.ItemIsEditable
00158         else:
00159             return QtCore.Qt.NoItemFlags
00160 
00161     def index(self, row, column, parent=QtCore.QModelIndex()):
00162         if not self.hasIndex(row, column, parent):
00163             return QtCore.QModelIndex()
00164 
00165         if parent.isValid() and parent.column() != 0:
00166             return QtCore.QModelIndex()
00167 
00168         parent_item = self.getItem(parent)
00169 
00170         child_item = parent_item.child(row)
00171         if child_item:
00172             return self.createIndex(row, column, child_item)
00173         else:
00174             return QtCore.QModelIndex()
00175 
00176     def parent(self, index=QtCore.QModelIndex()):
00177         if not index.isValid():
00178             return QtCore.QModelIndex()
00179 
00180         child_item = self.getItem(index)
00181         parent_item = child_item.parentItem()
00182 
00183         if parent_item == self._root_item:
00184             return QtCore.QModelIndex()
00185 
00186         return self.createIndex(parent_item.childNumber(), 0, parent_item)
00187 
00188     def findChild(self, description, parent=QtCore.QModelIndex()):
00189         parent_item = self.getItem(parent)
00190         if parent_item == self._root_item:
00191             parent = self.findBranch(description.base_class.data, parent)
00192 
00193         if not parent.isValid():
00194             return QtCore.QModelIndex()
00195 
00196         child_item = parent_item.findChild(description)
00197         if child_item:
00198             return self.index(child_item.childNumber(), 0, parent)
00199         else:
00200             return QtCore.QModelIndex()
00201 
00202     def findBranch(self, base_class, parent=QtCore.QModelIndex()):
00203         parent_item = self.getItem(parent)
00204 
00205         child_item = parent_item.findBranch(base_class)
00206         if child_item:
00207             return self.index(child_item.childNumber(), 0, parent)
00208         else:
00209             return QtCore.QModelIndex()
00210 
00211     def expandChildren(self, index, view):
00212         if not index.isValid():
00213             return
00214 
00215         for i in range(0, index.model().rowCount(index)):
00216             child = index.child(i, 0)
00217             self.expandChildren(child, view)
00218 
00219         if not view.expanded(index):
00220             view.expand(index)
00221 
00222     def expandAll(self):
00223         self.expandChildren(self.createIndex(0, 0, self._root_item))
00224 
00225 
00226 # Tree Item for Plugins
00227 class PluginTreeItem:
00228 
00229     def __init__(self, state=PluginState(), parent=None):
00230         self._parent_item = parent
00231         self._child_items = []
00232         self._plugin_state = PluginState()
00233         self.setData(state)
00234 
00235     def clear(self):
00236         for child in self._child_items:
00237             child.clear()
00238         self._child_items = []
00239         self._plugin_state = PluginState()
00240 
00241     def child(self, row):
00242         if row < self.childCount():
00243             return self._child_items[row]
00244         else:
00245             return None
00246 
00247     def childs(self):
00248         return self._child_items
00249 
00250     def childCount(self):
00251         return len(self._child_items)
00252 
00253     def childNumber(self):
00254         if self._parent_item is not None:
00255             return self._parent_item._child_items.index(self)
00256         return 0
00257 
00258     def insertChildren(self, position, count):
00259         if position < 0 or position > self.childCount():
00260             return False
00261 
00262         for row in range(0, count):
00263             self._child_items.insert(position, PluginTreeItem(parent=self))
00264 
00265         return True
00266 
00267     def removeChildren(self, position, count):
00268         if position < 0 or position > self.childCount():
00269             return False
00270 
00271         del self._child_items[position:position+count]
00272 
00273         return True
00274 
00275     def columnCount(self):
00276         return 2
00277 
00278     def data(self, column):
00279         if column == 0:
00280             if self.childCount() > 0:
00281                 return self._plugin_state.description.base_class.data
00282             else:
00283                 return self._plugin_state.description.type_class.data
00284         elif column == 1:
00285             if self.childCount() > 0:
00286                 return ""
00287             else:
00288                 return self._plugin_state.description.name.data
00289         else:
00290             return None
00291 
00292     def setData(self, state):
00293         self._plugin_state = state
00294 
00295     def getPluginState(self):
00296         return self._plugin_state
00297 
00298     def findChild(self, description):
00299         child_item = filter(lambda child: child.getPluginState().description == description, self._child_items)
00300         if not child_item:
00301             return None
00302         else:
00303             return child_item[0]
00304 
00305     def findBranch(self, base_class):
00306         branch_item = filter(lambda child: child.getPluginState().description.base_class.data == base_class, self._child_items)
00307         if not branch_item:
00308             return None
00309         else:
00310             return branch_item[0]
00311 
00312     def parentItem(self):
00313         return self._parent_item


vigir_pluginlib_manager
Author(s): Alexander Stumpf
autogenerated on Tue Sep 13 2016 03:47:32