Source code for spinetoolbox.widgets.pivot_table_view

######################################################################################################################
# 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/>.
######################################################################################################################

"""
Custom QTableView classes that support copy-paste and the like.

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

from PySide2.QtWidgets import QTableView, QApplication
from PySide2.QtCore import Qt, Slot, QItemSelectionModel
from PySide2.QtGui import QKeySequence
from .pivot_table_header_view import PivotTableHeaderView


[docs]class PivotTableView(QTableView): """Custom QTableView class with pivot capabilities. Attributes: parent (QWidget): The parent of this view """ def __init__(self, parent=None): """Initialize the class.""" super().__init__(parent) self.clipboard = QApplication.clipboard() self.clipboard_text = self.clipboard.text() self.clipboard.dataChanged.connect(self.clipboard_data_changed) h_header = PivotTableHeaderView(Qt.Horizontal, "columns", self) v_header = PivotTableHeaderView(Qt.Vertical, "rows", self) self.setHorizontalHeader(h_header) self.setVerticalHeader(v_header) h_header.setContextMenuPolicy(Qt.CustomContextMenu) @Slot(name="clipboard_data_changed")
[docs] def clipboard_data_changed(self): self.clipboard_text = self.clipboard.text()
[docs] def keyPressEvent(self, event): """Copy and paste to and from clipboard in Excel-like format.""" if event.matches(QKeySequence.Copy): selection = self.selectionModel().selection() if not selection: super().keyPressEvent(event) return # Take only the first selection in case of multiple selection. first = selection.first() content = "" v_header = self.verticalHeader() h_header = self.horizontalHeader() for i in range(first.top(), first.bottom() + 1): if v_header.isSectionHidden(i): continue row = list() for j in range(first.left(), first.right() + 1): if h_header.isSectionHidden(j): continue row.append(str(self.model().index(i, j).data(Qt.DisplayRole))) content += "\t".join(row) content += "\n" self.clipboard.setText(content) elif event.matches(QKeySequence.Paste): if not self.clipboard_text: super().keyPressEvent(event) return top_left_index = self.currentIndex() if not top_left_index.isValid(): super().keyPressEvent(event) return data = [line.split('\t') for line in self.clipboard_text.split('\n')[0:-1]] self.selectionModel().select(top_left_index, QItemSelectionModel.Select) self.model().paste_data(top_left_index, data) else: super().keyPressEvent(event)