Package node_manager_fkie :: Module service_list_model
[frames] | no frames]

Source Code for Module node_manager_fkie.service_list_model

  1  # Software License Agreement (BSD License) 
  2  # 
  3  # Copyright (c) 2012, Fraunhofer FKIE/US, Alexander Tiderko 
  4  # All rights reserved. 
  5  # 
  6  # Redistribution and use in source and binary forms, with or without 
  7  # modification, are permitted provided that the following conditions 
  8  # are met: 
  9  # 
 10  #  * Redistributions of source code must retain the above copyright 
 11  #    notice, this list of conditions and the following disclaimer. 
 12  #  * Redistributions in binary form must reproduce the above 
 13  #    copyright notice, this list of conditions and the following 
 14  #    disclaimer in the documentation and/or other materials provided 
 15  #    with the distribution. 
 16  #  * Neither the name of Fraunhofer nor the names of its 
 17  #    contributors may be used to endorse or promote products derived 
 18  #    from this software without specific prior written permission. 
 19  # 
 20  # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 
 21  # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 
 22  # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS 
 23  # FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE 
 24  # COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, 
 25  # INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, 
 26  # BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 
 27  # LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 
 28  # CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 
 29  # LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN 
 30  # ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 
 31  # POSSIBILITY OF SUCH DAMAGE. 
 32   
 33  from python_qt_binding.QtCore import Qt 
 34  from python_qt_binding.QtGui import QStandardItem, QStandardItemModel 
 35   
 36  from master_discovery_fkie.common import get_hostname 
 37  import node_manager_fkie as nm 
