mirror of
https://gitlab.com/pamhyr/pamhyr2.git
synced 2026-10-30 03:20:41 +01:00
Compare commits
No files matched your search
@@ -0,0 +1,12 @@
|
|||||||
|
# Pamhyr .editorconfig
|
||||||
|
|
||||||
|
root = true
|
||||||
|
|
||||||
|
[*.py]
|
||||||
|
charset = utf-8
|
||||||
|
indent_style = space
|
||||||
|
indent_size = 4
|
||||||
|
tab_width = 8
|
||||||
|
end_of_line = lf
|
||||||
|
trim_trailing_whitespace = true
|
||||||
|
insert_final_newline = true
|
||||||
+334
@@ -1,6 +1,7 @@
|
|||||||
### CUSTOM ###
|
### CUSTOM ###
|
||||||
|
|
||||||
*.exe
|
*.exe
|
||||||
|
*.msi
|
||||||
*.tar.xz
|
*.tar.xz
|
||||||
*.zip
|
*.zip
|
||||||
*.spec
|
*.spec
|
||||||
@@ -9,15 +10,33 @@
|
|||||||
|
|
||||||
tmp
|
tmp
|
||||||
|
|
||||||
|
*.tar
|
||||||
*.tar.*
|
*.tar.*
|
||||||
|
*.tgz
|
||||||
*.zip
|
*.zip
|
||||||
|
|
||||||
|
*.html
|
||||||
|
*.pdf
|
||||||
|
*.odt
|
||||||
|
|
||||||
|
doc/dev/images/auto_*
|
||||||
|
doc/dev/documentation.*
|
||||||
|
!doc/dev/*.org
|
||||||
|
|
||||||
|
doc/dev/images/auto_*
|
||||||
|
doc/users/documentation.*
|
||||||
|
!doc/users/*.org
|
||||||
|
|
||||||
|
TAGS
|
||||||
|
|
||||||
pamhyrBuild
|
pamhyrBuild
|
||||||
wine-pamhyr-build*
|
wine-pamhyr-build*
|
||||||
|
|
||||||
_PAMHYR_
|
_PAMHYR_
|
||||||
__old__
|
__old__
|
||||||
|
|
||||||
|
*-venv
|
||||||
|
|
||||||
### END CUSTOM ###
|
### END CUSTOM ###
|
||||||
|
|
||||||
# Created by https://www.toptal.com/developers/gitignore/api/python
|
# Created by https://www.toptal.com/developers/gitignore/api/python
|
||||||
@@ -309,3 +328,318 @@ compile_commands.json
|
|||||||
*_qmlcache.qrc
|
*_qmlcache.qrc
|
||||||
|
|
||||||
# End of https://www.toptal.com/developers/gitignore/api/qt
|
# End of https://www.toptal.com/developers/gitignore/api/qt
|
||||||
|
|
||||||
|
# Created by https://www.toptal.com/developers/gitignore/api/latex
|
||||||
|
# Edit at https://www.toptal.com/developers/gitignore?templates=latex
|
||||||
|
|
||||||
|
### LaTeX ###
|
||||||
|
## Core latex/pdflatex auxiliary files:
|
||||||
|
*.aux
|
||||||
|
*.lof
|
||||||
|
*.log
|
||||||
|
*.lot
|
||||||
|
*.fls
|
||||||
|
*.out
|
||||||
|
*.toc
|
||||||
|
*.fmt
|
||||||
|
*.fot
|
||||||
|
*.cb
|
||||||
|
*.cb2
|
||||||
|
.*.lb
|
||||||
|
|
||||||
|
## Intermediate documents:
|
||||||
|
*.dvi
|
||||||
|
*.xdv
|
||||||
|
*-converted-to.*
|
||||||
|
# these rules might exclude image files for figures etc.
|
||||||
|
# *.ps
|
||||||
|
# *.eps
|
||||||
|
# *.pdf
|
||||||
|
|
||||||
|
## Generated if empty string is given at "Please type another file name for output:"
|
||||||
|
.pdf
|
||||||
|
|
||||||
|
## Bibliography auxiliary files (bibtex/biblatex/biber):
|
||||||
|
*.bbl
|
||||||
|
*.bcf
|
||||||
|
*.blg
|
||||||
|
*-blx.aux
|
||||||
|
*-blx.bib
|
||||||
|
*.run.xml
|
||||||
|
|
||||||
|
## Build tool auxiliary files:
|
||||||
|
*.fdb_latexmk
|
||||||
|
*.synctex
|
||||||
|
*.synctex(busy)
|
||||||
|
*.synctex.gz
|
||||||
|
*.synctex.gz(busy)
|
||||||
|
*.pdfsync
|
||||||
|
|
||||||
|
## Build tool directories for auxiliary files
|
||||||
|
# latexrun
|
||||||
|
latex.out/
|
||||||
|
|
||||||
|
## Auxiliary and intermediate files from other packages:
|
||||||
|
# algorithms
|
||||||
|
*.alg
|
||||||
|
*.loa
|
||||||
|
|
||||||
|
# achemso
|
||||||
|
acs-*.bib
|
||||||
|
|
||||||
|
# amsthm
|
||||||
|
*.thm
|
||||||
|
|
||||||
|
# beamer
|
||||||
|
*.nav
|
||||||
|
*.pre
|
||||||
|
*.snm
|
||||||
|
*.vrb
|
||||||
|
|
||||||
|
# changes
|
||||||
|
*.soc
|
||||||
|
|
||||||
|
# comment
|
||||||
|
*.cut
|
||||||
|
|
||||||
|
# cprotect
|
||||||
|
*.cpt
|
||||||
|
|
||||||
|
# elsarticle (documentclass of Elsevier journals)
|
||||||
|
*.spl
|
||||||
|
|
||||||
|
# endnotes
|
||||||
|
*.ent
|
||||||
|
|
||||||
|
# fixme
|
||||||
|
*.lox
|
||||||
|
|
||||||
|
# feynmf/feynmp
|
||||||
|
*.mf
|
||||||
|
*.mp
|
||||||
|
*.t[1-9]
|
||||||
|
*.t[1-9][0-9]
|
||||||
|
*.tfm
|
||||||
|
|
||||||
|
#(r)(e)ledmac/(r)(e)ledpar
|
||||||
|
*.end
|
||||||
|
*.?end
|
||||||
|
*.[1-9]
|
||||||
|
*.[1-9][0-9]
|
||||||
|
*.[1-9][0-9][0-9]
|
||||||
|
*.[1-9]R
|
||||||
|
*.[1-9][0-9]R
|
||||||
|
*.[1-9][0-9][0-9]R
|
||||||
|
*.eledsec[1-9]
|
||||||
|
*.eledsec[1-9]R
|
||||||
|
*.eledsec[1-9][0-9]
|
||||||
|
*.eledsec[1-9][0-9]R
|
||||||
|
*.eledsec[1-9][0-9][0-9]
|
||||||
|
*.eledsec[1-9][0-9][0-9]R
|
||||||
|
|
||||||
|
# glossaries
|
||||||
|
*.acn
|
||||||
|
*.acr
|
||||||
|
*.glg
|
||||||
|
*.glo
|
||||||
|
*.gls
|
||||||
|
*.glsdefs
|
||||||
|
*.lzo
|
||||||
|
*.lzs
|
||||||
|
*.slg
|
||||||
|
*.slo
|
||||||
|
*.sls
|
||||||
|
|
||||||
|
# uncomment this for glossaries-extra (will ignore makeindex's style files!)
|
||||||
|
# *.ist
|
||||||
|
|
||||||
|
# gnuplot
|
||||||
|
*.gnuplot
|
||||||
|
*.table
|
||||||
|
|
||||||
|
# gnuplottex
|
||||||
|
*-gnuplottex-*
|
||||||
|
|
||||||
|
# gregoriotex
|
||||||
|
*.gaux
|
||||||
|
*.glog
|
||||||
|
*.gtex
|
||||||
|
|
||||||
|
# htlatex
|
||||||
|
*.4ct
|
||||||
|
*.4tc
|
||||||
|
*.idv
|
||||||
|
*.lg
|
||||||
|
*.trc
|
||||||
|
*.xref
|
||||||
|
|
||||||
|
# hyperref
|
||||||
|
*.brf
|
||||||
|
|
||||||
|
# knitr
|
||||||
|
*-concordance.tex
|
||||||
|
# TODO Uncomment the next line if you use knitr and want to ignore its generated tikz files
|
||||||
|
# *.tikz
|
||||||
|
*-tikzDictionary
|
||||||
|
|
||||||
|
# listings
|
||||||
|
*.lol
|
||||||
|
|
||||||
|
# luatexja-ruby
|
||||||
|
*.ltjruby
|
||||||
|
|
||||||
|
# makeidx
|
||||||
|
*.idx
|
||||||
|
*.ilg
|
||||||
|
*.ind
|
||||||
|
|
||||||
|
# minitoc
|
||||||
|
*.maf
|
||||||
|
*.mlf
|
||||||
|
*.mlt
|
||||||
|
*.mtc[0-9]*
|
||||||
|
*.slf[0-9]*
|
||||||
|
*.slt[0-9]*
|
||||||
|
*.stc[0-9]*
|
||||||
|
|
||||||
|
# minted
|
||||||
|
_minted*
|
||||||
|
*.pyg
|
||||||
|
|
||||||
|
# morewrites
|
||||||
|
*.mw
|
||||||
|
|
||||||
|
# newpax
|
||||||
|
*.newpax
|
||||||
|
|
||||||
|
# nomencl
|
||||||
|
*.nlg
|
||||||
|
*.nlo
|
||||||
|
*.nls
|
||||||
|
|
||||||
|
# pax
|
||||||
|
*.pax
|
||||||
|
|
||||||
|
# pdfpcnotes
|
||||||
|
*.pdfpc
|
||||||
|
|
||||||
|
# sagetex
|
||||||
|
*.sagetex.sage
|
||||||
|
*.sagetex.py
|
||||||
|
*.sagetex.scmd
|
||||||
|
|
||||||
|
# scrwfile
|
||||||
|
*.wrt
|
||||||
|
|
||||||
|
# svg
|
||||||
|
svg-inkscape/
|
||||||
|
|
||||||
|
# sympy
|
||||||
|
*.sout
|
||||||
|
*.sympy
|
||||||
|
sympy-plots-for-*.tex/
|
||||||
|
|
||||||
|
# pdfcomment
|
||||||
|
*.upa
|
||||||
|
*.upb
|
||||||
|
|
||||||
|
# pythontex
|
||||||
|
*.pytxcode
|
||||||
|
pythontex-files-*/
|
||||||
|
|
||||||
|
# tcolorbox
|
||||||
|
*.listing
|
||||||
|
|
||||||
|
# thmtools
|
||||||
|
*.loe
|
||||||
|
|
||||||
|
# TikZ & PGF
|
||||||
|
*.dpth
|
||||||
|
*.md5
|
||||||
|
*.auxlock
|
||||||
|
|
||||||
|
# titletoc
|
||||||
|
*.ptc
|
||||||
|
|
||||||
|
# todonotes
|
||||||
|
*.tdo
|
||||||
|
|
||||||
|
# vhistory
|
||||||
|
*.hst
|
||||||
|
*.ver
|
||||||
|
|
||||||
|
# easy-todo
|
||||||
|
*.lod
|
||||||
|
|
||||||
|
# xcolor
|
||||||
|
*.xcp
|
||||||
|
|
||||||
|
# xmpincl
|
||||||
|
*.xmpi
|
||||||
|
|
||||||
|
# xindy
|
||||||
|
*.xdy
|
||||||
|
|
||||||
|
# xypic precompiled matrices and outlines
|
||||||
|
*.xyc
|
||||||
|
*.xyd
|
||||||
|
|
||||||
|
# endfloat
|
||||||
|
*.ttt
|
||||||
|
*.fff
|
||||||
|
|
||||||
|
# Latexian
|
||||||
|
TSWLatexianTemp*
|
||||||
|
|
||||||
|
## Editors:
|
||||||
|
# WinEdt
|
||||||
|
*.bak
|
||||||
|
*.sav
|
||||||
|
|
||||||
|
# Texpad
|
||||||
|
.texpadtmp
|
||||||
|
|
||||||
|
# LyX
|
||||||
|
*.lyx~
|
||||||
|
|
||||||
|
# Kile
|
||||||
|
*.backup
|
||||||
|
|
||||||
|
# gummi
|
||||||
|
.*.swp
|
||||||
|
|
||||||
|
# KBibTeX
|
||||||
|
*~[0-9]*
|
||||||
|
|
||||||
|
# TeXnicCenter
|
||||||
|
*.tps
|
||||||
|
|
||||||
|
# auto folder when using emacs and auctex
|
||||||
|
./auto/*
|
||||||
|
*.el
|
||||||
|
|
||||||
|
# expex forward references with \gathertags
|
||||||
|
*-tags.tex
|
||||||
|
|
||||||
|
# standalone packages
|
||||||
|
*.sta
|
||||||
|
|
||||||
|
# Makeindex log files
|
||||||
|
*.lpz
|
||||||
|
|
||||||
|
# xwatermark package
|
||||||
|
*.xwm
|
||||||
|
|
||||||
|
# REVTeX puts footnotes in the bibliography by default, unless the nofootinbib
|
||||||
|
# option is specified. Footnotes are the stored in a file with suffix Notes.bib.
|
||||||
|
# Uncomment the next line to have this generated file ignored.
|
||||||
|
#*Notes.bib
|
||||||
|
|
||||||
|
### LaTeX Patch ###
|
||||||
|
# LIPIcs / OASIcs
|
||||||
|
*.vtc
|
||||||
|
|
||||||
|
# glossaries
|
||||||
|
*.glstex
|
||||||
|
|
||||||
|
# End of https://www.toptal.com/developers/gitignore/api/latex
|
||||||
+275
-115
@@ -15,96 +15,55 @@
|
|||||||
# along with this program. If not, see <https://www.gnu.org/licenses/>.
|
# along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
stages:
|
stages:
|
||||||
|
- downloads
|
||||||
- build
|
- build
|
||||||
- test
|
- test
|
||||||
- package
|
- package
|
||||||
- release
|
- release
|
||||||
|
|
||||||
|
#############
|
||||||
|
# DOWNLOADS #
|
||||||
|
#############
|
||||||
|
|
||||||
|
dl-mage-linux:
|
||||||
|
stage: downloads
|
||||||
|
tags:
|
||||||
|
- linux
|
||||||
|
rules:
|
||||||
|
- if: $CI_COMMIT_BRANCH == 'ci-test' || $CI_COMMIT_BRANCH == 'master' || $CI_COMMIT_TAG
|
||||||
|
script:
|
||||||
|
- curl -L -o mage.tgz https://gitlab.irstea.fr/jean-baptiste.faure/mage/-/releases/Test6/downloads/packages/mage_linux.tgz
|
||||||
|
- mkdir -p mage-linux
|
||||||
|
- cd mage-linux
|
||||||
|
- tar xvf ../mage.tgz
|
||||||
|
artifacts:
|
||||||
|
paths:
|
||||||
|
- mage-linux/mage
|
||||||
|
- mage-linux/mage_extraire
|
||||||
|
- mage-linux/mailleurPF
|
||||||
|
|
||||||
|
dl-mage-windows:
|
||||||
|
stage: downloads
|
||||||
|
tags:
|
||||||
|
- linux
|
||||||
|
rules:
|
||||||
|
- if: $CI_COMMIT_BRANCH == 'ci-test' || $CI_COMMIT_BRANCH == 'master' || $CI_COMMIT_TAG
|
||||||
|
script:
|
||||||
|
- curl -L -o mage.tgz https://gitlab.irstea.fr/jean-baptiste.faure/mage/-/releases/Test6/downloads/packages/mage_windows.tgz
|
||||||
|
- mkdir -p mage-windows
|
||||||
|
- cd mage-windows
|
||||||
|
- tar xvf ../mage.tgz
|
||||||
|
artifacts:
|
||||||
|
paths:
|
||||||
|
- mage-windows/mage.exe
|
||||||
|
- mage-windows/mage_extraire.exe
|
||||||
|
- mage-windows/mailleurPF.exe
|
||||||
|
|
||||||
#########
|
#########
|
||||||
# BUILD #
|
# BUILD #
|
||||||
#########
|
#########
|
||||||
|
|
||||||
build-mage-linux:
|
set-version:
|
||||||
stage: build
|
|
||||||
tags:
|
|
||||||
- linux
|
|
||||||
rules:
|
|
||||||
- if: $CI_COMMIT_BRANCH == 'master' || $CI_COMMIT_TAG
|
|
||||||
script:
|
|
||||||
- curl -L -o mage.tgz https://gitlab.irstea.fr/jean-baptiste.faure/mage/-/releases/Test6/downloads/packages/mage_linux.tgz
|
|
||||||
- mkdir -p mage
|
|
||||||
- cd mage
|
|
||||||
- tar xvf ../mage.tgz
|
|
||||||
artifacts:
|
|
||||||
paths:
|
|
||||||
- mage/mage
|
|
||||||
- mage/mage_extraire
|
|
||||||
- mage/mailleurPF
|
|
||||||
|
|
||||||
# build-mage-linux:
|
|
||||||
# stage: build
|
|
||||||
# tags:
|
|
||||||
# - linux
|
|
||||||
# rules:
|
|
||||||
# - if: $CI_COMMIT_BRANCH == 'master' || $CI_COMMIT_TAG
|
|
||||||
# variables:
|
|
||||||
# GIT_SUBMODULE_STRATEGY: recursive
|
|
||||||
# GIT_SUBMODULE_DEPTH: 20
|
|
||||||
# script:
|
|
||||||
# - cd mage/src/
|
|
||||||
# - mkdir -p build
|
|
||||||
# - cd build
|
|
||||||
# - cmake ..
|
|
||||||
# - make
|
|
||||||
# artifacts:
|
|
||||||
# paths:
|
|
||||||
# - mage/src/build/mage
|
|
||||||
# - mage/src/build/mage_extraire
|
|
||||||
# - mage/src/build/mailleurPF
|
|
||||||
|
|
||||||
build-mage-windows:
|
|
||||||
stage: build
|
|
||||||
tags:
|
|
||||||
- linux
|
|
||||||
rules:
|
|
||||||
- if: $CI_COMMIT_BRANCH == 'master' || $CI_COMMIT_TAG
|
|
||||||
script:
|
|
||||||
- curl -L -o mage.tgz https://gitlab.irstea.fr/jean-baptiste.faure/mage/-/releases/Test6/downloads/packages/mage_windows.tgz
|
|
||||||
- mkdir -p mage
|
|
||||||
- cd mage
|
|
||||||
- tar xvf ../mage.tgz
|
|
||||||
artifacts:
|
|
||||||
paths:
|
|
||||||
- mage/mage.exe
|
|
||||||
- mage/mage_extraire.exe
|
|
||||||
- mage/mailleurPF.exe
|
|
||||||
|
|
||||||
# build-mage-windows:
|
|
||||||
# stage: build
|
|
||||||
# tags:
|
|
||||||
# - wine
|
|
||||||
# rules:
|
|
||||||
# - if: $CI_COMMIT_BRANCH == 'master' || $CI_COMMIT_TAG
|
|
||||||
# variables:
|
|
||||||
# GIT_SUBMODULE_STRATEGY: recursive
|
|
||||||
# GIT_SUBMODULE_DEPTH: 20
|
|
||||||
# script:
|
|
||||||
# - cd mage/src/
|
|
||||||
# - sed s/add_compile_definitions(win)/add_compile_definitions(windows)/ CMakeLists.txt > __tmp__
|
|
||||||
# - echo set(CMAKE_Fortran_COMPILER "C:/Program\ Files/gcc/bin/gfortran.exe") > CMakeLists.txt
|
|
||||||
# - echo set(CMAKE_MAKE_PROGRAM "C:/Program Files\ \(x86\)/GnuWin32/bin/make.exe") >> CMakeLists.txt
|
|
||||||
# - type __tmp__ >> CMakeLists.txt
|
|
||||||
# - mkdir build
|
|
||||||
# - cd build
|
|
||||||
# - cmake -G "MinGW Makefiles" ..
|
|
||||||
# - make
|
|
||||||
# artifacts:
|
|
||||||
# paths:
|
|
||||||
# - mage/src/build/mage.exe
|
|
||||||
# - mage/src/build/mage_extraire.exe
|
|
||||||
# - mage/src/build/mailleurPF.exe
|
|
||||||
|
|
||||||
build:
|
|
||||||
stage: build
|
stage: build
|
||||||
tags:
|
tags:
|
||||||
- linux
|
- linux
|
||||||
@@ -126,60 +85,240 @@ build-lang:
|
|||||||
paths:
|
paths:
|
||||||
- src/lang/*.qm
|
- src/lang/*.qm
|
||||||
|
|
||||||
|
build-users-doc:
|
||||||
|
stage: build
|
||||||
|
tags:
|
||||||
|
- linux
|
||||||
|
needs:
|
||||||
|
- job: set-version
|
||||||
|
artifacts: true
|
||||||
|
script:
|
||||||
|
- cd ./doc/users/
|
||||||
|
- ./build.sh
|
||||||
|
artifacts:
|
||||||
|
paths:
|
||||||
|
- doc/users/documentation.pdf
|
||||||
|
- doc/users/documentation.html
|
||||||
|
- doc/users/images/
|
||||||
|
|
||||||
|
build-developers-doc:
|
||||||
|
stage: build
|
||||||
|
tags:
|
||||||
|
- linux
|
||||||
|
needs:
|
||||||
|
- job: set-version
|
||||||
|
artifacts: true
|
||||||
|
script:
|
||||||
|
- cd ./doc/dev/
|
||||||
|
- ./build.sh
|
||||||
|
# Create html documentation
|
||||||
|
- cd ../../src
|
||||||
|
- pdoc --html .
|
||||||
|
# Create archive
|
||||||
|
- tar cf html.tar ./html
|
||||||
|
- cd ../doc/dev
|
||||||
|
- mv ../../src/html.tar ./
|
||||||
|
artifacts:
|
||||||
|
paths:
|
||||||
|
- doc/dev/documentation.pdf
|
||||||
|
- doc/dev/documentation.html
|
||||||
|
- doc/dev/html.tar
|
||||||
|
- doc/dev/images/
|
||||||
|
|
||||||
|
build-linux:
|
||||||
|
stage: build
|
||||||
|
tags:
|
||||||
|
- linux
|
||||||
|
rules:
|
||||||
|
- if: $CI_COMMIT_BRANCH == 'ci-test' || $CI_COMMIT_BRANCH == 'master' || $CI_COMMIT_TAG
|
||||||
|
needs:
|
||||||
|
- job: dl-mage-linux
|
||||||
|
artifacts: true
|
||||||
|
- job: set-version
|
||||||
|
artifacts: true
|
||||||
|
- job: build-lang
|
||||||
|
artifacts: true
|
||||||
|
- job: build-developers-doc
|
||||||
|
artifacts: true
|
||||||
|
- job: build-users-doc
|
||||||
|
artifacts: true
|
||||||
|
script:
|
||||||
|
- mkdir -p linux
|
||||||
|
- cd linux
|
||||||
|
# Setup virtual env
|
||||||
|
- python3 -m venv linux-venv
|
||||||
|
- . linux-venv/bin/activate
|
||||||
|
- pip3 install -U -r ../requirements.txt
|
||||||
|
# Run Pyinstaller
|
||||||
|
- pyinstaller -y --paths linux-venv/lib/python3.8/site-packages ../src/pamhyr.py
|
||||||
|
# Create directory
|
||||||
|
- mkdir -p pamhyr
|
||||||
|
- mkdir -p pamhyr/pamhyr
|
||||||
|
- mkdir -p pamhyr/pamhyr/_internal
|
||||||
|
# Copy Pamhyr info
|
||||||
|
- cp -v ../VERSION pamhyr/pamhyr/_internal/
|
||||||
|
- cp -v ../AUTHORS pamhyr/pamhyr/_internal/
|
||||||
|
- cp -v ../LICENSE pamhyr/pamhyr/_internal/
|
||||||
|
# Copy mage
|
||||||
|
- mkdir -p pamhyr/mage
|
||||||
|
- cp -v ../mage-linux/* pamhyr/mage/
|
||||||
|
# Copy Pamhyr
|
||||||
|
- cp -r dist/pamhyr pamhyr/
|
||||||
|
# Copy Pamhyr resources
|
||||||
|
- mkdir -p pamhyr/pamhyr/_internal/View
|
||||||
|
- mkdir -p pamhyr/pamhyr/_internal/View/ui
|
||||||
|
- mkdir -p pamhyr/pamhyr/_internal/View/ui/Widgets
|
||||||
|
- cp -r ../src/View/ui/*.ui pamhyr/pamhyr/_internal/View/ui/
|
||||||
|
- cp -r ../src/View/ui/ressources/ pamhyr/pamhyr/_internal/View/ui
|
||||||
|
- cp -r ../src/View/ui/Widgets/*.ui pamhyr/pamhyr/_internal/View/ui/Widgets
|
||||||
|
# Copy lang
|
||||||
|
- mkdir -p pamhyr/pamhyr/_internal/lang
|
||||||
|
- cp -r ../src/lang/*.qm pamhyr/pamhyr/_internal/lang
|
||||||
|
# Copy tests cases
|
||||||
|
- mkdir -p pamhyr/tests_cases/
|
||||||
|
- mkdir -p pamhyr/tests_cases/Saar
|
||||||
|
- cp ../tests_cases/Saar/Saar.pamhyr pamhyr/tests_cases/Saar/
|
||||||
|
# Copy documentations
|
||||||
|
- mkdir -p pamhyr/doc/
|
||||||
|
- mkdir -p pamhyr/doc/images/
|
||||||
|
- mkdir -p pamhyr/doc/html/
|
||||||
|
- cp ../doc/users/documentation.pdf pamhyr/doc/Pamhyr2-users.pdf
|
||||||
|
- cp ../doc/users/documentation.html pamhyr/doc/Pamhyr2-users.html
|
||||||
|
- cp ../doc/dev/documentation.pdf pamhyr/doc/Pamhyr2-dev.pdf
|
||||||
|
- cp ../doc/dev/documentation.html pamhyr/doc/Pamhyr2-dev.html
|
||||||
|
#- cp ../doc/users/images/* pamhyr/doc/images
|
||||||
|
- cp ../doc/dev/images/* pamhyr/doc/images
|
||||||
|
- cp ../doc/images/* pamhyr/doc/images
|
||||||
|
# Create running script
|
||||||
|
- echo "#!/bin/sh" > pamhyr/Pamhyr2
|
||||||
|
- echo "./pamhyr/pamhyr $@" >> pamhyr/Pamhyr2
|
||||||
|
- chmod u+x pamhyr/Pamhyr2
|
||||||
|
artifacts:
|
||||||
|
paths:
|
||||||
|
- linux/pamhyr
|
||||||
|
|
||||||
|
build-windows:
|
||||||
|
stage: build
|
||||||
|
tags:
|
||||||
|
- wine
|
||||||
|
rules:
|
||||||
|
- if: $CI_COMMIT_BRANCH == 'ci-test' || $CI_COMMIT_BRANCH == 'master' || $CI_COMMIT_TAG
|
||||||
|
needs:
|
||||||
|
- job: dl-mage-windows
|
||||||
|
artifacts: true
|
||||||
|
- job: set-version
|
||||||
|
artifacts: true
|
||||||
|
- job: build-lang
|
||||||
|
artifacts: true
|
||||||
|
- job: build-developers-doc
|
||||||
|
artifacts: true
|
||||||
|
- job: build-users-doc
|
||||||
|
artifacts: true
|
||||||
|
script:
|
||||||
|
- mkdir windows
|
||||||
|
- cd windows
|
||||||
|
# Setup env
|
||||||
|
- python -m pip install -U -r ..\requirements.txt
|
||||||
|
# Run Pyinstaller
|
||||||
|
- pyinstaller -y ..\src\pamhyr.py
|
||||||
|
# Create directory
|
||||||
|
- mkdir pamhyr
|
||||||
|
- dir
|
||||||
|
- copy ..\packages\make-windows-dir.bat .\make-windows-dir.bat
|
||||||
|
- .\make-windows-dir.bat
|
||||||
|
artifacts:
|
||||||
|
paths:
|
||||||
|
- windows/pamhyr
|
||||||
|
|
||||||
#########
|
#########
|
||||||
# TESTS #
|
# TESTS #
|
||||||
#########
|
#########
|
||||||
|
|
||||||
test:
|
# test-windows:
|
||||||
stage: test
|
# stage: test
|
||||||
script:
|
# tags:
|
||||||
- echo "TODO PAMHYR tests"
|
# - wine
|
||||||
|
# needs:
|
||||||
|
# - job: set-version
|
||||||
|
# artifacts: true
|
||||||
|
# - job: build-windows
|
||||||
|
# artifacts: true
|
||||||
|
# script:
|
||||||
|
# - cd windows\pamhyr
|
||||||
|
# - pamhyr\pamhyr.exe hello
|
||||||
|
|
||||||
|
# test-linux:
|
||||||
|
# stage: test
|
||||||
|
# tags:
|
||||||
|
# - linux
|
||||||
|
# needs:
|
||||||
|
# - job: set-version
|
||||||
|
# artifacts: true
|
||||||
|
# - job: build-linux
|
||||||
|
# artifacts: true
|
||||||
|
# script:
|
||||||
|
# - cd linux/pamhyr
|
||||||
|
# - ./Pamhyr2 hello
|
||||||
|
|
||||||
############
|
############
|
||||||
# PACKAGES #
|
# PACKAGES #
|
||||||
############
|
############
|
||||||
|
|
||||||
linux-package:
|
linux-package-tar:
|
||||||
stage: package
|
stage: package
|
||||||
tags:
|
tags:
|
||||||
- release
|
- release
|
||||||
- linux
|
- linux
|
||||||
needs:
|
needs:
|
||||||
- job: build-lang
|
# - job: test-linux
|
||||||
artifacts: true
|
- job: build-linux
|
||||||
- job: build
|
|
||||||
artifacts: true
|
|
||||||
- job: build-mage-linux
|
|
||||||
artifacts: true
|
artifacts: true
|
||||||
rules:
|
rules:
|
||||||
- if: $CI_COMMIT_BRANCH == 'master' || $CI_COMMIT_TAG
|
- if: $CI_COMMIT_BRANCH == 'ci-test' || $CI_COMMIT_TAG
|
||||||
artifacts:
|
artifacts:
|
||||||
paths:
|
paths:
|
||||||
- packages/pamhyr-gnulinux-amd64.tar.xz
|
- linux/pamhyr-gnulinux.tar.xz
|
||||||
script:
|
script:
|
||||||
- cd packages
|
- cd linux
|
||||||
- ./linux.sh
|
- tar --xz -cf pamhyr-gnulinux.tar.xz ./pamhyr --checkpoint=.100
|
||||||
|
|
||||||
windows-package:
|
windows-package-zip:
|
||||||
|
stage: package
|
||||||
|
tags:
|
||||||
|
- release
|
||||||
|
- linux
|
||||||
|
needs:
|
||||||
|
# - job: test-windows
|
||||||
|
- job: build-windows
|
||||||
|
artifacts: true
|
||||||
|
rules:
|
||||||
|
- if: $CI_COMMIT_BRANCH == 'ci-test' || $CI_COMMIT_TAG
|
||||||
|
artifacts:
|
||||||
|
paths:
|
||||||
|
- windows/pamhyr-windows.zip
|
||||||
|
script:
|
||||||
|
- cd windows
|
||||||
|
- zip -r pamhyr-windows.zip pamhyr
|
||||||
|
|
||||||
|
windows-package-exe:
|
||||||
stage: package
|
stage: package
|
||||||
tags:
|
tags:
|
||||||
- release
|
- release
|
||||||
- wine
|
- wine
|
||||||
needs:
|
needs:
|
||||||
- job: build-lang
|
# - job: test-windows
|
||||||
artifacts: true
|
- job: build-windows
|
||||||
- job: build
|
|
||||||
artifacts: true
|
|
||||||
- job: build-mage-windows
|
|
||||||
artifacts: true
|
artifacts: true
|
||||||
rules:
|
rules:
|
||||||
- if: $CI_COMMIT_BRANCH == 'master' || $CI_COMMIT_TAG
|
- if: $CI_COMMIT_BRANCH == 'ci-test' || $CI_COMMIT_TAG
|
||||||
artifacts:
|
artifacts:
|
||||||
paths:
|
paths:
|
||||||
- packages/pamhyr-win-amd64.exe
|
- windows/pamhyr-windows.exe
|
||||||
script:
|
script:
|
||||||
- cd packages
|
- cd windows
|
||||||
- ./windows.bat
|
- copy ..\packages\make-windows-exe.bat make-windows-exe.bat
|
||||||
|
- copy ..\packages\pamhyr.nsi pamhyr.nsi
|
||||||
|
- .\make-windows-exe.bat
|
||||||
|
|
||||||
###########
|
###########
|
||||||
# RELEASE #
|
# RELEASE #
|
||||||
@@ -191,16 +330,25 @@ tag-release:
|
|||||||
- release
|
- release
|
||||||
- linux
|
- linux
|
||||||
needs:
|
needs:
|
||||||
- job: linux-package
|
- job: linux-package-tar
|
||||||
artifacts: true
|
artifacts: true
|
||||||
- job: windows-package
|
- job: windows-package-zip
|
||||||
|
artifacts: true
|
||||||
|
- job: windows-package-exe
|
||||||
|
artifacts: true
|
||||||
|
- job: build-users-doc
|
||||||
|
artifacts: true
|
||||||
|
- job: build-developers-doc
|
||||||
artifacts: true
|
artifacts: true
|
||||||
rules:
|
rules:
|
||||||
- if: $CI_COMMIT_TAG
|
- if: $CI_COMMIT_TAG
|
||||||
artifacts:
|
artifacts:
|
||||||
paths:
|
paths:
|
||||||
- packages/pamhyr-gnulinux-amd64.tar.xz
|
- linux/pamhyr-gnulinux.tar.xz
|
||||||
- packages/pamhyr-win-amd64.exe
|
- windows/pamhyr-windows.zip
|
||||||
|
- windows/pamhyr-windows.exe
|
||||||
|
- doc/dev/documentation.pdf
|
||||||
|
- doc/users/documentation.pdf
|
||||||
script:
|
script:
|
||||||
- cd packages
|
- cd packages
|
||||||
release:
|
release:
|
||||||
@@ -210,11 +358,23 @@ tag-release:
|
|||||||
ref: '$CI_COMMIT_SHA'
|
ref: '$CI_COMMIT_SHA'
|
||||||
assets:
|
assets:
|
||||||
links:
|
links:
|
||||||
- name: 'GNU/Linux amd64 (tar.xz)'
|
- name: 'GNU/Linux (tar.xz)'
|
||||||
url: '${CI_PROJECT_URL}/-/jobs/${CI_JOB_ID}/artifacts/raw/packages/pamhyr-gnulinux-amd64.tar.xz'
|
url: '${CI_PROJECT_URL}/-/jobs/${CI_JOB_ID}/artifacts/raw/linux/pamhyr-gnulinux.tar.xz'
|
||||||
filepath: '/packages/pamhyr-gnulinux-amd64.tar.xz'
|
filepath: '/linux/pamhyr-gnulinux.tar.xz'
|
||||||
link_type: 'package'
|
link_type: 'package'
|
||||||
- name: 'Windows amd64 (exe)'
|
- name: 'Windows (exe)'
|
||||||
url: '${CI_PROJECT_URL}/-/jobs/${CI_JOB_ID}/artifacts/raw/packages/pamhyr-win-amd64.exe'
|
url: '${CI_PROJECT_URL}/-/jobs/${CI_JOB_ID}/artifacts/raw/windows/pamhyr-windows.exe'
|
||||||
filepath: '/packages/pamhyr-win-amd64.exe'
|
filepath: '/windows/pamhyr-windows.exe'
|
||||||
link_type: 'package'
|
link_type: 'package'
|
||||||
|
- name: 'Windows (zip)'
|
||||||
|
url: '${CI_PROJECT_URL}/-/jobs/${CI_JOB_ID}/artifacts/raw/windows/pamhyr-windows.zip'
|
||||||
|
filepath: '/windows/pamhyr-windows.zip'
|
||||||
|
link_type: 'package'
|
||||||
|
- name: 'User documentations (pdf)'
|
||||||
|
url: '${CI_PROJECT_URL}/-/jobs/${CI_JOB_ID}/artifacts/raw/doc/users/documentation.pdf'
|
||||||
|
filepath: '/doc/users/documentation.pdf'
|
||||||
|
link_type: 'other'
|
||||||
|
- name: 'Dev documentations (pdf)'
|
||||||
|
url: '${CI_PROJECT_URL}/-/jobs/${CI_JOB_ID}/artifacts/raw/doc/dev/documentation.pdf'
|
||||||
|
filepath: '/doc/dev/documentation.pdf'
|
||||||
|
link_type: 'other'
|
||||||
@@ -47,5 +47,4 @@ pip3 install -r requirements.txt
|
|||||||
|
|
||||||
# Run pamhyr
|
# Run pamhyr
|
||||||
./src/pamhyr.py
|
./src/pamhyr.py
|
||||||
|
|
||||||
```
|
```
|
||||||
Executable
+18
@@ -0,0 +1,18 @@
|
|||||||
|
#! /bin/sh
|
||||||
|
|
||||||
|
echo " PDF documentation.org"
|
||||||
|
emacs -nw --batch \
|
||||||
|
--eval "(require 'org)" \
|
||||||
|
--eval "(require 'ox-latex)" \
|
||||||
|
--eval "(load-file \"../tools/setup.el\")" \
|
||||||
|
--file ./documentation.org \
|
||||||
|
-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
|
||||||
Symlink
+1
@@ -0,0 +1 @@
|
|||||||
|
../tools/ref.bib
|
||||||
File diff suppressed because it is too large.
Load diff
Whitespace-only changes.
Binary file not shown.
|
After Width: | Height: | Size: 21 KiB |
Binary file not shown.
|
After Width: | Height: | Size: 74 KiB |
Binary file not shown.
|
After Width: | Height: | Size: 61 KiB |
Binary file not shown.
|
After Width: | Height: | Size: 34 KiB |
@@ -0,0 +1,163 @@
|
|||||||
|
\ProvidesClass{Pamhyr}[Pamhyr class]
|
||||||
|
\NeedsTeXFormat{LaTeX2e}
|
||||||
|
\ProcessOptions\relax
|
||||||
|
\LoadClass[11pt,a4paper]{article}
|
||||||
|
|
||||||
|
\usepackage[hmargin=2cm, vmargin=3cm]{geometry}
|
||||||
|
\usepackage[british,UKenglish,USenglish,english,american]{babel}
|
||||||
|
\usepackage[T1]{fontenc}
|
||||||
|
\usepackage{times}
|
||||||
|
\usepackage[usenames,dvipsnames]{xcolor}
|
||||||
|
\usepackage[absolute]{textpos}
|
||||||
|
\usepackage{titlesec}
|
||||||
|
\usepackage{amssymb}
|
||||||
|
\usepackage{tcolorbox}
|
||||||
|
|
||||||
|
\usepackage{enumitem}
|
||||||
|
\setlist[enumerate]{itemsep=-0.5em}
|
||||||
|
\setlist[itemize]{itemsep=-0.5em}
|
||||||
|
|
||||||
|
%%
|
||||||
|
%% Bibtex
|
||||||
|
%%
|
||||||
|
|
||||||
|
\bibliographystyle{plain}
|
||||||
|
|
||||||
|
%%
|
||||||
|
%% Colors
|
||||||
|
%%
|
||||||
|
|
||||||
|
\definecolor{primary}{HTML}{212121}
|
||||||
|
\definecolor{lightheadings}{HTML}{5c5c5c}
|
||||||
|
\definecolor{headings}{HTML}{212121}
|
||||||
|
\definecolor{links}{HTML}{e12121}
|
||||||
|
|
||||||
|
%%
|
||||||
|
%% Title
|
||||||
|
%%
|
||||||
|
|
||||||
|
\setlength{\columnsep}{20pt}
|
||||||
|
\setlength{\parskip}{0pt} %% inter paragraph space
|
||||||
|
|
||||||
|
\renewcommand{\maketitle}{
|
||||||
|
{
|
||||||
|
\centering
|
||||||
|
{
|
||||||
|
\fontsize{35}{40}
|
||||||
|
\selectfont
|
||||||
|
\scshape
|
||||||
|
Pamhyr2 \\
|
||||||
|
\medskip
|
||||||
|
}
|
||||||
|
{
|
||||||
|
%\centering
|
||||||
|
\scshape
|
||||||
|
\fontsize{20pt}{24pt}
|
||||||
|
\selectfont
|
||||||
|
A graphical user interface for 1D hydro-sedimentary modelling
|
||||||
|
of rivers \\
|
||||||
|
\medskip
|
||||||
|
}
|
||||||
|
\rule{3cm}{0.4pt}\\
|
||||||
|
\vspace{0.3cm}
|
||||||
|
{
|
||||||
|
%\centering
|
||||||
|
\scshape
|
||||||
|
\fontsize{26pt}{24pt}
|
||||||
|
\selectfont
|
||||||
|
\@title \\
|
||||||
|
Document licence: GPLv3 \\
|
||||||
|
\medskip
|
||||||
|
\includegraphics[width=3cm]{../images/GPLv3_Logo.png} \\
|
||||||
|
\medskip
|
||||||
|
\fontsize{14pt}{16pt}
|
||||||
|
\selectfont
|
||||||
|
© \@author \\
|
||||||
|
\medskip
|
||||||
|
}
|
||||||
|
{
|
||||||
|
%\centering
|
||||||
|
%\scshape
|
||||||
|
\fontsize{12pt}{14pt}
|
||||||
|
\selectfont
|
||||||
|
\@date
|
||||||
|
%\medskip
|
||||||
|
}\\
|
||||||
|
\vspace{0.3cm}
|
||||||
|
\rule{3cm}{0.4pt}\\
|
||||||
|
\vspace{0.3cm}
|
||||||
|
{
|
||||||
|
\begin{minipage}[h]{0.24\textwidth}
|
||||||
|
\includegraphics[width=4cm]{../../src/View/ui/ressources/Logo-INRAE.png}
|
||||||
|
\end{minipage}
|
||||||
|
\begin{minipage}[h]{0.24\textwidth}
|
||||||
|
\includegraphics[width=4cm]{../images/riverly.png}
|
||||||
|
\end{minipage}
|
||||||
|
}\\
|
||||||
|
\vspace{0.3cm}
|
||||||
|
%%\rule{\textwidth}{0.4pt}
|
||||||
|
%%\newpage
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
%%
|
||||||
|
%% Texttt
|
||||||
|
%%
|
||||||
|
|
||||||
|
\usepackage[htt]{hyphenat} % Make texttt split at end of line
|
||||||
|
|
||||||
|
%%
|
||||||
|
%% Verbatim
|
||||||
|
%%
|
||||||
|
|
||||||
|
\AtBeginEnvironment{verbatim}{\footnotesize}
|
||||||
|
|
||||||
|
%% Add box arrond of verbatim
|
||||||
|
\BeforeBeginEnvironment{verbatim}{\begin{tcolorbox}[boxsep=0pt, left=0.1cm, right=0.1cm, arc=0pt, boxrule=0.5pt, colback=white]}%
|
||||||
|
\AfterEndEnvironment{verbatim}{\end{tcolorbox}}%
|
||||||
|
|
||||||
|
\makeatletter
|
||||||
|
\AtBeginEnvironment{verbatim}{\dontdofcolorbox}
|
||||||
|
|
||||||
|
\def\dontdofcolorbox{\renewcommand\fcolorbox[4][]{##4}}
|
||||||
|
\makeatother
|
||||||
|
|
||||||
|
%%
|
||||||
|
%% Source code blocks
|
||||||
|
%%
|
||||||
|
|
||||||
|
%% Use minted
|
||||||
|
\usepackage{minted}
|
||||||
|
\usemintedstyle{tango}
|
||||||
|
\setminted[c]{fontsize=\footnotesize,encoding=utf8,linenos}
|
||||||
|
\setminted[c++]{breaklines,fontsize=\footnotesize,encoding=utf8,linenos}
|
||||||
|
\setminted[python]{breaklines,fontsize=\footnotesize,encoding=utf8,linenos}
|
||||||
|
\setminted[shell]{breaklines,fontsize=\footnotesize,encoding=utf8}
|
||||||
|
\setminted[scheme]{breaklines,fontsize=\footnotesize,encoding=utf8}
|
||||||
|
\setminted[commun-lisp]{breaklines,fontsize=\footnotesize,encoding=utf8}
|
||||||
|
\setminted[text]{breaklines,fontsize=\footnotesize,encoding=utf8}
|
||||||
|
\setminted[llvm]{breaklines,fontsize=\footnotesize,encoding=utf8}
|
||||||
|
|
||||||
|
%% Add box arrond of minted
|
||||||
|
\BeforeBeginEnvironment{minted}{\begin{tcolorbox}[boxsep=0pt, left=0.1cm, right=0.1cm, arc=0pt, boxrule=0.5pt, colback=white]}%
|
||||||
|
\AfterEndEnvironment{minted}{\end{tcolorbox}}%
|
||||||
|
|
||||||
|
\makeatletter
|
||||||
|
\AtBeginEnvironment{minted}{\dontdofcolorbox}
|
||||||
|
|
||||||
|
\def\dontdofcolorbox{\renewcommand\fcolorbox[4][]{##4}}
|
||||||
|
\makeatother
|
||||||
|
|
||||||
|
|
||||||
|
%%
|
||||||
|
%% Water mark
|
||||||
|
%%
|
||||||
|
|
||||||
|
%% FIXME: Delete me for the first realease
|
||||||
|
\usepackage{draftwatermark}
|
||||||
|
\SetWatermarkLightness{0.8}
|
||||||
|
\SetWatermarkAngle{25}
|
||||||
|
\SetWatermarkScale{3}
|
||||||
|
\SetWatermarkFontSize{1cm}
|
||||||
|
\SetWatermarkText{Work in progress}
|
||||||
@@ -0,0 +1,19 @@
|
|||||||
|
# latex.org -- Pamhyr documentation latex config
|
||||||
|
# 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 -*-
|
||||||
|
|
||||||
|
#+LaTeX_CLASS: PamhyrDoc
|
||||||
@@ -0,0 +1,51 @@
|
|||||||
|
# macro.org -- Pamhyr documentation macro
|
||||||
|
# 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 -*-
|
||||||
|
|
||||||
|
# Constant name
|
||||||
|
#+MACRO: oldPamhyr PAMHyR
|
||||||
|
#+MACRO: Pamhyr Pamhyr2
|
||||||
|
#+MACRO: Mage Mage
|
||||||
|
#+MACRO: Rubarbe RubarBE
|
||||||
|
#+MACRO: Inrae INRAE
|
||||||
|
#+MACRO: latex \LaTeX
|
||||||
|
|
||||||
|
# Information
|
||||||
|
#+MACRO: version (eval (pamhyr-version))
|
||||||
|
#+MACRO: current-file (eval (pamhyr-current-file))
|
||||||
|
|
||||||
|
# Special format
|
||||||
|
#+MACRO: file =$1=
|
||||||
|
|
||||||
|
# Biblio
|
||||||
|
#+MACRO: cite [cite:$1]
|
||||||
|
#+MACRO: biblio \bibliography{documentation}
|
||||||
|
|
||||||
|
# Wrapper
|
||||||
|
#+NAME: attr_wrap
|
||||||
|
#+HEADER: :var width="\\textwidth"
|
||||||
|
#+HEADER: :var caption=""
|
||||||
|
#+HEADER: :var smallcaption=""
|
||||||
|
#+HEADER: :var name=""
|
||||||
|
#+HEADER: :var data=""
|
||||||
|
#+HEADER: :var float="nil"
|
||||||
|
#+BEGIN_SRC sh :results output :exports none
|
||||||
|
echo "#+CAPTION[$smallcaption]: $caption"
|
||||||
|
echo "#+NAME: $name"
|
||||||
|
echo "#+ATTR_LATEX: :width $width :float $float"
|
||||||
|
echo "$data"
|
||||||
|
#+END_SRC
|
||||||
Whitespace-only changes.
@@ -0,0 +1,66 @@
|
|||||||
|
(require 'org)
|
||||||
|
(require 'subr-x)
|
||||||
|
|
||||||
|
;; LaTeX config
|
||||||
|
|
||||||
|
(add-to-list
|
||||||
|
'org-latex-classes
|
||||||
|
'("PamhyrDoc"
|
||||||
|
"\\documentclass{../tools/PamhyrDoc}"
|
||||||
|
("\\section{%s}" . "\\section*{%s}")
|
||||||
|
("\\subsection{%s}" . "\\subsection*{%s}")
|
||||||
|
("\\subsubsection{%s}" . "\\subsubsection*{%s}")
|
||||||
|
("\\paragraph{%s}" . "\\paragraph*{%s}")
|
||||||
|
("\\subparagraph{%s}" . "\\subparagraph*{%s}")))
|
||||||
|
|
||||||
|
(setq org-confirm-babel-evaluate nil)
|
||||||
|
(setq org-latex-caption-above nil)
|
||||||
|
|
||||||
|
(org-babel-do-load-languages
|
||||||
|
'org-babel-load-languages
|
||||||
|
(add-to-list 'org-babel-load-languages '(shell . t)))
|
||||||
|
|
||||||
|
(org-babel-do-load-languages
|
||||||
|
'org-babel-load-languages
|
||||||
|
(add-to-list 'org-babel-load-languages '(dot . t)))
|
||||||
|
|
||||||
|
(org-babel-do-load-languages
|
||||||
|
'org-babel-load-languages
|
||||||
|
(add-to-list 'org-babel-load-languages '(python . t)))
|
||||||
|
|
||||||
|
(add-to-list 'org-latex-packages-alist '("" "minted"))
|
||||||
|
(setq org-latex-listings 'minted)
|
||||||
|
(setq org-src-fontify-natively t)
|
||||||
|
|
||||||
|
(setq org-latex-pdf-process
|
||||||
|
'("pdflatex -shell-escape -interaction nonstopmode -output-directory %o %f"
|
||||||
|
"bibtex documentation"
|
||||||
|
"pdflatex -shell-escape -interaction nonstopmode -output-directory %o %f"
|
||||||
|
"pdflatex -shell-escape -interaction nonstopmode -output-directory %o %f"))
|
||||||
|
|
||||||
|
;; Citations
|
||||||
|
|
||||||
|
(org-add-link-type
|
||||||
|
"cite" 'ebib
|
||||||
|
(lambda (path desc format)
|
||||||
|
(cond
|
||||||
|
((eq format 'html)
|
||||||
|
(format "(<cite>%s</cite>)" path))
|
||||||
|
((eq format 'latex)
|
||||||
|
(if (or (not desc) (equal 0 (search "cite:" desc)))
|
||||||
|
(format "\\cite{%s}" path)
|
||||||
|
(format "\\cite[%s][%s]{%s}"
|
||||||
|
(cadr (split-string desc ";"))
|
||||||
|
(car (split-string desc ";")) path))))))
|
||||||
|
|
||||||
|
;; Functools
|
||||||
|
|
||||||
|
(defun pamhyr-version ()
|
||||||
|
"Return the contents of the pamhyr version file."
|
||||||
|
(with-temp-buffer
|
||||||
|
(insert-file-contents "../../VERSION")
|
||||||
|
(buffer-string)))
|
||||||
|
|
||||||
|
(defun pamhyr-current-file ()
|
||||||
|
(let ((lst (split-string (buffer-file-name) "/")))
|
||||||
|
(string-join (nthcdr (- (length lst) 3) lst) "/")))
|
||||||
Executable
+18
@@ -0,0 +1,18 @@
|
|||||||
|
#! /bin/sh
|
||||||
|
|
||||||
|
echo " PDF documentation.org"
|
||||||
|
emacs -nw --batch \
|
||||||
|
--eval "(require 'org)" \
|
||||||
|
--eval "(require 'ox-latex)" \
|
||||||
|
--eval "(load-file \"../tools/setup.el\")" \
|
||||||
|
--file ./documentation.org \
|
||||||
|
-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
|
||||||
Symlink
+1
@@ -0,0 +1 @@
|
|||||||
|
../tools/ref.bib
|
||||||
@@ -0,0 +1,20 @@
|
|||||||
|
#+STARTUP: indent
|
||||||
|
|
||||||
|
#+INCLUDE: ../tools/macro.org
|
||||||
|
#+INCLUDE: ../tools/latex.org
|
||||||
|
|
||||||
|
#+TITLE: User documentation
|
||||||
|
#+SUBTITLE: Version: {{{version}}}
|
||||||
|
#+AUTHOR: {{{INRAE}}}
|
||||||
|
|
||||||
|
#+OPTIONS: toc:t
|
||||||
|
#+LANGUAGE: UKenglish
|
||||||
|
|
||||||
|
* TODO Over view
|
||||||
|
* TODO Get started
|
||||||
|
** Installation
|
||||||
|
*** Linux
|
||||||
|
*** Windows
|
||||||
|
* TODO Usage
|
||||||
|
|
||||||
|
{{{biblio}}}
|
||||||
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"
|
||||||
@@ -0,0 +1,60 @@
|
|||||||
|
rem windows.bat -- Pamhyr Windows batch for windows version building
|
||||||
|
rem Copyright (C) 2023 INRAE
|
||||||
|
rem
|
||||||
|
rem This program is free software: you can redistribute it and/or modify
|
||||||
|
rem it under the terms of the GNU General Public License as published by
|
||||||
|
rem the Free Software Foundation, either version 3 of the License, or
|
||||||
|
rem (at your option) any later version.
|
||||||
|
rem
|
||||||
|
rem This program is distributed in the hope that it will be useful,
|
||||||
|
rem but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
rem MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
rem GNU General Public License for more details.
|
||||||
|
rem
|
||||||
|
rem You should have received a copy of the GNU General Public License
|
||||||
|
rem along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
@ECHO ON
|
||||||
|
|
||||||
|
mkdir pamhyr\pamhyr\_internal
|
||||||
|
xcopy /s /e /y dist\pamhyr pamhyr\pamhyr
|
||||||
|
|
||||||
|
rem Copy data
|
||||||
|
mkdir pamhyr\pamhyr\_internal\lang
|
||||||
|
mkdir pamhyr\pamhyr\_internal\View\ui\ressources
|
||||||
|
mkdir pamhyr\pamhyr\_internal\View\ui\Widgets
|
||||||
|
|
||||||
|
rem UI
|
||||||
|
copy /y ..\src\View\ui\ressources\ pamhyr\pamhyr\_internal\View\ui\ressources
|
||||||
|
copy /y ..\src\View\ui\Widgets\*.ui pamhyr\pamhyr\_internal\View\ui\Widgets
|
||||||
|
copy /y ..\src\View\ui\*.ui pamhyr\pamhyr\_internal\View\ui\
|
||||||
|
|
||||||
|
rem Lang
|
||||||
|
copy /y ..\src\lang\*.qm pamhyr\pamhyr\_internal\lang\
|
||||||
|
|
||||||
|
rem Information
|
||||||
|
copy /y ..\VERSION pamhyr\pamhyr\_internal
|
||||||
|
copy /y ..\AUTHORS pamhyr\pamhyr\_internal
|
||||||
|
copy /y ..\LICENSE pamhyr\pamhyr\_internal
|
||||||
|
|
||||||
|
rem MAGE
|
||||||
|
mkdir pamhyr\mage
|
||||||
|
copy /y ..\mage-windows\mage.exe pamhyr\mage\
|
||||||
|
copy /y ..\mage-windows\mage_extraire.exe pamhyr\mage\
|
||||||
|
copy /y ..\mage-windows\mailleurPF.exe pamhyr\mage\
|
||||||
|
|
||||||
|
rem Copy tests_cases
|
||||||
|
mkdir pamhyr\tests_cases
|
||||||
|
mkdir pamhyr\tests_cases\Saar
|
||||||
|
copy /y ..\tests_cases\Saar\Saar.pamhyr pamhyr\tests_cases\Saar\
|
||||||
|
|
||||||
|
rem Documentations
|
||||||
|
mkdir pamhyr\doc
|
||||||
|
mkdir pamhyr\doc\images
|
||||||
|
copy /y ..\doc\users\documentation.pdf pamhyr\doc\Pamhyr2-users.pdf
|
||||||
|
copy /y ..\doc\dev\documentation.pdf pamhyr\doc\Pamhyr2-dev.pdf
|
||||||
|
copy /y ..\doc\users\documentation.html pamhyr\doc\Pamhyr2-users.html
|
||||||
|
copy /y ..\doc\dev\documentation.html pamhyr\doc\Pamhyr2-dev.html
|
||||||
|
copy /y ..\doc\users\images\* pamhyr\doc\images
|
||||||
|
copy /y ..\doc\dev\images\* pamhyr\doc\images
|
||||||
|
copy /y ..\doc\images\* pamhyr\doc\images
|
||||||
@@ -0,0 +1,20 @@
|
|||||||
|
rem windows.bat -- Pamhyr Windows batch for windows version building
|
||||||
|
rem Copyright (C) 2023 INRAE
|
||||||
|
rem
|
||||||
|
rem This program is free software: you can redistribute it and/or modify
|
||||||
|
rem it under the terms of the GNU General Public License as published by
|
||||||
|
rem the Free Software Foundation, either version 3 of the License, or
|
||||||
|
rem (at your option) any later version.
|
||||||
|
rem
|
||||||
|
rem This program is distributed in the hope that it will be useful,
|
||||||
|
rem but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
rem MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
rem GNU General Public License for more details.
|
||||||
|
rem
|
||||||
|
rem You should have received a copy of the GNU General Public License
|
||||||
|
rem along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
@ECHO ON
|
||||||
|
|
||||||
|
rem Make installer
|
||||||
|
"C:\Program Files (x86)\NSIS\makensis.exe" pamhyr.nsi
|
||||||
+23
-19
@@ -3,17 +3,17 @@
|
|||||||
!define LIC_NAME "LICENSE"
|
!define LIC_NAME "LICENSE"
|
||||||
!define APP_NAME "PAMHYR"
|
!define APP_NAME "PAMHYR"
|
||||||
|
|
||||||
Name "PAMHYR"
|
Name "Pamhyr2"
|
||||||
OutFile "pamhyr-win-amd64.exe"
|
OutFile "pamhyr-windows.exe"
|
||||||
LicenseData "..\LICENSE"
|
LicenseData "pamhyr\pamhyr\_internal\LICENSE"
|
||||||
LicenseText "I Agree"
|
LicenseText "I Agree"
|
||||||
|
|
||||||
RequestExecutionLevel admin
|
RequestExecutionLevel admin
|
||||||
|
|
||||||
Unicode True
|
Unicode True
|
||||||
InstallDir $PROGRAMFILES\PAMHYR
|
InstallDir $PROGRAMFILES\Pamhyr2
|
||||||
|
|
||||||
InstallDirRegKey HKLM "Software\PAMHYR" "Install_Dir"
|
InstallDirRegKey HKLM "Software\Pamhyr2" "Install_Dir"
|
||||||
|
|
||||||
Page license
|
Page license
|
||||||
Page components
|
Page components
|
||||||
@@ -23,35 +23,39 @@ Page instfiles
|
|||||||
UninstPage uninstConfirm
|
UninstPage uninstConfirm
|
||||||
UninstPage instfiles
|
UninstPage instfiles
|
||||||
|
|
||||||
Section "PAMHYR"
|
Section "Pamhyr2"
|
||||||
SectionIn RO
|
SectionIn RO
|
||||||
|
|
||||||
SetOutPath $INSTDIR
|
SetOutPath $INSTDIR
|
||||||
|
|
||||||
File /r "dist\pamhyr\*"
|
File /r "pamhyr\*"
|
||||||
|
|
||||||
WriteRegStr HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\PAMHYR" "DisplayName" "NSIS PAMHYR"
|
WriteRegStr HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\Pamhyr2" "DisplayName" "NSIS Pamhyr2"
|
||||||
WriteRegStr HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\PAMHYR" "UninstallString" "$INSTDIR\uninstall.exe"
|
WriteRegStr HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\Pamhyr2" "UninstallString" "$INSTDIR\uninstall.exe"
|
||||||
WriteRegDWORD HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\PAMHYR" "NoModify" 1
|
WriteRegDWORD HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\Pamhyr2" "NoModify" 1
|
||||||
WriteRegDWORD HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\PAMHYR" "NoRepair" 1
|
WriteRegDWORD HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\Pamhyr2" "NoRepair" 1
|
||||||
WriteUninstaller "$INSTDIR\uninstall.exe"
|
WriteUninstaller "$INSTDIR\uninstall.exe"
|
||||||
|
|
||||||
SectionEnd
|
SectionEnd
|
||||||
|
|
||||||
Section "Start Menu Shortcuts"
|
Section "Start Menu Shortcuts"
|
||||||
|
CreateDirectory "$SMPROGRAMS\Pamhyr2"
|
||||||
|
CreateShortcut "$SMPROGRAMS\Pamhyr2\Uninstall.lnk" "$INSTDIR\uninstall.exe"
|
||||||
|
CreateShortcut "$SMPROGRAMS\Pamhyr2\Pamhyr2.lnk" "$INSTDIR\pamhyr\pamhyr.exe"
|
||||||
|
SectionEnd
|
||||||
|
|
||||||
CreateDirectory "$SMPROGRAMS\PAMHYR"
|
Section "Desktop Shortcuts"
|
||||||
CreateShortcut "$SMPROGRAMS\PAMHYR\Uninstall.lnk" "$INSTDIR\uninstall.exe"
|
SetShellVarContext all
|
||||||
CreateShortcut "$SMPROGRAMS\PAMHYR\PAMHYR.lnk" "$INSTDIR\pamhyr.exe"
|
CreateShortcut "$desktop\Pamhyr2.lnk" "$instdir\pamhyr\pamhyr.exe"
|
||||||
|
|
||||||
SectionEnd
|
SectionEnd
|
||||||
|
|
||||||
Section "Uninstall"
|
Section "Uninstall"
|
||||||
DeleteRegKey HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\PAMHYR"
|
DeleteRegKey HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\Pamhyr2"
|
||||||
DeleteRegKey HKLM SOFTWARE\NSIS_PAMHYR
|
DeleteRegKey HKLM SOFTWARE\NSIS_Pamhyr2
|
||||||
|
|
||||||
Delete "$SMPROGRAMS\PAMHYR\*.lnk"
|
Delete "$SMPROGRAMS\Pamhyr2\*.lnk"
|
||||||
|
Delete "$desktop\Pamhyr2.lnk"
|
||||||
|
|
||||||
RMDir "$SMPROGRAMS\PAMHYR"
|
RMDir "$SMPROGRAMS\Pamhyr2"
|
||||||
RMDir /R "$INSTDIR"
|
RMDir /R "$INSTDIR"
|
||||||
SectionEnd
|
SectionEnd
|
||||||
+45
-16
@@ -81,13 +81,42 @@ wine pyinstaller ../src/pamhyr.py -y
|
|||||||
|
|
||||||
echo " *** COPY DATA"
|
echo " *** COPY DATA"
|
||||||
|
|
||||||
mkdir -p dist/pamhyr/View/ui
|
mkdir -p pamhyr
|
||||||
cp -r ../src/View/ui/ressources/ dist/pamhyr/View/ui/
|
mkdir -p pamhyr/pamhyr
|
||||||
cp -r ../src/View/ui/Widgets/*.ui dist/pamhyr/View/ui/
|
|
||||||
cp -r ../src/View/ui/*.ui dist/pamhyr/View/ui/
|
|
||||||
|
|
||||||
cp ../VERSION dist/pamhyr/
|
# Copy Pamhyr info
|
||||||
cp ../AUTHORS dist/pamhyr/
|
cp -v ../VERSION pamhyr/pamhyr/
|
||||||
|
cp -v ../AUTHORS pamhyr/pamhyr/
|
||||||
|
cp -v ../LICENSE pamhyr/pamhyr/
|
||||||
|
|
||||||
|
# Copy mage
|
||||||
|
mkdir -p pamhyr/mage
|
||||||
|
cp -v ../mage/* pamhyr/mage/
|
||||||
|
|
||||||
|
# Copy Pamhyr
|
||||||
|
cp -r dist/pamhyr pamhyr/
|
||||||
|
|
||||||
|
# Copy Pamhyr resources
|
||||||
|
mkdir -p pamhyr/pamhyr/View
|
||||||
|
mkdir -p pamhyr/pamhyr/View/ui
|
||||||
|
mkdir -p pamhyr/pamhyr/View/ui/Widgets
|
||||||
|
cp -r ../src/View/ui/*.ui pamhyr/pamhyr/View/ui/
|
||||||
|
cp -r ../src/View/ui/ressources/ pamhyr/pamhyr/View/ui
|
||||||
|
cp -r ../src/View/ui/Widgets/*.ui pamhyr/pamhyr/View/ui/Widgets
|
||||||
|
|
||||||
|
# Copy lang
|
||||||
|
mkdir -p pamhyr/pamhyr/lang
|
||||||
|
cp -r ../src/lang/*.qm pamhyr/pamhyr/lang
|
||||||
|
|
||||||
|
# Copy tests cases
|
||||||
|
mkdir -p pamhyr/tests_cases/
|
||||||
|
mkdir -p pamhyr/tests_cases/Saar
|
||||||
|
cp ../tests_cases/Saar/Saar.pamhyr pamhyr/tests_cases/Saar/
|
||||||
|
|
||||||
|
# Copy documentations
|
||||||
|
mkdir -p pamhyr/doc/
|
||||||
|
cp ../doc/users/documentation.pdf pamhyr/doc/Pamhyr2-users.pdf
|
||||||
|
cp ../doc/dev/documentation.pdf pamhyr/doc/Pamhyr2-dev.pdf
|
||||||
|
|
||||||
# Update TS and build QM files
|
# Update TS and build QM files
|
||||||
OLD_PWD=$PWD
|
OLD_PWD=$PWD
|
||||||
@@ -102,19 +131,19 @@ echo " *** MAKE PACKAGES"
|
|||||||
|
|
||||||
echo " TAR pamhyr-win-amd64.tar.xz"
|
echo " TAR pamhyr-win-amd64.tar.xz"
|
||||||
|
|
||||||
OLD_PWD=$PWD
|
# OLD_PWD=$PWD
|
||||||
cd dist/
|
# cd dist/
|
||||||
tar --xz -cf pamhyr-win-amd64.tar.xz pamhyr --checkpoint=.100
|
# tar --xz -cf pamhyr-win-amd64.tar.xz pamhyr --checkpoint=.100
|
||||||
cd $OLD_PWD
|
# cd $OLD_PWD
|
||||||
mv dist/pamhyr-win-amd64.tar.xz ./
|
# mv dist/pamhyr-win-amd64.tar.xz ./
|
||||||
|
|
||||||
echo " ZIP pamhyr-win-amd64.zip"
|
echo " ZIP pamhyr-win-amd64.zip"
|
||||||
|
|
||||||
OLD_PWD=$PWD
|
# OLD_PWD=$PWD
|
||||||
cd dist/
|
# cd dist/
|
||||||
zip -r pamhyr-win-amd64.zip pamhyr/
|
# zip -r pamhyr-win-amd64.zip pamhyr/
|
||||||
cd $OLD_PWD
|
# cd $OLD_PWD
|
||||||
mv dist/pamhyr-win-amd64.zip ./
|
# mv dist/pamhyr-win-amd64.zip ./
|
||||||
|
|
||||||
echo " *** MAKE INSTALLER"
|
echo " *** MAKE INSTALLER"
|
||||||
|
|
||||||
|
|||||||
+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
|
||||||
|
|||||||
@@ -1,10 +0,0 @@
|
|||||||
# -*- coding: utf-8 -*-
|
|
||||||
|
|
||||||
class AbstractModelComponent(object):
|
|
||||||
def __init__(self):
|
|
||||||
super(AbstractModelComponent, self).__init__()
|
|
||||||
|
|
||||||
def new(self, filename):
|
|
||||||
|
|
||||||
|
|
||||||
def export(self, filename):
|
|
||||||
@@ -20,7 +20,7 @@ import logging
|
|||||||
|
|
||||||
from tools import trace, timer, old_pamhyr_date_to_timestamp
|
from tools import trace, timer, old_pamhyr_date_to_timestamp
|
||||||
|
|
||||||
from Model.DB import SQLSubModel
|
from Model.Tools.PamhyrDB import SQLSubModel
|
||||||
from Model.Except import NotImplementedMethodeError
|
from Model.Except import NotImplementedMethodeError
|
||||||
|
|
||||||
logger = logging.getLogger()
|
logger = logging.getLogger()
|
||||||
|
|||||||
@@ -19,7 +19,7 @@
|
|||||||
from copy import copy
|
from copy import copy
|
||||||
from tools import trace, timer
|
from tools import trace, timer
|
||||||
|
|
||||||
from Model.DB import SQLSubModel
|
from Model.Tools.PamhyrList import PamhyrModelListWithTab
|
||||||
from Model.Except import NotImplementedMethodeError
|
from Model.Except import NotImplementedMethodeError
|
||||||
|
|
||||||
from Model.BoundaryCondition.BoundaryCondition import BoundaryCondition
|
from Model.BoundaryCondition.BoundaryCondition import BoundaryCondition
|
||||||
@@ -30,30 +30,12 @@ from Model.BoundaryCondition.BoundaryConditionTypes import (
|
|||||||
Solid,
|
Solid,
|
||||||
)
|
)
|
||||||
|
|
||||||
class BoundaryConditionList(SQLSubModel):
|
class BoundaryConditionList(PamhyrModelListWithTab):
|
||||||
|
_tabs_list = ["liquid", "solid", "suspenssion"]
|
||||||
_sub_classes = [
|
_sub_classes = [
|
||||||
BoundaryCondition,
|
BoundaryCondition,
|
||||||
]
|
]
|
||||||
|
|
||||||
def __init__(self, status = None):
|
|
||||||
super(BoundaryConditionList, self).__init__()
|
|
||||||
|
|
||||||
self._status = status
|
|
||||||
|
|
||||||
self._tabs = {
|
|
||||||
"liquid" : [],
|
|
||||||
"solid" : [],
|
|
||||||
"suspenssion" : []
|
|
||||||
}
|
|
||||||
|
|
||||||
@classmethod
|
|
||||||
def _sql_create(cls, execute):
|
|
||||||
return cls._create_submodel(execute)
|
|
||||||
|
|
||||||
@classmethod
|
|
||||||
def _sql_update(cls, execute, version):
|
|
||||||
return True
|
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def _sql_load(cls, execute, data = None):
|
def _sql_load(cls, execute, data = None):
|
||||||
new = cls(status = data['status'])
|
new = cls(status = data['status'])
|
||||||
@@ -82,66 +64,12 @@ class BoundaryConditionList(SQLSubModel):
|
|||||||
|
|
||||||
return True
|
return True
|
||||||
|
|
||||||
def len(self, lst):
|
|
||||||
return len(self._tabs[lst])
|
|
||||||
|
|
||||||
def get_tab(self, lst):
|
|
||||||
return self._tabs[lst].copy()
|
|
||||||
|
|
||||||
def get(self, lst, row):
|
|
||||||
return self._tabs[lst][row]
|
|
||||||
|
|
||||||
def set(self, lst, row, new):
|
|
||||||
self._tabs[lst][row] = new
|
|
||||||
self._status.modified()
|
|
||||||
|
|
||||||
def new(self, lst, index):
|
def new(self, lst, index):
|
||||||
n = NotDefined(status=self._status)
|
n = NotDefined(status=self._status)
|
||||||
self._tabs[lst].insert(index, n)
|
self._tabs[lst].insert(index, n)
|
||||||
self._status.modified()
|
self._status.modified()
|
||||||
return n
|
return n
|
||||||
|
|
||||||
def insert(self, lst, index, new):
|
|
||||||
self._tabs[lst].insert(index, new)
|
|
||||||
self._status.modified()
|
|
||||||
|
|
||||||
def delete(self, lst, bcs):
|
|
||||||
for bc in bcs:
|
|
||||||
self._tabs[lst].remove(bc)
|
|
||||||
self._status.modified()
|
|
||||||
|
|
||||||
def delete_i(self, lst, indexes):
|
|
||||||
bcs = list(
|
|
||||||
map(
|
|
||||||
lambda x: x[1],
|
|
||||||
filter(
|
|
||||||
lambda x: x[0] in indexes,
|
|
||||||
enumerate(self._tabs[lst])
|
|
||||||
)
|
|
||||||
)
|
|
||||||
)
|
|
||||||
self.delete(lst, bcs)
|
|
||||||
|
|
||||||
def sort(self, lst, reverse=False, key=None):
|
|
||||||
self._tabs[lst].sort(reverse=reverse, key=key)
|
|
||||||
self._status.modified()
|
|
||||||
|
|
||||||
def move_up(self, lst, index):
|
|
||||||
if index < len(self._tabs[lst]):
|
|
||||||
next = index - 1
|
|
||||||
|
|
||||||
l = self._tabs[lst]
|
|
||||||
l[index], l[next] = l[next], l[index]
|
|
||||||
self._status.modified()
|
|
||||||
|
|
||||||
def move_down(self, lst, index):
|
|
||||||
if index >= 0:
|
|
||||||
prev = index + 1
|
|
||||||
|
|
||||||
l = self._tabs[lst]
|
|
||||||
l[index], l[prev] = l[prev], l[index]
|
|
||||||
self._status.modified()
|
|
||||||
|
|
||||||
def __copy__(self):
|
def __copy__(self):
|
||||||
new = BoundaryConditionList()
|
new = BoundaryConditionList()
|
||||||
|
|
||||||
|
|||||||
@@ -18,7 +18,7 @@
|
|||||||
|
|
||||||
from tools import trace, timer
|
from tools import trace, timer
|
||||||
|
|
||||||
from Model.DB import SQLSubModel
|
from Model.Tools.PamhyrDB import SQLSubModel
|
||||||
|
|
||||||
class Friction(SQLSubModel):
|
class Friction(SQLSubModel):
|
||||||
def __init__(self, name:str = "", status = None):
|
def __init__(self, name:str = "", status = None):
|
||||||
|
|||||||
@@ -21,26 +21,18 @@ import logging
|
|||||||
from copy import copy
|
from copy import copy
|
||||||
from tools import trace, timer
|
from tools import trace, timer
|
||||||
|
|
||||||
from Model.DB import SQLSubModel
|
from Model.Tools.PamhyrDB import SQLSubModel
|
||||||
|
from Model.Tools.PamhyrList import PamhyrModelList
|
||||||
|
|
||||||
from Model.Friction.Friction import Friction
|
from Model.Friction.Friction import Friction
|
||||||
|
|
||||||
logger = logging.getLogger()
|
logger = logging.getLogger()
|
||||||
|
|
||||||
class FrictionList(SQLSubModel):
|
class FrictionList(PamhyrModelList):
|
||||||
_sub_classes = [
|
_sub_classes = [
|
||||||
Friction
|
Friction
|
||||||
]
|
]
|
||||||
|
|
||||||
def __init__(self, status = None):
|
|
||||||
super(FrictionList, self).__init__()
|
|
||||||
|
|
||||||
self._status = status
|
|
||||||
self._frictions = []
|
|
||||||
|
|
||||||
@classmethod
|
|
||||||
def _sql_create(cls, execute):
|
|
||||||
return cls._create_submodel(execute)
|
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def _sql_update_0_0_1(cls, execute, version):
|
def _sql_update_0_0_1(cls, execute, version):
|
||||||
execute("ALTER TABLE `section` RENAME TO `friction`")
|
execute("ALTER TABLE `section` RENAME TO `friction`")
|
||||||
@@ -57,7 +49,7 @@ class FrictionList(SQLSubModel):
|
|||||||
def _sql_load(cls, execute, data = None):
|
def _sql_load(cls, execute, data = None):
|
||||||
new = cls(status = data['status'])
|
new = cls(status = data['status'])
|
||||||
|
|
||||||
new._frictions = Friction._sql_load(
|
new._lst = Friction._sql_load(
|
||||||
execute, data
|
execute, data
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -69,70 +61,19 @@ class FrictionList(SQLSubModel):
|
|||||||
|
|
||||||
ok = True
|
ok = True
|
||||||
ind = 0
|
ind = 0
|
||||||
for friction in self._frictions:
|
for friction in self._lst:
|
||||||
data["ind"] = ind
|
data["ind"] = ind
|
||||||
ok &= friction._sql_save(execute, data = data)
|
ok &= friction._sql_save(execute, data = data)
|
||||||
ind += 1
|
ind += 1
|
||||||
|
|
||||||
return ok
|
return ok
|
||||||
|
|
||||||
def __len__(self):
|
|
||||||
return len(self._frictions)
|
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def frictions(self):
|
def frictions(self):
|
||||||
return self._frictions.copy()
|
return self.lst
|
||||||
|
|
||||||
def get(self, row):
|
|
||||||
return self._frictions[row]
|
|
||||||
|
|
||||||
def set(self, row, new):
|
|
||||||
self._frictions[row] = new
|
|
||||||
self._status.modified()
|
|
||||||
|
|
||||||
def new(self, index):
|
def new(self, index):
|
||||||
n = Friction(status = self._status)
|
n = Friction(status = self._status)
|
||||||
self._frictions.insert(index, n)
|
self._lst.insert(index, n)
|
||||||
self._status.modified()
|
self._status.modified()
|
||||||
return n
|
return n
|
||||||
|
|
||||||
def insert(self, index, new):
|
|
||||||
self._frictions.insert(index, new)
|
|
||||||
self._status.modified()
|
|
||||||
|
|
||||||
def delete(self, frictions):
|
|
||||||
for friction in frictions:
|
|
||||||
self._frictions.remove(friction)
|
|
||||||
self._status.modified()
|
|
||||||
|
|
||||||
def delete_i(self, indexes):
|
|
||||||
frictions = list(
|
|
||||||
map(
|
|
||||||
lambda x: x[1],
|
|
||||||
filter(
|
|
||||||
lambda x: x[0] in indexes,
|
|
||||||
enumerate(self._frictions)
|
|
||||||
)
|
|
||||||
)
|
|
||||||
)
|
|
||||||
self.delete(frictions)
|
|
||||||
|
|
||||||
def sort(self, reverse=False, key=None):
|
|
||||||
self._frictions.sort(reverse=reverse, key=key)
|
|
||||||
self._status.modified()
|
|
||||||
|
|
||||||
def move_up(self, index):
|
|
||||||
if index < len(self._frictions):
|
|
||||||
next = index - 1
|
|
||||||
|
|
||||||
l = self._frictions
|
|
||||||
l[index], l[next] = l[next], l[index]
|
|
||||||
self._status.modified()
|
|
||||||
|
|
||||||
def move_down(self, index):
|
|
||||||
if index >= 0:
|
|
||||||
prev = index + 1
|
|
||||||
|
|
||||||
l = self._frictions
|
|
||||||
l[index], l[prev] = l[prev], l[index]
|
|
||||||
self._status.modified()
|
|
||||||
@@ -40,8 +40,8 @@ class Point(object):
|
|||||||
def sl(self, sl):
|
def sl(self, sl):
|
||||||
if sl == self._profile.sl:
|
if sl == self._profile.sl:
|
||||||
self._sl = None
|
self._sl = None
|
||||||
|
else:
|
||||||
self._sl = sl
|
self._sl = sl
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def name(self):
|
def name(self):
|
||||||
|
|||||||
@@ -19,7 +19,7 @@
|
|||||||
from math import dist
|
from math import dist
|
||||||
import numpy as np
|
import numpy as np
|
||||||
|
|
||||||
from Model.DB import SQLSubModel
|
from Model.Tools.PamhyrDB import SQLSubModel
|
||||||
from Model.Geometry.Point import Point
|
from Model.Geometry.Point import Point
|
||||||
|
|
||||||
class PointXYZ(Point, SQLSubModel):
|
class PointXYZ(Point, SQLSubModel):
|
||||||
|
|||||||
@@ -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)
|
||||||
|
|||||||
@@ -21,7 +21,7 @@ from typing import List
|
|||||||
|
|
||||||
from tools import timer
|
from tools import timer
|
||||||
|
|
||||||
from Model.DB import SQLSubModel
|
from Model.Tools.PamhyrDB import SQLSubModel
|
||||||
from Model.Except import ClipboardFormatError
|
from Model.Except import ClipboardFormatError
|
||||||
from Model.Geometry.Profile import Profile
|
from Model.Geometry.Profile import Profile
|
||||||
from Model.Geometry.PointXYZ import PointXYZ
|
from Model.Geometry.PointXYZ import PointXYZ
|
||||||
|
|||||||
@@ -27,7 +27,7 @@ from functools import reduce
|
|||||||
|
|
||||||
from tools import flatten, timer, trace
|
from tools import flatten, timer, trace
|
||||||
|
|
||||||
from Model.DB import SQLSubModel
|
from Model.Tools.PamhyrDB import SQLSubModel
|
||||||
|
|
||||||
from Model.Geometry.Profile import Profile
|
from Model.Geometry.Profile import Profile
|
||||||
from Model.Geometry.ProfileXYZ import ProfileXYZ
|
from Model.Geometry.ProfileXYZ import ProfileXYZ
|
||||||
@@ -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()
|
||||||
|
|||||||
@@ -20,7 +20,7 @@ from copy import copy, deepcopy
|
|||||||
from tools import trace, timer
|
from tools import trace, timer
|
||||||
from functools import reduce
|
from functools import reduce
|
||||||
|
|
||||||
from Model.DB import SQLSubModel
|
from Model.Tools.PamhyrDB import SQLSubModel
|
||||||
|
|
||||||
class Data(SQLSubModel):
|
class Data(SQLSubModel):
|
||||||
def __init__(self, name:str = "",
|
def __init__(self, name:str = "",
|
||||||
|
|||||||
@@ -19,29 +19,14 @@
|
|||||||
from copy import copy
|
from copy import copy
|
||||||
from tools import trace, timer
|
from tools import trace, timer
|
||||||
|
|
||||||
from Model.DB import SQLSubModel
|
from Model.Tools.PamhyrDict import PamhyrModelDict
|
||||||
from Model.InitialConditions.InitialConditions import InitialConditions
|
from Model.InitialConditions.InitialConditions import InitialConditions
|
||||||
|
|
||||||
class InitialConditionsDict(SQLSubModel):
|
class InitialConditionsDict(PamhyrModelDict):
|
||||||
_sub_classes = [
|
_sub_classes = [
|
||||||
InitialConditions,
|
InitialConditions,
|
||||||
]
|
]
|
||||||
|
|
||||||
def __init__(self, status = None):
|
|
||||||
super(InitialConditionsDict, self).__init__()
|
|
||||||
|
|
||||||
self._status = status
|
|
||||||
|
|
||||||
self._reach = {}
|
|
||||||
|
|
||||||
@classmethod
|
|
||||||
def _sql_create(cls, execute):
|
|
||||||
return cls._create_submodel(execute)
|
|
||||||
|
|
||||||
@classmethod
|
|
||||||
def _sql_update(cls, execute, version):
|
|
||||||
return cls._update_submodel(execute, version)
|
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def _sql_load(cls, execute, data = None):
|
def _sql_load(cls, execute, data = None):
|
||||||
new = cls(status = data["status"])
|
new = cls(status = data["status"])
|
||||||
@@ -55,7 +40,7 @@ class InitialConditionsDict(SQLSubModel):
|
|||||||
)
|
)
|
||||||
|
|
||||||
if ic is not None:
|
if ic is not None:
|
||||||
new._reach[reach] = ic
|
new._dict[reach] = ic
|
||||||
|
|
||||||
return new
|
return new
|
||||||
|
|
||||||
@@ -66,30 +51,12 @@ class InitialConditionsDict(SQLSubModel):
|
|||||||
|
|
||||||
execute("DELETE FROM initial_conditions")
|
execute("DELETE FROM initial_conditions")
|
||||||
|
|
||||||
for reach in self._reach:
|
for reach in self._dict:
|
||||||
data["reach"] = reach
|
data["reach"] = reach
|
||||||
ok &= self._reach[reach]._sql_save(execute, data)
|
ok &= self._dict[reach]._sql_save(execute, data)
|
||||||
|
|
||||||
return ok
|
return ok
|
||||||
|
|
||||||
def __len__(self):
|
|
||||||
return len(self._reach)
|
|
||||||
|
|
||||||
def is_defined(self, reach):
|
|
||||||
return reach in self._reach
|
|
||||||
|
|
||||||
def get(self, reach):
|
|
||||||
if reach in self._reach:
|
|
||||||
return self._reach[reach]
|
|
||||||
|
|
||||||
new = self.new(reach)
|
|
||||||
self.set(reach, new)
|
|
||||||
return new
|
|
||||||
|
|
||||||
def set(self, reach, new):
|
|
||||||
self._reach[reach] = new
|
|
||||||
self._status.modified()
|
|
||||||
|
|
||||||
def new(self, reach):
|
def new(self, reach):
|
||||||
new = InitialConditions(reach = reach, status = self._status)
|
new = InitialConditions(reach = reach, status = self._status)
|
||||||
self.set(reach, new)
|
self.set(reach, new)
|
||||||
|
|||||||
@@ -20,7 +20,7 @@ import logging
|
|||||||
|
|
||||||
from tools import trace, timer, old_pamhyr_date_to_timestamp
|
from tools import trace, timer, old_pamhyr_date_to_timestamp
|
||||||
|
|
||||||
from Model.DB import SQLSubModel
|
from Model.Tools.PamhyrDB import SQLSubModel
|
||||||
from Model.Except import NotImplementedMethodeError
|
from Model.Except import NotImplementedMethodeError
|
||||||
|
|
||||||
logger = logging.getLogger()
|
logger = logging.getLogger()
|
||||||
|
|||||||
@@ -19,7 +19,7 @@
|
|||||||
from copy import copy
|
from copy import copy
|
||||||
from tools import trace, timer
|
from tools import trace, timer
|
||||||
|
|
||||||
from Model.DB import SQLSubModel
|
from Model.Tools.PamhyrList import PamhyrModelListWithTab
|
||||||
from Model.Except import NotImplementedMethodeError
|
from Model.Except import NotImplementedMethodeError
|
||||||
|
|
||||||
from Model.LateralContribution.LateralContribution import LateralContribution
|
from Model.LateralContribution.LateralContribution import LateralContribution
|
||||||
@@ -27,30 +27,12 @@ from Model.LateralContribution.LateralContributionTypes import (
|
|||||||
NotDefined, LateralContrib, Rain, Evaporation,
|
NotDefined, LateralContrib, Rain, Evaporation,
|
||||||
)
|
)
|
||||||
|
|
||||||
class LateralContributionList(SQLSubModel):
|
class LateralContributionList(PamhyrModelListWithTab):
|
||||||
|
_tabs_list = ["liquid", "solid", "suspenssion"]
|
||||||
_sub_classes = [
|
_sub_classes = [
|
||||||
LateralContribution,
|
LateralContribution,
|
||||||
]
|
]
|
||||||
|
|
||||||
def __init__(self, status = None):
|
|
||||||
super(LateralContributionList, self).__init__()
|
|
||||||
|
|
||||||
self._status = status
|
|
||||||
|
|
||||||
self._tabs = {
|
|
||||||
"liquid" : [],
|
|
||||||
"solid" : [],
|
|
||||||
"suspenssion" : []
|
|
||||||
}
|
|
||||||
|
|
||||||
@classmethod
|
|
||||||
def _sql_create(cls, execute):
|
|
||||||
return cls._create_submodel(execute)
|
|
||||||
|
|
||||||
@classmethod
|
|
||||||
def _sql_update(cls, execute, version):
|
|
||||||
return True
|
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def _sql_load(cls, execute, data = None):
|
def _sql_load(cls, execute, data = None):
|
||||||
new = cls(status = data['status'])
|
new = cls(status = data['status'])
|
||||||
@@ -79,66 +61,12 @@ class LateralContributionList(SQLSubModel):
|
|||||||
|
|
||||||
return True
|
return True
|
||||||
|
|
||||||
def len(self, lst):
|
|
||||||
return len(self._tabs[lst])
|
|
||||||
|
|
||||||
def get_tab(self, lst):
|
|
||||||
return self._tabs[lst].copy()
|
|
||||||
|
|
||||||
def get(self, lst, row):
|
|
||||||
return self._tabs[lst][row]
|
|
||||||
|
|
||||||
def set(self, lst, row, new):
|
|
||||||
self._tabs[lst][row] = new
|
|
||||||
self._status.modified()
|
|
||||||
|
|
||||||
def new(self, lst, index):
|
def new(self, lst, index):
|
||||||
n = NotDefined(status=self._status)
|
n = NotDefined(status=self._status)
|
||||||
self._tabs[lst].insert(index, n)
|
self._tabs[lst].insert(index, n)
|
||||||
self._status.modified()
|
self._status.modified()
|
||||||
return n
|
return n
|
||||||
|
|
||||||
def insert(self, lst, index, new):
|
|
||||||
self._tabs[lst].insert(index, new)
|
|
||||||
self._status.modified()
|
|
||||||
|
|
||||||
def delete(self, lst, bcs):
|
|
||||||
for bc in bcs:
|
|
||||||
self._tabs[lst].remove(bc)
|
|
||||||
self._status.modified()
|
|
||||||
|
|
||||||
def delete_i(self, lst, indexes):
|
|
||||||
bcs = list(
|
|
||||||
map(
|
|
||||||
lambda x: x[1],
|
|
||||||
filter(
|
|
||||||
lambda x: x[0] in indexes,
|
|
||||||
enumerate(self._tabs[lst])
|
|
||||||
)
|
|
||||||
)
|
|
||||||
)
|
|
||||||
self.delete(lst, bcs)
|
|
||||||
|
|
||||||
def sort(self, lst, reverse=False, key=None):
|
|
||||||
self._tabs[lst].sort(reverse=reverse, key=key)
|
|
||||||
self._status.modified()
|
|
||||||
|
|
||||||
def move_up(self, lst, index):
|
|
||||||
if index < len(self._tabs[lst]):
|
|
||||||
next = index - 1
|
|
||||||
|
|
||||||
l = self._tabs[lst]
|
|
||||||
l[index], l[next] = l[next], l[index]
|
|
||||||
self._status.modified()
|
|
||||||
|
|
||||||
def move_down(self, lst, index):
|
|
||||||
if index >= 0:
|
|
||||||
prev = index + 1
|
|
||||||
|
|
||||||
l = self._tabs[lst]
|
|
||||||
l[index], l[prev] = l[prev], l[index]
|
|
||||||
self._status.modified()
|
|
||||||
|
|
||||||
def __copy__(self):
|
def __copy__(self):
|
||||||
new = LateralContributionList()
|
new = LateralContributionList()
|
||||||
|
|
||||||
|
|||||||
@@ -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
-5
@@ -18,7 +18,7 @@
|
|||||||
|
|
||||||
from tools import flatten
|
from tools import flatten
|
||||||
|
|
||||||
from Model.DB import SQLSubModel
|
from Model.Tools.PamhyrDB import SQLSubModel
|
||||||
|
|
||||||
from Model.Network.Node import Node
|
from Model.Network.Node import Node
|
||||||
from Model.Network.Edge import Edge
|
from Model.Network.Edge import Edge
|
||||||
@@ -311,10 +311,6 @@ class River(Graph, SQLSubModel):
|
|||||||
self._save_submodel(execute, objs, data)
|
self._save_submodel(execute, objs, data)
|
||||||
return True
|
return True
|
||||||
|
|
||||||
@property
|
|
||||||
def frictions(self):
|
|
||||||
return self._frictions
|
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def boundary_condition(self):
|
def boundary_condition(self):
|
||||||
return self._boundary_condition
|
return self._boundary_condition
|
||||||
|
|||||||
@@ -2,7 +2,7 @@
|
|||||||
|
|
||||||
from tools import trace, timer
|
from tools import trace, timer
|
||||||
|
|
||||||
from Model.DB import SQLSubModel
|
from Model.Tools.PamhyrDB import SQLSubModel
|
||||||
from Model.Except import NotImplementedMethodeError
|
from Model.Except import NotImplementedMethodeError
|
||||||
|
|
||||||
class Layer(SQLSubModel):
|
class Layer(SQLSubModel):
|
||||||
|
|||||||
@@ -2,35 +2,18 @@
|
|||||||
|
|
||||||
from tools import trace, timer
|
from tools import trace, timer
|
||||||
|
|
||||||
from Model.DB import SQLSubModel
|
|
||||||
from Model.Except import NotImplementedMethodeError
|
from Model.Except import NotImplementedMethodeError
|
||||||
|
from Model.Tools.PamhyrList import PamhyrModelList
|
||||||
from Model.SedimentLayer.SedimentLayer import SedimentLayer
|
from Model.SedimentLayer.SedimentLayer import SedimentLayer
|
||||||
|
|
||||||
class SedimentLayerList(SQLSubModel):
|
class SedimentLayerList(PamhyrModelList):
|
||||||
_sub_classes = [SedimentLayer]
|
_sub_classes = [SedimentLayer]
|
||||||
|
|
||||||
def __init__(self, status = None):
|
|
||||||
super(SedimentLayerList, self).__init__()
|
|
||||||
|
|
||||||
self._status = status
|
|
||||||
self._sl = []
|
|
||||||
|
|
||||||
def __len__(self):
|
|
||||||
return len(self._sl)
|
|
||||||
|
|
||||||
@classmethod
|
|
||||||
def _sql_create(cls, execute):
|
|
||||||
return cls._create_submodel(execute)
|
|
||||||
|
|
||||||
@classmethod
|
|
||||||
def _sql_update(cls, execute, version):
|
|
||||||
return cls._update_submodel(execute, version)
|
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def _sql_load(cls, execute, data = None):
|
def _sql_load(cls, execute, data = None):
|
||||||
new = cls(status = data["status"])
|
new = cls(status = data["status"])
|
||||||
|
|
||||||
new._sl = SedimentLayer._sql_load(execute, data)
|
new._lst = SedimentLayer._sql_load(execute, data)
|
||||||
|
|
||||||
return new
|
return new
|
||||||
|
|
||||||
@@ -41,61 +24,17 @@ class SedimentLayerList(SQLSubModel):
|
|||||||
execute("DELETE FROM sedimentary_layer")
|
execute("DELETE FROM sedimentary_layer")
|
||||||
execute("DELETE FROM sedimentary_layer_layer")
|
execute("DELETE FROM sedimentary_layer_layer")
|
||||||
|
|
||||||
for sl in self._sl:
|
for sl in self._lst:
|
||||||
ok &= sl._sql_save(execute, data)
|
ok &= sl._sql_save(execute, data)
|
||||||
|
|
||||||
return ok
|
return ok
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def sediment_layers(self):
|
def sediment_layers(self):
|
||||||
return self._sl.copy()
|
return self.lst
|
||||||
|
|
||||||
def get(self, index):
|
|
||||||
return self._sl[index]
|
|
||||||
|
|
||||||
def set(self, index, new):
|
|
||||||
self._sl[index] = new
|
|
||||||
self._status.modified()
|
|
||||||
|
|
||||||
def insert(self, index, new):
|
|
||||||
self._sl.insert(index, new)
|
|
||||||
self._status.modified()
|
|
||||||
|
|
||||||
def new(self, index):
|
def new(self, index):
|
||||||
n = SedimentLayer(status = self._status)
|
n = SedimentLayer(status = self._status)
|
||||||
self.insert(index, n)
|
self.insert(index, n)
|
||||||
self._status.modified()
|
self._status.modified()
|
||||||
return n
|
return n
|
||||||
|
|
||||||
def delete(self, els):
|
|
||||||
for el in els:
|
|
||||||
self._sl.remove(el)
|
|
||||||
self._status.modified()
|
|
||||||
|
|
||||||
def delete_i(self, indexes):
|
|
||||||
els = list(
|
|
||||||
map(
|
|
||||||
lambda x: x[1],
|
|
||||||
filter(
|
|
||||||
lambda x: x[0] in indexes,
|
|
||||||
enumerate(self._sl)
|
|
||||||
)
|
|
||||||
)
|
|
||||||
)
|
|
||||||
self.delete(els)
|
|
||||||
|
|
||||||
def move_up(self, index):
|
|
||||||
if index < len(self._sl):
|
|
||||||
next = index - 1
|
|
||||||
|
|
||||||
l = self._sl
|
|
||||||
l[index], l[next] = l[next], l[index]
|
|
||||||
self._status.modified()
|
|
||||||
|
|
||||||
def move_down(self, index):
|
|
||||||
if index >= 0:
|
|
||||||
prev = index + 1
|
|
||||||
|
|
||||||
l = self._sl
|
|
||||||
l[index], l[prev] = l[prev], l[index]
|
|
||||||
self._status.modified()
|
|
||||||
@@ -20,7 +20,7 @@ from copy import copy
|
|||||||
from tools import trace, timer
|
from tools import trace, timer
|
||||||
from Solver.Solvers import solver_type_list
|
from Solver.Solvers import solver_type_list
|
||||||
|
|
||||||
from Model.DB import SQLSubModel
|
from Model.Tools.PamhyrList import PamhyrModelList
|
||||||
|
|
||||||
class Parameter():
|
class Parameter():
|
||||||
def __init__(self,
|
def __init__(self,
|
||||||
@@ -63,13 +63,13 @@ class Parameter():
|
|||||||
|
|
||||||
return new
|
return new
|
||||||
|
|
||||||
class SolverParametersList(SQLSubModel):
|
class SolverParametersList(PamhyrModelList):
|
||||||
def __init__(self, solver_type = None, status = None):
|
def __init__(self, solver_type = None, status = None):
|
||||||
super(SolverParametersList, self).__init__()
|
super(SolverParametersList, self).__init__()
|
||||||
|
|
||||||
self._status = status
|
self._status = status
|
||||||
self._solver = solver_type
|
self._solver = solver_type
|
||||||
self._parameters = list(
|
self._lst = list(
|
||||||
map(
|
map(
|
||||||
lambda t: Parameter.from_tuple(t, self._status),
|
lambda t: Parameter.from_tuple(t, self._status),
|
||||||
solver_type.default_parameters()
|
solver_type.default_parameters()
|
||||||
@@ -194,7 +194,7 @@ class SolverParametersList(SQLSubModel):
|
|||||||
)
|
)
|
||||||
|
|
||||||
ind = 0
|
ind = 0
|
||||||
for param in self._parameters:
|
for param in self._lst:
|
||||||
sql = (
|
sql = (
|
||||||
"INSERT INTO " +
|
"INSERT INTO " +
|
||||||
"solver_parameter(ind, name, value, solver) "+
|
"solver_parameter(ind, name, value, solver) "+
|
||||||
@@ -210,39 +210,36 @@ class SolverParametersList(SQLSubModel):
|
|||||||
|
|
||||||
return True
|
return True
|
||||||
|
|
||||||
def __len__(self):
|
|
||||||
return len(self._parameters)
|
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def parameters(self):
|
def parameters(self):
|
||||||
return self._parameters.copy()
|
return self.lst
|
||||||
|
|
||||||
def get(self, index):
|
def get(self, index):
|
||||||
return self._parameters[index]
|
return self._lst[index]
|
||||||
|
|
||||||
def get_by_key(self, key):
|
def get_by_key(self, key):
|
||||||
try:
|
try:
|
||||||
return next(
|
return next(
|
||||||
filter(
|
filter(
|
||||||
lambda p: p["name"] == key,
|
lambda p: p["name"] == key,
|
||||||
self._parameters
|
self._lst
|
||||||
)
|
)
|
||||||
)["value"]
|
)["value"]
|
||||||
except:
|
except:
|
||||||
return None
|
return None
|
||||||
|
|
||||||
def set(self, index, new):
|
def set(self, index, new):
|
||||||
self._parameters[index] = new
|
self._lst[index] = new
|
||||||
self._status.modified()
|
self._status.modified()
|
||||||
|
|
||||||
def set_value(self, key, value):
|
def set_value(self, key, value):
|
||||||
for p in self._parameters:
|
for p in self._lst:
|
||||||
if p["name"] == key:
|
if p["name"] == key:
|
||||||
p["value"] = value
|
p["value"] = value
|
||||||
self._status.modified()
|
self._status.modified()
|
||||||
return
|
return
|
||||||
|
|
||||||
self._parameters.append(
|
self._lst.append(
|
||||||
Parameter(
|
Parameter(
|
||||||
name = key,
|
name = key,
|
||||||
value = value,
|
value = value,
|
||||||
@@ -253,47 +250,6 @@ class SolverParametersList(SQLSubModel):
|
|||||||
|
|
||||||
def new(self, index):
|
def new(self, index):
|
||||||
n = Parameter(status = self._status)
|
n = Parameter(status = self._status)
|
||||||
self._parameters.insert(index, n)
|
self._lst.insert(index, n)
|
||||||
self._status.modified()
|
self._status.modified()
|
||||||
return n
|
return n
|
||||||
|
|
||||||
def insert(self, index, new):
|
|
||||||
self._parameters.insert(index, new)
|
|
||||||
self._status.modified()
|
|
||||||
|
|
||||||
def delete(self, parameters):
|
|
||||||
for parameter in parameters:
|
|
||||||
self._parameters.remove(parameter)
|
|
||||||
self._status.modified()
|
|
||||||
|
|
||||||
def delete_i(self, indexes):
|
|
||||||
parameters = list(
|
|
||||||
map(
|
|
||||||
lambda x: x[1],
|
|
||||||
filter(
|
|
||||||
lambda x: x[0] in indexes,
|
|
||||||
enumerate(self._parameters)
|
|
||||||
)
|
|
||||||
)
|
|
||||||
)
|
|
||||||
self.delete(parameters)
|
|
||||||
|
|
||||||
def sort(self, reverse=False, key=None):
|
|
||||||
self._parameters.sort(reverse=reverse, key=key)
|
|
||||||
self._status.modified()
|
|
||||||
|
|
||||||
def move_up(self, index):
|
|
||||||
if index < len(self._parameters):
|
|
||||||
next = index - 1
|
|
||||||
|
|
||||||
l = self._parameters
|
|
||||||
l[index], l[next] = l[next], l[index]
|
|
||||||
self._status.modified()
|
|
||||||
|
|
||||||
def move_down(self, index):
|
|
||||||
if index >= 0:
|
|
||||||
prev = index + 1
|
|
||||||
|
|
||||||
l = self._parameters
|
|
||||||
l[index], l[prev] = l[prev], l[index]
|
|
||||||
self._status.modified()
|
|
||||||
@@ -18,7 +18,7 @@
|
|||||||
|
|
||||||
from tools import trace, timer
|
from tools import trace, timer
|
||||||
|
|
||||||
from Model.DB import SQLSubModel
|
from Model.Tools.PamhyrDB import SQLSubModel
|
||||||
|
|
||||||
class Stricklers(SQLSubModel):
|
class Stricklers(SQLSubModel):
|
||||||
_id_cnt = 0
|
_id_cnt = 0
|
||||||
|
|||||||
@@ -18,22 +18,15 @@
|
|||||||
|
|
||||||
from tools import trace, timer
|
from tools import trace, timer
|
||||||
|
|
||||||
from Model.DB import SQLSubModel
|
|
||||||
from Model.Saved import SavedStatus
|
from Model.Saved import SavedStatus
|
||||||
|
from Model.Tools.PamhyrList import PamhyrModelList
|
||||||
from Model.Stricklers.Stricklers import Stricklers
|
from Model.Stricklers.Stricklers import Stricklers
|
||||||
|
|
||||||
class StricklersList(SQLSubModel):
|
class StricklersList(PamhyrModelList):
|
||||||
_sub_classes = [
|
_sub_classes = [
|
||||||
Stricklers,
|
Stricklers,
|
||||||
]
|
]
|
||||||
|
|
||||||
def __init__(self, status = None):
|
|
||||||
if status is None:
|
|
||||||
status = SavedStatus()
|
|
||||||
self._status = status
|
|
||||||
|
|
||||||
self._stricks = []
|
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def _sql_create(cls, execute):
|
def _sql_create(cls, execute):
|
||||||
return cls._create_submodel(execute)
|
return cls._create_submodel(execute)
|
||||||
@@ -46,7 +39,7 @@ class StricklersList(SQLSubModel):
|
|||||||
def _sql_load(cls, execute, data = None):
|
def _sql_load(cls, execute, data = None):
|
||||||
new = cls(status = data["status"])
|
new = cls(status = data["status"])
|
||||||
|
|
||||||
new._stricks = Stricklers._sql_load(
|
new._lst = Stricklers._sql_load(
|
||||||
execute,
|
execute,
|
||||||
data = data
|
data = data
|
||||||
)
|
)
|
||||||
@@ -56,60 +49,26 @@ class StricklersList(SQLSubModel):
|
|||||||
def _sql_save(self, execute, data = None):
|
def _sql_save(self, execute, data = None):
|
||||||
execute("DELETE FROM stricklers")
|
execute("DELETE FROM stricklers")
|
||||||
|
|
||||||
objs = self._stricks
|
objs = self._lst
|
||||||
return self._save_submodel(execute, objs, data)
|
return self._save_submodel(execute, objs, data)
|
||||||
|
|
||||||
def __len__(self):
|
|
||||||
return len(self._stricks)
|
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def stricklers(self):
|
def stricklers(self):
|
||||||
return self._stricks.copy()
|
return self.lst
|
||||||
|
|
||||||
def get(self, index):
|
def new(self, index):
|
||||||
if 0 <= index < len(self._stricks):
|
|
||||||
return self._stricks[index]
|
|
||||||
|
|
||||||
return None
|
|
||||||
|
|
||||||
def insert(self, index, strick):
|
|
||||||
self._stricks.insert(index, strick)
|
|
||||||
self._status.modified()
|
|
||||||
|
|
||||||
def add(self, index):
|
|
||||||
s = Stricklers(status = self._status)
|
s = Stricklers(status = self._status)
|
||||||
self.insert(index, s)
|
self.insert(index, s)
|
||||||
return s
|
return s
|
||||||
|
|
||||||
def delete(self, stricks):
|
|
||||||
self._stricks = list(
|
|
||||||
filter(
|
|
||||||
lambda s: s not in stricks,
|
|
||||||
self._stricks
|
|
||||||
)
|
|
||||||
)
|
|
||||||
self._status.modified()
|
|
||||||
|
|
||||||
def delete_i(self, indexes):
|
|
||||||
stricks = set(
|
|
||||||
map(
|
|
||||||
lambda e: e[1],
|
|
||||||
filter(
|
|
||||||
lambda e: e[0] in indexes,
|
|
||||||
enumerate(self._stricks)
|
|
||||||
)
|
|
||||||
)
|
|
||||||
)
|
|
||||||
self.delete(stricks)
|
|
||||||
|
|
||||||
@timer
|
@timer
|
||||||
def sort(self, reverse:bool = False, key=None):
|
def sort(self, reverse:bool = False, key=None):
|
||||||
f = lambda st: st.name
|
f = lambda st: st.name
|
||||||
if key is not None:
|
if key is not None:
|
||||||
f = key
|
f = key
|
||||||
|
|
||||||
self._stricks = sorted(
|
self._lst = sorted(
|
||||||
self._stricks,
|
self._lst,
|
||||||
key = f,
|
key = f,
|
||||||
reverse = reverse,
|
reverse = reverse,
|
||||||
)
|
)
|
||||||
|
|||||||
+1
-1
@@ -23,7 +23,7 @@ from datetime import datetime
|
|||||||
|
|
||||||
from tools import timer, timestamp
|
from tools import timer, timestamp
|
||||||
|
|
||||||
from Model.DB import SQLModel
|
from Model.Tools.PamhyrDB import SQLModel
|
||||||
from Model.Saved import SavedStatus
|
from Model.Saved import SavedStatus
|
||||||
from Model.Serializable import Serializable
|
from Model.Serializable import Serializable
|
||||||
from Model.Except import NotImplementedMethodeError
|
from Model.Except import NotImplementedMethodeError
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
# DB.py -- Pamhyr abstract model database classes
|
# PamhyrDB.py -- Pamhyr abstract model database classes
|
||||||
# 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,74 @@
|
|||||||
|
# PamhyrDict.py -- Pamhyr abstract dict for model classes
|
||||||
|
# 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 logging
|
||||||
|
|
||||||
|
from copy import copy
|
||||||
|
from tools import trace, timer
|
||||||
|
|
||||||
|
from Model.Tools.PamhyrDB import SQLSubModel
|
||||||
|
from Model.Except import NotImplementedMethodeError
|
||||||
|
|
||||||
|
logger = logging.getLogger()
|
||||||
|
|
||||||
|
|
||||||
|
class PamhyrModelDict(SQLSubModel):
|
||||||
|
_sub_classes = []
|
||||||
|
|
||||||
|
def __init__(self, status = None):
|
||||||
|
super(PamhyrModelDict, self).__init__()
|
||||||
|
|
||||||
|
self._status = status
|
||||||
|
|
||||||
|
self._dict = {}
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def _sql_create(cls, execute):
|
||||||
|
return cls._create_submodel(execute)
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def _sql_update(cls, execute, version):
|
||||||
|
return cls._update_submodel(execute, version)
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def _sql_load(cls, execute, data = None):
|
||||||
|
raise NotImplementedMethodeError(cls, cls._sql_load)
|
||||||
|
|
||||||
|
def _sql_save(self, execute, data = None):
|
||||||
|
raise NotImplementedMethodeError(self, self._sql_save)
|
||||||
|
|
||||||
|
def __len__(self):
|
||||||
|
return len(self._dict)
|
||||||
|
|
||||||
|
def is_defined(self, key):
|
||||||
|
return key in self._dict
|
||||||
|
|
||||||
|
def set(self, key, new):
|
||||||
|
self._dict[key] = new
|
||||||
|
self._status.modified()
|
||||||
|
|
||||||
|
def get(self, key):
|
||||||
|
if key in self._dict:
|
||||||
|
return self._dict[key]
|
||||||
|
|
||||||
|
new = self.new(key)
|
||||||
|
self.set(key, new)
|
||||||
|
return new
|
||||||
|
|
||||||
|
def new(self, key):
|
||||||
|
raise NotImplementedMethodeError(self, self.new)
|
||||||
@@ -0,0 +1,229 @@
|
|||||||
|
# PamhyrList.py -- Pamhyr Abstract List object for the Model
|
||||||
|
# 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 logging
|
||||||
|
|
||||||
|
from copy import copy
|
||||||
|
from tools import trace, timer
|
||||||
|
|
||||||
|
from Model.Tools.PamhyrDB import SQLSubModel
|
||||||
|
from Model.Except import NotImplementedMethodeError
|
||||||
|
|
||||||
|
logger = logging.getLogger()
|
||||||
|
|
||||||
|
class PamhyrModelList(SQLSubModel):
|
||||||
|
_sub_classes = [
|
||||||
|
]
|
||||||
|
|
||||||
|
def __init__(self, status = None):
|
||||||
|
super(PamhyrModelList, self).__init__()
|
||||||
|
|
||||||
|
self._status = status
|
||||||
|
self._lst = []
|
||||||
|
|
||||||
|
#######
|
||||||
|
# SQL #
|
||||||
|
#######
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def _sql_create(cls, execute):
|
||||||
|
return cls._create_submodel(execute)
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def _sql_update(cls, execute, version):
|
||||||
|
return cls._update_submodel(execute, version)
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def _sql_load(cls, execute, data = None):
|
||||||
|
raise NotImplementedMethodeError(cls, cls._sql_load)
|
||||||
|
|
||||||
|
def _sql_save(self, execute, data = None):
|
||||||
|
raise NotImplementedMethodeError(self, self._sql_save)
|
||||||
|
|
||||||
|
################
|
||||||
|
# MODEL METHOD #
|
||||||
|
################
|
||||||
|
|
||||||
|
def __len__(self):
|
||||||
|
return len(self._lst)
|
||||||
|
|
||||||
|
@property
|
||||||
|
def lst(self):
|
||||||
|
return self._lst.copy()
|
||||||
|
|
||||||
|
def get(self, row):
|
||||||
|
return self._lst[row]
|
||||||
|
|
||||||
|
def set(self, row, new):
|
||||||
|
self._lst[row] = new
|
||||||
|
self._status.modified()
|
||||||
|
|
||||||
|
def new(self, index):
|
||||||
|
"""Create new elements and add it to list
|
||||||
|
|
||||||
|
Args:
|
||||||
|
index: The index of new elements
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
The new elements
|
||||||
|
"""
|
||||||
|
raise NotImplementedMethodeError(self, self.new)
|
||||||
|
|
||||||
|
def insert(self, index, new):
|
||||||
|
self._lst.insert(index, new)
|
||||||
|
self._status.modified()
|
||||||
|
|
||||||
|
def delete(self, lst):
|
||||||
|
for el in lst:
|
||||||
|
self._lst.remove(el)
|
||||||
|
self._status.modified()
|
||||||
|
|
||||||
|
def delete_i(self, indexes):
|
||||||
|
lst = list(
|
||||||
|
map(
|
||||||
|
lambda x: x[1],
|
||||||
|
filter(
|
||||||
|
lambda x: x[0] in indexes,
|
||||||
|
enumerate(self._lst)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
self.delete(lst)
|
||||||
|
|
||||||
|
def sort(self, reverse=False, key=None):
|
||||||
|
self._lst.sort(reverse=reverse, key=key)
|
||||||
|
self._status.modified()
|
||||||
|
|
||||||
|
def move_up(self, index):
|
||||||
|
if index < len(self._lst):
|
||||||
|
next = index - 1
|
||||||
|
|
||||||
|
l = self._lst
|
||||||
|
l[index], l[next] = l[next], l[index]
|
||||||
|
self._status.modified()
|
||||||
|
|
||||||
|
def move_down(self, index):
|
||||||
|
if index >= 0:
|
||||||
|
prev = index + 1
|
||||||
|
|
||||||
|
l = self._lst
|
||||||
|
l[index], l[prev] = l[prev], l[index]
|
||||||
|
self._status.modified()
|
||||||
|
|
||||||
|
|
||||||
|
class PamhyrModelListWithTab(SQLSubModel):
|
||||||
|
_tabs_list = []
|
||||||
|
_sub_classes = [
|
||||||
|
]
|
||||||
|
|
||||||
|
def __init__(self, status = None):
|
||||||
|
super(PamhyrModelListWithTab, self).__init__()
|
||||||
|
|
||||||
|
self._status = status
|
||||||
|
self._tabs = {}
|
||||||
|
for tab in self._tabs_list:
|
||||||
|
self._tabs[tab] = []
|
||||||
|
|
||||||
|
#######
|
||||||
|
# SQL #
|
||||||
|
#######
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def _sql_create(cls, execute):
|
||||||
|
return cls._create_submodel(execute)
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def _sql_update(cls, execute, version):
|
||||||
|
return cls._update_submodel(execute, version)
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def _sql_load(cls, execute, data = None):
|
||||||
|
raise NotImplementedMethodeError(cls, cls._sql_load)
|
||||||
|
|
||||||
|
def _sql_save(self, execute, data = None):
|
||||||
|
raise NotImplementedMethodeError(self, self._sql_save)
|
||||||
|
|
||||||
|
################
|
||||||
|
# MODEL METHOD #
|
||||||
|
################
|
||||||
|
|
||||||
|
def len(self, lst):
|
||||||
|
return len(self._tabs[lst])
|
||||||
|
|
||||||
|
def get_tab(self, lst):
|
||||||
|
return self._tabs[lst].copy()
|
||||||
|
|
||||||
|
def get(self, lst, row):
|
||||||
|
return self._tabs[lst][row]
|
||||||
|
|
||||||
|
def set(self, lst, row, new):
|
||||||
|
self._tabs[lst][row] = new
|
||||||
|
self._status.modified()
|
||||||
|
|
||||||
|
def new(self, lst, index):
|
||||||
|
"""Create new elements and add it to list
|
||||||
|
|
||||||
|
Args:
|
||||||
|
lst: The tab name
|
||||||
|
index: The index of new elements
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
The new elements
|
||||||
|
"""
|
||||||
|
raise NotImplementedMethodeError(self, self.new)
|
||||||
|
|
||||||
|
def insert(self, lst, index, new):
|
||||||
|
self._tabs[lst].insert(index, new)
|
||||||
|
self._status.modified()
|
||||||
|
|
||||||
|
def delete(self, lst, els):
|
||||||
|
for el in els:
|
||||||
|
self._tabs[lst].remove(el)
|
||||||
|
self._status.modified()
|
||||||
|
|
||||||
|
def delete_i(self, lst, indexes):
|
||||||
|
els = list(
|
||||||
|
map(
|
||||||
|
lambda x: x[1],
|
||||||
|
filter(
|
||||||
|
lambda x: x[0] in indexes,
|
||||||
|
enumerate(self._tabs[lst])
|
||||||
|
)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
self.delete(lst, els)
|
||||||
|
|
||||||
|
def sort(self, lst, reverse=False, key=None):
|
||||||
|
self._tabs[lst].sort(reverse=reverse, key=key)
|
||||||
|
self._status.modified()
|
||||||
|
|
||||||
|
def move_up(self, lst, index):
|
||||||
|
if index < len(self._tabs[lst]):
|
||||||
|
next = index - 1
|
||||||
|
|
||||||
|
l = self._tabs[lst]
|
||||||
|
l[index], l[next] = l[next], l[index]
|
||||||
|
self._status.modified()
|
||||||
|
|
||||||
|
def move_down(self, lst, index):
|
||||||
|
if index >= 0:
|
||||||
|
prev = index + 1
|
||||||
|
|
||||||
|
l = self._tabs[lst]
|
||||||
|
l[index], l[prev] = l[prev], l[index]
|
||||||
|
self._status.modified()
|
||||||
@@ -0,0 +1,36 @@
|
|||||||
|
# AScript.py -- Pamhyr abstract script class
|
||||||
|
# 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 Model.Except import NotImplementedMethodeError
|
||||||
|
|
||||||
|
class AScript(object):
|
||||||
|
name = ""
|
||||||
|
description = ""
|
||||||
|
|
||||||
|
def __init__(self, app, conf, args):
|
||||||
|
super(AScript, self).__init__()
|
||||||
|
|
||||||
|
self._app = app
|
||||||
|
self._conf = conf
|
||||||
|
self._args = args.copy()
|
||||||
|
|
||||||
|
def usage(self):
|
||||||
|
raise NotImplementedMethodeError(self, self.usage)
|
||||||
|
|
||||||
|
def run(self):
|
||||||
|
raise NotImplementedMethodeError(self, self.run)
|
||||||
@@ -0,0 +1,34 @@
|
|||||||
|
# Hello.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 logging
|
||||||
|
from Scripts.AScript import AScript
|
||||||
|
|
||||||
|
logger = logging.getLogger()
|
||||||
|
|
||||||
|
|
||||||
|
class ScriptHello(AScript):
|
||||||
|
name = "Hello"
|
||||||
|
description = "Display hello"
|
||||||
|
|
||||||
|
def usage(self):
|
||||||
|
logger.info(f"Usage : {self._args[0]} hello")
|
||||||
|
|
||||||
|
def run(self):
|
||||||
|
logger.info("Hello from Pamhyr2 script !")
|
||||||
|
return 0
|
||||||
@@ -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()
|
|
||||||
@@ -22,6 +22,7 @@ import logging
|
|||||||
from tools import timer
|
from tools import timer
|
||||||
|
|
||||||
try:
|
try:
|
||||||
|
# Installation allow Unix-like signal
|
||||||
from signal import SIGTERM, SIGSTOP, SIGCONT
|
from signal import SIGTERM, SIGSTOP, SIGCONT
|
||||||
_signal = True
|
_signal = True
|
||||||
except:
|
except:
|
||||||
@@ -201,7 +202,7 @@ class AbstractSolver(object):
|
|||||||
return os.path.abspath(
|
return os.path.abspath(
|
||||||
os.path.join(
|
os.path.join(
|
||||||
os.path.dirname(__file__),
|
os.path.dirname(__file__),
|
||||||
".."
|
"..", ".."
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -216,7 +217,6 @@ class AbstractSolver(object):
|
|||||||
The executable and list of arguments
|
The executable and list of arguments
|
||||||
"""
|
"""
|
||||||
# HACK: Works in most case... Trust me i'm an engineer
|
# HACK: Works in most case... Trust me i'm an engineer
|
||||||
|
|
||||||
cmd = cmd.replace("@install_dir", self._install_dir())
|
cmd = cmd.replace("@install_dir", self._install_dir())
|
||||||
cmd = cmd.replace("@path", path.replace(" ", "\ "))
|
cmd = cmd.replace("@path", path.replace(" ", "\ "))
|
||||||
cmd = cmd.replace("@input", self.input_param())
|
cmd = cmd.replace("@input", self.input_param())
|
||||||
@@ -358,6 +358,7 @@ class AbstractSolver(object):
|
|||||||
|
|
||||||
def start(self, study, process = None):
|
def start(self, study, process = None):
|
||||||
if _signal:
|
if _signal:
|
||||||
|
# Solver is PAUSED, so continue execution
|
||||||
if self._status == STATUS.PAUSED:
|
if self._status == STATUS.PAUSED:
|
||||||
os.kill(self._process.pid(), SIGCONT)
|
os.kill(self._process.pid(), SIGCONT)
|
||||||
self._status = STATUS.RUNNING
|
self._status = STATUS.RUNNING
|
||||||
@@ -371,6 +372,7 @@ class AbstractSolver(object):
|
|||||||
if self._process is None:
|
if self._process is None:
|
||||||
return False
|
return False
|
||||||
|
|
||||||
|
# Send SIGSTOP to PAUSED solver
|
||||||
os.kill(self._process.pid(), SIGSTOP)
|
os.kill(self._process.pid(), SIGSTOP)
|
||||||
self._status = STATUS.PAUSED
|
self._status = STATUS.PAUSED
|
||||||
return True
|
return True
|
||||||
|
|||||||
@@ -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,7 @@ 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.Tools.PamhyrTable import PamhyrTableModel
|
||||||
from View.ListedSubWindow import ListedSubWindow
|
|
||||||
|
|
||||||
from PyQt5.QtCore import (
|
from PyQt5.QtCore import (
|
||||||
Qt, QVariant, QAbstractTableModel,
|
Qt, QVariant, QAbstractTableModel,
|
||||||
@@ -47,131 +46,12 @@ 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
|
||||||
|
|
||||||
logger = logging.getLogger()
|
logger = logging.getLogger()
|
||||||
|
|
||||||
class ExtendedTimeEdit(AWidget):
|
class TableModel(PamhyrTableModel):
|
||||||
def __init__(self, parent=None):
|
|
||||||
super(ExtendedTimeEdit, self).__init__(
|
|
||||||
ui="extendedTimeEdit",
|
|
||||||
parent=parent
|
|
||||||
)
|
|
||||||
self.parent = parent
|
|
||||||
|
|
||||||
self.spinBox_days = self.find(QSpinBox, "spinBox_days")
|
|
||||||
self.timeEdit = self.find(QTimeEdit, "timeEdit")
|
|
||||||
|
|
||||||
def set_time(self, time):
|
|
||||||
days = 0
|
|
||||||
stime = time
|
|
||||||
|
|
||||||
# if ',' in time, time format is 'DD days, HH:MM:SS',
|
|
||||||
# otherelse is 'HH:MM:SS'
|
|
||||||
if "," in time:
|
|
||||||
s = time.strip().split(" ")
|
|
||||||
days = int(s[0])
|
|
||||||
stime = s[-1]
|
|
||||||
|
|
||||||
qtime = QTime.fromString(
|
|
||||||
stime,
|
|
||||||
"h:mm:ss"
|
|
||||||
)
|
|
||||||
self.spinBox_days.setValue(days)
|
|
||||||
self.timeEdit.setTime(qtime)
|
|
||||||
|
|
||||||
def get_time(self):
|
|
||||||
days = self.spinBox_days.value()
|
|
||||||
time = self.timeEdit.time().toPyTime()
|
|
||||||
secs = (
|
|
||||||
(time.hour * 3600) +
|
|
||||||
(time.minute * 60) +
|
|
||||||
time.second
|
|
||||||
)
|
|
||||||
|
|
||||||
return timedelta(days=days, seconds=secs)
|
|
||||||
|
|
||||||
class ExtendedDateTimeEdit(AWidget):
|
|
||||||
def __init__(self, parent=None):
|
|
||||||
super(ExtendedDateTimeEdit, self).__init__(
|
|
||||||
ui="extendedDateTimeEdit",
|
|
||||||
parent=parent
|
|
||||||
)
|
|
||||||
self.parent = parent
|
|
||||||
|
|
||||||
self.dateTimeEdit = self.find(QDateTimeEdit, "dateTimeEdit")
|
|
||||||
|
|
||||||
def set_time(self, time):
|
|
||||||
qdatetime = QDateTime.fromString(
|
|
||||||
time,
|
|
||||||
"yyyy-MM-dd hh:mm:ss"
|
|
||||||
)
|
|
||||||
self.dateTimeEdit.setDateTime(qdatetime)
|
|
||||||
|
|
||||||
def get_time(self):
|
|
||||||
time = self.dateTimeEdit.dateTime().toPyDateTime()
|
|
||||||
return time
|
|
||||||
|
|
||||||
class ExTimeDelegate(QItemDelegate):
|
|
||||||
def __init__(self, data=None, mode="time", parent=None):
|
|
||||||
super(ExTimeDelegate, self).__init__(parent)
|
|
||||||
|
|
||||||
self._data = data
|
|
||||||
self._mode = mode
|
|
||||||
|
|
||||||
def createEditor(self, parent, option, index):
|
|
||||||
if self._mode == "time":
|
|
||||||
self.editor = ExtendedTimeEdit(parent=parent)
|
|
||||||
else:
|
|
||||||
self.editor = ExtendedDateTimeEdit(parent=parent)
|
|
||||||
value = index.data(Qt.DisplayRole)
|
|
||||||
self.editor.set_time(value)
|
|
||||||
logger.debug(str(value))
|
|
||||||
return self.editor
|
|
||||||
|
|
||||||
def setModelData(self, editor, model, index):
|
|
||||||
time = editor.get_time()
|
|
||||||
if self._mode == "time":
|
|
||||||
model.setData(index, int(time.total_seconds()))
|
|
||||||
else:
|
|
||||||
logger.debug(str(time.timestamp()))
|
|
||||||
model.setData(index, int(time.timestamp()))
|
|
||||||
editor.close()
|
|
||||||
editor.deleteLater()
|
|
||||||
|
|
||||||
def updateEditorGeometry(self, editor, option, index):
|
|
||||||
r = QRect(option.rect)
|
|
||||||
if self.editor.windowFlags() & Qt.Popup and editor.parent() is not None:
|
|
||||||
r.setTopLeft(self.editor.parent().mapToGlobal(r.topLeft()))
|
|
||||||
editor.setGeometry(r)
|
|
||||||
|
|
||||||
@pyqtSlot()
|
|
||||||
def currentItemChanged(self):
|
|
||||||
self.commitData.emit(self.sender())
|
|
||||||
|
|
||||||
|
|
||||||
class TableModel(QAbstractTableModel):
|
|
||||||
def __init__(self, data=None, mode="time", undo=None):
|
|
||||||
super(QAbstractTableModel, self).__init__()
|
|
||||||
self._headers = data.header
|
|
||||||
self._data = data
|
|
||||||
self._mode = mode
|
|
||||||
self._undo = undo
|
|
||||||
|
|
||||||
def flags(self, index):
|
|
||||||
options = Qt.ItemIsEnabled | Qt.ItemIsSelectable
|
|
||||||
options |= Qt.ItemIsEditable
|
|
||||||
|
|
||||||
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):
|
||||||
if role == Qt.TextAlignmentRole:
|
if role == Qt.TextAlignmentRole:
|
||||||
return Qt.AlignHCenter | Qt.AlignVCenter
|
return Qt.AlignHCenter | Qt.AlignVCenter
|
||||||
@@ -189,7 +69,7 @@ class TableModel(QAbstractTableModel):
|
|||||||
if self._data.get_type_column(column) == float:
|
if self._data.get_type_column(column) == float:
|
||||||
value = f"{v:.4f}"
|
value = f"{v:.4f}"
|
||||||
elif self._data.header[column] == "time":
|
elif self._data.header[column] == "time":
|
||||||
if self._mode == "time":
|
if self._opt_data == "time":
|
||||||
t0 = datetime.fromtimestamp(0)
|
t0 = datetime.fromtimestamp(0)
|
||||||
t = datetime.fromtimestamp(v)
|
t = datetime.fromtimestamp(v)
|
||||||
value = str(t - t0)
|
value = str(t - t0)
|
||||||
@@ -200,12 +80,6 @@ class TableModel(QAbstractTableModel):
|
|||||||
|
|
||||||
return value
|
return value
|
||||||
|
|
||||||
def headerData(self, section, orientation, role):
|
|
||||||
if role == Qt.ItemDataRole.DisplayRole and orientation == Qt.Orientation.Horizontal:
|
|
||||||
return 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
|
||||||
@@ -315,12 +189,3 @@ class TableModel(QAbstractTableModel):
|
|||||||
|
|
||||||
self.layoutAboutToBeChanged.emit()
|
self.layoutAboutToBeChanged.emit()
|
||||||
self.layoutChanged.emit()
|
self.layoutChanged.emit()
|
||||||
|
|
||||||
|
|
||||||
def undo(self):
|
|
||||||
self._undo.undo()
|
|
||||||
self.layoutChanged.emit()
|
|
||||||
|
|
||||||
def redo(self):
|
|
||||||
self._undo.redo()
|
|
||||||
self.layoutChanged.emit()
|
|
||||||
@@ -16,10 +16,13 @@
|
|||||||
|
|
||||||
# -*- coding: utf-8 -*-
|
# -*- coding: utf-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 PyQt5.QtGui import (
|
from PyQt5.QtGui import (
|
||||||
QKeySequence,
|
QKeySequence,
|
||||||
@@ -38,26 +41,28 @@ 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.navigation_toolbar_2qt import PamHyrNavigationToolbar2QT
|
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.UndoCommand import SetMetaDataCommand
|
from View.BoundaryCondition.Edit.UndoCommand import SetMetaDataCommand
|
||||||
from View.BoundaryCondition.Edit.Table import TableModel, ExTimeDelegate
|
from View.BoundaryCondition.Edit.Table import TableModel
|
||||||
from View.BoundaryCondition.Edit.Plot import Plot
|
from View.BoundaryCondition.Edit.Plot import Plot
|
||||||
|
|
||||||
_translate = QCoreApplication.translate
|
_translate = QCoreApplication.translate
|
||||||
|
|
||||||
class WD50Sigma(AWidget):
|
logger = logging.getLogger()
|
||||||
|
|
||||||
|
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")
|
||||||
@@ -89,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"
|
||||||
|
|
||||||
@@ -141,23 +139,29 @@ 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):
|
||||||
table = self.find(QTableView, "tableView")
|
headers = {}
|
||||||
self._table = TableModel(
|
table_headers = self._trad.get_dict("table_headers")
|
||||||
|
for h in self._data.header:
|
||||||
|
headers[h] = table_headers[h]
|
||||||
|
|
||||||
|
self._delegate_time = PamhyrExTimeDelegate(
|
||||||
data = self._data,
|
data = self._data,
|
||||||
undo = self._undo_stack,
|
mode = self._study.time_system,
|
||||||
mode = self._study.time_system
|
parent = self
|
||||||
)
|
)
|
||||||
|
|
||||||
if self._data.header[0] == "time":
|
table = self.find(QTableView, "tableView")
|
||||||
self._delegate_time = ExTimeDelegate(
|
self._table = TableModel(
|
||||||
data = self._data,
|
table_view = table,
|
||||||
mode = self._study.time_system,
|
table_headers = headers,
|
||||||
parent = self
|
editable_headers = self._data.header,
|
||||||
)
|
delegates = {
|
||||||
|
"time": self._delegate_time,
|
||||||
table.setItemDelegateForColumn(
|
},
|
||||||
0, self._delegate_time
|
data = self._data,
|
||||||
)
|
undo = self._undo_stack,
|
||||||
|
opt_data = self._study.time_system
|
||||||
|
)
|
||||||
|
|
||||||
table.setModel(self._table)
|
table.setModel(self._table)
|
||||||
table.setSelectionBehavior(QAbstractItemView.SelectRows)
|
table.setSelectionBehavior(QAbstractItemView.SelectRows)
|
||||||
@@ -167,7 +171,7 @@ class EditBoundaryConditionWindow(ASubMainWindow, ListedSubWindow):
|
|||||||
def setup_plot(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 = PamHyrNavigationToolbar2QT(
|
self.toolbar = PamhyrPlotToolbar(
|
||||||
self.canvas, self
|
self.canvas, self
|
||||||
)
|
)
|
||||||
self.verticalLayout.addWidget(self.toolbar)
|
self.verticalLayout.addWidget(self.toolbar)
|
||||||
@@ -177,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:
|
||||||
@@ -240,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:
|
||||||
@@ -273,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 = []
|
||||||
@@ -285,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:
|
||||||
@@ -299,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,14 +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"),
|
self._sub_dict["table_headers"] = {
|
||||||
"discharge": _translate("BoundaryCondition", "Discharge (m³/s)"),
|
"x": _translate("BoundaryCondition", "X"),
|
||||||
"z": _translate("BoundaryCondition", "Z (m)"),
|
"y": _translate("BoundaryCondition", "Y"),
|
||||||
"solid": _translate("BoundaryCondition", "Solid (kg/s)"),
|
"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)"),
|
||||||
|
}
|
||||||
@@ -39,24 +39,31 @@ from Model.BoundaryCondition.BoundaryConditionTypes import (
|
|||||||
TimeOverZ, TimeOverDischarge, ZOverDischarge
|
TimeOverZ, TimeOverDischarge, ZOverDischarge
|
||||||
)
|
)
|
||||||
|
|
||||||
|
from View.Tools.PamhyrTable import PamhyrTableModel
|
||||||
|
|
||||||
from View.BoundaryCondition.UndoCommand import (
|
from View.BoundaryCondition.UndoCommand import (
|
||||||
SetNameCommand, SetNodeCommand, SetTypeCommand,
|
SetNameCommand, SetNodeCommand, SetTypeCommand,
|
||||||
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)
|
||||||
@@ -64,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()
|
||||||
@@ -104,26 +111,20 @@ class ComboBoxDelegate(QItemDelegate):
|
|||||||
self.commitData.emit(self.sender())
|
self.commitData.emit(self.sender())
|
||||||
|
|
||||||
|
|
||||||
class TableModel(QAbstractTableModel):
|
class TableModel(PamhyrTableModel):
|
||||||
def __init__(self, data=None, undo=None, tab=""):
|
def __init__(self, **kwargs):
|
||||||
super(QAbstractTableModel, self).__init__()
|
super(TableModel, self).__init__(**kwargs)
|
||||||
self._headers = list(table_headers.keys())
|
|
||||||
self._data = data
|
|
||||||
self._undo = undo
|
|
||||||
self._tab = tab
|
|
||||||
self._bcs = self._data.boundary_condition
|
|
||||||
|
|
||||||
def flags(self, index):
|
self._long_types = {}
|
||||||
options = Qt.ItemIsEnabled | Qt.ItemIsSelectable
|
if self._trad is not None:
|
||||||
options |= Qt.ItemIsEditable
|
self._long_types = self._trad.get_dict("long_types")
|
||||||
|
|
||||||
return options
|
def _setup_lst(self):
|
||||||
|
self._lst = self._data.boundary_condition
|
||||||
|
self._tab = self._opt_data
|
||||||
|
|
||||||
def rowCount(self, parent):
|
def rowCount(self, parent):
|
||||||
return self._bcs.len(self._tab)
|
return self._lst.len(self._tab)
|
||||||
|
|
||||||
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:
|
||||||
@@ -133,24 +134,18 @@ class TableModel(QAbstractTableModel):
|
|||||||
column = index.column()
|
column = index.column()
|
||||||
|
|
||||||
if self._headers[column] == "name":
|
if self._headers[column] == "name":
|
||||||
return self._bcs.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._bcs.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._bcs.get(self._tab, row).node
|
n = self._lst.get(self._tab, row).node
|
||||||
if n is None:
|
if n is None:
|
||||||
return _translate("BoundaryCondition", "Not associate")
|
return _translate("BoundaryCondition", "Not associate")
|
||||||
return n.name
|
return n.name
|
||||||
|
|
||||||
return QVariant()
|
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()
|
|
||||||
|
|
||||||
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
|
||||||
@@ -162,20 +157,20 @@ class TableModel(QAbstractTableModel):
|
|||||||
if self._headers[column] == "name":
|
if self._headers[column] == "name":
|
||||||
self._undo.push(
|
self._undo.push(
|
||||||
SetNameCommand(
|
SetNameCommand(
|
||||||
self._bcs, self._tab,row, value
|
self._lst, self._tab,row, value
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
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._bcs, self._tab,row, BC_types[key]
|
self._lst, self._tab,row, BC_types[key]
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
elif self._headers[column] == "node":
|
elif self._headers[column] == "node":
|
||||||
self._undo.push(
|
self._undo.push(
|
||||||
SetNodeCommand(
|
SetNodeCommand(
|
||||||
self._bcs, self._tab,row, self._data.node(value)
|
self._lst, self._tab,row, self._data.node(value)
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
@@ -190,7 +185,7 @@ class TableModel(QAbstractTableModel):
|
|||||||
|
|
||||||
self._undo.push(
|
self._undo.push(
|
||||||
AddCommand(
|
AddCommand(
|
||||||
self._bcs, self._tab,row
|
self._lst, self._tab,row
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -202,7 +197,7 @@ class TableModel(QAbstractTableModel):
|
|||||||
|
|
||||||
self._undo.push(
|
self._undo.push(
|
||||||
DelCommand(
|
DelCommand(
|
||||||
self._bcs, self._tab,rows
|
self._lst, self._tab, rows
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -214,7 +209,7 @@ class TableModel(QAbstractTableModel):
|
|||||||
|
|
||||||
self._undo.push(
|
self._undo.push(
|
||||||
SortCommand(
|
SortCommand(
|
||||||
self._bcs, self._tab,False
|
self._lst, self._tab, False
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -231,7 +226,7 @@ class TableModel(QAbstractTableModel):
|
|||||||
|
|
||||||
self._undo_stack.push(
|
self._undo_stack.push(
|
||||||
MoveCommand(
|
MoveCommand(
|
||||||
self._bcs, self._tab,"up", row
|
self._lst, self._tab, "up", row
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -239,7 +234,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._bcs):
|
if row > len(self._lst):
|
||||||
return
|
return
|
||||||
|
|
||||||
target = row
|
target = row
|
||||||
@@ -248,7 +243,7 @@ class TableModel(QAbstractTableModel):
|
|||||||
|
|
||||||
self._undo_stack.push(
|
self._undo_stack.push(
|
||||||
MoveCommand(
|
MoveCommand(
|
||||||
self._bcs, self._tab,"down", row
|
self._lst, self._tab, "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,
|
||||||
@@ -56,71 +55,70 @@ from View.BoundaryCondition.Table import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
from View.Network.GraphWidget import GraphWidget
|
from View.Network.GraphWidget import GraphWidget
|
||||||
from View.BoundaryCondition.translate import *
|
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):
|
||||||
self._table = {}
|
self._table = {}
|
||||||
|
|
||||||
for t in ["liquid", "solid", "suspenssion"]:
|
for t in ["liquid", "solid", "suspenssion"]:
|
||||||
table = self.find(QTableView, f"tableView_{t}")
|
|
||||||
self._table[t] = TableModel(
|
|
||||||
data = self._study.river,
|
|
||||||
undo = self._undo_stack,
|
|
||||||
tab = t,
|
|
||||||
)
|
|
||||||
table.setModel(self._table[t])
|
|
||||||
|
|
||||||
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,
|
||||||
parent=self
|
parent=self
|
||||||
)
|
)
|
||||||
|
|
||||||
table.setItemDelegateForColumn(
|
table = self.find(QTableView, f"tableView_{t}")
|
||||||
1, self._delegate_type
|
self._table[t] = TableModel(
|
||||||
|
table_view = table,
|
||||||
|
table_headers = self._trad.get_dict("table_headers"),
|
||||||
|
editable_headers = ["name", "type", "node"],
|
||||||
|
delegates = {
|
||||||
|
"type": self._delegate_type,
|
||||||
|
"node": self._delegate_node,
|
||||||
|
},
|
||||||
|
trad = self._trad,
|
||||||
|
data = self._study.river,
|
||||||
|
undo = self._undo_stack,
|
||||||
|
opt_data = t,
|
||||||
)
|
)
|
||||||
table.setItemDelegateForColumn(
|
table.setModel(self._table[t])
|
||||||
2, self._delegate_node
|
|
||||||
)
|
|
||||||
|
|
||||||
table.setSelectionBehavior(QAbstractItemView.SelectRows)
|
table.setSelectionBehavior(QAbstractItemView.SelectRows)
|
||||||
table.horizontalHeader().setSectionResizeMode(QHeaderView.Stretch)
|
table.horizontalHeader().setSectionResizeMode(QHeaderView.Stretch)
|
||||||
table.setAlternatingRowColors(True)
|
table.setAlternatingRowColors(True)
|
||||||
@@ -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,
|
||||||
@@ -49,3 +36,22 @@ BC_types = {
|
|||||||
"ZD": ZOverDischarge,
|
"ZD": ZOverDischarge,
|
||||||
"SL": Solid,
|
"SL": Solid,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
class BCTranslate(PamhyrTranslate):
|
||||||
|
def __init__(self):
|
||||||
|
super(BCTranslate, self).__init__()
|
||||||
|
|
||||||
|
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
|
||||||
|
|||||||
@@ -37,10 +37,11 @@ class Worker(QObject):
|
|||||||
self.signalStatus.emit('end')
|
self.signalStatus.emit('end')
|
||||||
|
|
||||||
def _compute(self):
|
def _compute(self):
|
||||||
|
# The computation loop
|
||||||
for checker in self._checker_list:
|
for checker in self._checker_list:
|
||||||
self.signalStatus.emit(checker.name)
|
self.signalStatus.emit(checker.name)
|
||||||
|
|
||||||
# time.sleep(1)
|
# Run checker
|
||||||
checker.run(self._study)
|
checker.run(self._study)
|
||||||
|
|
||||||
self.signalStatus.emit("progress")
|
self.signalStatus.emit("progress")
|
||||||
@@ -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_():
|
||||||
|
|||||||
+15
-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 = []
|
||||||
@@ -92,7 +90,9 @@ class ReplWindow(ASubMainWindow, ListedSubWindow):
|
|||||||
self.set_plaintext_edit_text("plainTextEdit", "")
|
self.set_plaintext_edit_text("plainTextEdit", "")
|
||||||
self._history_ind = 0
|
self._history_ind = 0
|
||||||
|
|
||||||
|
# Code to rich_code
|
||||||
rich_code = code.strip().split("\n")
|
rich_code = code.strip().split("\n")
|
||||||
|
# Add return variable for results display at last row
|
||||||
rich_code[-1] = "self.__debug_exec_result__ = " + rich_code[-1]
|
rich_code[-1] = "self.__debug_exec_result__ = " + rich_code[-1]
|
||||||
rich_code = "\n".join(rich_code)
|
rich_code = "\n".join(rich_code)
|
||||||
logger.debug(f"User debug command : {rich_code}")
|
logger.debug(f"User debug command : {rich_code}")
|
||||||
@@ -102,6 +102,8 @@ class ReplWindow(ASubMainWindow, ListedSubWindow):
|
|||||||
except Exception as e:
|
except Exception as e:
|
||||||
value = f"<font color=\"red\">" + str(e) + "</font>"
|
value = f"<font color=\"red\">" + str(e) + "</font>"
|
||||||
|
|
||||||
|
# Display code
|
||||||
msg = f"<font color=\"grey\"> # " + code + " #</font>"
|
msg = f"<font color=\"grey\"> # " + code + " #</font>"
|
||||||
self.find(QTextEdit, "textEdit").append(msg)
|
self.find(QTextEdit, "textEdit").append(msg)
|
||||||
|
# Display results
|
||||||
self.find(QTextEdit, "textEdit").append(str(value))
|
self.find(QTextEdit, "textEdit").append(str(value))
|
||||||
@@ -0,0 +1,106 @@
|
|||||||
|
# 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, sys
|
||||||
|
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"
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def _path_file(cls, filename):
|
||||||
|
if ".py" in sys.argv[0]:
|
||||||
|
return os.path.abspath(
|
||||||
|
os.path.join(
|
||||||
|
os.path.dirname(__file__),
|
||||||
|
"..", "..", "..", "doc", 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,62 +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 *
|
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):
|
||||||
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,
|
||||||
@@ -111,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)
|
||||||
@@ -155,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\
|
||||||
@@ -233,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,13 +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)"),
|
self._sub_dict["table_headers"] = {
|
||||||
"begin_strickler": _translate("Frictions", "Begin strickler"),
|
"name": _translate("Frictions", "Name"),
|
||||||
"end_strickler": _translate("Frictions", "End strickler"),
|
# "edge": _translate("Frictions", "Reach"),
|
||||||
}
|
"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"),
|
||||||
|
}
|
||||||
@@ -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,259 +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, navigation_toolbar_2qt
|
|
||||||
|
|
||||||
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 = navigation_toolbar_2qt.PamHyrNavigationToolbar2QT(
|
|
||||||
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, navigation_toolbar_2qt
|
|
||||||
)
|
|
||||||
|
|
||||||
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 = navigation_toolbar_2qt.PamHyrNavigationToolbar2QT(
|
|
||||||
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 = navigation_toolbar_2qt.PamHyrNavigationToolbar2QT(
|
|
||||||
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 = navigation_toolbar_2qt.PamHyrNavigationToolbar2QT(
|
|
||||||
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.navigation_toolbar_2qt import PamHyrNavigationToolbar2QT
|
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 *
|
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,68 +60,65 @@ _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):
|
||||||
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 = PamHyrNavigationToolbar2QT(
|
self.toolbar_1 = PamhyrPlotToolbar(
|
||||||
self.canvas_1, self
|
self.canvas_1, self
|
||||||
)
|
)
|
||||||
self.plot_layout_1 = self.find(QVBoxLayout, "verticalLayout_1")
|
self.plot_layout_1 = self.find(QVBoxLayout, "verticalLayout_1")
|
||||||
@@ -132,13 +128,15 @@ 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()
|
||||||
|
|
||||||
self.canvas_2 = MplCanvas(width=5, height=4, dpi=100)
|
self.canvas_2 = MplCanvas(width=5, height=4, dpi=100)
|
||||||
self.canvas_2.setObjectName("canvas_2")
|
self.canvas_2.setObjectName("canvas_2")
|
||||||
self.toolbar_2 = PamHyrNavigationToolbar2QT(
|
self.toolbar_2 = PamhyrPlotToolbar(
|
||||||
self.canvas_2, self
|
self.canvas_2, self
|
||||||
)
|
)
|
||||||
self.plot_layout_2 = self.find(QVBoxLayout, "verticalLayout_2")
|
self.plot_layout_2 = self.find(QVBoxLayout, "verticalLayout_2")
|
||||||
@@ -148,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()
|
||||||
|
|
||||||
@@ -165,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):
|
||||||
@@ -225,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,14 +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)"),
|
self._dict["elevation"] = _translate("InitialCondition", "Elevation (m)")
|
||||||
"elevation": _translate("LateralContribution", "Elevation (m)"),
|
self._dict["discharge"] = _translate("InitialCondition", "Discharge (m³/s)")
|
||||||
"height": _translate("LateralContribution", "Height (m)"),
|
self._dict["kp"] = _translate("InitialCondition", "KP (m)")
|
||||||
# "comment": _translate("LateralContribution", "Comment"),
|
|
||||||
}
|
self._sub_dict["table_headers"] = {
|
||||||
|
# "name": _translate("InitialCondition", "Name"),
|
||||||
|
"kp": _translate("InitialCondition", "KP (m)"),
|
||||||
|
# "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)
|
||||||
|
|||||||
Loaded 100 of 170 files, more files were not shown because too many files have changed in this diff.
Show more
Reference in new issue
Block a user