Coverage for graphica/gui/provenance_panel.py: 100.0%
44 statements
« prev ^ index » next coverage.py v7.16.2, created at 2026-10-12 16:38 +0000
« prev ^ index » next coverage.py v7.16.2, created at 2026-10-12 16:38 +0000
1"""選んだデータセットの処理の履歴をツリーで見せるドック。
3操作の下にその元のデータセットを置き、元にも履歴があれば祖先まで辿る。元が消されていれば「(削除済み)」で止める
4(履歴が親の ID だけでなく名前も持つのはこのため)。
5"""
6from PySide6.QtWidgets import QWidget, QVBoxLayout, QLabel, QTreeWidget, QTreeWidgetItem
8from graphica.core.methods_text import describe_operation
11class ProvenancePanel(QWidget):
12 def __init__(self, parent=None):
13 super().__init__(parent)
14 layout = QVBoxLayout(self)
15 layout.setContentsMargins(4, 4, 4, 4)
17 self.placeholder_label = QLabel(
18 "処理履歴(フィット・ベースライン補正・平滑化等で生成された\n"
19 "データセット)を選択すると、ここに処理の流れが表示されます。"
20 )
21 self.placeholder_label.setWordWrap(True)
22 self.placeholder_label.setStyleSheet("color: gray; padding: 12px;")
23 layout.addWidget(self.placeholder_label)
25 self.tree = QTreeWidget()
26 self.tree.setHeaderHidden(True)
27 layout.addWidget(self.tree)
28 self.tree.setVisible(False)
30 def refresh(self, dataset, project):
31 """dataset は None でもよい。project は祖先を辿るのに使う。"""
32 self.tree.clear()
33 if dataset is None:
34 self.tree.setVisible(False)
35 self.placeholder_label.setVisible(True)
36 return
38 self.placeholder_label.setVisible(False)
39 self.tree.setVisible(True)
41 root_item = QTreeWidgetItem([dataset.name])
42 self.tree.addTopLevelItem(root_item)
43 self._add_provenance_children(root_item, dataset, project, frozenset())
44 self.tree.expandAll()
46 def _add_provenance_children(self, parent_item, dataset, project, visited):
47 """dataset を作った操作と元のデータセットを parent_item の下に足し、元も辿る。visited で循環を止める。"""
48 if dataset is None or not dataset.provenance or dataset.dataset_id in visited:
49 return
50 visited = visited | {dataset.dataset_id}
52 operation_item = QTreeWidgetItem([describe_operation(dataset.provenance)])
53 parent_item.addChild(operation_item)
55 source_ids = dataset.provenance.get('source_dataset_ids') or []
56 source_names = dataset.provenance.get('source_dataset_names') or []
57 for i, source_id in enumerate(source_ids):
58 source_dataset = next((ds for ds in project.datasets if ds.dataset_id == source_id), None)
59 fallback_name = source_names[i] if i < len(source_names) else "不明"
60 if source_dataset is None:
61 operation_item.addChild(QTreeWidgetItem([f"{fallback_name}(削除済み)"]))
62 continue
63 source_item = QTreeWidgetItem([source_dataset.name])
64 operation_item.addChild(source_item)
65 self._add_provenance_children(source_item, source_dataset, project, visited)