Source code for spinetoolbox.widgets.indexed_value_table_context_menu

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

"""
Offers a convenience function for time pattern and time series editor widgets.

:author: A. Soininen (VTT)
:date:   5.7.2019
"""

from PySide2.QtWidgets import QInputDialog, QMenu


[docs]def handle_table_context_menu(click_pos, table_view, model, parent_widget): """ Shows a context menu for parameter_value tables and handles the selection. Args: click_pos {QPoint): position from the context menu event table_view (QTableView): the table widget model (TimePatternModel, TimeSeriesModelFixedResolution, TimeSeriesModelVariableResolution): a model parent_widget (QWidget: context menu's parent widget """ INSERT_SINGLE_AFTER = "Insert row after" INSERT_MULTI_AFTER = "Insert multiple rows after" INSERT_SINGLE_BEFORE = "Insert row before" INSERT_MULTI_BEFORE = "Insert multiple rows before" REMOVE = "Remove rows" column = table_view.columnAt(click_pos.x()) row = table_view.rowAt(click_pos.y()) if column < 0 or row < 0: return menu = QMenu(parent_widget) menu.addAction(INSERT_SINGLE_BEFORE) menu.addAction(INSERT_MULTI_BEFORE) menu.addSeparator() menu.addAction(INSERT_SINGLE_AFTER) menu.addAction(INSERT_MULTI_AFTER) menu.addSeparator() menu.addAction(REMOVE) global_pos = table_view.mapToGlobal(click_pos) action = menu.exec_(global_pos) if action is None: return action_text = action.text() selected_indexes = table_view.selectedIndexes() selected_rows = sorted([index.row() for index in selected_indexes]) first_row = selected_rows[0] if action_text == INSERT_SINGLE_BEFORE: model.insertRows(first_row, 1) elif action_text == INSERT_MULTI_BEFORE: row_count, accepted = QInputDialog.getInt( parent_widget, "Enter number of rows", "Number of rows to insert", minValue=1 ) if accepted: model.insertRows(first_row, row_count) elif action_text == INSERT_SINGLE_AFTER: model.insertRows(first_row + 1, 1) elif action_text == INSERT_MULTI_AFTER: row_count, accepted = QInputDialog.getInt( parent_widget, "Enter number of rows", "Number of rows to insert", minValue=1 ) if accepted: model.insertRows(first_row + 1, row_count) elif action_text == REMOVE: _remove_rows(selected_rows, model)
[docs]def _remove_rows(selected_rows, model): """Packs consecutive rows into a single removeRows call.""" class RowPack: def __init__(self, first_row, count): self.first_row = first_row self.count = count if len(selected_rows) == 1: packed_rows = [RowPack(selected_rows[0], 1)] else: packed_rows = [RowPack(selected_rows[0], 1)] row_count = 1 for i in range(1, len(selected_rows)): if selected_rows[i] == selected_rows[i - 1] + 1: row_count += 1 else: packed_rows[-1].count = row_count packed_rows.append(RowPack(selected_rows[i], 1)) row_count = 1 packed_rows[-1].count = row_count for row_pack in reversed(packed_rows): model.removeRows(row_pack.first_row, row_pack.count)