Commit 2e94348b authored by Pierre-Antoine Rouby's avatar Pierre-Antoine Rouby
Browse files

refactoring: Add PamhyrTranslate class for GUI translation and document it.

Showing with 148 additions and 73 deletions
+148 -73
......@@ -443,49 +443,83 @@ than hand made windows and widget creation, and saves us some purely
descriptive code. The UI files are saved into =src/View/ui= for
window, and =/src/View/ui/Widgets= for custom widget.
*** Translate
#+NAME: pamhyr-trad
#+CAPTION: Example of =PamhyrTranslate= class implementation with a global traduction for /FooBar/ and a additional dictionary =table_headers=
#+begin_src python :python python3 :results output :noweb yes
from PyQt5.QtCore import QCoreApplication
from View.Tools.PamhyrTranslate import PamhyrTranslate
_translate = QCoreApplication.translate
class MyTranslate(PamhyrTranslate):
def __init__(self):
super(MyTranslate, self).__init__()
# Add traduction to global dictionary
self._dict["My"] = _translate("My", "FooBar")
# Add an additional translate dictionary
self._sub_dict["table_headers"] = {
"foo": _translate("My", "Foo"),
"bar": _translate("My", "Bar"),
"baz": _translate("My", "Baz"),
}
#+end_src
*** Window
The abstract class PamhyrWindow and PamhyrDialog are used for most of
Pamhyr2 window. These class allow to create an window for Pamhyr2 GUI
and implemente some useful methods.
and implemente some useful methods. The super class method difine some
generic value from optional parameters, for examples:
- =self._study=: The study giving in constructor parameters =study=
(typically a =Model.Study= class object)
- =self._config=: The configuration giving in constructor parameters
=config= (typically a =Config= class object)
- =self._trad=: The traductor dictionary giving in constructor
parameters =trad= (typically a =Model.Tools.PamhyrTranslate= class
object)
#+NAME: window
#+CAPTION: Example of Pamhyr2 window
#+begin_src python :python python3 :results output :noweb yes
from View.Tools.PamhyrWindow import PamhyrWindow
class MyWindow(PamhyrWindow):
_pamhyr_ui = "MyUI"
_pamhyr_name = "My window"
def __init__(self, my_data=None,
study=None, config=None,
parent=None):
self._my_data = my_data
super(MyWindow, self).__init__(
# Window title
title = self._pamhyr_name + " - " + study.name,
# Window standard data
study = study, config = config, parent = parent,
# Activate undo/redo and copy/paste shortcut
options = ["undo", "copy"]
)
from View.Tools.PamhyrWindow import PamhyrWindow
from View.My.Translate import MyTranslate
class MyWindow(PamhyrWindow):
_pamhyr_ui = "MyUI"
_pamhyr_name = "My window"
def __init__(self, my_data=None,
study=None, config=None,
parent=None):
self._my_data = my_data
super(MyWindow, self).__init__(
# Window title
title = self._pamhyr_name + " - " + study.name,
# Window standard data
study = study, config = config,
trad = MyTranslate(),
parent = parent,
# Activate undo/redo and copy/paste shortcut
options = ["undo", "copy"]
)
# Add custom data to hash window computation
self._hash_data.append(self._my_data)
# Add custom data to hash window computation
self._hash_data.append(self._my_data)
# Setup custom window components
self.setup_table()
self.setup_connections()
# Setup custom window components
self.setup_table()
self.setup_connections()
def setup_table(self):
# Init table(s)...
def setup_table(self):
# Init table(s)...
def setup_connections(self):
# Init action connection(s)...
def setup_connections(self):
# Init action connection(s)...
# ...
# ...
#+end_src
Typically we called method =setup_*=, the method to initialize some
......@@ -499,20 +533,6 @@ and =setData= methode to implement, but the constructor needs more
information than a classic QAbstractTableModel class.
#+begin_src python :python python3 :results output :noweb yes
# Table headers with display name translatable (translate.py)
table_headers = {
"foo": _translate("My", "Foo"),
"bar": _translate("My", "Bar"),
"baz": _translate("My", "Baz"),
}
def retranslate():
# Hack because dict definition is not able to be
# translate... (need to be called in window '__init__')
table_headers["foo"] = _translate("My", "Foo")
table_headers["bar"] = _translate("My", "Bar")
table_headers["baz"] = _translate("My", "Baz")
# Table model definition (Table.py)
class MyTableModel(PamhyrTableModel):
def data(self, index, role):
......@@ -523,6 +543,7 @@ information than a classic QAbstractTableModel class.
# Set VALUE at INDEX...
# Table model creation (Window.py)
table_headers = self._trad.get_dict("table_headers")
self._model = MyTableModel(
table_view = table, # The table view object
table_headers = table_headers, # The table column headers dict
......
......@@ -41,10 +41,7 @@ from Model.River import RiverNode, RiverReach, River
from View.Tools.PamhyrWindow import PamhyrWindow
from View.Network.GraphWidget import GraphWidget
from View.Network.UndoCommand import *
from View.Network.translate import (
table_headers_node, table_headers_edge,
retranslate,
)
from View.Network.translate import NetworkTranslate
from View.Network.Table import (
ComboBoxDelegate, NodeTableModel, EdgeTableModel,
)
......@@ -63,24 +60,25 @@ class NetworkWindow(PamhyrWindow):
title = self._pamhyr_name + " - " + study.name,
study = study,
config = config,
trad = NetworkTranslate(),
options = ['undo'],
parent=parent,
)
self._graph = study.river
self._table_headers_node = self._trad.get_dict("table_headers_node")
self._table_headers_edge = self._trad.get_dict("table_headers_edge")
self.setup_graph()
self.setup_table()
self.setup_connections()
def setup_table(self):
retranslate()
# Nodes table
table = self.find(QTableView, "tableView_nodes")
self._nodes_model = NodeTableModel(
table_view = table,
table_headers = table_headers_node,
table_headers = self._table_headers_node,
editable_headers = ["name"],
data = self._graph,
undo = self._undo_stack,
......@@ -99,7 +97,7 @@ class NetworkWindow(PamhyrWindow):
self._reachs_model = EdgeTableModel(
table_view = table,
table_headers = table_headers_edge,
table_headers = self._table_headers_edge,
editable_headers = ["name", "node1", "node2"],
delegates = {
"node1": self.delegate_combobox,
......
......@@ -18,23 +18,21 @@
from PyQt5.QtCore import QCoreApplication
_translate = QCoreApplication.translate
from View.Tools.PamhyrTranslate import PamhyrTranslate
table_headers_node = {
"name": _translate("Network", "Name"),
"type": _translate("Network", "Type"),
}
_translate = QCoreApplication.translate
table_headers_edge = {
"name": _translate("Network", "Name"),
"node1": _translate("Network", "Source node"),
"node2": _translate("Network", "Destination node"),
}
class NetworkTranslate(PamhyrTranslate):
def __init__(self):
super(NetworkTranslate, self).__init__()
def retranslate():
table_headers_node["name"] = _translate("Network", "Name")
table_headers_node["type"] = _translate("Network", "Type")
self._sub_dict["table_headers_node"] = {
"name": _translate("Network", "Name"),
"type": _translate("Network", "Type"),
}
table_headers_edge["name"] = _translate("Network", "Name")
table_headers_edge["node1"] = _translate("Network", "Source node")
table_headers_edge["node2"] = _translate("Network", "Destination node")
self._sub_dict["table_headers_edge"] = {
"name": _translate("Network", "Name"),
"node1": _translate("Network", "Source node"),
"node2": _translate("Network", "Destination node"),
}
# PamhyrTranslate.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
_translate = QCoreApplication.translate
class PamhyrTranslate(object):
def __init__(self):
# Module global dictionnary
self._dict = {}
# Module sub dictionnary
self._sub_dict = {}
def __getitem__(self, index):
if index not in self._dict:
return None
return self._dict[index]
def _get_in_sub_dict(self, dictionary, index):
if dictionary not in self._sub_dict:
return None
return self._sub_dict[index]
def get(self, dictionary, index):
if dictionary == "global":
return self[index]
return self._get_in_sub_dict(dictionary, index)
def get_dict(self, dictionary):
_dict = None
if dictionary == "global":
_dict = self._dict
if dictionary in self._sub_dict:
_dict = self._sub_dict[dictionary]
return _dict
......@@ -140,12 +140,13 @@ class PamhyrWindow(ASubMainWindow, ListedSubWindow, PamhyrWindowTools):
def __init__(self,
title = "Pamhyr2",
study = None, config = None,
study = None, config = None, trad = None,
options = ["undo", "copy"],
parent = None):
self._title = title
self._study = study
self._config = config
self._trad = trad
self._parent = parent
super(PamhyrWindow, self).__init__(
......@@ -166,21 +167,22 @@ class PamhyrDialog(ASubWindow, ListedSubWindow, PamhyrWindowTools):
def __init__(self,
title = "Pamhyr2",
study = None, config = None,
study = None, config = None, trad = None,
options = ["undo", "copy"],
parent = None):
self._title = title
self._study = study
self._config = config
self._trad = trad
self._parent = parent
logger.info(self._pamhyr_name)
logger.info(self._pamhyr_ui)
super(PamhyrDialog, self).__init__(
name = self._pamhyr_name,
ui = self._pamhyr_ui,
parent = parent,
)
self._hash_data.append(self._study)
self._hash_data.append(self._config)
self._set_title()
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment