diff --git a/src/Model/AdditionalFile/AddFile.py b/src/Model/AdditionalFile/AddFile.py new file mode 100644 index 0000000000000000000000000000000000000000..640992055ca63fabaf560e80839cf96addb469eb --- /dev/null +++ b/src/Model/AdditionalFile/AddFile.py @@ -0,0 +1,148 @@ +# AddFile.py -- Pamhyr +# Copyright (C) 2024 INRAE +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see <https://www.gnu.org/licenses/>. + +# -*- coding: utf-8 -*- + +from functools import reduce + +from tools import trace, timer + +from Model.Tools.PamhyrDB import SQLSubModel +from Model.Except import NotImplementedMethodeError + + +class AddFile(SQLSubModel): + _sub_classes = [] + _id_cnt = 0 + + def __init__(self, id: int = -1, enabled=True, + name="", path="", text="", + status=None): + super(AddFile, self).__init__() + + if id == -1: + self.id = AddFile._id_cnt + else: + self.id = id + + self._status = status + + self._enabled = enabled + self._name = f"File {self.id}" if name == "" else name + self._path = path + self._text = text + + AddFile._id_cnt = max(id, AddFile._id_cnt+1) + + @property + def enabled(self): + return self._enabled + + @enabled.setter + def enabled(self, enabled): + self._enabled = enabled + + def is_enabled(self): + return self._enabled + + @property + def name(self): + return self._name + + @name.setter + def name(self, name): + self._name = name + + @property + def path(self): + return self._path + + @path.setter + def path(self, path): + self._path = path + + @property + def text(self): + return self._text + + @text.setter + def text(self, text): + self._text = text + + @classmethod + def _db_create(cls, execute): + execute(""" + CREATE TABLE additional_files( + id INTEGER NOT NULL PRIMARY KEY, + enabled BOOLEAN NOT NULL, + name TEXT NOT NULL, + path TEXT NOT NULL, + text TEXT NOT NULL + ) + """) + + return cls._create_submodel(execute) + + @classmethod + def _db_update(cls, execute, version): + major, minor, release = version.strip().split(".") + if major == minor == "0": + if int(release) < 8: + cls._db_create(execute) + + return True + + @classmethod + def _db_load(cls, execute, data=None): + new = [] + + table = execute( + "SELECT id, enabled, name, path, text " + + "FROM additional_files" + ) + + for row in table: + it = iter(row) + + id = next(it) + enabled = (next(it) == 1) + name = next(it) + path = next(it) + text = next(it) + + f = cls( + id=id, enabled=enabled, name=name, path=path, text=text, + status=data['status'] + ) + + new.append(f) + + return new + + def _db_save(self, execute, data=None): + sql = ( + "INSERT INTO " + + "additional_files(id, enabled, name, path, text) " + + "VALUES (" + + f"{self.id}, {self._enabled}, " + + f"'{self._db_format(self._name)}', " + + f"'{self._db_format(self._path)}', " + + f"'{self._db_format(self._text)}'" + + ")" + ) + execute(sql) + + return True diff --git a/src/Model/AdditionalFile/AddFileList.py b/src/Model/AdditionalFile/AddFileList.py new file mode 100644 index 0000000000000000000000000000000000000000..8d28e21194a052351af4f961d282adcb09b35ea3 --- /dev/null +++ b/src/Model/AdditionalFile/AddFileList.py @@ -0,0 +1,56 @@ +# AddFileList.py -- Pamhyr +# Copyright (C) 2024 INRAE +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see <https://www.gnu.org/licenses/>. + +# -*- coding: utf-8 -*- + +from tools import trace, timer + +from Model.Except import NotImplementedMethodeError +from Model.Tools.PamhyrList import PamhyrModelList +from Model.AdditionalFile.AddFile import AddFile + + +class AddFileList(PamhyrModelList): + _sub_classes = [AddFile] + + @classmethod + def _db_load(cls, execute, data=None): + new = cls(status=data["status"]) + + new._lst = AddFile._db_load(execute, data) + + return new + + def _db_save(self, execute, data=None): + ok = True + + # Delete previous data + execute("DELETE FROM additional_files") + + for af in self._lst: + ok &= af._db_save(execute, data) + + return ok + + @property + def files(self): + return self.lst + + def new(self, index): + n = AddFile(status=self._status) + self.insert(index, n) + self._status.modified() + return n diff --git a/src/Model/River.py b/src/Model/River.py index 80da45f4af8b51fb67db900305a560135a104013..41d4e0d82d4c7ee72cabc2074a499564a733209b 100644 --- a/src/Model/River.py +++ b/src/Model/River.py @@ -40,6 +40,7 @@ from Model.Reservoir.ReservoirList import ReservoirList from Model.HydraulicStructures.HydraulicStructuresList import ( HydraulicStructureList, ) +from Model.AdditionalFile.AddFileList import AddFileList from Solver.Solvers import solver_type_list @@ -224,6 +225,7 @@ class River(Graph, SQLSubModel): SedimentLayerList, ReservoirList, HydraulicStructureList, + AddFileList, ] def __init__(self, status=None): @@ -245,6 +247,7 @@ class River(Graph, SQLSubModel): self._hydraulic_structures = HydraulicStructureList( status=self._status ) + self._additional_files = AddFileList(status=self._status) @classmethod def _db_create(cls, execute): @@ -263,64 +266,59 @@ class River(Graph, SQLSubModel): # Stricklers (Stricklers is load in first because it's needed # for reachs) new._stricklers = StricklersList._db_load( - execute, - data + execute, data ) data["stricklers"] = new._stricklers # Initial conditions new._sediment_layers = SedimentLayerList._db_load( - execute, - data + execute, data ) data["sediment_layers_list"] = new._sediment_layers # Network new._nodes = RiverNode._db_load( - execute, - data + execute, data ) data["nodes"] = new.nodes() new._edges = RiverReach._db_load( - execute, - data + execute, data ) data["edges"] = new.edges() # Boundary Condition new._boundary_condition = BoundaryConditionList._db_load( - execute, - data + execute, data ) # Lateral Contribution new._lateral_contribution = LateralContributionList._db_load( - execute, - data + execute, data ) # Initial conditions new._initial_conditions = InitialConditionsDict._db_load( - execute, - data + execute, data ) # Reservoir new._reservoir = ReservoirList._db_load( - execute, - data + execute, data ) # Hydraulic Structures new._hydraulic_structures = HydraulicStructureList._db_load( - execute, - data + execute, data ) # Parameters new._parameters = SolverParametersList._db_load( - execute, - data + execute, data + ) + + # Additional Files + new._additional_files = AddFileList._db_load( + execute, data ) return new @@ -336,6 +334,7 @@ class River(Graph, SQLSubModel): objs.append(self._stricklers) objs.append(self._reservoir) objs.append(self._hydraulic_structures) + objs.append(self._additional_files) for solver in self._parameters: objs.append(self._parameters[solver]) @@ -373,11 +372,27 @@ class River(Graph, SQLSubModel): logger_exception(e) def init_default(self): + self.init_default_network() + self.init_default_additional_files() + + def init_default_network(self): n1 = self.add_node(880.0, 950.0) n2 = self.add_node(1120.0, 1020.0) e = self.add_edge(n1, n2) + def init_default_additional_files(self): + add_file = self._additional_files.new(0) + add_file.name = "Pamhyr2 stamp file" + add_file.path = "Pamhyr2.txt" + add_file.text = """This repository has been generated by Pamhyr2 \ +version "@version" ! + +All hand made file modification could be erased by the next solver +execution... + +Last export at: @date.""" + @property def boundary_condition(self): return self._boundary_condition @@ -419,6 +434,10 @@ class River(Graph, SQLSubModel): def hydraulic_structures(self): return self._hydraulic_structures + @property + def additional_files(self): + return self._additional_files + @property def parameters(self): return self._parameters diff --git a/src/Model/Study.py b/src/Model/Study.py index 2b8a859c9ad59d8fefbe1714040aaed697e8e0c5..d9167d1946ce4923ae361fe316c96a0164afed21 100644 --- a/src/Model/Study.py +++ b/src/Model/Study.py @@ -41,7 +41,7 @@ class Study(SQLModel): def __init__(self, filename=None, init_new=True): # Metadata - self._version = "0.0.7" + self._version = "0.0.8" self.creation_date = datetime.now() self.last_modification_date = datetime.now() self.last_save_date = datetime.now() diff --git a/src/Modules.py b/src/Modules.py index 2c4d8f6b709544bc5e2fb5c33c2d359fc41edbc0..90881369db6d16b169a101dbdc5236d3e9be85e6 100644 --- a/src/Modules.py +++ b/src/Modules.py @@ -40,6 +40,7 @@ class Modules(Flag): HYDRAULIC_STRUCTURES = auto() RESERVOIR = auto() SEDIMENT_LAYER = auto() + ADDITIONAL_FILES = auto() # Results RESULTS = auto() diff --git a/src/Solver/CommandLine.py b/src/Solver/CommandLine.py index 6066e0c8d34f13f81f07a04aaa8ec9eecd7b218c..e93d4e9845764f06a8b233aa639d16963c412ae5 100644 --- a/src/Solver/CommandLine.py +++ b/src/Solver/CommandLine.py @@ -19,7 +19,8 @@ import os import logging -from tools import timer, parse_command_line +from datetime import datetime +from tools import timer, parse_command_line, get_version try: # Installation allow Unix-like signal @@ -124,6 +125,39 @@ class CommandLineSolver(AbstractSolver): """ raise NotImplementedMethodeError(self, self.log_file) + def export_additional_files(self, study, repertory, qlog, name="0"): + files = [] + + if qlog is not None: + qlog.put("Export additional files") + + files = study.river.additional_files.files + for add_file in files: + self.export_additional_file( + add_file, repertory, files + ) + + def export_additional_file(self, add_file, repertory, files): + if add_file.path == "" or not add_file.is_enabled(): + return files + + path = os.path.join(repertory, add_file.path) + os.makedirs( + os.path.dirname(path), + exist_ok=True + ) + + with open(path, "w+") as f: + files.append(add_file.path) + + txt = add_file.text + txt = txt.replace("@version", get_version()) + txt = txt.replace("@date", datetime.now().isoformat(sep=" ")) + + f.write(txt) + + return files + ####### # Run # ####### diff --git a/src/Solver/Mage.py b/src/Solver/Mage.py index e4754ccbb474291b07f30096ea4db69c90064bd0..51f7d65668aef8a7e9c39d5e53e40abeea98b5a3 100644 --- a/src/Solver/Mage.py +++ b/src/Solver/Mage.py @@ -671,6 +671,7 @@ class Mage(CommandLineSolver): self._bin_file = f"{name}.BIN" self._export_ST(study, repertory, qlog, name=name) + self.export_additional_files(study, repertory, qlog, name=name) return True @@ -886,6 +887,10 @@ class Mage8(Mage): files = files + self._export_VAR(study, repertory, qlog, name=name) files = files + self._export_CAS(study, repertory, qlog, name=name) files = files + self._export_DEV(study, repertory, qlog, name=name) + files = files + self.export_additional_files( + study, repertory, qlog, name=name + ) + self._export_REP(study, repertory, files, qlog, name=name) return True diff --git a/src/View/AdditionalFiles/Edit/Window.py b/src/View/AdditionalFiles/Edit/Window.py new file mode 100644 index 0000000000000000000000000000000000000000..6db27942a885a21858def1b5e3b0fcec1791b38e --- /dev/null +++ b/src/View/AdditionalFiles/Edit/Window.py @@ -0,0 +1,80 @@ +# Window.py -- Pamhyr +# Copyright (C) 2024 INRAE +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see <https://www.gnu.org/licenses/>. + +# -*- coding: utf-8 -*- + +import logging + +from Modules import Modules +from View.Tools.PamhyrWindow import PamhyrWindow + +from PyQt5.QtWidgets import ( + QLabel, QPlainTextEdit, QPushButton, + QCheckBox, +) + +from View.AdditionalFiles.Translate import AddFileTranslate + +logger = logging.getLogger() + + +class EditAddFileWindow(PamhyrWindow): + _pamhyr_ui = "AdditionalFile" + _pamhyr_name = "Edit additional file" + + def __init__(self, study=None, config=None, add_file=None, + trad=None, parent=None): + + name = trad[self._pamhyr_name] + " - " + study.name + super(EditAddFileWindow, self).__init__( + title=name, + study=study, + config=config, + options=[], + parent=parent + ) + + self._add_file = add_file + self._hash_data.append(self._add_file) + + self.setup_values() + self.setup_connection() + + def setup_values(self): + self.set_check_box("checkBox", self._add_file.enabled) + self.set_line_edit_text("lineEdit_name", self._add_file.name) + self.set_line_edit_text("lineEdit_path", self._add_file.path) + self.set_plaintext_edit_text("plainTextEdit", self._add_file.text) + + def setup_connection(self): + self.find(QPushButton, "pushButton_cancel")\ + .clicked.connect(self.close) + self.find(QPushButton, "pushButton_ok")\ + .clicked.connect(self.accept) + + def accept(self): + is_enabled = self.get_check_box("checkBox") + name = self.get_line_edit_text("lineEdit_name") + path = self.get_line_edit_text("lineEdit_path") + text = self.get_plaintext_edit_text("plainTextEdit") + + self._add_file.enabled = is_enabled + self._add_file.name = name + self._add_file.path = path + self._add_file.text = text + + self._propagate_update(key=Modules.ADDITIONAL_FILES) + self.close() diff --git a/src/View/AdditionalFiles/List.py b/src/View/AdditionalFiles/List.py new file mode 100644 index 0000000000000000000000000000000000000000..374ce54c672fa3ecff0094f1f777e12f0b4b54f2 --- /dev/null +++ b/src/View/AdditionalFiles/List.py @@ -0,0 +1,71 @@ +# List.py -- Pamhyr +# Copyright (C) 2024 INRAE +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see <https://www.gnu.org/licenses/>. + +# -*- coding: utf-8 -*- + +import logging + +from functools import reduce +from tools import trace, timer + +from PyQt5.QtCore import ( + Qt, QVariant, +) + +from PyQt5.QtGui import ( + QColor, QBrush, +) + +from View.Tools.PamhyrList import PamhyrListModel + +logger = logging.getLogger() + + +class ListModel(PamhyrListModel): + def data(self, index, role): + row = index.row() + column = index.column() + + file = self._data.files[row] + + if role == Qt.ForegroundRole: + color = Qt.gray + + if file.is_enabled(): + color = QColor("black") + else: + color = QColor("grey") + + return QBrush(color) + + if role == Qt.ItemDataRole.DisplayRole: + text = f"{file.name}: '{file.path}'" + + if not file.is_enabled(): + text += " (disabled)" + + return text + + return QVariant() + + def add(self, row): + self._data.new(row) + self.update() + + def delete(self, rows): + logger.info(f"add_files: delete {rows}") + self._data.delete_i(rows) + self.update() diff --git a/src/View/AdditionalFiles/Translate.py b/src/View/AdditionalFiles/Translate.py new file mode 100644 index 0000000000000000000000000000000000000000..3df7d3397671be458f75b58532c7a5159f2f05fc --- /dev/null +++ b/src/View/AdditionalFiles/Translate.py @@ -0,0 +1,35 @@ +# Translate.py -- Pamhyr +# Copyright (C) 2024 INRAE +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see <https://www.gnu.org/licenses/>. + +# -*- coding: utf-8 -*- + +from PyQt5.QtCore import QCoreApplication +from View.Translate import MainTranslate + +_translate = QCoreApplication.translate + + +class AddFileTranslate(MainTranslate): + def __init__(self): + super(AddFileTranslate, self).__init__() + + self._dict["Additional files"] = _translate( + "AdditionalFiles", "Additional files" + ) + + self._dict["Edit additional file"] = _translate( + "AdditionalFiles", "Edit additional file" + ) diff --git a/src/View/AdditionalFiles/Window.py b/src/View/AdditionalFiles/Window.py new file mode 100644 index 0000000000000000000000000000000000000000..6cd84203030dd8ed8c1fb861edeb904bc77c07bf --- /dev/null +++ b/src/View/AdditionalFiles/Window.py @@ -0,0 +1,104 @@ +# Window.py -- Pamhyr +# Copyright (C) 2024 INRAE +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see <https://www.gnu.org/licenses/>. + +# -*- coding: utf-8 -*- + +from tools import trace, timer + +from PyQt5.QtWidgets import ( + QAction, QListView, +) + +from View.Tools.PamhyrWindow import PamhyrWindow + +from View.AdditionalFiles.List import ListModel +from View.AdditionalFiles.Translate import AddFileTranslate +from View.AdditionalFiles.Edit.Window import EditAddFileWindow + + +class AddFileListWindow(PamhyrWindow): + _pamhyr_ui = "AdditionalFileList" + _pamhyr_name = "Additional files" + + def __init__(self, study=None, config=None, + parent=None): + trad = AddFileTranslate() + name = trad[self._pamhyr_name] + " - " + study.name + + super(AddFileListWindow, self).__init__( + title=name, + study=study, + config=config, + trad=trad, + options=[], + parent=parent + ) + + self.setup_list() + self.setup_connections() + + def setup_list(self): + lst = self.find(QListView, f"listView") + self._list = ListModel( + list_view=lst, + data=self._study.river.additional_files, + ) + + def setup_connections(self): + self.find(QAction, "action_add").triggered.connect(self.add) + self.find(QAction, "action_delete").triggered.connect(self.delete) + self.find(QAction, "action_edit").triggered.connect(self.edit) + + def update(self): + self._list.update() + + def selected_rows(self): + lst = self.find(QListView, f"listView") + return list(map(lambda i: i.row(), lst.selectedIndexes())) + + def add(self): + rows = self.selected_rows() + if len(rows) > 0: + row = rows[0] + else: + row = 0 + + self._list.add(row) + + def delete(self): + rows = self.selected_rows() + self._list.delete(rows) + + def edit(self): + rows = self.selected_rows() + + for row in rows: + add_file = self._study.river.additional_files.files[row] + + if self.sub_window_exists( + EditAddFileWindow, + data=[self._study, self._config, add_file] + ): + continue + + win = EditAddFileWindow( + study=self._study, + config=self._config, + add_file=add_file, + trad=self._trad, + parent=self, + ) + win.show() diff --git a/src/View/MainWindow.py b/src/View/MainWindow.py index 496c894cedba3f77ec1d3174f62c43a4e8883191..836f6d7e5df12b3baba894b61eef0c0d083d2a9a 100644 --- a/src/View/MainWindow.py +++ b/src/View/MainWindow.py @@ -67,6 +67,7 @@ from View.Stricklers.Window import StricklersWindow from View.Frictions.Window import FrictionsWindow from View.SedimentLayers.Window import SedimentLayersWindow from View.SedimentLayers.Reach.Window import ReachSedimentLayersWindow +from View.AdditionalFiles.Window import AddFileListWindow from View.SolverParameters.Window import SolverParametersWindow from View.RunSolver.Window import SelectSolverWindow, SolverLogWindow from View.CheckList.Window import CheckListWindow @@ -117,7 +118,7 @@ define_model_action = [ "action_menu_edit_friction", "action_menu_edit_lateral_contribution", "action_menu_run_solver", "action_menu_sediment_layers", "action_menu_edit_reach_sediment_layers", "action_menu_edit_reservoirs", - "action_menu_edit_hydraulic_structures", + "action_menu_edit_hydraulic_structures", "action_menu_additional_file", "action_menu_results_last", "action_open_results_from_file", "action_menu_boundary_conditions_sediment", ] @@ -252,6 +253,7 @@ class ApplicationWindow(QMainWindow, ListedSubWindow, WindowToolKit): "action_menu_sediment_layers": self.open_sediment_layers, "action_menu_edit_reach_sediment_layers": self.open_reach_sediment_layers, + "action_menu_additional_file": self.open_additional_files, "action_menu_close": self.close_model, "action_menu_results_last": self.open_last_results, "action_open_results_from_file": self.open_results_from_file, @@ -1063,6 +1065,19 @@ class ApplicationWindow(QMainWindow, ListedSubWindow, WindowToolKit): else: self.msg_select_reach() + def open_additional_files(self): + if self._study is not None: + if self.sub_window_exists( + AddFileListWindow, + data=[self._study, None] + ): + return + + self.additonal_files = AddFileListWindow( + study=self._study, parent=self + ) + self.additonal_files.show() + def open_solver_parameters(self): if self.sub_window_exists( SolverParametersWindow, diff --git a/src/View/ui/AdditionalFile.ui b/src/View/ui/AdditionalFile.ui new file mode 100644 index 0000000000000000000000000000000000000000..b4419c420c8560ca5952ef71a0916a5062d65df1 --- /dev/null +++ b/src/View/ui/AdditionalFile.ui @@ -0,0 +1,112 @@ +<?xml version="1.0" encoding="UTF-8"?> +<ui version="4.0"> + <class>MainWindow</class> + <widget class="QMainWindow" name="MainWindow"> + <property name="geometry"> + <rect> + <x>0</x> + <y>0</y> + <width>896</width> + <height>504</height> + </rect> + </property> + <property name="windowTitle"> + <string>MainWindow</string> + </property> + <property name="locale"> + <locale language="English" country="Europe"/> + </property> + <widget class="QWidget" name="centralwidget"> + <layout class="QGridLayout" name="gridLayout_3"> + <item row="2" column="1"> + <layout class="QHBoxLayout" name="horizontalLayout"> + <item> + <spacer name="horizontalSpacer"> + <property name="orientation"> + <enum>Qt::Horizontal</enum> + </property> + <property name="sizeHint" stdset="0"> + <size> + <width>40</width> + <height>20</height> + </size> + </property> + </spacer> + </item> + <item> + <widget class="QPushButton" name="pushButton_cancel"> + <property name="text"> + <string>Cancel</string> + </property> + </widget> + </item> + <item> + <widget class="QPushButton" name="pushButton_ok"> + <property name="text"> + <string>Ok</string> + </property> + </widget> + </item> + </layout> + </item> + <item row="1" column="0" colspan="2"> + <widget class="QGroupBox" name="groupBox_2"> + <property name="title"> + <string>File text</string> + </property> + <layout class="QGridLayout" name="gridLayout_2"> + <item row="0" column="0"> + <widget class="QPlainTextEdit" name="plainTextEdit"/> + </item> + </layout> + </widget> + </item> + <item row="0" column="0" colspan="2"> + <widget class="QGroupBox" name="groupBox"> + <property name="title"> + <string>Information</string> + </property> + <layout class="QGridLayout" name="gridLayout"> + <item row="2" column="0"> + <widget class="QCheckBox" name="checkBox"> + <property name="text"> + <string>Enabled</string> + </property> + <property name="checked"> + <bool>true</bool> + </property> + </widget> + </item> + <item row="1" column="1"> + <widget class="QLineEdit" name="lineEdit_path"> + <property name="toolTip"> + <string>The relative file path on executable directory</string> + </property> + </widget> + </item> + <item row="0" column="1"> + <widget class="QLineEdit" name="lineEdit_name"/> + </item> + <item row="0" column="0"> + <widget class="QLabel" name="label"> + <property name="text"> + <string>Name</string> + </property> + </widget> + </item> + <item row="1" column="0"> + <widget class="QLabel" name="label_2"> + <property name="text"> + <string>Path</string> + </property> + </widget> + </item> + </layout> + </widget> + </item> + </layout> + </widget> + </widget> + <resources/> + <connections/> +</ui> diff --git a/src/View/ui/AdditionalFileList.ui b/src/View/ui/AdditionalFileList.ui new file mode 100644 index 0000000000000000000000000000000000000000..45da9fc62b5bd0dec367472637f176e96e2d1747 --- /dev/null +++ b/src/View/ui/AdditionalFileList.ui @@ -0,0 +1,76 @@ +<?xml version="1.0" encoding="UTF-8"?> +<ui version="4.0"> + <class>MainWindow</class> + <widget class="QMainWindow" name="MainWindow"> + <property name="geometry"> + <rect> + <x>0</x> + <y>0</y> + <width>896</width> + <height>504</height> + </rect> + </property> + <property name="windowTitle"> + <string>MainWindow</string> + </property> + <widget class="QWidget" name="centralwidget"> + <layout class="QGridLayout" name="gridLayout"> + <item row="0" column="0"> + <widget class="QListView" name="listView"/> + </item> + </layout> + </widget> + <widget class="QToolBar" name="toolBar"> + <property name="windowTitle"> + <string>toolBar</string> + </property> + <attribute name="toolBarArea"> + <enum>TopToolBarArea</enum> + </attribute> + <attribute name="toolBarBreak"> + <bool>false</bool> + </attribute> + <addaction name="action_add"/> + <addaction name="action_delete"/> + <addaction name="action_edit"/> + </widget> + <action name="action_add"> + <property name="icon"> + <iconset> + <normaloff>ressources/gtk-add.png</normaloff>ressources/gtk-add.png</iconset> + </property> + <property name="text"> + <string>Add</string> + </property> + <property name="toolTip"> + <string>Add a new file</string> + </property> + </action> + <action name="action_delete"> + <property name="icon"> + <iconset> + <normaloff>ressources/gtk-remove.png</normaloff>ressources/gtk-remove.png</iconset> + </property> + <property name="text"> + <string>Delete</string> + </property> + <property name="toolTip"> + <string>Delete selected file(s)</string> + </property> + </action> + <action name="action_edit"> + <property name="icon"> + <iconset> + <normaloff>ressources/edit.png</normaloff>ressources/edit.png</iconset> + </property> + <property name="text"> + <string>Edit</string> + </property> + <property name="toolTip"> + <string>Edit file</string> + </property> + </action> + </widget> + <resources/> + <connections/> +</ui> diff --git a/src/View/ui/MainWindow.ui b/src/View/ui/MainWindow.ui index 3f6d6bdd0881bef2d1407dfa262e3924d67239ed..35e05ab619450f5b0a10e13b1190e3e1303e13c3 100644 --- a/src/View/ui/MainWindow.ui +++ b/src/View/ui/MainWindow.ui @@ -204,11 +204,18 @@ <string>&Windows</string> </property> </widget> + <widget class="QMenu" name="menu_Avensed"> + <property name="title"> + <string>&Advansed</string> + </property> + <addaction name="action_menu_additional_file"/> + </widget> <addaction name="menu_File"/> <addaction name="menu_network"/> <addaction name="menu_geometry"/> <addaction name="menu_Hydraulics"/> <addaction name="menuSediment"/> + <addaction name="menu_Avensed"/> <addaction name="menu_run"/> <addaction name="menu_results"/> <addaction name="menu_cartography"/> @@ -988,6 +995,11 @@ <string>Boundary conditions and punctual contributions</string> </property> </action> + <action name="action_menu_additional_file"> + <property name="text"> + <string>&Additional file</string> + </property> + </action> </widget> <resources/> <connections> diff --git a/src/tools.py b/src/tools.py index 60e4ee9fb90e53483be40be2178ae834cc58cf1e..ae8da822c460f15e3a009ec56ebe475b4bc87c9b 100644 --- a/src/tools.py +++ b/src/tools.py @@ -279,10 +279,20 @@ def get_user_name(): return "Me" +def get_version(): + with open(os.path.abspath( + os.path.join( + os.path.dirname(__file__), + "VERSION" + ) + ), "r") as f: + return f.readline().strip() + ####################### # COMMAND LINE PARSER # ####################### + parser_special_char = ["\"", "\'"]