Skip to content

Commit 7e64c8b

Browse files
Enable changing of a whole column at the same time (#56)
1 parent dde3a9c commit 7e64c8b

4 files changed

Lines changed: 38 additions & 8 deletions

File tree

src/petab_gui/C.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -56,4 +56,5 @@
5656

5757
# String constants
5858
ROW = 'row'
59-
COLUMN = 'column'
59+
COLUMN = 'column'
60+
INDEX = 'index'

src/petab_gui/controllers/table_controllers.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,7 @@ def __init__(
4242
super().__init__()
4343
self.view = view
4444
self.model = model
45+
self.model.view = self.view.table_view
4546
self.proxy_model = PandasTableFilterProxy(model)
4647
self.logger = logger
4748
self.mother_controller = mother_controller

src/petab_gui/models/pandas_table_model.py

Lines changed: 27 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
from PySide6.QtGui import QColor
44

55
from ..C import COLUMNS
6-
from ..utils import validate_value, create_empty_dataframe, is_invalid
6+
from ..utils import validate_value, create_empty_dataframe, is_invalid, get_selected
77

88

99
class PandasTableModel(QAbstractTableModel):
@@ -24,6 +24,8 @@ def __init__(self, data_frame, allowed_columns, table_type, parent=None):
2424
if data_frame is None:
2525
data_frame = create_empty_dataframe(allowed_columns, table_type)
2626
self._data_frame = data_frame
27+
# add a view here, access is needed for selectionModels
28+
self.view = None
2729

2830
def rowCount(self, parent=QModelIndex()):
2931
return self._data_frame.shape[0] + 1 # empty row at the end
@@ -126,11 +128,23 @@ def insertColumn(self, column_name: str):
126128
return True
127129

128130
def setData(self, index, value, role=Qt.EditRole):
131+
if not (index.isValid() and role == Qt.EditRole):
132+
return False
133+
# check whether multiple rows but only one column is selected
134+
multi_row_change, selected = self.check_selection()
135+
if not multi_row_change:
136+
return self._set_data_single(index, value)
137+
# multiple rows but only one column is selected
138+
all_set = list()
139+
for index in selected:
140+
all_set.append(self._set_data_single(index, value))
141+
return all(all_set)
142+
143+
def _set_data_single(self, index, value):
144+
"""Set the data of a single cell."""
129145
col_setoff = 0
130146
if self._has_named_index:
131147
col_setoff = 1
132-
if not (index.isValid() and role == Qt.EditRole):
133-
return False
134148
if index.row() == self._data_frame.shape[0]:
135149
# empty row at the end
136150
self.insertRows(index.row(), 1)
@@ -260,6 +274,16 @@ def clear_table(self):
260274
self._data_frame.drop(self._data_frame.index, inplace=True)
261275
self.endResetModel()
262276

277+
def check_selection(self):
278+
"""Check if multiple rows but only one column is selected."""
279+
if self.view is None:
280+
return False
281+
selected = get_selected(self.view, mode="index")
282+
cols = set([index.column() for index in selected])
283+
rows = set([index.row() for index in selected])
284+
return len(rows) > 1 and len(cols) == 1, selected
285+
286+
263287

264288
class IndexedPandasTableModel(PandasTableModel):
265289
"""Table model for tables with named index."""

src/petab_gui/utils.py

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77
from matplotlib.figure import Figure
88
import pandas as pd
99
import logging
10-
from .C import ROW, COLUMN
10+
from .C import ROW, COLUMN, INDEX
1111
import antimony
1212
import os
1313
import numpy as np
@@ -567,18 +567,22 @@ def get_selected(table_view: QTableView, mode: str = ROW) -> list[int]:
567567
"""
568568
if not table_view or not isinstance(table_view, QTableView):
569569
return []
570-
if mode not in [ROW, COLUMN]:
570+
if mode not in [ROW, COLUMN, INDEX]:
571571
return []
572572

573573
selection_model = table_view.selectionModel()
574574
if not selection_model:
575575
return []
576576
selected_indexes = selection_model.selectedIndexes()
577+
if mode == INDEX:
578+
return selected_indexes
577579
if mode == COLUMN:
578580
selected_columns = set([index.column() for index in selected_indexes])
579581
return selected_columns
580-
selected_rows = set([index.row() for index in selected_indexes])
581-
return selected_rows
582+
if mode == ROW:
583+
selected_rows = set([index.row() for index in selected_indexes])
584+
return selected_rows
585+
return None
582586

583587

584588
def process_file(filepath, logger):

0 commit comments

Comments
 (0)