Source code for taurus.qt.qtcore.model.taurusmodel

#!/usr/bin/env python

# ###########################################################################
#
# This file is part of Taurus
#
# http://taurus-scada.org
#
# Copyright 2011 CELLS / ALBA Synchrotron, Bellaterra, Spain
#
# Taurus is free software: you can redistribute it and/or modify
# it under the terms of the GNU Lesser General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# Taurus is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU Lesser General Public License for more details.
#
# You should have received a copy of the GNU Lesser General Public License
# along with Taurus.  If not, see <http://www.gnu.org/licenses/>.
#
# ###########################################################################

"""This module provides base taurus tree item and a base tree model
"""

from taurus.external.qt import Qt
from taurus.core.taurusbasetypes import TaurusElementType
from taurus.core.util.log import Logger, deprecation_decorator

QtQt = Qt.Qt


__docformat__ = "restructuredtext"


[docs]class TaurusBaseTreeItem(object): """A generic node""" DisplayFunc = str def __init__(self, model, data, parent=None): self._model = model self._itemData = data self._parentItem = parent self._childItems = [] self._depth = self._calcDepth()
[docs] def itemData(self): """The internal itemData object :return: object holding the data of this item :rtype: object """ return self._itemData
[docs] def depth(self): """Depth of the node in the hierarchy :return: the node depth :rtype: int """ return self._depth
[docs] def appendChild(self, child): """Adds a new child node :param child: child to be added :type child: TaurusTreeBaseItem """ self._childItems.append(child)
[docs] def child(self, row): """Returns the child in the given row :return: the child node for the given row :rtype: TaurusTreeBaseItem """ return self._childItems[row]
[docs] def childCount(self): """Returns the number of childs for this node :return: number of childs for this node :rtype: int """ return len(self._childItems)
[docs] def hasChildren(self): return len(self._childItems) > 0
[docs] def data(self, index): """Returns the data of this node for the given index :return: the data for the given index :rtype: object """ return self._itemData[index.column()]
[docs] def icon(self, index): return None
[docs] def toolTip(self, index): return self.data(index)
[docs] def setData(self, index, data): """Sets the node data :param data: the data to be associated with this node :type data: object """ self._itemData = data
[docs] def parent(self): """Returns the parent node or None if no parent exists :return: the parent node :rtype: TaurusTreeBaseItem """ return self._parentItem
[docs] def row(self): """Returns the row for this node :return: row number for this node :rtype: int """ if self._parentItem is None: return 0 return self._parentItem._childItems.index(self)
def _calcDepth(self): d = 0 n = self.parent() while n is not None: n = n.parent() d += 1 return d
[docs] def display(self): """Returns the display string for this node :return: the node's display string :rtype: str """ if not hasattr(self, "_display"): if self._itemData is None: return None self._display = self.DisplayFunc(self._itemData) return self._display
@deprecation_decorator(alt="display", rel="4.5") def qdisplay(self): return str(self.display())
[docs] def mimeData(self, index): return self.data(index)
[docs] def role(self): """Returns the prefered role for the item. This implementation returns taurus.core.taurusbasetypes.TaurusElementType.Unknown This method should be able to return any kind of python object as long as the model that is used is compatible. :return: the role in form of element type :rtype: taurus.core.taurusbasetypes.TaurusElementType """ return TaurusElementType.Unknown
def __str__(self): return self.display()
[docs]class TaurusBaseModel(Qt.QAbstractItemModel, Logger): """The base class for all Taurus Qt models.""" ColumnNames = () ColumnRoles = ((),) DftFont = Qt.QFont("Mono", 8) def __init__(self, parent=None, data=None): Qt.QAbstractItemModel.__init__(self, parent) Logger.__init__(self) self._data_src = None self._rootItem = None self._filters = [] self._selectables = [self.ColumnRoles[0][-1]] self.setDataSource(data) def __getattr__(self, name): return getattr(self.dataSource(), name)
[docs] def createNewRootItem(self): return TaurusBaseTreeItem(self, self.ColumnNames)
[docs] def refresh(self, refresh_source=False): self.beginResetModel() self._rootItem = self.createNewRootItem() self.setupModelData(self.dataSource()) self.endResetModel()
[docs] def setupModelData(self, data): raise NotImplementedError( "setupModelData must be implemented " "in %s" % self.__class__.__name__ )
[docs] def roleIcon(self, role): raise NotImplementedError( "roleIcon must be implemented " "in %s" % self.__class__.__name__ )
[docs] def roleSize(self, role): raise NotImplementedError( "roleSize must be implemented " "in %s" % self.__class__.__name__ )
[docs] def roleToolTip(self, role): raise NotImplementedError( "roleToolTip must be implemented " "in %s" % self.__class__.__name__ )
[docs] def setDataSource(self, data_src): self._data_src = data_src self.refresh()
[docs] def dataSource(self): return self._data_src
[docs] def setSelectables(self, seq_elem_types): self._selectables = seq_elem_types
[docs] def selectables(self): return self._selectables
[docs] def role(self, column, depth=0): cr = self.ColumnRoles if column == 0: return cr[0][depth] return self.ColumnRoles[column]
[docs] def columnCount(self, parent=Qt.QModelIndex()): return len(self.ColumnRoles)
[docs] def columnIcon(self, column): return self.roleIcon(self.role(column))
[docs] def columnToolTip(self, column): return self.roleToolTip(self.role(column))
[docs] def columnSize(self, column): role = self.role(column) s = self.roleSize(role) return s
[docs] def pyData(self, index, role=QtQt.DisplayRole): if not index.isValid(): return None item = index.internalPointer() ret = None if role == QtQt.DisplayRole or role == QtQt.EditRole: ret = item.data(index) # elif role == QtQt.CheckStateRole: # data = item.data(index) # if type(data) != bool: # data = str(data).lower() == 'true' # ret = QtQt.Unchecked # if data == True: # ret = QtQt.Checked elif role == QtQt.DecorationRole: ret = item.icon(index) elif role == QtQt.ToolTipRole: ret = item.toolTip(index) # elif role == QtQt.SizeHintRole: # ret = self.columnSize(column) elif role == QtQt.FontRole: ret = self.DftFont elif role == QtQt.UserRole: ret = item return ret
[docs] def data(self, index, role=QtQt.DisplayRole): ret = self.pyData(index, role) return ret
def _setData(self, index, qvalue, role=QtQt.EditRole): item = index.internalPointer() item.setData(index, qvalue) return True
[docs] def flags(self, index): if not index.isValid(): return 0 ret = QtQt.ItemIsEnabled | QtQt.ItemIsDragEnabled item = index.internalPointer() column, depth = index.column(), item.depth() taurus_role = self.role(column, depth) if taurus_role in self.selectables(): ret |= QtQt.ItemIsSelectable return ret
[docs] def headerData(self, section, orientation, role=QtQt.DisplayRole): ret = None if orientation == QtQt.Horizontal: if role == QtQt.TextAlignmentRole: ret = int(QtQt.AlignLeft | QtQt.AlignVCenter) elif role == QtQt.DisplayRole: ret = self.ColumnNames[section] elif role == QtQt.SizeHintRole: ret = Qt.QSize(self.columnSize(section)) ret.setHeight(24) elif role == QtQt.ToolTipRole: ret = self.columnToolTip(section) elif role == QtQt.DecorationRole: ret = self.columnIcon(section) return ret
[docs] def index(self, row, column, parent=Qt.QModelIndex()): if not self.hasIndex(row, column, parent): return Qt.QModelIndex() if not parent.isValid(): parentItem = self._rootItem else: parentItem = parent.internalPointer() childItem = parentItem.child(row) if childItem: return self.createIndex(row, column, childItem) return Qt.QModelIndex()
[docs] def parent(self, index): if not index.isValid(): return Qt.QModelIndex() childItem = index.internalPointer() parentItem = childItem.parent() if parentItem is None or parentItem == self._rootItem: return Qt.QModelIndex() return self.createIndex(parentItem.row(), 0, parentItem)
[docs] def rowCount(self, parent=Qt.QModelIndex()): if parent.column() > 0: return 0 if not parent.isValid(): parentItem = self._rootItem else: parentItem = parent.internalPointer() if parentItem is None: return 0 return parentItem.childCount()
[docs] def hasChildren(self, parent=Qt.QModelIndex()): if parent.column() > 0: return 0 if not parent.isValid(): parentItem = self._rootItem else: parentItem = parent.internalPointer() if parentItem is None: return False return parentItem.hasChildren()
[docs]class TaurusBaseProxyModel(Qt.QSortFilterProxyModel): """A taurus base Qt filter & sort model""" def __init__(self, parent=None): Qt.QSortFilterProxyModel.__init__(self, parent) # filter configuration self.setFilterCaseSensitivity(QtQt.CaseInsensitive) self.setFilterKeyColumn(0) self.setFilterRole(QtQt.DisplayRole) # sort configuration self.setSortCaseSensitivity(QtQt.CaseInsensitive) self.setSortRole(QtQt.DisplayRole) # general configuration self.setDynamicSortFilter(True) def __getattr__(self, name): return getattr(self.sourceModel(), name)