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 ...@@ -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 descriptive code. The UI files are saved into =src/View/ui= for
window, and =/src/View/ui/Widgets= for custom widget. 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 *** Window
The abstract class PamhyrWindow and PamhyrDialog are used for most of The abstract class PamhyrWindow and PamhyrDialog are used for most of
Pamhyr2 window. These class allow to create an window for Pamhyr2 GUI 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 #+NAME: window
#+CAPTION: Example of Pamhyr2 window #+CAPTION: Example of Pamhyr2 window
#+begin_src python :python python3 :results output :noweb yes #+begin_src python :python python3 :results output :noweb yes
from View.Tools.PamhyrWindow import PamhyrWindow from View.Tools.PamhyrWindow import PamhyrWindow
from View.My.Translate import MyTranslate
class MyWindow(PamhyrWindow):
_pamhyr_ui = "MyUI" class MyWindow(PamhyrWindow):
_pamhyr_name = "My window" _pamhyr_ui = "MyUI"
_pamhyr_name = "My window"
def __init__(self, my_data=None,
study=None, config=None, def __init__(self, my_data=None,
parent=None): study=None, config=None,
self._my_data = my_data parent=None):
self._my_data = my_data
super(MyWindow, self).__init__(
# Window title super(MyWindow, self).__init__(
title = self._pamhyr_name + " - " + study.name, # Window title
# Window standard data title = self._pamhyr_name + " - " + study.name,
study = study, config = config, parent = parent, # Window standard data
# Activate undo/redo and copy/paste shortcut study = study, config = config,
options = ["undo", "copy"] trad = MyTranslate(),
) parent = parent,
# Activate undo/redo and copy/paste shortcut
options = ["undo", "copy"]
)
# Add custom data to hash window computation # Add custom data to hash window computation
self._hash_data.append(self._my_data) self._hash_data.append(self._my_data)
# Setup custom window components # Setup custom window components
self.setup_table() self.setup_table()
self.setup_connections() self.setup_connections()
def setup_table(self): def setup_table(self):
# Init table(s)... # Init table(s)...
def setup_connections(self): def setup_connections(self):
# Init action connection(s)... # Init action connection(s)...
# ... # ...
#+end_src #+end_src
Typically we called method =setup_*=, the method to initialize some Typically we called method =setup_*=, the method to initialize some
...@@ -499,20 +533,6 @@ and =setData= methode to implement, but the constructor needs more ...@@ -499,20 +533,6 @@ and =setData= methode to implement, but the constructor needs more
information than a classic QAbstractTableModel class. information than a classic QAbstractTableModel class.
#+begin_src python :python python3 :results output :noweb yes #+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) # Table model definition (Table.py)
class MyTableModel(PamhyrTableModel): class MyTableModel(PamhyrTableModel):
def data(self, index, role): def data(self, index, role):
...@@ -523,6 +543,7 @@ information than a classic QAbstractTableModel class. ...@@ -523,6 +543,7 @@ information than a classic QAbstractTableModel class.
# Set VALUE at INDEX... # Set VALUE at INDEX...
# Table model creation (Window.py) # Table model creation (Window.py)
table_headers = self._trad.get_dict("table_headers")
self._model = MyTableModel( self._model = MyTableModel(
table_view = table, # The table view object table_view = table, # The table view object
table_headers = table_headers, # The table column headers dict table_headers = table_headers, # The table column headers dict
......
...@@ -41,10 +41,7 @@ from Model.River import RiverNode, RiverReach, River ...@@ -41,10 +41,7 @@ from Model.River import RiverNode, RiverReach, River
from View.Tools.PamhyrWindow import PamhyrWindow from View.Tools.PamhyrWindow import PamhyrWindow
from View.Network.GraphWidget import GraphWidget from View.Network.GraphWidget import GraphWidget
from View.Network.UndoCommand import * from View.Network.UndoCommand import *
from View.Network.translate import ( from View.Network.translate import NetworkTranslate
table_headers_node, table_headers_edge,
retranslate,
)
from View.Network.Table import ( from View.Network.Table import (
ComboBoxDelegate, NodeTableModel, EdgeTableModel, ComboBoxDelegate, NodeTableModel, EdgeTableModel,
) )
...@@ -63,24 +60,25 @@ class NetworkWindow(PamhyrWindow): ...@@ -63,24 +60,25 @@ class NetworkWindow(PamhyrWindow):
title = self._pamhyr_name + " - " + study.name, title = self._pamhyr_name + " - " + study.name,
study = study, study = study,
config = config, config = config,
trad = NetworkTranslate(),
options = ['undo'], options = ['undo'],
parent=parent, parent=parent,
) )
self._graph = study.river self._graph = study.river
self._table_headers_node = self._trad.get_dict("table_headers_node")
self._table_headers_edge = self._trad.get_dict("table_headers_edge")
self.setup_graph() self.setup_graph()
self.setup_table() self.setup_table()
self.setup_connections() self.setup_connections()
def setup_table(self): def setup_table(self):
retranslate()
# Nodes table # Nodes table
table = self.find(QTableView, "tableView_nodes") table = self.find(QTableView, "tableView_nodes")
self._nodes_model = NodeTableModel( self._nodes_model = NodeTableModel(
table_view = table, table_view = table,
table_headers = table_headers_node, table_headers = self._table_headers_node,
editable_headers = ["name"], editable_headers = ["name"],
data = self._graph, data = self._graph,
undo = self._undo_stack, undo = self._undo_stack,
...@@ -99,7 +97,7 @@ class NetworkWindow(PamhyrWindow): ...@@ -99,7 +97,7 @@ class NetworkWindow(PamhyrWindow):
self._reachs_model = EdgeTableModel( self._reachs_model = EdgeTableModel(
table_view = table, table_view = table,
table_headers = table_headers_edge, table_headers = self._table_headers_edge,
editable_headers = ["name", "node1", "node2"], editable_headers = ["name", "node1", "node2"],
delegates = { delegates = {
"node1": self.delegate_combobox, "node1": self.delegate_combobox,
......
...@@ -18,23 +18,21 @@ ...@@ -18,23 +18,21 @@
from PyQt5.QtCore import QCoreApplication from PyQt5.QtCore import QCoreApplication
_translate = QCoreApplication.translate from View.Tools.PamhyrTranslate import PamhyrTranslate
table_headers_node = { _translate = QCoreApplication.translate
"name": _translate("Network", "Name"),
"type": _translate("Network", "Type"),
}
table_headers_edge = { class NetworkTranslate(PamhyrTranslate):
"name": _translate("Network", "Name"), def __init__(self):
"node1": _translate("Network", "Source node"), super(NetworkTranslate, self).__init__()
"node2": _translate("Network", "Destination node"),
}
def retranslate(): self._sub_dict["table_headers_node"] = {
table_headers_node["name"] = _translate("Network", "Name") "name": _translate("Network", "Name"),
table_headers_node["type"] = _translate("Network", "Type") "type": _translate("Network", "Type"),
}
table_headers_edge["name"] = _translate("Network", "Name") self._sub_dict["table_headers_edge"] = {
table_headers_edge["node1"] = _translate("Network", "Source node") "name": _translate("Network", "Name"),
table_headers_edge["node2"] = _translate("Network", "Destination node") "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): ...@@ -140,12 +140,13 @@ class PamhyrWindow(ASubMainWindow, ListedSubWindow, PamhyrWindowTools):
def __init__(self, def __init__(self,
title = "Pamhyr2", title = "Pamhyr2",
study = None, config = None, study = None, config = None, trad = None,
options = ["undo", "copy"], options = ["undo", "copy"],
parent = None): parent = None):
self._title = title self._title = title
self._study = study self._study = study
self._config = config self._config = config
self._trad = trad
self._parent = parent self._parent = parent
super(PamhyrWindow, self).__init__( super(PamhyrWindow, self).__init__(
...@@ -166,21 +167,22 @@ class PamhyrDialog(ASubWindow, ListedSubWindow, PamhyrWindowTools): ...@@ -166,21 +167,22 @@ class PamhyrDialog(ASubWindow, ListedSubWindow, PamhyrWindowTools):
def __init__(self, def __init__(self,
title = "Pamhyr2", title = "Pamhyr2",
study = None, config = None, study = None, config = None, trad = None,
options = ["undo", "copy"], options = ["undo", "copy"],
parent = None): parent = None):
self._title = title self._title = title
self._study = study self._study = study
self._config = config self._config = config
self._trad = trad
self._parent = parent self._parent = parent
logger.info(self._pamhyr_name)
logger.info(self._pamhyr_ui)
super(PamhyrDialog, self).__init__( super(PamhyrDialog, self).__init__(
name = self._pamhyr_name, name = self._pamhyr_name,
ui = self._pamhyr_ui, ui = self._pamhyr_ui,
parent = parent, parent = parent,
) )
self._hash_data.append(self._study)
self._hash_data.append(self._config)
self._set_title() 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