38 39 40 -class ServiceItem(QStandardItem):
41 ''' 42 The service item stored in the service model. This class stores the service as 43 U{master_discovery_fkie.ServiceInfo<http://docs.ros.org/kinetic/api/master_discovery_fkie/html/modules.html#master_discovery_fkie.master_info.ServiceInfo>}. 44 The name of the service is represented in HTML. 45 ''' 46 47 ITEM_TYPE = QStandardItem.UserType + 37 48 NAME_ROLE = Qt.UserRole + 1 49 TYPE_ROLE = Qt.UserRole + 2 50 NODENAMES_ROLE = Qt.UserRole + 3 51
52 - def __init__(self, service, parent=None):
53 ''' 54 Initialize the service item. 55 @param service: the service object to view 56 @type service: U{master_discovery_fkie.ServiceInfo<http://docs.ros.org/kinetic/api/master_discovery_fkie/html/modules.html#master_discovery_fkie.master_info.ServiceInfo>} 57 ''' 58 QStandardItem.__init__(self, service.name) 59 self.service = service 60 '''@ivar: service info as U{master_discovery_fkie.ServiceInfo<http://docs.ros.org/kinetic/api/master_discovery_fkie/html/modules.html#master_discovery_fkie.master_info.ServiceInfo>}.'''
61
62 - def updateServiceView(self, parent):
63 ''' 64 Updates the view of the service on changes. 65 @param parent: the item containing this item 66 @type parent: U{QtGui.QStandardItem<https://srinikom.github.io/pyside-docs/PySide/QtGui/QStandardItem.html>} 67 ''' 68 if parent is not None: 69 # update type view 70 child = parent.child(self.row(), 1) 71 if child is not None: 72 self.updateTypeView(self.service, child)
73
74 - def type(self):
76 77 @classmethod
78 - def getItemList(self, service):
79 ''' 80 Creates the list of the items from service. This list is used for the 81 visualization of service data as a table row. 82 @param service: the service data 83 @type service: U{master_discovery_fkie.ServiceInfo<http://docs.ros.org/kinetic/api/master_discovery_fkie/html/modules.html#master_discovery_fkie.master_info.ServiceInfo>} 84 @return: the list for the representation as a row 85 @rtype: C{[L{ServiceItem} or U{QtGui.QStandardItem<https://srinikom.github.io/pyside-docs/PySide/QtGui/QStandardItem.html>}, ...]} 86 ''' 87 items = [] 88 item = ServiceItem(service) 89 # removed tooltip for clarity !!! 90 # item.setToolTip(''.join(['<div><h4>', str(service.name), '</h4><dl><dt>', str(service.uri),'</dt></dl></div>'])) 91 items.append(item) 92 typeItem = QStandardItem() 93 ServiceItem.updateTypeView(service, typeItem) 94 items.append(typeItem) 95 return items
96 97 @classmethod
98 - def updateTypeView(cls, service, item):
99 ''' 100 Updates the representation of the column contains the type of the service. 101 @param service: the service data 102 @type service: U{master_discovery_fkie.ServiceInfo<http://docs.ros.org/kinetic/api/master_discovery_fkie/html/modules.html#master_discovery_fkie.master_info.ServiceInfo>} 103 @param item: corresponding item in the model 104 @type item: L{ServiceItem} 105 ''' 106 try: 107 if service.isLocal and service.type: 108 service_class = service.get_service_class(nm.is_local(get_hostname(service.uri))) 109 item.setText(service_class._type) 110 elif service.type: 111 item.setText(service.type) 112 else: 113 item.setText('unknown type') 114 # removed tooltip for clarity !!! 115 # tooltip = '' 116 # tooltip = ''.join([tooltip, '<h4>', service_class._type, '</h4>']) 117 # tooltip = ''.join([tooltip, '<b><u>', 'Request', ':</u></b>']) 118 # tooltip = ''.join([tooltip, '<dl><dt>', str(service_class._request_class.__slots__), '</dt></dl>']) 119 # 120 # tooltip = ''.join([tooltip, '<b><u>', 'Response', ':</u></b>']) 121 # tooltip = ''.join([tooltip, '<dl><dt>', str(service_class._response_class.__slots__), '</dt></dl>']) 122 # 123 # item.setToolTip(''.join(['<div>', tooltip, '</div>'])) 124 item.setToolTip('') 125 except: 126 if not service.isLocal: 127 tooltip = ''.join(['<h4>', 'Service type is not available due to he running on another host.', '</h4>']) 128 item.setToolTip(''.join(['<div>', tooltip, '</div>']))
129
130 - def data(self, role):
131 if role == self.NAME_ROLE: 132 return self.service.name 133 elif role == self.TYPE_ROLE: 134 return str(self.service.get_service_class(False)) 135 elif role == self.NODENAMES_ROLE: 136 return str(self.service.serviceProvider) 137 else: 138 return QStandardItem.data(self, role)
139
140 # def __eq__(self, item): 141 # ''' 142 # Compares the name of service. 143 # ''' 144 # if isinstance(item, str) or isinstance(item, unicode): 145 # return self.service.name.lower() == item.lower() 146 # elif not (item is None): 147 # return self.service.name.lower() == item.service.name.lower() 148 # return False 149 # 150 # def __gt__(self, item): 151 # ''' 152 # Compares the name of service. 153 # ''' 154 # if isinstance(item, str) or isinstance(item, unicode): 155 # return self.service.name.lower() > item.lower() 156 # elif not (item is None): 157 # return self.service.name.lower() > item.service.name.lower() 158 # return False 159 160 161 -class ServiceModel(QStandardItemModel):
162 ''' 163 The model to manage the list with services in ROS network. 164 ''' 165 header = [('Name', 300), 166 ('Type', -1)] 167 '''@ivar: the list with columns C{[(name, width), ...]}''' 168
169 - def __init__(self):
170 ''' 171 Creates a new list model. 172 ''' 173 QStandardItemModel.__init__(self) 174 self.setColumnCount(len(ServiceModel.header)) 175 self.setHorizontalHeaderLabels([label for label, _ in ServiceModel.header]) 176 self.pyqt_workaround = dict() # workaround for using with PyQt: store the python object to keep the defined attributes in the ServiceItem subclass
177
178 - def flags(self, index):
179 ''' 180 @param index: parent of the list 181 @type index: U{QtCore.QModelIndex<https://srinikom.github.io/pyside-docs/PySide/QtCore/QModelIndex.html>} 182 @return: Flag or the requestet item 183 @rtype: U{QtCore.Qt.ItemFlag<https://srinikom.github.io/pyside-docs/PySide/QtCore/Qt.html>} 184 @see: U{http://www.pyside.org/docs/pyside-1.0.1/PySide/QtCore/Qt.html} 185 ''' 186 if not index.isValid(): 187 return Qt.NoItemFlags 188 return Qt.ItemIsEnabled | Qt.ItemIsSelectable
189
190 - def updateModelData(self, services, added_srvs, updated_srvs, removed_srvs):
191 ''' 192 Updates the service list model. New services will be inserted in sorting 193 order. Not available services removed from the model. 194 @param services: The dictionary with services 195 @type services: C{dict(service name : U{master_discovery_fkie.ServiceInfo<http://docs.ros.org/kinetic/api/master_discovery_fkie/html/modules.html#master_discovery_fkie.master_info.ServiceInfo>})} 196 @param added_srvs: the list of new services in the :service: list 197 @type added_srvs: list or set 198 @param updated_srvs: the list of updated services in the :service: list 199 @type updated_srvs: list or set 200 @param removed_srvs: the list of removed services in the :service: list 201 @type removed_srvs: list or set 202 ''' 203 root = self.invisibleRootItem() 204 # import os 205 # cputimes = os.times() 206 # cputime_init = cputimes[0] + cputimes[1] 207 # remove items from model 208 for i in reversed(range(root.rowCount())): 209 serviceItem = root.child(i) 210 if serviceItem.service.name in removed_srvs: 211 root.removeRow(i) 212 try: 213 del self.pyqt_workaround[serviceItem.service.name] 214 except: 215 pass 216 elif serviceItem.service.name in updated_srvs: 217 serviceItem.updateServiceView(root) 218 # add new items in sorted order 219 for srv_name in added_srvs: 220 try: 221 doAddItem = True 222 service = services[srv_name] 223 for i in range(root.rowCount()): 224 if srv_name not in updated_srvs: 225 serviceItem = root.child(i) 226 if cmp(serviceItem.service.name, service.name) > 0: 227 service_item_row = ServiceItem.getItemList(service) 228 root.insertRow(i, service_item_row) 229 self.pyqt_workaround[srv_name] = service_item_row 230 doAddItem = False 231 break 232 else: 233 doAddItem = False 234 break 235 if doAddItem: 236 service_item_row = ServiceItem.getItemList(service) 237 root.appendRow(service_item_row) 238 self.pyqt_workaround[srv_name] = service_item_row 239 except: 240 pass
241 # import traceback 242 # print traceback.format_exc(1) 243 # cputimes = os.times() 244 # cputime = cputimes[0] + cputimes[1] - cputime_init 245 # print " update services ", cputime, ', service count:', len(services) 246
247 - def index_from_names(self, services):
248 ''' 249 Returns for given services the list of QModelIndex in this model. 250 :param services: the list of service names 251 :type services: [str, ...] 252 :return: the list of QModelIndex 253 :rtype: [U{QtCore.QModelIndex<https://srinikom.github.io/pyside-docs/PySide/QtCore/QModelIndex.html>}, ...] 254 ''' 255 result = [] 256 root = self.invisibleRootItem() 257 for i in range(root.rowCount()): 258 serviceItem = root.child(i) 259 if serviceItem.service.name in services: 260 result.append(self.index(i, 0)) 261 return result
262