diff --git a/cutevariant/gui/plugins/genotypes/widgets.py b/cutevariant/gui/plugins/genotypes/widgets.py index 061c925b..17afe416 100644 --- a/cutevariant/gui/plugins/genotypes/widgets.py +++ b/cutevariant/gui/plugins/genotypes/widgets.py @@ -142,7 +142,7 @@ def __init__(self, conn: sqlite3.Connection = None, parent=None): self._genotypes = [] # Selected fields - self._fields = set() + self._fields = [] # Selected samples self._samples = set() @@ -153,6 +153,9 @@ def __init__(self, conn: sqlite3.Connection = None, parent=None): self._headers = [] self.fields_descriptions = {} + # Used to communicate field order during a refresh after clicking on a preset + self.clicked_preset_fields = [] + # FROM config("classification"), see on_project_data self.classifications = [] @@ -194,7 +197,20 @@ def get_fields(self) -> typing.List[str]: return self._fields def set_fields(self, fields: typing.List[str]): - self._fields = list(set(fields)) + if self.clicked_preset_fields != []: + #reorder fields corresponding to the preset that was just clicked + if not sorted(fields) == sorted(self.clicked_preset_fields): + raise RuntimeError(f"Fields in the clicked preset: {self.clicked_preset_fields} should be equal to selected fields: {fields}, only order should differ") + self._fields = self.clicked_preset_fields + self.clicked_preset_fields = [] # reset after use + else: + seen = set() + unique_fields = [] + for f in fields: + if f not in seen: + seen.add(f) + unique_fields.append(f) + self._fields = unique_fields def set_variant_id(self, variant_id: int): self._variant_id = variant_id @@ -398,6 +414,12 @@ def clear(self): self.endResetModel() self.load_finished.emit() + def set_clicked_preset_fields(self, ordered_fields: list): + """ + Allows to store ordered fields, to be used during the next refresh + """ + self.clicked_preset_fields = ordered_fields + # class SamplesView(QTableView): # def __init__(self, parent=None): @@ -436,6 +458,8 @@ def __init__(self, parent=None, conn=None): self.view.setSortingEnabled(True) self.view.setIconSize(QSize(16, 16)) self.view.horizontalHeader().setHighlightSections(False) + self.view.horizontalHeader().setSectionsMovable(True) + self.view.horizontalHeader().sectionMoved.connect(self._on_section_moved) self.view.setModel(self.model) self.view.setVerticalHeader(GenotypeVerticalHeader()) @@ -498,13 +522,14 @@ def __init__(self, parent=None, conn=None): def on_model_reset(self): if self.model.rowCount() > 0: self.stack_layout.setCurrentIndex(1) - # self.view.horizontalHeader().setSectionResizeMode(QHeaderView.ResizeToContents) - # self.view.horizontalHeader().setSectionResizeMode(0, QHeaderView.Stretch) + self.view.horizontalHeader().setSectionResizeMode(QHeaderView.Interactive) + self.view.resizeColumnsToContents() # using horizontalHeader() prevented interactivity + self.view.horizontalHeader().setSectionResizeMode( + self.model.columnCount() - 1, QHeaderView.Stretch + ) # strech last column only else: self.stack_layout.setCurrentIndex(0) - # self.view.horizontalHeader().setSectionResizeMode(QHeaderView.AdjustToContents) - def setup_actions(self): # Fields to display @@ -616,7 +641,7 @@ def _on_select_preset(self): key = self.sender().data() if key in presets: self.fields_button.set_checked(presets[key]) - + self.model.set_clicked_preset_fields(presets[key]) self.on_refresh() def _on_double_clicked(self): @@ -625,6 +650,16 @@ def _on_double_clicked(self): def _on_double_clicked_vertical_header(self): self._show_sample_variant_dialog() + def _on_section_moved(self, logical: int, old_visual_index: int, new_visual_index: int): + """ + Update fields value so that saving a preset will keep the current column order + """ + fields = self.model.get_fields() + moved_field = fields.pop(old_visual_index - 1) + fields.insert(new_visual_index - 1, moved_field) + self.model.set_fields(fields) + self.view.horizontalHeader().setSectionResizeMode(QHeaderView.Interactive) + def contextMenuEvent(self, event: QContextMenuEvent): row = self.view.selectionModel().currentIndex().row()