From 7f656ef2854295a5ebc086e01eee4d721bae6a84 Mon Sep 17 00:00:00 2001 From: Zohar Malamant Date: Mon, 4 Mar 2024 09:51:27 +0100 Subject: [PATCH] Add columns to Manage Cases overview --- pyproject.toml | 1 + src/ert/gui/ertwidgets/closabledialog.py | 6 +- .../gui/ertwidgets/models/storage_model.py | 58 ++++++++++++++++--- src/ert/gui/ertwidgets/storage_widget.py | 4 -- 4 files changed, 54 insertions(+), 15 deletions(-) diff --git a/pyproject.toml b/pyproject.toml index 8d4ad14f79f..aff275cd5e2 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -50,6 +50,7 @@ dependencies=[ "resdata", "fastapi", "filelock", + "humanize", "importlib_resources;python_version <= '3.8'", "iterative_ensemble_smoother>=0.2.3", "typing_extensions>=4.5", diff --git a/src/ert/gui/ertwidgets/closabledialog.py b/src/ert/gui/ertwidgets/closabledialog.py index 6b204a8ff96..da7ee9b9a64 100644 --- a/src/ert/gui/ertwidgets/closabledialog.py +++ b/src/ert/gui/ertwidgets/closabledialog.py @@ -1,5 +1,5 @@ from qtpy.QtCore import Qt -from qtpy.QtWidgets import QDialog, QHBoxLayout, QLayout, QPushButton, QVBoxLayout +from qtpy.QtWidgets import QDialog, QHBoxLayout, QPushButton, QVBoxLayout class ClosableDialog(QDialog): @@ -12,8 +12,7 @@ def __init__(self, title, widget, parent=None): self.setWindowFlags(self.windowFlags() & ~Qt.WindowCloseButtonHint) layout = QVBoxLayout() - layout.setSizeConstraint(QLayout.SetFixedSize) # not resizable!!! - layout.addWidget(widget) + layout.addWidget(widget, stretch=1) self.__button_layout = QHBoxLayout() self.close_button = QPushButton("Close") @@ -23,7 +22,6 @@ def __init__(self, title, widget, parent=None): self.__button_layout.addStretch() self.__button_layout.addWidget(self.close_button) - layout.addStretch() layout.addLayout(self.__button_layout) self.setLayout(layout) diff --git a/src/ert/gui/ertwidgets/models/storage_model.py b/src/ert/gui/ertwidgets/models/storage_model.py index 4261f88efb1..c8f4955cd09 100644 --- a/src/ert/gui/ertwidgets/models/storage_model.py +++ b/src/ert/gui/ertwidgets/models/storage_model.py @@ -1,15 +1,34 @@ +from enum import IntEnum from typing import Any, List +import humanize from qtpy.QtCore import ( QAbstractItemModel, QModelIndex, Qt, Slot, ) +from qtpy.QtWidgets import QApplication from ert.storage import EnsembleReader, ExperimentReader, StorageReader +class _Column(IntEnum): + NAME = 0 + TIME = 1 + TYPE = 2 + UUID = 3 + + +_NUM_COLUMNS = max(_Column).value + 1 +_COLUMN_TEXT = { + 0: "Name", + 1: "Created at", + 2: "Type", + 3: "ID", +} + + class Ensemble: def __init__(self, ensemble: EnsembleReader, parent: Any): self._parent = parent @@ -22,12 +41,21 @@ def row(self) -> int: return self._parent._children.index(self) return 0 - def data(self, index: QModelIndex, role=Qt.ItemDataRole.DisplayRole) -> Any: + def data(self, index: QModelIndex, role) -> Any: if not index.isValid(): return None + col = index.column() if role == Qt.ItemDataRole.DisplayRole: - return f"{self._name} - {self._start_time} ({self._id})" + if col == _Column.NAME: + return self._name + if col == _Column.TIME: + return humanize.naturaltime(self._start_time) + if col == _Column.UUID: + return str(self._id) + elif role == Qt.ItemDataRole.ToolTipRole: + if col == _Column.TIME: + return str(self._start_time) return None @@ -37,9 +65,7 @@ def __init__(self, experiment: ExperimentReader, parent: Any): self._parent = parent self._id = experiment.id self._name = experiment.name - self._experiment_type = experiment.simulation_arguments.get( - "analysis_module", "" - ) + self._experiment_type = experiment.simulation_arguments.get("ensemble_type") self._children: List[Ensemble] = [] def add_ensemble(self, ensemble: Ensemble) -> None: @@ -54,13 +80,25 @@ def data(self, index: QModelIndex, role=Qt.ItemDataRole.DisplayRole) -> Any: if not index.isValid(): return None + col = index.column() if role == Qt.ItemDataRole.DisplayRole: - return f"{self._name} - {self._experiment_type} ({self._id})" + if col == _Column.NAME: + return self._name + if col == _Column.TYPE: + return self._experiment_type or "None" + if col == _Column.UUID: + return str(self._id) + elif role == Qt.ItemDataRole.ForegroundRole: + if col == _Column.TYPE and not self._experiment_type: + qapp = QApplication.instance() + assert isinstance(qapp, QApplication) + return qapp.palette().mid() return None class StorageModel(QAbstractItemModel): + def __init__(self, storage: StorageReader): super().__init__(None) self._children: List[Experiment] = [] @@ -89,7 +127,7 @@ def _load_storage(self, storage: StorageReader) -> None: self._children.append(ex) def columnCount(self, parent: QModelIndex) -> int: - return 1 + return _NUM_COLUMNS def rowCount(self, parent: QModelIndex) -> int: if parent.isValid(): @@ -111,6 +149,12 @@ def parent(self, index: QModelIndex) -> QModelIndex: return self.createIndex(parentItem.row(), 0, parentItem) + def headerData(self, section: int, orientation: int, role: int) -> Any: + if role != Qt.ItemDataRole.DisplayRole: + return None + + return _COLUMN_TEXT[_Column(section)] + def data(self, index: QModelIndex, role=Qt.ItemDataRole.DisplayRole) -> Any: if not index.isValid(): return None diff --git a/src/ert/gui/ertwidgets/storage_widget.py b/src/ert/gui/ertwidgets/storage_widget.py index caeef9639c4..b44de7b82e8 100644 --- a/src/ert/gui/ertwidgets/storage_widget.py +++ b/src/ert/gui/ertwidgets/storage_widget.py @@ -1,6 +1,5 @@ from qtpy.QtCore import QSortFilterProxyModel, Qt from qtpy.QtWidgets import ( - QHeaderView, QLineEdit, QTreeView, QVBoxLayout, @@ -31,9 +30,6 @@ def __init__( lambda: storage_model.reloadStorage(self._notifier.storage) ) - if isinstance(tree_view.header(), QHeaderView): - tree_view.header().hide() - search_bar = QLineEdit(self) search_bar.setPlaceholderText("Filter") proxy_model = QSortFilterProxyModel()