Refactoring: Use ui file for geometry reach window.

setup.py
Pierre-Antoine Rouby 2023-10-03 15:10:46 +02:00
parent ef672798ef
commit 44ccf99d48
11 changed files with 625 additions and 251 deletions

View File

@ -106,6 +106,9 @@ class Reach(SQLSubModel):
return self._parent.name
def __len__(self):
return len(self._profiles)
@property
def profiles(self):
return self._profiles.copy()

View File

@ -19,7 +19,7 @@
import logging
from tools import timer
from View.Plot.APlot import APlot
from View.Tools.PamhyrPlot import PamhyrPlot
from PyQt5.QtCore import (
QCoreApplication
@ -29,12 +29,15 @@ _translate = QCoreApplication.translate
logger = logging.getLogger()
class PlotAC(APlot):
def __init__(self, canvas=None, data=None, toolbar=None, plot_xy=None):
class PlotAC(PamhyrPlot):
def __init__(self, canvas=None, trad=None, data=None, toolbar=None,
plot_xy=None, parent=None):
super(PlotAC, self).__init__(
canvas=canvas,
data=data,
toolbar=toolbar
canvas = canvas,
trad = trad,
data = data,
toolbar = toolbar,
parent = parent
)
self.plot_xy = plot_xy

View File

@ -19,7 +19,7 @@
import logging
from tools import timer
from View.Plot.APlot import APlot
from View.Tools.PamhyrPlot import PamhyrPlot
from PyQt5.QtCore import (
QCoreApplication
@ -29,13 +29,15 @@ _translate = QCoreApplication.translate
logger = logging.getLogger()
class PlotKPZ(APlot):
def __init__(self, canvas=None, data=None, toolbar=None,
display_current=True):
class PlotKPZ(PamhyrPlot):
def __init__(self, canvas=None, trad=None, data=None, toolbar=None,
display_current=True, parent=None):
super(PlotKPZ, self).__init__(
canvas=canvas,
data=data,
toolbar=toolbar
canvas = canvas,
trad = trad,
data = data,
toolbar = toolbar,
parent = parent
)
self.display_current = display_current

View File

@ -17,7 +17,7 @@
# -*- coding: utf-8 -*-
from tools import timer, trace
from View.Plot.APlot import APlot
from View.Tools.PamhyrPlot import PamhyrPlot
from PyQt5.QtCore import (
QCoreApplication
@ -25,12 +25,15 @@ from PyQt5.QtCore import (
_translate = QCoreApplication.translate
class PlotXY(APlot):
def __init__(self, canvas=None, data=None, toolbar=None, display_current=True):
class PlotXY(PamhyrPlot):
def __init__(self, canvas=None, trad=None, data=None, toolbar=None,
display_current=True, parent=None):
super(PlotXY, self).__init__(
canvas=canvas,
data=data,
toolbar=toolbar
canvas = canvas,
trad = trad,
data = data,
toolbar = toolbar,
parent = parent
)
self.display_current = display_current
@ -60,11 +63,11 @@ class PlotXY(APlot):
# Axes
self.canvas.axes.set_xlabel(
_translate("MainWindow_reach", "X (m)"),
_translate("Geometry", "X (m)"),
color='green', fontsize=12
)
self.canvas.axes.set_ylabel(
_translate("MainWindow_reach", "Y (m)"),
_translate("Geometry", "Y (m)"),
color='green', fontsize=12
)
self.canvas.axes.axis("equal")

View File

@ -35,6 +35,8 @@ from PyQt5.QtWidgets import (
QComboBox,
)
from View.Tools.PamhyrTable import PamhyrTableModel
from Model.Geometry import Reach
from Model.Geometry.ProfileXYZ import ProfileXYZ
from View.Geometry.UndoCommand import *
@ -44,53 +46,26 @@ logger = logging.getLogger()
_translate = QCoreApplication.translate
class TableEditableModel(QAbstractTableModel):
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)
class TableEditableModel(PamhyrTableModel):
def data(self, index, role=Qt.DisplayRole):
if not index.isValid():
return QVariant()
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:
kp = self._reach.profile(index.row()).kp
kp = self._data.profile(index.row()).kp
return f"{kp:.4f}"
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:
return Qt.AlignHCenter | Qt.AlignVCenter
if role == Qt.ForegroundRole and index.column() == 0:
name = self._reach.profile(index.row()).name\
name = self._data.profile(index.row()).name\
.strip()\
.lower()
if (name == "upstream" or name == "up" or
@ -102,16 +77,6 @@ class TableEditableModel(QAbstractTableModel):
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):
row = index.row()
column = index.column()
@ -119,19 +84,19 @@ class TableEditableModel(QAbstractTableModel):
if role == Qt.EditRole and index.column() != 2:
try:
if index.column() == 0:
self._undo_stack.push(
self._undo.push(
SetNameCommand(
self._reach, index.row(),
self._reach.profile(index.row()).name,
self._data, index.row(),
self._data.profile(index.row()).name,
value
)
)
if index.column() == 1:
self._undo_stack.push(
self._undo.push(
SetKPCommand(
self._reach, index.row(),
self._reach.profile(index.row()).kp,
self._data, index.row(),
self._data.profile(index.row()).kp,
value
)
)
@ -149,27 +114,13 @@ class TableEditableModel(QAbstractTableModel):
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()
def insert_row(self, row, parent=QModelIndex()):
self.beginInsertRows(parent, row, row - 1)
self._undo_stack.push(
self._undo.push(
AddCommand(
self._reach, row
self._data, row
)
)
@ -179,9 +130,9 @@ class TableEditableModel(QAbstractTableModel):
def remove_rows(self, rows, parent=QModelIndex()):
self.beginRemoveRows(parent, rows[0], rows[-1])
self._undo_stack.push(
self._undo.push(
DelCommand(
self._reach, rows
self._data, rows
)
)
@ -191,9 +142,9 @@ class TableEditableModel(QAbstractTableModel):
def sort_profiles(self, _reverse):
self.layoutAboutToBeChanged.emit()
self._undo_stack.push(
self._undo.push(
SortCommand(
self._reach, _reverse
self._data, _reverse
)
)
@ -209,9 +160,9 @@ class TableEditableModel(QAbstractTableModel):
self.beginMoveRows(parent, row - 1, row - 1, parent, target)
self._undo_stack.push(
self._undo.push(
MoveCommand(
self._reach, "up", row
self._data, "up", row
)
)
@ -219,16 +170,16 @@ class TableEditableModel(QAbstractTableModel):
self.layoutChanged.emit()
def move_row_down(self, row, parent=QModelIndex()):
if row > self._reach.number_profiles:
if row > self._data.number_profiles:
return
target = row
self.beginMoveRows(parent, row + 1, row + 1, parent, target)
self._undo_stack.push(
self._undo.push(
MoveCommand(
self._reach, "down", row
self._data, "down", row
)
)
@ -238,9 +189,9 @@ class TableEditableModel(QAbstractTableModel):
def duplicate(self, rows, profiles):
self.layoutAboutToBeChanged.emit()
self._undo_stack.push(
self._undo.push(
DuplicateCommand(
self._reach, rows,
self._data, rows,
profiles
)
)
@ -250,7 +201,7 @@ class TableEditableModel(QAbstractTableModel):
def paste(self, row, header, data):
if row > self._reach.number_profiles:
if row > self._data.number_profiles:
return
if len(data) == 0:
@ -258,9 +209,9 @@ class TableEditableModel(QAbstractTableModel):
self.layoutAboutToBeChanged.emit()
self._undo_stack.push(
self._undo.push(
PasteCommand(
self._reach, row,
self._data, row,
list(
map(
lambda d: ProfileXYZ.from_data(header, d),
@ -273,16 +224,7 @@ class TableEditableModel(QAbstractTableModel):
self.layoutAboutToBeChanged.emit()
self.layoutChanged.emit()
def undo(self):
self._undo_stack.undo()
self.layoutChanged.emit()
def redo(self):
self._undo_stack.redo()
self.layoutChanged.emit()
# TODO: Delete useless delegate
class Delegate(QStyledItemDelegate):
def __init__(self, parent=None, setModelDataEvent=None):
super(Delegate, self).__init__(parent)

View File

@ -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"),
}

View File

@ -34,118 +34,168 @@ from PyQt5.QtCore import (
)
from PyQt5.QtWidgets import (
QApplication, QMainWindow, QFileDialog, QCheckBox,
QUndoStack, QShortcut,
QUndoStack, QShortcut, QTableView, QHeaderView,
QAction, QSlider, QPushButton, QVBoxLayout,
QLabel,
)
from View.Geometry.PlotXY import PlotXY
from View.Geometry.PlotKPZ import PlotKPZ
from View.Geometry.PlotAC import PlotAC
from View.Tools.ASubWindow import ASubMainWindow, WindowToolKit
from View.Tools.ListedSubWindow import ListedSubWindow
from View.Tools.PamhyrWindow import PamhyrWindow
from View.Tools.Plot.PamhyrToolbar import PamhyrPlotToolbar
from View.Tools.Plot.PamhyrCanvas import MplCanvas
from View.Geometry.mainwindow_ui_reach import Ui_MainWindow
from View.Geometry.Table import *
from View.Geometry.Profile.Window import ProfileWindow
from View.Geometry.Translate import GeometryTranslate
# from View.Geometry.Profile.Window import ProfileWindow
_translate = QCoreApplication.translate
class GeometryWindow(ASubMainWindow, ListedSubWindow):
def __init__(self, model=None, title="Geometry", parent=None):
self._title = title
self.parent = parent
class GeometryWindow(PamhyrWindow):
_pamhyr_ui = "GeometryReach"
_pamhyr_name = "Geometry"
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__(
name=self._title,
parent=parent
title = name,
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._profile_window = []
self._clipboard = None
self.setup_window()
self.setup_sc()
self.setup_model()
self.setup_table()
self.setup_plots()
self.setup_statusbar()
self.setup_connections()
self.changed_slider_value()
def setup_window(self):
self._title = f"{self.ui.mainwindow_title} - {self._reach.name}"
self.setWindowTitle(self._title)
def setup_table(self):
table_headers = self._trad.get_dict("table_headers")
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_model(self):
table = self.find(QTableView, "tableView")
self._tablemodel = TableEditableModel(
headers = self.ui.tableView_header,
reach = self._reach,
table_view = table,
table_headers = table_headers,
editable_headers = ["name", "kp"],
data = self._reach,
undo = self._undo_stack
)
self.tableView.setModel(self._tablemodel)
self.tableView.setItemDelegate(Delegate())
table.setModel(self._tablemodel)
table.setSelectionBehavior(QAbstractItemView.SelectRows)
table.horizontalHeader().setSectionResizeMode(QHeaderView.Stretch)
table.setAlternatingRowColors(True)
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._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._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()
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):
self.ui.btn_open.triggered.connect(self.open_file_dialog)
self.ui.btn_sort_asc.triggered.connect(self.sort_ascending)
self.ui.btn_sort_desc.triggered.connect(self.sort_descending)
self.ui.btn_move_up.triggered.connect(self.move_row_up)
self.ui.btn_move_down.triggered.connect(self.move_row_down)
# self.ui.btn_end_editing.triggered.connect(self.handleSave)
self.ui.btn_add.triggered.connect(self.insert_row)
self.ui.btn_delete.triggered.connect(self.delete_rows)
self.ui.btn_edit.triggered.connect(self.edit_profile)
self.ui.verticalSlider.valueChanged.connect(self.changed_slider_value)
actions = {
"action_import": self.import_from_file,
# "action_export": self.export_to_file,
"action_sort_asc": self.sort_ascending,
"action_sort_des": self.sort_descending,
"action_up": self.move_up,
"action_down": self.move_down,
"action_add": self.add,
"action_delete": self.delete,
"action_edit": self.edit_profile,
}
self.ui.btn_slider_up.clicked.connect(self.decrement_value_slider)
self.ui.btn_slider_down.clicked.connect(self.increment_value_slider)
self.ui.btn_move_up.triggered.connect(self.changed_profile_slot)
for action in actions:
self.find(QAction, action)\
.triggered.connect(actions[action])
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.find(QSlider, "verticalSlider").valueChanged.connect(self.changed_slider_value)
self.find(QPushButton, "pushButton_up").clicked.connect(self.decrement_value_slider)
self.find(QPushButton, "pushButton_down").clicked.connect(self.increment_value_slider)
# Profile selection when line change in table
self.tableView.selectionModel()\
.selectionChanged\
.connect(self.select_current_profile)
self.find(QTableView, "tableView").selectionModel()\
.selectionChanged\
.connect(self.select_current_profile)
def open_file_dialog(self):
def import_from_file(self):
options = QFileDialog.Options()
settings = QSettings(QSettings.IniFormat, QSettings.UserScope, 'MyOrg', )
options |= QFileDialog.DontUseNativeDialog
file_types = [
self._trad["file_st"],
self._trad["file_m"],
self._trad["file_all"],
]
filename, _ = QtWidgets.QFileDialog.getOpenFileName(
self,
_translate("MainWindow_reach", "Ouvrir un fichier"),
self._trad["open_file"],
"",
_translate("MainWindow_reach", "Fichiers .ST (*.ST)") +
";; " +
_translate("MainWindow_reach", "Fichiers .M (*.M)") +
";; " +
_translate("MainWindow_reach", "Tous les fichiers (*)"),
";; ".join(file_types),
options=options
)
@ -159,20 +209,6 @@ class GeometryWindow(ASubMainWindow, ListedSubWindow):
self.plot_kpc()
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):
self.tableView.model().blockSignals(True)
@ -215,9 +251,9 @@ class GeometryWindow(ASubMainWindow, ListedSubWindow):
self.tableView.model().blockSignals(True)
self._plot_xy = PlotXY(
canvas = self.ui.canvas_1,
canvas = self._canvas_xy,
data = self._reach,
toolbar = self.ui.toolbar_1
toolbar = self._toolbar_xy
)
self._plot_xy.draw()
@ -232,9 +268,9 @@ class GeometryWindow(ASubMainWindow, ListedSubWindow):
self.tableView.model().blockSignals(True)
self._plot_kpc = PlotKPZ(
canvas = self.ui.canvas_2,
canvas = self._canvas_kpc,
data = self._reach,
toolbar = self.ui.toolbar_2
toolbar = self._toolbar_kpc
)
self._plot_kpc.draw()
@ -249,9 +285,9 @@ class GeometryWindow(ASubMainWindow, ListedSubWindow):
self.tableView.model().blockSignals(True)
self._plot_ac = PlotAC(
canvas = self.ui.canvas_3,
canvas = self._canvas_ac,
data = self._reach,
toolbar = self.ui.toolbar_3,
toolbar = self._toolbar_ac,
plot_xy = self._plot_xy
)
self._plot_ac.draw()
@ -304,7 +340,7 @@ class GeometryWindow(ASubMainWindow, ListedSubWindow):
if len(self.tableView.selectedIndexes()) > 0:
row = self.index_selected_row()
self.ui.verticalSlider.setValue(row)
self.find(QSlider, "verticalSlider").setValue(row)
self.select_plot_xy(row)
self.select_plot_kpc(row)
self.select_plot_ac(row)
@ -315,41 +351,37 @@ class GeometryWindow(ASubMainWindow, ListedSubWindow):
self.tableView.model().blockSignals(True)
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
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_kpc(slider_value)
self.select_row_profile_slider(slider_value)
self.update_statusbar()
self.tableView.model().blockSignals(False)
def increment_value_slider(self):
if 0 <= self.ui.verticalSlider.value() < self._tablemodel.rowCount() - 1:
self.ui.verticalSlider.setValue(self.ui.verticalSlider.value() + 1)
slider = self.find(QSlider, "verticalSlider")
if 0 <= slider.value() < self._tablemodel.rowCount() - 1:
slider.setValue(slider.value() + 1)
def decrement_value_slider(self):
if 0 < self.ui.verticalSlider.value() < self._tablemodel.rowCount():
self.ui.verticalSlider.setValue(self.ui.verticalSlider.value() - 1)
slider = self.find(QSlider, "verticalSlider")
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:
self._tablemodel.insert_row(self._tablemodel.rowCount())
self._tablemodel.add(self._tablemodel.rowCount())
else:
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(
list(
set(
@ -384,14 +416,14 @@ class GeometryWindow(ASubMainWindow, ListedSubWindow):
self.select_current_profile()
self.changed_slider_value()
def move_row_up(self):
def move_up(self):
row = self.index_selected_row()
self._tablemodel.move_row_up(row)
self._tablemodel.move_up(row)
self.select_current_profile()
def move_row_down(self):
def move_down(self):
row = self.index_selected_row()
self._tablemodel.move_row_down(row)
self._tablemodel.move_down(row)
self.select_current_profile()
def duplicate(self):
@ -412,7 +444,7 @@ class GeometryWindow(ASubMainWindow, ListedSubWindow):
self._tablemodel.duplicate(rows, profiles)
self.select_current_profile()
def copy(self):
def _copy(self):
rows = self.tableView\
.selectionModel()\
.selectedRows()
@ -428,7 +460,7 @@ class GeometryWindow(ASubMainWindow, ListedSubWindow):
self.copyTableIntoClipboard(table)
def paste(self):
def _paste(self):
header, data = self.parseClipboardTable()
if len(data) == 0:
@ -443,19 +475,19 @@ class GeometryWindow(ASubMainWindow, ListedSubWindow):
self._tablemodel.paste(row, header, data)
self.select_current_profile()
def undo(self):
def _undo(self):
self._tablemodel.undo()
self.select_current_profile()
self.update_plot_xy()
self.update_plot_kpc()
def redo(self):
def _redo(self):
self._tablemodel.redo()
self.select_current_profile()
self.update_plot_xy()
self.update_plot_kpc()
def handleSave(self):
def export_to_file(self):
options = QFileDialog.Options()
DEFAULT_DIRECTORY = '/home/'
settings = QSettings(QSettings.IniFormat, QSettings.UserScope, 'MyOrg', )
@ -464,32 +496,11 @@ class GeometryWindow(ASubMainWindow, ListedSubWindow):
filename, filters = QFileDialog.getSaveFileName(
self,
filter=_translate("MainWindow_reach",
"Files .ST(*.ST or *.st)")
+ ";; " +
_translate("MainWindow_reach", "All files "
"(*)"),
options=options
filter = self._trad["file_st"] + ";; " + self._trad["file_all"],
options = options
)
current_dir = os.path.split(filename)[0] or DEFAULT_DIRECTORY
if 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 = ''

View File

@ -44,7 +44,7 @@ from View.Configure.Window import ConfigureWindow
from View.Study.Window import NewStudyWindow
from View.About.Window import AboutWindow
from View.Network.Window import NetworkWindow
# from View.Geometry.Window import GeometryWindow
from View.Geometry.Window import GeometryWindow
# from View.BoundaryCondition.Window import BoundaryConditionWindow
# from View.LateralContribution.Window import LateralContributionWindow
# from View.InitialConditions.Window import InitialConditionsWindow
@ -534,7 +534,7 @@ class ApplicationWindow(QMainWindow, ListedSubWindow, WindowToolKit):
)
if geometry is None:
geometry = GeometryWindow(model=self._study, parent=self)
geometry = GeometryWindow(study=self._study, config=self.conf, parent=self)
geometry.show()
else:
geometry.activateWindow()

View File

@ -115,10 +115,10 @@ class PamhyrTableModel(QAbstractTableModel):
return options
def rowCount(self, parent):
def rowCount(self, parent=QModelIndex()):
return len(self._lst)
def columnCount(self, parent):
def columnCount(self, parent=QModelIndex()):
return len(self._headers)
def headerData(self, section, orientation, role):

View File

@ -0,0 +1,134 @@
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>MainWindow</class>
<widget class="QMainWindow" name="MainWindow">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>1120</width>
<height>630</height>
</rect>
</property>
<property name="windowTitle">
<string>MainWindow</string>
</property>
<widget class="QWidget" name="centralwidget">
<layout class="QGridLayout" name="gridLayout">
<item row="0" column="0">
<widget class="QSplitter" name="splitter">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<widget class="QTableView" name="tableView"/>
<widget class="QWidget" name="verticalLayoutWidget">
<layout class="QVBoxLayout" name="verticalLayout"/>
</widget>
</widget>
</item>
</layout>
</widget>
<widget class="QMenuBar" name="menubar">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>1120</width>
<height>22</height>
</rect>
</property>
</widget>
<widget class="QStatusBar" name="statusbar"/>
<widget class="QToolBar" name="toolBar">
<property name="windowTitle">
<string>toolBar</string>
</property>
<attribute name="toolBarArea">
<enum>TopToolBarArea</enum>
</attribute>
<attribute name="toolBarBreak">
<bool>false</bool>
</attribute>
<addaction name="action_add"/>
<addaction name="action_delete"/>
<addaction name="action_sort"/>
<addaction name="action_resort"/>
<addaction name="action_up"/>
<addaction name="action_down"/>
</widget>
<action name="action_add">
<property name="icon">
<iconset>
<normaloff>ressources/gtk-add.png</normaloff>ressources/gtk-add.png</iconset>
</property>
<property name="text">
<string>add</string>
</property>
<property name="toolTip">
<string>Add a point on cross-section</string>
</property>
</action>
<action name="action_delete">
<property name="icon">
<iconset>
<normaloff>ressources/gtk-remove.png</normaloff>ressources/gtk-remove.png</iconset>
</property>
<property name="text">
<string>delete</string>
</property>
<property name="toolTip">
<string>Delete selected point(s)</string>
</property>
</action>
<action name="action_up">
<property name="icon">
<iconset>
<normaloff>ressources/up.png</normaloff>ressources/up.png</iconset>
</property>
<property name="text">
<string>up</string>
</property>
<property name="toolTip">
<string>Move up selected point(s)</string>
</property>
</action>
<action name="action_down">
<property name="icon">
<iconset>
<normaloff>ressources/down.png</normaloff>ressources/down.png</iconset>
</property>
<property name="text">
<string>down</string>
</property>
<property name="toolTip">
<string>Mode down selected point(s)</string>
</property>
</action>
<action name="action_sort">
<property name="icon">
<iconset>
<normaloff>ressources/gtk-sort-ascending.png</normaloff>ressources/gtk-sort-ascending.png</iconset>
</property>
<property name="text">
<string>sort</string>
</property>
<property name="toolTip">
<string>Sort points by nearest neighbor</string>
</property>
</action>
<action name="action_resort">
<property name="icon">
<iconset>
<normaloff>ressources/gtk-sort-descending.png</normaloff>ressources/gtk-sort-descending.png</iconset>
</property>
<property name="text">
<string>resort</string>
</property>
<property name="toolTip">
<string>Sort reversed points by nearest neighbor</string>
</property>
</action>
</widget>
<resources/>
<connections/>
</ui>

View File

@ -0,0 +1,231 @@
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>MainWindow</class>
<widget class="QMainWindow" name="MainWindow">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>1280</width>
<height>720</height>
</rect>
</property>
<property name="windowTitle">
<string>MainWindow</string>
</property>
<property name="locale">
<locale language="English" country="Europe"/>
</property>
<widget class="QWidget" name="centralwidget">
<layout class="QGridLayout" name="gridLayout">
<item row="0" column="0">
<layout class="QHBoxLayout" name="horizontalLayout">
<item>
<widget class="QSplitter" name="splitter_3">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<widget class="QTableView" name="tableView"/>
<widget class="QSplitter" name="splitter_2">
<property name="orientation">
<enum>Qt::Vertical</enum>
</property>
<widget class="QSplitter" name="splitter">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<widget class="QWidget" name="verticalLayoutWidget">
<layout class="QVBoxLayout" name="verticalLayout"/>
</widget>
<widget class="QWidget" name="verticalLayoutWidget_2">
<layout class="QVBoxLayout" name="verticalLayout_2"/>
</widget>
</widget>
<widget class="QWidget" name="verticalLayoutWidget_3">
<layout class="QVBoxLayout" name="verticalLayout_3"/>
</widget>
</widget>
</widget>
</item>
<item>
<layout class="QVBoxLayout" name="verticalLayout_4">
<item>
<layout class="QHBoxLayout" name="horizontalLayout_2">
<item>
<widget class="QSlider" name="verticalSlider">
<property name="orientation">
<enum>Qt::Vertical</enum>
</property>
<property name="invertedAppearance">
<bool>true</bool>
</property>
<property name="invertedControls">
<bool>true</bool>
</property>
</widget>
</item>
</layout>
</item>
<item>
<widget class="QPushButton" name="pushButton_up">
<property name="text">
<string/>
</property>
<property name="icon">
<iconset>
<normaloff>ressources/go-up2.png</normaloff>ressources/go-up2.png</iconset>
</property>
</widget>
</item>
<item>
<widget class="QPushButton" name="pushButton_down">
<property name="text">
<string/>
</property>
<property name="icon">
<iconset>
<normaloff>ressources/go-down1.png</normaloff>ressources/go-down1.png</iconset>
</property>
</widget>
</item>
</layout>
</item>
</layout>
</item>
</layout>
</widget>
<widget class="QMenuBar" name="menubar">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>1280</width>
<height>22</height>
</rect>
</property>
</widget>
<widget class="QStatusBar" name="statusbar"/>
<widget class="QToolBar" name="toolBar">
<property name="windowTitle">
<string>toolBar</string>
</property>
<attribute name="toolBarArea">
<enum>TopToolBarArea</enum>
</attribute>
<attribute name="toolBarBreak">
<bool>false</bool>
</attribute>
<addaction name="action_import"/>
<addaction name="action_add"/>
<addaction name="action_delete"/>
<addaction name="action_edit"/>
<addaction name="action_sort_asc"/>
<addaction name="action_sort_des"/>
<addaction name="action_up"/>
<addaction name="action_down"/>
<addaction name="action_export"/>
</widget>
<action name="action_import">
<property name="text">
<string>import</string>
</property>
<property name="toolTip">
<string>Import geometry</string>
</property>
</action>
<action name="action_export">
<property name="text">
<string>export</string>
</property>
<property name="toolTip">
<string>Export geometry</string>
</property>
</action>
<action name="action_add">
<property name="icon">
<iconset>
<normaloff>ressources/gtk-add.png</normaloff>ressources/gtk-add.png</iconset>
</property>
<property name="text">
<string>add</string>
</property>
<property name="toolTip">
<string>Add a cross-section</string>
</property>
</action>
<action name="action_delete">
<property name="icon">
<iconset>
<normaloff>ressources/gtk-remove.png</normaloff>ressources/gtk-remove.png</iconset>
</property>
<property name="text">
<string>delete</string>
</property>
<property name="toolTip">
<string>Delete selected cross-section(s)</string>
</property>
</action>
<action name="action_edit">
<property name="icon">
<iconset>
<normaloff>ressources/edit.png</normaloff>ressources/edit.png</iconset>
</property>
<property name="text">
<string>edit</string>
</property>
<property name="toolTip">
<string>Edit selected cross section(s)</string>
</property>
</action>
<action name="action_sort_asc">
<property name="icon">
<iconset>
<normaloff>ressources/gtk-sort-ascending.png</normaloff>ressources/gtk-sort-ascending.png</iconset>
</property>
<property name="text">
<string>sort_asc</string>
</property>
<property name="toolTip">
<string>Sort cross-sections by ascending KP</string>
</property>
</action>
<action name="action_sort_des">
<property name="icon">
<iconset>
<normaloff>ressources/gtk-sort-descending.png</normaloff>ressources/gtk-sort-descending.png</iconset>
</property>
<property name="text">
<string>sort_des</string>
</property>
<property name="toolTip">
<string>Sort cross-sections by descending KP</string>
</property>
</action>
<action name="action_up">
<property name="icon">
<iconset>
<normaloff>ressources/up.png</normaloff>ressources/up.png</iconset>
</property>
<property name="text">
<string>up</string>
</property>
<property name="toolTip">
<string>Move up selected cross-section(s)</string>
</property>
</action>
<action name="action_down">
<property name="icon">
<iconset>
<normaloff>ressources/down.png</normaloff>ressources/down.png</iconset>
</property>
<property name="text">
<string>down</string>
</property>
<property name="toolTip">
<string>Move down selected cross-section(s)</string>
</property>
</action>
</widget>
<resources/>
<connections/>
</ui>