From 63592b91a9cccba5e0ec1ed46f0e91684b63a485 Mon Sep 17 00:00:00 2001 From: Pierre-Antoine Rouby Date: Fri, 25 Sep 2026 11:46:37 +0200 Subject: [PATCH] Ensemble: Add Export/Import method with json files. --- src/Model/Ensembles/Ensemble.py | 15 ++++-- src/Model/Ensembles/EnsembleList.py | 9 ++++ src/View/Ensembles/UndoCommand.py | 27 ++++++++++ src/View/Ensembles/Window.py | 78 ++++++++++++++++++++++++++++- src/View/Tools/ASubWindow.py | 2 +- src/View/Translate.py | 3 ++ src/View/ui/Ensembles.ui | 27 ++++++++++ 7 files changed, 156 insertions(+), 5 deletions(-) diff --git a/src/Model/Ensembles/Ensemble.py b/src/Model/Ensembles/Ensemble.py index 37eaa970..6dcad248 100644 --- a/src/Model/Ensembles/Ensemble.py +++ b/src/Model/Ensembles/Ensemble.py @@ -253,12 +253,21 @@ class Ensemble(SQLSubModel): self._target_data = target_data self._status.modified() - def get_data_dict(self): + def get_data_dict(self, use_ids=False): + target_data = self.target_data + distribution = self.distribution + + if use_ids: + if self.target_data: + target_data = self.target_data.pamhyr_id + if self.distribution: + distribution = self.distribution.name + return { "name": self.name, "data_type": self.data_type, - "target_data": self.target_data, - "distribution": self.distribution, + "target_data": target_data, + "distribution": distribution, "params": self.params, } diff --git a/src/Model/Ensembles/EnsembleList.py b/src/Model/Ensembles/EnsembleList.py index 364a7c94..b62bbe83 100644 --- a/src/Model/Ensembles/EnsembleList.py +++ b/src/Model/Ensembles/EnsembleList.py @@ -51,3 +51,12 @@ class EnsembleList(PamhyrModelList): self._lst.insert(index, r) self._status.modified() return r + + def new_with_data(self, index, data): + r = Ensemble(status=self._status) + + r.set_data_dict(data) + + self._lst.insert(index, r) + self._status.modified() + return r diff --git a/src/View/Ensembles/UndoCommand.py b/src/View/Ensembles/UndoCommand.py index 542eda05..5c2db8a0 100644 --- a/src/View/Ensembles/UndoCommand.py +++ b/src/View/Ensembles/UndoCommand.py @@ -114,6 +114,33 @@ class AddCommand(QUndoCommand): else: self._ensembles.insert(self._index, self._new) +class ImportCommand(QUndoCommand): + def __init__(self, ensembles, data, index): + QUndoCommand.__init__(self) + + self._ensembles = ensembles + self._index = index + self._data = data + self._news = None + + def undo(self): + for new in self._news: + new.set_as_deleted() + + def redo(self): + if self._news is None: + self._news = list( + map( + lambda d: self._ensembles.new_with_data( + self._index, d + ), + self._data, + ) + ) + else: + for new in self._news: + new.set_as_not_deleted() + class DelCommand(QUndoCommand): def __init__(self, ensembles, rows): diff --git a/src/View/Ensembles/Window.py b/src/View/Ensembles/Window.py index 60dba0b5..ca5785ed 100644 --- a/src/View/Ensembles/Window.py +++ b/src/View/Ensembles/Window.py @@ -17,6 +17,7 @@ # -*- coding: utf-8 -*- import logging +import json from tools import trace, timer, logger_exception @@ -47,7 +48,7 @@ from View.Ensembles.Table import ( EnsembleTableModel, ComboBoxDelegate ) from View.Ensembles.Translate import EnsemblesTranslate -from View.Ensembles.UndoCommand import SetAllCommand +from View.Ensembles.UndoCommand import SetAllCommand, ImportCommand logger = logging.getLogger() @@ -140,6 +141,12 @@ class EnsemblesWindow(PamhyrWindow): self.find(QAction, "action_add").triggered.connect(self.add) self.find(QAction, "action_del").triggered.connect(self.delete) self.find(QAction, "action_edit").triggered.connect(self.edit) + self.find(QAction, "action_export").triggered.connect( + self.export_to_json + ) + self.find(QAction, "action_import").triggered.connect( + self.import_from_json + ) table = self.find(QTableView, f"tableView") table.selectionModel()\ @@ -204,6 +211,75 @@ class EnsemblesWindow(PamhyrWindow): logger_exception(e) return + def export_to_json(self): + ens = [] + for e in self._ensembles.lst: + ens.append(e.get_data_dict(use_ids=True)) + + data = {"ensembles" : ens} + + def aux(filename): + with open(filename[0], 'w') as f: + f.write(json.dumps(data)) + + self.file_dialog( + select_file=None, + callback=aux, + default_suffix='.json', + file_filter=[self._trad["file_json"]] + ) + + def import_from_json(self): + def aux(filename): + with open(filename[0], 'r') as f: + return json.load(f) + + data = self.file_dialog( + select_file=None, + callback=aux, + default_suffix='.json', + file_filter=[self._trad["file_json"]] + ) + + dtarget = dict( + map( + lambda s: (s.pamhyr_id, s), + self._study.river.stricklers.stricklers + ) + ) + + ddistr = dict( + map( + lambda d: (d.name, d), + self._study._ens_distributions.lst + ) + ) + + def update(d, values): + d.update(values) + return d + + updated = list( + map( + lambda d: update( + d, {"target_data": dtarget[d["target_data"]]} + ), + map( + lambda d: update( + d, {"distribution": ddistr[d["distribution"]]} + ), + data["ensembles"] + ) + ) + ) + + self._undo_stack.push( + ImportCommand( + self._ensembles, updated, 0 + ) + ) + self._table.update() + class Ensemble1ParamsDialog(PamhyrDialog): _pamhyr_ui = "Ensemble1ParamsDialog" diff --git a/src/View/Tools/ASubWindow.py b/src/View/Tools/ASubWindow.py index 965dcf9e..5558a742 100644 --- a/src/View/Tools/ASubWindow.py +++ b/src/View/Tools/ASubWindow.py @@ -107,7 +107,7 @@ class WindowToolKit(object): dialog = QFileDialog(self, options=options) - if select_file == "Existing_file": + if select_file == "ExistingFile": mode = QFileDialog.FileMode.ExistingFile elif select_file == "Directory": mode = QFileDialog.FileMode.Directory diff --git a/src/View/Translate.py b/src/View/Translate.py index d890f626..bf9ecbe2 100644 --- a/src/View/Translate.py +++ b/src/View/Translate.py @@ -72,6 +72,9 @@ class CommonWordTranslate(PamhyrTranslate): self._dict["file_csv"] = _translate( "CommonWord", "CSV file (*.csv)" ) + self._dict["file_json"] = _translate( + "CommonWord", "JSON file (*.json)" + ) class UnitTranslate(CommonWordTranslate): diff --git a/src/View/ui/Ensembles.ui b/src/View/ui/Ensembles.ui index a88796c4..6de49991 100644 --- a/src/View/ui/Ensembles.ui +++ b/src/View/ui/Ensembles.ui @@ -33,6 +33,9 @@ + + + @@ -79,6 +82,30 @@ QAction::NoRole + + + + ressources/export.pngressources/export.png + + + Export + + + Export all ensemble configuration into json file + + + + + + ressources/import.pngressources/import.png + + + Import + + + Import ensemble configuration from json file + +