Source code for spinetoolbox.widgets.custom_qlistview

######################################################################################################################
# Copyright (C) 2017-2020 Spine project consortium
# This file is part of Spine Toolbox.
# Spine Toolbox 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. This program 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
# this program. If not, see <http://www.gnu.org/licenses/>.
######################################################################################################################

"""
Classes for custom QListView.

:author: M. Marin (KTH)
:date:   14.11.2018
"""

from PySide2.QtWidgets import QListView, QApplication
from PySide2.QtGui import QDrag
from PySide2.QtCore import Qt, QMimeData, QSize, Slot


[docs]class DragListView(QListView): """Custom QListView class with dragging support. Attributes: parent (QWidget): The parent of this view """ def __init__(self, parent): """Initialize the view.""" super().__init__(parent=parent) self.drag_start_pos = None self.pixmap = None self.mime_data = None
[docs] def mousePressEvent(self, event): """Register drag start position""" super().mousePressEvent(event) if event.button() == Qt.LeftButton: index = self.indexAt(event.pos()) if not index.isValid() or not index.model().is_index_draggable(index): self.drag_start_pos = None self.pixmap = None self.mime_data = None return self.drag_start_pos = event.pos() self.pixmap = index.data(Qt.DecorationRole).pixmap(self.iconSize()) mime_data_text = self.model().get_mime_data_text(index) self.mime_data = QMimeData() self.mime_data.setText(mime_data_text)
[docs] def mouseMoveEvent(self, event): """Start dragging action if needed""" if not event.buttons() & Qt.LeftButton: return if not self.drag_start_pos: return if (event.pos() - self.drag_start_pos).manhattanLength() < QApplication.startDragDistance(): return drag = QDrag(self) drag.setPixmap(self.pixmap) drag.setMimeData(self.mime_data) drag.setHotSpot(self.pixmap.rect().center()) drag.exec_() self.drag_start_pos = None self.pixmap = None self.mime_data = None
[docs] def mouseReleaseEvent(self, event): """Forget drag start position""" super().mouseReleaseEvent(event) self.drag_start_pos = None self.pixmap = None self.mime_data = None
[docs]class ProjectItemDragListView(DragListView): def __init__(self, parent): super().__init__(parent) base_size = QSize(24, 24) self.setIconSize(base_size) font = self.font() font.setPointSize(9) self.setFont(font) self.setStyleSheet("QListView {background: transparent;}") self.setResizeMode(DragListView.Adjust) self.setContextMenuPolicy(Qt.CustomContextMenu) self.set_orientation(self.parent().orientation()) self.parent().orientationChanged.connect(self.set_orientation) @Slot("Qt.Orientation")
[docs] def set_orientation(self, orientation): if orientation == Qt.Horizontal: self.setFlow(QListView.LeftToRight) elif orientation == Qt.Vertical: self.setFlow(QListView.TopToBottom)
[docs] def updateGeometries(self): """Resize to contents.""" super().updateGeometries() size = self.contentsSize() if not size.isValid(): size = QSize(0, 0) margin = 2 * self.frameWidth() size += QSize(margin, margin) self.setMaximumSize(size)