mirror of
https://gitlab.com/pamhyr/pamhyr2.git
synced 2026-10-29 19:10:42 +01:00
Merge branch 'doc-dev' with refactoring and user/dev documentation.
This commit is contained in:
commit
44b057c522
117 files changed
+3813
-3160
No files matched your search
@@ -98,6 +98,8 @@ build-users-doc:
|
|||||||
artifacts:
|
artifacts:
|
||||||
paths:
|
paths:
|
||||||
- doc/users/documentation.pdf
|
- doc/users/documentation.pdf
|
||||||
|
- doc/users/documentation.html
|
||||||
|
- doc/users/images/
|
||||||
|
|
||||||
build-developers-doc:
|
build-developers-doc:
|
||||||
stage: build
|
stage: build
|
||||||
@@ -109,9 +111,19 @@ build-developers-doc:
|
|||||||
script:
|
script:
|
||||||
- cd ./doc/dev/
|
- cd ./doc/dev/
|
||||||
- ./build.sh
|
- ./build.sh
|
||||||
|
# Create html documentation
|
||||||
|
- cd ../../src
|
||||||
|
- pdoc --html .
|
||||||
|
# Create archive
|
||||||
|
- tar cf html.tar ./html
|
||||||
|
- cd ../doc/dev
|
||||||
|
- mv ../../src/html.tar ./
|
||||||
artifacts:
|
artifacts:
|
||||||
paths:
|
paths:
|
||||||
- doc/dev/documentation.pdf
|
- doc/dev/documentation.pdf
|
||||||
|
- doc/dev/documentation.html
|
||||||
|
- doc/dev/html.tar
|
||||||
|
- doc/dev/images/
|
||||||
|
|
||||||
build-linux:
|
build-linux:
|
||||||
stage: build
|
stage: build
|
||||||
@@ -167,8 +179,10 @@ build-linux:
|
|||||||
- cp ../tests_cases/Saar/Saar.pamhyr pamhyr/tests_cases/Saar/
|
- cp ../tests_cases/Saar/Saar.pamhyr pamhyr/tests_cases/Saar/
|
||||||
# Copy documentations
|
# Copy documentations
|
||||||
- mkdir -p pamhyr/doc/
|
- mkdir -p pamhyr/doc/
|
||||||
|
- mkdir -p pamhyr/doc/html/
|
||||||
- cp ../doc/users/documentation.pdf pamhyr/doc/Pamhyr2-users.pdf
|
- cp ../doc/users/documentation.pdf pamhyr/doc/Pamhyr2-users.pdf
|
||||||
- cp ../doc/dev/documentation.pdf pamhyr/doc/Pamhyr2-dev.pdf
|
- cp ../doc/dev/documentation.pdf pamhyr/doc/Pamhyr2-dev.pdf
|
||||||
|
- cp ../doc/dev/documentation.html pamhyr/doc/html/dev.html
|
||||||
# Create running script
|
# Create running script
|
||||||
- echo "#!/bin/sh" > pamhyr/Pamhyr2
|
- echo "#!/bin/sh" > pamhyr/Pamhyr2
|
||||||
- echo "./pamhyr/pamhyr $@" >> pamhyr/Pamhyr2
|
- echo "./pamhyr/pamhyr $@" >> pamhyr/Pamhyr2
|
||||||
|
|||||||
+11
-3
@@ -1,10 +1,18 @@
|
|||||||
#! /bin/sh
|
#! /bin/sh
|
||||||
|
|
||||||
# Build the PDF
|
echo " PDF documentation.org"
|
||||||
|
emacs -nw --batch \
|
||||||
emacs -Q -q -nw --batch \
|
|
||||||
--eval "(require 'org)" \
|
--eval "(require 'org)" \
|
||||||
--eval "(require 'ox-latex)" \
|
--eval "(require 'ox-latex)" \
|
||||||
--eval "(load-file \"../tools/setup.el\")" \
|
--eval "(load-file \"../tools/setup.el\")" \
|
||||||
--file ./documentation.org \
|
--file ./documentation.org \
|
||||||
-f org-latex-export-to-pdf
|
-f org-latex-export-to-pdf
|
||||||
|
|
||||||
|
echo " HTML documentation.org"
|
||||||
|
emacs -nw --batch \
|
||||||
|
--eval "(require 'org)" \
|
||||||
|
--eval "(require 'ox-latex)" \
|
||||||
|
--eval "(require 'ox-html)" \
|
||||||
|
--eval "(load-file \"../tools/setup.el\")" \
|
||||||
|
--file ./documentation.org \
|
||||||
|
-f org-html-export-to-html
|
||||||
+846
-117
File diff suppressed because it is too large.
Load diff
Binary file not shown.
|
After Width: | Height: | Size: 74 KiB |
+11
-3
@@ -1,10 +1,18 @@
|
|||||||
#! /bin/sh
|
#! /bin/sh
|
||||||
|
|
||||||
# Build the PDF
|
echo " PDF documentation.org"
|
||||||
|
emacs -nw --batch \
|
||||||
emacs -Q -q -nw --batch \
|
|
||||||
--eval "(require 'org)" \
|
--eval "(require 'org)" \
|
||||||
--eval "(require 'ox-latex)" \
|
--eval "(require 'ox-latex)" \
|
||||||
--eval "(load-file \"../tools/setup.el\")" \
|
--eval "(load-file \"../tools/setup.el\")" \
|
||||||
--file ./documentation.org \
|
--file ./documentation.org \
|
||||||
-f org-latex-export-to-pdf
|
-f org-latex-export-to-pdf
|
||||||
|
|
||||||
|
echo " HTML documentation.org"
|
||||||
|
emacs -nw --batch \
|
||||||
|
--eval "(require 'org)" \
|
||||||
|
--eval "(require 'ox-latex)" \
|
||||||
|
--eval "(require 'ox-html)" \
|
||||||
|
--eval "(load-file \"../tools/setup.el\")" \
|
||||||
|
--file ./documentation.org \
|
||||||
|
-f org-html-export-to-html
|
||||||
Whitespace-only changes.
+28
-13
@@ -43,18 +43,21 @@ cd $OLD_PWD
|
|||||||
|
|
||||||
echo " *** COPY DATA"
|
echo " *** COPY DATA"
|
||||||
|
|
||||||
mkdir -p dist/pamhyr/View/ui
|
mkdir -p dist/pamhyr/_internal/View/ui
|
||||||
mkdir -p dist/pamhyr/View/ui/Widgets
|
mkdir -p dist/pamhyr/_internal/View/ui/Widgets
|
||||||
cp -r ../src/View/ui/ressources/ dist/pamhyr/View/ui/
|
cp -r ../src/View/ui/ressources/ dist/pamhyr/_internal/View/ui/
|
||||||
cp -r ../src/View/ui/Widgets/*.ui dist/pamhyr/View/ui/Widgets/
|
cp -r ../src/View/ui/Widgets/*.ui dist/pamhyr/_internal/View/ui/Widgets/
|
||||||
cp -r ../src/View/ui/*.ui dist/pamhyr/View/ui/
|
cp -r ../src/View/ui/*.ui dist/pamhyr/_internal/View/ui/
|
||||||
|
|
||||||
mkdir -p dist/pamhyr/lang
|
mkdir -p dist/pamhyr/lang
|
||||||
cp -r ../src/lang/*.qm dist/pamhyr/lang/
|
cp -r ../src/lang/*.qm dist/pamhyr/lang/
|
||||||
|
|
||||||
cp ../VERSION dist/pamhyr/
|
mkdir dist/pamhyr/_internal/
|
||||||
cp ../AUTHORS dist/pamhyr/
|
#cp ../VERSION dist/pamhyr/_internal/
|
||||||
cp ../LICENSE dist/pamhyr/
|
VERSION=$(cat ../VERSION)
|
||||||
|
echo "local-build-$VERSION" > dist/pamhyr/_internal/VERSION
|
||||||
|
cp ../AUTHORS dist/pamhyr/_internal/
|
||||||
|
cp ../LICENSE dist/pamhyr/_internal/
|
||||||
|
|
||||||
mkdir -p dist/pamhyr/mage/
|
mkdir -p dist/pamhyr/mage/
|
||||||
cp ../mage/mage dist/pamhyr/mage/
|
cp ../mage/mage dist/pamhyr/mage/
|
||||||
@@ -65,6 +68,18 @@ mkdir -p dist/pamhyr/tests_cases/
|
|||||||
mkdir -p dist/pamhyr/tests_cases/Saar
|
mkdir -p dist/pamhyr/tests_cases/Saar
|
||||||
cp ../tests_cases/Saar/Saar.pamhyr dist/pamhyr/tests_cases/Saar/
|
cp ../tests_cases/Saar/Saar.pamhyr dist/pamhyr/tests_cases/Saar/
|
||||||
|
|
||||||
|
mkdir -p dist/pamhyr/doc/
|
||||||
|
cp ../doc/dev/documentation.pdf dist/pamhyr/doc/Pamhyr2-dev.pdf
|
||||||
|
cp ../doc/dev/documentation.html dist/pamhyr/doc/Pamhyr2-dev.html
|
||||||
|
|
||||||
|
cp ../doc/users/documentation.pdf dist/pamhyr/doc/Pamhyr2-users.pdf
|
||||||
|
cp ../doc/users/documentation.html dist/pamhyr/doc/Pamhyr2-users.html
|
||||||
|
|
||||||
|
mkdir -p dist/pamhyr/doc/images
|
||||||
|
cp ../doc/users/images/* dist/pamhyr/doc/images/
|
||||||
|
cp ../doc/dev/images/* dist/pamhyr/doc/images/
|
||||||
|
cp ../doc/images/* dist/pamhyr/doc/images/
|
||||||
|
|
||||||
echo " *** MAKE SRC PACKAGE"
|
echo " *** MAKE SRC PACKAGE"
|
||||||
|
|
||||||
OLD_PWD=$PWD
|
OLD_PWD=$PWD
|
||||||
@@ -76,11 +91,11 @@ mv ../pamhyr-src.tar.gz ./
|
|||||||
|
|
||||||
echo " *** MAKE BIN PACKAGE"
|
echo " *** MAKE BIN PACKAGE"
|
||||||
|
|
||||||
OLD_PWD=$PWD
|
# OLD_PWD=$PWD
|
||||||
cd dist/
|
# cd dist/
|
||||||
tar --xz -cf pamhyr-gnulinux-amd64.tar.xz pamhyr --checkpoint=.100
|
# tar --xz -cf pamhyr-gnulinux-amd64.tar.xz pamhyr --checkpoint=.100
|
||||||
cd $OLD_PWD
|
# cd $OLD_PWD
|
||||||
|
|
||||||
mv dist/pamhyr-gnulinux-amd64.tar.xz ./
|
# mv dist/pamhyr-gnulinux-amd64.tar.xz ./
|
||||||
|
|
||||||
echo " *** DONE"
|
echo " *** DONE"
|
||||||
+2
-1
@@ -1,6 +1,7 @@
|
|||||||
PyQt5==5.15.4
|
PyQt5==5.15.4
|
||||||
PyQt5-Qt5==5.15.2
|
PyQt5-Qt5==5.15.2
|
||||||
PyQt5-sip==12.8.1
|
PyQt5-sip==12.12.2
|
||||||
|
PyQtWebEngine==5.15.6
|
||||||
pyqtgraph>=0.12.1
|
pyqtgraph>=0.12.1
|
||||||
matplotlib>=3.4.1
|
matplotlib>=3.4.1
|
||||||
numpy>=1.24.2
|
numpy>=1.24.2
|
||||||
|
|||||||
@@ -56,6 +56,9 @@ class Profile(object):
|
|||||||
|
|
||||||
self._profile_type = _type
|
self._profile_type = _type
|
||||||
|
|
||||||
|
def __len__(self):
|
||||||
|
return len(self._points)
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def number_points(self):
|
def number_points(self):
|
||||||
return len(self._points)
|
return len(self._points)
|
||||||
|
|||||||
@@ -42,7 +42,7 @@ class Reach(SQLSubModel):
|
|||||||
]
|
]
|
||||||
|
|
||||||
def __init__(self, status=None, parent=None):
|
def __init__(self, status=None, parent=None):
|
||||||
self.id = parent.id
|
self.id = parent.id if parent is not None else 0
|
||||||
self._status = status
|
self._status = status
|
||||||
self._parent = parent
|
self._parent = parent
|
||||||
self._profiles: List[Profile] = []
|
self._profiles: List[Profile] = []
|
||||||
@@ -106,6 +106,9 @@ class Reach(SQLSubModel):
|
|||||||
|
|
||||||
return self._parent.name
|
return self._parent.name
|
||||||
|
|
||||||
|
def __len__(self):
|
||||||
|
return len(self._profiles)
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def profiles(self):
|
def profiles(self):
|
||||||
return self._profiles.copy()
|
return self._profiles.copy()
|
||||||
|
|||||||
@@ -43,6 +43,10 @@ class Results(object):
|
|||||||
def river(self):
|
def river(self):
|
||||||
return self._river
|
return self._river
|
||||||
|
|
||||||
|
@property
|
||||||
|
def study(self):
|
||||||
|
return self._study
|
||||||
|
|
||||||
def set(self, key, value):
|
def set(self, key, value):
|
||||||
self._meta_data[key] = value
|
self._meta_data[key] = value
|
||||||
|
|
||||||
|
|||||||
@@ -26,6 +26,9 @@ class Profile(object):
|
|||||||
self._profile = profile # Source profile in the study
|
self._profile = profile # Source profile in the study
|
||||||
self._data = {} # Dict of dict {<ts>: {<key>: <value>, ...}, ...}
|
self._data = {} # Dict of dict {<ts>: {<key>: <value>, ...}, ...}
|
||||||
|
|
||||||
|
def __len__(self):
|
||||||
|
return len(self._data)
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def name(self):
|
def name(self):
|
||||||
return self._profile.name
|
return self._profile.name
|
||||||
@@ -66,6 +69,9 @@ class Reach(object):
|
|||||||
)
|
)
|
||||||
)
|
)
|
||||||
|
|
||||||
|
def __len__(self):
|
||||||
|
return len(self._profiles)
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def name(self):
|
def name(self):
|
||||||
return self._reach.name
|
return self._reach.name
|
||||||
@@ -91,6 +97,9 @@ class River(object):
|
|||||||
# Dict with timestamps as key
|
# Dict with timestamps as key
|
||||||
self._reachs = []
|
self._reachs = []
|
||||||
|
|
||||||
|
def __len__(self):
|
||||||
|
return len(self._reachs)
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def reachs(self):
|
def reachs(self):
|
||||||
return self._reachs.copy()
|
return self._reachs.copy()
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
# help.py -- Pamhyr
|
# Hello.py -- Pamhyr
|
||||||
# Copyright (C) 2023 INRAE
|
# Copyright (C) 2023 INRAE
|
||||||
#
|
#
|
||||||
# This program is free software: you can redistribute it and/or modify
|
# This program is free software: you can redistribute it and/or modify
|
||||||
|
|||||||
@@ -0,0 +1,115 @@
|
|||||||
|
# P3DST.py -- Pamhyr
|
||||||
|
# Copyright (C) 2023 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 sys
|
||||||
|
import logging
|
||||||
|
|
||||||
|
from matplotlib import pyplot as plt
|
||||||
|
from numpy import mean
|
||||||
|
|
||||||
|
from Scripts.AScript import AScript
|
||||||
|
|
||||||
|
from Model.Saved import SavedStatus
|
||||||
|
from Model.Geometry.Reach import Reach
|
||||||
|
|
||||||
|
logger = logging.getLogger()
|
||||||
|
|
||||||
|
class Script3DST(AScript):
|
||||||
|
name = "3DST"
|
||||||
|
description = "Display a 3D plot of a river reach from ST file"
|
||||||
|
|
||||||
|
def usage(self):
|
||||||
|
logger.info(f"Usage : {self._args[0]} 3DST <INPUT_ST_FILE>")
|
||||||
|
|
||||||
|
def set_axes_equal(self, ax):
|
||||||
|
"""Make axes of 3D plot have equal scale
|
||||||
|
|
||||||
|
Make axes of 3D plot have equal scale so that spheres appear
|
||||||
|
as spheres, cubes as cubes, etc.. This is one possible
|
||||||
|
solution to Matplotlib's ax.set_aspect('equal') and
|
||||||
|
ax.axis('equal') not working for 3D.
|
||||||
|
|
||||||
|
Args:
|
||||||
|
ax: a matplotlib axis, e.g., as output from plt.gca()
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
The input axis
|
||||||
|
"""
|
||||||
|
x_limits = ax.get_xlim3d()
|
||||||
|
y_limits = ax.get_ylim3d()
|
||||||
|
z_limits = ax.get_zlim3d()
|
||||||
|
|
||||||
|
x_range = abs(x_limits[1] - x_limits[0])
|
||||||
|
x_middle = mean(x_limits)
|
||||||
|
y_range = abs(y_limits[1] - y_limits[0])
|
||||||
|
y_middle = mean(y_limits)
|
||||||
|
z_range = abs(z_limits[1] - z_limits[0])
|
||||||
|
z_middle = mean(z_limits)
|
||||||
|
|
||||||
|
# The plot bounding box is a sphere in the sense of the infinity
|
||||||
|
# norm, hence I call half the max range the plot radius.
|
||||||
|
plot_radius = 0.5*max([x_range, y_range, z_range])
|
||||||
|
|
||||||
|
ax.set_xlim3d([x_middle - plot_radius, x_middle + plot_radius])
|
||||||
|
ax.set_ylim3d([y_middle - plot_radius, y_middle + plot_radius])
|
||||||
|
ax.set_zlim3d([z_middle - plot_radius, z_middle + plot_radius])
|
||||||
|
|
||||||
|
return ax
|
||||||
|
|
||||||
|
def run(self):
|
||||||
|
try:
|
||||||
|
st_file = self._args[2]
|
||||||
|
logger.info(f"Use ST file: {st_file}")
|
||||||
|
except Exception as e:
|
||||||
|
logger.error(f"Arguments parcing: {str(e)}")
|
||||||
|
return 1
|
||||||
|
|
||||||
|
try:
|
||||||
|
status = SavedStatus()
|
||||||
|
|
||||||
|
my_reach = Reach(status = status)
|
||||||
|
my_reach.import_geometry(st_file)
|
||||||
|
my_reach.compute_guidelines()
|
||||||
|
|
||||||
|
ax = plt.figure().add_subplot(projection="3d")
|
||||||
|
logger.info(my_reach.get_x())
|
||||||
|
for x, y, z in zip(
|
||||||
|
my_reach.get_x(),
|
||||||
|
my_reach.get_y(),
|
||||||
|
my_reach.get_z()
|
||||||
|
):
|
||||||
|
ax.plot(x, y, z, color='r', lw=1.)
|
||||||
|
|
||||||
|
for x, y, z in zip(
|
||||||
|
my_reach.get_guidelines_x(),
|
||||||
|
my_reach.get_guidelines_y(),
|
||||||
|
my_reach.get_guidelines_z()
|
||||||
|
):
|
||||||
|
ax.plot(x, y, z, color='b', lw=1.)
|
||||||
|
|
||||||
|
ax.set_xlabel('X')
|
||||||
|
ax.set_ylabel('Y')
|
||||||
|
ax.set_zlabel('Z')
|
||||||
|
plt.tight_layout()
|
||||||
|
self.set_axes_equal(ax)
|
||||||
|
plt.show()
|
||||||
|
|
||||||
|
return 0
|
||||||
|
except Exception as e:
|
||||||
|
logger.error(str(e))
|
||||||
|
return 1
|
||||||
@@ -1,68 +0,0 @@
|
|||||||
# plot_3DST.py -- Pamhyr
|
|
||||||
# Copyright (C) 2023 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 -*-
|
|
||||||
|
|
||||||
# a lancer depuis src
|
|
||||||
import sys
|
|
||||||
from matplotlib import pyplot as plt
|
|
||||||
from Model.Geometry.Reach import Reach
|
|
||||||
from numpy import mean
|
|
||||||
|
|
||||||
def set_axes_equal(ax):
|
|
||||||
'''Make axes of 3D plot have equal scale so that spheres appear as spheres,
|
|
||||||
cubes as cubes, etc.. This is one possible solution to Matplotlib's
|
|
||||||
ax.set_aspect('equal') and ax.axis('equal') not working for 3D.
|
|
||||||
|
|
||||||
Input
|
|
||||||
ax: a matplotlib axis, e.g., as output from plt.gca().
|
|
||||||
'''
|
|
||||||
|
|
||||||
x_limits = ax.get_xlim3d()
|
|
||||||
y_limits = ax.get_ylim3d()
|
|
||||||
z_limits = ax.get_zlim3d()
|
|
||||||
|
|
||||||
x_range = abs(x_limits[1] - x_limits[0])
|
|
||||||
x_middle = mean(x_limits)
|
|
||||||
y_range = abs(y_limits[1] - y_limits[0])
|
|
||||||
y_middle = mean(y_limits)
|
|
||||||
z_range = abs(z_limits[1] - z_limits[0])
|
|
||||||
z_middle = mean(z_limits)
|
|
||||||
|
|
||||||
# The plot bounding box is a sphere in the sense of the infinity
|
|
||||||
# norm, hence I call half the max range the plot radius.
|
|
||||||
plot_radius = 0.5*max([x_range, y_range, z_range])
|
|
||||||
|
|
||||||
ax.set_xlim3d([x_middle - plot_radius, x_middle + plot_radius])
|
|
||||||
ax.set_ylim3d([y_middle - plot_radius, y_middle + plot_radius])
|
|
||||||
ax.set_zlim3d([z_middle - plot_radius, z_middle + plot_radius])
|
|
||||||
|
|
||||||
st_file = sys.argv[1]
|
|
||||||
my_reach = Reach(None)
|
|
||||||
my_reach.import_geometry(st_file)
|
|
||||||
my_reach.compute_guidelines()
|
|
||||||
|
|
||||||
ax = plt.figure().add_subplot(projection="3d")
|
|
||||||
for x, y, z in zip(my_reach.get_x(), my_reach.get_y(), my_reach.get_z()):
|
|
||||||
ax.plot(x, y, z, color='r', lw=1.)
|
|
||||||
for x, y, z in zip(my_reach.get_guidelines_x(), my_reach.get_guidelines_y(), my_reach.get_guidelines_z()):
|
|
||||||
ax.plot(x, y, z, color='b', lw=1.)
|
|
||||||
ax.set_xlabel('X')
|
|
||||||
ax.set_ylabel('Y')
|
|
||||||
ax.set_zlabel('Z')
|
|
||||||
plt.tight_layout()
|
|
||||||
set_axes_equal(ax)
|
|
||||||
plt.show()
|
|
||||||
@@ -24,9 +24,9 @@ from Solver.Mage import Mage7, Mage8
|
|||||||
_translate = QCoreApplication.translate
|
_translate = QCoreApplication.translate
|
||||||
|
|
||||||
solver_long_name = {
|
solver_long_name = {
|
||||||
"generic": _translate("Solvers", "Generic"),
|
"generic": "Generic",
|
||||||
# "mage7": _translate("Solvers", "Mage version 7"),
|
# "mage7": "Mage v7",
|
||||||
"mage8": _translate("Solvers", "Mage version 8"),
|
"mage8": "Mage v8",
|
||||||
}
|
}
|
||||||
|
|
||||||
solver_type_list = {
|
solver_type_list = {
|
||||||
|
|||||||
@@ -19,14 +19,17 @@
|
|||||||
import os
|
import os
|
||||||
import logging
|
import logging
|
||||||
|
|
||||||
from View.ASubWindow import ASubWindow
|
from View.Tools.PamhyrWindow import PamhyrDialog
|
||||||
|
|
||||||
from PyQt5.QtCore import QCoreApplication
|
from PyQt5.QtCore import QCoreApplication
|
||||||
|
|
||||||
_translate = QCoreApplication.translate
|
_translate = QCoreApplication.translate
|
||||||
logger = logging.getLogger()
|
logger = logging.getLogger()
|
||||||
|
|
||||||
class AboutWindow(ASubWindow):
|
class AboutWindow(PamhyrDialog):
|
||||||
|
_pamhyr_ui = "about"
|
||||||
|
_pamhyr_name = "About"
|
||||||
|
|
||||||
def _path_file(self, filename):
|
def _path_file(self, filename):
|
||||||
return os.path.abspath(
|
return os.path.abspath(
|
||||||
os.path.join(
|
os.path.join(
|
||||||
@@ -35,10 +38,14 @@ class AboutWindow(ASubWindow):
|
|||||||
)
|
)
|
||||||
)
|
)
|
||||||
|
|
||||||
|
def __init__(self, study = None, config = None, parent=None):
|
||||||
def __init__(self, title="About", parent=None):
|
super(AboutWindow, self).__init__(
|
||||||
super(AboutWindow, self).__init__(name=title, ui="about", parent=parent)
|
title = _translate("About", "About"),
|
||||||
self.ui.setWindowTitle(title)
|
study = study,
|
||||||
|
config = config,
|
||||||
|
options = [],
|
||||||
|
parent = parent
|
||||||
|
)
|
||||||
|
|
||||||
# Version
|
# Version
|
||||||
with open(self._path_file("VERSION"), "r") as f:
|
with open(self._path_file("VERSION"), "r") as f:
|
||||||
|
|||||||
@@ -21,27 +21,31 @@ import logging
|
|||||||
from datetime import datetime
|
from datetime import datetime
|
||||||
|
|
||||||
from tools import timer, trace
|
from tools import timer, trace
|
||||||
from View.Plot.APlot import APlot
|
from View.Tools.PamhyrPlot import PamhyrPlot
|
||||||
|
|
||||||
from PyQt5.QtCore import (
|
from PyQt5.QtCore import (
|
||||||
QCoreApplication
|
QCoreApplication
|
||||||
)
|
)
|
||||||
|
|
||||||
from View.BoundaryCondition.Edit.translate import *
|
from View.BoundaryCondition.Edit.translate import BCETranslate
|
||||||
|
|
||||||
_translate = QCoreApplication.translate
|
_translate = QCoreApplication.translate
|
||||||
|
|
||||||
logger = logging.getLogger()
|
logger = logging.getLogger()
|
||||||
|
|
||||||
class Plot(APlot):
|
class Plot(PamhyrPlot):
|
||||||
def __init__(self, canvas=None, data=None,
|
def __init__(self, mode = "time", data=None,
|
||||||
mode = "time", toolbar=None):
|
trad=None, canvas=None, toolbar=None,
|
||||||
|
parent=None):
|
||||||
super(Plot, self).__init__(
|
super(Plot, self).__init__(
|
||||||
canvas=canvas,
|
canvas = canvas,
|
||||||
data=data,
|
trad = trad,
|
||||||
toolbar=toolbar
|
data = data,
|
||||||
|
toolbar = toolbar,
|
||||||
|
parent = parent
|
||||||
)
|
)
|
||||||
|
|
||||||
|
self._table_headers = self._trad.get_dict("table_headers")
|
||||||
self._mode = mode
|
self._mode = mode
|
||||||
|
|
||||||
def custom_ticks(self):
|
def custom_ticks(self):
|
||||||
@@ -109,10 +113,10 @@ class Plot(APlot):
|
|||||||
# Plot label
|
# Plot label
|
||||||
header = self.data.header
|
header = self.data.header
|
||||||
self.canvas.axes.set_xlabel(
|
self.canvas.axes.set_xlabel(
|
||||||
table_headers[header[0]], color='black', fontsize=10
|
self._table_headers[header[0]], color='black', fontsize=10
|
||||||
)
|
)
|
||||||
self.canvas.axes.set_ylabel(
|
self.canvas.axes.set_ylabel(
|
||||||
table_headers[header[1]], color='black', fontsize=10
|
self._table_headers[header[1]], color='black', fontsize=10
|
||||||
)
|
)
|
||||||
|
|
||||||
self.canvas.axes.autoscale_view(True, True, True)
|
self.canvas.axes.autoscale_view(True, True, True)
|
||||||
|
|||||||
@@ -23,8 +23,6 @@ from datetime import date, time, datetime, timedelta
|
|||||||
|
|
||||||
from tools import trace, timer
|
from tools import trace, timer
|
||||||
|
|
||||||
from View.ASubWindow import ASubMainWindow, AWidget
|
|
||||||
from View.ListedSubWindow import ListedSubWindow
|
|
||||||
from View.Tools.PamhyrTable import PamhyrTableModel
|
from View.Tools.PamhyrTable import PamhyrTableModel
|
||||||
|
|
||||||
from PyQt5.QtCore import (
|
from PyQt5.QtCore import (
|
||||||
@@ -48,7 +46,6 @@ from View.BoundaryCondition.Edit.UndoCommand import (
|
|||||||
SortCommand, MoveCommand, PasteCommand,
|
SortCommand, MoveCommand, PasteCommand,
|
||||||
DuplicateCommand,
|
DuplicateCommand,
|
||||||
)
|
)
|
||||||
from View.BoundaryCondition.Edit.translate import *
|
|
||||||
|
|
||||||
_translate = QCoreApplication.translate
|
_translate = QCoreApplication.translate
|
||||||
|
|
||||||
|
|||||||
@@ -20,8 +20,8 @@ import logging
|
|||||||
|
|
||||||
from tools import timer, trace
|
from tools import timer, trace
|
||||||
|
|
||||||
from View.ASubWindow import ASubMainWindow, AWidget
|
from View.Tools.PamhyrWindow import PamhyrWindow
|
||||||
from View.ListedSubWindow import ListedSubWindow
|
from View.Tools.PamhyrWidget import PamhyrWidget
|
||||||
from View.Tools.PamhyrDelegate import PamhyrExTimeDelegate
|
from View.Tools.PamhyrDelegate import PamhyrExTimeDelegate
|
||||||
|
|
||||||
from PyQt5.QtGui import (
|
from PyQt5.QtGui import (
|
||||||
@@ -41,11 +41,10 @@ from PyQt5.QtWidgets import (
|
|||||||
QHeaderView, QDoubleSpinBox, QVBoxLayout,
|
QHeaderView, QDoubleSpinBox, QVBoxLayout,
|
||||||
)
|
)
|
||||||
|
|
||||||
from View.Plot.MplCanvas import MplCanvas
|
from View.Tools.Plot.PamhyrCanvas import MplCanvas
|
||||||
from View.Plot.PamhyrToolbar import PamhyrPlotToolbar
|
from View.Tools.Plot.PamhyrToolbar import PamhyrPlotToolbar
|
||||||
|
|
||||||
from View.BoundaryCondition.translate import long_types
|
from View.BoundaryCondition.Edit.translate import BCETranslate
|
||||||
from View.BoundaryCondition.Edit.translate import table_headers, retranslate
|
|
||||||
from View.BoundaryCondition.Edit.UndoCommand import SetMetaDataCommand
|
from View.BoundaryCondition.Edit.UndoCommand import SetMetaDataCommand
|
||||||
from View.BoundaryCondition.Edit.Table import TableModel
|
from View.BoundaryCondition.Edit.Table import TableModel
|
||||||
from View.BoundaryCondition.Edit.Plot import Plot
|
from View.BoundaryCondition.Edit.Plot import Plot
|
||||||
@@ -54,16 +53,16 @@ _translate = QCoreApplication.translate
|
|||||||
|
|
||||||
logger = logging.getLogger()
|
logger = logging.getLogger()
|
||||||
|
|
||||||
class WD50Sigma(AWidget):
|
class WD50Sigma(PamhyrWidget):
|
||||||
|
_pamhyr_ui = "d50sigma"
|
||||||
|
|
||||||
d50Changed = pyqtSignal(float)
|
d50Changed = pyqtSignal(float)
|
||||||
sigmaChanged = pyqtSignal(float)
|
sigmaChanged = pyqtSignal(float)
|
||||||
|
|
||||||
def __init__(self, parent=None):
|
def __init__(self, parent=None):
|
||||||
super(WD50Sigma, self).__init__(
|
super(WD50Sigma, self).__init__(
|
||||||
ui="d50sigma",
|
|
||||||
parent=parent
|
parent=parent
|
||||||
)
|
)
|
||||||
self.parent = parent
|
|
||||||
|
|
||||||
self.spinBox_d50 = self.find(QDoubleSpinBox, "doubleSpinBox_d50")
|
self.spinBox_d50 = self.find(QDoubleSpinBox, "doubleSpinBox_d50")
|
||||||
self.spinBox_sigma = self.find(QDoubleSpinBox, "doubleSpinBox_sigma")
|
self.spinBox_sigma = self.find(QDoubleSpinBox, "doubleSpinBox_sigma")
|
||||||
@@ -95,46 +94,39 @@ class WD50Sigma(AWidget):
|
|||||||
def valueChangedSigma(self, value):
|
def valueChangedSigma(self, value):
|
||||||
self.sigmaChanged.emit(value)
|
self.sigmaChanged.emit(value)
|
||||||
|
|
||||||
class EditBoundaryConditionWindow(ASubMainWindow, ListedSubWindow):
|
class EditBoundaryConditionWindow(PamhyrWindow):
|
||||||
def __init__(self, title="Edit boundary condition",
|
_pamhyr_ui = "EditBoundaryConditions"
|
||||||
data=None, study=None, parent=None):
|
_pamhyr_name = "Edit Boundary Conditions"
|
||||||
self._data = data
|
|
||||||
self._study = study
|
|
||||||
self._title = title
|
|
||||||
|
|
||||||
self.compute_title()
|
def __init__(self, data=None, study=None, config=None, parent=None):
|
||||||
|
self._data = data
|
||||||
|
trad = BCETranslate()
|
||||||
|
self._long_types = trad.get_dict("long_types")
|
||||||
|
|
||||||
|
name = self._pamhyr_name
|
||||||
|
if self._data is not None:
|
||||||
|
node_name = (self._data.node.name if self._data.node is not None
|
||||||
|
else _translate("BoundaryCondition", "Not associate"))
|
||||||
|
name = (
|
||||||
|
_translate("Edit boundary condition", self._pamhyr_name) +
|
||||||
|
f" - {study.name} " +
|
||||||
|
f" - {self._data.name} ({self._data.id}) " +
|
||||||
|
f"({self._long_types[self._data.bctype]} - {node_name})"
|
||||||
|
)
|
||||||
|
|
||||||
super(EditBoundaryConditionWindow, self).__init__(
|
super(EditBoundaryConditionWindow, self).__init__(
|
||||||
name=self._title, ui="EditBoundaryConditions", parent=parent
|
title = name,
|
||||||
|
study = study,
|
||||||
|
config = config,
|
||||||
|
trad = trad,
|
||||||
|
parent = parent
|
||||||
)
|
)
|
||||||
|
|
||||||
self.ui.setWindowTitle(self._title)
|
|
||||||
|
|
||||||
self.setup_sc()
|
|
||||||
self.setup_table()
|
self.setup_table()
|
||||||
self.setup_plot()
|
self.setup_plot()
|
||||||
self.setup_data()
|
self.setup_data()
|
||||||
self.setup_connections()
|
self.setup_connections()
|
||||||
|
|
||||||
def compute_title(self):
|
|
||||||
if self._data is not None:
|
|
||||||
node_name = (self._data.node.name if self._data.node is not None
|
|
||||||
else _translate("BoundaryCondition", "Not associate"))
|
|
||||||
self._title = (
|
|
||||||
_translate("Edit boundary condition", self._title) +
|
|
||||||
f" - {self._study.name} " +
|
|
||||||
f" - {self._data.name} ({self._data.id}) " +
|
|
||||||
f"({long_types[self._data.bctype]} - {node_name})"
|
|
||||||
)
|
|
||||||
|
|
||||||
def setup_sc(self):
|
|
||||||
self._undo_stack = QUndoStack()
|
|
||||||
|
|
||||||
self.undo_sc = QShortcut(QKeySequence.Undo, self)
|
|
||||||
self.redo_sc = QShortcut(QKeySequence.Redo, self)
|
|
||||||
self.copy_sc = QShortcut(QKeySequence.Copy, self)
|
|
||||||
self.paste_sc = QShortcut(QKeySequence.Paste, self)
|
|
||||||
|
|
||||||
def setup_data(self):
|
def setup_data(self):
|
||||||
self._is_solid = self._data.bctype == "SL"
|
self._is_solid = self._data.bctype == "SL"
|
||||||
|
|
||||||
@@ -147,8 +139,8 @@ class EditBoundaryConditionWindow(ASubMainWindow, ListedSubWindow):
|
|||||||
self._d50sigma.set_sigma(self._data.sigma)
|
self._d50sigma.set_sigma(self._data.sigma)
|
||||||
|
|
||||||
def setup_table(self):
|
def setup_table(self):
|
||||||
retranslate()
|
|
||||||
headers = {}
|
headers = {}
|
||||||
|
table_headers = self._trad.get_dict("table_headers")
|
||||||
for h in self._data.header:
|
for h in self._data.header:
|
||||||
headers[h] = table_headers[h]
|
headers[h] = table_headers[h]
|
||||||
|
|
||||||
@@ -189,21 +181,16 @@ class EditBoundaryConditionWindow(ASubMainWindow, ListedSubWindow):
|
|||||||
canvas = self.canvas,
|
canvas = self.canvas,
|
||||||
data = self._data,
|
data = self._data,
|
||||||
mode = self._study.time_system,
|
mode = self._study.time_system,
|
||||||
|
trad = self._trad,
|
||||||
toolbar = self.toolbar,
|
toolbar = self.toolbar,
|
||||||
)
|
)
|
||||||
self.plot.draw()
|
self.plot.draw()
|
||||||
|
|
||||||
|
|
||||||
def setup_connections(self):
|
def setup_connections(self):
|
||||||
self.find(QAction, "action_add").triggered.connect(self.add)
|
self.find(QAction, "action_add").triggered.connect(self.add)
|
||||||
self.find(QAction, "action_del").triggered.connect(self.delete)
|
self.find(QAction, "action_del").triggered.connect(self.delete)
|
||||||
self.find(QAction, "action_sort").triggered.connect(self.sort)
|
self.find(QAction, "action_sort").triggered.connect(self.sort)
|
||||||
|
|
||||||
self.undo_sc.activated.connect(self.undo)
|
|
||||||
self.redo_sc.activated.connect(self.redo)
|
|
||||||
self.copy_sc.activated.connect(self.copy)
|
|
||||||
self.paste_sc.activated.connect(self.paste)
|
|
||||||
|
|
||||||
self._table.dataChanged.connect(self.update)
|
self._table.dataChanged.connect(self.update)
|
||||||
|
|
||||||
if self._is_solid:
|
if self._is_solid:
|
||||||
@@ -252,7 +239,6 @@ class EditBoundaryConditionWindow(ASubMainWindow, ListedSubWindow):
|
|||||||
)
|
)
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
def add(self):
|
def add(self):
|
||||||
rows = self.index_selected_rows()
|
rows = self.index_selected_rows()
|
||||||
if len(self._data) == 0 or len(rows) == 0:
|
if len(self._data) == 0 or len(rows) == 0:
|
||||||
@@ -285,7 +271,7 @@ class EditBoundaryConditionWindow(ASubMainWindow, ListedSubWindow):
|
|||||||
self.plot.update()
|
self.plot.update()
|
||||||
|
|
||||||
|
|
||||||
def copy(self):
|
def _copy(self):
|
||||||
rows = self.index_selected_rows()
|
rows = self.index_selected_rows()
|
||||||
|
|
||||||
table = []
|
table = []
|
||||||
@@ -297,7 +283,7 @@ class EditBoundaryConditionWindow(ASubMainWindow, ListedSubWindow):
|
|||||||
|
|
||||||
self.copyTableIntoClipboard(table)
|
self.copyTableIntoClipboard(table)
|
||||||
|
|
||||||
def paste(self):
|
def _paste(self):
|
||||||
header, data = self.parseClipboardTable()
|
header, data = self.parseClipboardTable()
|
||||||
|
|
||||||
if len(data) == 0:
|
if len(data) == 0:
|
||||||
@@ -311,12 +297,12 @@ class EditBoundaryConditionWindow(ASubMainWindow, ListedSubWindow):
|
|||||||
self._table.paste(row, header, data)
|
self._table.paste(row, header, data)
|
||||||
self.plot.update()
|
self.plot.update()
|
||||||
|
|
||||||
def undo(self):
|
def _undo(self):
|
||||||
self._table.undo()
|
self._table.undo()
|
||||||
self.plot.update()
|
self.plot.update()
|
||||||
self.widget_update()
|
self.widget_update()
|
||||||
|
|
||||||
def redo(self):
|
def _redo(self):
|
||||||
self._table.redo()
|
self._table.redo()
|
||||||
self.plot.update()
|
self.plot.update()
|
||||||
self.widget_update()
|
self.widget_update()
|
||||||
@@ -18,23 +18,22 @@
|
|||||||
|
|
||||||
from PyQt5.QtCore import QCoreApplication
|
from PyQt5.QtCore import QCoreApplication
|
||||||
|
|
||||||
|
from View.Tools.PamhyrTranslate import PamhyrTranslate
|
||||||
|
|
||||||
|
from View.BoundaryCondition.translate import BCTranslate
|
||||||
|
|
||||||
_translate = QCoreApplication.translate
|
_translate = QCoreApplication.translate
|
||||||
|
|
||||||
table_headers = {
|
class BCETranslate(BCTranslate):
|
||||||
"x": _translate("BoundaryCondition", "X"),
|
def __init__(self):
|
||||||
"y": _translate("BoundaryCondition", "Y"),
|
super(BCETranslate, self).__init__()
|
||||||
"time": _translate("BoundaryCondition", "Time"),
|
|
||||||
"date": _translate("BoundaryCondition", "Date"),
|
|
||||||
"discharge": _translate("BoundaryCondition", "Discharge (m³/s)"),
|
|
||||||
"z": _translate("BoundaryCondition", "Z (m)"),
|
|
||||||
"solid": _translate("BoundaryCondition", "Solid (kg/s)"),
|
|
||||||
}
|
|
||||||
|
|
||||||
def retranslate():
|
self._sub_dict["table_headers"] = {
|
||||||
table_headers["x"] = _translate("BoundaryCondition", "X")
|
"x": _translate("BoundaryCondition", "X"),
|
||||||
table_headers["y"] = _translate("BoundaryCondition", "Y")
|
"y": _translate("BoundaryCondition", "Y"),
|
||||||
table_headers["time"] = _translate("BoundaryCondition", "Time")
|
"time": _translate("BoundaryCondition", "Time"),
|
||||||
table_headers["date"] = _translate("BoundaryCondition", "Date")
|
"date": _translate("BoundaryCondition", "Date"),
|
||||||
table_headers["discharge"] = _translate("BoundaryCondition", "Discharge (m³/s)")
|
"discharge": _translate("BoundaryCondition", "Discharge (m³/s)"),
|
||||||
table_headers["z"] = _translate("BoundaryCondition", "Z (m)")
|
"z": _translate("BoundaryCondition", "Z (m)"),
|
||||||
table_headers["solid"] = _translate("BoundaryCondition", "Solid (kg/s)")
|
"solid": _translate("BoundaryCondition", "Solid (kg/s)"),
|
||||||
|
}
|
||||||
@@ -46,19 +46,24 @@ from View.BoundaryCondition.UndoCommand import (
|
|||||||
AddCommand, DelCommand, SortCommand,
|
AddCommand, DelCommand, SortCommand,
|
||||||
MoveCommand, PasteCommand, DuplicateCommand,
|
MoveCommand, PasteCommand, DuplicateCommand,
|
||||||
)
|
)
|
||||||
from View.BoundaryCondition.translate import *
|
from View.BoundaryCondition.translate import BC_types
|
||||||
|
|
||||||
logger = logging.getLogger()
|
logger = logging.getLogger()
|
||||||
|
|
||||||
_translate = QCoreApplication.translate
|
_translate = QCoreApplication.translate
|
||||||
|
|
||||||
class ComboBoxDelegate(QItemDelegate):
|
class ComboBoxDelegate(QItemDelegate):
|
||||||
def __init__(self, data=None, mode="type", tab="", parent=None):
|
def __init__(self, data=None, mode="type", tab="", trad=None, parent=None):
|
||||||
super(ComboBoxDelegate, self).__init__(parent)
|
super(ComboBoxDelegate, self).__init__(parent)
|
||||||
|
|
||||||
self._data = data
|
self._data = data
|
||||||
self._mode = mode
|
self._mode = mode
|
||||||
self._tab = tab
|
self._tab = tab
|
||||||
|
self._trad = trad
|
||||||
|
|
||||||
|
self._long_types = {}
|
||||||
|
if self._trad is not None:
|
||||||
|
self._long_types = self._trad.get_dict("long_types")
|
||||||
|
|
||||||
def createEditor(self, parent, option, index):
|
def createEditor(self, parent, option, index):
|
||||||
self.editor = QComboBox(parent)
|
self.editor = QComboBox(parent)
|
||||||
@@ -66,7 +71,7 @@ class ComboBoxDelegate(QItemDelegate):
|
|||||||
if self._mode == "type":
|
if self._mode == "type":
|
||||||
lst = list(
|
lst = list(
|
||||||
map(
|
map(
|
||||||
lambda k: long_types[k],
|
lambda k: self._long_types[k],
|
||||||
filter(
|
filter(
|
||||||
lambda k: self._tab in BC_types[k].compatibility(),
|
lambda k: self._tab in BC_types[k].compatibility(),
|
||||||
BC_types.keys()
|
BC_types.keys()
|
||||||
@@ -107,6 +112,13 @@ class ComboBoxDelegate(QItemDelegate):
|
|||||||
|
|
||||||
|
|
||||||
class TableModel(PamhyrTableModel):
|
class TableModel(PamhyrTableModel):
|
||||||
|
def __init__(self, **kwargs):
|
||||||
|
super(TableModel, self).__init__(**kwargs)
|
||||||
|
|
||||||
|
self._long_types = {}
|
||||||
|
if self._trad is not None:
|
||||||
|
self._long_types = self._trad.get_dict("long_types")
|
||||||
|
|
||||||
def _setup_lst(self):
|
def _setup_lst(self):
|
||||||
self._lst = self._data.boundary_condition
|
self._lst = self._data.boundary_condition
|
||||||
self._tab = self._opt_data
|
self._tab = self._opt_data
|
||||||
@@ -125,7 +137,7 @@ class TableModel(PamhyrTableModel):
|
|||||||
return self._lst.get(self._tab, row).name
|
return self._lst.get(self._tab, row).name
|
||||||
elif self._headers[column] == "type":
|
elif self._headers[column] == "type":
|
||||||
t = self._lst.get(self._tab, row).bctype
|
t = self._lst.get(self._tab, row).bctype
|
||||||
return long_types[t]
|
return self._long_types[t]
|
||||||
elif self._headers[column] == "node":
|
elif self._headers[column] == "node":
|
||||||
n = self._lst.get(self._tab, row).node
|
n = self._lst.get(self._tab, row).node
|
||||||
if n is None:
|
if n is None:
|
||||||
@@ -149,7 +161,7 @@ class TableModel(PamhyrTableModel):
|
|||||||
)
|
)
|
||||||
)
|
)
|
||||||
elif self._headers[column] == "type":
|
elif self._headers[column] == "type":
|
||||||
key = next(k for k, v in long_types.items() if v == value)
|
key = next(k for k, v in self._long_types.items() if v == value)
|
||||||
self._undo.push(
|
self._undo.push(
|
||||||
SetTypeCommand(
|
SetTypeCommand(
|
||||||
self._lst, self._tab,row, BC_types[key]
|
self._lst, self._tab,row, BC_types[key]
|
||||||
|
|||||||
@@ -20,8 +20,7 @@ import logging
|
|||||||
|
|
||||||
from tools import trace, timer
|
from tools import trace, timer
|
||||||
|
|
||||||
from View.ASubWindow import ASubMainWindow
|
from View.Tools.PamhyrWindow import PamhyrWindow
|
||||||
from View.ListedSubWindow import ListedSubWindow
|
|
||||||
|
|
||||||
from PyQt5.QtGui import (
|
from PyQt5.QtGui import (
|
||||||
QKeySequence,
|
QKeySequence,
|
||||||
@@ -56,51 +55,49 @@ from View.BoundaryCondition.Table import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
from View.Network.GraphWidget import GraphWidget
|
from View.Network.GraphWidget import GraphWidget
|
||||||
from View.BoundaryCondition.translate import table_headers, retranslate
|
from View.BoundaryCondition.translate import BCTranslate
|
||||||
from View.BoundaryCondition.Edit.Window import EditBoundaryConditionWindow
|
from View.BoundaryCondition.Edit.Window import EditBoundaryConditionWindow
|
||||||
|
|
||||||
_translate = QCoreApplication.translate
|
_translate = QCoreApplication.translate
|
||||||
|
|
||||||
logger = logging.getLogger()
|
logger = logging.getLogger()
|
||||||
|
|
||||||
class BoundaryConditionWindow(ASubMainWindow, ListedSubWindow):
|
class BoundaryConditionWindow(PamhyrWindow):
|
||||||
def __init__(self, title="Boundary conditions", study=None, parent=None):
|
_pamhyr_ui = "BoundaryConditions"
|
||||||
self._title = title + " - " + study.name
|
_pamhyr_name = "Boundary conditions"
|
||||||
|
|
||||||
|
def __init__(self, study=None, config=None, parent=None):
|
||||||
|
name = self._pamhyr_name + " - " + study.name
|
||||||
|
|
||||||
super(BoundaryConditionWindow, self).__init__(
|
super(BoundaryConditionWindow, self).__init__(
|
||||||
name=title, ui="BoundaryConditions", parent=parent
|
title = name,
|
||||||
|
study = study,
|
||||||
|
config = config,
|
||||||
|
trad = BCTranslate(),
|
||||||
|
parent=parent
|
||||||
)
|
)
|
||||||
|
|
||||||
self._study = study
|
|
||||||
self._bcs = self._study.river.boundary_condition
|
self._bcs = self._study.river.boundary_condition
|
||||||
|
|
||||||
self.setup_sc()
|
|
||||||
self.setup_table()
|
self.setup_table()
|
||||||
self.setup_graph()
|
self.setup_graph()
|
||||||
self.setup_connections()
|
self.setup_connections()
|
||||||
|
|
||||||
self.ui.setWindowTitle(self._title)
|
self.ui.setWindowTitle(self._title)
|
||||||
|
|
||||||
def setup_sc(self):
|
|
||||||
self._undo_stack = QUndoStack()
|
|
||||||
|
|
||||||
self.undo_sc = QShortcut(QKeySequence.Undo, self)
|
|
||||||
self.redo_sc = QShortcut(QKeySequence.Redo, self)
|
|
||||||
self.copy_sc = QShortcut(QKeySequence.Copy, self)
|
|
||||||
self.paste_sc = QShortcut(QKeySequence.Paste, self)
|
|
||||||
|
|
||||||
def setup_table(self):
|
def setup_table(self):
|
||||||
retranslate()
|
|
||||||
self._table = {}
|
self._table = {}
|
||||||
|
|
||||||
for t in ["liquid", "solid", "suspenssion"]:
|
for t in ["liquid", "solid", "suspenssion"]:
|
||||||
self._delegate_type = ComboBoxDelegate(
|
self._delegate_type = ComboBoxDelegate(
|
||||||
|
trad = self._trad,
|
||||||
data = self._study.river,
|
data = self._study.river,
|
||||||
mode = "type",
|
mode = "type",
|
||||||
tab = t,
|
tab = t,
|
||||||
parent=self
|
parent=self
|
||||||
)
|
)
|
||||||
self._delegate_node = ComboBoxDelegate(
|
self._delegate_node = ComboBoxDelegate(
|
||||||
|
trad = self._trad,
|
||||||
data = self._study.river,
|
data = self._study.river,
|
||||||
mode = "node",
|
mode = "node",
|
||||||
tab = t,
|
tab = t,
|
||||||
@@ -110,12 +107,13 @@ class BoundaryConditionWindow(ASubMainWindow, ListedSubWindow):
|
|||||||
table = self.find(QTableView, f"tableView_{t}")
|
table = self.find(QTableView, f"tableView_{t}")
|
||||||
self._table[t] = TableModel(
|
self._table[t] = TableModel(
|
||||||
table_view = table,
|
table_view = table,
|
||||||
table_headers = table_headers,
|
table_headers = self._trad.get_dict("table_headers"),
|
||||||
editable_headers = ["name", "type", "node"],
|
editable_headers = ["name", "type", "node"],
|
||||||
delegates = {
|
delegates = {
|
||||||
"type": self._delegate_type,
|
"type": self._delegate_type,
|
||||||
"node": self._delegate_node,
|
"node": self._delegate_node,
|
||||||
},
|
},
|
||||||
|
trad = self._trad,
|
||||||
data = self._study.river,
|
data = self._study.river,
|
||||||
undo = self._undo_stack,
|
undo = self._undo_stack,
|
||||||
opt_data = t,
|
opt_data = t,
|
||||||
@@ -141,11 +139,6 @@ class BoundaryConditionWindow(ASubMainWindow, ListedSubWindow):
|
|||||||
self.find(QAction, "action_edit").triggered.connect(self.edit)
|
self.find(QAction, "action_edit").triggered.connect(self.edit)
|
||||||
self.find(QAction, "action_sort").triggered.connect(self.sort)
|
self.find(QAction, "action_sort").triggered.connect(self.sort)
|
||||||
|
|
||||||
self.undo_sc.activated.connect(self.undo)
|
|
||||||
self.redo_sc.activated.connect(self.redo)
|
|
||||||
self.copy_sc.activated.connect(self.copy)
|
|
||||||
self.paste_sc.activated.connect(self.paste)
|
|
||||||
|
|
||||||
def current_tab(self):
|
def current_tab(self):
|
||||||
return self.find(QTabWidget, "tabWidget")\
|
return self.find(QTabWidget, "tabWidget")\
|
||||||
.currentWidget()\
|
.currentWidget()\
|
||||||
@@ -202,17 +195,17 @@ class BoundaryConditionWindow(ASubMainWindow, ListedSubWindow):
|
|||||||
row = self.index_selected_row()
|
row = self.index_selected_row()
|
||||||
self._table[tab].move_down(row)
|
self._table[tab].move_down(row)
|
||||||
|
|
||||||
def copy(self):
|
def _copy(self):
|
||||||
logger.info("TODO: copy")
|
logger.info("TODO: copy")
|
||||||
|
|
||||||
def paste(self):
|
def _paste(self):
|
||||||
logger.info("TODO: paste")
|
logger.info("TODO: paste")
|
||||||
|
|
||||||
def undo(self):
|
def _undo(self):
|
||||||
tab = self.current_tab()
|
tab = self.current_tab()
|
||||||
self._table[tab].undo()
|
self._table[tab].undo()
|
||||||
|
|
||||||
def redo(self):
|
def _redo(self):
|
||||||
tab = self.current_tab()
|
tab = self.current_tab()
|
||||||
self._table[tab].redo()
|
self._table[tab].redo()
|
||||||
|
|
||||||
|
|||||||
@@ -18,6 +18,8 @@
|
|||||||
|
|
||||||
from PyQt5.QtCore import QCoreApplication
|
from PyQt5.QtCore import QCoreApplication
|
||||||
|
|
||||||
|
from View.Tools.PamhyrTranslate import PamhyrTranslate
|
||||||
|
|
||||||
from Model.BoundaryCondition.BoundaryConditionTypes import (
|
from Model.BoundaryCondition.BoundaryConditionTypes import (
|
||||||
NotDefined, PonctualContribution,
|
NotDefined, PonctualContribution,
|
||||||
TimeOverZ, TimeOverDischarge, ZOverDischarge,
|
TimeOverZ, TimeOverDischarge, ZOverDischarge,
|
||||||
@@ -26,21 +28,6 @@ from Model.BoundaryCondition.BoundaryConditionTypes import (
|
|||||||
|
|
||||||
_translate = QCoreApplication.translate
|
_translate = QCoreApplication.translate
|
||||||
|
|
||||||
long_types = {
|
|
||||||
"ND": _translate("BoundaryCondition", "Not defined"),
|
|
||||||
"PC": _translate("BoundaryCondition", "Ponctual contribution"),
|
|
||||||
"TZ": _translate("BoundaryCondition", "TimeZ"),
|
|
||||||
"TD": _translate("BoundaryCondition", "TimeDischarge"),
|
|
||||||
"ZD": _translate("BoundaryCondition", "ZDischarge"),
|
|
||||||
"SL": _translate("BoundaryCondition", "Solid"),
|
|
||||||
}
|
|
||||||
|
|
||||||
table_headers = {
|
|
||||||
"name": _translate("BoundaryCondition", "Name"),
|
|
||||||
"type": _translate("BoundaryCondition", "Type"),
|
|
||||||
"node": _translate("BoundaryCondition", "Node")
|
|
||||||
}
|
|
||||||
|
|
||||||
BC_types = {
|
BC_types = {
|
||||||
"ND": NotDefined,
|
"ND": NotDefined,
|
||||||
"PC": PonctualContribution,
|
"PC": PonctualContribution,
|
||||||
@@ -50,7 +37,21 @@ BC_types = {
|
|||||||
"SL": Solid,
|
"SL": Solid,
|
||||||
}
|
}
|
||||||
|
|
||||||
def retranslate():
|
class BCTranslate(PamhyrTranslate):
|
||||||
table_headers["name"] = _translate("BoundaryCondition", "Name")
|
def __init__(self):
|
||||||
table_headers["type"] = _translate("BoundaryCondition", "Type")
|
super(BCTranslate, self).__init__()
|
||||||
table_headers["node"] = _translate("BoundaryCondition", "Node")
|
|
||||||
|
self._sub_dict["long_types"] = {
|
||||||
|
"ND": _translate("BoundaryCondition", "Not defined"),
|
||||||
|
"PC": _translate("BoundaryCondition", "Ponctual contribution"),
|
||||||
|
"TZ": _translate("BoundaryCondition", "TimeZ"),
|
||||||
|
"TD": _translate("BoundaryCondition", "TimeDischarge"),
|
||||||
|
"ZD": _translate("BoundaryCondition", "ZDischarge"),
|
||||||
|
"SL": _translate("BoundaryCondition", "Solid"),
|
||||||
|
}
|
||||||
|
|
||||||
|
self._sub_dict["table_headers"] = {
|
||||||
|
"name": _translate("BoundaryCondition", "Name"),
|
||||||
|
"type": _translate("BoundaryCondition", "Type"),
|
||||||
|
"node": _translate("BoundaryCondition", "Node")
|
||||||
|
}
|
||||||
@@ -35,25 +35,12 @@ from PyQt5.QtWidgets import (
|
|||||||
QComboBox,
|
QComboBox,
|
||||||
)
|
)
|
||||||
|
|
||||||
|
from View.Tools.PamhyrTable import PamhyrTableModel
|
||||||
|
|
||||||
_translate = QCoreApplication.translate
|
_translate = QCoreApplication.translate
|
||||||
|
|
||||||
|
|
||||||
class TableModel(QAbstractTableModel):
|
class TableModel(PamhyrTableModel):
|
||||||
def __init__(self, data=None):
|
|
||||||
super(QAbstractTableModel, self).__init__()
|
|
||||||
self._headers = ["name", "status"]
|
|
||||||
self._data = data
|
|
||||||
|
|
||||||
def flags(self, index):
|
|
||||||
options = Qt.ItemIsEnabled | Qt.ItemIsSelectable
|
|
||||||
return options
|
|
||||||
|
|
||||||
def rowCount(self, parent):
|
|
||||||
return len(self._data)
|
|
||||||
|
|
||||||
def columnCount(self, parent):
|
|
||||||
return len(self._headers)
|
|
||||||
|
|
||||||
def data(self, index, role):
|
def data(self, index, role):
|
||||||
row = index.row()
|
row = index.row()
|
||||||
column = index.column()
|
column = index.column()
|
||||||
@@ -81,12 +68,3 @@ class TableModel(QAbstractTableModel):
|
|||||||
return self._data[row].summary
|
return self._data[row].summary
|
||||||
|
|
||||||
return QVariant()
|
return QVariant()
|
||||||
|
|
||||||
def headerData(self, section, orientation, role):
|
|
||||||
if role == Qt.ItemDataRole.DisplayRole and orientation == Qt.Orientation.Horizontal:
|
|
||||||
return self._headers[section]
|
|
||||||
|
|
||||||
return QVariant()
|
|
||||||
|
|
||||||
def update(self):
|
|
||||||
self.layoutChanged.emit()
|
|
||||||
@@ -0,0 +1,32 @@
|
|||||||
|
# Translate.py -- Pamhyr
|
||||||
|
# Copyright (C) 2023 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.Tools.PamhyrTranslate import PamhyrTranslate
|
||||||
|
|
||||||
|
_translate = QCoreApplication.translate
|
||||||
|
|
||||||
|
class CheckListTranslate(PamhyrTranslate):
|
||||||
|
def __init__(self):
|
||||||
|
super(CheckListTranslate, self).__init__()
|
||||||
|
|
||||||
|
self._sub_dict["table_headers"] = {
|
||||||
|
"name": _translate("CheckList", "Name"),
|
||||||
|
"status": _translate("CheckList", "Status"),
|
||||||
|
}
|
||||||
@@ -18,8 +18,7 @@
|
|||||||
|
|
||||||
from tools import trace, timer
|
from tools import trace, timer
|
||||||
|
|
||||||
from View.ASubWindow import ASubMainWindow
|
from View.Tools.PamhyrWindow import PamhyrWindow
|
||||||
from View.ListedSubWindow import ListedSubWindow
|
|
||||||
|
|
||||||
from PyQt5.QtGui import (
|
from PyQt5.QtGui import (
|
||||||
QKeySequence,
|
QKeySequence,
|
||||||
@@ -41,33 +40,36 @@ from PyQt5.QtWidgets import (
|
|||||||
|
|
||||||
from View.CheckList.Table import TableModel
|
from View.CheckList.Table import TableModel
|
||||||
from View.CheckList.Worker import Worker
|
from View.CheckList.Worker import Worker
|
||||||
|
from View.CheckList.Translate import CheckListTranslate
|
||||||
|
|
||||||
_translate = QCoreApplication.translate
|
_translate = QCoreApplication.translate
|
||||||
|
|
||||||
class CheckListWindow(ASubMainWindow, ListedSubWindow):
|
class CheckListWindow(PamhyrWindow):
|
||||||
|
_pamhyr_ui = "CheckList"
|
||||||
|
_pamhyr_name = "Check list"
|
||||||
|
|
||||||
signalStatus = pyqtSignal(str)
|
signalStatus = pyqtSignal(str)
|
||||||
|
|
||||||
def __init__(self, title="Check list",
|
def __init__(self, autorun:bool=True,
|
||||||
autorun:bool=True,
|
|
||||||
study=None, config=None,
|
study=None, config=None,
|
||||||
solver=None, parent=None):
|
solver=None, parent=None):
|
||||||
self._title = title + " - " + study.name
|
|
||||||
|
|
||||||
self._autorun = autorun
|
self._autorun = autorun
|
||||||
|
|
||||||
self._study = study
|
|
||||||
self._config = config
|
|
||||||
self._solver = solver
|
self._solver = solver
|
||||||
self._parent = parent
|
|
||||||
|
name = self._pamhyr_name + " - " + study.name
|
||||||
|
|
||||||
super(CheckListWindow, self).__init__(
|
super(CheckListWindow, self).__init__(
|
||||||
name=self._title, ui="CheckList", parent=parent
|
title = name,
|
||||||
|
study = study,
|
||||||
|
config = config,
|
||||||
|
trad = CheckListTranslate(),
|
||||||
|
options = [],
|
||||||
|
parent = parent
|
||||||
)
|
)
|
||||||
self.ui.setWindowTitle(self._title)
|
|
||||||
|
|
||||||
self._checker_list = (
|
self._checker_list = (
|
||||||
self._study.checkers() + self._solver.checkers()
|
self._study.checkers() +
|
||||||
|
self._solver.checkers()
|
||||||
)
|
)
|
||||||
|
|
||||||
self.setup_table()
|
self.setup_table()
|
||||||
@@ -78,16 +80,12 @@ class CheckListWindow(ASubMainWindow, ListedSubWindow):
|
|||||||
|
|
||||||
def setup_table(self):
|
def setup_table(self):
|
||||||
table = self.find(QTableView, f"tableView")
|
table = self.find(QTableView, f"tableView")
|
||||||
|
|
||||||
self._table = TableModel(
|
self._table = TableModel(
|
||||||
|
table_view = table,
|
||||||
|
table_headers = self._trad.get_dict("table_headers"),
|
||||||
data = self._checker_list,
|
data = self._checker_list,
|
||||||
)
|
)
|
||||||
|
|
||||||
table.setModel(self._table)
|
|
||||||
table.setSelectionBehavior(QAbstractItemView.SelectRows)
|
|
||||||
table.horizontalHeader().setSectionResizeMode(QHeaderView.Stretch)
|
|
||||||
table.setAlternatingRowColors(True)
|
|
||||||
|
|
||||||
def setup_progress_bar(self):
|
def setup_progress_bar(self):
|
||||||
self._progress = self.find(QProgressBar, f"progressBar")
|
self._progress = self.find(QProgressBar, f"progressBar")
|
||||||
self._p = 0 # Progress current step
|
self._p = 0 # Progress current step
|
||||||
|
|||||||
@@ -16,7 +16,7 @@
|
|||||||
|
|
||||||
# -*- coding: utf-8 -*-
|
# -*- coding: utf-8 -*-
|
||||||
|
|
||||||
from View.ASubWindow import ASubWindow
|
from View.Tools.PamhyrWindow import PamhyrDialog
|
||||||
from Solver.Solvers import solver_type_list
|
from Solver.Solvers import solver_type_list
|
||||||
from Solver.GenericSolver import GenericSolver
|
from Solver.GenericSolver import GenericSolver
|
||||||
|
|
||||||
@@ -24,12 +24,22 @@ from PyQt5.QtWidgets import (
|
|||||||
QPushButton,
|
QPushButton,
|
||||||
)
|
)
|
||||||
|
|
||||||
class ConfigureSolverWindow(ASubWindow):
|
class ConfigureSolverWindow(PamhyrDialog):
|
||||||
def __init__(self, data=None, title="Configuration : Add Solver", parent=None):
|
_pamhyr_ui = "ConfigureAddSolverDialog"
|
||||||
|
_pamhyr_name = "Add/Edit Solver"
|
||||||
|
|
||||||
|
def __init__(self, data=None, config=None, parent=None):
|
||||||
|
if data is not None:
|
||||||
|
name = f"Edit Solver - {data.name}"
|
||||||
|
else:
|
||||||
|
name = "Add a new Solver"
|
||||||
|
|
||||||
super(ConfigureSolverWindow, self).__init__(
|
super(ConfigureSolverWindow, self).__init__(
|
||||||
name=title, ui="ConfigureAddSolverDialog", parent=parent
|
title = name,
|
||||||
|
config = config,
|
||||||
|
options = [],
|
||||||
|
parent=parent
|
||||||
)
|
)
|
||||||
self.ui.setWindowTitle(title)
|
|
||||||
|
|
||||||
# Combo box item
|
# Combo box item
|
||||||
for solver in solver_type_list:
|
for solver in solver_type_list:
|
||||||
@@ -37,10 +47,10 @@ class ConfigureSolverWindow(ASubWindow):
|
|||||||
|
|
||||||
# Data to return
|
# Data to return
|
||||||
self.data = data
|
self.data = data
|
||||||
if not self.data is None:
|
if self.data is not None:
|
||||||
self.copy_data()
|
self.copy_data()
|
||||||
|
|
||||||
self.connect()
|
self.setup_connection()
|
||||||
|
|
||||||
def copy_data(self):
|
def copy_data(self):
|
||||||
self.set_combobox_text("comboBox_solver", self.data.type)
|
self.set_combobox_text("comboBox_solver", self.data.type)
|
||||||
@@ -53,7 +63,7 @@ class ConfigureSolverWindow(ASubWindow):
|
|||||||
self.set_line_edit_text("lineEdit_output", self.data._path_output)
|
self.set_line_edit_text("lineEdit_output", self.data._path_output)
|
||||||
self.set_line_edit_text("lineEdit_output_cmd", self.data._cmd_output)
|
self.set_line_edit_text("lineEdit_output_cmd", self.data._cmd_output)
|
||||||
|
|
||||||
def connect(self):
|
def setup_connection(self):
|
||||||
# File button
|
# File button
|
||||||
buttons = {
|
buttons = {
|
||||||
"pushButton_input": (lambda: self.file_dialog(
|
"pushButton_input": (lambda: self.file_dialog(
|
||||||
|
|||||||
@@ -21,8 +21,7 @@ import logging
|
|||||||
from copy import deepcopy
|
from copy import deepcopy
|
||||||
|
|
||||||
from config import Config
|
from config import Config
|
||||||
from View.ASubWindow import ASubWindow
|
from View.Tools.PamhyrWindow import PamhyrDialog
|
||||||
from View.ListedSubWindow import ListedSubWindow
|
|
||||||
|
|
||||||
from View.Stricklers.Table import TableModel
|
from View.Stricklers.Table import TableModel
|
||||||
from View.Stricklers.translate import *
|
from View.Stricklers.translate import *
|
||||||
@@ -95,50 +94,42 @@ class SolverTableModel(QAbstractTableModel):
|
|||||||
self.layoutChanged.emit()
|
self.layoutChanged.emit()
|
||||||
|
|
||||||
|
|
||||||
class ConfigureWindow(ASubWindow, ListedSubWindow):
|
class ConfigureWindow(PamhyrDialog):
|
||||||
def __init__(self, conf=None, title="Configure", parent=None):
|
_pamhyr_ui = "ConfigureDialog"
|
||||||
|
_pamhyr_name = "Configure"
|
||||||
|
|
||||||
|
def __init__(self, config=None, parent=None):
|
||||||
|
if config is None:
|
||||||
|
config = Config()
|
||||||
|
|
||||||
super(ConfigureWindow, self).__init__(
|
super(ConfigureWindow, self).__init__(
|
||||||
name=title, ui="ConfigureDialog", parent=parent
|
title = self._pamhyr_name,
|
||||||
|
config = config,
|
||||||
|
options = [],
|
||||||
|
parent=parent
|
||||||
)
|
)
|
||||||
self.ui.setWindowTitle(title)
|
|
||||||
|
|
||||||
if conf is None:
|
self.setup_custom_sc()
|
||||||
self.conf = Config()
|
self.setup_solver()
|
||||||
else:
|
self.setup_stricklers()
|
||||||
self.conf = conf
|
self.setup_data()
|
||||||
|
self.setup_connection()
|
||||||
|
|
||||||
self.setup_sc()
|
def setup_solver(self):
|
||||||
|
|
||||||
# Solver
|
|
||||||
table = self.find(QTableView, "tableView_solver")
|
table = self.find(QTableView, "tableView_solver")
|
||||||
self.solver_table_model = SolverTableModel(
|
self.solver_table_model = SolverTableModel(
|
||||||
headers = ["name", "type", "description"],
|
headers = ["name", "type", "description"],
|
||||||
rows = conf.solvers
|
rows = self._config.solvers
|
||||||
)
|
)
|
||||||
table.setModel(self.solver_table_model)
|
table.setModel(self.solver_table_model)
|
||||||
table.setSelectionBehavior(QAbstractItemView.SelectRows)
|
table.setSelectionBehavior(QAbstractItemView.SelectRows)
|
||||||
table.horizontalHeader().setSectionResizeMode(QHeaderView.Stretch)
|
table.horizontalHeader().setSectionResizeMode(QHeaderView.Stretch)
|
||||||
table.setAlternatingRowColors(True)
|
table.setAlternatingRowColors(True)
|
||||||
|
table.resizeColumnsToContents()
|
||||||
|
|
||||||
# Meshing_Tool
|
def setup_stricklers(self):
|
||||||
self.set_line_edit_text("lineEdit_meshing_tool", self.conf.meshing_tool)
|
|
||||||
|
|
||||||
# Const
|
|
||||||
self.set_line_edit_text("lineEdit_segment", str(self.conf.segment))
|
|
||||||
self.set_line_edit_text("lineEdit_max_listing", str(self.conf.max_listing))
|
|
||||||
|
|
||||||
# Backup
|
|
||||||
self.set_check_box("checkBox_backup", self.conf.backup_enable)
|
|
||||||
self.set_line_edit_text("lineEdit_backup_path", self.conf.backup_path)
|
|
||||||
self.set_time_edit("timeEdit_backup_frequence", self.conf.backup_frequence)
|
|
||||||
self.set_spin_box("spinBox_backup_max", self.conf.backup_max)
|
|
||||||
|
|
||||||
self.find(QTableView, "tableView_solver").resizeColumnsToContents()
|
|
||||||
self.connect()
|
|
||||||
|
|
||||||
# Stricklers
|
|
||||||
table = self.find(QTableView, f"tableView_stricklers")
|
table = self.find(QTableView, f"tableView_stricklers")
|
||||||
self._stricklers = deepcopy(self.conf.stricklers)
|
self._stricklers = deepcopy(self._config.stricklers)
|
||||||
self._stricklers_table = TableModel(
|
self._stricklers_table = TableModel(
|
||||||
data = self._stricklers,
|
data = self._stricklers,
|
||||||
undo = self._undo_stack,
|
undo = self._undo_stack,
|
||||||
@@ -148,26 +139,35 @@ class ConfigureWindow(ASubWindow, ListedSubWindow):
|
|||||||
table.horizontalHeader().setSectionResizeMode(QHeaderView.Stretch)
|
table.horizontalHeader().setSectionResizeMode(QHeaderView.Stretch)
|
||||||
table.setAlternatingRowColors(True)
|
table.setAlternatingRowColors(True)
|
||||||
|
|
||||||
|
def setup_data(self):
|
||||||
|
# Meshing_Tool
|
||||||
|
self.set_line_edit_text("lineEdit_meshing_tool", self._config.meshing_tool)
|
||||||
|
|
||||||
|
# Const
|
||||||
|
self.set_line_edit_text("lineEdit_segment", str(self._config.segment))
|
||||||
|
self.set_line_edit_text("lineEdit_max_listing", str(self._config.max_listing))
|
||||||
|
|
||||||
|
# Backup
|
||||||
|
self.set_check_box("checkBox_backup", self._config.backup_enable)
|
||||||
|
self.set_line_edit_text("lineEdit_backup_path", self._config.backup_path)
|
||||||
|
self.set_time_edit("timeEdit_backup_frequence", self._config.backup_frequence)
|
||||||
|
self.set_spin_box("spinBox_backup_max", self._config.backup_max)
|
||||||
|
|
||||||
# Editor
|
# Editor
|
||||||
self.set_line_edit_text("lineEdit_editor_cmd", str(self.conf.editor))
|
self.set_line_edit_text("lineEdit_editor_cmd", str(self._config.editor))
|
||||||
|
|
||||||
# Language
|
# Language
|
||||||
languages = Config.languages()
|
languages = Config.languages()
|
||||||
for lang in languages:
|
for lang in languages:
|
||||||
self.combobox_add_item("comboBox_language", lang)
|
self.combobox_add_item("comboBox_language", lang)
|
||||||
if self.conf.lang == languages[lang]:
|
if self._config.lang == languages[lang]:
|
||||||
self.set_combobox_text("comboBox_language", lang)
|
self.set_combobox_text("comboBox_language", lang)
|
||||||
|
|
||||||
def setup_sc(self):
|
def setup_custom_sc(self):
|
||||||
self._undo_stack = QUndoStack()
|
self._debug_sc = QShortcut(QKeySequence("Ctrl+G"), self)
|
||||||
|
self._debug_sc.activated.connect(self.set_debug)
|
||||||
|
|
||||||
self.debug_sc = QShortcut(QKeySequence("Ctrl+G"), self)
|
def setup_connection(self):
|
||||||
self.undo_sc = QShortcut(QKeySequence.Undo, self)
|
|
||||||
self.redo_sc = QShortcut(QKeySequence.Redo, self)
|
|
||||||
self.copy_sc = QShortcut(QKeySequence.Copy, self)
|
|
||||||
self.paste_sc = QShortcut(QKeySequence.Paste, self)
|
|
||||||
|
|
||||||
def connect(self):
|
|
||||||
buttons = {
|
buttons = {
|
||||||
# Solvers
|
# Solvers
|
||||||
"pushButton_solver_add": self.add_solver,
|
"pushButton_solver_add": self.add_solver,
|
||||||
@@ -195,33 +195,31 @@ class ConfigureWindow(ASubWindow, ListedSubWindow):
|
|||||||
for button in buttons:
|
for button in buttons:
|
||||||
self.find(QPushButton, button).clicked.connect(buttons[button])
|
self.find(QPushButton, button).clicked.connect(buttons[button])
|
||||||
|
|
||||||
self.debug_sc.activated.connect(self.set_debug)
|
|
||||||
|
|
||||||
def accept(self):
|
def accept(self):
|
||||||
# Solvers
|
# Solvers
|
||||||
self.conf.solvers = self.solver_table_model.rows.copy()
|
self._config.solvers = self.solver_table_model.rows.copy()
|
||||||
|
|
||||||
# Meshing_Tool
|
# Meshing_Tool
|
||||||
self.conf.meshing_tool = self.get_line_edit_text("lineEdit_meshing_tool")
|
self._config.meshing_tool = self.get_line_edit_text("lineEdit_meshing_tool")
|
||||||
|
|
||||||
# Const
|
# Const
|
||||||
self.conf.segment = self.get_line_edit_text("lineEdit_segment")
|
self._config.segment = self.get_line_edit_text("lineEdit_segment")
|
||||||
self.conf.max_listing = self.get_line_edit_text("lineEdit_max_listing")
|
self._config.max_listing = self.get_line_edit_text("lineEdit_max_listing")
|
||||||
|
|
||||||
# Backup
|
# Backup
|
||||||
self.conf.backup_enable = self.get_check_box("checkBox_backup")
|
self._config.backup_enable = self.get_check_box("checkBox_backup")
|
||||||
self.conf.backup_path = self.get_line_edit_text("lineEdit_backup_path")
|
self._config.backup_path = self.get_line_edit_text("lineEdit_backup_path")
|
||||||
self.conf.backup_frequence = self.get_time_edit("timeEdit_backup_frequence")
|
self._config.backup_frequence = self.get_time_edit("timeEdit_backup_frequence")
|
||||||
self.conf.backup_max = self.get_spin_box("spinBox_backup_max")
|
self._config.backup_max = self.get_spin_box("spinBox_backup_max")
|
||||||
|
|
||||||
# Stricklers
|
# Stricklers
|
||||||
self.conf.stricklers = deepcopy(self._stricklers)
|
self._config.stricklers = deepcopy(self._stricklers)
|
||||||
|
|
||||||
# Editor
|
# Editor
|
||||||
self.conf.editor = self.get_line_edit_text("lineEdit_editor_cmd")
|
self._config.editor = self.get_line_edit_text("lineEdit_editor_cmd")
|
||||||
|
|
||||||
# Language
|
# Language
|
||||||
self.conf.lang = Config.languages()[self.get_combobox_text("comboBox_language")]
|
self._config.lang = Config.languages()[self.get_combobox_text("comboBox_language")]
|
||||||
|
|
||||||
self.end()
|
self.end()
|
||||||
|
|
||||||
@@ -230,13 +228,13 @@ class ConfigureWindow(ASubWindow, ListedSubWindow):
|
|||||||
self.end()
|
self.end()
|
||||||
|
|
||||||
def end(self):
|
def end(self):
|
||||||
self.conf.save()
|
self._config.save()
|
||||||
self.close()
|
self.close()
|
||||||
|
|
||||||
# Debug
|
# Debug
|
||||||
def set_debug(self):
|
def set_debug(self):
|
||||||
self.conf.debug = not self.conf.debug
|
self._config.debug = not self._config.debug
|
||||||
logger.info(f"Debug mode set : {self.conf.debug}")
|
logger.info(f"Debug mode set : {self._config.debug}")
|
||||||
self.parent.setup_debug_mode()
|
self.parent.setup_debug_mode()
|
||||||
|
|
||||||
# Solvers
|
# Solvers
|
||||||
@@ -246,6 +244,7 @@ class ConfigureWindow(ASubWindow, ListedSubWindow):
|
|||||||
for index in indexes:
|
for index in indexes:
|
||||||
self.edit_solver = ConfigureSolverWindow(
|
self.edit_solver = ConfigureSolverWindow(
|
||||||
data=self.solver_table_model.rows[index.row()],
|
data=self.solver_table_model.rows[index.row()],
|
||||||
|
config=self._config,
|
||||||
parent=self
|
parent=self
|
||||||
)
|
)
|
||||||
if self.edit_solver.exec_():
|
if self.edit_solver.exec_():
|
||||||
|
|||||||
+11
-13
@@ -20,8 +20,7 @@ import logging
|
|||||||
|
|
||||||
from tools import trace, timer
|
from tools import trace, timer
|
||||||
|
|
||||||
from View.ASubWindow import ASubMainWindow
|
from View.Tools.PamhyrWindow import PamhyrWindow
|
||||||
from View.ListedSubWindow import ListedSubWindow
|
|
||||||
|
|
||||||
from PyQt5.QtGui import (
|
from PyQt5.QtGui import (
|
||||||
QKeySequence,
|
QKeySequence,
|
||||||
@@ -45,20 +44,19 @@ logger = logging.getLogger()
|
|||||||
|
|
||||||
_translate = QCoreApplication.translate
|
_translate = QCoreApplication.translate
|
||||||
|
|
||||||
class ReplWindow(ASubMainWindow, ListedSubWindow):
|
class ReplWindow(PamhyrWindow):
|
||||||
def __init__(self, title="Debug REPL",
|
_pamhyr_ui = "DebugRepl"
|
||||||
study=None, config=None,
|
_pamhyr_name = "Debug REPL"
|
||||||
|
|
||||||
|
def __init__(self, study=None, config=None,
|
||||||
solver=None, parent=None):
|
solver=None, parent=None):
|
||||||
self._title = title
|
|
||||||
|
|
||||||
self._study = study
|
|
||||||
self._config = config
|
|
||||||
self._parent = parent
|
|
||||||
|
|
||||||
super(ReplWindow, self).__init__(
|
super(ReplWindow, self).__init__(
|
||||||
name=self._title, ui="DebugRepl", parent=parent
|
title = self._pamhyr_name,
|
||||||
|
study = study,
|
||||||
|
config = config,
|
||||||
|
options = [],
|
||||||
|
parent = parent
|
||||||
)
|
)
|
||||||
self.ui.setWindowTitle(self._title)
|
|
||||||
|
|
||||||
self.__debug_exec_result__ = None
|
self.__debug_exec_result__ = None
|
||||||
self._history = []
|
self._history = []
|
||||||
|
|||||||
@@ -0,0 +1,97 @@
|
|||||||
|
# Window.py -- Pamhyr
|
||||||
|
# Copyright (C) 2023 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 os
|
||||||
|
import logging
|
||||||
|
import subprocess
|
||||||
|
|
||||||
|
from View.Tools.PamhyrWindow import PamhyrWindow
|
||||||
|
|
||||||
|
from PyQt5.QtCore import QCoreApplication
|
||||||
|
|
||||||
|
_translate = QCoreApplication.translate
|
||||||
|
logger = logging.getLogger()
|
||||||
|
|
||||||
|
|
||||||
|
from PyQt5.QtWidgets import QApplication, QWidget, QVBoxLayout, QAction
|
||||||
|
from PyQt5.QtCore import QUrl
|
||||||
|
from PyQt5.QtWebEngineWidgets import QWebEngineView, QWebEngineSettings
|
||||||
|
|
||||||
|
class DocWindow(PamhyrWindow):
|
||||||
|
_pamhyr_ui = "WebView"
|
||||||
|
_pamhyr_name = "Doc"
|
||||||
|
|
||||||
|
def _path_file(self, filename):
|
||||||
|
return os.path.abspath(
|
||||||
|
os.path.join(
|
||||||
|
os.path.dirname(__file__),
|
||||||
|
"..", "..", "..", "doc", filename
|
||||||
|
)
|
||||||
|
)
|
||||||
|
|
||||||
|
def __init__(self, filename=None,
|
||||||
|
study=None, config=None,
|
||||||
|
parent=None):
|
||||||
|
super(DocWindow, self).__init__(
|
||||||
|
title = self._pamhyr_name,
|
||||||
|
study = study,
|
||||||
|
config = config,
|
||||||
|
options = [],
|
||||||
|
parent = parent
|
||||||
|
|
||||||
|
)
|
||||||
|
|
||||||
|
self._path = self._path_file(filename)
|
||||||
|
|
||||||
|
self.setup_web_engine()
|
||||||
|
self.setup_url(self._path)
|
||||||
|
self.setup_connection()
|
||||||
|
|
||||||
|
def setup_connection(self):
|
||||||
|
self.findChild(QAction, "action_back").triggered.connect(self.back)
|
||||||
|
self.findChild(QAction, "action_forward").triggered.connect(self.forward)
|
||||||
|
|
||||||
|
self.findChild(QAction, "action_firefox").triggered.connect(self.open_in_firefox)
|
||||||
|
|
||||||
|
|
||||||
|
def setup_web_engine(self):
|
||||||
|
vl = self.find(QVBoxLayout, "verticalLayout")
|
||||||
|
self._web_view = QWebEngineView()
|
||||||
|
|
||||||
|
settings = self._web_view.settings()
|
||||||
|
settings.setAttribute(QWebEngineSettings.PluginsEnabled, True)
|
||||||
|
settings.setAttribute(QWebEngineSettings.JavascriptEnabled, True)
|
||||||
|
settings.setAttribute(QWebEngineSettings.PdfViewerEnabled, True)
|
||||||
|
|
||||||
|
vl.addWidget(self._web_view)
|
||||||
|
|
||||||
|
def setup_url(self, filename):
|
||||||
|
logger.info(f"Open documentation : {filename}")
|
||||||
|
self._web_view.setUrl(QUrl(f"file://{self._path_file(filename)}"))
|
||||||
|
|
||||||
|
def back(self):
|
||||||
|
self._web_view.back()
|
||||||
|
|
||||||
|
def forward(self):
|
||||||
|
self._web_view.forward()
|
||||||
|
|
||||||
|
def open_in_firefox(self):
|
||||||
|
_ = subprocess.Popen(
|
||||||
|
f"firefox {self._path}",
|
||||||
|
shell = True
|
||||||
|
)
|
||||||
+10
-5
@@ -16,9 +16,14 @@
|
|||||||
|
|
||||||
# -*- coding: utf-8 -*-
|
# -*- coding: utf-8 -*-
|
||||||
|
|
||||||
from View.ASubWindow import ASubWindow
|
from View.Tools.PamhyrWindow import PamhyrWindow
|
||||||
|
|
||||||
class DummyWindow(ASubWindow):
|
class DummyWindow(PamhyrWindow):
|
||||||
def __init__(self, title="Dummy", parent=None):
|
__ui = "Dummy"
|
||||||
super(DummyWindow, self).__init__(name=title, ui="dummy", parent=parent)
|
__name = "Pamhyr Dummy Window"
|
||||||
self.ui.setWindowTitle(title)
|
|
||||||
|
def __init__(self, parent=None):
|
||||||
|
super(DummyWindow, self).__init__(
|
||||||
|
title = self.__name,
|
||||||
|
parent = parent,
|
||||||
|
)
|
||||||
@@ -17,7 +17,7 @@
|
|||||||
# -*- coding: utf-8 -*-
|
# -*- coding: utf-8 -*-
|
||||||
|
|
||||||
from tools import timer, flatten
|
from tools import timer, flatten
|
||||||
from View.Plot.APlot import APlot
|
from View.Tools.PamhyrPlot import PamhyrPlot
|
||||||
|
|
||||||
from PyQt5.QtCore import (
|
from PyQt5.QtCore import (
|
||||||
QCoreApplication
|
QCoreApplication
|
||||||
@@ -25,14 +25,7 @@ from PyQt5.QtCore import (
|
|||||||
|
|
||||||
_translate = QCoreApplication.translate
|
_translate = QCoreApplication.translate
|
||||||
|
|
||||||
class PlotStricklers(APlot):
|
class PlotStricklers(PamhyrPlot):
|
||||||
def __init__(self, canvas=None, data=None, toolbar=None):
|
|
||||||
super(PlotStricklers, self).__init__(
|
|
||||||
canvas=canvas,
|
|
||||||
data=data,
|
|
||||||
toolbar=toolbar
|
|
||||||
)
|
|
||||||
|
|
||||||
def draw_frictions(self, frictions, color="r"):
|
def draw_frictions(self, frictions, color="r"):
|
||||||
lst = frictions
|
lst = frictions
|
||||||
lst.sort(key = lambda s: s.begin_kp)
|
lst.sort(key = lambda s: s.begin_kp)
|
||||||
|
|||||||
+22
-42
@@ -41,6 +41,8 @@ from View.Frictions.UndoCommand import (
|
|||||||
MoveCommand, PasteCommand, DuplicateCommand,
|
MoveCommand, PasteCommand, DuplicateCommand,
|
||||||
)
|
)
|
||||||
|
|
||||||
|
from View.Tools.PamhyrTable import PamhyrTableModel
|
||||||
|
|
||||||
from View.Frictions.translate import *
|
from View.Frictions.translate import *
|
||||||
|
|
||||||
logger = logging.getLogger()
|
logger = logging.getLogger()
|
||||||
@@ -93,26 +95,10 @@ class ComboBoxDelegate(QItemDelegate):
|
|||||||
self.commitData.emit(self.sender())
|
self.commitData.emit(self.sender())
|
||||||
|
|
||||||
|
|
||||||
class TableModel(QAbstractTableModel):
|
class TableModel(PamhyrTableModel):
|
||||||
def __init__(self, data=None, study=None, undo=None):
|
def _setup_lst(self):
|
||||||
super(QAbstractTableModel, self).__init__()
|
self._lst = self._data.frictions
|
||||||
self._headers = list(table_headers.keys())
|
self._study = self._opt_data
|
||||||
self._data = data
|
|
||||||
self._study = study
|
|
||||||
self._undo = undo
|
|
||||||
self._frictions = self._data.frictions
|
|
||||||
|
|
||||||
def flags(self, index):
|
|
||||||
options = Qt.ItemIsEnabled | Qt.ItemIsSelectable
|
|
||||||
options |= Qt.ItemIsEditable
|
|
||||||
|
|
||||||
return options
|
|
||||||
|
|
||||||
def rowCount(self, parent):
|
|
||||||
return len(self._frictions)
|
|
||||||
|
|
||||||
def columnCount(self, parent):
|
|
||||||
return len(self._headers)
|
|
||||||
|
|
||||||
def data(self, index, role):
|
def data(self, index, role):
|
||||||
if role != Qt.ItemDataRole.DisplayRole:
|
if role != Qt.ItemDataRole.DisplayRole:
|
||||||
@@ -122,30 +108,24 @@ class TableModel(QAbstractTableModel):
|
|||||||
column = index.column()
|
column = index.column()
|
||||||
|
|
||||||
if self._headers[column] == "name":
|
if self._headers[column] == "name":
|
||||||
return self._frictions.get(row).name
|
return self._lst.get(row).name
|
||||||
elif self._headers[column] == "begin_kp":
|
elif self._headers[column] == "begin_kp":
|
||||||
return self._frictions.get(row).begin_kp
|
return self._lst.get(row).begin_kp
|
||||||
elif self._headers[column] == "end_kp":
|
elif self._headers[column] == "end_kp":
|
||||||
return self._frictions.get(row).end_kp
|
return self._lst.get(row).end_kp
|
||||||
elif self._headers[column] == "begin_strickler":
|
elif self._headers[column] == "begin_strickler":
|
||||||
value = self._frictions.get(row).begin_strickler
|
value = self._lst.get(row).begin_strickler
|
||||||
if value == None:
|
if value == None:
|
||||||
return _translate("Frictions", "Not defined")
|
return _translate("Frictions", "Not defined")
|
||||||
return str(value)
|
return str(value)
|
||||||
elif self._headers[column] == "end_strickler":
|
elif self._headers[column] == "end_strickler":
|
||||||
value = self._frictions.get(row).end_strickler
|
value = self._lst.get(row).end_strickler
|
||||||
if value == None:
|
if value == None:
|
||||||
return _translate("Frictions", "Not defined")
|
return _translate("Frictions", "Not defined")
|
||||||
return str(value)
|
return str(value)
|
||||||
|
|
||||||
return QVariant()
|
return QVariant()
|
||||||
|
|
||||||
def headerData(self, friction, orientation, role):
|
|
||||||
if role == Qt.ItemDataRole.DisplayRole and orientation == Qt.Orientation.Horizontal:
|
|
||||||
return table_headers[self._headers[friction]]
|
|
||||||
|
|
||||||
return QVariant()
|
|
||||||
|
|
||||||
def setData(self, index, value, role=Qt.EditRole):
|
def setData(self, index, value, role=Qt.EditRole):
|
||||||
if not index.isValid() or role != Qt.EditRole:
|
if not index.isValid() or role != Qt.EditRole:
|
||||||
return False
|
return False
|
||||||
@@ -157,31 +137,31 @@ class TableModel(QAbstractTableModel):
|
|||||||
if self._headers[column] == "name":
|
if self._headers[column] == "name":
|
||||||
self._undo.push(
|
self._undo.push(
|
||||||
SetNameCommand(
|
SetNameCommand(
|
||||||
self._frictions, row, value
|
self._lst, row, value
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
elif self._headers[column] == "begin_kp":
|
elif self._headers[column] == "begin_kp":
|
||||||
self._undo.push(
|
self._undo.push(
|
||||||
SetBeginCommand(
|
SetBeginCommand(
|
||||||
self._frictions, row, value
|
self._lst, row, value
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
elif self._headers[column] == "end_kp":
|
elif self._headers[column] == "end_kp":
|
||||||
self._undo.push(
|
self._undo.push(
|
||||||
SetEndCommand(
|
SetEndCommand(
|
||||||
self._frictions, row, value
|
self._lst, row, value
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
elif self._headers[column] == "begin_strickler":
|
elif self._headers[column] == "begin_strickler":
|
||||||
self._undo.push(
|
self._undo.push(
|
||||||
SetBeginStricklerCommand(
|
SetBeginStricklerCommand(
|
||||||
self._frictions, row, self._study.river.strickler(value)
|
self._lst, row, self._study.river.strickler(value)
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
elif self._headers[column] == "end_strickler":
|
elif self._headers[column] == "end_strickler":
|
||||||
self._undo.push(
|
self._undo.push(
|
||||||
SetEndStricklerCommand(
|
SetEndStricklerCommand(
|
||||||
self._frictions, row, self._study.river.strickler(value)
|
self._lst, row, self._study.river.strickler(value)
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
@@ -196,7 +176,7 @@ class TableModel(QAbstractTableModel):
|
|||||||
|
|
||||||
self._undo.push(
|
self._undo.push(
|
||||||
AddCommand(
|
AddCommand(
|
||||||
self._frictions, row, self._data
|
self._lst, row, self._data
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -208,7 +188,7 @@ class TableModel(QAbstractTableModel):
|
|||||||
|
|
||||||
self._undo.push(
|
self._undo.push(
|
||||||
DelCommand(
|
DelCommand(
|
||||||
self._frictions, rows
|
self._lst, rows
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -220,7 +200,7 @@ class TableModel(QAbstractTableModel):
|
|||||||
|
|
||||||
self._undo.push(
|
self._undo.push(
|
||||||
SortCommand(
|
SortCommand(
|
||||||
self._frictions, False
|
self._lst, False
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -237,7 +217,7 @@ class TableModel(QAbstractTableModel):
|
|||||||
|
|
||||||
self._undo_stack.push(
|
self._undo_stack.push(
|
||||||
MoveCommand(
|
MoveCommand(
|
||||||
self._frictions, "up", row
|
self._lst, "up", row
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -245,7 +225,7 @@ class TableModel(QAbstractTableModel):
|
|||||||
self.layoutChanged.emit()
|
self.layoutChanged.emit()
|
||||||
|
|
||||||
def move_down(self, index, parent=QModelIndex()):
|
def move_down(self, index, parent=QModelIndex()):
|
||||||
if row > len(self._frictions):
|
if row > len(self._lst):
|
||||||
return
|
return
|
||||||
|
|
||||||
target = row
|
target = row
|
||||||
@@ -254,7 +234,7 @@ class TableModel(QAbstractTableModel):
|
|||||||
|
|
||||||
self._undo_stack.push(
|
self._undo_stack.push(
|
||||||
MoveCommand(
|
MoveCommand(
|
||||||
self._frictions, "down", row
|
self._lst, "down", row
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|||||||
@@ -20,8 +20,7 @@ import logging
|
|||||||
|
|
||||||
from tools import trace, timer
|
from tools import trace, timer
|
||||||
|
|
||||||
from View.ASubWindow import ASubMainWindow
|
from View.Tools.PamhyrWindow import PamhyrWindow
|
||||||
from View.ListedSubWindow import ListedSubWindow
|
|
||||||
|
|
||||||
from PyQt5.QtGui import (
|
from PyQt5.QtGui import (
|
||||||
QKeySequence,
|
QKeySequence,
|
||||||
@@ -48,63 +47,49 @@ from View.Frictions.Table import (
|
|||||||
TableModel, ComboBoxDelegate
|
TableModel, ComboBoxDelegate
|
||||||
)
|
)
|
||||||
|
|
||||||
from View.Plot.MplCanvas import MplCanvas
|
from View.Tools.Plot.PamhyrCanvas import MplCanvas
|
||||||
from View.Geometry.PlotKPZ import PlotKPZ
|
from View.Geometry.PlotKPZ import PlotKPZ
|
||||||
from View.Frictions.PlotStricklers import PlotStricklers
|
from View.Frictions.PlotStricklers import PlotStricklers
|
||||||
from View.Frictions.translate import table_headers, retranslate
|
from View.Frictions.translate import FrictionsTranslate
|
||||||
|
|
||||||
from View.Stricklers.Window import StricklersWindow
|
from View.Stricklers.Window import StricklersWindow
|
||||||
|
|
||||||
_translate = QCoreApplication.translate
|
|
||||||
|
|
||||||
logger = logging.getLogger()
|
logger = logging.getLogger()
|
||||||
|
|
||||||
class FrictionsWindow(ASubMainWindow, ListedSubWindow):
|
class FrictionsWindow(PamhyrWindow):
|
||||||
def __init__(self, title="Frictions", study=None, parent=None):
|
_pamhyr_ui = "Frictions"
|
||||||
self._study = study
|
_pamhyr_name = "Edit frictions"
|
||||||
self._reach = self._study.river.current_reach()
|
|
||||||
|
def __init__(self, reach=None, study=None, config=None, parent=None):
|
||||||
|
if reach is not None:
|
||||||
|
self._reach = reach
|
||||||
|
else:
|
||||||
|
self._reach = study.river.current_reach()
|
||||||
|
|
||||||
self._frictions = self._reach.frictions
|
self._frictions = self._reach.frictions
|
||||||
|
|
||||||
self.setup_title(title)
|
name = (
|
||||||
|
self._pamhyr_name + " - "
|
||||||
super(FrictionsWindow, self).__init__(
|
+ study.name + " - "
|
||||||
name=title, ui="Frictions", parent=parent
|
+ self._reach.name
|
||||||
|
)
|
||||||
|
|
||||||
|
super(FrictionsWindow, self).__init__(
|
||||||
|
title = name,
|
||||||
|
study = study,
|
||||||
|
config = config,
|
||||||
|
trad = FrictionsTranslate(),
|
||||||
|
parent = parent
|
||||||
)
|
)
|
||||||
|
|
||||||
self.setup_sc()
|
|
||||||
self.setup_table()
|
self.setup_table()
|
||||||
self.setup_graph()
|
self.setup_graph()
|
||||||
self.setup_connections()
|
self.setup_connections()
|
||||||
|
|
||||||
self.ui.setWindowTitle(self._title)
|
|
||||||
|
|
||||||
def setup_title(self, title):
|
|
||||||
self._title = (
|
|
||||||
title + " - "
|
|
||||||
+ self._study.name + " - "
|
|
||||||
+ self._reach.name
|
|
||||||
)
|
|
||||||
|
|
||||||
def setup_sc(self):
|
|
||||||
self._undo_stack = QUndoStack()
|
|
||||||
|
|
||||||
self.undo_sc = QShortcut(QKeySequence.Undo, self)
|
|
||||||
self.redo_sc = QShortcut(QKeySequence.Redo, self)
|
|
||||||
self.copy_sc = QShortcut(QKeySequence.Copy, self)
|
|
||||||
self.paste_sc = QShortcut(QKeySequence.Paste, self)
|
|
||||||
|
|
||||||
def setup_table(self):
|
def setup_table(self):
|
||||||
retranslate()
|
|
||||||
self._table = {}
|
self._table = {}
|
||||||
|
|
||||||
table = self.find(QTableView, f"tableView")
|
|
||||||
self._table = TableModel(
|
|
||||||
data = self._reach,
|
|
||||||
study = self._study,
|
|
||||||
undo = self._undo_stack,
|
|
||||||
)
|
|
||||||
table.setModel(self._table)
|
|
||||||
|
|
||||||
self._delegate_stricklers = ComboBoxDelegate(
|
self._delegate_stricklers = ComboBoxDelegate(
|
||||||
data = self._reach,
|
data = self._reach,
|
||||||
study = self._study,
|
study = self._study,
|
||||||
@@ -112,13 +97,23 @@ class FrictionsWindow(ASubMainWindow, ListedSubWindow):
|
|||||||
parent=self
|
parent=self
|
||||||
)
|
)
|
||||||
|
|
||||||
table.setItemDelegateForColumn(
|
table = self.find(QTableView, f"tableView")
|
||||||
3, self._delegate_stricklers
|
self._table = TableModel(
|
||||||
|
table_view = table,
|
||||||
|
table_headers = self._trad.get_dict("table_headers"),
|
||||||
|
editable_headers = [
|
||||||
|
"name", "begin_kp", "end_kp",
|
||||||
|
"begin_strickler", "end_strickler"
|
||||||
|
],
|
||||||
|
delegates = {
|
||||||
|
"begin_strickler": self._delegate_stricklers,
|
||||||
|
"end_strickler": self._delegate_stricklers,
|
||||||
|
},
|
||||||
|
data = self._reach,
|
||||||
|
undo = self._undo_stack,
|
||||||
|
opt_data = self._study
|
||||||
)
|
)
|
||||||
table.setItemDelegateForColumn(
|
table.setModel(self._table)
|
||||||
4, self._delegate_stricklers
|
|
||||||
)
|
|
||||||
|
|
||||||
table.setSelectionBehavior(QAbstractItemView.SelectRows)
|
table.setSelectionBehavior(QAbstractItemView.SelectRows)
|
||||||
table.horizontalHeader().setSectionResizeMode(QHeaderView.Stretch)
|
table.horizontalHeader().setSectionResizeMode(QHeaderView.Stretch)
|
||||||
table.setAlternatingRowColors(True)
|
table.setAlternatingRowColors(True)
|
||||||
@@ -156,11 +151,6 @@ class FrictionsWindow(ASubMainWindow, ListedSubWindow):
|
|||||||
self.find(QAction, "action_sort").triggered.connect(self.sort)
|
self.find(QAction, "action_sort").triggered.connect(self.sort)
|
||||||
self.find(QAction, "action_edit_stricklers").triggered.connect(self.edit_stricklers)
|
self.find(QAction, "action_edit_stricklers").triggered.connect(self.edit_stricklers)
|
||||||
|
|
||||||
self.undo_sc.activated.connect(self.undo)
|
|
||||||
self.redo_sc.activated.connect(self.redo)
|
|
||||||
self.copy_sc.activated.connect(self.copy)
|
|
||||||
self.paste_sc.activated.connect(self.paste)
|
|
||||||
|
|
||||||
table = self.find(QTableView, f"tableView")
|
table = self.find(QTableView, f"tableView")
|
||||||
table.selectionModel()\
|
table.selectionModel()\
|
||||||
.selectionChanged\
|
.selectionChanged\
|
||||||
@@ -234,16 +224,16 @@ class FrictionsWindow(ASubMainWindow, ListedSubWindow):
|
|||||||
row = self.index_selected_row()
|
row = self.index_selected_row()
|
||||||
self._table.move_down(row)
|
self._table.move_down(row)
|
||||||
|
|
||||||
def copy(self):
|
def _copy(self):
|
||||||
logger.info("TODO: copy")
|
logger.info("TODO: copy")
|
||||||
|
|
||||||
def paste(self):
|
def _paste(self):
|
||||||
logger.info("TODO: paste")
|
logger.info("TODO: paste")
|
||||||
|
|
||||||
def undo(self):
|
def _undo(self):
|
||||||
self._table.undo()
|
self._table.undo()
|
||||||
|
|
||||||
def redo(self):
|
def _redo(self):
|
||||||
self._table.redo()
|
self._table.redo()
|
||||||
|
|
||||||
def edit_stricklers(self):
|
def edit_stricklers(self):
|
||||||
|
|||||||
@@ -18,21 +18,19 @@
|
|||||||
|
|
||||||
from PyQt5.QtCore import QCoreApplication
|
from PyQt5.QtCore import QCoreApplication
|
||||||
|
|
||||||
|
from View.Tools.PamhyrTranslate import PamhyrTranslate
|
||||||
|
|
||||||
_translate = QCoreApplication.translate
|
_translate = QCoreApplication.translate
|
||||||
|
|
||||||
table_headers = {
|
class FrictionsTranslate(PamhyrTranslate):
|
||||||
"name": _translate("Frictions", "Name"),
|
def __init__(self):
|
||||||
# "edge": _translate("Frictions", "Reach"),
|
super(FrictionsTranslate, self).__init__()
|
||||||
"begin_kp": _translate("Frictions", "Begin kp (m)"),
|
|
||||||
"end_kp": _translate("Frictions", "End kp (m)"),
|
|
||||||
"begin_strickler": _translate("Frictions", "Begin strickler"),
|
|
||||||
"end_strickler": _translate("Frictions", "End strickler"),
|
|
||||||
}
|
|
||||||
|
|
||||||
def retranslate():
|
self._sub_dict["table_headers"] = {
|
||||||
table_headers["name"] = _translate("Frictions", "Name")
|
"name": _translate("Frictions", "Name"),
|
||||||
# table_headers["edge"] = _translate("Frictions", "Reach")
|
# "edge": _translate("Frictions", "Reach"),
|
||||||
table_headers["begin_kp"] = _translate("Frictions", "Begin kp (m)")
|
"begin_kp": _translate("Frictions", "Begin kp (m)"),
|
||||||
table_headers["end_kp"] = _translate("Frictions", "End kp (m)")
|
"end_kp": _translate("Frictions", "End kp (m)"),
|
||||||
table_headers["begin_strickler"] = _translate("Frictions", "Begin strickler")
|
"begin_strickler": _translate("Frictions", "Begin strickler"),
|
||||||
table_headers["end_strickler"] = _translate("Frictions", "End strickler")
|
"end_strickler": _translate("Frictions", "End strickler"),
|
||||||
|
}
|
||||||
@@ -19,7 +19,7 @@
|
|||||||
import logging
|
import logging
|
||||||
|
|
||||||
from tools import timer
|
from tools import timer
|
||||||
from View.Plot.APlot import APlot
|
from View.Tools.PamhyrPlot import PamhyrPlot
|
||||||
|
|
||||||
from PyQt5.QtCore import (
|
from PyQt5.QtCore import (
|
||||||
QCoreApplication
|
QCoreApplication
|
||||||
@@ -29,12 +29,15 @@ _translate = QCoreApplication.translate
|
|||||||
|
|
||||||
logger = logging.getLogger()
|
logger = logging.getLogger()
|
||||||
|
|
||||||
class PlotAC(APlot):
|
class PlotAC(PamhyrPlot):
|
||||||
def __init__(self, canvas=None, data=None, toolbar=None, plot_xy=None):
|
def __init__(self, canvas=None, trad=None, data=None, toolbar=None,
|
||||||
|
plot_xy=None, parent=None):
|
||||||
super(PlotAC, self).__init__(
|
super(PlotAC, self).__init__(
|
||||||
canvas=canvas,
|
canvas = canvas,
|
||||||
data=data,
|
trad = trad,
|
||||||
toolbar=toolbar
|
data = data,
|
||||||
|
toolbar = toolbar,
|
||||||
|
parent = parent
|
||||||
)
|
)
|
||||||
|
|
||||||
self.plot_xy = plot_xy
|
self.plot_xy = plot_xy
|
||||||
|
|||||||
@@ -19,7 +19,7 @@
|
|||||||
import logging
|
import logging
|
||||||
|
|
||||||
from tools import timer
|
from tools import timer
|
||||||
from View.Plot.APlot import APlot
|
from View.Tools.PamhyrPlot import PamhyrPlot
|
||||||
|
|
||||||
from PyQt5.QtCore import (
|
from PyQt5.QtCore import (
|
||||||
QCoreApplication
|
QCoreApplication
|
||||||
@@ -29,13 +29,15 @@ _translate = QCoreApplication.translate
|
|||||||
|
|
||||||
logger = logging.getLogger()
|
logger = logging.getLogger()
|
||||||
|
|
||||||
class PlotKPZ(APlot):
|
class PlotKPZ(PamhyrPlot):
|
||||||
def __init__(self, canvas=None, data=None, toolbar=None,
|
def __init__(self, canvas=None, trad=None, data=None, toolbar=None,
|
||||||
display_current=True):
|
display_current=True, parent=None):
|
||||||
super(PlotKPZ, self).__init__(
|
super(PlotKPZ, self).__init__(
|
||||||
canvas=canvas,
|
canvas = canvas,
|
||||||
data=data,
|
trad = trad,
|
||||||
toolbar=toolbar
|
data = data,
|
||||||
|
toolbar = toolbar,
|
||||||
|
parent = parent
|
||||||
)
|
)
|
||||||
|
|
||||||
self.display_current = display_current
|
self.display_current = display_current
|
||||||
|
|||||||
@@ -17,7 +17,7 @@
|
|||||||
# -*- coding: utf-8 -*-
|
# -*- coding: utf-8 -*-
|
||||||
|
|
||||||
from tools import timer, trace
|
from tools import timer, trace
|
||||||
from View.Plot.APlot import APlot
|
from View.Tools.PamhyrPlot import PamhyrPlot
|
||||||
|
|
||||||
from PyQt5.QtCore import (
|
from PyQt5.QtCore import (
|
||||||
QCoreApplication
|
QCoreApplication
|
||||||
@@ -25,12 +25,15 @@ from PyQt5.QtCore import (
|
|||||||
|
|
||||||
_translate = QCoreApplication.translate
|
_translate = QCoreApplication.translate
|
||||||
|
|
||||||
class PlotXY(APlot):
|
class PlotXY(PamhyrPlot):
|
||||||
def __init__(self, canvas=None, data=None, toolbar=None, display_current=True):
|
def __init__(self, canvas=None, trad=None, data=None, toolbar=None,
|
||||||
|
display_current=True, parent=None):
|
||||||
super(PlotXY, self).__init__(
|
super(PlotXY, self).__init__(
|
||||||
canvas=canvas,
|
canvas = canvas,
|
||||||
data=data,
|
trad = trad,
|
||||||
toolbar=toolbar
|
data = data,
|
||||||
|
toolbar = toolbar,
|
||||||
|
parent = parent
|
||||||
)
|
)
|
||||||
|
|
||||||
self.display_current = display_current
|
self.display_current = display_current
|
||||||
@@ -60,11 +63,11 @@ class PlotXY(APlot):
|
|||||||
|
|
||||||
# Axes
|
# Axes
|
||||||
self.canvas.axes.set_xlabel(
|
self.canvas.axes.set_xlabel(
|
||||||
_translate("MainWindow_reach", "X (m)"),
|
_translate("Geometry", "X (m)"),
|
||||||
color='green', fontsize=12
|
color='green', fontsize=12
|
||||||
)
|
)
|
||||||
self.canvas.axes.set_ylabel(
|
self.canvas.axes.set_ylabel(
|
||||||
_translate("MainWindow_reach", "Y (m)"),
|
_translate("Geometry", "Y (m)"),
|
||||||
color='green', fontsize=12
|
color='green', fontsize=12
|
||||||
)
|
)
|
||||||
self.canvas.axes.axis("equal")
|
self.canvas.axes.axis("equal")
|
||||||
|
|||||||
@@ -19,8 +19,8 @@
|
|||||||
import logging
|
import logging
|
||||||
|
|
||||||
from tools import timer, trace
|
from tools import timer, trace
|
||||||
from View.Plot.APlot import APlot
|
from View.Tools.PamhyrPlot import PamhyrPlot
|
||||||
from View.Plot.mpl_canvas_onpick_event import OnpickEvent
|
from View.Tools.Plot.OnPickEvent import OnpickEvent
|
||||||
|
|
||||||
from PyQt5.QtCore import (
|
from PyQt5.QtCore import (
|
||||||
QCoreApplication
|
QCoreApplication
|
||||||
@@ -30,12 +30,15 @@ _translate = QCoreApplication.translate
|
|||||||
|
|
||||||
logger = logging.getLogger()
|
logger = logging.getLogger()
|
||||||
|
|
||||||
class Plot(APlot):
|
class Plot(PamhyrPlot):
|
||||||
def __init__(self, canvas=None, data=None, toolbar=None, table=None):
|
def __init__(self, canvas=None, trad=None, data=None, toolbar=None,
|
||||||
|
table=None, parent=None):
|
||||||
super(Plot, self).__init__(
|
super(Plot, self).__init__(
|
||||||
canvas=canvas,
|
canvas = canvas,
|
||||||
data=data,
|
trad = trad,
|
||||||
toolbar=toolbar
|
data = data,
|
||||||
|
toolbar = toolbar,
|
||||||
|
parent = parent
|
||||||
)
|
)
|
||||||
|
|
||||||
self._table = table
|
self._table = table
|
||||||
|
|||||||
@@ -29,10 +29,11 @@ from PyQt5.QtWidgets import (
|
|||||||
QMessageBox, QStyledItemDelegate, QLineEdit
|
QMessageBox, QStyledItemDelegate, QLineEdit
|
||||||
)
|
)
|
||||||
from PyQt5.QtCore import (
|
from PyQt5.QtCore import (
|
||||||
QModelIndex, Qt, QAbstractTableModel,
|
QModelIndex, Qt, QVariant, QCoreApplication
|
||||||
QVariant, QCoreApplication
|
|
||||||
)
|
)
|
||||||
|
|
||||||
|
from View.Tools.PamhyrTable import PamhyrTableModel
|
||||||
|
|
||||||
from Model.Geometry.PointXYZ import PointXYZ
|
from Model.Geometry.PointXYZ import PointXYZ
|
||||||
from Model.Geometry.ProfileXYZ import ProfileXYZ
|
from Model.Geometry.ProfileXYZ import ProfileXYZ
|
||||||
|
|
||||||
@@ -43,43 +44,22 @@ logger = logging.getLogger()
|
|||||||
_translate = QCoreApplication.translate
|
_translate = QCoreApplication.translate
|
||||||
|
|
||||||
|
|
||||||
class TableEditableModel(QAbstractTableModel):
|
class GeometryProfileTableModel(PamhyrTableModel):
|
||||||
def __init__(self, profile: ProfileXYZ, header=None, undo=None):
|
|
||||||
QAbstractTableModel.__init__(self)
|
|
||||||
|
|
||||||
self._undo_stack = undo
|
|
||||||
self._profile = profile
|
|
||||||
|
|
||||||
if header is None:
|
|
||||||
self._header = [
|
|
||||||
"X (m)", "Y (m)", "Z (m)",
|
|
||||||
_translate("MainWindowProfile", "Nom"),
|
|
||||||
_translate("MainWindowProfile", "Abs en travers (m)")
|
|
||||||
]
|
|
||||||
else:
|
|
||||||
self._header = header
|
|
||||||
|
|
||||||
def rowCount(self, parent=QModelIndex()):
|
|
||||||
return self._profile.number_points
|
|
||||||
|
|
||||||
def columnCount(self, parent=QModelIndex()):
|
|
||||||
return len(self._header)
|
|
||||||
|
|
||||||
def data(self, index, role=Qt.DisplayRole):
|
def data(self, index, role=Qt.DisplayRole):
|
||||||
if index.isValid():
|
if index.isValid():
|
||||||
if role == Qt.DisplayRole:
|
if role == Qt.DisplayRole:
|
||||||
value = ""
|
value = ""
|
||||||
|
|
||||||
if index.column() == 0:
|
if index.column() == 0:
|
||||||
value = self._profile.point(index.row()).x
|
value = self._data.point(index.row()).x
|
||||||
elif index.column() == 1:
|
elif index.column() == 1:
|
||||||
value = self._profile.point(index.row()).y
|
value = self._data.point(index.row()).y
|
||||||
elif index.column() == 2:
|
elif index.column() == 2:
|
||||||
value = self._profile.point(index.row()).z
|
value = self._data.point(index.row()).z
|
||||||
elif index.column() == 3:
|
elif index.column() == 3:
|
||||||
value = self._profile.point(index.row()).name
|
value = self._data.point(index.row()).name
|
||||||
elif index.column() == 4:
|
elif index.column() == 4:
|
||||||
station = self._profile.get_station()
|
station = self._data.get_station()
|
||||||
if station is None:
|
if station is None:
|
||||||
return "-"
|
return "-"
|
||||||
else:
|
else:
|
||||||
@@ -95,25 +75,25 @@ class TableEditableModel(QAbstractTableModel):
|
|||||||
return Qt.AlignHCenter | Qt.AlignVCenter
|
return Qt.AlignHCenter | Qt.AlignVCenter
|
||||||
|
|
||||||
if index.column() == 2:
|
if index.column() == 2:
|
||||||
value = self._profile.point(index.row()).z
|
value = self._data.point(index.row()).z
|
||||||
if role == Qt.ForegroundRole:
|
if role == Qt.ForegroundRole:
|
||||||
if value == self._profile.z_min():
|
if value == self._data.z_min():
|
||||||
return QColor("red")
|
return QColor("red")
|
||||||
elif value == self._profile.z_max():
|
elif value == self._data.z_max():
|
||||||
return QColor("blue")
|
return QColor("blue")
|
||||||
|
|
||||||
if role == Qt.ToolTipRole:
|
if role == Qt.ToolTipRole:
|
||||||
if value == self._profile.z_min():
|
if value == self._data.z_min():
|
||||||
return _translate("MainWindowProfile",
|
return _translate("MainWindowProfile",
|
||||||
"La cote du fond",
|
"La cote du fond",
|
||||||
"Z minimale")
|
"Z minimale")
|
||||||
elif value == self._profile.z_max():
|
elif value == self._data.z_max():
|
||||||
return _translate("MainWindowProfile",
|
return _translate("MainWindowProfile",
|
||||||
"La cote maximale",
|
"La cote maximale",
|
||||||
"Z maximale")
|
"Z maximale")
|
||||||
|
|
||||||
if index.column() == 3:
|
if index.column() == 3:
|
||||||
value = self._profile.point(index.row()).name
|
value = self._data.point(index.row()).name
|
||||||
|
|
||||||
if value.strip().upper() in ["RG", "RD"]:
|
if value.strip().upper() in ["RG", "RD"]:
|
||||||
if role == Qt.FontRole:
|
if role == Qt.FontRole:
|
||||||
@@ -132,21 +112,6 @@ class TableEditableModel(QAbstractTableModel):
|
|||||||
|
|
||||||
return QVariant()
|
return QVariant()
|
||||||
|
|
||||||
def headerData(self, section, orientation, role=Qt.DisplayRole):
|
|
||||||
if orientation == Qt.Horizontal and role == Qt.DisplayRole:
|
|
||||||
return self._header[section]
|
|
||||||
elif orientation == Qt.Vertical and role == Qt.DisplayRole:
|
|
||||||
return str(section + 1)
|
|
||||||
|
|
||||||
if role == Qt.ToolTipRole and section == 4:
|
|
||||||
return _translate(
|
|
||||||
"MainWindowProfile",
|
|
||||||
"Abscisse en travers calculée en projétant les points"
|
|
||||||
" \nsur le plan défini par les deux points nommés extrêmes "
|
|
||||||
)
|
|
||||||
|
|
||||||
return QVariant()
|
|
||||||
|
|
||||||
def setData(self, index, value, role=Qt.EditRole):
|
def setData(self, index, value, role=Qt.EditRole):
|
||||||
row = index.row()
|
row = index.row()
|
||||||
column = index.column()
|
column = index.column()
|
||||||
@@ -154,34 +119,34 @@ class TableEditableModel(QAbstractTableModel):
|
|||||||
if role == Qt.EditRole:
|
if role == Qt.EditRole:
|
||||||
try:
|
try:
|
||||||
if column == 0:
|
if column == 0:
|
||||||
self._undo_stack.push(
|
self._undo.push(
|
||||||
SetXCommand(
|
SetXCommand(
|
||||||
self._profile, row,
|
self._data, row,
|
||||||
self._profile.point(row).x,
|
self._data.point(row).x,
|
||||||
value
|
value
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
elif column == 1:
|
elif column == 1:
|
||||||
self._undo_stack.push(
|
self._undo.push(
|
||||||
SetYCommand(
|
SetYCommand(
|
||||||
self._profile, row,
|
self._data, row,
|
||||||
self._profile.point(row).y,
|
self._data.point(row).y,
|
||||||
value
|
value
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
elif column == 2:
|
elif column == 2:
|
||||||
self._undo_stack.push(
|
self._undo.push(
|
||||||
SetZCommand(
|
SetZCommand(
|
||||||
self._profile, row,
|
self._data, row,
|
||||||
self._profile.point(row).z,
|
self._data.point(row).z,
|
||||||
value
|
value
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
elif column == 3:
|
elif column == 3:
|
||||||
self._undo_stack.push(
|
self._undo.push(
|
||||||
SetNameCommand(
|
SetNameCommand(
|
||||||
self._profile, row,
|
self._data, row,
|
||||||
self._profile.point(row).name,
|
self._data.point(row).name,
|
||||||
value
|
value
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
@@ -213,9 +178,9 @@ class TableEditableModel(QAbstractTableModel):
|
|||||||
def insert_row(self, row, parent=QModelIndex()):
|
def insert_row(self, row, parent=QModelIndex()):
|
||||||
self.beginInsertRows(parent, row, row - 1)
|
self.beginInsertRows(parent, row, row - 1)
|
||||||
|
|
||||||
self._undo_stack.push(
|
self._undo.push(
|
||||||
AddCommand(
|
AddCommand(
|
||||||
self._profile, row
|
self._data, row
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -225,9 +190,9 @@ class TableEditableModel(QAbstractTableModel):
|
|||||||
def remove_rows(self, rows, parent=QModelIndex()):
|
def remove_rows(self, rows, parent=QModelIndex()):
|
||||||
self.beginRemoveRows(parent, rows[0], rows[-1])
|
self.beginRemoveRows(parent, rows[0], rows[-1])
|
||||||
|
|
||||||
self._undo_stack.push(
|
self._undo.push(
|
||||||
DelCommand(
|
DelCommand(
|
||||||
self._profile, rows
|
self._data, rows
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -239,15 +204,15 @@ class TableEditableModel(QAbstractTableModel):
|
|||||||
|
|
||||||
reverse = (order != Qt.AscendingOrder)
|
reverse = (order != Qt.AscendingOrder)
|
||||||
|
|
||||||
self._undo_stack.push(
|
self._undo.push(
|
||||||
SortCommand(
|
SortCommand(
|
||||||
self._profile, column, reverse
|
self._data, column, reverse
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
|
|
||||||
self.layoutChanged.emit()
|
self.layoutChanged.emit()
|
||||||
|
|
||||||
def move_row_up(self, row, parent=QModelIndex()):
|
def move_up(self, row, parent=QModelIndex()):
|
||||||
if row <= 0:
|
if row <= 0:
|
||||||
return
|
return
|
||||||
|
|
||||||
@@ -255,26 +220,26 @@ class TableEditableModel(QAbstractTableModel):
|
|||||||
|
|
||||||
self.beginMoveRows(parent, row - 1, row - 1, parent, target)
|
self.beginMoveRows(parent, row - 1, row - 1, parent, target)
|
||||||
|
|
||||||
self._undo_stack.push(
|
self._undo.push(
|
||||||
MoveCommand(
|
MoveCommand(
|
||||||
self._profile, "up", row
|
self._data, "up", row
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
|
|
||||||
self.endMoveRows()
|
self.endMoveRows()
|
||||||
self.layoutChanged.emit()
|
self.layoutChanged.emit()
|
||||||
|
|
||||||
def move_row_down(self, row_to_move, parent=QModelIndex()):
|
def move_down(self, row_to_move, parent=QModelIndex()):
|
||||||
if row > self._profile.number_points:
|
if row > self._data.number_points:
|
||||||
return
|
return
|
||||||
|
|
||||||
target = row
|
target = row
|
||||||
|
|
||||||
self.beginMoveRows(parent, row + 1, row + 1, parent, target)
|
self.beginMoveRows(parent, row + 1, row + 1, parent, target)
|
||||||
|
|
||||||
self._undo_stack.push(
|
self._undo.push(
|
||||||
MoveCommand(
|
MoveCommand(
|
||||||
self._profile, "down", row
|
self._data, "down", row
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -282,7 +247,7 @@ class TableEditableModel(QAbstractTableModel):
|
|||||||
self.layoutChanged.emit()
|
self.layoutChanged.emit()
|
||||||
|
|
||||||
def paste(self, row, header, data):
|
def paste(self, row, header, data):
|
||||||
if row > self._profile.number_points:
|
if row > self._data.number_points:
|
||||||
return
|
return
|
||||||
|
|
||||||
if len(data) == 0:
|
if len(data) == 0:
|
||||||
@@ -290,12 +255,12 @@ class TableEditableModel(QAbstractTableModel):
|
|||||||
|
|
||||||
self.layoutAboutToBeChanged.emit()
|
self.layoutAboutToBeChanged.emit()
|
||||||
|
|
||||||
self._undo_stack.push(
|
self._undo.push(
|
||||||
PasteCommand(
|
PasteCommand(
|
||||||
self._profile, row,
|
self._data, row,
|
||||||
list(
|
list(
|
||||||
map(
|
map(
|
||||||
lambda d: self._profile.point_from_data(header, d),
|
lambda d: self._data.point_from_data(header, d),
|
||||||
data
|
data
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
@@ -306,32 +271,9 @@ class TableEditableModel(QAbstractTableModel):
|
|||||||
self.layoutChanged.emit()
|
self.layoutChanged.emit()
|
||||||
|
|
||||||
def undo(self):
|
def undo(self):
|
||||||
self._undo_stack.undo()
|
self._undo.undo()
|
||||||
self.layoutChanged.emit()
|
self.layoutChanged.emit()
|
||||||
|
|
||||||
def redo(self):
|
def redo(self):
|
||||||
self._undo_stack.redo()
|
self._undo.redo()
|
||||||
self.layoutChanged.emit()
|
self.layoutChanged.emit()
|
||||||
|
|
||||||
|
|
||||||
class Delegate(QStyledItemDelegate):
|
|
||||||
def __init__(self, parent=None, setModelDataEvent=None):
|
|
||||||
super(Delegate, self).__init__(parent)
|
|
||||||
self.setModelDataEvent = setModelDataEvent
|
|
||||||
|
|
||||||
def createEditor(self, parent, option, index):
|
|
||||||
index.model().data(index, Qt.DisplayRole)
|
|
||||||
return QLineEdit(parent)
|
|
||||||
|
|
||||||
def setEditorData(self, editor, index):
|
|
||||||
value = index.model().data(index, Qt.DisplayRole)
|
|
||||||
editor.setText(str(value))
|
|
||||||
|
|
||||||
def setModelData(self, editor, model, index):
|
|
||||||
model.setData(index, editor.text())
|
|
||||||
|
|
||||||
if not self.setModelDataEvent is None:
|
|
||||||
self.setModelDataEvent()
|
|
||||||
|
|
||||||
def updateEditorGeometry(self, editor, option, index):
|
|
||||||
editor.setGeometry(option.rect)
|
|
||||||
@@ -0,0 +1,36 @@
|
|||||||
|
# Translate.py -- Pamhyr
|
||||||
|
# Copyright (C) 2023 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.Tools.PamhyrTranslate import PamhyrTranslate
|
||||||
|
from View.Geometry.Translate import GeometryTranslate
|
||||||
|
|
||||||
|
_translate = QCoreApplication.translate
|
||||||
|
|
||||||
|
class GeometryProfileTranslate(GeometryTranslate):
|
||||||
|
def __init__(self):
|
||||||
|
super(GeometryProfileTranslate, self).__init__()
|
||||||
|
|
||||||
|
self._sub_dict["table_headers"] = {
|
||||||
|
"x": _translate("Geometry", "X (m)"),
|
||||||
|
"y": _translate("Geometry", "Y (m)"),
|
||||||
|
"z": _translate("Geometry", "Z (m)"),
|
||||||
|
"name": _translate("Geometry", "Name"),
|
||||||
|
"abs": _translate("Geometry", "Traversal abs (m)"),
|
||||||
|
}
|
||||||
@@ -31,205 +31,188 @@ from PyQt5.QtCore import (
|
|||||||
)
|
)
|
||||||
from PyQt5.QtWidgets import (
|
from PyQt5.QtWidgets import (
|
||||||
QApplication, QMainWindow, QFileDialog, QCheckBox,
|
QApplication, QMainWindow, QFileDialog, QCheckBox,
|
||||||
QUndoStack, QShortcut,
|
QUndoStack, QShortcut, QTableView, QAbstractItemView,
|
||||||
|
QHeaderView, QVBoxLayout, QAction,
|
||||||
)
|
)
|
||||||
|
|
||||||
from Model.Geometry.Reach import Reach
|
from Model.Geometry.Reach import Reach
|
||||||
from Model.Geometry.ProfileXYZ import ProfileXYZ
|
from Model.Geometry.ProfileXYZ import ProfileXYZ
|
||||||
|
|
||||||
from View.ASubWindow import ASubMainWindow
|
from View.Tools.PamhyrWindow import PamhyrWindow
|
||||||
from View.Geometry.Profile.mainwindow_ui_profile import Ui_MainWindow
|
from View.Tools.Plot.PamhyrToolbar import PamhyrPlotToolbar
|
||||||
|
from View.Tools.Plot.PamhyrCanvas import MplCanvas
|
||||||
|
|
||||||
from View.Geometry.Profile.Plot import Plot
|
from View.Geometry.Profile.Plot import Plot
|
||||||
from View.Geometry.Profile.Table import *
|
from View.Geometry.Profile.Table import GeometryProfileTableModel
|
||||||
|
from View.Geometry.Profile.Translate import GeometryProfileTranslate
|
||||||
|
|
||||||
_translate = QCoreApplication.translate
|
_translate = QCoreApplication.translate
|
||||||
|
|
||||||
|
|
||||||
class ProfileWindow(ASubMainWindow):
|
class ProfileWindow(PamhyrWindow):
|
||||||
def __init__(self, profile=None, title="Profile", parent=None):
|
_pamhyr_ui = "GeometryCrossSection"
|
||||||
self._title = title
|
_pamhyr_name = "Geometry cross-section"
|
||||||
self.parent = parent
|
|
||||||
super(ProfileWindow, self).__init__(
|
|
||||||
name=self._title,
|
|
||||||
parent=self.parent
|
|
||||||
)
|
|
||||||
|
|
||||||
self.ui = Ui_MainWindow()
|
|
||||||
self.ui.setupUi(self)
|
|
||||||
|
|
||||||
|
def __init__(self, profile=None, study=None, config=None, parent=None):
|
||||||
self._profile = profile
|
self._profile = profile
|
||||||
self._model = None
|
|
||||||
|
|
||||||
self.setup_window()
|
name = f"{self._pamhyr_name} - {self._profile.name} {self._profile.kp}"
|
||||||
self.setup_sc()
|
super(ProfileWindow, self).__init__(
|
||||||
self.setup_model()
|
title = name,
|
||||||
self.setup_connections()
|
study = study,
|
||||||
self.plot()
|
config = config,
|
||||||
|
trad = GeometryProfileTranslate(),
|
||||||
self._model.dataChanged.connect(self.update_plot)
|
parent = parent
|
||||||
self.fileName = None
|
|
||||||
|
|
||||||
# self.ui.tableView.installEventFilter(self)
|
|
||||||
# self._model.dataChanged.connect(self.tableview_is_modified)
|
|
||||||
|
|
||||||
# self.ui.btn_go_back.setEnabled(False)
|
|
||||||
# self.ui.btn_check.setEnabled(False)
|
|
||||||
# self._model.dataChanged.connect(self.set_enable_cancel_btn)
|
|
||||||
# self._model.dataChanged.connect(self.set_enable_validate_changes_btn)
|
|
||||||
# self.ui.btn_reset.setEnabled(False)
|
|
||||||
# self._model.dataChanged.connect(self.set_enable_go_back_initial_state_btn)
|
|
||||||
|
|
||||||
def setup_window(self):
|
|
||||||
header = _translate("MainWindowProfile", "Profile")
|
|
||||||
|
|
||||||
name = self._profile.name
|
|
||||||
if (name is None) or (name == ""):
|
|
||||||
name = _translate("MainWindowProfile", "(no name)")
|
|
||||||
|
|
||||||
self._title = (
|
|
||||||
header + " - " +
|
|
||||||
f"{self._profile.reach.name}" + " - " +
|
|
||||||
f"{name} ({self._profile.kp})"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
self.setWindowTitle(self._title)
|
self.setup_table()
|
||||||
|
self.setup_plot()
|
||||||
|
self.setup_connections()
|
||||||
|
|
||||||
def setup_sc(self):
|
def setup_table(self):
|
||||||
self._undo_stack = QUndoStack()
|
table_headers = self._trad.get_dict("table_headers")
|
||||||
|
|
||||||
self.undo_sc = QShortcut(QKeySequence.Undo, self)
|
table = self.find(QTableView, "tableView")
|
||||||
self.redo_sc = QShortcut(QKeySequence.Redo, self)
|
self._tablemodel = GeometryProfileTableModel(
|
||||||
self.copy_sc = QShortcut(QKeySequence.Copy, self)
|
table_view = table,
|
||||||
self.paste_sc = QShortcut(QKeySequence.Paste, self)
|
table_headers = table_headers,
|
||||||
|
editable_headers = ["name", "x", "y", "z"],
|
||||||
def setup_model(self):
|
data = self._profile,
|
||||||
self._model = TableEditableModel(
|
|
||||||
profile = self._profile,
|
|
||||||
undo = self._undo_stack
|
undo = self._undo_stack
|
||||||
)
|
)
|
||||||
|
table.setModel(self._tablemodel)
|
||||||
|
table.setSelectionBehavior(QAbstractItemView.SelectRows)
|
||||||
|
table.horizontalHeader().setSectionResizeMode(QHeaderView.Stretch)
|
||||||
|
table.setAlternatingRowColors(True)
|
||||||
|
|
||||||
self.ui.tableView.setModel(self._model)
|
def setup_plot(self):
|
||||||
self.ui.tableView.setItemDelegate(Delegate())
|
self._tablemodel.blockSignals(True)
|
||||||
|
|
||||||
def setup_connections(self):
|
self._canvas = MplCanvas(width=3, height=4, dpi=100)
|
||||||
self.ui.btn_sort_asc_x.triggered.connect(self.sort_X_ascending)
|
self._canvas.setObjectName("canvas")
|
||||||
self.ui.btn_sort_desc_x.triggered.connect(self.sort_X_descending)
|
self._toolbar = PamhyrPlotToolbar(
|
||||||
self.ui.btn_sort_asc_y.triggered.connect(self.sort_Y_ascending)
|
self._canvas, self,
|
||||||
self.ui.btn_sort_desc_y.triggered.connect(self.sort_Y_descending)
|
items = ["home", "zoom", "save", "iso", "back/forward", "move"]
|
||||||
self.ui.btn_move_up.triggered.connect(self.move_row_up)
|
)
|
||||||
self.ui.btn_move_down.triggered.connect(self.move_row_down)
|
self._plot_layout = self.find(QVBoxLayout, "verticalLayout")
|
||||||
self.ui.btn_export.triggered.connect(self.handleSave)
|
self._plot_layout.addWidget(self._toolbar)
|
||||||
self.ui.btn_add.triggered.connect(self.insert_row)
|
self._plot_layout.addWidget(self._canvas)
|
||||||
self.ui.btn_delete.triggered.connect(self.delete_row)
|
|
||||||
# self.ui.btn_copy.clicked.connect(self.copyTable)
|
|
||||||
# self.ui.btn_paste.clicked.connect(self.pasteTable)
|
|
||||||
# self.ui.btn_check.clicked.connect(self.validate_changes)
|
|
||||||
# self.ui.btn_go_back.clicked.connect(self.cancel_validate_changes)
|
|
||||||
# self.ui.btn_reset.clicked.connect(self.go_back_to_initial_state)
|
|
||||||
|
|
||||||
self.undo_sc.activated.connect(self.undo)
|
|
||||||
self.redo_sc.activated.connect(self.redo)
|
|
||||||
self.copy_sc.activated.connect(self.copy)
|
|
||||||
self.paste_sc.activated.connect(self.paste)
|
|
||||||
|
|
||||||
def plot(self):
|
|
||||||
self.ui.tableView.model().blockSignals(True)
|
|
||||||
|
|
||||||
self._plot = Plot(
|
self._plot = Plot(
|
||||||
canvas = self.ui.canvas,
|
canvas = self._canvas,
|
||||||
data = self._profile,
|
data = self._profile,
|
||||||
toolbar = None,
|
toolbar = self._toolbar,
|
||||||
table = self.ui.tableView,
|
table = self.find(QTableView, "tableView")
|
||||||
)
|
)
|
||||||
self._plot.draw()
|
self._plot.draw()
|
||||||
|
|
||||||
self.ui.tableView.model().blockSignals(False)
|
self._tablemodel.blockSignals(False)
|
||||||
|
|
||||||
|
def setup_connections(self):
|
||||||
|
actions = {
|
||||||
|
"action_sort_asc": self.sort_X_ascending,
|
||||||
|
"action_sort_des": self.sort_X_descending,
|
||||||
|
"action_up": self.move_up,
|
||||||
|
"action_down": self.move_down,
|
||||||
|
"action_add": self.add,
|
||||||
|
"action_delete": self.delete,
|
||||||
|
}
|
||||||
|
|
||||||
|
for action in actions:
|
||||||
|
self.find(QAction, action)\
|
||||||
|
.triggered.connect(actions[action])
|
||||||
|
|
||||||
|
self._tablemodel.dataChanged.connect(self.update_plot)
|
||||||
|
|
||||||
def update_plot(self):
|
def update_plot(self):
|
||||||
self.ui.tableView.model().blockSignals(True)
|
self._tablemodel.blockSignals(True)
|
||||||
|
|
||||||
# TODO: Do not rebuild all graph
|
# TODO: Do not rebuild all graph
|
||||||
self._plot.update()
|
self._plot.update()
|
||||||
|
|
||||||
self.ui.tableView.model().blockSignals(False)
|
self._tablemodel.blockSignals(False)
|
||||||
|
|
||||||
def index_selected_row(self):
|
def index_selected_row(self):
|
||||||
rows = self.ui.tableView\
|
rows = self._tablemodel\
|
||||||
.selectionModel()\
|
.selectionModel()\
|
||||||
.selectedRows()
|
.selectedRows()
|
||||||
if len(rows) == 0:
|
if len(rows) == 0:
|
||||||
return 0
|
return 0
|
||||||
|
|
||||||
return self.ui.tableView\
|
return self._tablemodel\
|
||||||
.selectionModel()\
|
.selectionModel()\
|
||||||
.selectedRows()[0]\
|
.selectedRows()[0]\
|
||||||
.row()
|
.row()
|
||||||
|
|
||||||
def insert_row(self):
|
def add(self):
|
||||||
if len(self.ui.tableView.selectedIndexes()) == 0:
|
table = self.find(QTableView, "tableView")
|
||||||
self._model.insert_row(self._model.rowCount())
|
if len(table.selectedIndexes()) == 0:
|
||||||
|
self._tablemodel.insert_row(self._tablemodel.rowCount())
|
||||||
else:
|
else:
|
||||||
row = self.index_selected_row()
|
row = self.index_selected_row()
|
||||||
self._model.insert_row(row + 1)
|
self._tablemodel.insert_row(row + 1)
|
||||||
self.update_plot()
|
self.update_plot()
|
||||||
|
|
||||||
def delete_row(self):
|
def delete(self):
|
||||||
|
table = self.find(QTableView, "tableView")
|
||||||
rows = sorted(
|
rows = sorted(
|
||||||
list(
|
list(
|
||||||
set(
|
set(
|
||||||
[index.row() for index in self.ui.tableView.selectedIndexes()]
|
[index.row() for index in table.selectedIndexes()]
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
|
|
||||||
if len(rows) > 0:
|
if len(rows) > 0:
|
||||||
self._model.remove_rows(rows)
|
self._tablemodel.remove_rows(rows)
|
||||||
self.update_plot()
|
self.update_plot()
|
||||||
|
|
||||||
def sort_X_ascending(self):
|
def sort_X_ascending(self):
|
||||||
self._model.sort('x', order=Qt.AscendingOrder)
|
self._tablemodel.sort('x', order=Qt.AscendingOrder)
|
||||||
self.update_plot()
|
self.update_plot()
|
||||||
|
|
||||||
def sort_X_descending(self):
|
def sort_X_descending(self):
|
||||||
self._model.sort('x', order=Qt.DescendingOrder)
|
self._tablemodel.sort('x', order=Qt.DescendingOrder)
|
||||||
self.update_plot()
|
self.update_plot()
|
||||||
|
|
||||||
def sort_Y_ascending(self):
|
def sort_Y_ascending(self):
|
||||||
self._model.sort('y', order=Qt.AscendingOrder)
|
self._tablemodel.sort('y', order=Qt.AscendingOrder)
|
||||||
self.update_plot()
|
self.update_plot()
|
||||||
|
|
||||||
def sort_Y_descending(self):
|
def sort_Y_descending(self):
|
||||||
self._model.sort('y', order=Qt.DescendingOrder)
|
self._tablemodel.sort('y', order=Qt.DescendingOrder)
|
||||||
self.update_plot()
|
self.update_plot()
|
||||||
|
|
||||||
def move_row_down(self):
|
def move_down(self):
|
||||||
rows = list(
|
rows = list(
|
||||||
set(
|
set(
|
||||||
[index.row() for index in self.ui.tableView.selectedIndexes()]
|
[index.row() for index in
|
||||||
|
self.find(QTableView, "tableView").selectedIndexes()]
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
|
|
||||||
for row in rows:
|
for row in rows:
|
||||||
if row < self._model.rowCount() - 1:
|
if row < self._tablemodel.rowCount() - 1:
|
||||||
self._model.move_row_down(row)
|
self._tablemodel.move_down(row)
|
||||||
|
|
||||||
self.update_plot()
|
self.update_plot()
|
||||||
|
|
||||||
def move_row_up(self):
|
def move_up(self):
|
||||||
rows = list(
|
rows = list(
|
||||||
set(
|
set(
|
||||||
[index.row() for index in self.ui.tableView.selectedIndexes()]
|
[index.row() for index in
|
||||||
|
self.find(QTableView, "tableView").selectedIndexes()]
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
|
|
||||||
for row in rows:
|
for row in rows:
|
||||||
if 0 < row:
|
if 0 < row:
|
||||||
self._model.move_row_up(row)
|
self._tablemodel.move_up(row)
|
||||||
|
|
||||||
self.update_plot()
|
self.update_plot()
|
||||||
|
|
||||||
def copy(self):
|
def copy(self):
|
||||||
rows = self.ui.tableView\
|
rows = self._tablemodel\
|
||||||
.selectionModel()\
|
.selectionModel()\
|
||||||
.selectedRows()
|
.selectedRows()
|
||||||
table = []
|
table = []
|
||||||
@@ -257,136 +240,13 @@ class ProfileWindow(ASubMainWindow):
|
|||||||
row.append(self._profile)
|
row.append(self._profile)
|
||||||
|
|
||||||
row = self.index_selected_row()
|
row = self.index_selected_row()
|
||||||
self._model.paste(row, header, data)
|
self._tablemodel.paste(row, header, data)
|
||||||
self.update_plot()
|
self.update_plot()
|
||||||
|
|
||||||
def undo(self):
|
def undo(self):
|
||||||
self._model.undo()
|
self._tablemodel.undo()
|
||||||
self.update_plot()
|
self.update_plot()
|
||||||
|
|
||||||
def redo(self):
|
def redo(self):
|
||||||
self._model.redo()
|
self._tablemodel.redo()
|
||||||
self.update_plot()
|
self.update_plot()
|
||||||
|
|
||||||
def handleSave(self):
|
|
||||||
if self.fileName is None or self.fileName == '':
|
|
||||||
self.fileName, self.filters = QFileDialog.getSaveFileName(
|
|
||||||
self, filter="CSV files (*.csv)"
|
|
||||||
)
|
|
||||||
|
|
||||||
if self.fileName != '':
|
|
||||||
with open(self.fileName, 'w') as stream:
|
|
||||||
csvout = csv.writer(stream, delimiter='\t', quotechar=' ',
|
|
||||||
escapechar=None,
|
|
||||||
quoting=csv.QUOTE_NONNUMERIC,
|
|
||||||
lineterminator='\n')
|
|
||||||
|
|
||||||
for row in range(self._model.rowCount(QModelIndex())):
|
|
||||||
rowdata = []
|
|
||||||
for column in range(self._model.columnCount(QModelIndex())):
|
|
||||||
item = self._model.index(
|
|
||||||
row, column, QModelIndex()
|
|
||||||
).data(Qt.DisplayRole)
|
|
||||||
|
|
||||||
if item is not None:
|
|
||||||
rowdata.append(item)
|
|
||||||
|
|
||||||
if item == 'nan':
|
|
||||||
rowdata.remove(item)
|
|
||||||
|
|
||||||
csvout.writerow(rowdata)
|
|
||||||
|
|
||||||
def handleOpen(self):
|
|
||||||
self.fileName, self.filterName = QFileDialog.getOpenFileName(self)
|
|
||||||
|
|
||||||
if self.fileName != '':
|
|
||||||
with open(self.fileName, 'r') as f:
|
|
||||||
reader = csv.reader(f, delimiter='\t')
|
|
||||||
header = next(reader)
|
|
||||||
|
|
||||||
buf = []
|
|
||||||
for row in reader:
|
|
||||||
row[0] = QCheckBox("-")
|
|
||||||
buf.append(row)
|
|
||||||
|
|
||||||
self._model = None
|
|
||||||
self._model = TableEditableModel(buf)
|
|
||||||
self.ui.tableView.setModel(self._model)
|
|
||||||
self.fileName = ''
|
|
||||||
|
|
||||||
def set_enable_validate_changes_btn(self):
|
|
||||||
self.ui.btn_check.setEnabled(True)
|
|
||||||
|
|
||||||
def set_enable_cancel_btn(self):
|
|
||||||
self.ui.btn_go_back.setEnabled(True)
|
|
||||||
|
|
||||||
def set_enable_go_back_initial_state_btn(self):
|
|
||||||
self.ui.btn_reset.setEnabled(True)
|
|
||||||
|
|
||||||
def delete_empty_rows(self):
|
|
||||||
if self._model.data_contains_nan():
|
|
||||||
buttonReply = QtWidgets.QMessageBox.question(
|
|
||||||
self,
|
|
||||||
_translate("MainWindowProfile",
|
|
||||||
"Suppression les lignes incomplètes"),
|
|
||||||
_translate("MainWindowProfile",
|
|
||||||
"Supprimer les lignes des cellules"
|
|
||||||
" non renseignées ?"),
|
|
||||||
QtWidgets.QMessageBox.Yes | QtWidgets.QMessageBox.No
|
|
||||||
)
|
|
||||||
|
|
||||||
if buttonReply == QtWidgets.QMessageBox.Yes:
|
|
||||||
self._model.delete_empty_rows()
|
|
||||||
|
|
||||||
if buttonReply == QtWidgets.QMessageBox.No:
|
|
||||||
pass
|
|
||||||
|
|
||||||
def remove_duplicates_point_names(self):
|
|
||||||
counter_list = []
|
|
||||||
list_deleted_names = []
|
|
||||||
|
|
||||||
for ind, name_point in enumerate(self._model.name):
|
|
||||||
if name_point not in counter_list:
|
|
||||||
counter_list.append(name_point)
|
|
||||||
elif len(name_point.strip()) > 0 and name_point in counter_list:
|
|
||||||
if name_point not in list_deleted_names:
|
|
||||||
list_deleted_names.append(name_point)
|
|
||||||
|
|
||||||
if list_deleted_names:
|
|
||||||
self.msg_box_check_duplication_names(list_deleted_names)
|
|
||||||
|
|
||||||
def msg_box_check_duplication_names(self, list_deleted_names):
|
|
||||||
if len(list_deleted_names) == 1:
|
|
||||||
text = _translate("MainWindowProfile",
|
|
||||||
"Le nom ''{}'' est dupliqué."
|
|
||||||
" \n\nYes : Ne garder que la première occurrence. \nNo :"
|
|
||||||
" Annuler la suppression.".format(list_deleted_names[0]))
|
|
||||||
else:
|
|
||||||
text = _translate("MainWindowProfile",
|
|
||||||
"Les noms suivants : \n{} sont dupliqués"
|
|
||||||
" \n\nYes : Ne garder que la première occurrence de "
|
|
||||||
"chaque nom. \nNo :"
|
|
||||||
" Annuler la suppression.".format(list_deleted_names))
|
|
||||||
|
|
||||||
buttonReply = QtWidgets.QMessageBox.question(
|
|
||||||
self, _translate("MainWindowProfile",
|
|
||||||
"Suppression des noms répétés"),
|
|
||||||
text,
|
|
||||||
QtWidgets.QMessageBox.Yes | QtWidgets.QMessageBox.No
|
|
||||||
)
|
|
||||||
|
|
||||||
if buttonReply == QtWidgets.QMessageBox.Yes:
|
|
||||||
self._model.remove_duplicates_names()
|
|
||||||
|
|
||||||
def ask_quit(self):
|
|
||||||
choice = QtWidgets.QMessageBox.question(
|
|
||||||
self,
|
|
||||||
_translate("MainWindowProfile", "Quittez ?"),
|
|
||||||
_translate("MainWindowProfile",
|
|
||||||
"Etes-vous sûr de vouloir quitter ?"),
|
|
||||||
QtWidgets.QMessageBox.Yes | QtWidgets.QMessageBox.No
|
|
||||||
)
|
|
||||||
return choice == QtWidgets.QMessageBox.Yes
|
|
||||||
|
|
||||||
def initial_state_model(self, profile_initial_state):
|
|
||||||
return profile_initial_state
|
|
||||||
@@ -1,260 +0,0 @@
|
|||||||
# mainwindow_ui_profile.py -- Pamhyr
|
|
||||||
# Copyright (C) 2023 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 os.path
|
|
||||||
|
|
||||||
from PyQt5 import QtCore, QtGui, QtWidgets
|
|
||||||
from PyQt5.QtCore import Qt, QSize
|
|
||||||
from PyQt5.QtWidgets import (
|
|
||||||
QTableView, QAbstractItemView, QHeaderView,
|
|
||||||
QToolBar,
|
|
||||||
)
|
|
||||||
|
|
||||||
from View.Plot import MplCanvas
|
|
||||||
from View.Plot.PamhyrToolbar import PamhyrPlotToolbar
|
|
||||||
|
|
||||||
file_path = os.path.abspath(os.path.dirname(__file__))
|
|
||||||
icon_path = f"{os.path.dirname(os.path.dirname(file_path))}/../View/ui/ressources/"
|
|
||||||
|
|
||||||
class Ui_MainWindow(object):
|
|
||||||
def setupUi(self, MainWindowProfile):
|
|
||||||
MainWindowProfile.setObjectName("MainWindowProfile")
|
|
||||||
MainWindowProfile.resize(1089, 699)
|
|
||||||
self.centralwidget = QtWidgets.QWidget(MainWindowProfile)
|
|
||||||
self.centralwidget.setObjectName("centralwidget")
|
|
||||||
self.horizontalLayout_2 = QtWidgets.QHBoxLayout(self.centralwidget)
|
|
||||||
self.horizontalLayout_2.setObjectName("horizontalLayout_2")
|
|
||||||
self.splitter = QtWidgets.QSplitter(self.centralwidget)
|
|
||||||
self.splitter.setOrientation(Qt.Horizontal)
|
|
||||||
self.splitter.setObjectName("splitter")
|
|
||||||
self.widget = QtWidgets.QWidget(self.splitter)
|
|
||||||
self.widget.setObjectName("widget")
|
|
||||||
self.verticalLayout_left = QtWidgets.QVBoxLayout(self.widget)
|
|
||||||
self.verticalLayout_left.setContentsMargins(0, 0, 0, 0)
|
|
||||||
self.verticalLayout_left.setObjectName("verticalLayout_left")
|
|
||||||
|
|
||||||
self.horizontalLayout = QtWidgets.QHBoxLayout()
|
|
||||||
self.horizontalLayout.setObjectName("horizontalLayout")
|
|
||||||
|
|
||||||
self.toolBar = QToolBar(MainWindowProfile)
|
|
||||||
self.toolBar.setOrientation(Qt.Vertical)
|
|
||||||
self.toolBar.setEnabled(True)
|
|
||||||
MainWindowProfile.addToolBar(QtCore.Qt.TopToolBarArea, self.toolBar)
|
|
||||||
|
|
||||||
btn_size = QSize(40, 28)
|
|
||||||
|
|
||||||
self.btn_add = QtWidgets.QAction(self.widget)
|
|
||||||
self.btn_add.setObjectName("btn_add")
|
|
||||||
icon_btn_add = QtGui.QIcon()
|
|
||||||
icon_btn_add.addPixmap(
|
|
||||||
QtGui.QPixmap(f"{icon_path}gtk-add.png"))
|
|
||||||
self.btn_add.setIcon(icon_btn_add)
|
|
||||||
self.toolBar.addAction(self.btn_add)
|
|
||||||
|
|
||||||
self.btn_delete = QtWidgets.QAction(self.widget)
|
|
||||||
self.btn_delete.setObjectName("btn_delete")
|
|
||||||
icon_btn_delete = QtGui.QIcon()
|
|
||||||
icon_btn_delete.addPixmap(
|
|
||||||
QtGui.QPixmap(f"{icon_path}gtk-remove.png"))
|
|
||||||
self.btn_delete.setIcon(icon_btn_delete)
|
|
||||||
self.toolBar.addAction(self.btn_delete)
|
|
||||||
|
|
||||||
self.btn_sort_asc_x = QtWidgets.QAction(self.widget)
|
|
||||||
self.btn_sort_asc_x.setObjectName("btn_sort_asc_x")
|
|
||||||
icon_btn_sort_asc_x = QtGui.QIcon()
|
|
||||||
icon_btn_sort_asc_x.addPixmap(
|
|
||||||
QtGui.QPixmap(f"{icon_path}gtk-sort-ascending.png"))
|
|
||||||
self.btn_sort_asc_x.setIcon(icon_btn_sort_asc_x)
|
|
||||||
self.toolBar.addAction(self.btn_sort_asc_x)
|
|
||||||
|
|
||||||
self.btn_sort_desc_x = QtWidgets.QAction(self.widget)
|
|
||||||
self.btn_sort_desc_x.setObjectName("btn_sort_desc_x")
|
|
||||||
icon_btn_sort_desc_x = QtGui.QIcon()
|
|
||||||
icon_btn_sort_desc_x.addPixmap(
|
|
||||||
QtGui.QPixmap(f"{icon_path}gtk-sort-descending.png"))
|
|
||||||
self.btn_sort_desc_x.setIcon(icon_btn_sort_desc_x)
|
|
||||||
self.toolBar.addAction(self.btn_sort_desc_x)
|
|
||||||
|
|
||||||
self.btn_sort_asc_y = QtWidgets.QAction(self.widget)
|
|
||||||
self.btn_sort_asc_y.setObjectName("btn_sort_asc_y")
|
|
||||||
icon_btn_sort_asc_y = QtGui.QIcon()
|
|
||||||
icon_btn_sort_asc_y.addPixmap(
|
|
||||||
QtGui.QPixmap(f"{icon_path}gtk-sort-ascending.png"))
|
|
||||||
self.btn_sort_asc_y.setIcon(icon_btn_sort_asc_y)
|
|
||||||
self.toolBar.addAction(self.btn_sort_asc_y)
|
|
||||||
|
|
||||||
self.btn_sort_desc_y = QtWidgets.QAction(self.widget)
|
|
||||||
self.btn_sort_desc_y.setObjectName("btn_sort_desc_y")
|
|
||||||
icon_btn_sort_desc_y = QtGui.QIcon()
|
|
||||||
icon_btn_sort_desc_y.addPixmap(
|
|
||||||
QtGui.QPixmap(f"{icon_path}gtk-sort-descending.png"))
|
|
||||||
self.btn_sort_desc_y.setIcon(icon_btn_sort_desc_y)
|
|
||||||
self.toolBar.addAction(self.btn_sort_desc_y)
|
|
||||||
|
|
||||||
self.btn_move_up = QtWidgets.QAction(self.widget)
|
|
||||||
self.btn_move_up.setObjectName("btn_move_up")
|
|
||||||
icon_btn_move_up = QtGui.QIcon()
|
|
||||||
icon_btn_move_up.addPixmap(
|
|
||||||
QtGui.QPixmap(f"{icon_path}up.png"))
|
|
||||||
self.btn_move_up.setIcon(icon_btn_move_up)
|
|
||||||
self.toolBar.addAction(self.btn_move_up)
|
|
||||||
|
|
||||||
self.btn_move_down = QtWidgets.QAction(self.widget)
|
|
||||||
self.btn_move_down.setObjectName("btn_move_down")
|
|
||||||
icon_btn_move_down = QtGui.QIcon()
|
|
||||||
icon_btn_move_down.addPixmap(
|
|
||||||
QtGui.QPixmap(f"{icon_path}down.png"))
|
|
||||||
self.btn_move_down.setIcon(icon_btn_move_down)
|
|
||||||
self.toolBar.addAction(self.btn_move_down)
|
|
||||||
|
|
||||||
self.btn_export = QtWidgets.QAction(self.widget)
|
|
||||||
self.btn_export.setObjectName("btn_export")
|
|
||||||
icon_btn_export = QtGui.QIcon()
|
|
||||||
icon_btn_export.addPixmap(
|
|
||||||
QtGui.QPixmap(f"{icon_path}export.png"))
|
|
||||||
self.btn_export.setIcon(icon_btn_export)
|
|
||||||
self.toolBar.addAction(self.btn_export)
|
|
||||||
|
|
||||||
self.btn_copy = QtWidgets.QAction(self.widget)
|
|
||||||
self.btn_copy.setObjectName("btn_copy")
|
|
||||||
icon_btn_copy = QtGui.QIcon()
|
|
||||||
icon_btn_copy.addPixmap(
|
|
||||||
QtGui.QPixmap(f"{icon_path}gtk-copy.png"))
|
|
||||||
self.btn_copy.setIcon(icon_btn_copy)
|
|
||||||
self.toolBar.addAction(self.btn_copy)
|
|
||||||
|
|
||||||
self.btn_paste = QtWidgets.QAction(self.widget)
|
|
||||||
self.btn_paste.setObjectName("btn_paste")
|
|
||||||
icon_btn_paste = QtGui.QIcon()
|
|
||||||
icon_btn_paste.addPixmap(
|
|
||||||
QtGui.QPixmap(f"{icon_path}gtk-paste.png"))
|
|
||||||
self.btn_paste.setIcon(icon_btn_paste)
|
|
||||||
self.toolBar.addAction(self.btn_paste)
|
|
||||||
|
|
||||||
self.btn_check = QtWidgets.QAction(self.widget)
|
|
||||||
self.btn_check.setObjectName("btn_check")
|
|
||||||
icon_btn_check = QtGui.QIcon()
|
|
||||||
icon_btn_check.addPixmap(
|
|
||||||
QtGui.QPixmap(f"{icon_path}gtk-apply.png"))
|
|
||||||
self.btn_check.setIcon(icon_btn_check)
|
|
||||||
self.toolBar.addAction(self.btn_check)
|
|
||||||
|
|
||||||
self.btn_go_back = QtWidgets.QAction(self.widget)
|
|
||||||
self.btn_go_back.setObjectName("btn_go_back")
|
|
||||||
icon_btn_go_back = QtGui.QIcon()
|
|
||||||
icon_btn_go_back.addPixmap(
|
|
||||||
QtGui.QPixmap(f"{icon_path}gtk-undo.png"))
|
|
||||||
self.btn_go_back.setIcon(icon_btn_go_back)
|
|
||||||
self.toolBar.addAction(self.btn_go_back)
|
|
||||||
|
|
||||||
self.btn_reset = QtWidgets.QAction(self.widget)
|
|
||||||
self.btn_reset.setObjectName("btn_reset")
|
|
||||||
icon_btn_reset = QtGui.QIcon()
|
|
||||||
icon_btn_reset.addPixmap(
|
|
||||||
QtGui.QPixmap(f"{icon_path}cancel.png"))
|
|
||||||
self.btn_reset.setIcon(icon_btn_reset)
|
|
||||||
self.toolBar.addAction(self.btn_reset)
|
|
||||||
|
|
||||||
self.verticalLayout_left.addLayout(self.horizontalLayout)
|
|
||||||
|
|
||||||
self.tableView = QTableView(self.widget)
|
|
||||||
self.tableView.setObjectName("tableView")
|
|
||||||
self.tableView.setSelectionBehavior(QAbstractItemView.SelectRows)
|
|
||||||
self.tableView.setSizeAdjustPolicy(QtWidgets.QAbstractScrollArea.AdjustToContents)
|
|
||||||
self.tableView.resizeColumnsToContents()
|
|
||||||
self.tableView.resizeRowsToContents()
|
|
||||||
self.tableView.setAlternatingRowColors(True)
|
|
||||||
self.tableView.horizontalHeader().setSectionResizeMode(QHeaderView.Stretch)
|
|
||||||
self.verticalLayout_left.addWidget(self.tableView)
|
|
||||||
|
|
||||||
self.widget1 = QtWidgets.QWidget(self.splitter)
|
|
||||||
self.widget1.setObjectName("widget1")
|
|
||||||
|
|
||||||
self.verticalLayout_right = QtWidgets.QVBoxLayout(self.widget1)
|
|
||||||
self.verticalLayout_right.setContentsMargins(0, 0, 0, 0)
|
|
||||||
self.verticalLayout_right.setObjectName("verticalLayout_right")
|
|
||||||
|
|
||||||
self.label_graphic_help = QtWidgets.QLabel(self.widget1)
|
|
||||||
self.label_graphic_help.setMaximumSize(QtCore.QSize(16777215, 25))
|
|
||||||
self.label_graphic_help.setBaseSize(QtCore.QSize(0, 30))
|
|
||||||
self.label_graphic_help.setObjectName("label_graphic_help")
|
|
||||||
self.verticalLayout_right.addWidget(self.label_graphic_help)
|
|
||||||
|
|
||||||
self.canvas = MplCanvas.MplCanvas(width=5, height=4, dpi=100)
|
|
||||||
self.canvas.setObjectName("canvas")
|
|
||||||
|
|
||||||
self.my_toolbar = PamhyrPlotToolbar(
|
|
||||||
self.canvas, self.widget1
|
|
||||||
)
|
|
||||||
|
|
||||||
self.verticalLayout_right.addWidget(self.my_toolbar)
|
|
||||||
self.verticalLayout_right.addWidget(self.canvas)
|
|
||||||
self.horizontalLayout_2.addWidget(self.splitter)
|
|
||||||
|
|
||||||
MainWindowProfile.setCentralWidget(self.centralwidget)
|
|
||||||
|
|
||||||
self.menubar = QtWidgets.QMenuBar(MainWindowProfile)
|
|
||||||
self.menubar.setGeometry(QtCore.QRect(0, 0, 1089, 20))
|
|
||||||
self.menubar.setObjectName("menubar")
|
|
||||||
MainWindowProfile.setMenuBar(self.menubar)
|
|
||||||
self.statusbar = QtWidgets.QStatusBar(MainWindowProfile)
|
|
||||||
self.statusbar.setObjectName("statusbar")
|
|
||||||
MainWindowProfile.setStatusBar(self.statusbar)
|
|
||||||
|
|
||||||
self.retranslateUi(MainWindowProfile)
|
|
||||||
QtCore.QMetaObject.connectSlotsByName(MainWindowProfile)
|
|
||||||
|
|
||||||
def retranslateUi(self, MainWindow):
|
|
||||||
_translate = QtCore.QCoreApplication.translate
|
|
||||||
MainWindow.setWindowTitle(_translate("MainWindowProfile", "MainWindowProfile"))
|
|
||||||
self.btn_add.setToolTip(_translate("MainWindowProfile", "Insérer un point"))
|
|
||||||
self.btn_delete.setToolTip(
|
|
||||||
_translate("MainWindowProfile", "Supprimer le/les point(s) sélectionnés"))
|
|
||||||
self.btn_sort_asc_x.setToolTip(
|
|
||||||
_translate("MainWindowProfile", "Trier les points par ordre croissant de X"))
|
|
||||||
self.btn_sort_desc_x.setToolTip(
|
|
||||||
_translate("MainWindowProfile", "Trier les points par ordre décroissant de X"))
|
|
||||||
self.btn_sort_asc_y.setToolTip(_translate("MainWindowProfile",
|
|
||||||
"Trier les points par ordre croissant de Y"
|
|
||||||
))
|
|
||||||
self.btn_sort_desc_y.setToolTip(_translate("MainWindowProfile",
|
|
||||||
"Trier les points par ordre décroissant de Y"))
|
|
||||||
self.btn_move_up.setToolTip(_translate("MainWindowProfile",
|
|
||||||
"Décaler le point sélectionné vers le haut"))
|
|
||||||
self.btn_move_down.setToolTip(_translate("MainWindowProfile",
|
|
||||||
"Décaler le point sélectionné vers le bas"))
|
|
||||||
self.btn_export.setToolTip(_translate("MainWindowProfile",
|
|
||||||
"Exporter (dans un fichier) les points du profil au format tabulé"))
|
|
||||||
self.btn_copy.setToolTip(
|
|
||||||
_translate("MainWindowProfile", "Copier la sélection au format tabulé"))
|
|
||||||
self.btn_paste.setToolTip(_translate("MainWindowProfile",
|
|
||||||
"Coller la sélection depuis le presse-papier au format tabulé"))
|
|
||||||
self.btn_check.setToolTip(_translate("MainWindowProfile",
|
|
||||||
"Vérifier la validité de la saisie et garder ou pas les modifications "
|
|
||||||
"apportées"))
|
|
||||||
self.btn_go_back.setToolTip(_translate("MainWindowProfile",
|
|
||||||
"Annuler toutes les modifications depuis la dernière validation"))
|
|
||||||
self.btn_reset.setToolTip(_translate("MainWindowProfile",
|
|
||||||
"Annuler toutes les modifications et revenir à l\'état initial"))
|
|
||||||
self.label_graphic_help.setToolTip(_translate("MainWindowProfile",
|
|
||||||
"Ligne d'eau : \n \tZ : Cote (m) \n \tA : Aire mouillée ("
|
|
||||||
"m\u00B2) \n \tp : "
|
|
||||||
"Périmètre mouillé (m) \n \tL : Largeur au miroir (m)"))
|
|
||||||
self.label_graphic_help.setText(
|
|
||||||
_translate("MainWindowProfile", "\'Maj + Clic\' : Ligne d\'eau & \'Ctrl + Clic\' : "
|
|
||||||
"Sélectionner des points"))
|
|
||||||
+33
-150
@@ -35,6 +35,8 @@ from PyQt5.QtWidgets import (
|
|||||||
QComboBox,
|
QComboBox,
|
||||||
)
|
)
|
||||||
|
|
||||||
|
from View.Tools.PamhyrTable import PamhyrTableModel
|
||||||
|
|
||||||
from Model.Geometry import Reach
|
from Model.Geometry import Reach
|
||||||
from Model.Geometry.ProfileXYZ import ProfileXYZ
|
from Model.Geometry.ProfileXYZ import ProfileXYZ
|
||||||
from View.Geometry.UndoCommand import *
|
from View.Geometry.UndoCommand import *
|
||||||
@@ -44,53 +46,26 @@ logger = logging.getLogger()
|
|||||||
_translate = QCoreApplication.translate
|
_translate = QCoreApplication.translate
|
||||||
|
|
||||||
|
|
||||||
class TableEditableModel(QAbstractTableModel):
|
class GeometryReachTableModel(PamhyrTableModel):
|
||||||
def __init__(self, reach, headers=None, undo=None):
|
|
||||||
QAbstractTableModel.__init__(self)
|
|
||||||
data_list = []
|
|
||||||
|
|
||||||
self._undo_stack = undo
|
|
||||||
self._reach = reach
|
|
||||||
|
|
||||||
# Hack for qtlinguist
|
|
||||||
_ = _translate("Geometry", "Name")
|
|
||||||
_ = _translate("Geometry", "Kp (m)")
|
|
||||||
_ = _translate("Geometry", "Type")
|
|
||||||
|
|
||||||
if headers is None:
|
|
||||||
self.headers = [
|
|
||||||
"Name",
|
|
||||||
"Kp (m)",
|
|
||||||
"Type"
|
|
||||||
]
|
|
||||||
else:
|
|
||||||
self.headers = headers
|
|
||||||
|
|
||||||
def rowCount(self, parent=QModelIndex()):
|
|
||||||
return self._reach.number_profiles
|
|
||||||
|
|
||||||
def columnCount(self, parent=QModelIndex()):
|
|
||||||
return len(self.headers)
|
|
||||||
|
|
||||||
def data(self, index, role=Qt.DisplayRole):
|
def data(self, index, role=Qt.DisplayRole):
|
||||||
if not index.isValid():
|
if not index.isValid():
|
||||||
return QVariant()
|
return QVariant()
|
||||||
|
|
||||||
if role == Qt.DisplayRole and index.column() == 0:
|
if role == Qt.DisplayRole and index.column() == 0:
|
||||||
return self._reach.profile(index.row()).name
|
return self._data.profile(index.row()).name
|
||||||
|
|
||||||
if role == Qt.DisplayRole and index.column() == 1:
|
if role == Qt.DisplayRole and index.column() == 1:
|
||||||
kp = self._reach.profile(index.row()).kp
|
kp = self._data.profile(index.row()).kp
|
||||||
return f"{kp:.4f}"
|
return f"{kp:.4f}"
|
||||||
|
|
||||||
if role == Qt.DisplayRole and index.column() == 2:
|
if role == Qt.DisplayRole and index.column() == 2:
|
||||||
return self._reach.profile(index.row()).profile_type
|
return self._data.profile(index.row()).profile_type
|
||||||
|
|
||||||
if role == Qt.TextAlignmentRole:
|
if role == Qt.TextAlignmentRole:
|
||||||
return Qt.AlignHCenter | Qt.AlignVCenter
|
return Qt.AlignHCenter | Qt.AlignVCenter
|
||||||
|
|
||||||
if role == Qt.ForegroundRole and index.column() == 0:
|
if role == Qt.ForegroundRole and index.column() == 0:
|
||||||
name = self._reach.profile(index.row()).name\
|
name = self._data.profile(index.row()).name\
|
||||||
.strip()\
|
.strip()\
|
||||||
.lower()
|
.lower()
|
||||||
if (name == "upstream" or name == "up" or
|
if (name == "upstream" or name == "up" or
|
||||||
@@ -102,16 +77,6 @@ class TableEditableModel(QAbstractTableModel):
|
|||||||
|
|
||||||
return QVariant()
|
return QVariant()
|
||||||
|
|
||||||
def headerData(self, section, orientation, role=Qt.DisplayRole):
|
|
||||||
if role == Qt.DisplayRole:
|
|
||||||
if orientation == Qt.Horizontal:
|
|
||||||
if section < len(self.headers):
|
|
||||||
return _translate("Geometry", self.headers[section])
|
|
||||||
else:
|
|
||||||
return str(section + 1)
|
|
||||||
|
|
||||||
return QVariant()
|
|
||||||
|
|
||||||
def setData(self, index, value, role=Qt.EditRole):
|
def setData(self, index, value, role=Qt.EditRole):
|
||||||
row = index.row()
|
row = index.row()
|
||||||
column = index.column()
|
column = index.column()
|
||||||
@@ -119,19 +84,19 @@ class TableEditableModel(QAbstractTableModel):
|
|||||||
if role == Qt.EditRole and index.column() != 2:
|
if role == Qt.EditRole and index.column() != 2:
|
||||||
try:
|
try:
|
||||||
if index.column() == 0:
|
if index.column() == 0:
|
||||||
self._undo_stack.push(
|
self._undo.push(
|
||||||
SetNameCommand(
|
SetNameCommand(
|
||||||
self._reach, index.row(),
|
self._data, index.row(),
|
||||||
self._reach.profile(index.row()).name,
|
self._data.profile(index.row()).name,
|
||||||
value
|
value
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
|
|
||||||
if index.column() == 1:
|
if index.column() == 1:
|
||||||
self._undo_stack.push(
|
self._undo.push(
|
||||||
SetKPCommand(
|
SetKPCommand(
|
||||||
self._reach, index.row(),
|
self._data, index.row(),
|
||||||
self._reach.profile(index.row()).kp,
|
self._data.profile(index.row()).kp,
|
||||||
value
|
value
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
@@ -149,39 +114,25 @@ class TableEditableModel(QAbstractTableModel):
|
|||||||
|
|
||||||
return False
|
return False
|
||||||
|
|
||||||
def index(self, row, column, parent=QModelIndex()):
|
|
||||||
if not self.hasIndex(row, column, parent):
|
|
||||||
return QModelIndex()
|
|
||||||
|
|
||||||
return self.createIndex(row, column, QModelIndex())
|
|
||||||
|
|
||||||
def flags(self, index):
|
|
||||||
flg = Qt.ItemIsEnabled | Qt.ItemIsSelectable
|
|
||||||
|
|
||||||
if index.column() == 2:
|
|
||||||
return flg
|
|
||||||
else:
|
|
||||||
return Qt.ItemIsEditable | flg
|
|
||||||
|
|
||||||
# @QtCore.pyqtSlot()
|
# @QtCore.pyqtSlot()
|
||||||
def insert_row(self, row, parent=QModelIndex()):
|
def add(self, row, parent=QModelIndex()):
|
||||||
self.beginInsertRows(parent, row, row - 1)
|
self.beginInsertRows(parent, row, row - 1)
|
||||||
|
|
||||||
self._undo_stack.push(
|
self._undo.push(
|
||||||
AddCommand(
|
AddCommand(
|
||||||
self._reach, row
|
self._data, row
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
|
|
||||||
self.endInsertRows()
|
self.endInsertRows()
|
||||||
self.layoutChanged.emit()
|
self.layoutChanged.emit()
|
||||||
|
|
||||||
def remove_rows(self, rows, parent=QModelIndex()):
|
def delete(self, rows, parent=QModelIndex()):
|
||||||
self.beginRemoveRows(parent, rows[0], rows[-1])
|
self.beginRemoveRows(parent, rows[0], rows[-1])
|
||||||
|
|
||||||
self._undo_stack.push(
|
self._undo.push(
|
||||||
DelCommand(
|
DelCommand(
|
||||||
self._reach, rows
|
self._data, rows
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -191,9 +142,9 @@ class TableEditableModel(QAbstractTableModel):
|
|||||||
def sort_profiles(self, _reverse):
|
def sort_profiles(self, _reverse):
|
||||||
self.layoutAboutToBeChanged.emit()
|
self.layoutAboutToBeChanged.emit()
|
||||||
|
|
||||||
self._undo_stack.push(
|
self._undo.push(
|
||||||
SortCommand(
|
SortCommand(
|
||||||
self._reach, _reverse
|
self._data, _reverse
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -201,7 +152,7 @@ class TableEditableModel(QAbstractTableModel):
|
|||||||
self.layoutChanged.emit()
|
self.layoutChanged.emit()
|
||||||
|
|
||||||
|
|
||||||
def move_row_up(self, row, parent=QModelIndex()):
|
def move_up(self, row, parent=QModelIndex()):
|
||||||
if row <= 0:
|
if row <= 0:
|
||||||
return
|
return
|
||||||
|
|
||||||
@@ -209,26 +160,26 @@ class TableEditableModel(QAbstractTableModel):
|
|||||||
|
|
||||||
self.beginMoveRows(parent, row - 1, row - 1, parent, target)
|
self.beginMoveRows(parent, row - 1, row - 1, parent, target)
|
||||||
|
|
||||||
self._undo_stack.push(
|
self._undo.push(
|
||||||
MoveCommand(
|
MoveCommand(
|
||||||
self._reach, "up", row
|
self._data, "up", row
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
|
|
||||||
self.endMoveRows()
|
self.endMoveRows()
|
||||||
self.layoutChanged.emit()
|
self.layoutChanged.emit()
|
||||||
|
|
||||||
def move_row_down(self, row, parent=QModelIndex()):
|
def move_down(self, row, parent=QModelIndex()):
|
||||||
if row > self._reach.number_profiles:
|
if row > self._data.number_profiles:
|
||||||
return
|
return
|
||||||
|
|
||||||
target = row
|
target = row
|
||||||
|
|
||||||
self.beginMoveRows(parent, row + 1, row + 1, parent, target)
|
self.beginMoveRows(parent, row + 1, row + 1, parent, target)
|
||||||
|
|
||||||
self._undo_stack.push(
|
self._undo.push(
|
||||||
MoveCommand(
|
MoveCommand(
|
||||||
self._reach, "down", row
|
self._data, "down", row
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -238,9 +189,9 @@ class TableEditableModel(QAbstractTableModel):
|
|||||||
def duplicate(self, rows, profiles):
|
def duplicate(self, rows, profiles):
|
||||||
self.layoutAboutToBeChanged.emit()
|
self.layoutAboutToBeChanged.emit()
|
||||||
|
|
||||||
self._undo_stack.push(
|
self._undo.push(
|
||||||
DuplicateCommand(
|
DuplicateCommand(
|
||||||
self._reach, rows,
|
self._data, rows,
|
||||||
profiles
|
profiles
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
@@ -250,7 +201,7 @@ class TableEditableModel(QAbstractTableModel):
|
|||||||
|
|
||||||
|
|
||||||
def paste(self, row, header, data):
|
def paste(self, row, header, data):
|
||||||
if row > self._reach.number_profiles:
|
if row > self._data.number_profiles:
|
||||||
return
|
return
|
||||||
|
|
||||||
if len(data) == 0:
|
if len(data) == 0:
|
||||||
@@ -258,9 +209,9 @@ class TableEditableModel(QAbstractTableModel):
|
|||||||
|
|
||||||
self.layoutAboutToBeChanged.emit()
|
self.layoutAboutToBeChanged.emit()
|
||||||
|
|
||||||
self._undo_stack.push(
|
self._undo.push(
|
||||||
PasteCommand(
|
PasteCommand(
|
||||||
self._reach, row,
|
self._data, row,
|
||||||
list(
|
list(
|
||||||
map(
|
map(
|
||||||
lambda d: ProfileXYZ.from_data(header, d),
|
lambda d: ProfileXYZ.from_data(header, d),
|
||||||
@@ -272,71 +223,3 @@ class TableEditableModel(QAbstractTableModel):
|
|||||||
|
|
||||||
self.layoutAboutToBeChanged.emit()
|
self.layoutAboutToBeChanged.emit()
|
||||||
self.layoutChanged.emit()
|
self.layoutChanged.emit()
|
||||||
|
|
||||||
|
|
||||||
def undo(self):
|
|
||||||
self._undo_stack.undo()
|
|
||||||
self.layoutChanged.emit()
|
|
||||||
|
|
||||||
def redo(self):
|
|
||||||
self._undo_stack.redo()
|
|
||||||
self.layoutChanged.emit()
|
|
||||||
|
|
||||||
|
|
||||||
class Delegate(QStyledItemDelegate):
|
|
||||||
def __init__(self, parent=None, setModelDataEvent=None):
|
|
||||||
super(Delegate, self).__init__(parent)
|
|
||||||
self.setModelDataEvent = setModelDataEvent
|
|
||||||
|
|
||||||
def createEditor(self, parent, option, index):
|
|
||||||
index.model().data(index, Qt.DisplayRole)
|
|
||||||
return QLineEdit(parent)
|
|
||||||
|
|
||||||
def setEditorData(self, editor, index):
|
|
||||||
value = index.model().data(index, Qt.DisplayRole)
|
|
||||||
editor.setText(str(value))
|
|
||||||
|
|
||||||
def setModelData(self, editor, model, index):
|
|
||||||
model.setData(index, editor.text())
|
|
||||||
|
|
||||||
if not self.setModelDataEvent is None:
|
|
||||||
self.setModelDataEvent()
|
|
||||||
|
|
||||||
def updateEditorGeometry(self, editor, option, index):
|
|
||||||
editor.setGeometry(option.rect)
|
|
||||||
|
|
||||||
class Delegate1(QStyledItemDelegate):
|
|
||||||
def __init__(self, owner, choices):
|
|
||||||
super().__init__(owner)
|
|
||||||
self.items = choices
|
|
||||||
|
|
||||||
def paint(self, painter, option, index):
|
|
||||||
if isinstance(self.parent(), QAbstractItemView):
|
|
||||||
self.parent().openPersistentEditor(index)
|
|
||||||
super(Delegate1, self).paint(painter, option, index)
|
|
||||||
|
|
||||||
def createEditor(self, parent, option, index):
|
|
||||||
editor = QComboBox(parent)
|
|
||||||
# editor.currentIndexChanged.connect(self.commit_editor)
|
|
||||||
editor.addItems(self.items)
|
|
||||||
return editor
|
|
||||||
|
|
||||||
def setEditorData(self, editor, index):
|
|
||||||
editor.blockSignals(True)
|
|
||||||
text = index.model().data(index, Qt.DisplayRole)
|
|
||||||
try:
|
|
||||||
i = self.items.index(text)
|
|
||||||
except ValueError:
|
|
||||||
i = 0
|
|
||||||
editor.setCurrentIndex(i)
|
|
||||||
editor.blockSignals(False)
|
|
||||||
|
|
||||||
def setModelData(self, editor, model, index):
|
|
||||||
model.setData(index, editor.currentText(), Qt.DisplayRole)
|
|
||||||
|
|
||||||
def updateEditorGeometry(self, editor, option, index):
|
|
||||||
editor.setGeometry(option.rect)
|
|
||||||
|
|
||||||
@pyqtSlot()
|
|
||||||
def currentIndexChanged(self):
|
|
||||||
self.commitData.emit(self.sender())
|
|
||||||
@@ -0,0 +1,45 @@
|
|||||||
|
# Translate.py -- Pamhyr
|
||||||
|
# Copyright (C) 2023 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.Tools.PamhyrTranslate import PamhyrTranslate
|
||||||
|
|
||||||
|
_translate = QCoreApplication.translate
|
||||||
|
|
||||||
|
class GeometryTranslate(PamhyrTranslate):
|
||||||
|
def __init__(self):
|
||||||
|
super(GeometryTranslate, self).__init__()
|
||||||
|
|
||||||
|
self._dict["open_file"] = _translate("Geometry", "Open a file")
|
||||||
|
self._dict["file_st"] = _translate("Geometry", "File mage geometry (*.ST)")
|
||||||
|
self._dict["file_m"] = _translate("Geometry", "File mage meshed geometry (*.M)")
|
||||||
|
self._dict["file_all"] = _translate("Geometry", "All file (*)")
|
||||||
|
|
||||||
|
self._dict["reach"] = _translate("Geometry", "reach")
|
||||||
|
self._dict["reachs"] = _translate("Geometry", "reachs")
|
||||||
|
|
||||||
|
self._dict["cross_section"] = _translate("Geometry", "cross-section")
|
||||||
|
self._dict["cross_sections"] = _translate("Geometry", "cross-sections")
|
||||||
|
self._dict["profile"] = _translate("Geometry", "cross-section")
|
||||||
|
self._dict["profiles"] = _translate("Geometry", "cross-sections")
|
||||||
|
|
||||||
|
self._sub_dict["table_headers"] = {
|
||||||
|
"name": _translate("Geometry", "Name"),
|
||||||
|
"kp": _translate("Geometry", "KP"),
|
||||||
|
}
|
||||||
+156
-145
@@ -34,117 +34,167 @@ from PyQt5.QtCore import (
|
|||||||
)
|
)
|
||||||
from PyQt5.QtWidgets import (
|
from PyQt5.QtWidgets import (
|
||||||
QApplication, QMainWindow, QFileDialog, QCheckBox,
|
QApplication, QMainWindow, QFileDialog, QCheckBox,
|
||||||
QUndoStack, QShortcut,
|
QUndoStack, QShortcut, QTableView, QHeaderView,
|
||||||
|
QAction, QSlider, QPushButton, QVBoxLayout,
|
||||||
|
QLabel, QAbstractItemView,
|
||||||
)
|
)
|
||||||
|
|
||||||
from View.Geometry.PlotXY import PlotXY
|
from View.Tools.PamhyrWindow import PamhyrWindow
|
||||||
from View.Geometry.PlotKPZ import PlotKPZ
|
from View.Tools.Plot.PamhyrToolbar import PamhyrPlotToolbar
|
||||||
from View.Geometry.PlotAC import PlotAC
|
from View.Tools.Plot.PamhyrCanvas import MplCanvas
|
||||||
|
|
||||||
from View.ASubWindow import ASubMainWindow, WindowToolKit
|
from View.Geometry.Table import GeometryReachTableModel
|
||||||
from View.ListedSubWindow import ListedSubWindow
|
from View.Geometry.PlotXY import PlotXY
|
||||||
from View.Geometry.mainwindow_ui_reach import Ui_MainWindow
|
from View.Geometry.PlotAC import PlotAC
|
||||||
from View.Geometry.Table import *
|
from View.Geometry.PlotKPZ import PlotKPZ
|
||||||
|
from View.Geometry.Translate import GeometryTranslate
|
||||||
from View.Geometry.Profile.Window import ProfileWindow
|
from View.Geometry.Profile.Window import ProfileWindow
|
||||||
|
|
||||||
_translate = QCoreApplication.translate
|
_translate = QCoreApplication.translate
|
||||||
|
|
||||||
|
|
||||||
class GeometryWindow(ASubMainWindow, ListedSubWindow):
|
class GeometryWindow(PamhyrWindow):
|
||||||
def __init__(self, model=None, title="Geometry", parent=None):
|
_pamhyr_ui = "GeometryReach"
|
||||||
self._title = title
|
_pamhyr_name = "Geometry"
|
||||||
self.parent = parent
|
|
||||||
|
def __init__(self, reach=None, study=None, config=None, parent=None):
|
||||||
|
if reach is None:
|
||||||
|
self._reach = study.river.current_reach().reach
|
||||||
|
else:
|
||||||
|
self._reach = reach
|
||||||
|
|
||||||
|
name = f"{self._pamhyr_name} - {self._reach.name}"
|
||||||
|
|
||||||
super(GeometryWindow, self).__init__(
|
super(GeometryWindow, self).__init__(
|
||||||
name=self._title,
|
title = name,
|
||||||
parent=parent
|
study = study,
|
||||||
|
config = config,
|
||||||
|
trad = GeometryTranslate(),
|
||||||
|
parent = parent
|
||||||
)
|
)
|
||||||
|
|
||||||
self._model = model
|
|
||||||
self._reach = model.river.current_reach().reach
|
|
||||||
|
|
||||||
self.ui = Ui_MainWindow()
|
|
||||||
self.ui.setupUi(self)
|
|
||||||
|
|
||||||
self.tableView = self.ui.tableView
|
|
||||||
self.tableView_header = self.ui.tableView_header
|
|
||||||
|
|
||||||
self._tablemodel = None
|
self._tablemodel = None
|
||||||
self._profile_window = []
|
self._profile_window = []
|
||||||
self._clipboard = None
|
|
||||||
|
|
||||||
self.setup_window()
|
self.setup_table()
|
||||||
self.setup_sc()
|
|
||||||
self.setup_model()
|
|
||||||
self.setup_plots()
|
self.setup_plots()
|
||||||
|
self.setup_statusbar()
|
||||||
self.setup_connections()
|
self.setup_connections()
|
||||||
self.changed_slider_value()
|
self.changed_slider_value()
|
||||||
|
|
||||||
def setup_window(self):
|
def setup_table(self):
|
||||||
self._title = f"{self.ui.mainwindow_title} - {self._reach.name}"
|
table_headers = self._trad.get_dict("table_headers")
|
||||||
self.setWindowTitle(self._title)
|
|
||||||
|
|
||||||
def setup_sc(self):
|
table = self.find(QTableView, "tableView")
|
||||||
self._undo_stack = QUndoStack()
|
self._tablemodel = GeometryReachTableModel(
|
||||||
|
table_view = table,
|
||||||
self.undo_sc = QShortcut(QKeySequence.Undo, self)
|
table_headers = table_headers,
|
||||||
self.redo_sc = QShortcut(QKeySequence.Redo, self)
|
editable_headers = ["name", "kp"],
|
||||||
self.copy_sc = QShortcut(QKeySequence.Copy, self)
|
data = self._reach,
|
||||||
self.paste_sc = QShortcut(QKeySequence.Paste, self)
|
|
||||||
|
|
||||||
def setup_model(self):
|
|
||||||
self._tablemodel = TableEditableModel(
|
|
||||||
headers = self.ui.tableView_header,
|
|
||||||
reach = self._reach,
|
|
||||||
undo = self._undo_stack
|
undo = self._undo_stack
|
||||||
)
|
)
|
||||||
self.tableView.setModel(self._tablemodel)
|
table.setModel(self._tablemodel)
|
||||||
self.tableView.setItemDelegate(Delegate())
|
table.setSelectionBehavior(QAbstractItemView.SelectRows)
|
||||||
|
table.horizontalHeader().setSectionResizeMode(QHeaderView.Stretch)
|
||||||
|
table.setAlternatingRowColors(True)
|
||||||
|
|
||||||
def setup_plots(self):
|
def setup_plots(self):
|
||||||
|
self._canvas_xy = MplCanvas(width=3, height=4, dpi=100)
|
||||||
|
self._canvas_xy.setObjectName("canvas_xy")
|
||||||
|
self._toolbar_xy = PamhyrPlotToolbar(
|
||||||
|
self._canvas_xy, self,
|
||||||
|
items = ["home", "zoom", "save", "iso", "back/forward", "move"]
|
||||||
|
)
|
||||||
|
self._plot_layout_xy = self.find(QVBoxLayout, "verticalLayout")
|
||||||
|
self._plot_layout_xy.addWidget(self._toolbar_xy)
|
||||||
|
self._plot_layout_xy.addWidget(self._canvas_xy)
|
||||||
self.plot_xy()
|
self.plot_xy()
|
||||||
|
|
||||||
|
self._canvas_kpc = MplCanvas(width=6, height=4, dpi=100)
|
||||||
|
self._canvas_kpc.setObjectName("canvas_kpc")
|
||||||
|
self._toolbar_kpc = PamhyrPlotToolbar(
|
||||||
|
self._canvas_kpc, self,
|
||||||
|
items = ["home", "zoom", "save", "iso", "back/forward", "move"]
|
||||||
|
)
|
||||||
|
self._plot_layout_kpc = self.find(QVBoxLayout, "verticalLayout_2")
|
||||||
|
self._plot_layout_kpc.addWidget(self._toolbar_kpc)
|
||||||
|
self._plot_layout_kpc.addWidget(self._canvas_kpc)
|
||||||
self.plot_kpc()
|
self.plot_kpc()
|
||||||
|
|
||||||
|
self._canvas_ac = MplCanvas(width=9, height=4, dpi=100)
|
||||||
|
self._canvas_ac.setObjectName("canvas_ac")
|
||||||
|
self._toolbar_ac = PamhyrPlotToolbar(
|
||||||
|
self._canvas_ac, self,
|
||||||
|
items = ["home", "zoom", "save", "iso", "back/forward", "move"]
|
||||||
|
)
|
||||||
|
self._plot_layout_ac = self.find(QVBoxLayout, "verticalLayout_3")
|
||||||
|
self._plot_layout_ac.addWidget(self._toolbar_ac)
|
||||||
|
self._plot_layout_ac.addWidget(self._canvas_ac)
|
||||||
self.plot_ac()
|
self.plot_ac()
|
||||||
|
|
||||||
|
def _compute_status_label(self):
|
||||||
|
row = self.index_selected_row()
|
||||||
|
profile = self._reach.profile(row)
|
||||||
|
|
||||||
|
name = profile.name + " " + str(profile.kp)
|
||||||
|
|
||||||
|
return (
|
||||||
|
f"<font color=\"Grey\">{self._trad['reach']}: {self._reach.name}" + " - "
|
||||||
|
f"{self._trad['cross_section']}:</font> {name}"
|
||||||
|
)
|
||||||
|
|
||||||
|
def setup_statusbar(self):
|
||||||
|
txt = ""
|
||||||
|
self._status_label = QLabel(txt)
|
||||||
|
self.statusbar.addPermanentWidget(self._status_label)
|
||||||
|
|
||||||
|
def update_statusbar(self):
|
||||||
|
txt = self._compute_status_label()
|
||||||
|
self._status_label.setText(txt)
|
||||||
|
|
||||||
def setup_connections(self):
|
def setup_connections(self):
|
||||||
self.ui.btn_open.triggered.connect(self.open_file_dialog)
|
actions = {
|
||||||
self.ui.btn_sort_asc.triggered.connect(self.sort_ascending)
|
"action_import": self.import_from_file,
|
||||||
self.ui.btn_sort_desc.triggered.connect(self.sort_descending)
|
# "action_export": self.export_to_file,
|
||||||
self.ui.btn_move_up.triggered.connect(self.move_row_up)
|
"action_sort_asc": self.sort_ascending,
|
||||||
self.ui.btn_move_down.triggered.connect(self.move_row_down)
|
"action_sort_des": self.sort_descending,
|
||||||
# self.ui.btn_end_editing.triggered.connect(self.handleSave)
|
"action_up": self.move_up,
|
||||||
self.ui.btn_add.triggered.connect(self.insert_row)
|
"action_down": self.move_down,
|
||||||
self.ui.btn_delete.triggered.connect(self.delete_rows)
|
"action_add": self.add,
|
||||||
self.ui.btn_edit.triggered.connect(self.edit_profile)
|
"action_delete": self.delete,
|
||||||
self.ui.verticalSlider.valueChanged.connect(self.changed_slider_value)
|
"action_edit": self.edit_profile,
|
||||||
|
}
|
||||||
|
|
||||||
self.ui.btn_slider_up.clicked.connect(self.decrement_value_slider)
|
for action in actions:
|
||||||
self.ui.btn_slider_down.clicked.connect(self.increment_value_slider)
|
self.find(QAction, action)\
|
||||||
self.ui.btn_move_up.triggered.connect(self.changed_profile_slot)
|
.triggered.connect(actions[action])
|
||||||
|
|
||||||
self.undo_sc.activated.connect(self.undo)
|
self.find(QSlider, "verticalSlider").valueChanged.connect(self.changed_slider_value)
|
||||||
self.redo_sc.activated.connect(self.redo)
|
self.find(QPushButton, "pushButton_up").clicked.connect(self.decrement_value_slider)
|
||||||
self.copy_sc.activated.connect(self.copy)
|
self.find(QPushButton, "pushButton_down").clicked.connect(self.increment_value_slider)
|
||||||
self.paste_sc.activated.connect(self.paste)
|
|
||||||
|
|
||||||
# Profile selection when line change in table
|
# Profile selection when line change in table
|
||||||
self.tableView.selectionModel()\
|
self.find(QTableView, "tableView").selectionModel()\
|
||||||
.selectionChanged\
|
.selectionChanged\
|
||||||
.connect(self.select_current_profile)
|
.connect(self.select_current_profile)
|
||||||
|
|
||||||
def open_file_dialog(self):
|
|
||||||
|
def import_from_file(self):
|
||||||
options = QFileDialog.Options()
|
options = QFileDialog.Options()
|
||||||
settings = QSettings(QSettings.IniFormat, QSettings.UserScope, 'MyOrg', )
|
settings = QSettings(QSettings.IniFormat, QSettings.UserScope, 'MyOrg', )
|
||||||
options |= QFileDialog.DontUseNativeDialog
|
options |= QFileDialog.DontUseNativeDialog
|
||||||
|
|
||||||
|
file_types = [
|
||||||
|
self._trad["file_st"],
|
||||||
|
self._trad["file_m"],
|
||||||
|
self._trad["file_all"],
|
||||||
|
]
|
||||||
|
|
||||||
filename, _ = QtWidgets.QFileDialog.getOpenFileName(
|
filename, _ = QtWidgets.QFileDialog.getOpenFileName(
|
||||||
self,
|
self,
|
||||||
_translate("MainWindow_reach", "Ouvrir un fichier"),
|
self._trad["open_file"],
|
||||||
"",
|
"",
|
||||||
_translate("MainWindow_reach", "Fichiers .ST (*.ST)") +
|
";; ".join(file_types),
|
||||||
";; " +
|
|
||||||
_translate("MainWindow_reach", "Fichiers .M (*.M)") +
|
|
||||||
";; " +
|
|
||||||
_translate("MainWindow_reach", "Tous les fichiers (*)"),
|
|
||||||
options=options
|
options=options
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -158,20 +208,6 @@ class GeometryWindow(ASubMainWindow, ListedSubWindow):
|
|||||||
self.plot_kpc()
|
self.plot_kpc()
|
||||||
self.plot_ac()
|
self.plot_ac()
|
||||||
|
|
||||||
def messagebox_profile_editing(self):
|
|
||||||
msg_box = QtWidgets.QMessageBox()
|
|
||||||
msg_box.setIcon(QtWidgets.QMessageBox.Information)
|
|
||||||
msg_box.setWindowTitle(_translate("MainWindow_reach",
|
|
||||||
"Édition des profils sélectionnés"))
|
|
||||||
msg_box.setText(_translate("MainWindow_reach",
|
|
||||||
"Vous avez sélectionné plus de 5 profils."
|
|
||||||
" \nSeuls les 5 premiers seront édités."))
|
|
||||||
msg_box.setStandardButtons(QtWidgets.QMessageBox.Ok)
|
|
||||||
|
|
||||||
return_value = msg_box.exec()
|
|
||||||
# if return_value == QtWidgets.QMessageBox.Ok:
|
|
||||||
# print('OK clicked')
|
|
||||||
|
|
||||||
def edit_profile(self):
|
def edit_profile(self):
|
||||||
self.tableView.model().blockSignals(True)
|
self.tableView.model().blockSignals(True)
|
||||||
|
|
||||||
@@ -214,9 +250,9 @@ class GeometryWindow(ASubMainWindow, ListedSubWindow):
|
|||||||
self.tableView.model().blockSignals(True)
|
self.tableView.model().blockSignals(True)
|
||||||
|
|
||||||
self._plot_xy = PlotXY(
|
self._plot_xy = PlotXY(
|
||||||
canvas = self.ui.canvas_1,
|
canvas = self._canvas_xy,
|
||||||
data = self._reach,
|
data = self._reach,
|
||||||
toolbar = self.ui.toolbar_1
|
toolbar = self._toolbar_xy
|
||||||
)
|
)
|
||||||
self._plot_xy.draw()
|
self._plot_xy.draw()
|
||||||
|
|
||||||
@@ -231,9 +267,9 @@ class GeometryWindow(ASubMainWindow, ListedSubWindow):
|
|||||||
self.tableView.model().blockSignals(True)
|
self.tableView.model().blockSignals(True)
|
||||||
|
|
||||||
self._plot_kpc = PlotKPZ(
|
self._plot_kpc = PlotKPZ(
|
||||||
canvas = self.ui.canvas_2,
|
canvas = self._canvas_kpc,
|
||||||
data = self._reach,
|
data = self._reach,
|
||||||
toolbar = self.ui.toolbar_2
|
toolbar = self._toolbar_kpc
|
||||||
)
|
)
|
||||||
self._plot_kpc.draw()
|
self._plot_kpc.draw()
|
||||||
|
|
||||||
@@ -248,9 +284,9 @@ class GeometryWindow(ASubMainWindow, ListedSubWindow):
|
|||||||
self.tableView.model().blockSignals(True)
|
self.tableView.model().blockSignals(True)
|
||||||
|
|
||||||
self._plot_ac = PlotAC(
|
self._plot_ac = PlotAC(
|
||||||
canvas = self.ui.canvas_3,
|
canvas = self._canvas_ac,
|
||||||
data = self._reach,
|
data = self._reach,
|
||||||
toolbar = self.ui.toolbar_3,
|
toolbar = self._toolbar_ac,
|
||||||
plot_xy = self._plot_xy
|
plot_xy = self._plot_xy
|
||||||
)
|
)
|
||||||
self._plot_ac.draw()
|
self._plot_ac.draw()
|
||||||
@@ -303,7 +339,7 @@ class GeometryWindow(ASubMainWindow, ListedSubWindow):
|
|||||||
if len(self.tableView.selectedIndexes()) > 0:
|
if len(self.tableView.selectedIndexes()) > 0:
|
||||||
row = self.index_selected_row()
|
row = self.index_selected_row()
|
||||||
|
|
||||||
self.ui.verticalSlider.setValue(row)
|
self.find(QSlider, "verticalSlider").setValue(row)
|
||||||
self.select_plot_xy(row)
|
self.select_plot_xy(row)
|
||||||
self.select_plot_kpc(row)
|
self.select_plot_kpc(row)
|
||||||
self.select_plot_ac(row)
|
self.select_plot_ac(row)
|
||||||
@@ -314,41 +350,37 @@ class GeometryWindow(ASubMainWindow, ListedSubWindow):
|
|||||||
self.tableView.model().blockSignals(True)
|
self.tableView.model().blockSignals(True)
|
||||||
|
|
||||||
if self._tablemodel.rowCount() != 0:
|
if self._tablemodel.rowCount() != 0:
|
||||||
self.ui.verticalSlider.setMaximum(self._tablemodel.rowCount() - 1)
|
slider = self.find(QSlider, "verticalSlider")
|
||||||
|
slider.setMaximum(self._tablemodel.rowCount() - 1)
|
||||||
|
|
||||||
slider_value = self.ui.verticalSlider.value()
|
slider_value = slider.value()
|
||||||
kp = self._reach.profile(slider_value).kp
|
kp = self._reach.profile(slider_value).kp
|
||||||
|
|
||||||
self.ui.vertical_slider_label.setText(
|
|
||||||
_translate("MainWindow_reach", "Kp : ") +
|
|
||||||
f"{kp}" + "\n" +
|
|
||||||
_translate("MainWindow_reach",
|
|
||||||
"Profil N° : ") +
|
|
||||||
f"{slider_value + 1}"
|
|
||||||
)
|
|
||||||
|
|
||||||
self.select_plot_xy(slider_value)
|
self.select_plot_xy(slider_value)
|
||||||
self.select_plot_kpc(slider_value)
|
self.select_plot_kpc(slider_value)
|
||||||
self.select_row_profile_slider(slider_value)
|
self.select_row_profile_slider(slider_value)
|
||||||
|
self.update_statusbar()
|
||||||
|
|
||||||
self.tableView.model().blockSignals(False)
|
self.tableView.model().blockSignals(False)
|
||||||
|
|
||||||
def increment_value_slider(self):
|
def increment_value_slider(self):
|
||||||
if 0 <= self.ui.verticalSlider.value() < self._tablemodel.rowCount() - 1:
|
slider = self.find(QSlider, "verticalSlider")
|
||||||
self.ui.verticalSlider.setValue(self.ui.verticalSlider.value() + 1)
|
if 0 <= slider.value() < self._tablemodel.rowCount() - 1:
|
||||||
|
slider.setValue(slider.value() + 1)
|
||||||
|
|
||||||
def decrement_value_slider(self):
|
def decrement_value_slider(self):
|
||||||
if 0 < self.ui.verticalSlider.value() < self._tablemodel.rowCount():
|
slider = self.find(QSlider, "verticalSlider")
|
||||||
self.ui.verticalSlider.setValue(self.ui.verticalSlider.value() - 1)
|
if 0 < slider.value() < self._tablemodel.rowCount():
|
||||||
|
slider.setValue(slider.value() - 1)
|
||||||
|
|
||||||
def insert_row(self):
|
def add(self):
|
||||||
if len(self.tableView.selectedIndexes()) == 0:
|
if len(self.tableView.selectedIndexes()) == 0:
|
||||||
self._tablemodel.insert_row(self._tablemodel.rowCount())
|
self._tablemodel.add(self._tablemodel.rowCount())
|
||||||
else:
|
else:
|
||||||
row = self.index_selected_row()
|
row = self.index_selected_row()
|
||||||
self._tablemodel.insert_row(row + 1)
|
self._tablemodel.add(row + 1)
|
||||||
|
|
||||||
def delete_rows(self):
|
def delete(self):
|
||||||
rows = sorted(
|
rows = sorted(
|
||||||
list(
|
list(
|
||||||
set(
|
set(
|
||||||
@@ -358,7 +390,7 @@ class GeometryWindow(ASubMainWindow, ListedSubWindow):
|
|||||||
)
|
)
|
||||||
|
|
||||||
if len(rows) > 0:
|
if len(rows) > 0:
|
||||||
self._tablemodel.remove_rows(rows)
|
self._tablemodel.delete(rows)
|
||||||
|
|
||||||
self.update_plot_xy()
|
self.update_plot_xy()
|
||||||
self.select_current_profile()
|
self.select_current_profile()
|
||||||
@@ -373,24 +405,24 @@ class GeometryWindow(ASubMainWindow, ListedSubWindow):
|
|||||||
.row()
|
.row()
|
||||||
|
|
||||||
def sort_ascending(self):
|
def sort_ascending(self):
|
||||||
self._tablemodel.sort_profiles(True)
|
self._tablemodel.sort_profiles(False)
|
||||||
self.select_current_profile()
|
self.select_current_profile()
|
||||||
self.changed_slider_value()
|
self.changed_slider_value()
|
||||||
|
|
||||||
def sort_descending(self):
|
def sort_descending(self):
|
||||||
self._tablemodel.sort_profiles(False)
|
self._tablemodel.sort_profiles(True)
|
||||||
|
|
||||||
self.select_current_profile()
|
self.select_current_profile()
|
||||||
self.changed_slider_value()
|
self.changed_slider_value()
|
||||||
|
|
||||||
def move_row_up(self):
|
def move_up(self):
|
||||||
row = self.index_selected_row()
|
row = self.index_selected_row()
|
||||||
self._tablemodel.move_row_up(row)
|
self._tablemodel.move_up(row)
|
||||||
self.select_current_profile()
|
self.select_current_profile()
|
||||||
|
|
||||||
def move_row_down(self):
|
def move_down(self):
|
||||||
row = self.index_selected_row()
|
row = self.index_selected_row()
|
||||||
self._tablemodel.move_row_down(row)
|
self._tablemodel.move_down(row)
|
||||||
self.select_current_profile()
|
self.select_current_profile()
|
||||||
|
|
||||||
def duplicate(self):
|
def duplicate(self):
|
||||||
@@ -411,7 +443,7 @@ class GeometryWindow(ASubMainWindow, ListedSubWindow):
|
|||||||
self._tablemodel.duplicate(rows, profiles)
|
self._tablemodel.duplicate(rows, profiles)
|
||||||
self.select_current_profile()
|
self.select_current_profile()
|
||||||
|
|
||||||
def copy(self):
|
def _copy(self):
|
||||||
rows = self.tableView\
|
rows = self.tableView\
|
||||||
.selectionModel()\
|
.selectionModel()\
|
||||||
.selectedRows()
|
.selectedRows()
|
||||||
@@ -427,7 +459,7 @@ class GeometryWindow(ASubMainWindow, ListedSubWindow):
|
|||||||
|
|
||||||
self.copyTableIntoClipboard(table)
|
self.copyTableIntoClipboard(table)
|
||||||
|
|
||||||
def paste(self):
|
def _paste(self):
|
||||||
header, data = self.parseClipboardTable()
|
header, data = self.parseClipboardTable()
|
||||||
|
|
||||||
if len(data) == 0:
|
if len(data) == 0:
|
||||||
@@ -442,19 +474,19 @@ class GeometryWindow(ASubMainWindow, ListedSubWindow):
|
|||||||
self._tablemodel.paste(row, header, data)
|
self._tablemodel.paste(row, header, data)
|
||||||
self.select_current_profile()
|
self.select_current_profile()
|
||||||
|
|
||||||
def undo(self):
|
def _undo(self):
|
||||||
self._tablemodel.undo()
|
self._tablemodel.undo()
|
||||||
self.select_current_profile()
|
self.select_current_profile()
|
||||||
self.update_plot_xy()
|
self.update_plot_xy()
|
||||||
self.update_plot_kpc()
|
self.update_plot_kpc()
|
||||||
|
|
||||||
def redo(self):
|
def _redo(self):
|
||||||
self._tablemodel.redo()
|
self._tablemodel.redo()
|
||||||
self.select_current_profile()
|
self.select_current_profile()
|
||||||
self.update_plot_xy()
|
self.update_plot_xy()
|
||||||
self.update_plot_kpc()
|
self.update_plot_kpc()
|
||||||
|
|
||||||
def handleSave(self):
|
def export_to_file(self):
|
||||||
options = QFileDialog.Options()
|
options = QFileDialog.Options()
|
||||||
DEFAULT_DIRECTORY = '/home/'
|
DEFAULT_DIRECTORY = '/home/'
|
||||||
settings = QSettings(QSettings.IniFormat, QSettings.UserScope, 'MyOrg', )
|
settings = QSettings(QSettings.IniFormat, QSettings.UserScope, 'MyOrg', )
|
||||||
@@ -463,32 +495,11 @@ class GeometryWindow(ASubMainWindow, ListedSubWindow):
|
|||||||
|
|
||||||
filename, filters = QFileDialog.getSaveFileName(
|
filename, filters = QFileDialog.getSaveFileName(
|
||||||
self,
|
self,
|
||||||
filter=_translate("MainWindow_reach",
|
filter = self._trad["file_st"] + ";; " + self._trad["file_all"],
|
||||||
"Files .ST(*.ST or *.st)")
|
options = options
|
||||||
+ ";; " +
|
|
||||||
_translate("MainWindow_reach", "All files "
|
|
||||||
"(*)"),
|
|
||||||
options=options
|
|
||||||
)
|
)
|
||||||
|
|
||||||
current_dir = os.path.split(filename)[0] or DEFAULT_DIRECTORY
|
current_dir = os.path.split(filename)[0] or DEFAULT_DIRECTORY
|
||||||
|
|
||||||
if filename != '':
|
if filename != '':
|
||||||
self._tablemodel.export_reach(filename)
|
self._tablemodel.export_reach(filename)
|
||||||
|
|
||||||
def handleOpen(self):
|
|
||||||
filename, filterName = QFileDialog.getOpenFileName(self)
|
|
||||||
|
|
||||||
if filename != '':
|
|
||||||
with open(filename, 'r') as f:
|
|
||||||
reader = csv.reader(f, delimiter='\t')
|
|
||||||
header = next(reader)
|
|
||||||
buf = []
|
|
||||||
for row in reader:
|
|
||||||
row[0] = QCheckBox("-")
|
|
||||||
buf.append(row)
|
|
||||||
|
|
||||||
self._tablemodel = None
|
|
||||||
self._tablemodel = TableEditableModel(buf)
|
|
||||||
self.tableView.setModel(self._tablemodel)
|
|
||||||
filename = ''
|
|
||||||
@@ -1,357 +0,0 @@
|
|||||||
# mainwindow_ui_reach.py -- Pamhyr
|
|
||||||
# Copyright (C) 2023 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 sys
|
|
||||||
import os.path
|
|
||||||
|
|
||||||
from PyQt5 import QtCore, QtGui, QtWidgets
|
|
||||||
from PyQt5.QtCore import QSize, Qt
|
|
||||||
from PyQt5.QtWidgets import (
|
|
||||||
QAbstractItemView, QHeaderView, QToolBar,
|
|
||||||
)
|
|
||||||
|
|
||||||
from View.Plot import MplCanvas
|
|
||||||
from View.Plot.PamhyrToolbar import PamhyrPlotToolbar
|
|
||||||
|
|
||||||
|
|
||||||
file_path = os.path.abspath(os.path.dirname(__file__))
|
|
||||||
icon_path = f"{os.path.dirname(os.path.dirname(file_path))}/View/ui/ressources/"
|
|
||||||
|
|
||||||
class Ui_MainWindow(object):
|
|
||||||
def setupUi(self, MainWindow_reach):
|
|
||||||
MainWindow_reach.setObjectName("MainWindow_reach")
|
|
||||||
MainWindow_reach.resize(1400, 800)
|
|
||||||
self.centralwidget = QtWidgets.QWidget(MainWindow_reach)
|
|
||||||
self.centralwidget.setObjectName("centralwidget")
|
|
||||||
self.horizontalLayout_2 = QtWidgets.QHBoxLayout(self.centralwidget)
|
|
||||||
self.horizontalLayout_2.setObjectName("horizontalLayout_2")
|
|
||||||
self.splitter_3 = QtWidgets.QSplitter(self.centralwidget)
|
|
||||||
self.splitter_3.setOrientation(Qt.Horizontal)
|
|
||||||
self.splitter_3.setObjectName("splitter_3")
|
|
||||||
self.widget = QtWidgets.QWidget(self.splitter_3)
|
|
||||||
self.widget.setObjectName("widget")
|
|
||||||
self.verticalLayout = QtWidgets.QVBoxLayout(self.widget)
|
|
||||||
self.verticalLayout.setContentsMargins(0, 0, 0, 0)
|
|
||||||
self.verticalLayout.setObjectName("verticalLayout")
|
|
||||||
self.horizontalLayout = QtWidgets.QHBoxLayout()
|
|
||||||
self.horizontalLayout.setObjectName("horizontalLayout")
|
|
||||||
|
|
||||||
# self.label_section_order = QtWidgets.QLabel(self.widget)
|
|
||||||
# self.label_section_order.setLayoutDirection(Qt.LeftToRight)
|
|
||||||
# self.label_section_order.setObjectName("label_section_order")
|
|
||||||
|
|
||||||
# self.verticalLayout.addWidget(self.label_section_order)
|
|
||||||
|
|
||||||
self.toolBar = QToolBar(MainWindow_reach)
|
|
||||||
self.toolBar.setEnabled(True)
|
|
||||||
MainWindow_reach.addToolBar(QtCore.Qt.TopToolBarArea, self.toolBar)
|
|
||||||
|
|
||||||
btn_size = QSize(40, 28)
|
|
||||||
|
|
||||||
self.btn_open = QtWidgets.QAction(self.widget)
|
|
||||||
self.btn_open.setObjectName("btn_open")
|
|
||||||
icon_btn_open = QtGui.QIcon()
|
|
||||||
icon_btn_open.addPixmap(
|
|
||||||
QtGui.QPixmap(f"{icon_path}open.png"))
|
|
||||||
self.btn_open.setIcon(icon_btn_open)
|
|
||||||
self.toolBar.addAction(self.btn_open)
|
|
||||||
|
|
||||||
self.btn_add = QtWidgets.QAction(self.widget)
|
|
||||||
self.btn_add.setObjectName("btn_add")
|
|
||||||
icon_btn_add = QtGui.QIcon()
|
|
||||||
icon_btn_add.addPixmap(
|
|
||||||
QtGui.QPixmap(f"{icon_path}gtk_add.png"))
|
|
||||||
self.btn_add.setIcon(icon_btn_add)
|
|
||||||
self.toolBar.addAction(self.btn_add)
|
|
||||||
|
|
||||||
self.btn_delete = QtWidgets.QAction(self.widget)
|
|
||||||
self.btn_delete.setObjectName("btn_delete")
|
|
||||||
icon_btn_delete = QtGui.QIcon()
|
|
||||||
icon_btn_delete.addPixmap(
|
|
||||||
QtGui.QPixmap(f"{icon_path}gtk-remove.png"))
|
|
||||||
self.btn_delete.setIcon(icon_btn_delete)
|
|
||||||
self.toolBar.addAction(self.btn_delete)
|
|
||||||
|
|
||||||
self.btn_edit = QtWidgets.QAction(self.widget)
|
|
||||||
self.btn_edit.setObjectName("btn_edit")
|
|
||||||
icon_btn_edit = QtGui.QIcon()
|
|
||||||
icon_btn_edit.addPixmap(
|
|
||||||
QtGui.QPixmap(f"{icon_path}gnome-stock-edit.png"))
|
|
||||||
self.btn_edit.setIcon(icon_btn_edit)
|
|
||||||
self.toolBar.addAction(self.btn_edit)
|
|
||||||
|
|
||||||
# self.btn_copy_selected_profile = QtWidgets.QAction(self.widget)
|
|
||||||
# self.btn_copy_selected_profile.setObjectName("btn_copy_selected_profile")
|
|
||||||
# icon_btn_copy_selected_profile = QtGui.QIcon()
|
|
||||||
# icon_btn_copy_selected_profile.addPixmap(
|
|
||||||
# QtGui.QPixmap(f"{icon_path}gtk-copy.png"))
|
|
||||||
# self.btn_copy_selected_profile.setIcon(icon_btn_copy_selected_profile)
|
|
||||||
# self.toolBar.addAction(self.btn_copy_selected_profile)
|
|
||||||
|
|
||||||
# self.btn_paste_selected_profile = QtWidgets.QAction(self.widget)
|
|
||||||
# self.btn_paste_selected_profile.setObjectName("btn_paste_selected_profile")
|
|
||||||
# icon_btn_paste_selected_profile = QtGui.QIcon()
|
|
||||||
# icon_btn_paste_selected_profile.addPixmap(
|
|
||||||
# QtGui.QPixmap(f"{icon_path}gtk-paste.png"))
|
|
||||||
# self.btn_paste_selected_profile.setIcon(icon_btn_paste_selected_profile)
|
|
||||||
# self.toolBar.addAction(self.btn_paste_selected_profile)
|
|
||||||
|
|
||||||
# self.btn_duplicate_selected_profile = QtWidgets.QAction(self.widget)
|
|
||||||
# self.btn_duplicate_selected_profile.setObjectName("btn_duplicate_selected_profile")
|
|
||||||
# icon_btn_duplicate_selected_profile = QtGui.QIcon()
|
|
||||||
# icon_btn_duplicate_selected_profile.addPixmap(
|
|
||||||
# QtGui.QPixmap(f"{icon_path}gtk-dnd-multiple.png"))
|
|
||||||
# self.btn_duplicate_selected_profile.setIcon(icon_btn_duplicate_selected_profile)
|
|
||||||
# self.toolBar.addAction(self.btn_duplicate_selected_profile)
|
|
||||||
|
|
||||||
self.btn_sort_asc = QtWidgets.QAction(self.widget)
|
|
||||||
self.btn_sort_asc.setObjectName("btn_sort_asc")
|
|
||||||
icon_btn_sort_asc = QtGui.QIcon()
|
|
||||||
icon_btn_sort_asc.addPixmap(
|
|
||||||
QtGui.QPixmap(f"{icon_path}gtk-sort-ascending.png"))
|
|
||||||
self.btn_sort_asc.setIcon(icon_btn_sort_asc)
|
|
||||||
self.toolBar.addAction(self.btn_sort_asc)
|
|
||||||
|
|
||||||
self.btn_sort_desc = QtWidgets.QAction(self.widget)
|
|
||||||
self.btn_sort_desc.setObjectName("btn_sort_desc")
|
|
||||||
icon_btn_sort_desc = QtGui.QIcon()
|
|
||||||
icon_btn_sort_desc.addPixmap(
|
|
||||||
QtGui.QPixmap(f"{icon_path}gtk-sort-descending.png"))
|
|
||||||
self.btn_sort_desc.setIcon(icon_btn_sort_desc)
|
|
||||||
self.toolBar.addAction(self.btn_sort_desc)
|
|
||||||
|
|
||||||
self.btn_move_up = QtWidgets.QAction(self.widget)
|
|
||||||
self.btn_move_up.setObjectName("btn_move_up")
|
|
||||||
icon_btn_move_up = QtGui.QIcon()
|
|
||||||
icon_btn_move_up.addPixmap(
|
|
||||||
QtGui.QPixmap(f"{icon_path}up.png"))
|
|
||||||
self.btn_move_up.setIcon(icon_btn_move_up)
|
|
||||||
self.toolBar.addAction(self.btn_move_up)
|
|
||||||
|
|
||||||
self.btn_move_down = QtWidgets.QAction(self.widget)
|
|
||||||
self.btn_move_down.setObjectName("btn_move_down")
|
|
||||||
icon_btn_move_down = QtGui.QIcon()
|
|
||||||
icon_btn_move_down.addPixmap(
|
|
||||||
QtGui.QPixmap(f"{icon_path}down.png"))
|
|
||||||
self.btn_move_down.setIcon(icon_btn_move_down)
|
|
||||||
self.toolBar.addAction(self.btn_move_down)
|
|
||||||
|
|
||||||
# self.btn_end_editing = QtWidgets.QAction(self.widget)
|
|
||||||
# self.btn_end_editing.setObjectName("btn_end_editing")
|
|
||||||
# icon_btn_save = QtGui.QIcon()
|
|
||||||
# icon_btn_save.addPixmap(
|
|
||||||
# QtGui.QPixmap(f"{icon_path}gtk-apply.png"))
|
|
||||||
# self.btn_end_editing.setIcon(icon_btn_save)
|
|
||||||
# self.toolBar.addAction(self.btn_end_editing)
|
|
||||||
|
|
||||||
self.verticalLayout.addLayout(self.horizontalLayout)
|
|
||||||
self.tableView = QtWidgets.QTableView(self.widget)
|
|
||||||
self.tableView.setObjectName("tableView")
|
|
||||||
self.verticalLayout.addWidget(self.tableView)
|
|
||||||
self.tableView.setSelectionBehavior(QAbstractItemView.SelectRows)
|
|
||||||
self.tableView.horizontalHeader().setSectionResizeMode(QHeaderView.Stretch)
|
|
||||||
self.tableView.setAlternatingRowColors(True)
|
|
||||||
self.tableView.verticalHeader().hide()
|
|
||||||
self.tableView.resizeColumnsToContents()
|
|
||||||
self.tableView.resizeRowsToContents()
|
|
||||||
|
|
||||||
self.widget1 = QtWidgets.QWidget(self.splitter_3)
|
|
||||||
self.widget1.setObjectName("widget1")
|
|
||||||
self.gridLayout = QtWidgets.QGridLayout(self.widget1)
|
|
||||||
self.gridLayout.setContentsMargins(0, 0, 0, 0)
|
|
||||||
self.gridLayout.setObjectName("gridLayout")
|
|
||||||
self.splitter_2 = QtWidgets.QSplitter(self.widget1)
|
|
||||||
self.splitter_2.setOrientation(Qt.Vertical)
|
|
||||||
self.splitter_2.setObjectName("splitter_2")
|
|
||||||
self.splitter = QtWidgets.QSplitter(self.splitter_2)
|
|
||||||
self.splitter.setOrientation(Qt.Horizontal)
|
|
||||||
self.splitter.setObjectName("splitter")
|
|
||||||
self.verticalLayoutWidget_3 = QtWidgets.QWidget(self.splitter)
|
|
||||||
self.verticalLayoutWidget_3.setObjectName("verticalLayoutWidget_3")
|
|
||||||
self.verticalLayout_canvas_1 = QtWidgets.QVBoxLayout(self.verticalLayoutWidget_3)
|
|
||||||
self.verticalLayout_canvas_1.setContentsMargins(0, 0, 0, 0)
|
|
||||||
self.verticalLayout_canvas_1.setObjectName("verticalLayout_canvas_1")
|
|
||||||
|
|
||||||
self.canvas_1 = MplCanvas.MplCanvas(width=5, height=4, dpi=100)
|
|
||||||
self.canvas_1.setObjectName("canvas_1")
|
|
||||||
|
|
||||||
self.toolbar_1 = PamhyrPlotToolbar(
|
|
||||||
self.canvas_1, self.centralwidget,
|
|
||||||
items = ["home", "zoom", "save", "iso", "back/forward", "move"]
|
|
||||||
)
|
|
||||||
|
|
||||||
self.verticalLayout_canvas_1.addWidget(self.toolbar_1)
|
|
||||||
self.verticalLayout_canvas_1.addWidget(self.canvas_1)
|
|
||||||
|
|
||||||
self.verticalLayoutWidget_2 = QtWidgets.QWidget(self.splitter)
|
|
||||||
self.verticalLayoutWidget_2.setObjectName("verticalLayoutWidget_2")
|
|
||||||
self.verticalLayout_canvas_2 = QtWidgets.QVBoxLayout(self.verticalLayoutWidget_2)
|
|
||||||
self.verticalLayout_canvas_2.setContentsMargins(0, 0, 0, 0)
|
|
||||||
self.verticalLayout_canvas_2.setObjectName("verticalLayout_canvas_2")
|
|
||||||
|
|
||||||
self.canvas_2 = MplCanvas.MplCanvas(width=5, height=4, dpi=100)
|
|
||||||
self.canvas_2.setObjectName("canvas_2")
|
|
||||||
|
|
||||||
self.toolbar_2 = PamhyrPlotToolbar(
|
|
||||||
self.canvas_2, self.centralwidget,
|
|
||||||
items = ["home", "zoom", "save", "iso", "back/forward", "move"]
|
|
||||||
)
|
|
||||||
|
|
||||||
self.verticalLayout_canvas_2.addWidget(self.toolbar_2)
|
|
||||||
self.verticalLayout_canvas_2.addWidget(self.canvas_2)
|
|
||||||
self.verticalLayoutWidget = QtWidgets.QWidget(self.splitter_2)
|
|
||||||
self.verticalLayoutWidget.setObjectName("verticalLayoutWidget")
|
|
||||||
self.verticalLayout_canvas_3 = QtWidgets.QVBoxLayout(self.verticalLayoutWidget)
|
|
||||||
self.verticalLayout_canvas_3.setContentsMargins(0, 0, 0, 0)
|
|
||||||
self.verticalLayout_canvas_3.setObjectName("verticalLayout_canvas_3")
|
|
||||||
|
|
||||||
self.canvas_3 = MplCanvas.MplCanvas(width=5, height=4, dpi=100)
|
|
||||||
self.canvas_3.setObjectName("canvas_3")
|
|
||||||
|
|
||||||
self.toolbar_3 = PamhyrPlotToolbar(
|
|
||||||
self.canvas_3, self.centralwidget,
|
|
||||||
items = ["home", "zoom", "save", "iso", "back/forward", "move"]
|
|
||||||
)
|
|
||||||
|
|
||||||
self.verticalLayout_canvas_3.addWidget(self.toolbar_3)
|
|
||||||
self.verticalLayout_canvas_3.addWidget(self.canvas_3)
|
|
||||||
|
|
||||||
self.gridLayout.addWidget(self.splitter_2, 0, 0, 3, 3)
|
|
||||||
self.verticalSlider = QtWidgets.QSlider(self.widget1)
|
|
||||||
self.verticalSlider.setMinimumSize(QtCore.QSize(30, 0))
|
|
||||||
self.verticalSlider.setOrientation(Qt.Vertical)
|
|
||||||
self.verticalSlider.setInvertedAppearance(True)
|
|
||||||
self.verticalSlider.setInvertedControls(False)
|
|
||||||
self.verticalSlider.setObjectName("verticalSlider")
|
|
||||||
self.gridLayout.addWidget(self.verticalSlider, 0, 3, 1, 1)
|
|
||||||
|
|
||||||
self.btn_slider_up = QtWidgets.QPushButton(self.widget1)
|
|
||||||
self.btn_slider_up.setMaximumSize(btn_size)
|
|
||||||
self.btn_slider_up.setText("")
|
|
||||||
self.btn_slider_up.setObjectName("btn_slider_up")
|
|
||||||
icon_btn_slider_up = QtGui.QIcon()
|
|
||||||
icon_btn_slider_up.addPixmap(
|
|
||||||
QtGui.QPixmap(f"{icon_path}go-up2.png"))
|
|
||||||
self.btn_slider_up.setIcon(icon_btn_slider_up)
|
|
||||||
#self.btn_slider_up.setIconSize(btn_size)
|
|
||||||
self.gridLayout.addWidget(self.btn_slider_up, 1, 3, 1, 1)
|
|
||||||
|
|
||||||
self.btn_slider_down = QtWidgets.QPushButton(self.widget1)
|
|
||||||
self.btn_slider_down.setMaximumSize(btn_size)
|
|
||||||
self.btn_slider_down.setText("")
|
|
||||||
self.btn_slider_down.setObjectName("btn_slider_down")
|
|
||||||
icon_btn_slider_down = QtGui.QIcon()
|
|
||||||
icon_btn_slider_down.addPixmap(
|
|
||||||
QtGui.QPixmap(f"{icon_path}go-down1.png"))
|
|
||||||
self.btn_slider_down.setIcon(icon_btn_slider_down)
|
|
||||||
#self.btn_slider_down.setIconSize(btn_size)
|
|
||||||
self.gridLayout.addWidget(self.btn_slider_down, 2, 3, 1, 1)
|
|
||||||
|
|
||||||
self.vertical_slider_label = QtWidgets.QLabel(self.widget1)
|
|
||||||
self.vertical_slider_label.setObjectName("vertical_slider_label")
|
|
||||||
self.gridLayout.addWidget(self.vertical_slider_label, 3, 2, 2, 1)
|
|
||||||
self.vertical_slider_label.setAlignment(Qt.AlignRight)
|
|
||||||
|
|
||||||
# self.btn_slider_go_back = QtWidgets.QPushButton(self.widget1)
|
|
||||||
# self.btn_slider_go_back.setMaximumSize(btn_size)
|
|
||||||
# self.btn_slider_go_back.setText("")
|
|
||||||
# self.btn_slider_go_back.setObjectName("btn_slider_go_back")
|
|
||||||
# icon_btn_slider_go_back = QtGui.QIcon()
|
|
||||||
# icon_btn_slider_go_back.addPixmap(
|
|
||||||
# QtGui.QPixmap(f"{icon_path}gtk-go-back.png"))
|
|
||||||
# self.btn_slider_go_back.setIcon(icon_btn_slider_go_back)
|
|
||||||
# #self.btn_slider_go_back.setIconSize(btn_size)
|
|
||||||
# self.gridLayout.addWidget(self.btn_slider_go_back, 5, 0, 1, 1)
|
|
||||||
# self.btn_slider_go_back.setEnabled(False)
|
|
||||||
|
|
||||||
# self.btn_slider_go_forward = QtWidgets.QPushButton(self.widget1)
|
|
||||||
# self.btn_slider_go_forward.setMaximumSize(btn_size)
|
|
||||||
# self.btn_slider_go_forward.setText("")
|
|
||||||
# self.btn_slider_go_forward.setObjectName("btn_slider_go_forward")
|
|
||||||
# icon_btn_slider_go_forward = QtGui.QIcon()
|
|
||||||
# icon_btn_slider_go_forward.addPixmap(
|
|
||||||
# QtGui.QPixmap(f"{icon_path}gtk-go-forward.png"))
|
|
||||||
# self.btn_slider_go_forward.setIcon(icon_btn_slider_go_forward)
|
|
||||||
# #self.btn_slider_go_forward.setIconSize(btn_size)
|
|
||||||
# self.gridLayout.addWidget(self.btn_slider_go_forward, 5, 1, 1, 1)
|
|
||||||
# self.btn_slider_go_forward.setEnabled(False)
|
|
||||||
|
|
||||||
# self.horizontalSlider = QtWidgets.QSlider(self.widget1)
|
|
||||||
# self.horizontalSlider.setMinimumSize(QtCore.QSize(0, 30))
|
|
||||||
# self.horizontalSlider.setOrientation(Qt.Horizontal)
|
|
||||||
# self.horizontalSlider.setObjectName("horizontalSlider")
|
|
||||||
# self.gridLayout.addWidget(self.horizontalSlider, 5, 2, 1, 1)
|
|
||||||
# self.horizontalSlider.setEnabled(False)
|
|
||||||
|
|
||||||
self.horizontalLayout_2.addWidget(self.splitter_3)
|
|
||||||
MainWindow_reach.setCentralWidget(self.centralwidget)
|
|
||||||
self.menubar = QtWidgets.QMenuBar(MainWindow_reach)
|
|
||||||
self.menubar.setGeometry(QtCore.QRect(0, 0, 1123, 20))
|
|
||||||
self.menubar.setObjectName("menubar")
|
|
||||||
MainWindow_reach.setMenuBar(self.menubar)
|
|
||||||
self.statusbar = QtWidgets.QStatusBar(MainWindow_reach)
|
|
||||||
self.statusbar.setObjectName("statusbar")
|
|
||||||
MainWindow_reach.setStatusBar(self.statusbar)
|
|
||||||
|
|
||||||
self.retranslateUi(MainWindow_reach)
|
|
||||||
QtCore.QMetaObject.connectSlotsByName(MainWindow_reach)
|
|
||||||
|
|
||||||
def retranslateUi(self, MainWindow_reach):
|
|
||||||
_translate = QtCore.QCoreApplication.translate
|
|
||||||
self.name_reach = ""
|
|
||||||
self.mainwindow_title = _translate("MainWindow_reach", "Geometry reach edit")
|
|
||||||
MainWindow_reach.setWindowTitle(self.mainwindow_title + f"{self.name_reach}")
|
|
||||||
# self.label_section_order.setText(f"{self.text_section_order}")
|
|
||||||
self.vertical_slider_value = ""
|
|
||||||
self.vertical_slider_label.setText(_translate("MainWindow_reach", "Kp = ") + f"{self.vertical_slider_value}")
|
|
||||||
self.btn_open.setToolTip(_translate("MainWindow_reach", " Import geometry"))
|
|
||||||
self.btn_add.setToolTip(_translate("MainWindow_reach", " New profile"))
|
|
||||||
self.btn_delete.setToolTip(_translate("MainWindow_reach", " Delete selected profile"))
|
|
||||||
self.btn_edit.setToolTip(_translate("MainWindow_reach", " Editer selected profile"))
|
|
||||||
|
|
||||||
self.btn_sort_asc.setToolTip(_translate("MainWindow_reach", " Trier les profils par ordre croissant des Pk"))
|
|
||||||
self.btn_sort_desc.setToolTip(_translate("MainWindow_reach", " Trier les profils par ordre décroissant des Pk"))
|
|
||||||
self.btn_move_up.setToolTip(_translate("MainWindow_reach", " Changer l'ordre des profils (en décalant le "
|
|
||||||
"profil sélectionné vers le haut)"))
|
|
||||||
self.btn_move_down.setToolTip(_translate("MainWindow_reach", " Changer l'ordre des profils (en décalant le "
|
|
||||||
"profil sélectionné vers le bas)"))
|
|
||||||
# self.btn_end_editing.setToolTip(_translate("MainWindow_reach", " Terminer l'édition"))
|
|
||||||
self.tableView_header = [_translate("MainWindow_reach", "Name"),
|
|
||||||
_translate("MainWindow_reach", "Kp (m)"),
|
|
||||||
_translate("MainWindow_reach", "Type")]
|
|
||||||
|
|
||||||
self.toolbar_1._actions["isometric_view"].setShortcut(_translate("MainWindow_reach", "Alt+Z"))
|
|
||||||
self.toolbar_1._actions["isometric_view"].setToolTip(_translate("MainWindow_reach", "Vue isométrique (Alt+Z)"))
|
|
||||||
|
|
||||||
self.toolbar_2._actions["isometric_view"].setShortcut(_translate("MainWindow_reach", "Alt+E"))
|
|
||||||
self.toolbar_2._actions["isometric_view"].setToolTip(_translate("MainWindow_reach", "Vue isométrique (Alt+E)"))
|
|
||||||
|
|
||||||
self.toolbar_3._actions["isometric_view"].setShortcut(_translate("MainWindow_reach", "Alt+R"))
|
|
||||||
self.toolbar_3._actions["isometric_view"].setToolTip(_translate("MainWindow_reach", "Vue isométrique (Alt+R)"))
|
|
||||||
|
|
||||||
self.toolbar_1._actions["non_isometric_view"].setShortcut("Alt+S")
|
|
||||||
self.toolbar_1._actions["non_isometric_view"].setToolTip(
|
|
||||||
_translate("MainWindow_reach", "Vue globale automatique (Alt+S)"))
|
|
||||||
|
|
||||||
self.toolbar_2._actions["non_isometric_view"].setShortcut("Alt+D")
|
|
||||||
self.toolbar_2._actions["non_isometric_view"].setToolTip(
|
|
||||||
_translate("MainWindow_reach", "Vue globale automatique (Alt+D)"))
|
|
||||||
|
|
||||||
self.toolbar_3._actions["non_isometric_view"].setShortcut("Alt+F")
|
|
||||||
self.toolbar_3._actions["non_isometric_view"].setToolTip(
|
|
||||||
_translate("MainWindow_reach", "Vue globale automatique (Alt+F)"))
|
|
||||||
@@ -16,8 +16,7 @@
|
|||||||
|
|
||||||
# -*- coding: utf-8 -*-
|
# -*- coding: utf-8 -*-
|
||||||
|
|
||||||
from View.ASubWindow import ASubWindow
|
from View.Tools.PamhyrWindow import PamhyrDialog
|
||||||
from View.ListedSubWindow import ListedSubWindow
|
|
||||||
|
|
||||||
from PyQt5.QtGui import (
|
from PyQt5.QtGui import (
|
||||||
QKeySequence,
|
QKeySequence,
|
||||||
@@ -32,10 +31,15 @@ from PyQt5.QtWidgets import (
|
|||||||
QDoubleSpinBox,
|
QDoubleSpinBox,
|
||||||
)
|
)
|
||||||
|
|
||||||
class DischargeDialog(ASubWindow, ListedSubWindow):
|
class DischargeDialog(PamhyrDialog):
|
||||||
|
_pamhyr_ui = "InitialConditions_Dialog_Generator_Discharge"
|
||||||
|
_pamhyr_name = "Discharge"
|
||||||
|
|
||||||
def __init__(self, title="Discharge", parent=None):
|
def __init__(self, title="Discharge", parent=None):
|
||||||
super(DischargeDialog, self).__init__(
|
super(DischargeDialog, self).__init__(
|
||||||
name=title, ui="InitialConditions_Dialog_Generator_Discharge", parent=parent
|
title = self._pamhyr_name,
|
||||||
|
options = [],
|
||||||
|
parent = parent
|
||||||
)
|
)
|
||||||
|
|
||||||
self.value = None
|
self.value = None
|
||||||
|
|||||||
@@ -16,8 +16,7 @@
|
|||||||
|
|
||||||
# -*- coding: utf-8 -*-
|
# -*- coding: utf-8 -*-
|
||||||
|
|
||||||
from View.ASubWindow import ASubWindow
|
from View.Tools.PamhyrWindow import PamhyrDialog
|
||||||
from View.ListedSubWindow import ListedSubWindow
|
|
||||||
|
|
||||||
from PyQt5.QtGui import (
|
from PyQt5.QtGui import (
|
||||||
QKeySequence,
|
QKeySequence,
|
||||||
@@ -32,10 +31,15 @@ from PyQt5.QtWidgets import (
|
|||||||
QDoubleSpinBox,
|
QDoubleSpinBox,
|
||||||
)
|
)
|
||||||
|
|
||||||
class HeightDialog(ASubWindow, ListedSubWindow):
|
class HeightDialog(PamhyrDialog):
|
||||||
def __init__(self, title="Height", parent=None):
|
_pamhyr_ui = "InitialConditions_Dialog_Generator_Height"
|
||||||
|
_pamhyr_name = "Height"
|
||||||
|
|
||||||
|
def __init__(self, parent=None):
|
||||||
super(HeightDialog, self).__init__(
|
super(HeightDialog, self).__init__(
|
||||||
name=title, ui="InitialConditions_Dialog_Generator_Height", parent=parent
|
title = self._pamhyr_name,
|
||||||
|
options = [],
|
||||||
|
parent = parent
|
||||||
)
|
)
|
||||||
|
|
||||||
self.value = None
|
self.value = None
|
||||||
|
|||||||
@@ -17,7 +17,7 @@
|
|||||||
# -*- coding: utf-8 -*-
|
# -*- coding: utf-8 -*-
|
||||||
|
|
||||||
from tools import timer
|
from tools import timer
|
||||||
from View.Plot.APlot import APlot
|
from View.Tools.PamhyrPlot import PamhyrPlot
|
||||||
|
|
||||||
from PyQt5.QtCore import (
|
from PyQt5.QtCore import (
|
||||||
QCoreApplication
|
QCoreApplication
|
||||||
@@ -25,14 +25,7 @@ from PyQt5.QtCore import (
|
|||||||
|
|
||||||
_translate = QCoreApplication.translate
|
_translate = QCoreApplication.translate
|
||||||
|
|
||||||
class PlotDKP(APlot):
|
class PlotDKP(PamhyrPlot):
|
||||||
def __init__(self, canvas=None, data=None, toolbar=None):
|
|
||||||
super(PlotDKP, self).__init__(
|
|
||||||
canvas=canvas,
|
|
||||||
data=data,
|
|
||||||
toolbar=toolbar
|
|
||||||
)
|
|
||||||
|
|
||||||
@timer
|
@timer
|
||||||
def draw(self, highlight=None):
|
def draw(self, highlight=None):
|
||||||
self.canvas.axes.cla()
|
self.canvas.axes.cla()
|
||||||
@@ -42,11 +35,11 @@ class PlotDKP(APlot):
|
|||||||
return
|
return
|
||||||
|
|
||||||
self.canvas.axes.set_ylabel(
|
self.canvas.axes.set_ylabel(
|
||||||
_translate("MainWindow_reach", "Elevation (m)"),
|
self._trad["elevation"],
|
||||||
color='green', fontsize=11
|
color='green', fontsize=11
|
||||||
)
|
)
|
||||||
self.canvas.axes.set_xlabel(
|
self.canvas.axes.set_xlabel(
|
||||||
_translate("MainWindow_reach", "KP (m)"),
|
self._trad["kp"],
|
||||||
color='green', fontsize=11
|
color='green', fontsize=11
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|||||||
@@ -17,22 +17,9 @@
|
|||||||
# -*- coding: utf-8 -*-
|
# -*- coding: utf-8 -*-
|
||||||
|
|
||||||
from tools import timer
|
from tools import timer
|
||||||
from View.Plot.APlot import APlot
|
from View.Tools.PamhyrPlot import PamhyrPlot
|
||||||
|
|
||||||
from PyQt5.QtCore import (
|
|
||||||
QCoreApplication
|
|
||||||
)
|
|
||||||
|
|
||||||
_translate = QCoreApplication.translate
|
|
||||||
|
|
||||||
class PlotDischarge(APlot):
|
|
||||||
def __init__(self, canvas=None, data=None, toolbar=None):
|
|
||||||
super(PlotDischarge, self).__init__(
|
|
||||||
canvas=canvas,
|
|
||||||
data=data,
|
|
||||||
toolbar=toolbar
|
|
||||||
)
|
|
||||||
|
|
||||||
|
class PlotDischarge(PamhyrPlot):
|
||||||
@timer
|
@timer
|
||||||
def draw(self, highlight=None):
|
def draw(self, highlight=None):
|
||||||
self.canvas.axes.cla()
|
self.canvas.axes.cla()
|
||||||
@@ -42,11 +29,11 @@ class PlotDischarge(APlot):
|
|||||||
return
|
return
|
||||||
|
|
||||||
self.canvas.axes.set_ylabel(
|
self.canvas.axes.set_ylabel(
|
||||||
_translate("MainWindow_reach", "Discharge (m^3/s)"),
|
self._trad["discharge"],
|
||||||
color='green', fontsize=11
|
color='green', fontsize=11
|
||||||
)
|
)
|
||||||
self.canvas.axes.set_xlabel(
|
self.canvas.axes.set_xlabel(
|
||||||
_translate("MainWindow_reach", "KP (m)"),
|
self._trad["kp"],
|
||||||
color='green', fontsize=11
|
color='green', fontsize=11
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|||||||
@@ -33,14 +33,14 @@ from PyQt5.QtWidgets import (
|
|||||||
QComboBox,
|
QComboBox,
|
||||||
)
|
)
|
||||||
|
|
||||||
|
from View.Tools.PamhyrTable import PamhyrTableModel
|
||||||
|
|
||||||
from View.InitialConditions.UndoCommand import (
|
from View.InitialConditions.UndoCommand import (
|
||||||
SetCommand, AddCommand, DelCommand,
|
SetCommand, AddCommand, DelCommand,
|
||||||
SortCommand, MoveCommand, PasteCommand,
|
SortCommand, MoveCommand, PasteCommand,
|
||||||
DuplicateCommand, GenerateCommand,
|
DuplicateCommand, GenerateCommand,
|
||||||
)
|
)
|
||||||
|
|
||||||
from View.InitialConditions.translate import *
|
|
||||||
|
|
||||||
logger = logging.getLogger()
|
logger = logging.getLogger()
|
||||||
|
|
||||||
_translate = QCoreApplication.translate
|
_translate = QCoreApplication.translate
|
||||||
@@ -87,29 +87,13 @@ class ComboBoxDelegate(QItemDelegate):
|
|||||||
self.commitData.emit(self.sender())
|
self.commitData.emit(self.sender())
|
||||||
|
|
||||||
|
|
||||||
class TableModel(QAbstractTableModel):
|
class InitialConditionTableModel(PamhyrTableModel):
|
||||||
def __init__(self, river=None, reach=None, undo=None):
|
def __init__(self, reach=None, **kwargs):
|
||||||
super(QAbstractTableModel, self).__init__()
|
|
||||||
self._headers = list(table_headers.keys())
|
|
||||||
self._river = river
|
|
||||||
self._reach = reach
|
self._reach = reach
|
||||||
self._undo = undo
|
super(InitialConditionTableModel, self).__init__(**kwargs)
|
||||||
self._ics = self._river.initial_conditions.get(reach)
|
|
||||||
|
|
||||||
def flags(self, index):
|
def _setup_lst(self):
|
||||||
column = index.column()
|
self._lst = self._data.river.initial_conditions.get(self._reach)
|
||||||
|
|
||||||
options = Qt.ItemIsSelectable
|
|
||||||
if self._headers[column] != "speed":
|
|
||||||
options |= Qt.ItemIsEnabled | Qt.ItemIsEditable
|
|
||||||
|
|
||||||
return options
|
|
||||||
|
|
||||||
def rowCount(self, parent):
|
|
||||||
return len(self._ics)
|
|
||||||
|
|
||||||
def columnCount(self, parent):
|
|
||||||
return len(self._headers)
|
|
||||||
|
|
||||||
def data(self, index, role):
|
def data(self, index, role):
|
||||||
if role != Qt.ItemDataRole.DisplayRole:
|
if role != Qt.ItemDataRole.DisplayRole:
|
||||||
@@ -119,16 +103,10 @@ class TableModel(QAbstractTableModel):
|
|||||||
column = index.column()
|
column = index.column()
|
||||||
|
|
||||||
if self._headers[column] not in ["name", "comment"]:
|
if self._headers[column] not in ["name", "comment"]:
|
||||||
v = self._ics.get(row)[self._headers[column]]
|
v = self._lst.get(row)[self._headers[column]]
|
||||||
return f"{v:.4f}"
|
return f"{v:.4f}"
|
||||||
else:
|
else:
|
||||||
return self._ics.get(row)[self._headers[column]]
|
return self._lst.get(row)[self._headers[column]]
|
||||||
|
|
||||||
return QVariant()
|
|
||||||
|
|
||||||
def headerData(self, section, orientation, role):
|
|
||||||
if role == Qt.ItemDataRole.DisplayRole and orientation == Qt.Orientation.Horizontal:
|
|
||||||
return table_headers[self._headers[section]]
|
|
||||||
|
|
||||||
return QVariant()
|
return QVariant()
|
||||||
|
|
||||||
@@ -143,7 +121,7 @@ class TableModel(QAbstractTableModel):
|
|||||||
if self._headers[column] is not None:
|
if self._headers[column] is not None:
|
||||||
self._undo.push(
|
self._undo.push(
|
||||||
SetCommand(
|
SetCommand(
|
||||||
self._ics, row, self._headers[column], value
|
self._lst, row, self._headers[column], value
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
@@ -158,7 +136,7 @@ class TableModel(QAbstractTableModel):
|
|||||||
|
|
||||||
self._undo.push(
|
self._undo.push(
|
||||||
AddCommand(
|
AddCommand(
|
||||||
self._ics, row
|
self._lst, row
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -170,7 +148,7 @@ class TableModel(QAbstractTableModel):
|
|||||||
|
|
||||||
self._undo.push(
|
self._undo.push(
|
||||||
DelCommand(
|
DelCommand(
|
||||||
self._ics, rows
|
self._lst, rows
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -182,7 +160,7 @@ class TableModel(QAbstractTableModel):
|
|||||||
|
|
||||||
self._undo.push(
|
self._undo.push(
|
||||||
SortCommand(
|
SortCommand(
|
||||||
self._ics, False
|
self._lst, False
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -199,7 +177,7 @@ class TableModel(QAbstractTableModel):
|
|||||||
|
|
||||||
self._undo.push(
|
self._undo.push(
|
||||||
MoveCommand(
|
MoveCommand(
|
||||||
self._ics, "up", row
|
self._lst, "up", row
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -207,7 +185,7 @@ class TableModel(QAbstractTableModel):
|
|||||||
self.layoutChanged.emit()
|
self.layoutChanged.emit()
|
||||||
|
|
||||||
def move_down(self, index, parent=QModelIndex()):
|
def move_down(self, index, parent=QModelIndex()):
|
||||||
if row > len(self._ics):
|
if row > len(self._lst):
|
||||||
return
|
return
|
||||||
|
|
||||||
target = row
|
target = row
|
||||||
@@ -216,7 +194,7 @@ class TableModel(QAbstractTableModel):
|
|||||||
|
|
||||||
self._undo.push(
|
self._undo.push(
|
||||||
MoveCommand(
|
MoveCommand(
|
||||||
self._ics, "down", row
|
self._lst, "down", row
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -234,7 +212,7 @@ class TableModel(QAbstractTableModel):
|
|||||||
def generate(self, generator, param):
|
def generate(self, generator, param):
|
||||||
self._undo.push(
|
self._undo.push(
|
||||||
GenerateCommand(
|
GenerateCommand(
|
||||||
self._ics, generator, param
|
self._lst, generator, param
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
self.layoutChanged.emit()
|
self.layoutChanged.emit()
|
||||||
@@ -20,8 +20,7 @@ import logging
|
|||||||
|
|
||||||
from tools import trace, timer
|
from tools import trace, timer
|
||||||
|
|
||||||
from View.ASubWindow import ASubMainWindow
|
from View.Tools.PamhyrWindow import PamhyrWindow
|
||||||
from View.ListedSubWindow import ListedSubWindow
|
|
||||||
|
|
||||||
from PyQt5.QtGui import (
|
from PyQt5.QtGui import (
|
||||||
QKeySequence,
|
QKeySequence,
|
||||||
@@ -46,14 +45,14 @@ from View.InitialConditions.UndoCommand import (
|
|||||||
DuplicateCommand,
|
DuplicateCommand,
|
||||||
)
|
)
|
||||||
|
|
||||||
from View.InitialConditions.Table import TableModel, ComboBoxDelegate
|
from View.InitialConditions.Table import InitialConditionTableModel, ComboBoxDelegate
|
||||||
|
|
||||||
from View.Plot.MplCanvas import MplCanvas
|
from View.Tools.Plot.PamhyrCanvas import MplCanvas
|
||||||
from View.Plot.PamhyrToolbar import PamhyrPlotToolbar
|
from View.Tools.Plot.PamhyrToolbar import PamhyrPlotToolbar
|
||||||
|
|
||||||
from View.InitialConditions.PlotDKP import PlotDKP
|
from View.InitialConditions.PlotDKP import PlotDKP
|
||||||
from View.InitialConditions.PlotDischarge import PlotDischarge
|
from View.InitialConditions.PlotDischarge import PlotDischarge
|
||||||
from View.InitialConditions.translate import table_headers, retranslate
|
from View.InitialConditions.translate import ICTranslate
|
||||||
from View.InitialConditions.DialogHeight import HeightDialog
|
from View.InitialConditions.DialogHeight import HeightDialog
|
||||||
from View.InitialConditions.DialogDischarge import DischargeDialog
|
from View.InitialConditions.DialogDischarge import DischargeDialog
|
||||||
|
|
||||||
@@ -61,67 +60,62 @@ _translate = QCoreApplication.translate
|
|||||||
|
|
||||||
logger = logging.getLogger()
|
logger = logging.getLogger()
|
||||||
|
|
||||||
class InitialConditionsWindow(ASubMainWindow, ListedSubWindow):
|
class InitialConditionsWindow(PamhyrWindow):
|
||||||
def __init__(self, title="Initial condition",
|
_pamhyr_ui = "InitialConditions"
|
||||||
study=None, parent=None):
|
_pamhyr_name = "Initial condition"
|
||||||
self._study = study
|
|
||||||
self._reach = study.river.current_reach()
|
|
||||||
self._ics = self._study.river.initial_conditions.get(self._reach)
|
|
||||||
|
|
||||||
self.setup_title(title)
|
def __init__(self, study=None, config=None, reach=None, parent=None):
|
||||||
|
if reach is not None:
|
||||||
|
self._reach = reach
|
||||||
|
else:
|
||||||
|
self._reach = study.river.current_reach()
|
||||||
|
|
||||||
super(InitialConditionsWindow, self).__init__(
|
name = (
|
||||||
name=self._title, ui="InitialConditions", parent=parent
|
self._pamhyr_name +
|
||||||
|
" - " + study.name +
|
||||||
|
" - " + self._reach.name
|
||||||
)
|
)
|
||||||
|
|
||||||
self.setup_sc()
|
super(InitialConditionsWindow, self).__init__(
|
||||||
|
title = name,
|
||||||
|
study = study,
|
||||||
|
config = config,
|
||||||
|
trad = ICTranslate(),
|
||||||
|
parent = parent
|
||||||
|
)
|
||||||
|
|
||||||
|
self._ics = study.river.initial_conditions.get(self._reach)
|
||||||
|
|
||||||
self.setup_table()
|
self.setup_table()
|
||||||
self.setup_graph()
|
self.setup_plot()
|
||||||
self.setup_connections()
|
self.setup_connections()
|
||||||
|
|
||||||
self.ui.setWindowTitle(self._title)
|
self.ui.setWindowTitle(self._title)
|
||||||
|
|
||||||
def setup_title(self, title):
|
|
||||||
self._title = (
|
|
||||||
title + " - "
|
|
||||||
+ self._study.name + " - "
|
|
||||||
+ self._reach.name
|
|
||||||
)
|
|
||||||
|
|
||||||
def setup_sc(self):
|
|
||||||
self._undo_stack = QUndoStack()
|
|
||||||
|
|
||||||
self.undo_sc = QShortcut(QKeySequence.Undo, self)
|
|
||||||
self.redo_sc = QShortcut(QKeySequence.Redo, self)
|
|
||||||
self.copy_sc = QShortcut(QKeySequence.Copy, self)
|
|
||||||
self.paste_sc = QShortcut(QKeySequence.Paste, self)
|
|
||||||
|
|
||||||
def setup_table(self):
|
def setup_table(self):
|
||||||
retranslate()
|
|
||||||
|
|
||||||
table = self.find(QTableView, f"tableView")
|
table = self.find(QTableView, f"tableView")
|
||||||
self._table = TableModel(
|
|
||||||
river = self._study.river,
|
|
||||||
reach = self._reach,
|
|
||||||
undo = self._undo_stack,
|
|
||||||
)
|
|
||||||
table.setModel(self._table)
|
|
||||||
|
|
||||||
self._delegate_kp = ComboBoxDelegate(
|
self._delegate_kp = ComboBoxDelegate(
|
||||||
reach = self._reach,
|
reach = self._reach,
|
||||||
parent=self
|
parent = self
|
||||||
)
|
)
|
||||||
|
|
||||||
table.setItemDelegateForColumn(
|
self._table = InitialConditionTableModel(
|
||||||
list(table_headers).index("kp"),
|
reach = self._reach,
|
||||||
self._delegate_kp
|
table_view = table,
|
||||||
|
table_headers = self._trad.get_dict("table_headers"),
|
||||||
|
editable_headers = ["kp", "discharge", "elevation", "height"],
|
||||||
|
delegates = {"kp": self._delegate_kp},
|
||||||
|
data = self._study,
|
||||||
|
undo = self._undo_stack,
|
||||||
|
trad = self._trad
|
||||||
)
|
)
|
||||||
|
|
||||||
|
table.setModel(self._table)
|
||||||
table.setSelectionBehavior(QAbstractItemView.SelectRows)
|
table.setSelectionBehavior(QAbstractItemView.SelectRows)
|
||||||
table.horizontalHeader().setSectionResizeMode(QHeaderView.Stretch)
|
table.horizontalHeader().setSectionResizeMode(QHeaderView.Stretch)
|
||||||
table.setAlternatingRowColors(True)
|
table.setAlternatingRowColors(True)
|
||||||
|
|
||||||
def setup_graph(self):
|
def setup_plot(self):
|
||||||
self.canvas_1 = MplCanvas(width=5, height=4, dpi=100)
|
self.canvas_1 = MplCanvas(width=5, height=4, dpi=100)
|
||||||
self.canvas_1.setObjectName("canvas_1")
|
self.canvas_1.setObjectName("canvas_1")
|
||||||
self.toolbar_1 = PamhyrPlotToolbar(
|
self.toolbar_1 = PamhyrPlotToolbar(
|
||||||
@@ -134,7 +128,9 @@ class InitialConditionsWindow(ASubMainWindow, ListedSubWindow):
|
|||||||
self.plot_1 = PlotDKP(
|
self.plot_1 = PlotDKP(
|
||||||
canvas = self.canvas_1,
|
canvas = self.canvas_1,
|
||||||
data = self._ics,
|
data = self._ics,
|
||||||
|
trad = self._trad,
|
||||||
toolbar = self.toolbar_1,
|
toolbar = self.toolbar_1,
|
||||||
|
parent = self
|
||||||
)
|
)
|
||||||
self.plot_1.draw()
|
self.plot_1.draw()
|
||||||
|
|
||||||
@@ -150,7 +146,9 @@ class InitialConditionsWindow(ASubMainWindow, ListedSubWindow):
|
|||||||
self.plot_2 = PlotDischarge(
|
self.plot_2 = PlotDischarge(
|
||||||
canvas = self.canvas_2,
|
canvas = self.canvas_2,
|
||||||
data = self._ics,
|
data = self._ics,
|
||||||
|
trad = self._trad,
|
||||||
toolbar = self.toolbar_2,
|
toolbar = self.toolbar_2,
|
||||||
|
parent = self
|
||||||
)
|
)
|
||||||
self.plot_2.draw()
|
self.plot_2.draw()
|
||||||
|
|
||||||
@@ -167,11 +165,6 @@ class InitialConditionsWindow(ASubMainWindow, ListedSubWindow):
|
|||||||
self.generate_discharge
|
self.generate_discharge
|
||||||
)
|
)
|
||||||
|
|
||||||
self.undo_sc.activated.connect(self.undo)
|
|
||||||
self.redo_sc.activated.connect(self.redo)
|
|
||||||
self.copy_sc.activated.connect(self.copy)
|
|
||||||
self.paste_sc.activated.connect(self.paste)
|
|
||||||
|
|
||||||
self._table.dataChanged.connect(self._update_plot)
|
self._table.dataChanged.connect(self._update_plot)
|
||||||
|
|
||||||
def index_selected_row(self):
|
def index_selected_row(self):
|
||||||
@@ -227,19 +220,19 @@ class InitialConditionsWindow(ASubMainWindow, ListedSubWindow):
|
|||||||
self._table.move_down(row)
|
self._table.move_down(row)
|
||||||
self._update_plot()
|
self._update_plot()
|
||||||
|
|
||||||
def copy(self):
|
def _copy(self):
|
||||||
logger.info("TODO: copy")
|
logger.info("TODO: copy")
|
||||||
self._update_plot()
|
self._update_plot()
|
||||||
|
|
||||||
def paste(self):
|
def _paste(self):
|
||||||
logger.info("TODO: paste")
|
logger.info("TODO: paste")
|
||||||
self._update_plot()
|
self._update_plot()
|
||||||
|
|
||||||
def undo(self):
|
def _undo(self):
|
||||||
self._table.undo()
|
self._table.undo()
|
||||||
self._update_plot()
|
self._update_plot()
|
||||||
|
|
||||||
def redo(self):
|
def _redo(self):
|
||||||
self._table.redo()
|
self._table.redo()
|
||||||
self._update_plot()
|
self._update_plot()
|
||||||
|
|
||||||
|
|||||||
@@ -18,23 +18,24 @@
|
|||||||
|
|
||||||
from PyQt5.QtCore import QCoreApplication
|
from PyQt5.QtCore import QCoreApplication
|
||||||
|
|
||||||
|
from View.Tools.PamhyrTranslate import PamhyrTranslate
|
||||||
|
|
||||||
_translate = QCoreApplication.translate
|
_translate = QCoreApplication.translate
|
||||||
|
|
||||||
table_headers = {
|
class ICTranslate(PamhyrTranslate):
|
||||||
# "name": _translate("LateralContribution", "Name"),
|
def __init__(self):
|
||||||
"kp": _translate("LateralContribution", "KP (m)"),
|
super(ICTranslate, self).__init__()
|
||||||
# "speed": _translate("LateralContribution", "Speed (m/s)"),
|
|
||||||
"discharge": _translate("LateralContribution", "Discharge (m³/s)"),
|
|
||||||
"elevation": _translate("LateralContribution", "Elevation (m)"),
|
|
||||||
"height": _translate("LateralContribution", "Height (m)"),
|
|
||||||
# "comment": _translate("LateralContribution", "Comment"),
|
|
||||||
}
|
|
||||||
|
|
||||||
def retranslate():
|
self._dict["elevation"] = _translate("InitialCondition", "Elevation (m)")
|
||||||
# table_headers["name"] = _translate("LateralContribution", "Name")
|
self._dict["discharge"] = _translate("InitialCondition", "Discharge (m³/s)")
|
||||||
table_headers["kp"] = _translate("LateralContribution", "KP (m)")
|
self._dict["kp"] = _translate("InitialCondition", "KP (m)")
|
||||||
# table_headers["speed"] = _translate("LateralContribution", "Speed (m/s)")
|
|
||||||
table_headers["discharge"] = _translate("LateralContribution", "Discharge (m³/s)")
|
self._sub_dict["table_headers"] = {
|
||||||
table_headers["elevation"] = _translate("LateralContribution", "Elevation (m)")
|
# "name": _translate("InitialCondition", "Name"),
|
||||||
table_headers["height"] = _translate("LateralContribution", "Height (m)")
|
"kp": _translate("InitialCondition", "KP (m)"),
|
||||||
# table_headers["comment"] = _translate("LateralContribution", "Comment")
|
# "speed": _translate("InitialCondition", "Speed (m/s)"),
|
||||||
|
"discharge": _translate("InitialCondition", "Discharge (m³/s)"),
|
||||||
|
"elevation": _translate("InitialCondition", "Elevation (m)"),
|
||||||
|
"height": _translate("InitialCondition", "Height (m)"),
|
||||||
|
# "comment": _translate("InitialCondition", "Comment"),
|
||||||
|
}
|
||||||
@@ -19,7 +19,7 @@
|
|||||||
from datetime import datetime
|
from datetime import datetime
|
||||||
|
|
||||||
from tools import timer, trace
|
from tools import timer, trace
|
||||||
from View.Plot.APlot import APlot
|
from View.Tools.PamhyrPlot import PamhyrPlot
|
||||||
|
|
||||||
from PyQt5.QtCore import (
|
from PyQt5.QtCore import (
|
||||||
QCoreApplication
|
QCoreApplication
|
||||||
@@ -29,15 +29,19 @@ from View.LateralContribution.Edit.translate import *
|
|||||||
|
|
||||||
_translate = QCoreApplication.translate
|
_translate = QCoreApplication.translate
|
||||||
|
|
||||||
class Plot(APlot):
|
class Plot(PamhyrPlot):
|
||||||
def __init__(self, canvas=None, data=None,
|
def __init__(self, mode = "time", data=None,
|
||||||
mode = "time", toolbar=None):
|
canvas=None, trad=None, toolbar=None,
|
||||||
|
parent=None):
|
||||||
super(Plot, self).__init__(
|
super(Plot, self).__init__(
|
||||||
canvas=canvas,
|
canvas = canvas,
|
||||||
data=data,
|
trad = trad,
|
||||||
toolbar=toolbar
|
data = data,
|
||||||
|
toolbar = toolbar,
|
||||||
|
parent = parent
|
||||||
)
|
)
|
||||||
|
|
||||||
|
self._table_headers = self._trad.get_dict("table_headers")
|
||||||
self._mode = mode
|
self._mode = mode
|
||||||
|
|
||||||
def custom_ticks(self):
|
def custom_ticks(self):
|
||||||
@@ -105,10 +109,10 @@ class Plot(APlot):
|
|||||||
# Plot label
|
# Plot label
|
||||||
header = self.data.header
|
header = self.data.header
|
||||||
self.canvas.axes.set_xlabel(
|
self.canvas.axes.set_xlabel(
|
||||||
table_headers[header[0]], color='black', fontsize=10
|
self._table_headers[header[0]], color='black', fontsize=10
|
||||||
)
|
)
|
||||||
self.canvas.axes.set_ylabel(
|
self.canvas.axes.set_ylabel(
|
||||||
table_headers[header[1]], color='black', fontsize=10
|
self._table_headers[header[1]], color='black', fontsize=10
|
||||||
)
|
)
|
||||||
|
|
||||||
self.canvas.axes.autoscale_view(True, True, True)
|
self.canvas.axes.autoscale_view(True, True, True)
|
||||||
|
|||||||
@@ -22,8 +22,6 @@ from datetime import date, time, datetime, timedelta
|
|||||||
|
|
||||||
from tools import trace, timer
|
from tools import trace, timer
|
||||||
|
|
||||||
from View.ASubWindow import ASubMainWindow, AWidget
|
|
||||||
from View.ListedSubWindow import ListedSubWindow
|
|
||||||
from View.Tools.PamhyrTable import PamhyrTableModel
|
from View.Tools.PamhyrTable import PamhyrTableModel
|
||||||
|
|
||||||
from PyQt5.QtCore import (
|
from PyQt5.QtCore import (
|
||||||
|
|||||||
@@ -18,8 +18,7 @@
|
|||||||
|
|
||||||
from tools import timer, trace
|
from tools import timer, trace
|
||||||
|
|
||||||
from View.ASubWindow import ASubMainWindow
|
from View.Tools.PamhyrWindow import PamhyrWindow
|
||||||
from View.ListedSubWindow import ListedSubWindow
|
|
||||||
from View.Tools.PamhyrDelegate import PamhyrExTimeDelegate
|
from View.Tools.PamhyrDelegate import PamhyrExTimeDelegate
|
||||||
|
|
||||||
from PyQt5.QtGui import (
|
from PyQt5.QtGui import (
|
||||||
@@ -37,67 +36,60 @@ from PyQt5.QtWidgets import (
|
|||||||
QHeaderView,
|
QHeaderView,
|
||||||
)
|
)
|
||||||
|
|
||||||
from View.Plot.MplCanvas import MplCanvas
|
from View.Tools.Plot.PamhyrCanvas import MplCanvas
|
||||||
from View.Plot.PamhyrToolbar import PamhyrPlotToolbar
|
from View.Tools.Plot.PamhyrToolbar import PamhyrPlotToolbar
|
||||||
|
|
||||||
from View.LateralContribution.translate import long_types
|
from View.LateralContribution.Edit.translate import LCETranslate
|
||||||
from View.LateralContribution.Edit.translate import table_headers, retranslate
|
|
||||||
from View.LateralContribution.Edit.Table import TableModel
|
from View.LateralContribution.Edit.Table import TableModel
|
||||||
from View.LateralContribution.Edit.Plot import Plot
|
from View.LateralContribution.Edit.Plot import Plot
|
||||||
|
|
||||||
_translate = QCoreApplication.translate
|
_translate = QCoreApplication.translate
|
||||||
|
|
||||||
class EditLateralContributionWindow(ASubMainWindow, ListedSubWindow):
|
class EditLateralContributionWindow(PamhyrWindow):
|
||||||
def __init__(self, title="Edit lateral contribution",
|
_pamhyr_ui = "EditLateralContribution"
|
||||||
data=None, study=None, parent=None):
|
_pamhyr_name = "Edit lateral contribution"
|
||||||
self._data = data
|
|
||||||
self._study = study
|
|
||||||
self._title = title
|
|
||||||
|
|
||||||
self.compute_title()
|
def __init__(self, data=None,
|
||||||
|
study=None, config=None,
|
||||||
|
parent=None):
|
||||||
|
self._data = data
|
||||||
|
trad = LCETranslate()
|
||||||
|
|
||||||
|
name = self._pamhyr_name
|
||||||
|
if self._data is not None:
|
||||||
|
edge_name = (self._data.edge.name if self._data.edge is not None
|
||||||
|
else _translate("LateralContribution", "Not associate"))
|
||||||
|
name = (
|
||||||
|
_translate("Edit lateral contribution", self._pamhyr_name) +
|
||||||
|
f" - {study.name} " +
|
||||||
|
f" - {self._data.name} ({self._data.id}) " +
|
||||||
|
f"({trad.get_dict('long_types')[self._data.lctype]} - {edge_name})"
|
||||||
|
)
|
||||||
|
|
||||||
super(EditLateralContributionWindow, self).__init__(
|
super(EditLateralContributionWindow, self).__init__(
|
||||||
name=title, ui="EditLateralContribution", parent=parent
|
title = name,
|
||||||
|
study = study,
|
||||||
|
config = config,
|
||||||
|
trad = trad,
|
||||||
|
parent = parent
|
||||||
)
|
)
|
||||||
|
|
||||||
self.ui.setWindowTitle(self._title)
|
|
||||||
|
|
||||||
self.setup_sc()
|
|
||||||
self.setup_table()
|
self.setup_table()
|
||||||
self.setup_plot()
|
self.setup_plot()
|
||||||
self.setup_connections()
|
self.setup_connections()
|
||||||
|
|
||||||
def compute_title(self):
|
|
||||||
if self._data is not None:
|
|
||||||
edge_name = (self._data.edge.name if self._data.edge is not None
|
|
||||||
else _translate("LateralContribution", "Not associate"))
|
|
||||||
self._title = (
|
|
||||||
_translate("Edit lateral contribution", self._title) +
|
|
||||||
f" - {self._study.name} " +
|
|
||||||
f" - {self._data.name} ({self._data.id}) " +
|
|
||||||
f"({long_types[self._data.lctype]} - {edge_name})"
|
|
||||||
)
|
|
||||||
|
|
||||||
def setup_sc(self):
|
|
||||||
self._undo_stack = QUndoStack()
|
|
||||||
|
|
||||||
self.undo_sc = QShortcut(QKeySequence.Undo, self)
|
|
||||||
self.redo_sc = QShortcut(QKeySequence.Redo, self)
|
|
||||||
self.copy_sc = QShortcut(QKeySequence.Copy, self)
|
|
||||||
self.paste_sc = QShortcut(QKeySequence.Paste, self)
|
|
||||||
|
|
||||||
def setup_table(self):
|
def setup_table(self):
|
||||||
retranslate()
|
|
||||||
headers = {}
|
|
||||||
for h in self._data.header:
|
|
||||||
headers[h] = table_headers[h]
|
|
||||||
|
|
||||||
self._delegate_time = PamhyrExTimeDelegate(
|
self._delegate_time = PamhyrExTimeDelegate(
|
||||||
data = self._data,
|
data = self._data,
|
||||||
mode = self._study.time_system,
|
mode = self._study.time_system,
|
||||||
parent = self
|
parent = self
|
||||||
)
|
)
|
||||||
|
|
||||||
|
headers = {}
|
||||||
|
table_headers = self._trad.get_dict("table_headers")
|
||||||
|
for h in self._data.header:
|
||||||
|
headers[h] = table_headers[h]
|
||||||
|
|
||||||
table = self.find(QTableView, "tableView")
|
table = self.find(QTableView, "tableView")
|
||||||
self._table = TableModel(
|
self._table = TableModel(
|
||||||
table_view = table,
|
table_view = table,
|
||||||
@@ -108,6 +100,7 @@ class EditLateralContributionWindow(ASubMainWindow, ListedSubWindow):
|
|||||||
},
|
},
|
||||||
data = self._data,
|
data = self._data,
|
||||||
undo = self._undo_stack,
|
undo = self._undo_stack,
|
||||||
|
trad = self._trad,
|
||||||
opt_data = self._study.time_system
|
opt_data = self._study.time_system
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -130,20 +123,16 @@ class EditLateralContributionWindow(ASubMainWindow, ListedSubWindow):
|
|||||||
data = self._data,
|
data = self._data,
|
||||||
mode = self._study.time_system,
|
mode = self._study.time_system,
|
||||||
toolbar = self.toolbar,
|
toolbar = self.toolbar,
|
||||||
|
trad = self._trad,
|
||||||
|
parent = self
|
||||||
)
|
)
|
||||||
self.plot.draw()
|
self.plot.draw()
|
||||||
|
|
||||||
|
|
||||||
def setup_connections(self):
|
def setup_connections(self):
|
||||||
self.find(QAction, "action_add").triggered.connect(self.add)
|
self.find(QAction, "action_add").triggered.connect(self.add)
|
||||||
self.find(QAction, "action_del").triggered.connect(self.delete)
|
self.find(QAction, "action_del").triggered.connect(self.delete)
|
||||||
self.find(QAction, "action_sort").triggered.connect(self.sort)
|
self.find(QAction, "action_sort").triggered.connect(self.sort)
|
||||||
|
|
||||||
self.undo_sc.activated.connect(self.undo)
|
|
||||||
self.redo_sc.activated.connect(self.redo)
|
|
||||||
self.copy_sc.activated.connect(self.copy)
|
|
||||||
self.paste_sc.activated.connect(self.paste)
|
|
||||||
|
|
||||||
self._table.dataChanged.connect(self.update)
|
self._table.dataChanged.connect(self.update)
|
||||||
|
|
||||||
def update(self):
|
def update(self):
|
||||||
@@ -199,8 +188,7 @@ class EditLateralContributionWindow(ASubMainWindow, ListedSubWindow):
|
|||||||
self._table.move_down(row)
|
self._table.move_down(row)
|
||||||
self.plot.update()
|
self.plot.update()
|
||||||
|
|
||||||
|
def _copy(self):
|
||||||
def copy(self):
|
|
||||||
rows = self.index_selected_rows()
|
rows = self.index_selected_rows()
|
||||||
|
|
||||||
table = []
|
table = []
|
||||||
@@ -212,7 +200,7 @@ class EditLateralContributionWindow(ASubMainWindow, ListedSubWindow):
|
|||||||
|
|
||||||
self.copyTableIntoClipboard(table)
|
self.copyTableIntoClipboard(table)
|
||||||
|
|
||||||
def paste(self):
|
def _paste(self):
|
||||||
header, data = self.parseClipboardTable()
|
header, data = self.parseClipboardTable()
|
||||||
|
|
||||||
if len(data) == 0:
|
if len(data) == 0:
|
||||||
@@ -226,10 +214,10 @@ class EditLateralContributionWindow(ASubMainWindow, ListedSubWindow):
|
|||||||
self._table.paste(row, header, data)
|
self._table.paste(row, header, data)
|
||||||
self.plot.update()
|
self.plot.update()
|
||||||
|
|
||||||
def undo(self):
|
def _undo(self):
|
||||||
self._table.undo()
|
self._table.undo()
|
||||||
self.plot.update()
|
self.plot.update()
|
||||||
|
|
||||||
def redo(self):
|
def _redo(self):
|
||||||
self._table.redo()
|
self._table.redo()
|
||||||
self.plot.update()
|
self.plot.update()
|
||||||
@@ -18,21 +18,20 @@
|
|||||||
|
|
||||||
from PyQt5.QtCore import QCoreApplication
|
from PyQt5.QtCore import QCoreApplication
|
||||||
|
|
||||||
|
from View.Tools.PamhyrTranslate import PamhyrTranslate
|
||||||
|
from View.LateralContribution.translate import LCTranslate
|
||||||
|
|
||||||
_translate = QCoreApplication.translate
|
_translate = QCoreApplication.translate
|
||||||
|
|
||||||
table_headers = {
|
class LCETranslate(LCTranslate):
|
||||||
"x": _translate("LateralContribution", "X"),
|
def __init__(self):
|
||||||
"y": _translate("LateralContribution", "Y"),
|
super(LCETranslate, self).__init__()
|
||||||
"time": _translate("LateralContribution", "Time"),
|
|
||||||
"date": _translate("LateralContribution", "Date"),
|
|
||||||
"discharge": _translate("LateralContribution", "Discharge (m³/s)"),
|
|
||||||
"z": _translate("LateralContribution", "Z (m)")
|
|
||||||
}
|
|
||||||
|
|
||||||
def retranslate():
|
self._sub_dict["table_headers"] = {
|
||||||
table_headers["x"] = _translate("LateralContribution", "X")
|
"x": _translate("LateralContribution", "X"),
|
||||||
table_headers["y"] = _translate("LateralContribution", "Y")
|
"y": _translate("LateralContribution", "Y"),
|
||||||
table_headers["time"] = _translate("LateralContribution", "Time")
|
"time": _translate("LateralContribution", "Time"),
|
||||||
table_headers["date"] = _translate("LateralContribution", "Date")
|
"date": _translate("LateralContribution", "Date"),
|
||||||
table_headers["discharge"] = _translate("LateralContribution", "Discharge (m³/s)")
|
"discharge": _translate("LateralContribution", "Discharge (m³/s)"),
|
||||||
table_headers["z"] = _translate("LateralContribution", "Z (m)")
|
"z": _translate("LateralContribution", "Z (m)")
|
||||||
|
}
|
||||||
@@ -46,22 +46,24 @@ from Model.LateralContribution.LateralContributionTypes import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
from View.Tools.PamhyrTable import PamhyrTableModel
|
from View.Tools.PamhyrTable import PamhyrTableModel
|
||||||
from View.LateralContribution.translate import *
|
from View.LateralContribution.translate import LC_types
|
||||||
|
|
||||||
logger = logging.getLogger()
|
logger = logging.getLogger()
|
||||||
|
|
||||||
_translate = QCoreApplication.translate
|
_translate = QCoreApplication.translate
|
||||||
|
|
||||||
class ComboBoxDelegate(QItemDelegate):
|
class ComboBoxDelegate(QItemDelegate):
|
||||||
def __init__(self, data=None, mode="type", tab="", parent=None):
|
def __init__(self, data=None, mode="type", tab="", trad = None, parent=None):
|
||||||
super(ComboBoxDelegate, self).__init__(parent)
|
super(ComboBoxDelegate, self).__init__(parent)
|
||||||
|
|
||||||
self._data = data
|
self._data = data
|
||||||
self._mode = mode
|
self._mode = mode
|
||||||
self._tab = tab
|
self._tab = tab
|
||||||
|
self._trad = trad
|
||||||
|
|
||||||
def createEditor(self, parent, option, index):
|
def createEditor(self, parent, option, index):
|
||||||
self.editor = QComboBox(parent)
|
self.editor = QComboBox(parent)
|
||||||
|
long_types = self._trad.get_dict("long_types")
|
||||||
|
|
||||||
if self._mode == "type":
|
if self._mode == "type":
|
||||||
lst = list(
|
lst = list(
|
||||||
@@ -108,6 +110,7 @@ class TableModel(PamhyrTableModel):
|
|||||||
def _setup_lst(self):
|
def _setup_lst(self):
|
||||||
self._lst = self._data.lateral_contribution
|
self._lst = self._data.lateral_contribution
|
||||||
self._tab = self._opt_data
|
self._tab = self._opt_data
|
||||||
|
self._long_types = self._trad.get_dict("long_types")
|
||||||
|
|
||||||
def rowCount(self, parent):
|
def rowCount(self, parent):
|
||||||
return self._lst.len(self._tab)
|
return self._lst.len(self._tab)
|
||||||
@@ -123,7 +126,7 @@ class TableModel(PamhyrTableModel):
|
|||||||
return self._lst.get(self._tab, row).name
|
return self._lst.get(self._tab, row).name
|
||||||
elif self._headers[column] == "type":
|
elif self._headers[column] == "type":
|
||||||
t = self._lst.get(self._tab, row).lctype
|
t = self._lst.get(self._tab, row).lctype
|
||||||
return long_types[t]
|
return self._long_types[t]
|
||||||
elif self._headers[column] == "edge":
|
elif self._headers[column] == "edge":
|
||||||
n = self._lst.get(self._tab, row).edge
|
n = self._lst.get(self._tab, row).edge
|
||||||
if n is None:
|
if n is None:
|
||||||
@@ -151,7 +154,7 @@ class TableModel(PamhyrTableModel):
|
|||||||
)
|
)
|
||||||
)
|
)
|
||||||
elif self._headers[column] == "type":
|
elif self._headers[column] == "type":
|
||||||
key = next(k for k, v in long_types.items() if v == value)
|
key = next(k for k, v in self._long_types.items() if v == value)
|
||||||
self._undo.push(
|
self._undo.push(
|
||||||
SetTypeCommand(
|
SetTypeCommand(
|
||||||
self._lst, self._tab, row, LC_types[key]
|
self._lst, self._tab, row, LC_types[key]
|
||||||
|
|||||||
@@ -20,8 +20,7 @@ import logging
|
|||||||
|
|
||||||
from tools import trace, timer
|
from tools import trace, timer
|
||||||
|
|
||||||
from View.ASubWindow import ASubMainWindow
|
from View.Tools.PamhyrWindow import PamhyrWindow
|
||||||
from View.ListedSubWindow import ListedSubWindow
|
|
||||||
|
|
||||||
from PyQt5.QtGui import (
|
from PyQt5.QtGui import (
|
||||||
QKeySequence,
|
QKeySequence,
|
||||||
@@ -54,46 +53,37 @@ from View.LateralContribution.Table import (
|
|||||||
TableModel, ComboBoxDelegate
|
TableModel, ComboBoxDelegate
|
||||||
)
|
)
|
||||||
|
|
||||||
from View.Plot.MplCanvas import MplCanvas
|
from View.Tools.Plot.PamhyrCanvas import MplCanvas
|
||||||
from View.Geometry.PlotXY import PlotXY
|
from View.Geometry.PlotXY import PlotXY
|
||||||
from View.LateralContribution.translate import (
|
from View.LateralContribution.translate import (
|
||||||
long_types, table_headers, LC_types,
|
LC_types, LCTranslate,
|
||||||
retranslate,
|
|
||||||
)
|
)
|
||||||
from View.LateralContribution.Edit.Window import EditLateralContributionWindow
|
from View.LateralContribution.Edit.Window import EditLateralContributionWindow
|
||||||
|
|
||||||
_translate = QCoreApplication.translate
|
|
||||||
|
|
||||||
logger = logging.getLogger()
|
logger = logging.getLogger()
|
||||||
|
|
||||||
class LateralContributionWindow(ASubMainWindow, ListedSubWindow):
|
class LateralContributionWindow(PamhyrWindow):
|
||||||
def __init__(self, title="Lateral contribution", study=None, parent=None):
|
_pamhyr_ui = "LateralContributions"
|
||||||
self._title = title + " - " + study.name
|
_pamhyr_name = "Lateral contribution"
|
||||||
|
|
||||||
|
def __init__(self, study=None, config=None, parent=None):
|
||||||
|
name = self._pamhyr_name + " - " + study.name
|
||||||
|
|
||||||
super(LateralContributionWindow, self).__init__(
|
super(LateralContributionWindow, self).__init__(
|
||||||
name=title, ui="LateralContributions", parent=parent
|
title = name,
|
||||||
|
study = study,
|
||||||
|
trad = LCTranslate(),
|
||||||
|
config = config,
|
||||||
|
parent=parent
|
||||||
)
|
)
|
||||||
|
|
||||||
self._study = study
|
|
||||||
self._lcs = self._study.river.lateral_contribution
|
self._lcs = self._study.river.lateral_contribution
|
||||||
|
|
||||||
self.setup_sc()
|
|
||||||
self.setup_table()
|
self.setup_table()
|
||||||
self.setup_graph()
|
self.setup_graph()
|
||||||
self.setup_connections()
|
self.setup_connections()
|
||||||
|
|
||||||
self.ui.setWindowTitle(self._title)
|
|
||||||
|
|
||||||
def setup_sc(self):
|
|
||||||
self._undo_stack = QUndoStack()
|
|
||||||
|
|
||||||
self.undo_sc = QShortcut(QKeySequence.Undo, self)
|
|
||||||
self.redo_sc = QShortcut(QKeySequence.Redo, self)
|
|
||||||
self.copy_sc = QShortcut(QKeySequence.Copy, self)
|
|
||||||
self.paste_sc = QShortcut(QKeySequence.Paste, self)
|
|
||||||
|
|
||||||
def setup_table(self):
|
def setup_table(self):
|
||||||
retranslate()
|
|
||||||
self._table = {}
|
self._table = {}
|
||||||
|
|
||||||
for t in ["liquid", "solid", "suspenssion"]:
|
for t in ["liquid", "solid", "suspenssion"]:
|
||||||
@@ -101,19 +91,21 @@ class LateralContributionWindow(ASubMainWindow, ListedSubWindow):
|
|||||||
data = self._study.river,
|
data = self._study.river,
|
||||||
mode = "type",
|
mode = "type",
|
||||||
tab = t,
|
tab = t,
|
||||||
|
trad = self._trad,
|
||||||
parent=self
|
parent=self
|
||||||
)
|
)
|
||||||
self._delegate_edge = ComboBoxDelegate(
|
self._delegate_edge = ComboBoxDelegate(
|
||||||
data = self._study.river,
|
data = self._study.river,
|
||||||
mode = "edge",
|
mode = "edge",
|
||||||
tab = t,
|
tab = t,
|
||||||
|
trad = self._trad,
|
||||||
parent=self
|
parent=self
|
||||||
)
|
)
|
||||||
|
|
||||||
table = self.find(QTableView, f"tableView_{t}")
|
table = self.find(QTableView, f"tableView_{t}")
|
||||||
self._table[t] = TableModel(
|
self._table[t] = TableModel(
|
||||||
table_view = table,
|
table_view = table,
|
||||||
table_headers = table_headers,
|
table_headers = self._trad.get_dict("table_headers"),
|
||||||
editable_headers = True,
|
editable_headers = True,
|
||||||
delegates = {
|
delegates = {
|
||||||
"type": self._delegate_type,
|
"type": self._delegate_type,
|
||||||
@@ -121,6 +113,7 @@ class LateralContributionWindow(ASubMainWindow, ListedSubWindow):
|
|||||||
},
|
},
|
||||||
data = self._study.river,
|
data = self._study.river,
|
||||||
undo = self._undo_stack,
|
undo = self._undo_stack,
|
||||||
|
trad = self._trad,
|
||||||
opt_data = t,
|
opt_data = t,
|
||||||
)
|
)
|
||||||
table.setModel(self._table[t])
|
table.setModel(self._table[t])
|
||||||
@@ -146,11 +139,6 @@ class LateralContributionWindow(ASubMainWindow, ListedSubWindow):
|
|||||||
self.find(QAction, "action_edit").triggered.connect(self.edit)
|
self.find(QAction, "action_edit").triggered.connect(self.edit)
|
||||||
self.find(QAction, "action_sort").triggered.connect(self.sort)
|
self.find(QAction, "action_sort").triggered.connect(self.sort)
|
||||||
|
|
||||||
self.undo_sc.activated.connect(self.undo)
|
|
||||||
self.redo_sc.activated.connect(self.redo)
|
|
||||||
self.copy_sc.activated.connect(self.copy)
|
|
||||||
self.paste_sc.activated.connect(self.paste)
|
|
||||||
|
|
||||||
for t in ["liquid", "solid", "suspenssion"]:
|
for t in ["liquid", "solid", "suspenssion"]:
|
||||||
table = self.find(QTableView, f"tableView_{t}")
|
table = self.find(QTableView, f"tableView_{t}")
|
||||||
table.selectionModel()\
|
table.selectionModel()\
|
||||||
@@ -247,20 +235,20 @@ class LateralContributionWindow(ASubMainWindow, ListedSubWindow):
|
|||||||
self._table[tab].move_down(row)
|
self._table[tab].move_down(row)
|
||||||
self._set_current_reach()
|
self._set_current_reach()
|
||||||
|
|
||||||
def copy(self):
|
def _copy(self):
|
||||||
logger.info("TODO: copy")
|
logger.info("TODO: copy")
|
||||||
self._set_current_reach()
|
self._set_current_reach()
|
||||||
|
|
||||||
def paste(self):
|
def _paste(self):
|
||||||
logger.info("TODO: paste")
|
logger.info("TODO: paste")
|
||||||
self._set_current_reach()
|
self._set_current_reach()
|
||||||
|
|
||||||
def undo(self):
|
def _undo(self):
|
||||||
tab = self.current_tab()
|
tab = self.current_tab()
|
||||||
self._table[tab].undo()
|
self._table[tab].undo()
|
||||||
self._set_current_reach()
|
self._set_current_reach()
|
||||||
|
|
||||||
def redo(self):
|
def _redo(self):
|
||||||
tab = self.current_tab()
|
tab = self.current_tab()
|
||||||
self._table[tab].redo()
|
self._table[tab].redo()
|
||||||
self._set_current_reach()
|
self._set_current_reach()
|
||||||
|
|||||||
@@ -18,27 +18,14 @@
|
|||||||
|
|
||||||
from PyQt5.QtCore import QCoreApplication
|
from PyQt5.QtCore import QCoreApplication
|
||||||
|
|
||||||
|
from View.Tools.PamhyrTranslate import PamhyrTranslate
|
||||||
|
|
||||||
from Model.LateralContribution.LateralContributionTypes import (
|
from Model.LateralContribution.LateralContributionTypes import (
|
||||||
NotDefined, LateralContrib, Rain, Evaporation,
|
NotDefined, LateralContrib, Rain, Evaporation,
|
||||||
)
|
)
|
||||||
|
|
||||||
_translate = QCoreApplication.translate
|
_translate = QCoreApplication.translate
|
||||||
|
|
||||||
long_types = {
|
|
||||||
"ND": _translate("LateralContribution", "Not defined"),
|
|
||||||
"LC": _translate("LateralContribution", "Lateral contribution"),
|
|
||||||
"RA": _translate("LateralContribution", "Rain"),
|
|
||||||
"EV": _translate("LateralContribution", "Evaporation"),
|
|
||||||
}
|
|
||||||
|
|
||||||
table_headers = {
|
|
||||||
"name": _translate("LateralContribution", "Name"),
|
|
||||||
"type": _translate("LateralContribution", "Type"),
|
|
||||||
"edge": _translate("LateralContribution", "Reach"),
|
|
||||||
"begin_kp": _translate("LateralContribution", "Begin kp (m)"),
|
|
||||||
"end_kp": _translate("LateralContribution", "End kp (m)")
|
|
||||||
}
|
|
||||||
|
|
||||||
LC_types = {
|
LC_types = {
|
||||||
"ND": NotDefined,
|
"ND": NotDefined,
|
||||||
"LC": LateralContrib,
|
"LC": LateralContrib,
|
||||||
@@ -46,14 +33,21 @@ LC_types = {
|
|||||||
"EV": Evaporation,
|
"EV": Evaporation,
|
||||||
}
|
}
|
||||||
|
|
||||||
def retranslate():
|
class LCTranslate(PamhyrTranslate):
|
||||||
table_headers["name"] = _translate("LateralContribution", "Name")
|
def __init__(self):
|
||||||
table_headers["type"] = _translate("LateralContribution", "Type")
|
super(LCTranslate, self).__init__()
|
||||||
table_headers["edge"] = _translate("LateralContribution", "Reach")
|
|
||||||
table_headers["begin_kp"] = _translate("LateralContribution", "Begin kp (m)")
|
|
||||||
table_headers["end_kp"] = _translate("LateralContribution", "End kp (m)")
|
|
||||||
|
|
||||||
long_types["ND"] = _translate("LateralContribution", "Not defined")
|
self._sub_dict["long_types"] = {
|
||||||
long_types["LC"] = _translate("LateralContribution", "Lateral contribution")
|
"ND": _translate("LateralContribution", "Not defined"),
|
||||||
long_types["RA"] = _translate("LateralContribution", "Rain")
|
"LC": _translate("LateralContribution", "Lateral contribution"),
|
||||||
long_types["EV"] = _translate("LateralContribution", "Evaporation")
|
"RA": _translate("LateralContribution", "Rain"),
|
||||||
|
"EV": _translate("LateralContribution", "Evaporation"),
|
||||||
|
}
|
||||||
|
|
||||||
|
self._sub_dict["table_headers"] = {
|
||||||
|
"name": _translate("LateralContribution", "Name"),
|
||||||
|
"type": _translate("LateralContribution", "Type"),
|
||||||
|
"edge": _translate("LateralContribution", "Reach"),
|
||||||
|
"begin_kp": _translate("LateralContribution", "Begin kp (m)"),
|
||||||
|
"end_kp": _translate("LateralContribution", "End kp (m)")
|
||||||
|
}
|
||||||
+85
-53
@@ -36,8 +36,8 @@ from PyQt5.QtWidgets import (
|
|||||||
)
|
)
|
||||||
from PyQt5.uic import loadUi
|
from PyQt5.uic import loadUi
|
||||||
|
|
||||||
from View.ASubWindow import WindowToolKit
|
from View.Tools.ASubWindow import WindowToolKit
|
||||||
from View.ListedSubWindow import ListedSubWindow
|
from View.Tools.ListedSubWindow import ListedSubWindow
|
||||||
from View.DummyWindow import DummyWindow
|
from View.DummyWindow import DummyWindow
|
||||||
|
|
||||||
from View.Configure.Window import ConfigureWindow
|
from View.Configure.Window import ConfigureWindow
|
||||||
@@ -56,6 +56,7 @@ from View.SolverParameters.Window import SolverParametersWindow
|
|||||||
from View.RunSolver.Window import SelectSolverWindow, SolverLogWindow
|
from View.RunSolver.Window import SelectSolverWindow, SolverLogWindow
|
||||||
from View.CheckList.Window import CheckListWindow
|
from View.CheckList.Window import CheckListWindow
|
||||||
from View.Results.Window import ResultsWindow
|
from View.Results.Window import ResultsWindow
|
||||||
|
from View.Doc.Window import DocWindow
|
||||||
from View.Debug.Window import ReplWindow
|
from View.Debug.Window import ReplWindow
|
||||||
|
|
||||||
from Model.Study import Study
|
from Model.Study import Study
|
||||||
@@ -108,9 +109,10 @@ class ApplicationWindow(QMainWindow, ListedSubWindow, WindowToolKit):
|
|||||||
self.conf = conf
|
self.conf = conf
|
||||||
|
|
||||||
# Model
|
# Model
|
||||||
self.model = None
|
self._study = None
|
||||||
|
|
||||||
# Results
|
# Results
|
||||||
|
self._last_solver = None
|
||||||
self._last_results = None
|
self._last_results = None
|
||||||
|
|
||||||
# UI
|
# UI
|
||||||
@@ -133,8 +135,8 @@ class ApplicationWindow(QMainWindow, ListedSubWindow, WindowToolKit):
|
|||||||
def set_title(self):
|
def set_title(self):
|
||||||
title = "(dbg) " if self.conf.debug else ""
|
title = "(dbg) " if self.conf.debug else ""
|
||||||
|
|
||||||
if self.model is not None:
|
if self._study is not None:
|
||||||
title += f"Pamhyr2 - {self.model.name}"
|
title += f"Pamhyr2 - {self._study.name}"
|
||||||
self.setWindowTitle(title)
|
self.setWindowTitle(title)
|
||||||
else:
|
else:
|
||||||
title += "Pamhyr2"
|
title += "Pamhyr2"
|
||||||
@@ -150,6 +152,7 @@ class ApplicationWindow(QMainWindow, ListedSubWindow, WindowToolKit):
|
|||||||
Returns:
|
Returns:
|
||||||
Nothing
|
Nothing
|
||||||
"""
|
"""
|
||||||
|
logger.debug(f"Set {action} to {enable}")
|
||||||
self.findChild(QAction, action).setEnabled(enable)
|
self.findChild(QAction, action).setEnabled(enable)
|
||||||
|
|
||||||
def setup_sc(self):
|
def setup_sc(self):
|
||||||
@@ -181,7 +184,12 @@ class ApplicationWindow(QMainWindow, ListedSubWindow, WindowToolKit):
|
|||||||
"action_menu_sediment_layers": self.open_sediment_layers,
|
"action_menu_sediment_layers": self.open_sediment_layers,
|
||||||
"action_menu_edit_reach_sediment_layers": self.open_reach_sediment_layers,
|
"action_menu_edit_reach_sediment_layers": self.open_reach_sediment_layers,
|
||||||
"action_menu_close": self.close_model,
|
"action_menu_close": self.close_model,
|
||||||
|
"action_menu_results_last": self.open_last_results,
|
||||||
## Help
|
## Help
|
||||||
|
"action_menu_pamhyr_users_pdf": lambda: self.open_doc_user(ext="pdf"),
|
||||||
|
"action_menu_pamhyr_developers_pdf": lambda: self.open_doc_dev(ext="pdf"),
|
||||||
|
"action_menu_pamhyr_users_html": lambda: self.open_doc_user(ext="html"),
|
||||||
|
"action_menu_pamhyr_developers_html": lambda: self.open_doc_dev(ext="html"),
|
||||||
"action_menu_about": self.open_about,
|
"action_menu_about": self.open_about,
|
||||||
# ToolBar action
|
# ToolBar action
|
||||||
"action_toolBar_quit": self.close,
|
"action_toolBar_quit": self.close,
|
||||||
@@ -217,7 +225,7 @@ class ApplicationWindow(QMainWindow, ListedSubWindow, WindowToolKit):
|
|||||||
super(ApplicationWindow, self).changeEvent(event)
|
super(ApplicationWindow, self).changeEvent(event)
|
||||||
|
|
||||||
def close(self):
|
def close(self):
|
||||||
if self.model is not None and not self.model.is_saved:
|
if self._study is not None and not self._study.is_saved:
|
||||||
self._close_question = True
|
self._close_question = True
|
||||||
if self.dialog_close():
|
if self.dialog_close():
|
||||||
# PAMHYR is close correctly (no crash)
|
# PAMHYR is close correctly (no crash)
|
||||||
@@ -234,7 +242,7 @@ class ApplicationWindow(QMainWindow, ListedSubWindow, WindowToolKit):
|
|||||||
|
|
||||||
def closeEvent(self, event):
|
def closeEvent(self, event):
|
||||||
if not self._close_question:
|
if not self._close_question:
|
||||||
if self.model is not None and not self.model.is_saved:
|
if self._study is not None and not self._study.is_saved:
|
||||||
if self.dialog_close(cancel = False):
|
if self.dialog_close(cancel = False):
|
||||||
# PAMHYR is close correctly (no crash)
|
# PAMHYR is close correctly (no crash)
|
||||||
self.conf.set_close_correctly()
|
self.conf.set_close_correctly()
|
||||||
@@ -292,16 +300,16 @@ class ApplicationWindow(QMainWindow, ListedSubWindow, WindowToolKit):
|
|||||||
#########
|
#########
|
||||||
|
|
||||||
def get_model(self):
|
def get_model(self):
|
||||||
return self.model
|
return self._study
|
||||||
|
|
||||||
def set_model(self, model):
|
def set_model(self, model):
|
||||||
self.model = model
|
self._study = model
|
||||||
self.update_enable_action()
|
self.update_enable_action()
|
||||||
self.conf.set_last_study(self.model.filename)
|
self.conf.set_last_study(self._study.filename)
|
||||||
self.set_title()
|
self.set_title()
|
||||||
|
|
||||||
def close_model(self):
|
def close_model(self):
|
||||||
self.model = None
|
self._study = None
|
||||||
self.update_enable_action()
|
self.update_enable_action()
|
||||||
self.conf.set_close_correctly()
|
self.conf.set_close_correctly()
|
||||||
self.set_title()
|
self.set_title()
|
||||||
@@ -315,7 +323,7 @@ class ApplicationWindow(QMainWindow, ListedSubWindow, WindowToolKit):
|
|||||||
Returns:
|
Returns:
|
||||||
Nothing
|
Nothing
|
||||||
"""
|
"""
|
||||||
no_model = self.model is None
|
no_model = self._study is None
|
||||||
|
|
||||||
for action in no_model_action:
|
for action in no_model_action:
|
||||||
self.enable_actions(action, no_model)
|
self.enable_actions(action, no_model)
|
||||||
@@ -326,9 +334,12 @@ class ApplicationWindow(QMainWindow, ListedSubWindow, WindowToolKit):
|
|||||||
for action in model_action:
|
for action in model_action:
|
||||||
self.enable_actions(action, not no_model)
|
self.enable_actions(action, not no_model)
|
||||||
|
|
||||||
def set_results(self, results):
|
def set_results(self, solver, results):
|
||||||
|
self._last_solver = solver
|
||||||
self._last_results = results
|
self._last_results = results
|
||||||
|
|
||||||
|
self.enable_actions("action_menu_results_last", True)
|
||||||
|
|
||||||
############
|
############
|
||||||
# FEATURES #
|
# FEATURES #
|
||||||
############
|
############
|
||||||
@@ -343,7 +354,7 @@ class ApplicationWindow(QMainWindow, ListedSubWindow, WindowToolKit):
|
|||||||
Nothing
|
Nothing
|
||||||
"""
|
"""
|
||||||
self.set_model(Study.open(filename))
|
self.set_model(Study.open(filename))
|
||||||
logger.info(f"Open Study - {self.model.name}")
|
logger.info(f"Open Study - {self._study.name}")
|
||||||
self.set_title()
|
self.set_title()
|
||||||
|
|
||||||
def save_study(self):
|
def save_study(self):
|
||||||
@@ -355,22 +366,22 @@ class ApplicationWindow(QMainWindow, ListedSubWindow, WindowToolKit):
|
|||||||
Returns:
|
Returns:
|
||||||
Nothing
|
Nothing
|
||||||
"""
|
"""
|
||||||
if self.model.filename is None or self.model.filename == "":
|
if self._study.filename is None or self._study.filename == "":
|
||||||
file_name, _ = QFileDialog.getSaveFileName(
|
file_name, _ = QFileDialog.getSaveFileName(
|
||||||
self, "Save File",
|
self, "Save File",
|
||||||
"", "Pamhyr(*.pamhyr)"
|
"", "Pamhyr(*.pamhyr)"
|
||||||
)
|
)
|
||||||
|
|
||||||
if file_name.rsplit(".", 1)[-1] == "pamhyr":
|
if file_name.rsplit(".", 1)[-1] == "pamhyr":
|
||||||
self.model.filename = file_name
|
self._study.filename = file_name
|
||||||
else:
|
else:
|
||||||
self.model.filename = file_name + ".pamhyr"
|
self._study.filename = file_name + ".pamhyr"
|
||||||
|
|
||||||
if self.model.is_saved:
|
if self._study.is_saved:
|
||||||
return
|
return
|
||||||
|
|
||||||
logger.info("Save...")
|
logger.info("Save...")
|
||||||
self.model.save()
|
self._study.save()
|
||||||
|
|
||||||
def save_as_study(self):
|
def save_as_study(self):
|
||||||
"""Save current study as new file
|
"""Save current study as new file
|
||||||
@@ -387,11 +398,11 @@ class ApplicationWindow(QMainWindow, ListedSubWindow, WindowToolKit):
|
|||||||
)
|
)
|
||||||
|
|
||||||
if file_name[-4:] == ".pamhyr":
|
if file_name[-4:] == ".pamhyr":
|
||||||
self.model.filename = file_name
|
self._study.filename = file_name
|
||||||
else:
|
else:
|
||||||
self.model.filename = file_name + ".pamhyr"
|
self._study.filename = file_name + ".pamhyr"
|
||||||
|
|
||||||
self.model.save()
|
self._study.save()
|
||||||
|
|
||||||
##################
|
##################
|
||||||
# MSG AND DIALOG #
|
# MSG AND DIALOG #
|
||||||
@@ -457,7 +468,7 @@ class ApplicationWindow(QMainWindow, ListedSubWindow, WindowToolKit):
|
|||||||
Returns:
|
Returns:
|
||||||
Nothing
|
Nothing
|
||||||
"""
|
"""
|
||||||
self.config = ConfigureWindow(conf=self.conf, parent=self)
|
self.config = ConfigureWindow(config=self.conf, parent=self)
|
||||||
self.config.show()
|
self.config.show()
|
||||||
|
|
||||||
def open_about(self):
|
def open_about(self):
|
||||||
@@ -477,7 +488,7 @@ class ApplicationWindow(QMainWindow, ListedSubWindow, WindowToolKit):
|
|||||||
Returns:
|
Returns:
|
||||||
Nothing
|
Nothing
|
||||||
"""
|
"""
|
||||||
if self.model is None:
|
if self._study is None:
|
||||||
dialog = QFileDialog(self)
|
dialog = QFileDialog(self)
|
||||||
dialog.setFileMode(QFileDialog.FileMode.ExistingFile)
|
dialog.setFileMode(QFileDialog.FileMode.ExistingFile)
|
||||||
dialog.setDefaultSuffix(".pamhyr")
|
dialog.setDefaultSuffix(".pamhyr")
|
||||||
@@ -495,7 +506,7 @@ class ApplicationWindow(QMainWindow, ListedSubWindow, WindowToolKit):
|
|||||||
Returns:
|
Returns:
|
||||||
Nothing
|
Nothing
|
||||||
"""
|
"""
|
||||||
if self.model is None:
|
if self._study is None:
|
||||||
self.new_study = NewStudyWindow(parent=self)
|
self.new_study = NewStudyWindow(parent=self)
|
||||||
self.new_study.show()
|
self.new_study.show()
|
||||||
|
|
||||||
@@ -505,8 +516,8 @@ class ApplicationWindow(QMainWindow, ListedSubWindow, WindowToolKit):
|
|||||||
Returns:
|
Returns:
|
||||||
Nothing
|
Nothing
|
||||||
"""
|
"""
|
||||||
if not self.model is None:
|
if not self._study is None:
|
||||||
self.new_study = NewStudyWindow(study=self.model, parent=self)
|
self.new_study = NewStudyWindow(study=self._study, parent=self)
|
||||||
self.new_study.show()
|
self.new_study.show()
|
||||||
|
|
||||||
def open_network(self):
|
def open_network(self):
|
||||||
@@ -515,9 +526,9 @@ class ApplicationWindow(QMainWindow, ListedSubWindow, WindowToolKit):
|
|||||||
Returns:
|
Returns:
|
||||||
Nothing
|
Nothing
|
||||||
"""
|
"""
|
||||||
if self.model is not None:
|
if self._study is not None:
|
||||||
if not self.sub_win_exists("River network"):
|
if not self.sub_win_exists("River network"):
|
||||||
self.network = NetworkWindow(model=self.model, parent=self)
|
self.network = NetworkWindow(study=self._study, parent=self)
|
||||||
self.network.show()
|
self.network.show()
|
||||||
else:
|
else:
|
||||||
self.network.activateWindow()
|
self.network.activateWindow()
|
||||||
@@ -528,14 +539,14 @@ class ApplicationWindow(QMainWindow, ListedSubWindow, WindowToolKit):
|
|||||||
Returns:
|
Returns:
|
||||||
Nothing
|
Nothing
|
||||||
"""
|
"""
|
||||||
if (self.model is not None and self.model.river.has_current_reach()):
|
if (self._study is not None and self._study.river.has_current_reach()):
|
||||||
geometry = self.sub_win_filter_first(
|
geometry = self.sub_win_filter_first(
|
||||||
"Geometry",
|
"Geometry",
|
||||||
contain = [self.model.river.current_reach().name]
|
contain = [self._study.river.current_reach().name]
|
||||||
)
|
)
|
||||||
|
|
||||||
if geometry is None:
|
if geometry is None:
|
||||||
geometry = GeometryWindow(model=self.model, parent=self)
|
geometry = GeometryWindow(study=self._study, config=self.conf, parent=self)
|
||||||
geometry.show()
|
geometry.show()
|
||||||
else:
|
else:
|
||||||
geometry.activateWindow()
|
geometry.activateWindow()
|
||||||
@@ -549,7 +560,7 @@ class ApplicationWindow(QMainWindow, ListedSubWindow, WindowToolKit):
|
|||||||
)
|
)
|
||||||
|
|
||||||
if bound is None:
|
if bound is None:
|
||||||
bound = BoundaryConditionWindow(study = self.model, parent = self)
|
bound = BoundaryConditionWindow(study = self._study, parent = self)
|
||||||
bound.show()
|
bound.show()
|
||||||
else:
|
else:
|
||||||
bound.activateWindow()
|
bound.activateWindow()
|
||||||
@@ -561,7 +572,7 @@ class ApplicationWindow(QMainWindow, ListedSubWindow, WindowToolKit):
|
|||||||
)
|
)
|
||||||
|
|
||||||
if lateral is None:
|
if lateral is None:
|
||||||
lateral = LateralContributionWindow(study = self.model, parent = self)
|
lateral = LateralContributionWindow(study = self._study, parent = self)
|
||||||
lateral.show()
|
lateral.show()
|
||||||
else:
|
else:
|
||||||
lateral.activateWindow()
|
lateral.activateWindow()
|
||||||
@@ -574,7 +585,7 @@ class ApplicationWindow(QMainWindow, ListedSubWindow, WindowToolKit):
|
|||||||
|
|
||||||
if strick is None:
|
if strick is None:
|
||||||
strick = StricklersWindow(
|
strick = StricklersWindow(
|
||||||
study = self.model,
|
study = self._study,
|
||||||
config = self.conf,
|
config = self.conf,
|
||||||
parent = self
|
parent = self
|
||||||
)
|
)
|
||||||
@@ -583,17 +594,17 @@ class ApplicationWindow(QMainWindow, ListedSubWindow, WindowToolKit):
|
|||||||
strick.activateWindow()
|
strick.activateWindow()
|
||||||
|
|
||||||
def open_frictions(self):
|
def open_frictions(self):
|
||||||
if (self.model is not None and
|
if (self._study is not None and
|
||||||
self.model.river.has_current_reach()):
|
self._study.river.has_current_reach()):
|
||||||
|
|
||||||
frictions = self.sub_win_filter_first(
|
frictions = self.sub_win_filter_first(
|
||||||
"Frictions",
|
"Frictions",
|
||||||
contain = [self.model.river.current_reach().name]
|
contain = [self._study.river.current_reach().name]
|
||||||
)
|
)
|
||||||
|
|
||||||
if frictions is None:
|
if frictions is None:
|
||||||
frictions = FrictionsWindow(
|
frictions = FrictionsWindow(
|
||||||
study = self.model,
|
study = self._study,
|
||||||
parent = self
|
parent = self
|
||||||
)
|
)
|
||||||
frictions.show()
|
frictions.show()
|
||||||
@@ -603,15 +614,16 @@ class ApplicationWindow(QMainWindow, ListedSubWindow, WindowToolKit):
|
|||||||
self.msg_select_reach()
|
self.msg_select_reach()
|
||||||
|
|
||||||
def open_initial_conditions(self):
|
def open_initial_conditions(self):
|
||||||
if self.model.river.has_current_reach():
|
if self._study.river.has_current_reach():
|
||||||
initial = self.sub_win_filter_first(
|
initial = self.sub_win_filter_first(
|
||||||
"Initial condition",
|
"Initial condition",
|
||||||
contain = [self.model.river.current_reach().name]
|
contain = [self._study.river.current_reach().name]
|
||||||
)
|
)
|
||||||
|
|
||||||
if initial is None:
|
if initial is None:
|
||||||
initial = InitialConditionsWindow(
|
initial = InitialConditionsWindow(
|
||||||
study = self.model,
|
study = self._study,
|
||||||
|
config = self.conf,
|
||||||
parent = self
|
parent = self
|
||||||
)
|
)
|
||||||
initial.show()
|
initial.show()
|
||||||
@@ -628,7 +640,7 @@ class ApplicationWindow(QMainWindow, ListedSubWindow, WindowToolKit):
|
|||||||
|
|
||||||
if params is None:
|
if params is None:
|
||||||
params = SolverParametersWindow(
|
params = SolverParametersWindow(
|
||||||
study = self.model,
|
study = self._study,
|
||||||
parent = self
|
parent = self
|
||||||
)
|
)
|
||||||
params.show()
|
params.show()
|
||||||
@@ -637,31 +649,31 @@ class ApplicationWindow(QMainWindow, ListedSubWindow, WindowToolKit):
|
|||||||
|
|
||||||
def open_sediment_layers(self):
|
def open_sediment_layers(self):
|
||||||
sl = SedimentLayersWindow(
|
sl = SedimentLayersWindow(
|
||||||
study = self.model,
|
study = self._study,
|
||||||
parent = self
|
parent = self
|
||||||
)
|
)
|
||||||
sl.show()
|
sl.show()
|
||||||
|
|
||||||
def open_reach_sediment_layers(self):
|
def open_reach_sediment_layers(self):
|
||||||
sl = ReachSedimentLayersWindow(
|
sl = ReachSedimentLayersWindow(
|
||||||
study = self.model,
|
study = self._study,
|
||||||
parent = self
|
parent = self
|
||||||
)
|
)
|
||||||
sl.show()
|
sl.show()
|
||||||
|
|
||||||
def run_solver(self):
|
def run_solver(self):
|
||||||
if self.model is None:
|
if self._study is None:
|
||||||
return
|
return
|
||||||
|
|
||||||
run = SelectSolverWindow(
|
run = SelectSolverWindow(
|
||||||
study = self.model,
|
study = self._study,
|
||||||
config = self.conf,
|
config = self.conf,
|
||||||
parent = self
|
parent = self
|
||||||
)
|
)
|
||||||
if run.exec():
|
if run.exec():
|
||||||
solver = run.solver
|
solver = run.solver
|
||||||
check = CheckListWindow(
|
check = CheckListWindow(
|
||||||
study = self.model,
|
study = self._study,
|
||||||
config = self.conf,
|
config = self.conf,
|
||||||
solver = solver,
|
solver = solver,
|
||||||
parent = self
|
parent = self
|
||||||
@@ -670,7 +682,7 @@ class ApplicationWindow(QMainWindow, ListedSubWindow, WindowToolKit):
|
|||||||
|
|
||||||
def solver_log(self, solver):
|
def solver_log(self, solver):
|
||||||
sol = SolverLogWindow(
|
sol = SolverLogWindow(
|
||||||
study = self.model,
|
study = self._study,
|
||||||
config = self.conf,
|
config = self.conf,
|
||||||
solver = solver,
|
solver = solver,
|
||||||
parent = self
|
parent = self
|
||||||
@@ -694,7 +706,7 @@ class ApplicationWindow(QMainWindow, ListedSubWindow, WindowToolKit):
|
|||||||
|
|
||||||
if res is None:
|
if res is None:
|
||||||
res = ResultsWindow(
|
res = ResultsWindow(
|
||||||
study = self.model,
|
study = self._study,
|
||||||
solver = solver,
|
solver = solver,
|
||||||
results = results,
|
results = results,
|
||||||
parent = self
|
parent = self
|
||||||
@@ -703,24 +715,44 @@ class ApplicationWindow(QMainWindow, ListedSubWindow, WindowToolKit):
|
|||||||
else:
|
else:
|
||||||
res.activateWindow()
|
res.activateWindow()
|
||||||
|
|
||||||
|
def open_last_results(self):
|
||||||
|
if self._last_solver is None or self._last_results is None:
|
||||||
|
return
|
||||||
|
|
||||||
|
self.open_solver_results(self._last_solver, self._last_results)
|
||||||
|
|
||||||
|
def open_doc(self, filename):
|
||||||
|
doc = DocWindow(
|
||||||
|
filename = filename,
|
||||||
|
parent = self
|
||||||
|
)
|
||||||
|
doc.show()
|
||||||
|
|
||||||
|
|
||||||
|
def open_doc_user(self, ext="pdf"):
|
||||||
|
self.open_doc(f"Pamhyr2-users.{ext}")
|
||||||
|
|
||||||
|
def open_doc_dev(self, ext="pdf"):
|
||||||
|
self.open_doc(f"Pamhyr2-dev.{ext}")
|
||||||
|
|
||||||
#########
|
#########
|
||||||
# DEBUG #
|
# DEBUG #
|
||||||
#########
|
#########
|
||||||
|
|
||||||
def open_debug(self):
|
def open_debug(self):
|
||||||
repl = ReplWindow(
|
repl = ReplWindow(
|
||||||
study = self.model,
|
study = self._study,
|
||||||
config = self.conf,
|
config = self.conf,
|
||||||
parent = self
|
parent = self
|
||||||
)
|
)
|
||||||
repl.show()
|
repl.show()
|
||||||
|
|
||||||
def open_sqlite(self):
|
def open_sqlite(self):
|
||||||
if self.model is None:
|
if self._study is None:
|
||||||
logger.debug("No study open for sql debuging...")
|
logger.debug("No study open for sql debuging...")
|
||||||
return
|
return
|
||||||
|
|
||||||
file = self.model.filename
|
file = self._study.filename
|
||||||
_ = subprocess.Popen(
|
_ = subprocess.Popen(
|
||||||
f"sqlitebrowser {file}",
|
f"sqlitebrowser {file}",
|
||||||
shell=True
|
shell=True
|
||||||
|
|||||||
@@ -22,7 +22,6 @@ import traceback
|
|||||||
from Model.Network.Node import Node
|
from Model.Network.Node import Node
|
||||||
from Model.Network.Edge import Edge
|
from Model.Network.Edge import Edge
|
||||||
from Model.Network.Graph import Graph
|
from Model.Network.Graph import Graph
|
||||||
from View.ASubWindow import ASubWindow
|
|
||||||
from View.Network.GraphWidget import GraphWidget
|
from View.Network.GraphWidget import GraphWidget
|
||||||
from View.Network.UndoCommand import *
|
from View.Network.UndoCommand import *
|
||||||
from View.Tools.PamhyrTable import PamhyrTableModel
|
from View.Tools.PamhyrTable import PamhyrTableModel
|
||||||
|
|||||||
+26
-33
@@ -16,6 +16,8 @@
|
|||||||
|
|
||||||
# -*- coding: utf-8 -*-
|
# -*- coding: utf-8 -*-
|
||||||
|
|
||||||
|
import logging
|
||||||
|
|
||||||
from PyQt5.QtCore import QCoreApplication
|
from PyQt5.QtCore import QCoreApplication
|
||||||
|
|
||||||
from PyQt5.QtGui import (
|
from PyQt5.QtGui import (
|
||||||
@@ -36,55 +38,47 @@ from PyQt5.QtWidgets import (
|
|||||||
|
|
||||||
from Model.River import RiverNode, RiverReach, River
|
from Model.River import RiverNode, RiverReach, River
|
||||||
|
|
||||||
from View.ASubWindow import ASubMainWindow
|
from View.Tools.PamhyrWindow import PamhyrWindow
|
||||||
from View.Network.GraphWidget import GraphWidget
|
from View.Network.GraphWidget import GraphWidget
|
||||||
from View.Network.UndoCommand import *
|
from View.Network.UndoCommand import *
|
||||||
from View.Network.translate import (
|
from View.Network.translate import NetworkTranslate
|
||||||
table_headers_node, table_headers_edge,
|
|
||||||
retranslate,
|
|
||||||
)
|
|
||||||
from View.Network.Table import (
|
from View.Network.Table import (
|
||||||
ComboBoxDelegate, NodeTableModel, EdgeTableModel,
|
ComboBoxDelegate, NodeTableModel, EdgeTableModel,
|
||||||
)
|
)
|
||||||
|
|
||||||
|
logger = logging.getLogger()
|
||||||
|
|
||||||
_translate = QCoreApplication.translate
|
_translate = QCoreApplication.translate
|
||||||
|
|
||||||
|
|
||||||
class NetworkWindow(ASubMainWindow):
|
class NetworkWindow(PamhyrWindow):
|
||||||
def __init__(self, model=None, title="River network", parent=None):
|
_pamhyr_ui = "Network"
|
||||||
self._title = title
|
_pamhyr_name = "River network"
|
||||||
self._model = model
|
|
||||||
self._graph = self._model.river
|
|
||||||
|
|
||||||
self.setup_title()
|
|
||||||
|
|
||||||
|
def __init__(self, study=None, config=None, parent=None):
|
||||||
super(NetworkWindow, self).__init__(
|
super(NetworkWindow, self).__init__(
|
||||||
name=title, ui="Network", parent=parent
|
title = self._pamhyr_name + " - " + study.name,
|
||||||
|
study = study,
|
||||||
|
config = config,
|
||||||
|
trad = NetworkTranslate(),
|
||||||
|
options = ['undo'],
|
||||||
|
parent=parent,
|
||||||
)
|
)
|
||||||
self.ui.setWindowTitle(self._title)
|
|
||||||
|
|
||||||
self.setup_sc()
|
self._graph = study.river
|
||||||
|
self._table_headers_node = self._trad.get_dict("table_headers_node")
|
||||||
|
self._table_headers_edge = self._trad.get_dict("table_headers_edge")
|
||||||
|
|
||||||
self.setup_graph()
|
self.setup_graph()
|
||||||
self.setup_table()
|
self.setup_table()
|
||||||
self.setup_connections()
|
self.setup_connections()
|
||||||
|
|
||||||
def setup_title(self):
|
|
||||||
self._title = self._title + " - " + self._model.name
|
|
||||||
|
|
||||||
def setup_sc(self):
|
|
||||||
self._undo_stack = QUndoStack()
|
|
||||||
|
|
||||||
self.undo_sc = QShortcut(QKeySequence.Undo, self)
|
|
||||||
self.redo_sc = QShortcut(QKeySequence.Redo, self)
|
|
||||||
|
|
||||||
def setup_table(self):
|
def setup_table(self):
|
||||||
retranslate()
|
|
||||||
|
|
||||||
# Nodes table
|
# Nodes table
|
||||||
table = self.find(QTableView, "tableView_nodes")
|
table = self.find(QTableView, "tableView_nodes")
|
||||||
self._nodes_model = NodeTableModel(
|
self._nodes_model = NodeTableModel(
|
||||||
table_view = table,
|
table_view = table,
|
||||||
table_headers = table_headers_node,
|
table_headers = self._table_headers_node,
|
||||||
editable_headers = ["name"],
|
editable_headers = ["name"],
|
||||||
data = self._graph,
|
data = self._graph,
|
||||||
undo = self._undo_stack,
|
undo = self._undo_stack,
|
||||||
@@ -103,7 +97,7 @@ class NetworkWindow(ASubMainWindow):
|
|||||||
|
|
||||||
self._reachs_model = EdgeTableModel(
|
self._reachs_model = EdgeTableModel(
|
||||||
table_view = table,
|
table_view = table,
|
||||||
table_headers = table_headers_edge,
|
table_headers = self._table_headers_edge,
|
||||||
editable_headers = ["name", "node1", "node2"],
|
editable_headers = ["name", "node1", "node2"],
|
||||||
delegates = {
|
delegates = {
|
||||||
"node1": self.delegate_combobox,
|
"node1": self.delegate_combobox,
|
||||||
@@ -143,9 +137,6 @@ class NetworkWindow(ASubMainWindow):
|
|||||||
self.clicked_del
|
self.clicked_del
|
||||||
)
|
)
|
||||||
|
|
||||||
self.undo_sc.activated.connect(self.undo)
|
|
||||||
self.redo_sc.activated.connect(self.redo)
|
|
||||||
|
|
||||||
def clicked_add(self):
|
def clicked_add(self):
|
||||||
if self.get_action_checkable("action_toolBar_add"):
|
if self.get_action_checkable("action_toolBar_add"):
|
||||||
self.set_action_checkable("action_toolBar_del", False)
|
self.set_action_checkable("action_toolBar_del", False)
|
||||||
@@ -166,13 +157,15 @@ class NetworkWindow(ASubMainWindow):
|
|||||||
if key == Qt.Key_Escape:
|
if key == Qt.Key_Escape:
|
||||||
self._graph_widget.reset_selection
|
self._graph_widget.reset_selection
|
||||||
|
|
||||||
def undo(self):
|
# Redefine undo/redo method
|
||||||
|
|
||||||
|
def _undo(self):
|
||||||
self._undo_stack.undo()
|
self._undo_stack.undo()
|
||||||
self._reachs_model.update()
|
self._reachs_model.update()
|
||||||
self._nodes_model.update()
|
self._nodes_model.update()
|
||||||
self._graph_widget.display_update()
|
self._graph_widget.display_update()
|
||||||
|
|
||||||
def redo(self):
|
def _redo(self):
|
||||||
self._undo_stack.redo()
|
self._undo_stack.redo()
|
||||||
self._reachs_model.update()
|
self._reachs_model.update()
|
||||||
self._nodes_model.update()
|
self._nodes_model.update()
|
||||||
|
|||||||
@@ -18,23 +18,21 @@
|
|||||||
|
|
||||||
from PyQt5.QtCore import QCoreApplication
|
from PyQt5.QtCore import QCoreApplication
|
||||||
|
|
||||||
|
from View.Tools.PamhyrTranslate import PamhyrTranslate
|
||||||
|
|
||||||
_translate = QCoreApplication.translate
|
_translate = QCoreApplication.translate
|
||||||
|
|
||||||
table_headers_node = {
|
class NetworkTranslate(PamhyrTranslate):
|
||||||
"name": _translate("Network", "Name"),
|
def __init__(self):
|
||||||
"type": _translate("Network", "Type"),
|
super(NetworkTranslate, self).__init__()
|
||||||
}
|
|
||||||
|
|
||||||
table_headers_edge = {
|
self._sub_dict["table_headers_node"] = {
|
||||||
"name": _translate("Network", "Name"),
|
"name": _translate("Network", "Name"),
|
||||||
"node1": _translate("Network", "Source node"),
|
"type": _translate("Network", "Type"),
|
||||||
"node2": _translate("Network", "Destination node"),
|
}
|
||||||
}
|
|
||||||
|
|
||||||
def retranslate():
|
self._sub_dict["table_headers_edge"] = {
|
||||||
table_headers_node["name"] = _translate("Network", "Name")
|
"name": _translate("Network", "Name"),
|
||||||
table_headers_node["type"] = _translate("Network", "Type")
|
"node1": _translate("Network", "Source node"),
|
||||||
|
"node2": _translate("Network", "Destination node"),
|
||||||
table_headers_edge["name"] = _translate("Network", "Name")
|
}
|
||||||
table_headers_edge["node1"] = _translate("Network", "Source node")
|
|
||||||
table_headers_edge["node2"] = _translate("Network", "Destination node")
|
|
||||||
@@ -17,7 +17,7 @@
|
|||||||
# -*- coding: utf-8 -*-
|
# -*- coding: utf-8 -*-
|
||||||
|
|
||||||
from tools import timer
|
from tools import timer
|
||||||
from View.Plot.APlot import APlot
|
from View.Tools.PamhyrPlot import PamhyrPlot
|
||||||
|
|
||||||
from PyQt5.QtCore import (
|
from PyQt5.QtCore import (
|
||||||
QCoreApplication
|
QCoreApplication
|
||||||
@@ -25,14 +25,16 @@ from PyQt5.QtCore import (
|
|||||||
|
|
||||||
_translate = QCoreApplication.translate
|
_translate = QCoreApplication.translate
|
||||||
|
|
||||||
class PlotAC(APlot):
|
class PlotAC(PamhyrPlot):
|
||||||
def __init__(self, canvas=None, results=None,
|
def __init__(self, canvas=None, trad=None, toolbar=None,
|
||||||
reach_id=0, profile_id=0,
|
results=None, reach_id=0, profile_id=0,
|
||||||
toolbar=None):
|
parent=None):
|
||||||
super(PlotAC, self).__init__(
|
super(PlotAC, self).__init__(
|
||||||
canvas=canvas,
|
canvas = canvas,
|
||||||
data=results,
|
trad = trad,
|
||||||
toolbar=toolbar
|
data = results,
|
||||||
|
toolbar = toolbar,
|
||||||
|
parent = parent
|
||||||
)
|
)
|
||||||
|
|
||||||
self._current_timestamp = max(results.get("timestamps"))
|
self._current_timestamp = max(results.get("timestamps"))
|
||||||
|
|||||||
@@ -22,7 +22,7 @@ from functools import reduce
|
|||||||
from datetime import datetime
|
from datetime import datetime
|
||||||
|
|
||||||
from tools import timer, trace
|
from tools import timer, trace
|
||||||
from View.Plot.APlot import APlot
|
from View.Tools.PamhyrPlot import PamhyrPlot
|
||||||
|
|
||||||
from PyQt5.QtCore import (
|
from PyQt5.QtCore import (
|
||||||
QCoreApplication
|
QCoreApplication
|
||||||
@@ -32,14 +32,16 @@ _translate = QCoreApplication.translate
|
|||||||
|
|
||||||
logger = logging.getLogger()
|
logger = logging.getLogger()
|
||||||
|
|
||||||
class PlotH(APlot):
|
class PlotH(PamhyrPlot):
|
||||||
def __init__(self, canvas=None, results=None,
|
def __init__(self, canvas=None, trad=None, toolbar=None,
|
||||||
reach_id=0, profile_id=0,
|
results=None, reach_id=0, profile_id=0,
|
||||||
toolbar=None):
|
parent=None):
|
||||||
super(PlotH, self).__init__(
|
super(PlotH, self).__init__(
|
||||||
canvas=canvas,
|
canvas = canvas,
|
||||||
data=results,
|
trad = trad,
|
||||||
toolbar=toolbar
|
data = results,
|
||||||
|
toolbar = toolbar,
|
||||||
|
parent = parent
|
||||||
)
|
)
|
||||||
|
|
||||||
self._mode = "time"
|
self._mode = "time"
|
||||||
|
|||||||
@@ -17,7 +17,7 @@
|
|||||||
# -*- coding: utf-8 -*-
|
# -*- coding: utf-8 -*-
|
||||||
|
|
||||||
from tools import timer
|
from tools import timer
|
||||||
from View.Plot.APlot import APlot
|
from View.Tools.PamhyrPlot import PamhyrPlot
|
||||||
|
|
||||||
from PyQt5.QtCore import (
|
from PyQt5.QtCore import (
|
||||||
QCoreApplication
|
QCoreApplication
|
||||||
@@ -25,14 +25,16 @@ from PyQt5.QtCore import (
|
|||||||
|
|
||||||
_translate = QCoreApplication.translate
|
_translate = QCoreApplication.translate
|
||||||
|
|
||||||
class PlotKPC(APlot):
|
class PlotKPC(PamhyrPlot):
|
||||||
def __init__(self, canvas=None, results=None,
|
def __init__(self, canvas=None, trad=None, toolbar=None,
|
||||||
reach_id=0, profile_id=0,
|
results=None, reach_id=0, profile_id=0,
|
||||||
toolbar=None):
|
parent=None):
|
||||||
super(PlotKPC, self).__init__(
|
super(PlotKPC, self).__init__(
|
||||||
canvas=canvas,
|
canvas = canvas,
|
||||||
data=results,
|
trad = trad,
|
||||||
toolbar=toolbar
|
data = results,
|
||||||
|
toolbar = toolbar,
|
||||||
|
parent = parent
|
||||||
)
|
)
|
||||||
|
|
||||||
self._current_timestamp = max(results.get("timestamps"))
|
self._current_timestamp = max(results.get("timestamps"))
|
||||||
|
|||||||
@@ -5,7 +5,7 @@ import logging
|
|||||||
from functools import reduce
|
from functools import reduce
|
||||||
|
|
||||||
from tools import timer
|
from tools import timer
|
||||||
from View.Plot.APlot import APlot
|
from View.Tools.PamhyrPlot import PamhyrPlot
|
||||||
|
|
||||||
from PyQt5.QtCore import (
|
from PyQt5.QtCore import (
|
||||||
QCoreApplication
|
QCoreApplication
|
||||||
@@ -15,14 +15,16 @@ _translate = QCoreApplication.translate
|
|||||||
|
|
||||||
logger = logging.getLogger()
|
logger = logging.getLogger()
|
||||||
|
|
||||||
class PlotSedProfile(APlot):
|
class PlotSedProfile(PamhyrPlot):
|
||||||
def __init__(self, canvas=None, study=None, results=None,
|
def __init__(self, canvas=None, trad=None, toolbar=None,
|
||||||
reach_id=0, profile_id=0,
|
results=None, reach_id=0, profile_id=0,
|
||||||
toolbar=None):
|
parent=None):
|
||||||
super(PlotSedProfile, self).__init__(
|
super(PlotSedProfile, self).__init__(
|
||||||
canvas=canvas,
|
canvas = canvas,
|
||||||
data=study,
|
trad = trad,
|
||||||
toolbar=toolbar
|
data = results,
|
||||||
|
toolbar = toolbar,
|
||||||
|
parent = parent
|
||||||
)
|
)
|
||||||
|
|
||||||
self._results = results
|
self._results = results
|
||||||
|
|||||||
@@ -5,7 +5,7 @@ import logging
|
|||||||
from functools import reduce
|
from functools import reduce
|
||||||
|
|
||||||
from tools import timer
|
from tools import timer
|
||||||
from View.Plot.APlot import APlot
|
from View.Tools.PamhyrPlot import PamhyrPlot
|
||||||
|
|
||||||
from PyQt5.QtCore import (
|
from PyQt5.QtCore import (
|
||||||
QCoreApplication
|
QCoreApplication
|
||||||
@@ -15,14 +15,16 @@ _translate = QCoreApplication.translate
|
|||||||
|
|
||||||
logger = logging.getLogger()
|
logger = logging.getLogger()
|
||||||
|
|
||||||
class PlotSedReach(APlot):
|
class PlotSedReach(PamhyrPlot):
|
||||||
def __init__(self, canvas=None, study=None, results=None,
|
def __init__(self, canvas=None, trad=None, toolbar=None,
|
||||||
reach_id=0, profile_id=0,
|
results=None, reach_id=0, profile_id=0,
|
||||||
toolbar=None):
|
parent=None):
|
||||||
super(PlotSedReach, self).__init__(
|
super(PlotSedReach, self).__init__(
|
||||||
canvas=canvas,
|
canvas = canvas,
|
||||||
data=study,
|
trad = trad,
|
||||||
toolbar=toolbar
|
data = results,
|
||||||
|
toolbar = toolbar,
|
||||||
|
parent = parent
|
||||||
)
|
)
|
||||||
|
|
||||||
self._results = results
|
self._results = results
|
||||||
|
|||||||
@@ -21,7 +21,7 @@ import logging
|
|||||||
from functools import reduce
|
from functools import reduce
|
||||||
|
|
||||||
from tools import timer, trace
|
from tools import timer, trace
|
||||||
from View.Plot.APlot import APlot
|
from View.Tools.PamhyrPlot import PamhyrPlot
|
||||||
|
|
||||||
from PyQt5.QtCore import (
|
from PyQt5.QtCore import (
|
||||||
QCoreApplication
|
QCoreApplication
|
||||||
@@ -31,14 +31,16 @@ _translate = QCoreApplication.translate
|
|||||||
|
|
||||||
logger = logging.getLogger()
|
logger = logging.getLogger()
|
||||||
|
|
||||||
class PlotXY(APlot):
|
class PlotXY(PamhyrPlot):
|
||||||
def __init__(self, canvas=None, results=None,
|
def __init__(self, canvas=None, trad=None, toolbar=None,
|
||||||
reach_id=0, profile_id=0,
|
results=None, reach_id=0, profile_id=0,
|
||||||
toolbar=None, display_current=True):
|
display_current=True, parent=None):
|
||||||
super(PlotXY, self).__init__(
|
super(PlotXY, self).__init__(
|
||||||
canvas=canvas,
|
canvas = canvas,
|
||||||
data=results,
|
trad = trad,
|
||||||
toolbar=toolbar
|
data = results,
|
||||||
|
toolbar = toolbar,
|
||||||
|
parent = parent
|
||||||
)
|
)
|
||||||
|
|
||||||
self.display_current = display_current
|
self.display_current = display_current
|
||||||
|
|||||||
+20
-45
@@ -34,6 +34,7 @@ from PyQt5.QtWidgets import (
|
|||||||
QComboBox,
|
QComboBox,
|
||||||
)
|
)
|
||||||
|
|
||||||
|
from View.Tools.PamhyrTable import PamhyrTableModel
|
||||||
from View.Results.translate import *
|
from View.Results.translate import *
|
||||||
|
|
||||||
logger = logging.getLogger()
|
logger = logging.getLogger()
|
||||||
@@ -41,33 +42,16 @@ logger = logging.getLogger()
|
|||||||
_translate = QCoreApplication.translate
|
_translate = QCoreApplication.translate
|
||||||
|
|
||||||
|
|
||||||
class TableModel(QAbstractTableModel):
|
class TableModel(PamhyrTableModel):
|
||||||
def __init__(self, results = None, study = None, mode = None, undo=None):
|
def _setup_lst(self):
|
||||||
super(QAbstractTableModel, self).__init__()
|
_river = self._data.river
|
||||||
|
if self._opt_data == "reach":
|
||||||
|
self._lst = _river.reachs
|
||||||
|
else:
|
||||||
|
self._lst = _river.reach(0).profiles
|
||||||
|
|
||||||
self._results = results
|
def __init__(self, **kwargs):
|
||||||
self._study = study
|
super(TableModel, self).__init__(**kwargs)
|
||||||
self._mode = mode
|
|
||||||
self._undo_stack = undo
|
|
||||||
|
|
||||||
self._table_headers = table_headers_reach
|
|
||||||
if mode != "reach":
|
|
||||||
self._table_headers = table_headers_profile
|
|
||||||
|
|
||||||
self._headers = list(self._table_headers.keys())
|
|
||||||
|
|
||||||
self._selected = 0
|
|
||||||
self._timestamp = 0
|
|
||||||
|
|
||||||
def rowCount(self, parent=QModelIndex()):
|
|
||||||
if self._mode == "reach":
|
|
||||||
return len(self._results.river.reachs)
|
|
||||||
|
|
||||||
current_reach = self._results.river.reach(self._selected)
|
|
||||||
return len(current_reach.profiles)
|
|
||||||
|
|
||||||
def columnCount(self, parent=QModelIndex()):
|
|
||||||
return len(self._headers)
|
|
||||||
|
|
||||||
def data(self, index, role=Qt.DisplayRole):
|
def data(self, index, role=Qt.DisplayRole):
|
||||||
if role != Qt.ItemDataRole.DisplayRole:
|
if role != Qt.ItemDataRole.DisplayRole:
|
||||||
@@ -76,32 +60,23 @@ class TableModel(QAbstractTableModel):
|
|||||||
row = index.row()
|
row = index.row()
|
||||||
column = index.column()
|
column = index.column()
|
||||||
|
|
||||||
if self._mode == "reach":
|
if self._opt_data == "reach":
|
||||||
if self._headers[column] == "name":
|
if self._headers[column] == "name":
|
||||||
v = self._results.river.reach(row).name
|
v = self._lst[row].name
|
||||||
return str(v)
|
return str(v)
|
||||||
else:
|
else:
|
||||||
current_reach = self._results.river.reach(self._selected)
|
|
||||||
if self._headers[column] == "name":
|
if self._headers[column] == "name":
|
||||||
v = current_reach.profile(row).name
|
v = self._lst[row].name
|
||||||
return str(v)
|
return str(v)
|
||||||
elif self._headers[column] == "kp":
|
elif self._headers[column] == "kp":
|
||||||
v = current_reach.profile(row).kp
|
v = self._lst[row].kp
|
||||||
return f"{v:.4f}"
|
return f"{v:.4f}"
|
||||||
|
|
||||||
return QVariant()
|
return QVariant()
|
||||||
|
|
||||||
def headerData(self, section, orientation, role=Qt.DisplayRole):
|
def update(self, reach):
|
||||||
if role == Qt.ItemDataRole.DisplayRole and orientation == Qt.Orientation.Horizontal:
|
_river = self._data.river
|
||||||
return self._table_headers[self._headers[section]]
|
if self._opt_data == "reach":
|
||||||
|
self._lst = _river.reachs
|
||||||
return QVariant()
|
else:
|
||||||
|
self._lst = _river.reach(reach).profiles
|
||||||
def index(self, row, column, parent=QModelIndex()):
|
|
||||||
if not self.hasIndex(row, column, parent):
|
|
||||||
return QModelIndex()
|
|
||||||
|
|
||||||
return self.createIndex(row, column, QModelIndex())
|
|
||||||
|
|
||||||
def flags(self, index):
|
|
||||||
return Qt.ItemIsEnabled | Qt.ItemIsSelectable
|
|
||||||
+34
-59
@@ -21,8 +21,7 @@ from datetime import datetime
|
|||||||
|
|
||||||
from tools import trace, timer
|
from tools import trace, timer
|
||||||
|
|
||||||
from View.ASubWindow import ASubMainWindow
|
from View.Tools.PamhyrWindow import PamhyrWindow
|
||||||
from View.ListedSubWindow import ListedSubWindow
|
|
||||||
|
|
||||||
from PyQt5.QtGui import (
|
from PyQt5.QtGui import (
|
||||||
QKeySequence,
|
QKeySequence,
|
||||||
@@ -42,8 +41,8 @@ from PyQt5.QtWidgets import (
|
|||||||
QSlider, QLabel,
|
QSlider, QLabel,
|
||||||
)
|
)
|
||||||
|
|
||||||
from View.Plot.MplCanvas import MplCanvas
|
from View.Tools.Plot.PamhyrCanvas import MplCanvas
|
||||||
from View.Plot.PamhyrToolbar import PamhyrPlotToolbar
|
from View.Tools.Plot.PamhyrToolbar import PamhyrPlotToolbar
|
||||||
|
|
||||||
from View.Results.PlotXY import PlotXY
|
from View.Results.PlotXY import PlotXY
|
||||||
from View.Results.PlotAC import PlotAC
|
from View.Results.PlotAC import PlotAC
|
||||||
@@ -53,74 +52,57 @@ from View.Results.PlotSedReach import PlotSedReach
|
|||||||
from View.Results.PlotSedProfile import PlotSedProfile
|
from View.Results.PlotSedProfile import PlotSedProfile
|
||||||
|
|
||||||
from View.Results.Table import TableModel
|
from View.Results.Table import TableModel
|
||||||
from View.Results.translate import (
|
from View.Results.translate import ResultsTranslate
|
||||||
table_headers_reach, table_headers_profile,
|
|
||||||
retranslate,
|
|
||||||
)
|
|
||||||
from View.Stricklers.Window import StricklersWindow
|
from View.Stricklers.Window import StricklersWindow
|
||||||
|
|
||||||
_translate = QCoreApplication.translate
|
_translate = QCoreApplication.translate
|
||||||
|
|
||||||
logger = logging.getLogger()
|
logger = logging.getLogger()
|
||||||
|
|
||||||
class ResultsWindow(ASubMainWindow, ListedSubWindow):
|
class ResultsWindow(PamhyrWindow):
|
||||||
def __init__(self, title="Results",
|
_pamhyr_ui = "Results"
|
||||||
study=None, solver=None, results=None,
|
_pamhyr_name = "Results"
|
||||||
|
|
||||||
|
def __init__(self, study=None, config=None,
|
||||||
|
solver=None, results=None,
|
||||||
parent=None):
|
parent=None):
|
||||||
self._study = study
|
|
||||||
self._solver = solver
|
self._solver = solver
|
||||||
self._results = results
|
self._results = results
|
||||||
|
|
||||||
self._timestamps = sorted(list(self._results.get("timestamps")))
|
self._timestamps = sorted(list(self._results.get("timestamps")))
|
||||||
|
|
||||||
self.setup_title(title)
|
name = (
|
||||||
|
self._pamhyr_name + " - "
|
||||||
super(ResultsWindow, self).__init__(
|
+ study.name + " - "
|
||||||
name=title, ui="Results", parent=parent
|
|
||||||
)
|
|
||||||
|
|
||||||
self.setup_sc()
|
|
||||||
self.setup_table()
|
|
||||||
self.setup_graph()
|
|
||||||
self.setup_slider()
|
|
||||||
self.setup_statusbar()
|
|
||||||
self.setup_connections()
|
|
||||||
|
|
||||||
self.ui.setWindowTitle(self._title)
|
|
||||||
|
|
||||||
def setup_title(self, title):
|
|
||||||
self._title = (
|
|
||||||
title + " - "
|
|
||||||
+ self._study.name + " - "
|
|
||||||
+ self._solver.name + " - "
|
+ self._solver.name + " - "
|
||||||
+ self._results.date
|
+ self._results.date
|
||||||
)
|
)
|
||||||
|
|
||||||
def setup_sc(self):
|
super(ResultsWindow, self).__init__(
|
||||||
self._undo_stack = QUndoStack()
|
title = name,
|
||||||
|
study = study,
|
||||||
|
config = config,
|
||||||
|
trad = ResultsTranslate(),
|
||||||
|
parent=parent
|
||||||
|
)
|
||||||
|
|
||||||
self.undo_sc = QShortcut(QKeySequence.Undo, self)
|
self.setup_table()
|
||||||
self.redo_sc = QShortcut(QKeySequence.Redo, self)
|
self.setup_plot()
|
||||||
self.copy_sc = QShortcut(QKeySequence.Copy, self)
|
self.setup_slider()
|
||||||
self.paste_sc = QShortcut(QKeySequence.Paste, self)
|
self.setup_statusbar()
|
||||||
|
self.setup_connections()
|
||||||
|
|
||||||
def setup_table(self):
|
def setup_table(self):
|
||||||
retranslate()
|
|
||||||
self._table = {}
|
self._table = {}
|
||||||
|
|
||||||
for t in ["reach", "profile"]:
|
for t in ["reach", "profile"]:
|
||||||
table = self.find(QTableView, f"tableView_{t}")
|
table = self.find(QTableView, f"tableView_{t}")
|
||||||
self._table[t] = TableModel(
|
self._table[t] = TableModel(
|
||||||
results = self._results,
|
table_view = table,
|
||||||
study = self._study,
|
table_headers = self._trad.get_dict(f"table_headers_{t}"),
|
||||||
mode = t,
|
data = self._results,
|
||||||
undo = self._undo_stack,
|
undo = self._undo_stack,
|
||||||
|
opt_data = t
|
||||||
)
|
)
|
||||||
table.setModel(self._table[t])
|
|
||||||
|
|
||||||
table.setSelectionBehavior(QAbstractItemView.SelectRows)
|
|
||||||
table.horizontalHeader().setSectionResizeMode(QHeaderView.Stretch)
|
|
||||||
table.setAlternatingRowColors(True)
|
|
||||||
|
|
||||||
def setup_slider(self):
|
def setup_slider(self):
|
||||||
self._slider_profile = self.find(QSlider, f"verticalSlider_profile")
|
self._slider_profile = self.find(QSlider, f"verticalSlider_profile")
|
||||||
@@ -132,7 +114,7 @@ class ResultsWindow(ASubMainWindow, ListedSubWindow):
|
|||||||
self._slider_time.setMaximum(len(self._timestamps) - 1)
|
self._slider_time.setMaximum(len(self._timestamps) - 1)
|
||||||
self._slider_time.setValue(len(self._timestamps) - 1)
|
self._slider_time.setValue(len(self._timestamps) - 1)
|
||||||
|
|
||||||
def setup_graph(self):
|
def setup_plot(self):
|
||||||
self.canvas = MplCanvas(width=5, height=4, dpi=100)
|
self.canvas = MplCanvas(width=5, height=4, dpi=100)
|
||||||
self.canvas.setObjectName("canvas")
|
self.canvas.setObjectName("canvas")
|
||||||
self.toolbar = PamhyrPlotToolbar(
|
self.toolbar = PamhyrPlotToolbar(
|
||||||
@@ -219,7 +201,6 @@ class ResultsWindow(ASubMainWindow, ListedSubWindow):
|
|||||||
self.plot_sed_reach = PlotSedReach(
|
self.plot_sed_reach = PlotSedReach(
|
||||||
canvas = self.canvas_5,
|
canvas = self.canvas_5,
|
||||||
results = self._results,
|
results = self._results,
|
||||||
study = self._study,
|
|
||||||
reach_id = 0,
|
reach_id = 0,
|
||||||
profile_id = 0,
|
profile_id = 0,
|
||||||
toolbar = self.toolbar_5
|
toolbar = self.toolbar_5
|
||||||
@@ -239,7 +220,6 @@ class ResultsWindow(ASubMainWindow, ListedSubWindow):
|
|||||||
self.plot_sed_profile = PlotSedProfile(
|
self.plot_sed_profile = PlotSedProfile(
|
||||||
canvas = self.canvas_6,
|
canvas = self.canvas_6,
|
||||||
results = self._results,
|
results = self._results,
|
||||||
study = self._study,
|
|
||||||
reach_id = 0,
|
reach_id = 0,
|
||||||
profile_id = 0,
|
profile_id = 0,
|
||||||
toolbar = self.toolbar_6
|
toolbar = self.toolbar_6
|
||||||
@@ -289,11 +269,6 @@ class ResultsWindow(ASubMainWindow, ListedSubWindow):
|
|||||||
self._status_label.setText(txt)
|
self._status_label.setText(txt)
|
||||||
|
|
||||||
def setup_connections(self):
|
def setup_connections(self):
|
||||||
self.undo_sc.activated.connect(self.undo)
|
|
||||||
self.redo_sc.activated.connect(self.redo)
|
|
||||||
self.copy_sc.activated.connect(self.copy)
|
|
||||||
self.paste_sc.activated.connect(self.paste)
|
|
||||||
|
|
||||||
fun = {
|
fun = {
|
||||||
"reach": self._set_current_reach,
|
"reach": self._set_current_reach,
|
||||||
"profile": self._set_current_profile,
|
"profile": self._set_current_profile,
|
||||||
@@ -411,14 +386,14 @@ class ResultsWindow(ASubMainWindow, ListedSubWindow):
|
|||||||
timestamp = self._timestamps[self._slider_time.value()]
|
timestamp = self._timestamps[self._slider_time.value()]
|
||||||
self.update(timestamp = timestamp)
|
self.update(timestamp = timestamp)
|
||||||
|
|
||||||
def copy(self):
|
def _copy(self):
|
||||||
logger.info("TODO: copy")
|
logger.info("TODO: copy")
|
||||||
|
|
||||||
def paste(self):
|
def _paste(self):
|
||||||
logger.info("TODO: paste")
|
logger.info("TODO: paste")
|
||||||
|
|
||||||
def undo(self):
|
def _undo(self):
|
||||||
self._table.undo()
|
self._table.undo()
|
||||||
|
|
||||||
def redo(self):
|
def _redo(self):
|
||||||
self._table.redo()
|
self._table.redo()
|
||||||
@@ -18,19 +18,19 @@
|
|||||||
|
|
||||||
from PyQt5.QtCore import QCoreApplication
|
from PyQt5.QtCore import QCoreApplication
|
||||||
|
|
||||||
|
from View.Tools.PamhyrTranslate import PamhyrTranslate
|
||||||
|
|
||||||
_translate = QCoreApplication.translate
|
_translate = QCoreApplication.translate
|
||||||
|
|
||||||
table_headers_reach = {
|
class ResultsTranslate(PamhyrTranslate):
|
||||||
"name": _translate("Results", "Reach name"),
|
def __init__(self):
|
||||||
}
|
super(ResultsTranslate, self).__init__()
|
||||||
|
|
||||||
table_headers_profile = {
|
self._sub_dict["table_headers_reach"] = {
|
||||||
"name": _translate("Results", "Name"),
|
"name": _translate("Results", "Reach name"),
|
||||||
"kp": _translate("Results", "KP (m)"),
|
}
|
||||||
}
|
|
||||||
|
|
||||||
def retranslate():
|
self._sub_dict["table_headers_profile"] = {
|
||||||
table_headers_reach["name"] = _translate("Results", "Reach name")
|
"name": _translate("Results", "Name"),
|
||||||
|
"kp": _translate("Results", "KP (m)"),
|
||||||
table_headers_profile["name"] = _translate("Results", "Name")
|
}
|
||||||
table_headers_profile["kp"] = _translate("Results", "KP (m)")
|
|
||||||
@@ -22,8 +22,7 @@ import os
|
|||||||
from queue import Queue
|
from queue import Queue
|
||||||
from tools import trace, timer
|
from tools import trace, timer
|
||||||
|
|
||||||
from View.ASubWindow import ASubWindow, ASubMainWindow
|
from View.Tools.PamhyrWindow import PamhyrDialog, PamhyrWindow
|
||||||
from View.ListedSubWindow import ListedSubWindow
|
|
||||||
|
|
||||||
from PyQt5.QtGui import (
|
from PyQt5.QtGui import (
|
||||||
QKeySequence,
|
QKeySequence,
|
||||||
@@ -45,24 +44,23 @@ from PyQt5.QtWidgets import (
|
|||||||
|
|
||||||
_translate = QCoreApplication.translate
|
_translate = QCoreApplication.translate
|
||||||
|
|
||||||
class SolverLogFileWindow(ASubMainWindow, ListedSubWindow):
|
class SolverLogFileWindow(PamhyrWindow):
|
||||||
def __init__(self, title="Solver logs",
|
_pamhyr_ui = "SolverLogFile"
|
||||||
file_name = None,
|
_pamhyr_name = "Solver logs"
|
||||||
|
|
||||||
|
def __init__(self, file_name = None,
|
||||||
study=None, config=None,
|
study=None, config=None,
|
||||||
solver=None, parent=None):
|
solver=None, parent=None):
|
||||||
self._title = title
|
|
||||||
self._parent = parent
|
|
||||||
|
|
||||||
self._study = study
|
|
||||||
self._config = config
|
|
||||||
self._solver = solver
|
self._solver = solver
|
||||||
|
|
||||||
self._file_name = file_name
|
self._file_name = file_name
|
||||||
|
|
||||||
super(SolverLogFileWindow, self).__init__(
|
super(SolverLogFileWindow, self).__init__(
|
||||||
name=self._title, ui="SolverLogFile", parent=parent
|
title = self._pamhyr_name,
|
||||||
|
study = study,
|
||||||
|
config = config,
|
||||||
|
options = [],
|
||||||
|
parent = parent
|
||||||
)
|
)
|
||||||
self.ui.setWindowTitle(self._title)
|
|
||||||
|
|
||||||
self.setup_action()
|
self.setup_action()
|
||||||
self.setup_connections()
|
self.setup_connections()
|
||||||
|
|||||||
@@ -23,8 +23,7 @@ import tempfile
|
|||||||
from queue import Queue
|
from queue import Queue
|
||||||
from tools import trace, timer
|
from tools import trace, timer
|
||||||
|
|
||||||
from View.ASubWindow import ASubWindow, ASubMainWindow
|
from View.Tools.PamhyrWindow import PamhyrDialog, PamhyrWindow
|
||||||
from View.ListedSubWindow import ListedSubWindow
|
|
||||||
|
|
||||||
from PyQt5.QtGui import (
|
from PyQt5.QtGui import (
|
||||||
QKeySequence,
|
QKeySequence,
|
||||||
@@ -56,20 +55,21 @@ _translate = QCoreApplication.translate
|
|||||||
|
|
||||||
logger = logging.getLogger()
|
logger = logging.getLogger()
|
||||||
|
|
||||||
class SelectSolverWindow(ASubWindow, ListedSubWindow):
|
class SelectSolverWindow(PamhyrDialog):
|
||||||
def __init__(self, title="Select solver",
|
_pamhyr_ui = "SelectSolver"
|
||||||
study=None, config=None,
|
_pamhyr_name = "Select solver"
|
||||||
parent=None):
|
|
||||||
self._title = title
|
|
||||||
|
|
||||||
self._study = study
|
def __init__(self, study=None, config=None,
|
||||||
self._config = config
|
parent=None):
|
||||||
self._solver = None
|
self._solver = None
|
||||||
|
|
||||||
super(SelectSolverWindow, self).__init__(
|
super(SelectSolverWindow, self).__init__(
|
||||||
name=self._title, ui="SelectSolver", parent=parent
|
title = self._pamhyr_name,
|
||||||
|
study = study,
|
||||||
|
config = config,
|
||||||
|
options = [],
|
||||||
|
parent = parent
|
||||||
)
|
)
|
||||||
self.ui.setWindowTitle(self._title)
|
|
||||||
|
|
||||||
self.setup_combobox()
|
self.setup_combobox()
|
||||||
self.setup_connections()
|
self.setup_connections()
|
||||||
@@ -101,24 +101,22 @@ class SelectSolverWindow(ASubWindow, ListedSubWindow):
|
|||||||
|
|
||||||
super(SelectSolverWindow, self).accept()
|
super(SelectSolverWindow, self).accept()
|
||||||
|
|
||||||
|
class SolverLogWindow(PamhyrWindow):
|
||||||
|
_pamhyr_ui = "SolverLog"
|
||||||
|
_pamhyr_name = "Solver Log"
|
||||||
|
|
||||||
class SolverLogWindow(ASubMainWindow, ListedSubWindow):
|
def __init__(self, study=None, config=None,
|
||||||
def __init__(self, title="Solver logs",
|
|
||||||
study=None, config=None,
|
|
||||||
solver=None, parent=None):
|
solver=None, parent=None):
|
||||||
self._title = title
|
|
||||||
self._parent = parent
|
|
||||||
|
|
||||||
self._study = study
|
|
||||||
self._config = config
|
|
||||||
self._solver = solver
|
self._solver = solver
|
||||||
|
|
||||||
self._results = None
|
self._results = None
|
||||||
|
|
||||||
super(SolverLogWindow, self).__init__(
|
super(SolverLogWindow, self).__init__(
|
||||||
name=self._title, ui="SolverLog", parent=parent
|
title = self._pamhyr_name,
|
||||||
|
study = study,
|
||||||
|
config = config,
|
||||||
|
options = [],
|
||||||
|
parent = parent
|
||||||
)
|
)
|
||||||
self.ui.setWindowTitle(self._title)
|
|
||||||
|
|
||||||
self.setup_action()
|
self.setup_action()
|
||||||
self.setup_alarm()
|
self.setup_alarm()
|
||||||
@@ -206,6 +204,11 @@ class SolverLogWindow(ASubMainWindow, ListedSubWindow):
|
|||||||
if self._solver.log_file() != "":
|
if self._solver.log_file() != "":
|
||||||
self.find(QAction, "action_log_file").setEnabled(True)
|
self.find(QAction, "action_log_file").setEnabled(True)
|
||||||
|
|
||||||
|
# Get results
|
||||||
|
if self._results is None:
|
||||||
|
self._results = self._solver.results(self._study, self._workdir, qlog = self._output)
|
||||||
|
self._parent.set_results(self._solver, self._results)
|
||||||
|
|
||||||
while self._output.qsize() != 0:
|
while self._output.qsize() != 0:
|
||||||
s = self._output.get()
|
s = self._output.get()
|
||||||
if type(s) is str and "[ERROR]" in s:
|
if type(s) is str and "[ERROR]" in s:
|
||||||
@@ -258,7 +261,7 @@ class SolverLogWindow(ASubMainWindow, ListedSubWindow):
|
|||||||
if self._results is None:
|
if self._results is None:
|
||||||
self._results = self._solver.results(self._study, self._workdir, qlog = self._output)
|
self._results = self._solver.results(self._study, self._workdir, qlog = self._output)
|
||||||
|
|
||||||
self._parent.set_results(self._results)
|
self._parent.set_results(self._solver, self._results)
|
||||||
self._parent.open_solver_results(self._solver, self._results)
|
self._parent.open_solver_results(self._solver, self._results)
|
||||||
|
|
||||||
def log_file(self):
|
def log_file(self):
|
||||||
|
|||||||
@@ -5,23 +5,19 @@ import logging
|
|||||||
from functools import reduce
|
from functools import reduce
|
||||||
|
|
||||||
from tools import timer
|
from tools import timer
|
||||||
from View.Plot.APlot import APlot
|
from View.Tools.PamhyrPlot import PamhyrPlot
|
||||||
|
|
||||||
from PyQt5.QtCore import (
|
|
||||||
QCoreApplication
|
|
||||||
)
|
|
||||||
|
|
||||||
_translate = QCoreApplication.translate
|
|
||||||
|
|
||||||
logger = logging.getLogger()
|
logger = logging.getLogger()
|
||||||
|
|
||||||
class Plot(APlot):
|
class Plot(PamhyrPlot):
|
||||||
def __init__(self, canvas=None, data=None, toolbar=None,
|
def __init__(self, canvas=None, trad=None, data=None, toolbar=None,
|
||||||
display_current=True):
|
display_current=True, parent=None):
|
||||||
super(Plot, self).__init__(
|
super(Plot, self).__init__(
|
||||||
canvas=canvas,
|
canvas = canvas,
|
||||||
data=data,
|
trad = trad,
|
||||||
toolbar=toolbar
|
data = data,
|
||||||
|
toolbar = toolbar,
|
||||||
|
parent = parent
|
||||||
)
|
)
|
||||||
|
|
||||||
self._display_current = display_current
|
self._display_current = display_current
|
||||||
@@ -34,13 +30,9 @@ class Plot(APlot):
|
|||||||
self.canvas.axes.cla()
|
self.canvas.axes.cla()
|
||||||
self.canvas.axes.grid(color='grey', linestyle='--', linewidth=0.5)
|
self.canvas.axes.grid(color='grey', linestyle='--', linewidth=0.5)
|
||||||
|
|
||||||
# self.canvas.axes.set_xlabel(
|
|
||||||
# _translate("MainWindow_reach", "X (m)"),
|
|
||||||
# color='green', fontsize=12
|
|
||||||
# )
|
|
||||||
self.canvas.axes.axes.get_xaxis().set_visible(False)
|
self.canvas.axes.axes.get_xaxis().set_visible(False)
|
||||||
self.canvas.axes.set_ylabel(
|
self.canvas.axes.set_ylabel(
|
||||||
_translate("MainWindow_reach", "Height (m)"),
|
self._trad["height"],
|
||||||
color='green', fontsize=12
|
color='green', fontsize=12
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|||||||
@@ -15,32 +15,14 @@ from PyQt5.QtWidgets import (
|
|||||||
QComboBox,
|
QComboBox,
|
||||||
)
|
)
|
||||||
|
|
||||||
|
from View.Tools.PamhyrTable import PamhyrTableModel
|
||||||
|
|
||||||
from View.SedimentLayers.Edit.UndoCommand import *
|
from View.SedimentLayers.Edit.UndoCommand import *
|
||||||
from View.SedimentLayers.Edit.translate import *
|
|
||||||
|
|
||||||
_translate = QCoreApplication.translate
|
_translate = QCoreApplication.translate
|
||||||
|
|
||||||
|
|
||||||
class TableModel(QAbstractTableModel):
|
class TableModel(PamhyrTableModel):
|
||||||
def __init__(self, study=None, sl=None, undo=None):
|
|
||||||
super(QAbstractTableModel, self).__init__()
|
|
||||||
self._headers = list(table_headers.keys())
|
|
||||||
self._study = study
|
|
||||||
self._undo = undo
|
|
||||||
self._sl = sl
|
|
||||||
|
|
||||||
def flags(self, index):
|
|
||||||
options = Qt.ItemIsEnabled | Qt.ItemIsSelectable
|
|
||||||
options |= Qt.ItemIsEditable
|
|
||||||
|
|
||||||
return options
|
|
||||||
|
|
||||||
def rowCount(self, parent):
|
|
||||||
return len(self._sl)
|
|
||||||
|
|
||||||
def columnCount(self, parent):
|
|
||||||
return len(self._headers)
|
|
||||||
|
|
||||||
def data(self, index, role):
|
def data(self, index, role):
|
||||||
if role != Qt.ItemDataRole.DisplayRole:
|
if role != Qt.ItemDataRole.DisplayRole:
|
||||||
return QVariant()
|
return QVariant()
|
||||||
@@ -49,23 +31,17 @@ class TableModel(QAbstractTableModel):
|
|||||||
column = index.column()
|
column = index.column()
|
||||||
|
|
||||||
if self._headers[column] == "name":
|
if self._headers[column] == "name":
|
||||||
return self._sl.get(row).name
|
return self._data.get(row).name
|
||||||
elif self._headers[column] == "type":
|
elif self._headers[column] == "type":
|
||||||
return self._sl.get(row).type
|
return self._data.get(row).type
|
||||||
elif self._headers[column] == "height":
|
elif self._headers[column] == "height":
|
||||||
return self._sl.get(row).height
|
return self._data.get(row).height
|
||||||
elif self._headers[column] == "d50":
|
elif self._headers[column] == "d50":
|
||||||
return self._sl.get(row).d50
|
return self._data.get(row).d50
|
||||||
elif self._headers[column] == "sigma":
|
elif self._headers[column] == "sigma":
|
||||||
return self._sl.get(row).sigma
|
return self._data.get(row).sigma
|
||||||
elif self._headers[column] == "critical_constraint":
|
elif self._headers[column] == "critical_constraint":
|
||||||
return self._sl.get(row).critical_constraint
|
return self._data.get(row).critical_constraint
|
||||||
|
|
||||||
return QVariant()
|
|
||||||
|
|
||||||
def headerData(self, friction, orientation, role):
|
|
||||||
if role == Qt.ItemDataRole.DisplayRole and orientation == Qt.Orientation.Horizontal:
|
|
||||||
return table_headers[self._headers[friction]]
|
|
||||||
|
|
||||||
return QVariant()
|
return QVariant()
|
||||||
|
|
||||||
@@ -79,37 +55,37 @@ class TableModel(QAbstractTableModel):
|
|||||||
if self._headers[column] == "name":
|
if self._headers[column] == "name":
|
||||||
self._undo.push(
|
self._undo.push(
|
||||||
SetNameCommand(
|
SetNameCommand(
|
||||||
self._sl, row, value
|
self._data, row, value
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
if self._headers[column] == "type":
|
if self._headers[column] == "type":
|
||||||
self._undo.push(
|
self._undo.push(
|
||||||
SetTypeCommand(
|
SetTypeCommand(
|
||||||
self._sl, row, value
|
self._data, row, value
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
if self._headers[column] == "height":
|
if self._headers[column] == "height":
|
||||||
self._undo.push(
|
self._undo.push(
|
||||||
SetHeightCommand(
|
SetHeightCommand(
|
||||||
self._sl, row, value
|
self._data, row, value
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
if self._headers[column] == "d50":
|
if self._headers[column] == "d50":
|
||||||
self._undo.push(
|
self._undo.push(
|
||||||
SetD50Command(
|
SetD50Command(
|
||||||
self._sl, row, value
|
self._data, row, value
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
if self._headers[column] == "sigma":
|
if self._headers[column] == "sigma":
|
||||||
self._undo.push(
|
self._undo.push(
|
||||||
SetSigmaCommand(
|
SetSigmaCommand(
|
||||||
self._sl, row, value
|
self._data, row, value
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
if self._headers[column] == "critical_constraint":
|
if self._headers[column] == "critical_constraint":
|
||||||
self._undo.push(
|
self._undo.push(
|
||||||
SetCriticalConstraintCommand(
|
SetCriticalConstraintCommand(
|
||||||
self._sl, row, value
|
self._data, row, value
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -121,7 +97,7 @@ class TableModel(QAbstractTableModel):
|
|||||||
|
|
||||||
self._undo.push(
|
self._undo.push(
|
||||||
AddCommand(
|
AddCommand(
|
||||||
self._sl, row
|
self._data, row
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -133,7 +109,7 @@ class TableModel(QAbstractTableModel):
|
|||||||
|
|
||||||
self._undo.push(
|
self._undo.push(
|
||||||
DelCommand(
|
DelCommand(
|
||||||
self._sl, rows
|
self._data, rows
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -150,7 +126,7 @@ class TableModel(QAbstractTableModel):
|
|||||||
|
|
||||||
self._undo.push(
|
self._undo.push(
|
||||||
MoveCommand(
|
MoveCommand(
|
||||||
self._sl, "up", row
|
self._data, "up", row
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -158,7 +134,7 @@ class TableModel(QAbstractTableModel):
|
|||||||
self.layoutChanged.emit()
|
self.layoutChanged.emit()
|
||||||
|
|
||||||
def move_down(self, row, parent=QModelIndex()):
|
def move_down(self, row, parent=QModelIndex()):
|
||||||
if row + 1 >= len(self._sl):
|
if row + 1 >= len(self._data):
|
||||||
return
|
return
|
||||||
|
|
||||||
target = row
|
target = row
|
||||||
@@ -167,7 +143,7 @@ class TableModel(QAbstractTableModel):
|
|||||||
|
|
||||||
self._undo.push(
|
self._undo.push(
|
||||||
MoveCommand(
|
MoveCommand(
|
||||||
self._sl, "down", row
|
self._data, "down", row
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|||||||
@@ -20,8 +20,7 @@ import logging
|
|||||||
|
|
||||||
from tools import trace, timer
|
from tools import trace, timer
|
||||||
|
|
||||||
from View.ASubWindow import ASubMainWindow
|
from View.Tools.PamhyrWindow import PamhyrWindow
|
||||||
from View.ListedSubWindow import ListedSubWindow
|
|
||||||
|
|
||||||
from PyQt5.QtGui import (
|
from PyQt5.QtGui import (
|
||||||
QKeySequence,
|
QKeySequence,
|
||||||
@@ -40,66 +39,58 @@ from PyQt5.QtWidgets import (
|
|||||||
QComboBox, QVBoxLayout, QHeaderView, QTabWidget,
|
QComboBox, QVBoxLayout, QHeaderView, QTabWidget,
|
||||||
)
|
)
|
||||||
|
|
||||||
from View.Plot.MplCanvas import MplCanvas
|
from View.Tools.Plot.PamhyrCanvas import MplCanvas
|
||||||
from View.Plot.PamhyrToolbar import PamhyrPlotToolbar
|
from View.Tools.Plot.PamhyrToolbar import PamhyrPlotToolbar
|
||||||
|
|
||||||
from View.SedimentLayers.Edit.UndoCommand import *
|
from View.SedimentLayers.Edit.UndoCommand import *
|
||||||
from View.SedimentLayers.Edit.Table import *
|
from View.SedimentLayers.Edit.Table import *
|
||||||
from View.SedimentLayers.Edit.Plot import Plot
|
from View.SedimentLayers.Edit.Plot import Plot
|
||||||
from View.SedimentLayers.Edit.translate import table_headers, retranslate
|
from View.SedimentLayers.Edit.translate import SedimentEditTranslate
|
||||||
|
|
||||||
_translate = QCoreApplication.translate
|
_translate = QCoreApplication.translate
|
||||||
|
|
||||||
logger = logging.getLogger()
|
logger = logging.getLogger()
|
||||||
|
|
||||||
class EditSedimentLayersWindow(ASubMainWindow, ListedSubWindow):
|
class EditSedimentLayersWindow(PamhyrWindow):
|
||||||
def __init__(self, title="Edit Sediment Layers",
|
_pamhyr_ui = "EditSedimentLayers"
|
||||||
study=None, sl=None, parent=None):
|
_pamhyr_name = "Edit Sediment Layers"
|
||||||
self._study = study
|
|
||||||
|
def __init__(self, study=None, config = None,
|
||||||
|
sl=None, parent=None):
|
||||||
self._sl = sl
|
self._sl = sl
|
||||||
|
|
||||||
self.setup_title(title)
|
|
||||||
|
|
||||||
super(EditSedimentLayersWindow, self).__init__(
|
|
||||||
name=self._title, ui="EditSedimentLayers", parent=parent
|
|
||||||
)
|
|
||||||
|
|
||||||
self.setup_sc()
|
|
||||||
self.setup_table()
|
|
||||||
self.setup_graph()
|
|
||||||
self.setup_connections()
|
|
||||||
|
|
||||||
self.ui.setWindowTitle(self._title)
|
|
||||||
|
|
||||||
def setup_title(self, title):
|
|
||||||
name = self._sl.name
|
name = self._sl.name
|
||||||
if name == "":
|
if name == "":
|
||||||
name = _translate("SedimentLayers", "(no name)")
|
name = _translate("SedimentLayers", "(no name)")
|
||||||
|
|
||||||
self._title = (
|
name = (
|
||||||
title + " - " + self._study.name + " - " + name
|
self._pamhyr_name + " - " + study.name + " - " + name
|
||||||
)
|
)
|
||||||
|
|
||||||
def setup_sc(self):
|
super(EditSedimentLayersWindow, self).__init__(
|
||||||
self._undo_stack = QUndoStack()
|
title = name,
|
||||||
|
study = study,
|
||||||
|
config = config,
|
||||||
|
trad = SedimentEditTranslate(),
|
||||||
|
parent = parent
|
||||||
|
)
|
||||||
|
|
||||||
self.undo_sc = QShortcut(QKeySequence.Undo, self)
|
self.setup_table()
|
||||||
self.redo_sc = QShortcut(QKeySequence.Redo, self)
|
self.setup_graph()
|
||||||
self.copy_sc = QShortcut(QKeySequence.Copy, self)
|
self.setup_connections()
|
||||||
self.paste_sc = QShortcut(QKeySequence.Paste, self)
|
|
||||||
|
|
||||||
def setup_table(self):
|
def setup_table(self):
|
||||||
retranslate()
|
table_headers = self._trad.get_dict("table_headers")
|
||||||
self._table = {}
|
|
||||||
|
|
||||||
table = self.find(QTableView, f"tableView")
|
table = self.find(QTableView, f"tableView")
|
||||||
self._table = TableModel(
|
self._table = TableModel(
|
||||||
study = self._study,
|
table_view = table,
|
||||||
sl = self._sl,
|
table_headers = table_headers,
|
||||||
|
editable_headers = list(table_headers),
|
||||||
|
data = self._sl,
|
||||||
|
trad = self._trad,
|
||||||
undo = self._undo_stack,
|
undo = self._undo_stack,
|
||||||
)
|
)
|
||||||
table.setModel(self._table)
|
table.setModel(self._table)
|
||||||
|
|
||||||
table.setSelectionBehavior(QAbstractItemView.SelectRows)
|
table.setSelectionBehavior(QAbstractItemView.SelectRows)
|
||||||
table.horizontalHeader().setSectionResizeMode(QHeaderView.Stretch)
|
table.horizontalHeader().setSectionResizeMode(QHeaderView.Stretch)
|
||||||
table.setAlternatingRowColors(True)
|
table.setAlternatingRowColors(True)
|
||||||
@@ -120,6 +111,7 @@ class EditSedimentLayersWindow(ASubMainWindow, ListedSubWindow):
|
|||||||
canvas = self.canvas,
|
canvas = self.canvas,
|
||||||
data = self._sl,
|
data = self._sl,
|
||||||
toolbar = self.toolbar,
|
toolbar = self.toolbar,
|
||||||
|
trad = self._trad,
|
||||||
display_current = False
|
display_current = False
|
||||||
)
|
)
|
||||||
self.plot.draw()
|
self.plot.draw()
|
||||||
@@ -131,11 +123,6 @@ class EditSedimentLayersWindow(ASubMainWindow, ListedSubWindow):
|
|||||||
self.find(QAction, "action_move_up").triggered.connect(self.move_up)
|
self.find(QAction, "action_move_up").triggered.connect(self.move_up)
|
||||||
self.find(QAction, "action_move_down").triggered.connect(self.move_down)
|
self.find(QAction, "action_move_down").triggered.connect(self.move_down)
|
||||||
|
|
||||||
self.undo_sc.activated.connect(self.undo)
|
|
||||||
self.redo_sc.activated.connect(self.redo)
|
|
||||||
self.copy_sc.activated.connect(self.copy)
|
|
||||||
self.paste_sc.activated.connect(self.paste)
|
|
||||||
|
|
||||||
self._table.dataChanged.connect(self._set_plot)
|
self._table.dataChanged.connect(self._set_plot)
|
||||||
self._table.layoutChanged.connect(self._set_plot)
|
self._table.layoutChanged.connect(self._set_plot)
|
||||||
|
|
||||||
@@ -179,14 +166,14 @@ class EditSedimentLayersWindow(ASubMainWindow, ListedSubWindow):
|
|||||||
|
|
||||||
self._table.move_down(rows[0])
|
self._table.move_down(rows[0])
|
||||||
|
|
||||||
def copy(self):
|
def _copy(self):
|
||||||
logger.info("TODO: copy")
|
logger.info("TODO: copy")
|
||||||
|
|
||||||
def paste(self):
|
def _paste(self):
|
||||||
logger.info("TODO: paste")
|
logger.info("TODO: paste")
|
||||||
|
|
||||||
def undo(self):
|
def _undo(self):
|
||||||
self._table.undo()
|
self._table.undo()
|
||||||
|
|
||||||
def redo(self):
|
def _redo(self):
|
||||||
self._table.redo()
|
self._table.redo()
|
||||||
@@ -2,21 +2,21 @@
|
|||||||
|
|
||||||
from PyQt5.QtCore import QCoreApplication
|
from PyQt5.QtCore import QCoreApplication
|
||||||
|
|
||||||
|
from View.SedimentLayers.translate import SedimentTranslate
|
||||||
|
|
||||||
_translate = QCoreApplication.translate
|
_translate = QCoreApplication.translate
|
||||||
|
|
||||||
table_headers = {
|
class SedimentEditTranslate(SedimentTranslate):
|
||||||
"name": _translate("SedimentLayers", "Name"),
|
def __init__(self):
|
||||||
# "type": _translate("SedimentLayers", "Type"),
|
super(SedimentEditTranslate, self).__init__()
|
||||||
"height": _translate("SedimentLayers", "Height"),
|
|
||||||
"d50": _translate("SedimentLayers", "D50"),
|
|
||||||
"sigma": _translate("SedimentLayers", "Sigma"),
|
|
||||||
"critical_constraint": _translate("SedimentLayers", "Critical constraint"),
|
|
||||||
}
|
|
||||||
|
|
||||||
def retranslate():
|
self._dict["height"] = _translate("SedimentLayers", "Height (m)"),
|
||||||
table_headers["name"] = _translate("SedimentLayers", "Name")
|
|
||||||
# table_headers["type"] = _translate("SedimentLayers", "Type")
|
self._sub_dict["table_headers"] = {
|
||||||
table_headers["height"] = _translate("SedimentLayers", "Height")
|
"name": _translate("SedimentLayers", "Name"),
|
||||||
table_headers["d50"] = _translate("SedimentLayers", "D50")
|
# "type": _translate("SedimentLayers", "Type"),
|
||||||
table_headers["sigma"] = _translate("SedimentLayers", "Sigma")
|
"height": _translate("SedimentLayers", "Height"),
|
||||||
table_headers["critical_constraint"] = _translate("SedimentLayers", "Critical constraint")
|
"d50": _translate("SedimentLayers", "D50"),
|
||||||
|
"sigma": _translate("SedimentLayers", "Sigma"),
|
||||||
|
"critical_constraint": _translate("SedimentLayers", "Critical constraint"),
|
||||||
|
}
|
||||||
@@ -5,7 +5,7 @@ import logging
|
|||||||
from functools import reduce
|
from functools import reduce
|
||||||
|
|
||||||
from tools import timer
|
from tools import timer
|
||||||
from View.Plot.APlot import APlot
|
from View.Tools.PamhyrPlot import PamhyrPlot
|
||||||
|
|
||||||
from PyQt5.QtCore import (
|
from PyQt5.QtCore import (
|
||||||
QCoreApplication
|
QCoreApplication
|
||||||
@@ -15,13 +15,16 @@ _translate = QCoreApplication.translate
|
|||||||
|
|
||||||
logger = logging.getLogger()
|
logger = logging.getLogger()
|
||||||
|
|
||||||
class Plot(APlot):
|
class Plot(PamhyrPlot):
|
||||||
def __init__(self, canvas=None, data=None, toolbar=None,
|
def __init__(self, data=None, display_current=True,
|
||||||
display_current=True):
|
canvas=None, trad=None, toolbar=None,
|
||||||
|
parent=None):
|
||||||
super(Plot, self).__init__(
|
super(Plot, self).__init__(
|
||||||
canvas=canvas,
|
canvas = canvas,
|
||||||
data=data,
|
trad = trad,
|
||||||
toolbar=toolbar
|
data = data,
|
||||||
|
toolbar = toolbar,
|
||||||
|
parent = parent
|
||||||
)
|
)
|
||||||
|
|
||||||
self._display_current = display_current
|
self._display_current = display_current
|
||||||
@@ -41,11 +44,11 @@ class Plot(APlot):
|
|||||||
return
|
return
|
||||||
|
|
||||||
self.canvas.axes.set_xlabel(
|
self.canvas.axes.set_xlabel(
|
||||||
_translate("MainWindow_reach", "Kp (m)"),
|
self._trad["kp"],
|
||||||
color='green', fontsize=12
|
color='green', fontsize=12
|
||||||
)
|
)
|
||||||
self.canvas.axes.set_ylabel(
|
self.canvas.axes.set_ylabel(
|
||||||
_translate("MainWindow_reach", "Height (m)"),
|
self._trad["height"],
|
||||||
color='green', fontsize=12
|
color='green', fontsize=12
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|||||||
@@ -5,7 +5,7 @@ import logging
|
|||||||
from functools import reduce
|
from functools import reduce
|
||||||
|
|
||||||
from tools import timer
|
from tools import timer
|
||||||
from View.Plot.APlot import APlot
|
from View.Tools.PamhyrPlot import PamhyrPlot
|
||||||
|
|
||||||
from PyQt5.QtCore import (
|
from PyQt5.QtCore import (
|
||||||
QCoreApplication
|
QCoreApplication
|
||||||
@@ -15,13 +15,16 @@ _translate = QCoreApplication.translate
|
|||||||
|
|
||||||
logger = logging.getLogger()
|
logger = logging.getLogger()
|
||||||
|
|
||||||
class Plot(APlot):
|
class Plot(PamhyrPlot):
|
||||||
def __init__(self, canvas=None, data=None, toolbar=None,
|
def __init__(self, data=None, display_current=True,
|
||||||
display_current=True):
|
canvas=None, trad=None, toolbar=None,
|
||||||
|
parent=None):
|
||||||
super(Plot, self).__init__(
|
super(Plot, self).__init__(
|
||||||
canvas=canvas,
|
canvas = canvas,
|
||||||
data=data,
|
trad = trad,
|
||||||
toolbar=toolbar
|
data = data,
|
||||||
|
toolbar = toolbar,
|
||||||
|
parent = parent
|
||||||
)
|
)
|
||||||
|
|
||||||
self._display_current = display_current
|
self._display_current = display_current
|
||||||
|
|||||||
@@ -20,6 +20,8 @@ from PyQt5.QtWidgets import (
|
|||||||
from View.SedimentLayers.Reach.Profile.UndoCommand import *
|
from View.SedimentLayers.Reach.Profile.UndoCommand import *
|
||||||
from View.SedimentLayers.Reach.Profile.translate import *
|
from View.SedimentLayers.Reach.Profile.translate import *
|
||||||
|
|
||||||
|
from View.Tools.PamhyrTable import PamhyrTableModel
|
||||||
|
|
||||||
_translate = QCoreApplication.translate
|
_translate = QCoreApplication.translate
|
||||||
|
|
||||||
logger = logging.getLogger()
|
logger = logging.getLogger()
|
||||||
@@ -67,28 +69,10 @@ class ComboBoxDelegate(QItemDelegate):
|
|||||||
self.commitData.emit(self.sender())
|
self.commitData.emit(self.sender())
|
||||||
|
|
||||||
|
|
||||||
class TableModel(QAbstractTableModel):
|
class TableModel(PamhyrTableModel):
|
||||||
def __init__(self, study=None, profile=None, undo=None):
|
def _setup_lst(self):
|
||||||
super(QAbstractTableModel, self).__init__()
|
self._lst = self._data
|
||||||
self._headers = list(table_headers.keys())
|
self._study = self._opt_data
|
||||||
self._study = study
|
|
||||||
self._undo = undo
|
|
||||||
self._profile = profile
|
|
||||||
|
|
||||||
def flags(self, index):
|
|
||||||
column = index.column()
|
|
||||||
|
|
||||||
options = Qt.ItemIsEnabled | Qt.ItemIsSelectable
|
|
||||||
if self._headers[column] == "sl":
|
|
||||||
options |= Qt.ItemIsEditable
|
|
||||||
|
|
||||||
return options
|
|
||||||
|
|
||||||
def rowCount(self, parent):
|
|
||||||
return self._profile.number_points
|
|
||||||
|
|
||||||
def columnCount(self, parent):
|
|
||||||
return len(self._headers)
|
|
||||||
|
|
||||||
def data(self, index, role):
|
def data(self, index, role):
|
||||||
if role != Qt.ItemDataRole.DisplayRole:
|
if role != Qt.ItemDataRole.DisplayRole:
|
||||||
@@ -98,25 +82,19 @@ class TableModel(QAbstractTableModel):
|
|||||||
column = index.column()
|
column = index.column()
|
||||||
|
|
||||||
if self._headers[column] == "name":
|
if self._headers[column] == "name":
|
||||||
return self._profile.point(row).name
|
return self._data.point(row).name
|
||||||
elif self._headers[column] == "sl":
|
elif self._headers[column] == "sl":
|
||||||
value = self._profile.point(row).sl
|
value = self._data.point(row).sl
|
||||||
if value == None:
|
if value == None:
|
||||||
text = _translate("SedimentLayers", "Not defined")
|
text = _translate("SedimentLayers", "Not defined")
|
||||||
return text
|
return text
|
||||||
return str(value)
|
return str(value)
|
||||||
elif self._headers[column] == "x":
|
elif self._headers[column] == "x":
|
||||||
return self._profile.point(row).x
|
return self._data.point(row).x
|
||||||
elif self._headers[column] == "y":
|
elif self._headers[column] == "y":
|
||||||
return self._profile.point(row).y
|
return self._data.point(row).y
|
||||||
elif self._headers[column] == "z":
|
elif self._headers[column] == "z":
|
||||||
return self._profile.point(row).z
|
return self._data.point(row).z
|
||||||
|
|
||||||
return QVariant()
|
|
||||||
|
|
||||||
def headerData(self, friction, orientation, role):
|
|
||||||
if role == Qt.ItemDataRole.DisplayRole and orientation == Qt.Orientation.Horizontal:
|
|
||||||
return table_headers[self._headers[friction]]
|
|
||||||
|
|
||||||
return QVariant()
|
return QVariant()
|
||||||
|
|
||||||
@@ -139,7 +117,7 @@ class TableModel(QAbstractTableModel):
|
|||||||
|
|
||||||
self._undo.push(
|
self._undo.push(
|
||||||
SetSLCommand(
|
SetSLCommand(
|
||||||
self._profile, row, new
|
self._data, row, new
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|||||||
@@ -4,8 +4,7 @@ import logging
|
|||||||
|
|
||||||
from tools import trace, timer
|
from tools import trace, timer
|
||||||
|
|
||||||
from View.ASubWindow import ASubMainWindow
|
from View.Tools.PamhyrWindow import PamhyrWindow
|
||||||
from View.ListedSubWindow import ListedSubWindow
|
|
||||||
|
|
||||||
from PyQt5.QtGui import (
|
from PyQt5.QtGui import (
|
||||||
QKeySequence,
|
QKeySequence,
|
||||||
@@ -28,37 +27,42 @@ from View.SedimentLayers.Reach.Profile.UndoCommand import *
|
|||||||
from View.SedimentLayers.Reach.Profile.Table import *
|
from View.SedimentLayers.Reach.Profile.Table import *
|
||||||
from View.SedimentLayers.Reach.Profile.Plot import Plot
|
from View.SedimentLayers.Reach.Profile.Plot import Plot
|
||||||
|
|
||||||
from View.Plot.MplCanvas import MplCanvas
|
from View.Tools.Plot.PamhyrCanvas import MplCanvas
|
||||||
from View.Plot.PamhyrToolbar import PamhyrPlotToolbar
|
from View.Tools.Plot.PamhyrToolbar import PamhyrPlotToolbar
|
||||||
|
|
||||||
from View.SedimentLayers.Reach.Profile.translate import table_headers, retranslate
|
from View.SedimentLayers.Reach.Profile.translate import SedimentProfileTranslate
|
||||||
from View.SedimentLayers.Window import SedimentLayersWindow
|
from View.SedimentLayers.Window import SedimentLayersWindow
|
||||||
|
|
||||||
_translate = QCoreApplication.translate
|
_translate = QCoreApplication.translate
|
||||||
|
|
||||||
logger = logging.getLogger()
|
logger = logging.getLogger()
|
||||||
|
|
||||||
class ProfileSedimentLayersWindow(ASubMainWindow, ListedSubWindow):
|
class ProfileSedimentLayersWindow(PamhyrWindow):
|
||||||
def __init__(self, title="Profile sediment layers", study=None, profile=None, parent=None):
|
_pamhyr_ui = "ProfileSedimentLayers"
|
||||||
self._study = study
|
_pamhyr_name = "Profile sediment layers"
|
||||||
self._sediment_layers = self._study.river.sediment_layers
|
|
||||||
self._profile = profile
|
|
||||||
self._reach = self._study.river.current_reach().reach
|
|
||||||
|
|
||||||
self.setup_title(title)
|
def __init__(self, study=None, config=None, profile=None, parent=None):
|
||||||
|
self._sediment_layers = study.river.sediment_layers
|
||||||
|
self._profile = profile
|
||||||
|
self._reach = profile.reach
|
||||||
|
|
||||||
|
name = self.compute_name(study)
|
||||||
|
|
||||||
super(ProfileSedimentLayersWindow, self).__init__(
|
super(ProfileSedimentLayersWindow, self).__init__(
|
||||||
name=self._title, ui="ProfileSedimentLayers", parent=parent
|
title = name,
|
||||||
|
study = study,
|
||||||
|
config = config,
|
||||||
|
trad = SedimentProfileTranslate(),
|
||||||
|
parent = parent
|
||||||
)
|
)
|
||||||
|
|
||||||
self.setup_sc()
|
|
||||||
self.setup_table()
|
self.setup_table()
|
||||||
self.setup_graph()
|
self.setup_graph()
|
||||||
self.setup_connections()
|
self.setup_connections()
|
||||||
|
|
||||||
self.ui.setWindowTitle(self._title)
|
self.ui.setWindowTitle(self._title)
|
||||||
|
|
||||||
def setup_title(self, title):
|
def compute_name(self, study):
|
||||||
rname = self._reach.name
|
rname = self._reach.name
|
||||||
if rname == "":
|
if rname == "":
|
||||||
rname = _translate("SedimentLayers", "(no name)")
|
rname = _translate("SedimentLayers", "(no name)")
|
||||||
@@ -70,41 +74,32 @@ class ProfileSedimentLayersWindow(ASubMainWindow, ListedSubWindow):
|
|||||||
"(no name - @kp)").replace("@kp", str(self._profile.kp)
|
"(no name - @kp)").replace("@kp", str(self._profile.kp)
|
||||||
)
|
)
|
||||||
|
|
||||||
self._title = (
|
return (
|
||||||
title + " - "
|
self._pamhyr_name + " - "
|
||||||
+ self._study.name + " - "
|
+ study.name + " - "
|
||||||
+ rname + " - " + pname
|
+ rname + " - " + pname
|
||||||
)
|
)
|
||||||
|
|
||||||
def setup_sc(self):
|
|
||||||
self._undo_stack = QUndoStack()
|
|
||||||
|
|
||||||
self.undo_sc = QShortcut(QKeySequence.Undo, self)
|
|
||||||
self.redo_sc = QShortcut(QKeySequence.Redo, self)
|
|
||||||
self.copy_sc = QShortcut(QKeySequence.Copy, self)
|
|
||||||
self.paste_sc = QShortcut(QKeySequence.Paste, self)
|
|
||||||
|
|
||||||
def setup_table(self):
|
def setup_table(self):
|
||||||
retranslate()
|
table_headers = self._trad.get_dict("table_headers")
|
||||||
|
|
||||||
table = self.find(QTableView, f"tableView")
|
self._delegate_sl = ComboBoxDelegate(
|
||||||
self._table = TableModel(
|
|
||||||
study = self._study,
|
|
||||||
profile = self._profile,
|
|
||||||
undo = self._undo_stack,
|
|
||||||
)
|
|
||||||
table.setModel(self._table)
|
|
||||||
|
|
||||||
self._delegate_stricklers = ComboBoxDelegate(
|
|
||||||
study = self._study,
|
study = self._study,
|
||||||
parent=self
|
parent=self
|
||||||
)
|
)
|
||||||
|
|
||||||
table.setItemDelegateForColumn(
|
table = self.find(QTableView, f"tableView")
|
||||||
list(table_headers).index("sl"),
|
self._table = TableModel(
|
||||||
self._delegate_stricklers
|
table_view = table,
|
||||||
|
data = self._profile,
|
||||||
|
opt_data = self._study,
|
||||||
|
table_headers = table_headers,
|
||||||
|
editable_headers = ["sl"],
|
||||||
|
delegates = {"sl": self._delegate_sl},
|
||||||
|
trad = self._trad,
|
||||||
|
undo = self._undo_stack,
|
||||||
)
|
)
|
||||||
|
table.setModel(self._table)
|
||||||
table.setSelectionBehavior(QAbstractItemView.SelectRows)
|
table.setSelectionBehavior(QAbstractItemView.SelectRows)
|
||||||
table.horizontalHeader().setSectionResizeMode(QHeaderView.Stretch)
|
table.horizontalHeader().setSectionResizeMode(QHeaderView.Stretch)
|
||||||
table.setAlternatingRowColors(True)
|
table.setAlternatingRowColors(True)
|
||||||
@@ -130,18 +125,9 @@ class ProfileSedimentLayersWindow(ASubMainWindow, ListedSubWindow):
|
|||||||
)
|
)
|
||||||
self.plot.draw()
|
self.plot.draw()
|
||||||
|
|
||||||
|
|
||||||
def setup_connections(self):
|
def setup_connections(self):
|
||||||
self.undo_sc.activated.connect(self.undo)
|
self._table.layoutChanged.connect(self._update_plot)
|
||||||
self.redo_sc.activated.connect(self.redo)
|
self._table.dataChanged.connect(self._update_plot)
|
||||||
self.copy_sc.activated.connect(self.copy)
|
|
||||||
self.paste_sc.activated.connect(self.paste)
|
|
||||||
|
|
||||||
self._table.layoutChanged\
|
|
||||||
.connect(self._update_plot)
|
|
||||||
self._table.dataChanged\
|
|
||||||
.connect(self._update_plot)
|
|
||||||
|
|
||||||
|
|
||||||
def index_selected_rows(self):
|
def index_selected_rows(self):
|
||||||
table = self.find(QTableView, f"tableView")
|
table = self.find(QTableView, f"tableView")
|
||||||
@@ -155,14 +141,14 @@ class ProfileSedimentLayersWindow(ASubMainWindow, ListedSubWindow):
|
|||||||
)
|
)
|
||||||
)
|
)
|
||||||
|
|
||||||
def copy(self):
|
def _copy(self):
|
||||||
logger.info("TODO: copy")
|
logger.info("TODO: copy")
|
||||||
|
|
||||||
def paste(self):
|
def _paste(self):
|
||||||
logger.info("TODO: paste")
|
logger.info("TODO: paste")
|
||||||
|
|
||||||
def undo(self):
|
def _undo(self):
|
||||||
self._table.undo()
|
self._table.undo()
|
||||||
|
|
||||||
def redo(self):
|
def _redo(self):
|
||||||
self._table.redo()
|
self._table.redo()
|
||||||
@@ -2,19 +2,18 @@
|
|||||||
|
|
||||||
from PyQt5.QtCore import QCoreApplication
|
from PyQt5.QtCore import QCoreApplication
|
||||||
|
|
||||||
|
from View.SedimentLayers.Reach.translate import SedimentReachTranslate
|
||||||
|
|
||||||
_translate = QCoreApplication.translate
|
_translate = QCoreApplication.translate
|
||||||
|
|
||||||
table_headers = {
|
class SedimentProfileTranslate(SedimentReachTranslate):
|
||||||
"x": _translate("SedimentLayers", "X (m)"),
|
def __init__(self):
|
||||||
"y": _translate("SedimentLayers", "Y (m)"),
|
super(SedimentProfileTranslate, self).__init__()
|
||||||
"z": _translate("SedimentLayers", "Z (m)"),
|
|
||||||
"name": _translate("SedimentLayers", "Name"),
|
|
||||||
"sl": _translate("SedimentLayers", "Sediment layers"),
|
|
||||||
}
|
|
||||||
|
|
||||||
def retranslate():
|
self._sub_dict["table_headers"] = {
|
||||||
table_headers["x"] = _translate("SedimentLayers", "X (m)")
|
"x": _translate("SedimentLayers", "X (m)"),
|
||||||
table_headers["y"] = _translate("SedimentLayers", "Y (m)")
|
"y": _translate("SedimentLayers", "Y (m)"),
|
||||||
table_headers["z"] = _translate("SedimentLayers", "Z (m)")
|
"z": _translate("SedimentLayers", "Z (m)"),
|
||||||
table_headers["name"] = _translate("SedimentLayers", "Name")
|
"name": _translate("SedimentLayers", "Name"),
|
||||||
table_headers["sl"] = _translate("SedimentLayers", "Sediment layers")
|
"sl": _translate("SedimentLayers", "Sediment layers"),
|
||||||
|
}
|
||||||
@@ -1,7 +1,6 @@
|
|||||||
# -*- coding: utf-8 -*-
|
# -*- coding: utf-8 -*-
|
||||||
|
|
||||||
from View.ASubWindow import ASubWindow
|
from View.Tools.PamhyrWindow import PamhyrDialog
|
||||||
from View.ListedSubWindow import ListedSubWindow
|
|
||||||
|
|
||||||
from PyQt5.QtGui import (
|
from PyQt5.QtGui import (
|
||||||
QKeySequence,
|
QKeySequence,
|
||||||
@@ -20,12 +19,16 @@ from View.SedimentLayers.Reach.translate import *
|
|||||||
|
|
||||||
_translate = QCoreApplication.translate
|
_translate = QCoreApplication.translate
|
||||||
|
|
||||||
class SLDialog(ASubWindow, ListedSubWindow):
|
class SLDialog(PamhyrDialog):
|
||||||
def __init__(self, title="SL", study=None, parent=None):
|
_pamhyr_ui = "SLDialog"
|
||||||
self._study = study
|
_pamhyr_name = "SL"
|
||||||
|
|
||||||
|
def __init__(self, study=None, config=None, parent=None):
|
||||||
super(SLDialog, self).__init__(
|
super(SLDialog, self).__init__(
|
||||||
name=title, ui="SLDialog", parent=parent
|
title = self._pamhyr_name,
|
||||||
|
study = study,
|
||||||
|
config = config,
|
||||||
|
parent=parent
|
||||||
)
|
)
|
||||||
|
|
||||||
self.setup_combobox()
|
self.setup_combobox()
|
||||||
|
|||||||
@@ -18,23 +18,25 @@ from PyQt5.QtWidgets import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
from View.SedimentLayers.Reach.UndoCommand import *
|
from View.SedimentLayers.Reach.UndoCommand import *
|
||||||
from View.SedimentLayers.Reach.translate import *
|
|
||||||
|
from View.Tools.PamhyrTable import PamhyrTableModel
|
||||||
|
|
||||||
_translate = QCoreApplication.translate
|
_translate = QCoreApplication.translate
|
||||||
|
|
||||||
logger = logging.getLogger()
|
logger = logging.getLogger()
|
||||||
|
|
||||||
class ComboBoxDelegate(QItemDelegate):
|
class ComboBoxDelegate(QItemDelegate):
|
||||||
def __init__(self, study=None, parent=None):
|
def __init__(self, study=None, trad=None, parent=None):
|
||||||
super(ComboBoxDelegate, self).__init__(parent)
|
super(ComboBoxDelegate, self).__init__(parent)
|
||||||
|
|
||||||
self._study = study
|
self._study = study
|
||||||
|
self._trad = trad
|
||||||
|
|
||||||
def createEditor(self, parent, option, index):
|
def createEditor(self, parent, option, index):
|
||||||
self.editor = QComboBox(parent)
|
self.editor = QComboBox(parent)
|
||||||
|
|
||||||
self.editor.addItems(
|
self.editor.addItems(
|
||||||
[_translate("SedimentLayers", "Not defined")] +
|
[self._trad["nd"]] +
|
||||||
list(
|
list(
|
||||||
map(
|
map(
|
||||||
lambda sl: str(sl),
|
lambda sl: str(sl),
|
||||||
@@ -67,28 +69,10 @@ class ComboBoxDelegate(QItemDelegate):
|
|||||||
self.commitData.emit(self.sender())
|
self.commitData.emit(self.sender())
|
||||||
|
|
||||||
|
|
||||||
class TableModel(QAbstractTableModel):
|
class TableModel(PamhyrTableModel):
|
||||||
def __init__(self, study=None, reach=None, undo=None):
|
def _setup_lst(self):
|
||||||
super(QAbstractTableModel, self).__init__()
|
self._lst = self._data
|
||||||
self._headers = list(table_headers.keys())
|
self._study = self._opt_data
|
||||||
self._study = study
|
|
||||||
self._undo = undo
|
|
||||||
self._reach = reach
|
|
||||||
|
|
||||||
def flags(self, index):
|
|
||||||
column = index.column()
|
|
||||||
|
|
||||||
options = Qt.ItemIsEnabled | Qt.ItemIsSelectable
|
|
||||||
if self._headers[column] == "sl":
|
|
||||||
options |= Qt.ItemIsEditable
|
|
||||||
|
|
||||||
return options
|
|
||||||
|
|
||||||
def rowCount(self, parent):
|
|
||||||
return self._reach.number_profiles
|
|
||||||
|
|
||||||
def columnCount(self, parent):
|
|
||||||
return len(self._headers)
|
|
||||||
|
|
||||||
def data(self, index, role):
|
def data(self, index, role):
|
||||||
if role != Qt.ItemDataRole.DisplayRole:
|
if role != Qt.ItemDataRole.DisplayRole:
|
||||||
@@ -98,11 +82,11 @@ class TableModel(QAbstractTableModel):
|
|||||||
column = index.column()
|
column = index.column()
|
||||||
|
|
||||||
if self._headers[column] == "name":
|
if self._headers[column] == "name":
|
||||||
return self._reach.profile(row).name
|
return self._data.profile(row).name
|
||||||
if self._headers[column] == "kp":
|
if self._headers[column] == "kp":
|
||||||
return self._reach.profile(row).kp
|
return self._data.profile(row).kp
|
||||||
if self._headers[column] == "sl":
|
if self._headers[column] == "sl":
|
||||||
value = self._reach.profile(row).sl
|
value = self._data.profile(row).sl
|
||||||
if value == None:
|
if value == None:
|
||||||
text = _translate("SedimentLayers", "Not defined")
|
text = _translate("SedimentLayers", "Not defined")
|
||||||
return text
|
return text
|
||||||
@@ -110,12 +94,6 @@ class TableModel(QAbstractTableModel):
|
|||||||
|
|
||||||
return QVariant()
|
return QVariant()
|
||||||
|
|
||||||
def headerData(self, friction, orientation, role):
|
|
||||||
if role == Qt.ItemDataRole.DisplayRole and orientation == Qt.Orientation.Horizontal:
|
|
||||||
return table_headers[self._headers[friction]]
|
|
||||||
|
|
||||||
return QVariant()
|
|
||||||
|
|
||||||
def setData(self, index, value, role=Qt.EditRole):
|
def setData(self, index, value, role=Qt.EditRole):
|
||||||
if not index.isValid() or role != Qt.EditRole:
|
if not index.isValid() or role != Qt.EditRole:
|
||||||
return False
|
return False
|
||||||
@@ -135,7 +113,7 @@ class TableModel(QAbstractTableModel):
|
|||||||
|
|
||||||
self._undo.push(
|
self._undo.push(
|
||||||
SetSLCommand(
|
SetSLCommand(
|
||||||
self._reach, row, new
|
self._data, row, new
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -145,7 +123,7 @@ class TableModel(QAbstractTableModel):
|
|||||||
def apply_sl_each_profile(self, sl):
|
def apply_sl_each_profile(self, sl):
|
||||||
self._undo.push(
|
self._undo.push(
|
||||||
ApplySLCommand(
|
ApplySLCommand(
|
||||||
self._reach, sl
|
self._data, sl
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
self.layoutChanged.emit()
|
self.layoutChanged.emit()
|
||||||
|
|||||||
@@ -4,8 +4,7 @@ import logging
|
|||||||
|
|
||||||
from tools import trace, timer
|
from tools import trace, timer
|
||||||
|
|
||||||
from View.ASubWindow import ASubMainWindow
|
from View.Tools.PamhyrWindow import PamhyrWindow
|
||||||
from View.ListedSubWindow import ListedSubWindow
|
|
||||||
|
|
||||||
from PyQt5.QtGui import (
|
from PyQt5.QtGui import (
|
||||||
QKeySequence,
|
QKeySequence,
|
||||||
@@ -29,10 +28,10 @@ from View.SedimentLayers.Reach.Table import *
|
|||||||
from View.SedimentLayers.Reach.Plot import Plot
|
from View.SedimentLayers.Reach.Plot import Plot
|
||||||
from View.SedimentLayers.Reach.SLDialog import SLDialog
|
from View.SedimentLayers.Reach.SLDialog import SLDialog
|
||||||
|
|
||||||
from View.Plot.MplCanvas import MplCanvas
|
from View.Tools.Plot.PamhyrCanvas import MplCanvas
|
||||||
from View.Plot.PamhyrToolbar import PamhyrPlotToolbar
|
from View.Tools.Plot.PamhyrToolbar import PamhyrPlotToolbar
|
||||||
|
|
||||||
from View.SedimentLayers.Reach.translate import table_headers, retranslate
|
from View.SedimentLayers.Reach.translate import SedimentReachTranslate
|
||||||
from View.SedimentLayers.Window import SedimentLayersWindow
|
from View.SedimentLayers.Window import SedimentLayersWindow
|
||||||
from View.SedimentLayers.Reach.Profile.Window import ProfileSedimentLayersWindow
|
from View.SedimentLayers.Reach.Profile.Window import ProfileSedimentLayersWindow
|
||||||
|
|
||||||
@@ -40,64 +39,58 @@ _translate = QCoreApplication.translate
|
|||||||
|
|
||||||
logger = logging.getLogger()
|
logger = logging.getLogger()
|
||||||
|
|
||||||
class ReachSedimentLayersWindow(ASubMainWindow, ListedSubWindow):
|
class ReachSedimentLayersWindow(PamhyrWindow):
|
||||||
def __init__(self, title="Reach sediment layers", study=None, parent=None):
|
_pamhyr_ui = "ReachSedimentLayers"
|
||||||
self._study = study
|
_pamhyr_name = "Reach sediment layers"
|
||||||
self._sediment_layers = self._study.river.sediment_layers
|
|
||||||
self._reach = self._study.river.current_reach().reach
|
|
||||||
|
|
||||||
self.setup_title(title)
|
def __init__(self, study=None, config=None, parent=None):
|
||||||
|
self._sediment_layers = study.river.sediment_layers
|
||||||
|
self._reach = study.river.current_reach().reach
|
||||||
|
|
||||||
|
name = (
|
||||||
|
self._pamhyr_name + " - " +
|
||||||
|
study.name + " - " +
|
||||||
|
self._reach.name
|
||||||
|
)
|
||||||
|
|
||||||
super(ReachSedimentLayersWindow, self).__init__(
|
super(ReachSedimentLayersWindow, self).__init__(
|
||||||
name=self._title, ui="ReachSedimentLayers", parent=parent
|
title = name,
|
||||||
|
study = study,
|
||||||
|
config = config,
|
||||||
|
trad = SedimentReachTranslate(),
|
||||||
|
parent = parent
|
||||||
)
|
)
|
||||||
|
|
||||||
self.setup_sc()
|
|
||||||
self.setup_table()
|
self.setup_table()
|
||||||
self.setup_graph()
|
self.setup_plot()
|
||||||
self.setup_connections()
|
self.setup_connections()
|
||||||
|
|
||||||
self.ui.setWindowTitle(self._title)
|
|
||||||
|
|
||||||
def setup_title(self, title):
|
|
||||||
self._title = (
|
|
||||||
title + " - " + self._study.name + " - " + self._reach.name
|
|
||||||
)
|
|
||||||
|
|
||||||
def setup_sc(self):
|
|
||||||
self._undo_stack = QUndoStack()
|
|
||||||
|
|
||||||
self.undo_sc = QShortcut(QKeySequence.Undo, self)
|
|
||||||
self.redo_sc = QShortcut(QKeySequence.Redo, self)
|
|
||||||
self.copy_sc = QShortcut(QKeySequence.Copy, self)
|
|
||||||
self.paste_sc = QShortcut(QKeySequence.Paste, self)
|
|
||||||
|
|
||||||
def setup_table(self):
|
def setup_table(self):
|
||||||
retranslate()
|
table_headers = self._trad.get_dict("table_headers")
|
||||||
|
|
||||||
table = self.find(QTableView, f"tableView")
|
self._delegate_sl = ComboBoxDelegate(
|
||||||
self._table = TableModel(
|
|
||||||
study = self._study,
|
|
||||||
reach = self._reach,
|
|
||||||
undo = self._undo_stack,
|
|
||||||
)
|
|
||||||
table.setModel(self._table)
|
|
||||||
|
|
||||||
self._delegate_stricklers = ComboBoxDelegate(
|
|
||||||
study = self._study,
|
study = self._study,
|
||||||
|
trad = self._trad,
|
||||||
parent=self
|
parent=self
|
||||||
)
|
)
|
||||||
|
|
||||||
table.setItemDelegateForColumn(
|
table = self.find(QTableView, f"tableView")
|
||||||
list(table_headers).index("sl"),
|
self._table = TableModel(
|
||||||
self._delegate_stricklers
|
table_view = table,
|
||||||
|
data = self._reach,
|
||||||
|
opt_data = self._study,
|
||||||
|
table_headers = table_headers,
|
||||||
|
editable_headers = ["sl"],
|
||||||
|
delegates = {"sl": self._delegate_sl},
|
||||||
|
trad = self._trad,
|
||||||
|
undo = self._undo_stack,
|
||||||
)
|
)
|
||||||
|
table.setModel(self._table)
|
||||||
table.setSelectionBehavior(QAbstractItemView.SelectRows)
|
table.setSelectionBehavior(QAbstractItemView.SelectRows)
|
||||||
table.horizontalHeader().setSectionResizeMode(QHeaderView.Stretch)
|
table.horizontalHeader().setSectionResizeMode(QHeaderView.Stretch)
|
||||||
table.setAlternatingRowColors(True)
|
table.setAlternatingRowColors(True)
|
||||||
|
|
||||||
def setup_graph(self):
|
def setup_plot(self):
|
||||||
self.canvas = MplCanvas(width=5, height=4, dpi=100)
|
self.canvas = MplCanvas(width=5, height=4, dpi=100)
|
||||||
self.canvas.setObjectName("canvas")
|
self.canvas.setObjectName("canvas")
|
||||||
self.toolbar = PamhyrPlotToolbar(
|
self.toolbar = PamhyrPlotToolbar(
|
||||||
@@ -114,6 +107,7 @@ class ReachSedimentLayersWindow(ASubMainWindow, ListedSubWindow):
|
|||||||
canvas = self.canvas,
|
canvas = self.canvas,
|
||||||
data = self._reach,
|
data = self._reach,
|
||||||
toolbar = self.toolbar,
|
toolbar = self.toolbar,
|
||||||
|
trad = self._trad,
|
||||||
display_current = False
|
display_current = False
|
||||||
)
|
)
|
||||||
self.plot.draw()
|
self.plot.draw()
|
||||||
@@ -129,11 +123,6 @@ class ReachSedimentLayersWindow(ASubMainWindow, ListedSubWindow):
|
|||||||
.clicked\
|
.clicked\
|
||||||
.connect(self.apply_sl_each_profile)
|
.connect(self.apply_sl_each_profile)
|
||||||
|
|
||||||
self.undo_sc.activated.connect(self.undo)
|
|
||||||
self.redo_sc.activated.connect(self.redo)
|
|
||||||
self.copy_sc.activated.connect(self.copy)
|
|
||||||
self.paste_sc.activated.connect(self.paste)
|
|
||||||
|
|
||||||
self._table.layoutChanged\
|
self._table.layoutChanged\
|
||||||
.connect(self._update_plot)
|
.connect(self._update_plot)
|
||||||
self._table.dataChanged\
|
self._table.dataChanged\
|
||||||
@@ -152,17 +141,17 @@ class ReachSedimentLayersWindow(ASubMainWindow, ListedSubWindow):
|
|||||||
)
|
)
|
||||||
)
|
)
|
||||||
|
|
||||||
def copy(self):
|
def _copy(self):
|
||||||
logger.info("TODO: copy")
|
logger.info("TODO: copy")
|
||||||
|
|
||||||
def paste(self):
|
def _paste(self):
|
||||||
logger.info("TODO: paste")
|
logger.info("TODO: paste")
|
||||||
|
|
||||||
def undo(self):
|
def _undo(self):
|
||||||
self._table.undo()
|
self._table.undo()
|
||||||
self._update_plot()
|
self._update_plot()
|
||||||
|
|
||||||
def redo(self):
|
def _redo(self):
|
||||||
self._table.redo()
|
self._table.redo()
|
||||||
self._update_plot()
|
self._update_plot()
|
||||||
|
|
||||||
|
|||||||
@@ -2,15 +2,20 @@
|
|||||||
|
|
||||||
from PyQt5.QtCore import QCoreApplication
|
from PyQt5.QtCore import QCoreApplication
|
||||||
|
|
||||||
|
from View.SedimentLayers.translate import SedimentTranslate
|
||||||
|
|
||||||
_translate = QCoreApplication.translate
|
_translate = QCoreApplication.translate
|
||||||
|
|
||||||
table_headers = {
|
class SedimentReachTranslate(SedimentTranslate):
|
||||||
"name": _translate("SedimentLayers", "Name"),
|
def __init__(self):
|
||||||
"kp": _translate("SedimentLayers", "KP (m)"),
|
super(SedimentReachTranslate, self).__init__()
|
||||||
"sl": _translate("SedimentLayers", "Sediment layers"),
|
|
||||||
}
|
|
||||||
|
|
||||||
def retranslate():
|
self._dict["nd"] = _translate("SedimentLayers", "Not defined")
|
||||||
table_headers["name"] = _translate("SedimentLayers", "Name")
|
self._dict["kp"] = _translate("SedimentLayers", "Kp (m)")
|
||||||
table_headers["kp"] = _translate("SedimentLayers", "KP (m)")
|
self._dict["height"] = _translate("SedimentLayers", "Height (m)")
|
||||||
table_headers["sl"] = _translate("SedimentLayers", "Sediment layers")
|
|
||||||
|
self._sub_dict["table_headers"] = {
|
||||||
|
"name": _translate("SedimentLayers", "Name"),
|
||||||
|
"kp": _translate("SedimentLayers", "KP (m)"),
|
||||||
|
"sl": _translate("SedimentLayers", "Sediment layers"),
|
||||||
|
}
|
||||||
@@ -15,32 +15,12 @@ from PyQt5.QtWidgets import (
|
|||||||
QComboBox,
|
QComboBox,
|
||||||
)
|
)
|
||||||
|
|
||||||
|
from View.Tools.PamhyrTable import PamhyrTableModel
|
||||||
|
|
||||||
from View.SedimentLayers.UndoCommand import *
|
from View.SedimentLayers.UndoCommand import *
|
||||||
from View.SedimentLayers.translate import *
|
|
||||||
|
|
||||||
_translate = QCoreApplication.translate
|
|
||||||
|
|
||||||
|
|
||||||
class TableModel(QAbstractTableModel):
|
class TableModel(PamhyrTableModel):
|
||||||
def __init__(self, study=None, undo=None):
|
|
||||||
super(QAbstractTableModel, self).__init__()
|
|
||||||
self._headers = list(table_headers.keys())
|
|
||||||
self._study = study
|
|
||||||
self._undo = undo
|
|
||||||
self._sl = self._study.river.sediment_layers
|
|
||||||
|
|
||||||
def flags(self, index):
|
|
||||||
options = Qt.ItemIsEnabled | Qt.ItemIsSelectable
|
|
||||||
options |= Qt.ItemIsEditable
|
|
||||||
|
|
||||||
return options
|
|
||||||
|
|
||||||
def rowCount(self, parent):
|
|
||||||
return len(self._sl)
|
|
||||||
|
|
||||||
def columnCount(self, parent):
|
|
||||||
return len(self._headers)
|
|
||||||
|
|
||||||
def data(self, index, role):
|
def data(self, index, role):
|
||||||
if role != Qt.ItemDataRole.DisplayRole:
|
if role != Qt.ItemDataRole.DisplayRole:
|
||||||
return QVariant()
|
return QVariant()
|
||||||
@@ -49,15 +29,9 @@ class TableModel(QAbstractTableModel):
|
|||||||
column = index.column()
|
column = index.column()
|
||||||
|
|
||||||
if self._headers[column] == "name":
|
if self._headers[column] == "name":
|
||||||
return self._sl.get(row).name
|
return self._data.get(row).name
|
||||||
elif self._headers[column] == "comment":
|
elif self._headers[column] == "comment":
|
||||||
return self._sl.get(row).comment
|
return self._data.get(row).comment
|
||||||
|
|
||||||
return QVariant()
|
|
||||||
|
|
||||||
def headerData(self, friction, orientation, role):
|
|
||||||
if role == Qt.ItemDataRole.DisplayRole and orientation == Qt.Orientation.Horizontal:
|
|
||||||
return table_headers[self._headers[friction]]
|
|
||||||
|
|
||||||
return QVariant()
|
return QVariant()
|
||||||
|
|
||||||
@@ -71,13 +45,13 @@ class TableModel(QAbstractTableModel):
|
|||||||
if self._headers[column] == "name":
|
if self._headers[column] == "name":
|
||||||
self._undo.push(
|
self._undo.push(
|
||||||
SetNameCommand(
|
SetNameCommand(
|
||||||
self._sl, row, value
|
self._data, row, value
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
if self._headers[column] == "comment":
|
if self._headers[column] == "comment":
|
||||||
self._undo.push(
|
self._undo.push(
|
||||||
SetCommentCommand(
|
SetCommentCommand(
|
||||||
self._sl, row, value
|
self._data, row, value
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -89,7 +63,7 @@ class TableModel(QAbstractTableModel):
|
|||||||
|
|
||||||
self._undo.push(
|
self._undo.push(
|
||||||
AddCommand(
|
AddCommand(
|
||||||
self._sl, row
|
self._data, row
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -101,7 +75,7 @@ class TableModel(QAbstractTableModel):
|
|||||||
|
|
||||||
self._undo.push(
|
self._undo.push(
|
||||||
DelCommand(
|
DelCommand(
|
||||||
self._sl, rows
|
self._data, rows
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -118,7 +92,7 @@ class TableModel(QAbstractTableModel):
|
|||||||
|
|
||||||
self._undo_stack.push(
|
self._undo_stack.push(
|
||||||
MoveCommand(
|
MoveCommand(
|
||||||
self._sl, "up", row
|
self._data, "up", row
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -126,7 +100,7 @@ class TableModel(QAbstractTableModel):
|
|||||||
self.layoutChanged.emit()
|
self.layoutChanged.emit()
|
||||||
|
|
||||||
def move_down(self, index, parent=QModelIndex()):
|
def move_down(self, index, parent=QModelIndex()):
|
||||||
if row > len(self._sl):
|
if row > len(self._data):
|
||||||
return
|
return
|
||||||
|
|
||||||
target = row
|
target = row
|
||||||
@@ -135,7 +109,7 @@ class TableModel(QAbstractTableModel):
|
|||||||
|
|
||||||
self._undo_stack.push(
|
self._undo_stack.push(
|
||||||
MoveCommand(
|
MoveCommand(
|
||||||
self._sl, "down", row
|
self._data, "down", row
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|||||||
@@ -1,11 +1,26 @@
|
|||||||
|
# Window.py -- Pamhyr
|
||||||
|
# Copyright (C) 2023 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 -*-
|
# -*- coding: utf-8 -*-
|
||||||
|
|
||||||
import logging
|
import logging
|
||||||
|
|
||||||
from tools import trace, timer
|
from tools import trace, timer
|
||||||
|
|
||||||
from View.ASubWindow import ASubMainWindow
|
from View.Tools.PamhyrWindow import PamhyrWindow
|
||||||
from View.ListedSubWindow import ListedSubWindow
|
|
||||||
|
|
||||||
from PyQt5.QtGui import (
|
from PyQt5.QtGui import (
|
||||||
QKeySequence,
|
QKeySequence,
|
||||||
@@ -29,62 +44,53 @@ from View.SedimentLayers.Table import *
|
|||||||
|
|
||||||
from View.SedimentLayers.Edit.Plot import Plot
|
from View.SedimentLayers.Edit.Plot import Plot
|
||||||
|
|
||||||
from View.Plot.MplCanvas import MplCanvas
|
from View.Tools.Plot.PamhyrCanvas import MplCanvas
|
||||||
from View.SedimentLayers.translate import table_headers, retranslate
|
from View.SedimentLayers.translate import SedimentTranslate
|
||||||
|
|
||||||
from View.SedimentLayers.Edit.Window import EditSedimentLayersWindow
|
from View.SedimentLayers.Edit.Window import EditSedimentLayersWindow
|
||||||
|
|
||||||
_translate = QCoreApplication.translate
|
|
||||||
|
|
||||||
logger = logging.getLogger()
|
logger = logging.getLogger()
|
||||||
|
|
||||||
class SedimentLayersWindow(ASubMainWindow, ListedSubWindow):
|
class SedimentLayersWindow(PamhyrWindow):
|
||||||
def __init__(self, title="SedimentLayersList", study=None, parent=None):
|
_pamhyr_ui = "SedimentLayersList"
|
||||||
self._study = study
|
_pamhyr_name = "Sediment Layers List"
|
||||||
self._sediment_layers = self._study.river.sediment_layers
|
|
||||||
|
|
||||||
self.setup_title(title)
|
def __init__(self, study=None, config=None, parent=None):
|
||||||
|
self._sediment_layers = study.river.sediment_layers
|
||||||
|
|
||||||
|
name = (
|
||||||
|
self._pamhyr_name + " - " + study.name
|
||||||
|
)
|
||||||
|
|
||||||
super(SedimentLayersWindow, self).__init__(
|
super(SedimentLayersWindow, self).__init__(
|
||||||
name=self._title, ui="SedimentLayersList", parent=parent
|
title = name,
|
||||||
|
study = study,
|
||||||
|
config = config,
|
||||||
|
trad = SedimentTranslate(),
|
||||||
|
parent=parent
|
||||||
)
|
)
|
||||||
|
|
||||||
self.setup_sc()
|
|
||||||
self.setup_table()
|
self.setup_table()
|
||||||
self.setup_graph()
|
self.setup_plot()
|
||||||
self.setup_connections()
|
self.setup_connections()
|
||||||
|
|
||||||
self.ui.setWindowTitle(self._title)
|
|
||||||
|
|
||||||
def setup_title(self, title):
|
|
||||||
self._title = (
|
|
||||||
title + " - " + self._study.name
|
|
||||||
)
|
|
||||||
|
|
||||||
def setup_sc(self):
|
|
||||||
self._undo_stack = QUndoStack()
|
|
||||||
|
|
||||||
self.undo_sc = QShortcut(QKeySequence.Undo, self)
|
|
||||||
self.redo_sc = QShortcut(QKeySequence.Redo, self)
|
|
||||||
self.copy_sc = QShortcut(QKeySequence.Copy, self)
|
|
||||||
self.paste_sc = QShortcut(QKeySequence.Paste, self)
|
|
||||||
|
|
||||||
def setup_table(self):
|
def setup_table(self):
|
||||||
retranslate()
|
|
||||||
|
|
||||||
table = self.find(QTableView, f"tableView")
|
table = self.find(QTableView, f"tableView")
|
||||||
self._table = TableModel(
|
self._table = TableModel(
|
||||||
study = self._study,
|
table_view = table,
|
||||||
|
table_headers = self._trad.get_dict("table_headers"),
|
||||||
|
editable_headers = ["name", "comment"],
|
||||||
|
data = self._study.river.sediment_layers,
|
||||||
|
trad = self._trad,
|
||||||
undo = self._undo_stack,
|
undo = self._undo_stack,
|
||||||
)
|
)
|
||||||
table.setModel(self._table)
|
table.setModel(self._table)
|
||||||
|
|
||||||
table.setSelectionBehavior(QAbstractItemView.SelectRows)
|
table.setSelectionBehavior(QAbstractItemView.SelectRows)
|
||||||
table.horizontalHeader().setSectionResizeMode(QHeaderView.Stretch)
|
table.horizontalHeader().setSectionResizeMode(QHeaderView.Stretch)
|
||||||
table.setAlternatingRowColors(True)
|
table.setAlternatingRowColors(True)
|
||||||
|
|
||||||
def setup_graph(self):
|
def setup_plot(self):
|
||||||
self.canvas = MplCanvas(width=5, height=4, dpi=100)
|
self.canvas = MplCanvas(width=2, height=4, dpi=100)
|
||||||
self.canvas.setObjectName("canvas")
|
self.canvas.setObjectName("canvas")
|
||||||
self.plot_layout = self.find(QVBoxLayout, "verticalLayout")
|
self.plot_layout = self.find(QVBoxLayout, "verticalLayout")
|
||||||
self.plot_layout.addWidget(self.canvas)
|
self.plot_layout.addWidget(self.canvas)
|
||||||
@@ -94,11 +100,6 @@ class SedimentLayersWindow(ASubMainWindow, ListedSubWindow):
|
|||||||
self.find(QAction, "action_del").triggered.connect(self.delete)
|
self.find(QAction, "action_del").triggered.connect(self.delete)
|
||||||
self.find(QAction, "action_edit").triggered.connect(self.edit_sediment_layers)
|
self.find(QAction, "action_edit").triggered.connect(self.edit_sediment_layers)
|
||||||
|
|
||||||
self.undo_sc.activated.connect(self.undo)
|
|
||||||
self.redo_sc.activated.connect(self.redo)
|
|
||||||
self.copy_sc.activated.connect(self.copy)
|
|
||||||
self.paste_sc.activated.connect(self.paste)
|
|
||||||
|
|
||||||
table = self.find(QTableView, f"tableView")
|
table = self.find(QTableView, f"tableView")
|
||||||
table.selectionModel()\
|
table.selectionModel()\
|
||||||
.selectionChanged\
|
.selectionChanged\
|
||||||
@@ -116,6 +117,7 @@ class SedimentLayersWindow(ASubMainWindow, ListedSubWindow):
|
|||||||
self.plot = Plot(
|
self.plot = Plot(
|
||||||
canvas = self.canvas,
|
canvas = self.canvas,
|
||||||
data = self._sediment_layers.get(rows[0]),
|
data = self._sediment_layers.get(rows[0]),
|
||||||
|
trad = self._trad,
|
||||||
toolbar = None,
|
toolbar = None,
|
||||||
display_current = False
|
display_current = False
|
||||||
)
|
)
|
||||||
@@ -148,16 +150,16 @@ class SedimentLayersWindow(ASubMainWindow, ListedSubWindow):
|
|||||||
|
|
||||||
self._table.delete(rows)
|
self._table.delete(rows)
|
||||||
|
|
||||||
def copy(self):
|
def _copy(self):
|
||||||
logger.info("TODO: copy")
|
logger.info("TODO: copy")
|
||||||
|
|
||||||
def paste(self):
|
def _paste(self):
|
||||||
logger.info("TODO: paste")
|
logger.info("TODO: paste")
|
||||||
|
|
||||||
def undo(self):
|
def _undo(self):
|
||||||
self._table.undo()
|
self._table.undo()
|
||||||
|
|
||||||
def redo(self):
|
def _redo(self):
|
||||||
self._table.redo()
|
self._table.redo()
|
||||||
|
|
||||||
def edit_sediment_layers(self):
|
def edit_sediment_layers(self):
|
||||||
|
|||||||
@@ -2,13 +2,15 @@
|
|||||||
|
|
||||||
from PyQt5.QtCore import QCoreApplication
|
from PyQt5.QtCore import QCoreApplication
|
||||||
|
|
||||||
|
from View.Tools.PamhyrTranslate import PamhyrTranslate
|
||||||
|
|
||||||
_translate = QCoreApplication.translate
|
_translate = QCoreApplication.translate
|
||||||
|
|
||||||
table_headers = {
|
class SedimentTranslate(PamhyrTranslate):
|
||||||
"name": _translate("SedimentLayers", "Name"),
|
def __init__(self):
|
||||||
"comment": _translate("SedimentLayers", "Comment"),
|
super(SedimentTranslate, self).__init__()
|
||||||
}
|
|
||||||
|
|
||||||
def retranslate():
|
self._sub_dict["table_headers"] = {
|
||||||
table_headers["name"] = _translate("SedimentLayers", "Name")
|
"name": _translate("SedimentLayers", "Name"),
|
||||||
table_headers["comment"] = _translate("SedimentLayers", "Comment")
|
"comment": _translate("SedimentLayers", "Comment"),
|
||||||
|
}
|
||||||
@@ -34,37 +34,20 @@ from PyQt5.QtWidgets import (
|
|||||||
QComboBox,
|
QComboBox,
|
||||||
)
|
)
|
||||||
|
|
||||||
|
from View.Tools.PamhyrTable import PamhyrTableModel
|
||||||
|
|
||||||
from View.SolverParameters.UndoCommand import *
|
from View.SolverParameters.UndoCommand import *
|
||||||
from View.SolverParameters import translate as tr
|
|
||||||
|
|
||||||
from Solver.Solvers import solver_long_name, solver_type_list
|
from Solver.Solvers import solver_long_name, solver_type_list
|
||||||
|
|
||||||
|
logger = logging.getLogger()
|
||||||
|
|
||||||
_translate = QCoreApplication.translate
|
_translate = QCoreApplication.translate
|
||||||
|
|
||||||
class TableModel(QAbstractTableModel):
|
class TableModel(PamhyrTableModel):
|
||||||
def __init__(self, data=None, undo=None, tab=""):
|
def _setup_lst(self):
|
||||||
super(QAbstractTableModel, self).__init__()
|
self._tab = self._opt_data
|
||||||
self._headers = list(tr.table_headers.keys())
|
self._lst = self._data.get_params(self._tab)
|
||||||
self._data = data
|
|
||||||
self._undo = undo
|
|
||||||
self._tab = tab
|
|
||||||
self._params = self._data.get_params(self._tab)
|
|
||||||
|
|
||||||
def flags(self, index):
|
|
||||||
options = Qt.ItemIsEnabled | Qt.ItemIsSelectable
|
|
||||||
|
|
||||||
column = index.column()
|
|
||||||
|
|
||||||
if self._headers[column] == "value":
|
|
||||||
options |= Qt.ItemIsEditable
|
|
||||||
|
|
||||||
return options
|
|
||||||
|
|
||||||
def rowCount(self, parent):
|
|
||||||
return len(self._params)
|
|
||||||
|
|
||||||
def columnCount(self, parent):
|
|
||||||
return len(self._headers)
|
|
||||||
|
|
||||||
def data(self, index, role):
|
def data(self, index, role):
|
||||||
if role != Qt.ItemDataRole.DisplayRole:
|
if role != Qt.ItemDataRole.DisplayRole:
|
||||||
@@ -75,24 +58,18 @@ class TableModel(QAbstractTableModel):
|
|||||||
cname = self._headers[column]
|
cname = self._headers[column]
|
||||||
|
|
||||||
if cname == "name":
|
if cname == "name":
|
||||||
value = self._params.get(row)[cname]
|
value = self._lst.get(row)[cname]
|
||||||
if value in tr.names:
|
if value in self._trad.get_dict("names"):
|
||||||
value = tr.names[value]
|
value = self._trad.get_dict("names")[value]
|
||||||
return value
|
return value
|
||||||
elif cname == "value":
|
elif cname == "value":
|
||||||
value = self._params.get(row)[cname]
|
value = self._lst.get(row)[cname]
|
||||||
if value in tr.yes_no:
|
if value in self._trad.get_dict("yes_no"):
|
||||||
value = tr.yes_no[value]
|
value = self._trad.get_dict("yes_no")[value]
|
||||||
return value
|
return value
|
||||||
|
|
||||||
return QVariant()
|
return QVariant()
|
||||||
|
|
||||||
def headerData(self, section, orientation, role):
|
|
||||||
if role == Qt.ItemDataRole.DisplayRole and orientation == Qt.Orientation.Horizontal:
|
|
||||||
return tr.table_headers[self._headers[section]]
|
|
||||||
|
|
||||||
return QVariant()
|
|
||||||
|
|
||||||
def setData(self, index, value, role=Qt.EditRole):
|
def setData(self, index, value, role=Qt.EditRole):
|
||||||
if not index.isValid() or role != Qt.EditRole:
|
if not index.isValid() or role != Qt.EditRole:
|
||||||
return False
|
return False
|
||||||
@@ -102,12 +79,12 @@ class TableModel(QAbstractTableModel):
|
|||||||
|
|
||||||
try:
|
try:
|
||||||
if self._headers[column] == "value":
|
if self._headers[column] == "value":
|
||||||
if value in tr.r_yes_no:
|
if value in self._trad.get_dict("r_yes_no"):
|
||||||
value = tr.r_yes_no[value].lower()
|
value = self._trad.get_dict("r_yes_no")[value].lower()
|
||||||
|
|
||||||
self._undo.push(
|
self._undo.push(
|
||||||
SetCommand(
|
SetCommand(
|
||||||
self._params, row,
|
self._lst, row,
|
||||||
"value", value
|
"value", value
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
@@ -123,7 +100,7 @@ class TableModel(QAbstractTableModel):
|
|||||||
|
|
||||||
# self._undo.push(
|
# self._undo.push(
|
||||||
# AddCommand(
|
# AddCommand(
|
||||||
# self._params, row
|
# self._lst, row
|
||||||
# )
|
# )
|
||||||
# )
|
# )
|
||||||
|
|
||||||
@@ -135,7 +112,7 @@ class TableModel(QAbstractTableModel):
|
|||||||
|
|
||||||
# self._undo.push(
|
# self._undo.push(
|
||||||
# DelCommand(
|
# DelCommand(
|
||||||
# self._params, rows
|
# self._lst, rows
|
||||||
# )
|
# )
|
||||||
# )
|
# )
|
||||||
|
|
||||||
@@ -147,7 +124,7 @@ class TableModel(QAbstractTableModel):
|
|||||||
|
|
||||||
# self._undo.push(
|
# self._undo.push(
|
||||||
# SortCommand(
|
# SortCommand(
|
||||||
# self._params, False
|
# self._lst, False
|
||||||
# )
|
# )
|
||||||
# )
|
# )
|
||||||
|
|
||||||
@@ -164,7 +141,7 @@ class TableModel(QAbstractTableModel):
|
|||||||
|
|
||||||
# self._undo_stack.push(
|
# self._undo_stack.push(
|
||||||
# MoveCommand(
|
# MoveCommand(
|
||||||
# self._params, "up", row
|
# self._lst, "up", row
|
||||||
# )
|
# )
|
||||||
# )
|
# )
|
||||||
|
|
||||||
@@ -172,7 +149,7 @@ class TableModel(QAbstractTableModel):
|
|||||||
# self.layoutChanged.emit()
|
# self.layoutChanged.emit()
|
||||||
|
|
||||||
# def move_down(self, index, parent=QModelIndex()):
|
# def move_down(self, index, parent=QModelIndex()):
|
||||||
# if row > len(self._params):
|
# if row > len(self._lst):
|
||||||
# return
|
# return
|
||||||
|
|
||||||
# target = row
|
# target = row
|
||||||
@@ -181,7 +158,7 @@ class TableModel(QAbstractTableModel):
|
|||||||
|
|
||||||
# self._undo_stack.push(
|
# self._undo_stack.push(
|
||||||
# MoveCommand(
|
# MoveCommand(
|
||||||
# self._params, "down", row
|
# self._lst, "down", row
|
||||||
# )
|
# )
|
||||||
# )
|
# )
|
||||||
|
|
||||||
|
|||||||
@@ -20,8 +20,7 @@ import logging
|
|||||||
|
|
||||||
from tools import trace, timer
|
from tools import trace, timer
|
||||||
|
|
||||||
from View.ASubWindow import ASubMainWindow
|
from View.Tools.PamhyrWindow import PamhyrWindow
|
||||||
from View.ListedSubWindow import ListedSubWindow
|
|
||||||
|
|
||||||
from PyQt5.QtGui import (
|
from PyQt5.QtGui import (
|
||||||
QKeySequence,
|
QKeySequence,
|
||||||
@@ -43,7 +42,7 @@ from PyQt5.QtWidgets import (
|
|||||||
|
|
||||||
from View.SolverParameters.UndoCommand import *
|
from View.SolverParameters.UndoCommand import *
|
||||||
from View.SolverParameters.Table import TableModel
|
from View.SolverParameters.Table import TableModel
|
||||||
from View.SolverParameters import translate as tr
|
from View.SolverParameters.translate import ParamTranslate
|
||||||
|
|
||||||
from Solver.Solvers import solver_long_name, solver_type_list
|
from Solver.Solvers import solver_long_name, solver_type_list
|
||||||
|
|
||||||
@@ -51,25 +50,25 @@ _translate = QCoreApplication.translate
|
|||||||
|
|
||||||
logger = logging.getLogger()
|
logger = logging.getLogger()
|
||||||
|
|
||||||
class SolverParametersWindow(ASubMainWindow, ListedSubWindow):
|
class SolverParametersWindow(PamhyrWindow):
|
||||||
def __init__(self, title="Solver parameters", study=None, parent=None):
|
_pamhyr_ui = "SolverParameters"
|
||||||
# Init tanslate dictionary
|
_pamhyr_name = "Solver parameters"
|
||||||
tr.init()
|
|
||||||
|
|
||||||
self._title = title + " - " + study.name
|
|
||||||
|
|
||||||
|
def __init__(self, study=None, config=None, parent=None):
|
||||||
|
name = self._pamhyr_name + " - " + study.name
|
||||||
super(SolverParametersWindow, self).__init__(
|
super(SolverParametersWindow, self).__init__(
|
||||||
name=title, ui="SolverParameters", parent=parent
|
title = name,
|
||||||
|
study = study,
|
||||||
|
config = config,
|
||||||
|
options = ['copy'],
|
||||||
|
trad = ParamTranslate(),
|
||||||
|
parent = parent
|
||||||
)
|
)
|
||||||
|
|
||||||
self._study = study
|
|
||||||
self._params = self._study.river.parameters
|
self._params = self._study.river.parameters
|
||||||
|
|
||||||
self.setup_sc()
|
self.setup_sc()
|
||||||
self.setup_table()
|
self.setup_table()
|
||||||
self.setup_connections()
|
|
||||||
|
|
||||||
self.ui.setWindowTitle(self._title)
|
|
||||||
|
|
||||||
def setup_sc(self):
|
def setup_sc(self):
|
||||||
self._undo_stack = {}
|
self._undo_stack = {}
|
||||||
@@ -77,10 +76,10 @@ class SolverParametersWindow(ASubMainWindow, ListedSubWindow):
|
|||||||
for st in solver_type_list:
|
for st in solver_type_list:
|
||||||
self._undo_stack[st] = QUndoStack()
|
self._undo_stack[st] = QUndoStack()
|
||||||
|
|
||||||
self.undo_sc = QShortcut(QKeySequence.Undo, self)
|
self._undo_sc = QShortcut(QKeySequence.Undo, self)
|
||||||
self.redo_sc = QShortcut(QKeySequence.Redo, self)
|
self._redo_sc = QShortcut(QKeySequence.Redo, self)
|
||||||
self.copy_sc = QShortcut(QKeySequence.Copy, self)
|
self._undo_sc.activated.connect(self._undo)
|
||||||
self.paste_sc = QShortcut(QKeySequence.Paste, self)
|
self._redo_sc.activated.connect(self._redo)
|
||||||
|
|
||||||
def setup_table(self):
|
def setup_table(self):
|
||||||
self._table = {}
|
self._table = {}
|
||||||
@@ -97,9 +96,13 @@ class SolverParametersWindow(ASubMainWindow, ListedSubWindow):
|
|||||||
|
|
||||||
# Create table model
|
# Create table model
|
||||||
self._table[st] = TableModel(
|
self._table[st] = TableModel(
|
||||||
|
table_view = table,
|
||||||
data = self._study.river,
|
data = self._study.river,
|
||||||
|
opt_data = st,
|
||||||
|
table_headers = self._trad.get_dict("table_headers"),
|
||||||
|
editable_headers = ["value"],
|
||||||
|
trad = self._trad,
|
||||||
undo = self._undo_stack[st],
|
undo = self._undo_stack[st],
|
||||||
tab = st,
|
|
||||||
)
|
)
|
||||||
|
|
||||||
table.setModel(self._table[st])
|
table.setModel(self._table[st])
|
||||||
@@ -115,31 +118,24 @@ class SolverParametersWindow(ASubMainWindow, ListedSubWindow):
|
|||||||
# Create tab
|
# Create tab
|
||||||
self._tab_widget.addTab(widget, f"{solver_long_name[st]}")
|
self._tab_widget.addTab(widget, f"{solver_long_name[st]}")
|
||||||
|
|
||||||
|
|
||||||
def setup_connections(self):
|
|
||||||
self.undo_sc.activated.connect(self.undo)
|
|
||||||
self.redo_sc.activated.connect(self.redo)
|
|
||||||
self.copy_sc.activated.connect(self.copy)
|
|
||||||
self.paste_sc.activated.connect(self.paste)
|
|
||||||
|
|
||||||
def current_tab(self):
|
def current_tab(self):
|
||||||
return self.find(QTabWidget, "tabWidget")\
|
return self.find(QTabWidget, "tabWidget")\
|
||||||
.currentWidget()\
|
.currentWidget()\
|
||||||
.objectName()\
|
.objectName()\
|
||||||
.replace("tab_", "")
|
.replace("tab_", "")
|
||||||
|
|
||||||
def undo(self):
|
def _undo(self):
|
||||||
tab = self.current_tab()
|
tab = self.current_tab()
|
||||||
self._table[tab].undo()
|
self._table[tab].undo()
|
||||||
self._set_current_reach()
|
self._set_current_reach()
|
||||||
|
|
||||||
def redo(self):
|
def _redo(self):
|
||||||
tab = self.current_tab()
|
tab = self.current_tab()
|
||||||
self._table[tab].redo()
|
self._table[tab].redo()
|
||||||
self._set_current_reach()
|
self._set_current_reach()
|
||||||
|
|
||||||
def copy(self):
|
def _copy(self):
|
||||||
logger.info("TODO: copy")
|
logger.info("TODO: copy")
|
||||||
|
|
||||||
def paste(self):
|
def _paste(self):
|
||||||
logger.info("TODO: paste")
|
logger.info("TODO: paste")
|
||||||
@@ -18,66 +18,60 @@
|
|||||||
|
|
||||||
from PyQt5.QtCore import QCoreApplication
|
from PyQt5.QtCore import QCoreApplication
|
||||||
|
|
||||||
|
from View.Tools.PamhyrTranslate import PamhyrTranslate
|
||||||
|
|
||||||
_translate = QCoreApplication.translate
|
_translate = QCoreApplication.translate
|
||||||
|
|
||||||
table_headers = None
|
class ParamTranslate(PamhyrTranslate):
|
||||||
yes_no = None
|
def __init__(self):
|
||||||
r_yes_no = None
|
super(ParamTranslate, self).__init__()
|
||||||
names = None
|
|
||||||
|
|
||||||
def init():
|
self._sub_dict["table_headers"] = {
|
||||||
global table_headers
|
"name": _translate("SolverParameters", "Name"),
|
||||||
table_headers = {
|
"value": _translate("SolverParameters", "Value")
|
||||||
"name": _translate("SolverParameters", "Name"),
|
}
|
||||||
"value": _translate("SolverParameters", "Value")
|
|
||||||
}
|
|
||||||
|
|
||||||
# Used to translate user parameter with value yes or no
|
self._sub_dict["yes_no"] = {
|
||||||
global yes_no
|
"yes": _translate("SolverParameters", "Yes"),
|
||||||
yes_no = {
|
"no": _translate("SolverParameters", "No"),
|
||||||
"yes": _translate("SolverParameters", "Yes"),
|
"y": _translate("SolverParameters", "Y"),
|
||||||
"no": _translate("SolverParameters", "No"),
|
"n": _translate("SolverParameters", "N"),
|
||||||
"y": _translate("SolverParameters", "Y"),
|
}
|
||||||
"n": _translate("SolverParameters", "N"),
|
|
||||||
}
|
|
||||||
|
|
||||||
# Reverse
|
self._sub_dict["r_yes_no"] = {
|
||||||
global r_yes_no
|
_translate("SolverParameters", "Yes"): "yes",
|
||||||
r_yes_no = {
|
_translate("SolverParameters", "No"): "no",
|
||||||
_translate("SolverParameters", "Yes"): "yes",
|
_translate("SolverParameters", "Y"): "y",
|
||||||
_translate("SolverParameters", "No"): "no",
|
_translate("SolverParameters", "N"): "n",
|
||||||
_translate("SolverParameters", "Y"): "y",
|
}
|
||||||
_translate("SolverParameters", "N"): "n",
|
|
||||||
}
|
|
||||||
|
|
||||||
global names
|
self._sub_dict["names"] = {
|
||||||
names = {
|
"all_init_time": _translate("SolverParameters", "Initial time (jj:hh:mm:ss)"),
|
||||||
"all_init_time": _translate("SolverParameters", "Initial time (jj:hh:mm:ss)"),
|
"all_final_time": _translate("SolverParameters", "Final time (jj:hh:mm:ss)"),
|
||||||
"all_final_time": _translate("SolverParameters", "Final time (jj:hh:mm:ss)"),
|
"all_timestep": _translate("SolverParameters", "Timestep (second)"),
|
||||||
"all_timestep": _translate("SolverParameters", "Timestep (second)"),
|
"all_command_line_arguments": _translate("SolverParameters", "Command line arguments"),
|
||||||
"all_command_line_arguments": _translate("SolverParameters", "Command line arguments"),
|
# Mage specific parameters
|
||||||
# Mage specific parameters
|
"mage_min_timestep": _translate("SolverParameters", "Minimum timestep (second)"),
|
||||||
"mage_min_timestep": _translate("SolverParameters", "Minimum timestep (second)"),
|
"mage_timestep_tra": _translate("SolverParameters", "Time step of writing on .TRA"),
|
||||||
"mage_timestep_tra": _translate("SolverParameters", "Time step of writing on .TRA"),
|
"mage_timestep_bin": _translate("SolverParameters", "Time step of writing on .BIN"),
|
||||||
"mage_timestep_bin": _translate("SolverParameters", "Time step of writing on .BIN"),
|
"mage_implicitation": _translate("SolverParameters", "Implicitation parameter"),
|
||||||
"mage_implicitation": _translate("SolverParameters", "Implicitation parameter"),
|
"mage_continuity_discretization": _translate("SolverParameters", "Continuity discretization type (S/L)"),
|
||||||
"mage_continuity_discretization": _translate("SolverParameters", "Continuity discretization type (S/L)"),
|
"mage_qsj_discretization": _translate("SolverParameters", "QSJ discretization (A/B)"),
|
||||||
"mage_qsj_discretization": _translate("SolverParameters", "QSJ discretization (A/B)"),
|
"mage_stop_criterion_iterations": _translate("SolverParameters", "Stop criterion iterations (G/A/R)"),
|
||||||
"mage_stop_criterion_iterations": _translate("SolverParameters", "Stop criterion iterations (G/A/R)"),
|
"mage_iteration_type": _translate("SolverParameters", "Iteration type"),
|
||||||
"mage_iteration_type": _translate("SolverParameters", "Iteration type"),
|
"mage_smooth_coef": _translate("SolverParameters", "Smoothing coefficient"),
|
||||||
"mage_smooth_coef": _translate("SolverParameters", "Smoothing coefficient"),
|
"mage_cfl_max": _translate("SolverParameters", "Maximun accepted number of CFL"),
|
||||||
"mage_cfl_max": _translate("SolverParameters", "Maximun accepted number of CFL"),
|
"mage_min_height": _translate("SolverParameters", "Minimum water height (meter)"),
|
||||||
"mage_min_height": _translate("SolverParameters", "Minimum water height (meter)"),
|
"mage_max_niter": _translate("SolverParameters", "Maximun number of iterations (< 100)"),
|
||||||
"mage_max_niter": _translate("SolverParameters", "Maximun number of iterations (< 100)"),
|
"mage_timestep_reduction_factor": _translate("SolverParameters", "Timestep reduction factor"),
|
||||||
"mage_timestep_reduction_factor": _translate("SolverParameters", "Timestep reduction factor"),
|
"mage_precision_reduction_factor_Z": _translate("SolverParameters", "Reduction precision factor of Z"),
|
||||||
"mage_precision_reduction_factor_Z": _translate("SolverParameters", "Reduction precision factor of Z"),
|
"mage_precision_reduction_factor_Q": _translate("SolverParameters", "Reduction precision factor of Q"),
|
||||||
"mage_precision_reduction_factor_Q": _translate("SolverParameters", "Reduction precision factor of Q"),
|
"mage_precision_reduction_factor_r": _translate("SolverParameters", "Reduction precision factor of residue"),
|
||||||
"mage_precision_reduction_factor_r": _translate("SolverParameters", "Reduction precision factor of residue"),
|
"mage_niter_max_precision": _translate("SolverParameters", "Number of iteration at maximum precision"),
|
||||||
"mage_niter_max_precision": _translate("SolverParameters", "Number of iteration at maximum precision"),
|
"mage_niter_before_switch": _translate("SolverParameters", "Number of iteration before switch"),
|
||||||
"mage_niter_before_switch": _translate("SolverParameters", "Number of iteration before switch"),
|
"mage_max_froude": _translate("SolverParameters", "Maximum accepted Froude number"),
|
||||||
"mage_max_froude": _translate("SolverParameters", "Maximum accepted Froude number"),
|
"mage_diffluence_node_height_balance": _translate("SolverParameters", "Diffluence node height balance"),
|
||||||
"mage_diffluence_node_height_balance": _translate("SolverParameters", "Diffluence node height balance"),
|
"mage_compute_reach_volume_balance": _translate("SolverParameters", "Compute reach volume balance (Y/N)"),
|
||||||
"mage_compute_reach_volume_balance": _translate("SolverParameters", "Compute reach volume balance (Y/N)"),
|
"mage_max_reach_volume_balance": _translate("SolverParameters", "Maximum reach volume balance"),
|
||||||
"mage_max_reach_volume_balance": _translate("SolverParameters", "Maximum reach volume balance"),
|
"mage_min_reach_volume_to_check": _translate("SolverParameters", "Minimum reach volume to check"),
|
||||||
"mage_min_reach_volume_to_check": _translate("SolverParameters", "Minimum reach volume to check"),
|
}
|
||||||
}
|
|
||||||
@@ -20,8 +20,7 @@ import logging
|
|||||||
|
|
||||||
from tools import trace, timer
|
from tools import trace, timer
|
||||||
|
|
||||||
from View.ASubWindow import ASubMainWindow
|
from View.Tools.PamhyrWindow import PamhyrWindow
|
||||||
from View.ListedSubWindow import ListedSubWindow
|
|
||||||
|
|
||||||
from PyQt5.QtGui import (
|
from PyQt5.QtGui import (
|
||||||
QKeySequence,
|
QKeySequence,
|
||||||
@@ -44,40 +43,31 @@ from Model.Stricklers.Stricklers import Stricklers
|
|||||||
|
|
||||||
from View.Stricklers.UndoCommand import PasteCommand
|
from View.Stricklers.UndoCommand import PasteCommand
|
||||||
from View.Stricklers.Table import TableModel
|
from View.Stricklers.Table import TableModel
|
||||||
from View.Stricklers.translate import table_headers, retranslate
|
from View.Stricklers.translate import StricklersTranslate
|
||||||
|
|
||||||
_translate = QCoreApplication.translate
|
_translate = QCoreApplication.translate
|
||||||
|
|
||||||
logger = logging.getLogger()
|
logger = logging.getLogger()
|
||||||
|
|
||||||
class StricklersWindow(ASubMainWindow, ListedSubWindow):
|
class StricklersWindow(PamhyrWindow):
|
||||||
def __init__(self, title="Stricklers", study=None, config=None, parent=None):
|
_pamhyr_ui = "Stricklers"
|
||||||
self._title = title + " - " + study.name
|
_pamhyr_name = "Stricklers"
|
||||||
|
|
||||||
|
def __init__(self, study=None, config=None, parent=None):
|
||||||
|
name = self._pamhyr_name + " - " + study.name
|
||||||
|
|
||||||
super(StricklersWindow, self).__init__(
|
super(StricklersWindow, self).__init__(
|
||||||
name=title, ui="Stricklers", parent=parent
|
title = name,
|
||||||
|
study = study,
|
||||||
|
config = config,
|
||||||
|
trad = StricklersTranslate(),
|
||||||
|
parent = parent
|
||||||
)
|
)
|
||||||
|
|
||||||
self._study = study
|
|
||||||
self._config = config
|
|
||||||
|
|
||||||
self.setup_sc()
|
|
||||||
self.setup_table()
|
self.setup_table()
|
||||||
self.setup_connections()
|
self.setup_connections()
|
||||||
|
|
||||||
self.ui.setWindowTitle(self._title)
|
|
||||||
|
|
||||||
def setup_sc(self):
|
|
||||||
self._undo_stack = QUndoStack()
|
|
||||||
|
|
||||||
self.undo_sc = QShortcut(QKeySequence.Undo, self)
|
|
||||||
self.redo_sc = QShortcut(QKeySequence.Redo, self)
|
|
||||||
self.copy_sc = QShortcut(QKeySequence.Copy, self)
|
|
||||||
self.paste_sc = QShortcut(QKeySequence.Paste, self)
|
|
||||||
|
|
||||||
|
|
||||||
def setup_table(self):
|
def setup_table(self):
|
||||||
retranslate()
|
|
||||||
self._table = {}
|
self._table = {}
|
||||||
|
|
||||||
for t in ["app", "study"]:
|
for t in ["app", "study"]:
|
||||||
@@ -89,7 +79,7 @@ class StricklersWindow(ASubMainWindow, ListedSubWindow):
|
|||||||
|
|
||||||
self._table[t] = TableModel(
|
self._table[t] = TableModel(
|
||||||
table_view = table,
|
table_view = table,
|
||||||
table_headers = table_headers,
|
table_headers = self._trad.get_dict("table_headers"),
|
||||||
editable_headers = ["name", "comment", "minor", "medium"],
|
editable_headers = ["name", "comment", "minor", "medium"],
|
||||||
data = data,
|
data = data,
|
||||||
undo = self._undo_stack,
|
undo = self._undo_stack,
|
||||||
@@ -105,11 +95,6 @@ class StricklersWindow(ASubMainWindow, ListedSubWindow):
|
|||||||
self.find(QAction, "action_del").triggered.connect(self.delete)
|
self.find(QAction, "action_del").triggered.connect(self.delete)
|
||||||
self.find(QAction, "action_sort").triggered.connect(self.sort)
|
self.find(QAction, "action_sort").triggered.connect(self.sort)
|
||||||
|
|
||||||
self.undo_sc.activated.connect(self.undo)
|
|
||||||
self.redo_sc.activated.connect(self.redo)
|
|
||||||
self.copy_sc.activated.connect(self.copy)
|
|
||||||
self.paste_sc.activated.connect(self.paste)
|
|
||||||
|
|
||||||
def index_selected_rows(self):
|
def index_selected_rows(self):
|
||||||
table = self.find(QTableView, f"tableView_study")
|
table = self.find(QTableView, f"tableView_study")
|
||||||
return list(
|
return list(
|
||||||
@@ -139,14 +124,14 @@ class StricklersWindow(ASubMainWindow, ListedSubWindow):
|
|||||||
def sort(self):
|
def sort(self):
|
||||||
self._table['study'].sort(False)
|
self._table['study'].sort(False)
|
||||||
|
|
||||||
def copy(self):
|
def _copy(self):
|
||||||
logger.info("TODO: copy")
|
logger.info("TODO: copy")
|
||||||
|
|
||||||
def paste(self):
|
def _paste(self):
|
||||||
logger.info("TODO: paste")
|
logger.info("TODO: paste")
|
||||||
|
|
||||||
def undo(self):
|
def _undo(self):
|
||||||
self._table['study'].undo()
|
self._table['study'].undo()
|
||||||
|
|
||||||
def redo(self):
|
def _redo(self):
|
||||||
self._table['study'].redo()
|
self._table['study'].redo()
|
||||||
@@ -18,21 +18,18 @@
|
|||||||
|
|
||||||
from PyQt5.QtCore import QCoreApplication
|
from PyQt5.QtCore import QCoreApplication
|
||||||
|
|
||||||
from Model.LateralContribution.LateralContributionTypes import (
|
from View.Tools.PamhyrTranslate import PamhyrTranslate
|
||||||
NotDefined, LateralContrib, Rain, Evaporation,
|
|
||||||
)
|
|
||||||
|
|
||||||
_translate = QCoreApplication.translate
|
_translate = QCoreApplication.translate
|
||||||
|
|
||||||
table_headers = {
|
|
||||||
"name": _translate("LateralContribution", "Name"),
|
|
||||||
"minor": _translate("LateralContribution", "Minor bed"),
|
|
||||||
"medium": _translate("LateralContribution", "Medium bed"),
|
|
||||||
"comment": _translate("LateralContribution", "Comment"),
|
|
||||||
}
|
|
||||||
|
|
||||||
def retranslate():
|
class StricklersTranslate(PamhyrTranslate):
|
||||||
table_headers["name"] = _translate("LateralContribution", "Name")
|
def __init__(self):
|
||||||
table_headers["minor"] = _translate("LateralContribution", "Minor bed")
|
super(StricklersTranslate, self).__init__()
|
||||||
table_headers["medium"] = _translate("LateralContribution", "Medium bed")
|
|
||||||
table_headers["comment"] = _translate("LateralContribution", "Comment")
|
self._sub_dict["table_headers"] = {
|
||||||
|
"name": _translate("LateralContribution", "Name"),
|
||||||
|
"minor": _translate("LateralContribution", "Minor bed"),
|
||||||
|
"medium": _translate("LateralContribution", "Medium bed"),
|
||||||
|
"comment": _translate("LateralContribution", "Comment"),
|
||||||
|
}
|
||||||
+29
-19
@@ -17,7 +17,7 @@
|
|||||||
# -*- coding: utf-8 -*-
|
# -*- coding: utf-8 -*-
|
||||||
|
|
||||||
from Model.Study import Study
|
from Model.Study import Study
|
||||||
from View.ASubWindow import ASubWindow
|
from View.Tools.PamhyrWindow import PamhyrDialog
|
||||||
|
|
||||||
from PyQt5.QtCore import QCoreApplication
|
from PyQt5.QtCore import QCoreApplication
|
||||||
|
|
||||||
@@ -27,27 +27,37 @@ from PyQt5.QtWidgets import (
|
|||||||
|
|
||||||
_translate = QCoreApplication.translate
|
_translate = QCoreApplication.translate
|
||||||
|
|
||||||
class NewStudyWindow(ASubWindow):
|
class NewStudyWindow(PamhyrDialog):
|
||||||
def __init__(self, study=None, title="New Study", parent=None):
|
_pamhyr_ui = "NewStudy"
|
||||||
super(NewStudyWindow, self).__init__(name=title, ui="NewStudy", parent=parent)
|
_pamhyr_name = "Edit/New Study"
|
||||||
self.ui.setWindowTitle(title)
|
|
||||||
|
|
||||||
self.parent = parent
|
def __init__(self, study=None, config = None, parent=None):
|
||||||
self.study = study
|
if study is not None:
|
||||||
|
name = f"Edit study - {study.name}"
|
||||||
|
else:
|
||||||
|
name = "New study"
|
||||||
|
|
||||||
if not self.study is None:
|
super(NewStudyWindow, self).__init__(
|
||||||
self.set_line_edit_text("lineEdit_name", self.study.name)
|
title = name,
|
||||||
self.set_text_edit_text("textEdit_description", self.study.description)
|
study = study,
|
||||||
self.set_datetime_edit("dateTimeEdit_date", self.study.date)
|
config = config,
|
||||||
|
options = [],
|
||||||
|
parent = parent
|
||||||
|
)
|
||||||
|
|
||||||
|
if not self._study is None:
|
||||||
|
self.set_line_edit_text("lineEdit_name", self._study.name)
|
||||||
|
self.set_text_edit_text("textEdit_description", self._study.description)
|
||||||
|
self.set_datetime_edit("dateTimeEdit_date", self._study.date)
|
||||||
|
|
||||||
self.find(QLabel, "label_creation_date_data").setText(
|
self.find(QLabel, "label_creation_date_data").setText(
|
||||||
self.study.creation_date.isoformat(sep=" ")
|
self._study.creation_date.isoformat(sep=" ")
|
||||||
)
|
)
|
||||||
self.find(QLabel, "label_last_modification_data").setText(
|
self.find(QLabel, "label_last_modification_data").setText(
|
||||||
self.study.last_save_date.isoformat(sep=" ")
|
self._study.last_save_date.isoformat(sep=" ")
|
||||||
)
|
)
|
||||||
|
|
||||||
if self.study.time_system == "date":
|
if self._study.time_system == "date":
|
||||||
self.set_radio_button("radioButton_date", True)
|
self.set_radio_button("radioButton_date", True)
|
||||||
self.find(QLabel, "label_date").setEnabled(True)
|
self.find(QLabel, "label_date").setEnabled(True)
|
||||||
self.find(QDateTimeEdit, "dateTimeEdit_date").setEnabled(True)
|
self.find(QDateTimeEdit, "dateTimeEdit_date").setEnabled(True)
|
||||||
@@ -76,18 +86,18 @@ class NewStudyWindow(ASubWindow):
|
|||||||
name = self.get_line_edit_text("lineEdit_name")
|
name = self.get_line_edit_text("lineEdit_name")
|
||||||
description = self.get_text_edit_text("textEdit_description")
|
description = self.get_text_edit_text("textEdit_description")
|
||||||
|
|
||||||
if self.study is None:
|
if self._study is None:
|
||||||
study = Study.new(name, description)
|
study = Study.new(name, description)
|
||||||
if self.get_radio_button("radioButton_date"):
|
if self.get_radio_button("radioButton_date"):
|
||||||
date = self.get_datetime_edit("dateTimeEdit_date")
|
date = self.get_datetime_edit("dateTimeEdit_date")
|
||||||
study.use_date(date)
|
study.use_date(date)
|
||||||
self.parent.set_model(study)
|
self.parent.set_model(study)
|
||||||
else:
|
else:
|
||||||
self.study.name = name
|
self._study.name = name
|
||||||
self.study.description = description
|
self._study.description = description
|
||||||
if self.get_radio_button("radioButton_date"):
|
if self.get_radio_button("radioButton_date"):
|
||||||
date = self.get_datetime_edit("dateTimeEdit_date")
|
date = self.get_datetime_edit("dateTimeEdit_date")
|
||||||
self.study.use_date(date)
|
self._study.use_date(date)
|
||||||
else:
|
else:
|
||||||
self.study.use_time()
|
self._study.use_time()
|
||||||
self.done(True)
|
self.done(True)
|
||||||
@@ -463,11 +463,16 @@ class ASubWindowFeatures(object):
|
|||||||
# Top level interface
|
# Top level interface
|
||||||
|
|
||||||
class ASubMainWindow(QMainWindow, ASubWindowFeatures, WindowToolKit):
|
class ASubMainWindow(QMainWindow, ASubWindowFeatures, WindowToolKit):
|
||||||
def __init__(self, name="", ui="dummy", parent=None):
|
def __init__(self, name="", ui="dummy", parent=None, **kwargs):
|
||||||
super(ASubMainWindow, self).__init__(parent=parent)
|
super(ASubMainWindow, self).__init__(parent=parent)
|
||||||
if ui is not None:
|
if ui is not None:
|
||||||
self.ui = loadUi(
|
self.ui = loadUi(
|
||||||
os.path.join(os.path.dirname(__file__), "ui", f"{ui}.ui"),
|
os.path.abspath(
|
||||||
|
os.path.join(
|
||||||
|
os.path.dirname(__file__),
|
||||||
|
"..", "ui", f"{ui}.ui"
|
||||||
|
)
|
||||||
|
),
|
||||||
self
|
self
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -496,10 +501,15 @@ class ASubMainWindow(QMainWindow, ASubWindowFeatures, WindowToolKit):
|
|||||||
return self.ui.findChild(qtype, name)
|
return self.ui.findChild(qtype, name)
|
||||||
|
|
||||||
class ASubWindow(QDialog, ASubWindowFeatures, WindowToolKit):
|
class ASubWindow(QDialog, ASubWindowFeatures, WindowToolKit):
|
||||||
def __init__(self, name="", ui="dummy", parent=None):
|
def __init__(self, name="", ui="dummy", parent=None, **kwargs):
|
||||||
super(ASubWindow, self).__init__(parent=parent)
|
super(ASubWindow, self).__init__(parent=parent)
|
||||||
self.ui = loadUi(
|
self.ui = loadUi(
|
||||||
os.path.join(os.path.dirname(__file__), "ui", f"{ui}.ui"),
|
os.path.abspath(
|
||||||
|
os.path.join(
|
||||||
|
os.path.dirname(__file__),
|
||||||
|
"..", "ui", f"{ui}.ui"
|
||||||
|
)
|
||||||
|
),
|
||||||
self
|
self
|
||||||
)
|
)
|
||||||
self.name = name
|
self.name = name
|
||||||
@@ -530,7 +540,12 @@ class AWidget(QWidget, ASubWindowFeatures):
|
|||||||
def __init__(self, ui="", parent=None):
|
def __init__(self, ui="", parent=None):
|
||||||
super(AWidget, self).__init__(parent=parent)
|
super(AWidget, self).__init__(parent=parent)
|
||||||
self.ui = loadUi(
|
self.ui = loadUi(
|
||||||
os.path.join(os.path.dirname(__file__), "ui", "Widgets", f"{ui}.ui"),
|
os.path.abspath(
|
||||||
|
os.path.join(
|
||||||
|
os.path.dirname(__file__),
|
||||||
|
"..", "ui", "Widgets", f"{ui}.ui"
|
||||||
|
)
|
||||||
|
),
|
||||||
self
|
self
|
||||||
)
|
)
|
||||||
self.parent = parent
|
self.parent = parent
|
||||||
Loaded 100 of 117 files, more files were not shown because too many files have changed in this diff.
Show more
Reference in new issue
Block a user