diff options
Diffstat (limited to 'silx/gui/qt/_pyside_missing.py')
-rw-r--r-- | silx/gui/qt/_pyside_missing.py | 274 |
1 files changed, 274 insertions, 0 deletions
diff --git a/silx/gui/qt/_pyside_missing.py b/silx/gui/qt/_pyside_missing.py new file mode 100644 index 0000000..a7e2781 --- /dev/null +++ b/silx/gui/qt/_pyside_missing.py @@ -0,0 +1,274 @@ +# coding: utf-8 +# /*########################################################################## +# +# Copyright (c) 2017 European Synchrotron Radiation Facility +# +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the "Software"), to deal +# in the Software without restriction, including without limitation the rights +# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +# copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in +# all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +# THE SOFTWARE. +# +# ###########################################################################*/ +""" +Python implementation of classes which are not provided by default by PySide. +""" + +__authors__ = ["V. Valls"] +__license__ = "MIT" +__date__ = "17/01/2017" + + +from PySide.QtGui import QAbstractProxyModel +from PySide.QtCore import QModelIndex +from PySide.QtCore import Qt +from PySide.QtGui import QItemSelection +from PySide.QtGui import QItemSelectionRange + + +class QIdentityProxyModel(QAbstractProxyModel): + """Python translation of the source code of Qt c++ file""" + + def __init__(self, parent=None): + super(QIdentityProxyModel, self).__init__(parent) + self.__ignoreNextLayoutAboutToBeChanged = False + self.__ignoreNextLayoutChanged = False + self.__persistentIndexes = [] + + def columnCount(self, parent): + parent = self.mapToSource(parent) + return self.sourceModel().columnCount(parent) + + def dropMimeData(self, data, action, row, column, parent): + parent = self.mapToSource(parent) + return self.sourceModel().dropMimeData(data, action, row, column, parent) + + def index(self, row, column, parent=QModelIndex()): + parent = self.mapToSource(parent) + i = self.sourceModel().index(row, column, parent) + return self.mapFromSource(i) + + def insertColumns(self, column, count, parent=QModelIndex()): + parent = self.mapToSource(parent) + return self.sourceModel().insertColumns(column, count, parent) + + def insertRows(self, row, count, parent=QModelIndex()): + parent = self.mapToSource(parent) + return self.sourceModel().insertRows(row, count, parent) + + def mapFromSource(self, sourceIndex): + if self.sourceModel() is None or not sourceIndex.isValid(): + return QModelIndex() + index = self.createIndex(sourceIndex.row(), sourceIndex.column(), sourceIndex.internalPointer()) + return index + + def mapSelectionFromSource(self, sourceSelection): + proxySelection = QItemSelection() + if self.sourceModel() is None: + return proxySelection + + cursor = sourceSelection.constBegin() + end = sourceSelection.constEnd() + while cursor != end: + topLeft = self.mapFromSource(cursor.topLeft()) + bottomRight = self.mapFromSource(cursor.bottomRight()) + proxyRange = QItemSelectionRange(topLeft, bottomRight) + proxySelection.append(proxyRange) + cursor += 1 + return proxySelection + + def mapSelectionToSource(self, proxySelection): + sourceSelection = QItemSelection() + if self.sourceModel() is None: + return sourceSelection + + cursor = proxySelection.constBegin() + end = proxySelection.constEnd() + while cursor != end: + topLeft = self.mapToSource(cursor.topLeft()) + bottomRight = self.mapToSource(cursor.bottomRight()) + sourceRange = QItemSelectionRange(topLeft, bottomRight) + sourceSelection.append(sourceRange) + cursor += 1 + return sourceSelection + + def mapToSource(self, proxyIndex): + if self.sourceModel() is None or not proxyIndex.isValid(): + return QModelIndex() + return self.sourceModel().createIndex(proxyIndex.row(), proxyIndex.column(), proxyIndex.internalPointer()) + + def match(self, start, role, value, hits=1, flags=Qt.MatchFlags(Qt.MatchStartsWith | Qt.MatchWrap)): + if self.sourceModel() is None: + return [] + + start = self.mapToSource(start) + sourceList = self.sourceModel().match(start, role, value, hits, flags) + proxyList = [] + for cursor in sourceList: + proxyList.append(self.mapFromSource(cursor)) + return proxyList + + def parent(self, child): + sourceIndex = self.mapToSource(child) + sourceParent = sourceIndex.parent() + index = self.mapFromSource(sourceParent) + return index + + def removeColumns(self, column, count, parent=QModelIndex()): + parent = self.mapToSource(parent) + return self.sourceModel().removeColumns(column, count, parent) + + def removeRows(self, row, count, parent=QModelIndex()): + parent = self.mapToSource(parent) + return self.sourceModel().removeRows(row, count, parent) + + def rowCount(self, parent=QModelIndex()): + parent = self.mapToSource(parent) + return self.sourceModel().rowCount(parent) + + def setSourceModel(self, newSourceModel): + """Bind and unbind the source model events""" + self.beginResetModel() + + sourceModel = self.sourceModel() + if sourceModel is not None: + sourceModel.rowsAboutToBeInserted.disconnect(self.__rowsAboutToBeInserted) + sourceModel.rowsInserted.disconnect(self.__rowsInserted) + sourceModel.rowsAboutToBeRemoved.disconnect(self.__rowsAboutToBeRemoved) + sourceModel.rowsRemoved.disconnect(self.__rowsRemoved) + sourceModel.rowsAboutToBeMoved.disconnect(self.__rowsAboutToBeMoved) + sourceModel.rowsMoved.disconnect(self.__rowsMoved) + sourceModel.columnsAboutToBeInserted.disconnect(self.__columnsAboutToBeInserted) + sourceModel.columnsInserted.disconnect(self.__columnsInserted) + sourceModel.columnsAboutToBeRemoved.disconnect(self.__columnsAboutToBeRemoved) + sourceModel.columnsRemoved.disconnect(self.__columnsRemoved) + sourceModel.columnsAboutToBeMoved.disconnect(self.__columnsAboutToBeMoved) + sourceModel.columnsMoved.disconnect(self.__columnsMoved) + sourceModel.modelAboutToBeReset.disconnect(self.__modelAboutToBeReset) + sourceModel.modelReset.disconnect(self.__modelReset) + sourceModel.dataChanged.disconnect(self.__dataChanged) + sourceModel.headerDataChanged.disconnect(self.__headerDataChanged) + sourceModel.layoutAboutToBeChanged.disconnect(self.__layoutAboutToBeChanged) + sourceModel.layoutChanged.disconnect(self.__layoutChanged) + + super(QIdentityProxyModel, self).setSourceModel(newSourceModel) + + sourceModel = self.sourceModel() + if sourceModel is not None: + sourceModel.rowsAboutToBeInserted.connect(self.__rowsAboutToBeInserted) + sourceModel.rowsInserted.connect(self.__rowsInserted) + sourceModel.rowsAboutToBeRemoved.connect(self.__rowsAboutToBeRemoved) + sourceModel.rowsRemoved.connect(self.__rowsRemoved) + sourceModel.rowsAboutToBeMoved.connect(self.__rowsAboutToBeMoved) + sourceModel.rowsMoved.connect(self.__rowsMoved) + sourceModel.columnsAboutToBeInserted.connect(self.__columnsAboutToBeInserted) + sourceModel.columnsInserted.connect(self.__columnsInserted) + sourceModel.columnsAboutToBeRemoved.connect(self.__columnsAboutToBeRemoved) + sourceModel.columnsRemoved.connect(self.__columnsRemoved) + sourceModel.columnsAboutToBeMoved.connect(self.__columnsAboutToBeMoved) + sourceModel.columnsMoved.connect(self.__columnsMoved) + sourceModel.modelAboutToBeReset.connect(self.__modelAboutToBeReset) + sourceModel.modelReset.connect(self.__modelReset) + sourceModel.dataChanged.connect(self.__dataChanged) + sourceModel.headerDataChanged.connect(self.__headerDataChanged) + sourceModel.layoutAboutToBeChanged.connect(self.__layoutAboutToBeChanged) + sourceModel.layoutChanged.connect(self.__layoutChanged) + + self.endResetModel() + + def __columnsAboutToBeInserted(self, parent, start, end): + parent = self.mapFromSource(parent) + self.beginInsertColumns(parent, start, end) + + def __columnsAboutToBeMoved(self, sourceParent, sourceStart, sourceEnd, destParent, dest): + sourceParent = self.mapFromSource(sourceParent) + destParent = self.mapFromSource(destParent) + self.beginMoveColumns(sourceParent, sourceStart, sourceEnd, destParent, dest) + + def __columnsAboutToBeRemoved(self, parent, start, end): + parent = self.mapFromSource(parent) + self.beginRemoveColumns(parent, start, end) + + def __columnsInserted(self, parent, start, end): + self.endInsertColumns() + + def __columnsMoved(self, sourceParent, sourceStart, sourceEnd, destParent, dest): + self.endMoveColumns() + + def __columnsRemoved(self, parent, start, end): + self.endRemoveColumns() + + def __dataChanged(self, topLeft, bottomRight): + topLeft = self.mapFromSource(topLeft) + bottomRight = self.mapFromSource(bottomRight) + self.dataChanged(topLeft, bottomRight) + + def __headerDataChanged(self, orientation, first, last): + self.headerDataChanged(orientation, first, last) + + def __layoutAboutToBeChanged(self): + """Store persistent indexes""" + if self.__ignoreNextLayoutAboutToBeChanged: + return + + for proxyPersistentIndex in self.persistentIndexList(): + self.__proxyIndexes.append() + sourcePersistentIndex = self.mapToSource(proxyPersistentIndex) + mapping = proxyPersistentIndex, sourcePersistentIndex + self.__persistentIndexes.append(mapping) + + self.layoutAboutToBeChanged() + + def __layoutChanged(self): + """Restore persistent indexes""" + if self.__ignoreNextLayoutChanged: + return + + for mapping in self.__persistentIndexes: + proxyIndex, sourcePersistentIndex = mapping + sourcePersistentIndex = self.mapFromSource(sourcePersistentIndex) + self.changePersistentIndex(proxyIndex, sourcePersistentIndex) + + self.__persistentIndexes = [] + + self.layoutChanged() + + def __modelAboutToBeReset(self): + self.beginResetModel() + + def __modelReset(self): + self.endResetModel() + + def __rowsAboutToBeInserted(self, parent, start, end): + parent = self.mapFromSource(parent) + self.beginInsertRows(parent, start, end) + + def __rowsAboutToBeMoved(self, sourceParent, sourceStart, sourceEnd, destParent, dest): + sourceParent = self.mapFromSource(sourceParent) + destParent = self.mapFromSource(destParent) + self.beginMoveRows(sourceParent, sourceStart, sourceEnd, destParent, dest) + + def __rowsAboutToBeRemoved(self, parent, start, end): + parent = self.mapFromSource(parent) + self.beginRemoveRows(parent, start, end) + + def __rowsInserted(self, parent, start, end): + self.endInsertRows() + + def __rowsMoved(self, sourceParent, sourceStart, sourceEnd, destParent, dest): + self.endMoveRows() + + def __rowsRemoved(self, parent, start, end): + self.endRemoveRows() |