Package pyffi :: Package qskope :: Module global_model
[hide private]
[frames] | no frames]

Source Code for Module pyffi.qskope.global_model

  1  """The GlobalModel module defines a model to display the structure of a file 
  2  built from StructBase instances possibly referring to one another.""" 
  3   
  4  # ***** BEGIN LICENSE BLOCK ***** 
  5  # 
  6  # Copyright (c) 2007-2011, Python File Format Interface 
  7  # All rights reserved. 
  8  # 
  9  # Redistribution and use in source and binary forms, with or without 
 10  # modification, are permitted provided that the following conditions 
 11  # are met: 
 12  # 
 13  #    * Redistributions of source code must retain the above copyright 
 14  #      notice, this list of conditions and the following disclaimer. 
 15  # 
 16  #    * Redistributions in binary form must reproduce the above 
 17  #      copyright notice, this list of conditions and the following 
 18  #      disclaimer in the documentation and/or other materials provided 
 19  #      with the distribution. 
 20  # 
 21  #    * Neither the name of the Python File Format Interface 
 22  #      project nor the names of its contributors may be used to endorse 
 23  #      or promote products derived from this software without specific 
 24  #      prior written permission. 
 25  # 
 26  # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 
 27  # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 
 28  # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS 
 29  # FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE 
 30  # COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, 
 31  # INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, 
 32  # BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 
 33  # LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 
 34  # CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 
 35  # LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN 
 36  # ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 
 37  # POSSIBILITY OF SUCH DAMAGE. 
 38  # 
 39  # ***** END LICENSE BLOCK ***** 
 40   
 41  from UserDict import DictMixin 
 42   
 43  from PyQt4 import QtGui, QtCore 
 44   
 45  from pyffi.utils.graph import EdgeFilter 
 46  from pyffi.qskope.global_tree import GlobalTreeItemData, GlobalTreeItem 
 47   
 48  # implementation references: 
 49  # http://doc.trolltech.com/4.3/model-view-programming.html 
 50  # http://doc.trolltech.com/4.3/model-view-model-subclassing.html 
51 -class GlobalModel(QtCore.QAbstractItemModel):
52 """General purpose model for QModelIndexed access to data loaded with 53 pyffi.""" 54 # column definitions 55 NUM_COLUMNS = 3 56 COL_TYPE = 0 57 COL_NUMBER = 2 58 COL_NAME = 1 59
60 - class IndexDict(DictMixin):
61 - def __init__(self):
62 self.clear()
63
64 - def __getitem__(self, key):
65 try: 66 return self.data[id(key)] 67 except KeyError: 68 index = self.free_indices[-1] 69 self.data[id(key)] = index 70 if len(self.free_indices) == 1: 71 self.free_indices[0] += 1 72 else: 73 self.free_indices.pop()
74
75 - def __delitem__(self, key):
76 # index becomes available 77 self.free_indices.append(self.data[id(key)]) 78 # remove it 79 del self.data[id(key)]
80
81 - def clear(self):
82 # all indices larger than the first element 83 # are free as well 84 self.free_indices = [0] 85 self.data = {}
86
87 - def __init__(self, parent=None, globalnode=None, edge_filter=EdgeFilter()):
88 """Initialize the model to display the given data.""" 89 QtCore.QAbstractItemModel.__init__(self, parent) 90 # set up the tree 91 self.root_item = GlobalTreeItem( 92 data=GlobalTreeItemData(node=globalnode), 93 edge_filter=edge_filter) 94 # set up the index dictionary 95 self.index_dict = self.IndexDict() 96 self.updateIndexDict(self.root_item)
97
98 - def updateIndexDict(self, item):
99 self.index_dict[item.data.node] 100 for child_item in item.children: 101 self.updateIndexDict(child_item)
102 103
104 - def flags(self, index):
105 """Return flags for the given index: all indices are enabled and 106 selectable.""" 107 # all items are selectable 108 # they are enabled if their edge_type is active 109 if not index.isValid(): 110 return QtCore.Qt.ItemFlags() 111 item = index.internalPointer() 112 if item.edge_type.active: 113 flags = QtCore.Qt.ItemIsEnabled | QtCore.Qt.ItemIsSelectable 114 else: 115 flags = QtCore.Qt.ItemIsSelectable 116 return QtCore.Qt.ItemFlags(flags)
117
118 - def data(self, index, role):
119 """Return the data of model index in a particular role.""" 120 # check if the index is valid 121 # check if the role is supported 122 if not index.isValid() or role != QtCore.Qt.DisplayRole: 123 return QtCore.QVariant() 124 # get the data for display 125 data = index.internalPointer().data 126 127 # the type column 128 if index.column() == self.COL_TYPE: 129 return QtCore.QVariant(data.typename) 130 elif index.column() == self.COL_NAME: 131 return QtCore.QVariant(data.display) 132 elif index.column() == self.COL_NUMBER: 133 return QtCore.QVariant(self.index_dict[data.node]) 134 135 # other colums: invalid 136 else: 137 return QtCore.QVariant()
138
139 - def headerData(self, section, orientation, role):
140 """Return header data.""" 141 if (orientation == QtCore.Qt.Horizontal 142 and role == QtCore.Qt.DisplayRole): 143 if section == self.COL_TYPE: 144 return QtCore.QVariant("Type") 145 elif section == self.COL_NAME: 146 return QtCore.QVariant("Name") 147 elif section == self.COL_NUMBER: 148 return QtCore.QVariant("#") 149 return QtCore.QVariant()
150
151 - def rowCount(self, parent = QtCore.QModelIndex()):
152 """Calculate a row count for the given parent index.""" 153 if not parent.isValid(): 154 return 1 155 else: 156 # get the parent child count = number of references 157 return len(parent.internalPointer().children)
158
159 - def columnCount(self, parent = QtCore.QModelIndex()):
160 """Return column count.""" 161 # column count is constant everywhere 162 return self.NUM_COLUMNS
163
164 - def index(self, row, column, parent):
165 """Create an index to item (row, column) of object parent.""" 166 # check if the parent is valid 167 if not parent.isValid(): 168 # parent is not valid, so we need a top-level object 169 # return the index with row'th block as internal pointer 170 item = self.root_item 171 else: 172 # parent is valid, so we need to go get the row'th reference 173 # get the parent pointer 174 item = parent.internalPointer().children[row] 175 return self.createIndex(row, column, item)
176
177 - def parent(self, index):
178 """Calculate parent of a given index.""" 179 # get parent structure 180 parent_item = index.internalPointer().parent 181 # if parent's parent is None, then index must be a top 182 # level object, so return invalid index 183 if parent_item is None: 184 return QtCore.QModelIndex() 185 # if parent's parent is not None, then it must be member of 186 # some deeper nested structure, so calculate the row as usual 187 else: 188 return self.createIndex(parent_item.row, 0, parent_item)
189