diff --git a/.env.template b/.env.template
index b06759ee2..d5fd29230 100644
--- a/.env.template
+++ b/.env.template
@@ -7,4 +7,6 @@ VENV_DIR=
# Python path for development (sibling packages)
PYTHONPATH=.
# Locale (e.g. fr)
-LANG=
\ No newline at end of file
+LANG=
+# Debug mode (0 or 1)
+DATALAB_DEBUG=0
\ No newline at end of file
diff --git a/.github/workflows/_build.yml b/.github/workflows/_build.yml
index 1d590bdac..fb051a5b6 100644
--- a/.github/workflows/_build.yml
+++ b/.github/workflows/_build.yml
@@ -201,7 +201,7 @@ jobs:
x11-utils xvfb \
texlive-latex-base texlive-latex-extra texlive-fonts-recommended \
texlive-fonts-extra texlive-lang-french texlive-xetex latexmk \
- fonts-symbola \
+ fonts-noto-core fonts-noto-mono fonts-noto-extra \
imagemagick librsvg2-bin
/sbin/start-stop-daemon --start --quiet \
--pidfile /tmp/custom_xvfb_99.pid --make-pidfile --background \
diff --git a/.github/workflows/release-rc.yml b/.github/workflows/release-rc.yml
index 9f9ccab80..f19eabbcb 100644
--- a/.github/workflows/release-rc.yml
+++ b/.github/workflows/release-rc.yml
@@ -59,6 +59,8 @@ jobs:
runs-on: ubuntu-latest
permissions:
contents: write
+ id-token: write # required by attest-build-provenance (OIDC)
+ attestations: write # required by attest-build-provenance
steps:
- uses: actions/checkout@v4
@@ -85,6 +87,23 @@ jobs:
name: msi-installer
path: assets/msi
+ - name: Generate SHA256SUMS
+ run: |
+ cd assets
+ find dists msi pdfs -type f \
+ \( -name '*.whl' -o -name '*.tar.gz' -o -name '*.msi' -o -name '*.pdf' \) \
+ -printf '%P\n' | sort | xargs -I{} sha256sum {} \
+ > SHA256SUMS
+ cat SHA256SUMS
+
+ - name: Attest build provenance
+ uses: actions/attest-build-provenance@v2
+ with:
+ subject-path: |
+ assets/dists/*.whl
+ assets/dists/*.tar.gz
+ assets/msi/*.msi
+
- name: Extract release notes
run: |
python scripts/ci_release_helpers.py release-notes \
@@ -105,3 +124,4 @@ jobs:
assets/msi/*.msi
assets/pdfs/DataLab_fr.pdf
assets/pdfs/DataLab_en.pdf
+ assets/SHA256SUMS
diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml
index 777c22db5..a2a3a7cb8 100644
--- a/.github/workflows/release.yml
+++ b/.github/workflows/release.yml
@@ -67,6 +67,8 @@ jobs:
runs-on: ubuntu-latest
permissions:
contents: write
+ id-token: write # required by attest-build-provenance (OIDC)
+ attestations: write # required by attest-build-provenance
steps:
- uses: actions/checkout@v4
@@ -93,6 +95,28 @@ jobs:
name: msi-installer
path: assets/msi
+ - name: Generate SHA256SUMS
+ # Single checksums file covering every artifact published in the
+ # release. Users verify with: `sha256sum -c SHA256SUMS`.
+ run: |
+ cd assets
+ find dists msi pdfs -type f \
+ \( -name '*.whl' -o -name '*.tar.gz' -o -name '*.msi' -o -name '*.pdf' \) \
+ -printf '%P\n' | sort | xargs -I{} sha256sum {} \
+ > SHA256SUMS
+ echo "--- SHA256SUMS ---"
+ cat SHA256SUMS
+
+ - name: Attest build provenance
+ # Produces a Sigstore-backed attestation linking each artifact to
+ # this exact workflow run. Verifiable with `gh attestation verify`.
+ uses: actions/attest-build-provenance@v2
+ with:
+ subject-path: |
+ assets/dists/*.whl
+ assets/dists/*.tar.gz
+ assets/msi/*.msi
+
- name: Extract release notes
run: |
python scripts/ci_release_helpers.py release-notes \
@@ -114,6 +138,7 @@ jobs:
assets/msi/*.msi
assets/pdfs/DataLab_fr.pdf
assets/pdfs/DataLab_en.pdf
+ assets/SHA256SUMS
# ---------------------------------------------------------------------------
# Build & deploy documentation (delegated to pages.yml). Non-blocking.
diff --git a/.vscode/tasks.json b/.vscode/tasks.json
index 687e6003a..5f53aa7ed 100644
--- a/.vscode/tasks.json
+++ b/.vscode/tasks.json
@@ -372,29 +372,6 @@
"sphinx-intl build",
],
},
- {
- "label": "đ ïž Generate doc assets",
- "command": "${command:python.interpreterPath} scripts/run_with_env.py ${command:python.interpreterPath} -m guidata.utils.genreqs all; if ($?) { ${command:python.interpreterPath} scripts/run_with_env.py ${command:python.interpreterPath} doc/update_validation_status.py }",
- "options": {
- "cwd": "${workspaceFolder}",
- "statusbar": {
- "hide": true,
- },
- },
- "group": {
- "kind": "build",
- "isDefault": false,
- },
- "presentation": {
- "clear": true,
- "echo": true,
- "focus": false,
- "panel": "dedicated",
- "reveal": "always",
- "showReuseMessage": true,
- },
- "type": "shell",
- },
{
"label": "đ§Ș Coverage tests",
"type": "shell",
@@ -571,6 +548,30 @@
"clear": true,
},
},
+ {
+ "label": "đ Refresh doc metadata",
+ "detail": "Regenerate requirements.txt + doc/requirements.rst (via guidata.utils.genreqs) and update Sigima validation status in the docs.",
+ "command": "${command:python.interpreterPath} scripts/run_with_env.py ${command:python.interpreterPath} -m guidata.utils.genreqs all; if ($?) { ${command:python.interpreterPath} scripts/run_with_env.py ${command:python.interpreterPath} doc/update_validation_status.py }",
+ "options": {
+ "cwd": "${workspaceFolder}",
+ "statusbar": {
+ "hide": true,
+ },
+ },
+ "group": {
+ "kind": "build",
+ "isDefault": false,
+ },
+ "presentation": {
+ "clear": true,
+ "echo": true,
+ "focus": false,
+ "panel": "dedicated",
+ "reveal": "always",
+ "showReuseMessage": true,
+ },
+ "type": "shell",
+ },
{
"label": "đŒïž Refresh doc screenshots",
"detail": "Maintainer task: regenerate PNG screenshots under doc/images/ by launching DataLab for each language (fr + en). Commit the resulting diff in a dedicated 'docs: refresh screenshots' commit.",
@@ -601,7 +602,7 @@
},
},
{
- "label": "Create executable",
+ "label": "đïž Create executable",
"type": "shell",
"command": "${command:python.interpreterPath}",
"args": [
@@ -636,7 +637,7 @@
},
},
{
- "label": "Create installer",
+ "label": "đŠ Create installer",
"type": "shell",
"command": "${command:python.interpreterPath}",
"args": [
@@ -670,7 +671,7 @@
},
},
{
- "label": "Build PDF doc",
+ "label": "đ Build PDF doc",
"type": "shell",
"command": "${command:python.interpreterPath}",
"options": {
@@ -706,7 +707,7 @@
},
"dependsOrder": "sequence",
"dependsOn": [
- "đ ïž Generate doc assets",
+ "đ Refresh doc metadata",
],
},
{
@@ -803,7 +804,7 @@
},
"dependsOrder": "sequence",
"dependsOn": [
- "đ ïž Generate doc assets",
+ "đ Refresh doc metadata",
],
},
{
@@ -919,8 +920,7 @@
},
"dependsOrder": "sequence",
"dependsOn": [
- "đ ïž Generate doc assets",
- "Build PDF doc",
+ "đ Build PDF doc",
],
},
{
@@ -958,8 +958,8 @@
"Upgrade Sigima/PlotPyStack",
"đ Compile translations",
"Build Python packages",
- "Create executable",
- "Create installer",
+ "đïž Create executable",
+ "đŠ Create installer",
],
},
{
diff --git a/datalab/__init__.py b/datalab/__init__.py
index b8a132d61..88986cb99 100644
--- a/datalab/__init__.py
+++ b/datalab/__init__.py
@@ -24,7 +24,7 @@
# this module is imported more than once, e.g. when running tests)
pass
-__version__ = "1.2.0"
+__version__ = "1.2.1"
__docurl__ = __homeurl__ = "https://datalab-platform.com/"
__supporturl__ = "https://github.com/DataLab-Platform/DataLab/issues/new/choose"
diff --git a/datalab/config.py b/datalab/config.py
index 976e9568b..ce2032208 100644
--- a/datalab/config.py
+++ b/datalab/config.py
@@ -67,7 +67,7 @@ def get_config_app_name() -> str:
APP_DESC = _("""DataLab is a generic signal and image processing platform""")
APP_PATH = osp.dirname(__file__)
-DEBUG = os.environ.get("DEBUG", "").lower() in ("1", "true")
+DEBUG = os.environ.get("DATALAB_DEBUG", "").lower() in ("1", "true")
if DEBUG:
print("*** DEBUG mode *** [Reset configuration file, do not redirect std I/O]")
diff --git a/datalab/control/baseproxy.py b/datalab/control/baseproxy.py
index 638c2144b..1fcc404fc 100644
--- a/datalab/control/baseproxy.py
+++ b/datalab/control/baseproxy.py
@@ -380,6 +380,14 @@ def get_sel_object_uuids(self, include_groups: bool = False) -> list[str]:
List of selected objects uuids.
"""
+ @abc.abstractmethod
+ def get_current_object_uuid(self) -> str | None:
+ """Return current object uuid in current panel.
+
+ Returns:
+ UUID of the current object, or None if no object is current.
+ """
+
@abc.abstractmethod
def select_objects(
self,
@@ -815,6 +823,14 @@ def get_sel_object_uuids(self, include_groups: bool = False) -> list[str]:
"""
return self._datalab.get_sel_object_uuids(include_groups)
+ def get_current_object_uuid(self) -> str | None:
+ """Return current object uuid in current panel.
+
+ Returns:
+ UUID of the current object, or None if no object is current.
+ """
+ return self._datalab.get_current_object_uuid()
+
def add_group(
self, title: str, panel: str | None = None, select: bool = False
) -> None:
diff --git a/datalab/control/remote.py b/datalab/control/remote.py
index 5d8ba1cf0..c58110741 100644
--- a/datalab/control/remote.py
+++ b/datalab/control/remote.py
@@ -483,6 +483,15 @@ def get_sel_object_uuids(self, include_groups: bool = False) -> list[str]:
"""
return self.win.get_sel_object_uuids(include_groups)
+ @remote_call
+ def get_current_object_uuid(self) -> str | None:
+ """Return current object uuid in current panel.
+
+ Returns:
+ UUID of the current object, or None if no object is current.
+ """
+ return self.win.get_current_object_uuid()
+
@remote_call
def add_group(
self, title: str, panel: str | None = None, select: bool = False
diff --git a/datalab/data/logo/DataLab-Banner-150.png b/datalab/data/logo/DataLab-Banner-150.png
index a8d09ee87..f47bc7cb6 100644
Binary files a/datalab/data/logo/DataLab-Banner-150.png and b/datalab/data/logo/DataLab-Banner-150.png differ
diff --git a/datalab/data/logo/DataLab-Splash.png b/datalab/data/logo/DataLab-Splash.png
index 08dd0c18e..3380f939e 100644
Binary files a/datalab/data/logo/DataLab-Splash.png and b/datalab/data/logo/DataLab-Splash.png differ
diff --git a/datalab/data/logo/DataLab-watermark.png b/datalab/data/logo/DataLab-watermark.png
index 57d5e8817..9b43ab549 100644
Binary files a/datalab/data/logo/DataLab-watermark.png and b/datalab/data/logo/DataLab-watermark.png differ
diff --git a/datalab/env.py b/datalab/env.py
index 3e2b5ac57..cc6c7735a 100644
--- a/datalab/env.py
+++ b/datalab/env.py
@@ -19,7 +19,7 @@
from guidata.env import ExecEnv as GuiDataExecEnv
# We could import DEBUG from datalab.config, but is it really worth it?
-DEBUG = os.environ.get("DEBUG", "").lower() in ("1", "true")
+DEBUG = os.environ.get("DATALAB_DEBUG", "").lower() in ("1", "true")
class VerbosityLevels(enum.Enum):
diff --git a/datalab/gui/actionhandler.py b/datalab/gui/actionhandler.py
index 59f16ef41..c36ea21dd 100644
--- a/datalab/gui/actionhandler.py
+++ b/datalab/gui/actionhandler.py
@@ -1320,6 +1320,7 @@ def cra_fit(title, fitdlgfunc, tip: str | None = None):
self.action_for("reverse_x")
self.action_for("replace_x_by_other_y")
self.action_for("xy_mode")
+ self.action_for("calibration", separator=True)
self.action_for("to_cartesian", separator=True)
self.action_for("to_polar")
with self.new_menu(_("Frequency filters"), icon_name="highpass.svg"):
diff --git a/datalab/gui/docks.py b/datalab/gui/docks.py
index 1c523ca28..7fcf20900 100644
--- a/datalab/gui/docks.py
+++ b/datalab/gui/docks.py
@@ -24,7 +24,6 @@
from typing import TYPE_CHECKING
import numpy as np
-import scipy.integrate as spt
from guidata.configtools import get_icon, get_image_file_path
from guidata.qthelpers import create_action, is_dark_theme
from guidata.widgets.dockable import DockableWidget
@@ -68,69 +67,29 @@ class CurveStatsToolFunctions:
"""Statistical functions for `CurveStatsTool` and `YRangeCursorTool`"""
@classmethod
- def set_labelfuncs(cls, statstool: CurveStatsTool) -> None:
+ def set_labelfuncs(cls, statstool: CurveStatsTool | YRangeCursorTool) -> None:
"""Set label functions for the statistics tool"""
if isinstance(statstool, CurveStatsTool):
- labelfuncs = (
- ("%g < x < %g", lambda *args: cls.nan_min_max(args[0])),
- ("%g < y < %g", lambda *args: cls.nan_min_max(args[1])),
- ("âx=%g", lambda *args: cls.nan_delta(args[0])),
- ("ây=%g", lambda *args: cls.nan_delta(args[1])),
- ("<y>=%g", lambda *args: cls.nan_mean(args[1])),
- ("Ï(y)=%g", lambda *args: cls.nan_std(args[1])),
- ("â(y)=%g", lambda *args: spt.trapezoid(args[1])),
- ("â«ydx=%g
", lambda *args: spt.trapezoid(args[1], args[0])),
- ("FWHM=%s", cls.fwhm_info),
- ("âxRISE 10-90=%s", cls.rise_time_info),
- (
- "âxRISE 20-80=%s",
- lambda x, y: cls.rise_time_info(x, y, 0.2, 0.8),
- ),
- ("âxFALL 90-10=%s", cls.fall_time_info),
- (
- "âxFALL 80-20=%s",
- lambda x, y: cls.fall_time_info(x, y, 0.8, 0.2),
- ),
+ labelfuncs = list(CurveStatsTool.LABELFUNCS)
+ labelfuncs[-1] = (labelfuncs[-1][0] + "
", labelfuncs[-1][1])
+ labelfuncs.extend(
+ [
+ ("FWHM=%s", cls.fwhm_info),
+ ("âxRISE 10-90=%s", cls.rise_time_info),
+ (
+ "âxRISE 20-80=%s",
+ lambda x, y: cls.rise_time_info(x, y, 0.2, 0.8),
+ ),
+ ("âxFALL 90-10=%s", cls.fall_time_info),
+ (
+ "âxFALL 80-20=%s",
+ lambda x, y: cls.fall_time_info(x, y, 0.8, 0.2),
+ ),
+ ]
)
- else: # YRangeCursorTool
- labelfuncs = (
- ("%g < y < %g", lambda ymin, ymax: (ymin, ymax)),
- ("ây=%g", lambda ymin, ymax: ymax - ymin),
- )
- statstool.set_labelfuncs(labelfuncs)
-
- @staticmethod
- def nan_min_max(arr: np.ndarray) -> tuple[float, float]:
- """Return min/max tuple"""
- with warnings.catch_warnings():
- warnings.simplefilter("ignore", RuntimeWarning)
- min_val = np.nanmin(arr)
- max_val = np.nanmax(arr)
- return (min_val, max_val)
-
- @staticmethod
- def nan_delta(arr: np.ndarray) -> float:
- """Return delta value, ignoring NaNs"""
- with warnings.catch_warnings():
- warnings.simplefilter("ignore", RuntimeWarning)
- delta_val = np.nanmax(arr) - np.nanmin(arr)
- return delta_val
-
- @staticmethod
- def nan_mean(arr: np.ndarray) -> float:
- """Return mean value, ignoring NaNs"""
- with warnings.catch_warnings():
- warnings.simplefilter("ignore", RuntimeWarning)
- mean_val = np.nanmean(arr)
- return mean_val
-
- @staticmethod
- def nan_std(arr: np.ndarray) -> float:
- """Return standard deviation, ignoring NaNs"""
- with warnings.catch_warnings():
- warnings.simplefilter("ignore", RuntimeWarning)
- std_val = np.nanstd(arr)
- return std_val
+ statstool.set_labelfuncs(tuple(labelfuncs))
+ else: # YRangeCursorTool - use PlotPy's defaults as-is
+ statstool.set_labelfuncs(YRangeCursorTool.LABELFUNCS)
@staticmethod
def fwhm_info(x, y):
diff --git a/datalab/gui/main.py b/datalab/gui/main.py
index fee7dd5eb..45937f7b8 100644
--- a/datalab/gui/main.py
+++ b/datalab/gui/main.py
@@ -57,6 +57,8 @@
APP_NAME,
DATAPATH,
DEBUG,
+ PLOTPY_CONF,
+ PLOTPY_DEFAULTS,
TEST_SEGFAULT_ERROR,
Conf,
_,
@@ -409,6 +411,16 @@ def get_sel_object_uuids(self, include_groups: bool = False) -> list[str]:
panel = self.__get_current_basedatapanel()
return panel.objview.get_sel_object_uuids(include_groups)
+ @remote_controlled
+ def get_current_object_uuid(self) -> str | None:
+ """Return current object uuid in current panel.
+
+ Returns:
+ UUID of the current object, or None if no object is current.
+ """
+ panel = self.__get_current_basedatapanel()
+ return panel.objview.get_current_object_uuid()
+
@remote_controlled
def add_group(
self,
@@ -2416,6 +2428,7 @@ def __update_color_mode(self, startup: bool = False) -> None:
self.setUpdatesEnabled(False)
plotpy_config.set_plotpy_color_mode(mode)
+ PLOTPY_CONF.update_defaults(PLOTPY_DEFAULTS)
if self.console is not None:
self.console.update_color_mode()
diff --git a/datalab/gui/objectview.py b/datalab/gui/objectview.py
index 1fd4891a5..0ead2133d 100644
--- a/datalab/gui/objectview.py
+++ b/datalab/gui/objectview.py
@@ -616,6 +616,11 @@ def get_current_object(self) -> SignalObj | ImageObj | None:
return self.objmodel[oid]
return None
+ def get_current_object_uuid(self) -> str | None:
+ """Return current object uuid, or None if current item is a group
+ or if no item is current"""
+ return self.get_current_item_id(object_only=True)
+
def set_current_object(self, obj: SignalObj | ImageObj) -> None:
"""Set current object"""
self.set_current_item_id(get_uuid(obj))
diff --git a/datalab/gui/panel/base.py b/datalab/gui/panel/base.py
index 60c95db76..9fde16514 100644
--- a/datalab/gui/panel/base.py
+++ b/datalab/gui/panel/base.py
@@ -2980,6 +2980,15 @@ def get_roi_editor_output(
source_panel=self,
size=self.get_dialog_size(),
)
+ # Propagate the source plot axis scales (e.g. log) to the ROI editor
+ # so that signals/images displayed with non-linear scales keep the same
+ # representation in the ROI editor dialog (see issue: ROI editor was
+ # always opening with default lin-lin scales).
+ src_plot = self.plothandler.plot
+ roi_editor.get_plot().set_scales(
+ src_plot.get_axis_scale("bottom"),
+ src_plot.get_axis_scale("left"),
+ )
if exec_dialog(roi_editor):
return roi_editor.get_roieditor_results()
return None
diff --git a/datalab/locale/fr/LC_MESSAGES/datalab.po b/datalab/locale/fr/LC_MESSAGES/datalab.po
index c590f1511..2b92ec46a 100644
--- a/datalab/locale/fr/LC_MESSAGES/datalab.po
+++ b/datalab/locale/fr/LC_MESSAGES/datalab.po
@@ -1054,7 +1054,7 @@ msgid "Parameters for function `%s`"
msgstr "ParamĂštres pour la fonction `%s`"
msgid "Created"
-msgstr "Création de"
+msgstr "Créé"
msgid "Original object"
msgstr "Objet original"
@@ -1205,12 +1205,12 @@ msgstr "Supprimer les métadonnées"
msgid "Some selected objects have regions of interest.
Do you want to delete them as well?"
msgstr "Certains objets sĂ©lectionnĂ©s ont des rĂ©gions d'intĂ©rĂȘt.
Souhaitez-vous les supprimer également ?"
-msgid "New group"
-msgstr "Nouveau groupe"
-
msgid "Group name:"
msgstr "Nom du groupe :"
+msgid "New group"
+msgstr "Nouveau groupe"
+
msgid "Rename object"
msgstr "Renommer l'objet"
@@ -2854,12 +2854,12 @@ msgstr "Cliquer sur OK pour terminer la démo."
msgid "Cancel"
msgstr "Annuler"
-msgid "Error:"
-msgstr "Erreur:"
-
msgid "Context"
msgstr "Contexte"
+msgid "Error:"
+msgstr "Erreur:"
+
#, python-format
msgid "The file %s could not be read:"
msgstr "Le fichier %s n'a pas pu ĂȘtre ouvert :"
@@ -3040,18 +3040,18 @@ msgstr "Déplier la sélection"
msgid "HDF5 Browser"
msgstr "Explorateur HDF5"
-msgid "Size"
-msgstr "Taille"
-
-msgid "Type"
-msgstr "Type"
-
msgid "Value"
msgstr "Valeur"
msgid "Name"
msgstr "Nom"
+msgid "Size"
+msgstr "Taille"
+
+msgid "Type"
+msgstr "Type"
+
msgid "Unsupported data"
msgstr "Données non prises en charge"
diff --git a/datalab/tests/features/common/geometry_results_app_test.py b/datalab/tests/features/common/geometry_results_app_test.py
index 9bd73d840..dc3cde07e 100644
--- a/datalab/tests/features/common/geometry_results_app_test.py
+++ b/datalab/tests/features/common/geometry_results_app_test.py
@@ -116,11 +116,20 @@ def test_geometry_results() -> None:
with Conf.proc.keep_results.temp(keep_results):
# Test merging result shapes (duplicate obj, then compute average):
for panel in (win.signalpanel, win.imagepanel):
- panel.objview.select_objects((2,))
+ src_obj = panel[2]
+ group_id = panel.objmodel.get_object_group_id(src_obj)
+ panel.objview.select_objects([src_obj])
panel.duplicate_object()
- panel.objview.select_objects((2, len(panel)))
+ # The duplicate is the last object of the source object's group
+ duplicate = panel.objmodel[
+ panel.objmodel.get_group_object_ids(group_id)[-1]
+ ]
+ panel.objview.select_objects([src_obj, duplicate])
panel.processor.run_feature("average")
- last_obj = panel[len(panel)]
+ # The average result is the last object of the source group
+ last_obj = panel.objmodel[
+ panel.objmodel.get_group_object_ids(group_id)[-1]
+ ]
if keep_results:
__check_geometry_results_merge(panel[2], last_obj)
if panel is win.imagepanel:
diff --git a/datalab/tests/features/control/remoteclient_unit.py b/datalab/tests/features/control/remoteclient_unit.py
index 352974ca5..c433c2772 100644
--- a/datalab/tests/features/control/remoteclient_unit.py
+++ b/datalab/tests/features/control/remoteclient_unit.py
@@ -36,6 +36,7 @@ def multiple_commands(remote: RemoteProxy):
area = rect.get_rect()
remote.add_annotations_from_items([rect])
uuid = remote.get_sel_object_uuids()[0]
+ assert remote.get_current_object_uuid() == uuid
items = remote.get_object_shapes()
assert len(items) == 1 and items[0].get_rect() == area
remote.add_label_with_title(f"Image uuid: {uuid}")
diff --git a/doc/_static/DataLab-Frontpage.png b/doc/_static/DataLab-Frontpage.png
index 0f924da98..4618caaf8 100644
Binary files a/doc/_static/DataLab-Frontpage.png and b/doc/_static/DataLab-Frontpage.png differ
diff --git a/doc/_static/DataLab-Title.png b/doc/_static/DataLab-Title.png
index 9ef669c2e..bbeeca4be 100644
Binary files a/doc/_static/DataLab-Title.png and b/doc/_static/DataLab-Title.png differ
diff --git a/doc/conf.py b/doc/conf.py
index 20acbfe40..27ea1f143 100644
--- a/doc/conf.py
+++ b/doc/conf.py
@@ -5,10 +5,18 @@
import os
import os.path as osp
import sys
+import warnings
import zipfile
import guidata.config as gcfg
+# Silence Sphinx 10 deprecation warning emitted from cairocffi (third-party,
+# used by sphinxcontrib-svg2pdfconverter during LaTeX builds).
+warnings.filterwarnings(
+ "ignore",
+ message=r".*Sphinx 10 will drop support for representing paths as strings.*",
+)
+
sys.path.insert(0, os.path.abspath(".."))
# Importing sigima to avoid re-enabling guidata validation mode
@@ -223,20 +231,136 @@ def exclude_api_from_gettext(app):
}
latex_elements = {
+ # Drop the cmap package: it is a pdflatex-only helper, emits a noisy
+ # "pdftex not detected" warning under xelatex, and the resulting PDF
+ # remains fully searchable thanks to fontspec/XeTeX.
+ "cmappkg": "",
# Use xelatex (set via ``latex_engine`` below): pdflatex chokes on the
# emoji / box-drawing / arrow glyphs sprinkled across the docs. The
# ``ucharclasses`` package automatically routes whole Unicode blocks
- # (emoji, dingbats, box-drawing, ...) to the Symbola fallback font
- # (Debian/Ubuntu package ``fonts-symbola``; MiKTeX fetches it on
- # demand on Windows).
+ # to the Noto fallback fonts (SIL OFL, fully redistributable):
+ # * Noto Sans Symbols 2 -- miscellaneous symbols, arrows, dingbats,
+ # box drawing, geometric shapes...
+ # * Noto Emoji -- monochrome emoji (XeLaTeX does not render the
+ # COLR/CPAL color tables of Noto Color Emoji reliably).
+ # Install:
+ # * Debian/Ubuntu: ``apt install fonts-noto-core fonts-noto-mono
+ # fonts-noto-extra`` (``fonts-noto-extra`` ships the monochrome
+ # ``NotoEmoji-Regular.ttf``; ``fonts-noto-color-emoji`` is *not*
+ # usable because XeTeX rejects CBDT/CBLC color-bitmap fonts).
+ # * Windows: MiKTeX fetches the ``noto`` and ``noto-emoji`` packages
+ # on demand (``xelatex -enable-installer ...``).
"preamble": r"""
\usepackage{amsmath}
\usepackage{amssymb}
\usepackage{mathrsfs}
\usepackage{fontspec}
- \newfontfamily\unicodefallback{Symbola}[Scale=MatchLowercase]
- \usepackage[Symbols]{ucharclasses}
- \setTransitionsForSymbols{\unicodefallback}{\normalfont}
+ % Three complementary Noto fallbacks -- a single one does NOT cover every
+ % Unicode sub-block we hit in the docs:
+ % * Noto Sans Symbols -- arrows, box drawing, geometric shapes,
+ % misc. symbols (info, check mark, sparkles, ...), dingbats.
+ % * Noto Sans Symbols 2 -- box drawing extensions, transport, misc
+ % technical (â±), and a number of pictographs (đ đ đ ...) the
+ % monochrome Noto Emoji does NOT include.
+ % * Noto Sans Mono -- box drawing characters (â..âż), which
+ % none of the Symbols fonts cover.
+ % * Noto Emoji (mono) -- emoji-presentation chars (â
âš â â âč).
+ % Noto Color Emoji is not used because XeTeX rejects CBDT/CBLC bitmap
+ % fonts. A few extended pictographs (đ§± đ§ đ§© đ§č) live ONLY in Noto
+ % Color Emoji and remain reported as missing -- acceptable cosmetic
+ % limitation.
+ \newfontfamily\symbolsfallback{NotoSansSymbols-Regular.ttf}[Scale=MatchLowercase]
+ \newfontfamily\symbolstwofallback{NotoSansSymbols2-Regular.ttf}[Scale=MatchLowercase]
+ \newfontfamily\monofallback{NotoSansMono-Regular.ttf}[Scale=MatchLowercase]
+ \newfontfamily\emojifallback{NotoEmoji-Regular.ttf}[Scale=MatchLowercase]
+ \usepackage[Latin,Arrows,LetterlikeSymbols,BoxDrawing,GeometricShapes,Dingbats,MiscellaneousSymbols,MiscellaneousSymbolsAndArrows,MiscellaneousTechnical,Emoticons,MiscellaneousSymbolsAndPictographs,SupplementalSymbolsAndPictographs,TransportAndMapSymbols,SymbolsAndPictographsExtendedA]{ucharclasses}
+ % Restore the *current* family (rm / sf / tt) instead of an unconditional
+ % \normalfont, which would break monospace rendering inside verbatim and
+ % inline code whenever a Unicode symbol appears nearby.
+ \makeatletter
+ \newcommand{\dlrestorefont}{%
+ \ifx\f@family\ttdefault\ttfamily\else
+ \ifx\f@family\sfdefault\sffamily\else
+ \normalfont\fi\fi}
+ \makeatother
+ % Force an explicit transition back to the surrounding family whenever we
+ % re-enter a Latin block. Without this, XeTeX keeps the last font set by
+ % a Symbols/Emoji transition for every following Latin character,
+ % producing thousands of "Missing character: There is no in font
+ % Noto Emoji" warnings and a broken PDF.
+ \setTransitionsForLatin{\dlrestorefont}{}
+ % Route blocks to the font that actually covers them. Coverage notes:
+ % * Box Drawing / Block Elements / Misc Technical live in Symbols 2.
+ % * â â
âš â (Misc Symbols / Dingbats with emoji presentation)
+ % are only in Noto Emoji.
+ \setTransitionsFor{Arrows}{\symbolsfallback}{\dlrestorefont}
+ \setTransitionsFor{LetterlikeSymbols}{\emojifallback}{\dlrestorefont}
+ \setTransitionsFor{BoxDrawing}{\monofallback}{\dlrestorefont}
+ \setTransitionsFor{GeometricShapes}{\symbolsfallback}{\dlrestorefont}
+ \setTransitionsFor{Dingbats}{\emojifallback}{\dlrestorefont}
+ \setTransitionsFor{MiscellaneousSymbols}{\emojifallback}{\dlrestorefont}
+ \setTransitionsFor{MiscellaneousSymbolsAndArrows}{\symbolstwofallback}{\dlrestorefont}
+ \setTransitionsFor{MiscellaneousTechnical}{\symbolstwofallback}{\dlrestorefont}
+ \setTransitionsFor{Emoticons}{\emojifallback}{\dlrestorefont}
+ \setTransitionsFor{MiscellaneousSymbolsAndPictographs}{\emojifallback}{\dlrestorefont}
+ \setTransitionsFor{SupplementalSymbolsAndPictographs}{\emojifallback}{\dlrestorefont}
+ \setTransitionsFor{TransportAndMapSymbols}{\emojifallback}{\dlrestorefont}
+ \setTransitionsFor{SymbolsAndPictographsExtendedA}{\emojifallback}{\dlrestorefont}
+ % Individual overrides for codepoints that are NOT in the block-routed
+ % font but exist in another installed Noto. The strategy is:
+ % 1. Reset the codepoint's XeTeX charclass to 0 so the broader block's
+ % \setTransitionsFor (which would switch to Noto Emoji and miss
+ % the glyph) no longer fires for it.
+ % 2. Use \newunicodechar to redefine the character as a macro that
+ % locally switches to Symbols 2 and emits the glyph via \char to
+ % avoid the infinite recursion that would occur if the macro body
+ % contained the active character itself.
+ % * â HEAVY ROUND-TIPPED RIGHTWARDS ARROW (Dingbats).
+ % * đ đ đ đŒ: pictographs missing from Noto Emoji but present
+ % in Symbols 2.
+ \XeTeXcharclass"279D=0
+ \XeTeXcharclass"1F6E0=0
+ \XeTeXcharclass"1F3D7=0
+ \XeTeXcharclass"1F5C3=0
+ \XeTeXcharclass"1F5BC=0
+ \usepackage{newunicodechar}
+ \newunicodechar{â}{{\symbolstwofallback\char"279D\relax}}
+ \newunicodechar{đ }{{\symbolstwofallback\char"1F6E0\relax}}
+ \newunicodechar{đ}{{\symbolstwofallback\char"1F3D7\relax}}
+ \newunicodechar{đ}{{\symbolstwofallback\char"1F5C3\relax}}
+ \newunicodechar{đŒ}{{\symbolstwofallback\char"1F5BC\relax}}
+ % Discard U+FE0F (VARIATION SELECTOR-16) at the input layer: it has no
+ % visible glyph, only requests the emoji presentation of the preceding
+ % codepoint. catcode 9 means "ignored character", so XeTeX drops it before
+ % font selection -- no more "Missing character" warnings for it.
+ \catcode"FE0F=9\relax
+ % Silence cosmetic xelatex/LaTeX warnings that are inherent to the
+ % current Sphinx 9 + XeTeX + Noto fallback setup and do not affect the
+ % visible PDF output. We deliberately keep real errors and undefined
+ % cross-references visible.
+ % * \tracinglostchars=0 mutes the XeTeX "Missing character" terminal
+ % messages for the handful of color-bitmap-only emoji (đ§±đ§©đ§ đ§č)
+ % that no monochrome Noto font ships.
+ % * \hbadness / \vbadness raise the threshold so the engine no longer
+ % reports Underfull \hbox/\vbox notices caused by long identifier
+ % names in narrow table columns and code-style paragraphs.
+ % * The silence filters drop predictable, harmless package messages.
+ \tracinglostchars=0
+ % Sphinx resets \hbadness/\vbadness at \begin{document}, so we re-apply
+ % the thresholds inside an \AtBeginDocument hook to silence Underfull
+ % \hbox/\vbox reports. Note: residual Overfull \hbox notices inside
+ % Sphinx tabulary/varwidth cells are not suppressible from here (Sphinx
+ % resets \hfuzz locally) and remain as informative typographic notices.
+ \AtBeginDocument{%
+ \hbadness=99999\relax
+ \vbadness=99999\relax
+ }
+ \usepackage{silence}
+ \WarningFilter{latexfont}{Font shape}
+ \WarningFilter{latexfont}{Some font shapes were not available}
+ \WarningFilter{cmap}{pdftex not detected}
+ \WarningFilter{longtable}{Table widths have changed}
+ \WarningFilter{rerunfilecheck}{File}
% Prevent orphan section headings at the bottom of a page: force a page
% break if there is not enough room for the heading plus a few lines of
% its following paragraph.
@@ -245,10 +369,25 @@ def exclude_api_from_gettext(app):
\pretocmd{\section}{\Needspace{12\baselineskip}}{}{}
\pretocmd{\subsection}{\Needspace{10\baselineskip}}{}{}
\pretocmd{\subsubsection}{\Needspace{8\baselineskip}}{}{}
+ % Sphinx 9 wraps every table cell content in \begin{varwidth}[t]{...}.
+ % Combined with our `m{}` column specs (e.g. intro/operating-modes and
+ % stakeholders tables), the [t] reference point makes short single-line
+ % cells sit at the row bottom instead of the visual centre. Forcing the
+ % varwidth alignment to [c] makes m{} truly centre the content; it is a
+ % no-op for p{}-style columns where Sphinx ignores the box reference.
+ \usepackage{varwidth}
+ \let\dlorigvarwidth\varwidth
+ \let\dlorigendvarwidth\endvarwidth
+ \renewenvironment{varwidth}[2][c]{\dlorigvarwidth[c]{#2}}{\dlorigendvarwidth}
"""
+ "\n".join(f"\\newcommand{{\\{cmd}}}{{{defn}}}" for cmd, defn in macros.items()),
}
latex_engine = "xelatex"
+# Sphinx 9 emits the Python Module Index with a \detokenize/\sphinxstyleindexpageref
+# pattern whose key does not match the corresponding \label definitions, producing
+# spurious "undefined reference" warnings on every entry. The HTML build keeps a
+# fully functional modindex; the PDF one is not worth its bogus warnings.
+latex_domain_indices = False
# -- MathJax configuration for HTML output -----------------------------------
mathjax3_config = {
diff --git a/doc/contributing/environment.md b/doc/contributing/environment.md
index 5793358b1..abb054cf7 100644
--- a/doc/contributing/environment.md
+++ b/doc/contributing/environment.md
@@ -95,7 +95,7 @@ Specific environment variables
Enable the "debug" mode (no stdin/stdout redirection towards internal console):
@REM Mode DEBUG
- set DEBUG=1
+ set DATALAB_DEBUG=1
Building PDF documentation requires LaTeX. On Windows, the following environment:
diff --git a/doc/images/DataLab-Overview.png b/doc/images/DataLab-Overview.png
index d4fd55a3f..5aabc7660 100644
Binary files a/doc/images/DataLab-Overview.png and b/doc/images/DataLab-Overview.png differ
diff --git a/doc/images/DataLab-Screenshot-Theme.png b/doc/images/DataLab-Screenshot-Theme.png
index 584496d36..a87613b31 100644
Binary files a/doc/images/DataLab-Screenshot-Theme.png and b/doc/images/DataLab-Screenshot-Theme.png differ
diff --git a/doc/images/DataLab-banner.png b/doc/images/DataLab-banner.png
index f86815c2d..081ed6e40 100644
Binary files a/doc/images/DataLab-banner.png and b/doc/images/DataLab-banner.png differ
diff --git a/doc/images/shots/s_app_at_startup.en.png b/doc/images/shots/s_app_at_startup.en.png
index 7c0f4139b..3c282ce31 100644
Binary files a/doc/images/shots/s_app_at_startup.en.png and b/doc/images/shots/s_app_at_startup.en.png differ
diff --git a/doc/images/shots/s_app_at_startup.fr.png b/doc/images/shots/s_app_at_startup.fr.png
index 2d70f4f9a..80ccbeec9 100644
Binary files a/doc/images/shots/s_app_at_startup.fr.png and b/doc/images/shots/s_app_at_startup.fr.png differ
diff --git a/doc/images/shots/windows_installer.png b/doc/images/shots/windows_installer.png
index 6218c0530..dc9ac9749 100644
Binary files a/doc/images/shots/windows_installer.png and b/doc/images/shots/windows_installer.png differ
diff --git a/doc/index.rst b/doc/index.rst
index 2f8cf679d..7af20b9e1 100644
--- a/doc/index.rst
+++ b/doc/index.rst
@@ -74,10 +74,9 @@ Go to :bdg-ref-success-line:`Installation ` to get started!
DataLab has been funded, chronologically, by the following stakeholders:
-.. tabularcolumns:: |>{\centering\arraybackslash}m{2cm}|m{\dimexpr\linewidth-2cm-4\tabcolsep\relax}|
+.. tabularcolumns:: |>{\centering\arraybackslash}m{1.2cm}|m{\dimexpr\linewidth-1.2cm-4\tabcolsep\relax}|
.. list-table::
:header-rows: 0
- :widths: 8 92
* - |cea_logo|
- `CEA `_, the French Alternative Energies and Atomic Energy Commission, is the major investor in DataLab, and is the main contributor to the project.
@@ -88,23 +87,40 @@ DataLab has been funded, chronologically, by the following stakeholders:
* - |nlnet_logo|
- `NLnet Foundation `_, as part of the NGI0 Commons Fund, backed by the European Commission, has funded the `redesign of DataLab's core architecture `_.
-.. |cea_logo| image:: images/logos/cea.svg
- :width: 64px
- :height: 64px
- :target: https://www.cea.fr
- :class: dark-light no-scaled-link
+.. Sphinx converts ``px`` to ``bp`` at 72 dpi for LaTeX, which makes ``64px``
+ render at ~22mm in the PDF -- way larger than in HTML. Define separate
+ substitutions per output: pixels for HTML, centimetres for LaTeX.
-.. |codra_logo| image:: images/logos/codra.svg
- :width: 64px
- :height: 64px
- :target: https://codra.net
- :class: dark-light no-scaled-link
+.. only:: html
-.. |nlnet_logo| image:: images/logos/nlnet.svg
- :width: 64px
- :height: 64px
- :target: https://nlnet.nl
- :class: dark-light no-scaled-link
+ .. |cea_logo| image:: images/logos/cea.svg
+ :width: 64px
+ :height: 64px
+ :target: https://www.cea.fr
+ :class: dark-light no-scaled-link
+
+ .. |codra_logo| image:: images/logos/codra.svg
+ :width: 64px
+ :height: 64px
+ :target: https://codra.net
+ :class: dark-light no-scaled-link
+
+ .. |nlnet_logo| image:: images/logos/nlnet.svg
+ :width: 64px
+ :height: 64px
+ :target: https://nlnet.nl
+ :class: dark-light no-scaled-link
+
+.. only:: latex
+
+ .. |cea_logo| image:: images/logos/cea.svg
+ :width: 1cm
+
+ .. |codra_logo| image:: images/logos/codra.svg
+ :width: 1cm
+
+ .. |nlnet_logo| image:: images/logos/nlnet.svg
+ :width: 1cm
.. figure:: _static/plotpy-stack-powered.png
:align: center
diff --git a/doc/intro/index.rst b/doc/intro/index.rst
index 53bcc96de..e58484acf 100644
--- a/doc/intro/index.rst
+++ b/doc/intro/index.rst
@@ -13,10 +13,9 @@ and image analysis tasks.
DataLab integrates seemlessly into your workflow thanks to three main operating modes:
-.. tabularcolumns:: |>{\centering\arraybackslash}m{2cm}|m{\dimexpr\linewidth-2cm-4\tabcolsep\relax}|
+.. tabularcolumns:: |>{\centering\arraybackslash}m{1.2cm}|m{\dimexpr\linewidth-1.2cm-4\tabcolsep\relax}|
.. list-table::
:header-rows: 0
- :widths: 8 92
* - |appmode|
- **Stand-alone application**, with a graphical user interface that allows you to interact with your data and visualize the results of your analysis in real time.
@@ -27,20 +26,37 @@ DataLab integrates seemlessly into your workflow thanks to three main operating
* - |remotemode|
- **Remotely controlled** from your own software, or from an IDE (e.g., Spyder) or a Jupyter notebook, using the DataLab API.
-.. |appmode| image:: ../../resources/DataLab-app.svg
- :width: 64px
- :height: 64px
- :class: dark-light no-scaled-link
+.. Sphinx converts ``px`` to ``bp`` at 72 dpi for LaTeX, which makes ``64px``
+ render at ~22mm in the PDF -- way larger than in HTML. Define separate
+ substitutions per output: pixels for HTML, centimetres for LaTeX.
-.. |libmode| image:: ../../resources/DataLab-lib.svg
- :width: 64px
- :height: 64px
- :class: dark-light no-scaled-link
+.. only:: html
-.. |remotemode| image:: ../../resources/DataLab-remote.svg
- :width: 64px
- :height: 64px
- :class: dark-light no-scaled-link
+ .. |appmode| image:: ../../resources/DataLab-app.svg
+ :width: 64px
+ :height: 64px
+ :class: dark-light no-scaled-link
+
+ .. |libmode| image:: ../../resources/DataLab-lib.svg
+ :width: 64px
+ :height: 64px
+ :class: dark-light no-scaled-link
+
+ .. |remotemode| image:: ../../resources/DataLab-remote.svg
+ :width: 64px
+ :height: 64px
+ :class: dark-light no-scaled-link
+
+.. only:: latex
+
+ .. |appmode| image:: ../../resources/DataLab-app.svg
+ :width: 1cm
+
+ .. |libmode| image:: ../../resources/DataLab-lib.svg
+ :width: 1cm
+
+ .. |remotemode| image:: ../../resources/DataLab-remote.svg
+ :width: 1cm
DataLab leverages the power of Python and its scientific ecosystem, through the use of
the following libraries:
diff --git a/doc/locale/fr/LC_MESSAGES/features/advanced/plugins.po b/doc/locale/fr/LC_MESSAGES/features/advanced/plugins.po
index a6ca0421f..bc2318b69 100644
--- a/doc/locale/fr/LC_MESSAGES/features/advanced/plugins.po
+++ b/doc/locale/fr/LC_MESSAGES/features/advanced/plugins.po
@@ -292,52 +292,50 @@ msgstr "Désenregistrer le plugin"
msgid "Unregister all plugins"
msgstr "Désenregistrer tous les plugins"
-#, fuzzy
msgid "Clear registered plugin classes."
-msgstr "Retourne les classes de plugins"
+msgstr "Effacer les classes de plugins enregistrées"
msgid "This is mainly useful when reloading plugin modules at runtime."
-msgstr ""
+msgstr "Ceci est principalement utile lors du rechargement des modules de plugins à l'exécution."
msgid "Record an error traceback that occurred during plugin discovery."
-msgstr ""
+msgstr "Enregistrer une trace d'erreur survenue lors de la découverte des plugins."
msgid "Parameters"
msgstr "ParamĂštres"
msgid "Formatted traceback string"
-msgstr ""
+msgstr "Chaßne de trace d'erreur formatée"
msgid "Return error tracebacks collected during plugin discovery."
-msgstr ""
+msgstr "Retourner les traces d'erreur collectées lors de la découverte des plugins."
msgid "Returns"
msgstr "Retourne"
msgid "List of formatted traceback strings (may be empty)"
-msgstr ""
+msgstr "Liste des chaĂźnes de trace d'erreur formatĂ©es (peut ĂȘtre vide)"
msgid "Clear recorded discovery errors."
-msgstr ""
+msgstr "Effacer les erreurs de découverte enregistrées."
msgid "Record a plugin that failed to load or instantiate."
-msgstr ""
+msgstr "Enregistrer un plugin qui n'a pas pu ĂȘtre chargĂ© ou instanciĂ©."
-#, fuzzy
msgid "Module or plugin class name"
-msgstr "Retourne les classes de plugins"
+msgstr "Nom du module ou de la classe du plugin"
msgid "File path of the plugin module"
msgstr ""
msgid "Return structured info about plugins that failed to load."
-msgstr ""
+msgstr "Renvoie des informations structurĂ©es sur les plugins qui n'ont pas pu ĂȘtre chargĂ©s."
msgid "List of FailedPluginInfo objects (may be empty)"
-msgstr ""
+msgstr "Liste des objets FailedPluginInfo (peut ĂȘtre vide)"
msgid "Clear recorded failed plugin info."
-msgstr ""
+msgstr "Effacer les informations sur les plugins ayant échoué."
msgid "Return plugin information (names, versions, descriptions) in html format"
msgstr "Retourne les informations sur les plugins (noms, versions, descriptions) au format html"
@@ -346,7 +344,7 @@ msgid "return html formatted text (default: True)"
msgstr "retourner du texte formaté en html (par défaut : True)"
msgid "Information about a plugin that failed to load or instantiate."
-msgstr ""
+msgstr "Informations sur un plugin qui n'a pas pu ĂȘtre chargĂ© ou instanciĂ©."
msgid "Plugin info"
msgstr "Informations sur le plugin"
@@ -428,30 +426,28 @@ msgstr "Découvrir les plugins en utilisant la convention de nommage"
#, python-brace-format
msgid "This function reloads or imports all modules matching the DataLab plugin naming scheme (``\"{MOD_NAME}_*\"``). Plugin classes are then registered automatically via the :class:`PluginRegistry` metaclass."
-msgstr ""
+msgstr "Cette fonction recharge ou importe tous les modules correspondant au schéma de nommage des plugins DataLab (``\"{MOD_NAME}_*\"``). Les classes de plugins sont ensuite enregistrées automatiquement via la métaclasse :class:`PluginRegistry`."
msgid "Import errors for individual plugins are captured and logged so that one broken plugin does not prevent the others from loading. Error tracebacks are accumulated in :class:`PluginRegistry` class attributes so that callers (e.g. the main window) can replay them into the internal console once it is ready."
-msgstr ""
+msgstr "Les erreurs d'importation pour les plugins individuels sont capturĂ©es et enregistrĂ©es afin qu'un plugin dĂ©fectueux n'empĂȘche pas les autres de se charger. Les traces d'erreurs sont accumulĂ©es dans les attributs de classe :class:`PluginRegistry` afin que les appelants (par exemple, la fenĂȘtre principale) puissent les rejouer dans la console interne une fois qu'elle est prĂȘte."
-#, fuzzy
msgid "List of imported/reloaded plugin modules"
-msgstr "Redécouvrir et recharger les modules de plugins,"
+msgstr "Liste des modules de plugins importés/rechargés"
msgid "Reload plugin modules and reset plugin classes."
-msgstr ""
+msgstr "Recharger les modules de plugins et réinitialiser les classes de plugins."
msgid "This helper is intended for hot-reloading plugins at runtime. It:"
-msgstr ""
+msgstr "Cet assistant est destiné au rechargement à chaud des plugins à l'exécution. Il :"
msgid "Updates the plugin search path"
-msgstr ""
+msgstr "Met Ă jour le chemin de recherche des plugins"
-#, fuzzy
msgid "Clears the plugin class registry"
-msgstr "Retourne les classes de plugins"
+msgstr "Efface le registre des classes de plugins"
msgid "Reloads or imports all modules matching the plugin naming convention"
-msgstr ""
+msgstr "Recharge ou importe tous les modules correspondant Ă la convention de nommage des plugins"
msgid "Discover v0.20 plugins (with ``cdl_`` prefix) without importing them"
msgstr "Découvrir les plugins v0.20 (avec le préfixe ``cdl_``) sans les importer"
diff --git a/doc/locale/fr/LC_MESSAGES/features/advanced/proxy.po b/doc/locale/fr/LC_MESSAGES/features/advanced/proxy.po
index beb8e1997..6279448b2 100644
--- a/doc/locale/fr/LC_MESSAGES/features/advanced/proxy.po
+++ b/doc/locale/fr/LC_MESSAGES/features/advanced/proxy.po
@@ -243,6 +243,12 @@ msgstr ""
msgid "Disconnect from DataLab XML-RPC server."
msgstr ""
+msgid "Return current object uuid in current panel."
+msgstr ""
+
+msgid "UUID of the current object, or None if no object is current."
+msgstr ""
+
msgid "Return current panel name."
msgstr ""
diff --git a/doc/locale/fr/LC_MESSAGES/features/advanced/remote.po b/doc/locale/fr/LC_MESSAGES/features/advanced/remote.po
index b11b11dec..e238365de 100644
--- a/doc/locale/fr/LC_MESSAGES/features/advanced/remote.po
+++ b/doc/locale/fr/LC_MESSAGES/features/advanced/remote.po
@@ -143,466 +143,460 @@ msgid "Here is a simple example of how to use RemoteClient in a Python script or
msgstr "Voici un exemple simple de l'utilisation de RemoteClient dans un script Python ou dans un notebook Jupyter :"
msgid "Set XML-RPC port to connect to."
-msgstr ""
+msgstr "Définir le port XML-RPC auquel se connecter."
msgid "Parameters"
msgstr "ParamĂštres"
msgid "XML-RPC port to connect to. If None, the port is automatically retrieved from DataLab configuration."
-msgstr ""
+msgstr "Port XML-RPC auquel se connecter. Si None, le port est automatiquement récupéré depuis la configuration de DataLab."
msgid "Try to connect to DataLab XML-RPC server."
-msgstr ""
+msgstr "Essayer de se connecter au serveur XML-RPC de DataLab."
msgid "XML-RPC port to connect to. If not specified, the port is automatically retrieved from DataLab configuration."
-msgstr ""
+msgstr "Port XML-RPC auquel se connecter. Si non spécifié, le port est automatiquement récupéré depuis la configuration de DataLab."
msgid "Maximum time to wait for connection in seconds. Defaults to 5.0. This is the total maximum wait time, not per retry."
-msgstr ""
+msgstr "Temps maximum d'attente de connexion en secondes. Par défaut 5.0. Il s'agit du temps d'attente maximum total, et non par tentative."
msgid "Number of retries. Defaults to 10. This parameter is deprecated and will be removed in a future version (kept for backward compatibility)."
-msgstr ""
+msgstr "Nombre de tentatives. Par défaut 10. Ce paramÚtre est déprécié et sera supprimé dans une version future (conservé pour la compatibilité ascendante)."
msgid "Raises"
-msgstr ""
+msgstr "LĂšve"
msgid "Unable to connect to DataLab"
-msgstr ""
+msgstr "Impossible de se connecter Ă DataLab"
msgid "Invalid timeout (must be >= 0.0)"
-msgstr ""
+msgstr "DĂ©lai d'attente invalide (doit ĂȘtre >= 0.0)"
msgid "Invalid number of retries (must be >= 1)"
-msgstr ""
+msgstr "Nombre de tentatives invalide (doit ĂȘtre >= 1)"
msgid "Disconnect from DataLab XML-RPC server."
-msgstr ""
+msgstr "Se déconnecter du serveur XML-RPC de DataLab."
msgid "Return True if connected to DataLab XML-RPC server."
-msgstr ""
+msgstr "Renvoie True si connecté au serveur XML-RPC de DataLab."
msgid "Return list of available methods."
-msgstr ""
+msgstr "Renvoie la liste des méthodes disponibles."
msgid "Add signal data to DataLab."
-msgstr ""
+msgstr "Ajouter des données de signal à DataLab."
msgid "Signal title"
-msgstr ""
+msgstr "Titre du signal"
msgid "X data"
-msgstr ""
+msgstr "Données X"
msgid "Y data"
-msgstr ""
+msgstr "Données Y"
msgid "X unit. Defaults to \"\""
-msgstr ""
+msgstr "Unité X. Par défaut \"\""
msgid "Y unit. Defaults to \"\""
-msgstr ""
+msgstr "Unité Y. Par défaut \"\""
msgid "X label. Defaults to \"\""
-msgstr ""
+msgstr "Libellé X. Par défaut \"\""
msgid "Y label. Defaults to \"\""
-msgstr ""
+msgstr "Libellé Y. Par défaut \"\""
msgid "group id in which to add the signal. Defaults to \"\""
-msgstr ""
+msgstr "Identifiant du groupe dans lequel ajouter le signal. Par défaut \"\""
msgid "if True, set the added signal as current"
-msgstr ""
+msgstr "si True, définit le signal ajouté comme courant"
msgid "Returns"
-msgstr ""
+msgstr "Renvoie"
msgid "True if signal was added successfully, False otherwise"
-msgstr ""
+msgstr "True si le signal a été ajouté avec succÚs, False sinon"
msgid "Invalid xdata dtype"
-msgstr ""
+msgstr "Type de données xdata invalide"
msgid "Invalid ydata dtype"
-msgstr ""
+msgstr "Type de données ydata invalide"
msgid "Add image data to DataLab."
-msgstr ""
+msgstr "Ajouter des données d'image à DataLab."
msgid "Image title"
-msgstr ""
+msgstr "Titre de l'image"
msgid "Image data"
-msgstr ""
+msgstr "Données de l'image"
msgid "Z unit. Defaults to \"\""
-msgstr ""
+msgstr "Unité Z. Par défaut \"\""
msgid "Z label. Defaults to \"\""
-msgstr ""
+msgstr "Libellé Z. Par défaut \"\""
msgid "group id in which to add the image. Defaults to \"\""
-msgstr ""
+msgstr "Identifiant du groupe dans lequel ajouter l'image. Par défaut \"\""
msgid "if True, set the added image as current"
-msgstr ""
+msgstr "si True, définit l'image ajoutée comme courante"
msgid "True if image was added successfully, False otherwise"
-msgstr ""
+msgstr "True si l'image a été ajoutée avec succÚs, False sinon"
msgid "Invalid data dtype"
-msgstr ""
+msgstr "Type de données invalide"
msgid "Add object to DataLab."
-msgstr ""
+msgstr "Ajouter un objet Ă DataLab."
-#, fuzzy
msgid "Signal or image object"
-msgstr "Basculer vers le panneau de signal ou d'image"
+msgstr "Objet signal ou image"
msgid "group id in which to add the object. Defaults to \"\""
-msgstr ""
+msgstr "Identifiant du groupe dans lequel ajouter l'objet. Par défaut \"\""
msgid "if True, set the added object as current"
-msgstr ""
+msgstr "si True, définit l'objet ajouté comme courant"
msgid "Set object data in DataLab."
-msgstr ""
+msgstr "Définir les données d'un objet dans DataLab."
msgid "Update an existing object in DataLab with new data from ``obj``. The object is identified by its UUID (which is carried by ``obj`` from a previous :meth:`get_object` call)."
-msgstr ""
+msgstr "Mettre à jour un objet existant dans DataLab avec les nouvelles données de ``obj``. L'objet est identifié par son UUID (qui est porté par ``obj`` depuis un appel précédent à :meth:`get_object`)."
msgid "Signal or image object (must have the same UUID as an existing object in DataLab)"
-msgstr ""
+msgstr "Objet signal ou image (doit avoir le mĂȘme UUID qu'un objet existant dans DataLab)"
msgid "if no object with matching UUID is found"
-msgstr ""
+msgstr "si aucun objet avec un UUID correspondant n'est trouvé"
msgid "Call computation feature ``name``"
-msgstr ""
+msgstr "Appeler la fonctionnalité de calcul ``name``"
msgid "This calls either the processor's ``compute_`` method (if it exists), or the processor's ```` computation feature (if it is registered, using the ``run_feature`` method). It looks for the function in all panels, starting with the current one."
-msgstr ""
+msgstr "Ceci appelle soit la méthode ``compute_`` du processeur (si elle existe), soit la fonctionnalité de calcul ```` du processeur (si elle est enregistrée, en utilisant la méthode ``run_feature``). La fonction est recherchée dans tous les panneaux, en commençant par le panneau courant."
msgid "Compute function name"
-msgstr ""
+msgstr "Nom de la fonction de calcul"
msgid "Compute function parameter. Defaults to None."
-msgstr ""
+msgstr "ParamÚtre de la fonction de calcul. Par défaut None."
msgid "unknown function"
-msgstr ""
+msgstr "fonction inconnue"
-#, fuzzy
msgid "Get object (signal/image) from index."
-msgstr "Ouvrir un signal ou une image Ă partir d'un fichier"
+msgstr "Obtenir un objet (signal/image) Ă partir de l'index."
msgid "Object number, or object id, or object title. Defaults to None (current object)."
-msgstr ""
+msgstr "Numéro de l'objet, identifiant de l'objet, ou titre de l'objet. Par défaut None (objet courant)."
msgid "Panel name. Defaults to None (current panel)."
-msgstr ""
+msgstr "Nom du panneau. Par défaut None (panneau courant)."
msgid "Object"
-msgstr ""
+msgstr "Objet"
msgid "if object not found"
-msgstr ""
+msgstr "si l'objet n'est pas trouvé"
msgid "Get plot item shapes associated to object (signal/image)."
-msgstr ""
+msgstr "Obtenir les formes des éléments graphiques associées à l'objet (signal/image)."
msgid "List of plot item shapes"
-msgstr ""
+msgstr "Liste des formes des éléments graphiques"
msgid "Add object annotations (annotation plot items)."
-msgstr ""
+msgstr "Ajouter des annotations à l'objet (éléments graphiques d'annotation)."
msgid "annotation plot items"
-msgstr ""
+msgstr "éléments graphiques d'annotation"
msgid "refresh plot. Defaults to True."
-msgstr ""
+msgstr "rafraßchir le graphique. Par défaut True."
msgid "panel name (valid values: \"signal\", \"image\"). If None, current panel is used."
-msgstr ""
+msgstr "nom du panneau (valeurs valides : \"signal\", \"image\"). Si None, le panneau courant est utilisé."
msgid "Call a public method on a panel or main window."
-msgstr ""
+msgstr "Appeler une mĂ©thode publique sur un panneau ou la fenĂȘtre principale."
msgid "Method resolution order when panel is None: 1. Try main window (DLMainWindow) 2. If not found, try current panel (BaseDataPanel)"
-msgstr ""
+msgstr "Ordre de rĂ©solution des mĂ©thodes quand panel est None : 1. Essayer la fenĂȘtre principale (DLMainWindow) 2. Si non trouvĂ©, essayer le panneau courant (BaseDataPanel)"
msgid "Name of the method to call"
-msgstr ""
+msgstr "Nom de la méthode à appeler"
msgid "Positional arguments to pass to the method"
-msgstr ""
+msgstr "Arguments positionnels à passer à la méthode"
msgid "Panel name (\"signal\", \"image\", or None for auto-detection). Defaults to None."
-msgstr ""
+msgstr "Nom du panneau (\"signal\", \"image\", ou None pour la détection automatique). Par défaut None."
msgid "Keyword arguments to pass to the method"
-msgstr ""
+msgstr "Arguments nommés à passer à la méthode"
msgid "The return value of the called method"
-msgstr ""
+msgstr "La valeur de retour de la méthode appelée"
msgid "If the method does not exist or is not public"
-msgstr ""
+msgstr "Si la méthode n'existe pas ou n'est pas publique"
msgid "If the panel name is invalid"
-msgstr ""
+msgstr "Si le nom du panneau est invalide"
msgid "Start the WebAPI server."
-msgstr ""
+msgstr "Démarrer le serveur WebAPI."
msgid "Host address to bind to. Defaults to \"127.0.0.1\"."
-msgstr ""
+msgstr "Adresse hÎte à laquelle se lier. Par défaut \"127.0.0.1\"."
msgid "Port number. Defaults to 8080."
-msgstr ""
+msgstr "Numéro de port. Par défaut 8080."
msgid "Dictionary with server info including 'url' and 'token'."
-msgstr ""
+msgstr "Dictionnaire avec les informations du serveur incluant 'url' et 'token'."
msgid "Stop the WebAPI server."
-msgstr ""
+msgstr "ArrĂȘter le serveur WebAPI."
msgid "True if server was stopped, False if it wasn't running."
-msgstr ""
+msgstr "True si le serveur a Ă©tĂ© arrĂȘtĂ©, False s'il n'Ă©tait pas en cours d'exĂ©cution."
msgid "Get the current status of the WebAPI server."
-msgstr ""
+msgstr "Obtenir l'état actuel du serveur WebAPI."
msgid "Dictionary with status info including 'running', 'url', and 'port'."
-msgstr ""
+msgstr "Dictionnaire avec les informations d'état incluant 'running', 'url' et 'port'."
msgid "Add group to DataLab."
-msgstr ""
+msgstr "Ajouter un groupe Ă DataLab."
msgid "Group title"
-msgstr ""
+msgstr "Titre du groupe"
msgid "Panel name (valid values: \"signal\", \"image\"). Defaults to None."
-msgstr ""
+msgstr "Nom du panneau (valeurs valides : \"signal\", \"image\"). Par défaut None."
msgid "Select the group after creation. Defaults to False."
-msgstr ""
+msgstr "Sélectionner le groupe aprÚs sa création. Par défaut False."
msgid "Add a label with object title on the associated plot"
-msgstr ""
+msgstr "Ajouter un libellé avec le titre de l'objet sur le graphique associé"
msgid "Label title. Defaults to None. If None, the title is the object title."
-msgstr ""
+msgstr "Titre du libellé. Par défaut None. Si None, le titre est le titre de l'objet."
-#, fuzzy
msgid "Close DataLab application"
-msgstr "Depuis une application tierce"
+msgstr "Fermer l'application DataLab"
msgid "Return a context manager to temporarily disable auto refresh."
-msgstr ""
+msgstr "Renvoie un gestionnaire de contexte pour désactiver temporairement le rafraßchissement automatique."
msgid "Context manager"
-msgstr ""
+msgstr "Gestionnaire de contexte"
-#, fuzzy
msgid "Example"
-msgstr "Exemples"
+msgstr "Exemple"
msgid "Delete metadata of selected objects"
-msgstr ""
+msgstr "Supprimer les métadonnées des objets sélectionnés"
msgid "Refresh plot. Defaults to True."
-msgstr ""
+msgstr "Rafraßchir le graphique. Par défaut True."
msgid "Keep ROI. Defaults to False."
-msgstr ""
+msgstr "Conserver les ROI. Par défaut False."
+
+msgid "Return current object uuid in current panel."
+msgstr "Renvoie l'UUID de l'objet courant dans le panneau courant."
+
+msgid "UUID of the current object, or None if no object is current."
+msgstr "UUID de l'objet courant, ou None si aucun objet n'est courant."
msgid "Return current panel name."
-msgstr ""
+msgstr "Renvoie le nom du panneau courant."
msgid "\"signal\", \"image\", \"macro\"))"
-msgstr ""
+msgstr "\"signal\", \"image\", \"macro\"))"
msgid "Return type"
-msgstr ""
+msgstr "Type de retour"
msgid "Return groups titles and lists of inner objects uuids and titles."
-msgstr ""
+msgstr "Renvoie les titres des groupes et les listes des UUID et titres des objets internes."
msgid "groups titles, lists of inner objects uuids and titles"
-msgstr ""
+msgstr "titres des groupes, listes des UUID et titres des objets internes"
msgid "Get object (signal/image) list for current panel. Objects are sorted by group number and object index in group."
-msgstr ""
+msgstr "Obtenir la liste des objets (signal/image) pour le panneau courant. Les objets sont triés par numéro de groupe et index de l'objet dans le groupe."
msgid "panel name (valid values: \"signal\", \"image\", \"macro\"). If None, current data panel is used (i.e. signal or image panel)."
-msgstr ""
+msgstr "nom du panneau (valeurs valides : \"signal\", \"image\", \"macro\"). Si None, le panneau de données courant est utilisé (c'est-à -dire le panneau signal ou image)."
-#, fuzzy
msgid "List of object titles"
-msgstr "Obtenir la liste des objets"
+msgstr "Liste des titres des objets"
msgid "if panel not found"
-msgstr ""
+msgstr "si le panneau n'est pas trouvé"
msgid "Get object (signal/image) uuid list for current panel. Objects are sorted by group number and object index in group."
-msgstr ""
+msgstr "Obtenir la liste des UUID des objets (signal/image) pour le panneau courant. Les objets sont triés par numéro de groupe et index de l'objet dans le groupe."
msgid "Group number, or group id, or group title. Defaults to None (all groups)."
-msgstr ""
+msgstr "Numéro du groupe, identifiant du groupe, ou titre du groupe. Par défaut None (tous les groupes)."
-#, fuzzy
msgid "List of object uuids"
-msgstr "Obtenir la liste des objets"
+msgstr "Liste des UUID des objets"
msgid "Return all public methods of the class, except itself."
-msgstr ""
+msgstr "Renvoie toutes les mĂ©thodes publiques de la classe, sauf elle-mĂȘme."
msgid "List of public methods"
-msgstr ""
+msgstr "Liste des méthodes publiques"
msgid "Return selected objects uuids."
-msgstr ""
+msgstr "Renvoie les UUID des objets sélectionnés."
msgid "If True, also return objects from selected groups."
-msgstr ""
+msgstr "Si True, renvoie également les objets des groupes sélectionnés."
msgid "List of selected objects uuids."
-msgstr ""
+msgstr "Liste des UUID des objets sélectionnés."
msgid "Return DataLab public version."
-msgstr ""
+msgstr "Renvoie la version publique de DataLab."
msgid "DataLab version"
-msgstr ""
+msgstr "Version de DataLab"
msgid "Open DataLab HDF5 browser to Import HDF5 file."
-msgstr ""
+msgstr "Ouvrir le navigateur HDF5 de DataLab pour importer un fichier HDF5."
-#, fuzzy
msgid "HDF5 file name"
-msgstr "Parcourir un fichier HDF5"
+msgstr "Nom du fichier HDF5"
msgid "Reset all application data. Defaults to None."
-msgstr ""
+msgstr "Réinitialiser toutes les données de l'application. Par défaut None."
msgid "Import macro from file"
-msgstr ""
+msgstr "Importer une macro depuis un fichier"
msgid "Filename."
-msgstr ""
+msgstr "Nom du fichier."
msgid "Open objects from directory in current panel (signals/images)."
-msgstr ""
+msgstr "Ouvrir des objets depuis un répertoire dans le panneau courant (signaux/images)."
msgid "directory path"
-msgstr ""
+msgstr "chemin du répertoire"
msgid "Open objects from files in current panel (signals/images)."
-msgstr ""
+msgstr "Ouvrir des objets depuis des fichiers dans le panneau courant (signaux/images)."
msgid "list of file names"
-msgstr ""
+msgstr "liste des noms de fichiers"
msgid "Load native DataLab HDF5 workspace files without any GUI elements."
-msgstr ""
+msgstr "Charger des fichiers d'espace de travail HDF5 natifs DataLab sans aucun élément d'interface graphique."
msgid "This method can be safely called from scripts (e.g., internal console, macros) as it does not create any Qt widgets, dialogs, or progress bars."
-msgstr ""
+msgstr "Cette mĂ©thode peut ĂȘtre appelĂ©e en toute sĂ©curitĂ© depuis des scripts (par exemple, console interne, macros) car elle ne crĂ©e aucun widget Qt, boĂźte de dialogue ou barre de progression."
msgid "This method only supports native DataLab HDF5 files. For importing arbitrary HDF5 files (non-native), use :meth:`open_h5_files` or :meth:`import_h5_file` instead."
-msgstr ""
+msgstr "Cette méthode ne prend en charge que les fichiers HDF5 natifs DataLab. Pour importer des fichiers HDF5 arbitraires (non natifs), utilisez plutÎt :meth:`open_h5_files` ou :meth:`import_h5_file`."
-#, fuzzy
msgid "List of native DataLab HDF5 filenames"
-msgstr "Enregistrer la session en cours dans un fichier HDF5"
+msgstr "Liste des noms de fichiers HDF5 natifs DataLab"
msgid "Reset all application data before importing. Defaults to False."
-msgstr ""
+msgstr "Réinitialiser toutes les données de l'application avant l'importation. Par défaut False."
msgid "If a file is not a valid native DataLab HDF5 file"
-msgstr ""
+msgstr "Si un fichier n'est pas un fichier HDF5 natif DataLab valide"
msgid "Open a DataLab HDF5 file or import from any other HDF5 file."
-msgstr ""
+msgstr "Ouvrir un fichier HDF5 DataLab ou importer depuis tout autre fichier HDF5."
msgid "List of HDF5 files to open. Defaults to None."
-msgstr ""
+msgstr "Liste des fichiers HDF5 à ouvrir. Par défaut None."
msgid "Import all objects from HDF5 files. Defaults to None."
-msgstr ""
+msgstr "Importer tous les objets depuis les fichiers HDF5. Par défaut None."
msgid "Raise DataLab window"
-msgstr ""
+msgstr "Mettre la fenĂȘtre DataLab au premier plan"
msgid "Remove current object from current panel."
-msgstr ""
+msgstr "Supprimer l'objet courant du panneau courant."
msgid "if True, remove object without confirmation. Defaults to False."
-msgstr ""
+msgstr "si True, supprimer l'objet sans confirmation. Par défaut False."
msgid "Reset all application data"
-msgstr ""
+msgstr "Réinitialiser toutes les données de l'application"
msgid "Run macro."
-msgstr ""
+msgstr "Exécuter une macro."
msgid "Macro number, or macro title. Defaults to None (current macro)."
-msgstr ""
+msgstr "Numéro de la macro, ou titre de la macro. Par défaut None (macro courante)."
msgid "if macro not found"
-msgstr ""
+msgstr "si la macro n'est pas trouvée"
msgid "Save current workspace to a native DataLab HDF5 file without GUI elements."
-msgstr ""
+msgstr "Enregistrer l'espace de travail courant dans un fichier HDF5 natif DataLab sans éléments d'interface graphique."
-#, fuzzy
msgid "HDF5 filename to save to"
-msgstr "Parcourir un fichier HDF5"
+msgstr "Nom du fichier HDF5 dans lequel enregistrer"
msgid "If file cannot be saved"
-msgstr ""
+msgstr "Si le fichier ne peut pas ĂȘtre enregistrĂ©"
-#, fuzzy
msgid "Save to a DataLab HDF5 file."
-msgstr "Enregistrer la session en cours dans un fichier HDF5"
+msgstr "Enregistrer dans un fichier HDF5 DataLab."
msgid "Select groups in current panel."
-msgstr ""
+msgstr "Sélectionner des groupes dans le panneau courant."
msgid "List of group numbers (1 to N), or list of group uuids, or None to select all groups. Defaults to None."
-msgstr ""
+msgstr "Liste des numéros de groupes (1 à N), ou liste des UUID de groupes, ou None pour sélectionner tous les groupes. Par défaut None."
msgid "panel name (valid values: \"signal\", \"image\"). If None, current panel is used. Defaults to None."
-msgstr ""
+msgstr "nom du panneau (valeurs valides : \"signal\", \"image\"). Si None, le panneau courant est utilisé. Par défaut None."
msgid "Select objects in current panel."
-msgstr ""
+msgstr "Sélectionner des objets dans le panneau courant."
msgid "List of object numbers (1 to N) or uuids to select"
-msgstr ""
+msgstr "Liste des numéros d'objets (1 à N) ou UUID à sélectionner"
-#, fuzzy
msgid "Switch to panel."
-msgstr "Basculer vers le panneau de signal ou d'image"
+msgstr "Basculer vers le panneau."
msgid "Panel name (valid values: \"signal\", \"image\", \"macro\"))"
-msgstr ""
+msgstr "Nom du panneau (valeurs valides : \"signal\", \"image\", \"macro\"))"
msgid "Stop macro."
-msgstr ""
+msgstr "ArrĂȘter la macro."
msgid "Toggle auto refresh state."
-msgstr ""
+msgstr "Basculer l'état du rafraßchissement automatique."
msgid "Auto refresh state"
-msgstr ""
+msgstr "Ătat du rafraĂźchissement automatique"
msgid "Toggle show titles state."
-msgstr ""
+msgstr "Basculer l'état d'affichage des titres."
msgid "Show titles state"
-msgstr ""
-
+msgstr "Ătat d'affichage des titres"
diff --git a/doc/locale/fr/LC_MESSAGES/features/validation/status.po b/doc/locale/fr/LC_MESSAGES/features/validation/status.po
index fa93b4b4d..e0a849268 100644
--- a/doc/locale/fr/LC_MESSAGES/features/validation/status.po
+++ b/doc/locale/fr/LC_MESSAGES/features/validation/status.po
@@ -126,7 +126,7 @@ msgstr ""
msgid "Compute absolute value with :py:data:`numpy.absolute`"
msgstr ""
-msgid "`test_signal_absolute `_"
+msgid "`test_signal_absolute `_"
msgstr ""
msgid ":py:func:`add_gaussian_noise `"
@@ -135,7 +135,7 @@ msgstr ""
msgid "Add normal noise to the input signal"
msgstr ""
-msgid "`test_signal_add_gaussian_noise `_"
+msgid "`test_signal_add_gaussian_noise `_"
msgstr ""
msgid ":py:func:`add_poisson_noise `"
@@ -144,7 +144,7 @@ msgstr ""
msgid "Add Poisson noise to the input signal"
msgstr ""
-msgid "`test_signal_add_poisson_noise `_"
+msgid "`test_signal_add_poisson_noise `_"
msgstr ""
msgid ":py:func:`add_uniform_noise `"
@@ -153,7 +153,7 @@ msgstr ""
msgid "Add uniform noise to the input signal"
msgstr ""
-msgid "`test_signal_add_uniform_noise `_"
+msgid "`test_signal_add_uniform_noise `_"
msgstr ""
msgid ":py:func:`addition `"
@@ -162,7 +162,7 @@ msgstr ""
msgid "Compute the element-wise sum of multiple signals"
msgstr ""
-msgid "`test_signal_addition `_"
+msgid "`test_signal_addition `_"
msgstr ""
msgid ":py:func:`addition_constant `"
@@ -171,7 +171,7 @@ msgstr ""
msgid "Compute the sum of a signal and a constant value"
msgstr ""
-msgid "`test_signal_addition_constant `_"
+msgid "`test_signal_addition_constant `_"
msgstr ""
msgid ":py:func:`allan_deviation `"
@@ -180,7 +180,7 @@ msgstr ""
msgid "Compute Allan deviation"
msgstr "Calculer la déviation d'Allan"
-msgid "`test_signal_allan_deviation `_"
+msgid "`test_signal_allan_deviation `_"
msgstr ""
msgid ":py:func:`allan_variance `"
@@ -189,7 +189,7 @@ msgstr ""
msgid "Compute Allan variance"
msgstr ""
-msgid "`test_signal_allan_variance `_"
+msgid "`test_signal_allan_variance `_"
msgstr ""
msgid ":py:func:`apply_window `"
@@ -198,7 +198,7 @@ msgstr ""
msgid "Compute windowing"
msgstr "Calculer la fenĂȘtrage"
-msgid "`test_signal_apply_window `_"
+msgid "`test_signal_apply_window `_"
msgstr ""
msgid ":py:func:`arithmetic `"
@@ -207,7 +207,7 @@ msgstr ""
msgid "Perform an arithmetic operation on two signals"
msgstr ""
-msgid "`test_signal_arithmetic `_"
+msgid "`test_signal_arithmetic `_"
msgstr ""
msgid ":py:func:`astype `"
@@ -216,7 +216,7 @@ msgstr ""
msgid "Convert data type"
msgstr ""
-msgid "`test_signal_astype `_"
+msgid "`test_signal_astype `_"
msgstr ""
msgid ":py:func:`average `"
@@ -225,7 +225,7 @@ msgstr ""
msgid "Compute the element-wise average of multiple signals"
msgstr ""
-msgid "`test_signal_average `_"
+msgid "`test_signal_average `_"
msgstr ""
msgid ":py:func:`bandpass `"
@@ -234,7 +234,7 @@ msgstr ""
msgid "Compute band-pass filter"
msgstr ""
-msgid "`test_signal_bandpass `_"
+msgid "`test_signal_bandpass `_"
msgstr ""
msgid ":py:func:`bandstop `"
@@ -243,7 +243,7 @@ msgstr ""
msgid "Compute band-stop filter"
msgstr ""
-msgid "`test_signal_bandstop `_"
+msgid "`test_signal_bandstop `_"
msgstr ""
msgid ":py:func:`bandwidth_3db `"
@@ -252,7 +252,7 @@ msgstr ""
msgid "Compute bandwidth at -3 dB"
msgstr ""
-msgid "`test_signal_bandwidth_3db `_"
+msgid "`test_signal_bandwidth_3db `_"
msgstr ""
msgid ":py:func:`calibration `"
@@ -261,7 +261,7 @@ msgstr ""
msgid "Compute linear calibration"
msgstr ""
-msgid "`test_signal_calibration `_"
+msgid "`test_signal_calibration `_"
msgstr ""
msgid ":py:func:`cdf_fit `"
@@ -270,7 +270,7 @@ msgstr ""
msgid "Compute CDF fit"
msgstr ""
-msgid "`test_signal_cdf_fit `_"
+msgid "`test_signal_cdf_fit `_"
msgstr ""
msgid ":py:func:`clip `"
@@ -279,7 +279,7 @@ msgstr ""
msgid "Compute maximum data clipping"
msgstr ""
-msgid "`test_signal_clip `_"
+msgid "`test_signal_clip `_"
msgstr ""
msgid ":py:func:`complex_from_magnitude_phase `"
@@ -288,7 +288,7 @@ msgstr ""
msgid "Combine magnitude and phase signals into a complex signal"
msgstr ""
-msgid "`test_signal_complex_from_magnitude_phase `_"
+msgid "`test_signal_complex_from_magnitude_phase `_"
msgstr ""
msgid ":py:func:`complex_from_real_imag `"
@@ -297,7 +297,7 @@ msgstr ""
msgid "Combine two real signals into a complex signal using real + i * imag"
msgstr ""
-msgid "`test_signal_complex_from_real_imag `_"
+msgid "`test_signal_complex_from_real_imag `_"
msgstr ""
msgid ":py:func:`contrast `"
@@ -306,7 +306,7 @@ msgstr ""
msgid "Compute contrast"
msgstr "Calculer le contraste"
-msgid "`test_signal_contrast `_"
+msgid "`test_signal_contrast `_"
msgstr ""
msgid ":py:func:`convolution `"
@@ -315,7 +315,7 @@ msgstr ""
msgid "Compute convolution of two signals"
msgstr ""
-msgid "`test_signal_convolution `_"
+msgid "`test_signal_convolution `_"
msgstr ""
msgid ":py:func:`deconvolution `"
@@ -324,7 +324,7 @@ msgstr ""
msgid "Compute deconvolution"
msgstr "Calculer la déconvolution"
-msgid "`test_signal_deconvolution `_"
+msgid "`test_signal_deconvolution `_"
msgstr ""
msgid ":py:func:`derivative `"
@@ -333,7 +333,7 @@ msgstr ""
msgid "Compute derivative"
msgstr "Calculer la dérivée"
-msgid "`test_signal_derivative `_"
+msgid "`test_signal_derivative `_"
msgstr ""
msgid ":py:func:`detrending `"
@@ -342,7 +342,7 @@ msgstr ""
msgid "Detrend data"
msgstr ""
-msgid "`test_signal_detrending `_"
+msgid "`test_signal_detrending `_"
msgstr ""
msgid ":py:func:`difference `"
@@ -351,7 +351,7 @@ msgstr ""
msgid "Compute the element-wise difference between two signals"
msgstr ""
-msgid "`test_signal_difference `_"
+msgid "`test_signal_difference `_"
msgstr ""
msgid ":py:func:`difference_constant `"
@@ -360,7 +360,7 @@ msgstr ""
msgid "Compute the difference between a signal and a constant value"
msgstr ""
-msgid "`test_signal_difference_constant `_"
+msgid "`test_signal_difference_constant `_"
msgstr ""
msgid ":py:func:`division `"
@@ -369,7 +369,7 @@ msgstr ""
msgid "Compute the element-wise division between two signals"
msgstr ""
-msgid "`test_signal_division `_"
+msgid "`test_signal_division `_"
msgstr ""
msgid ":py:func:`division_constant `"
@@ -378,7 +378,7 @@ msgstr ""
msgid "Compute the division of a signal by a constant value"
msgstr ""
-msgid "`test_signal_division_constant `_"
+msgid "`test_signal_division_constant `_"
msgstr ""
msgid ":py:func:`dynamic_parameters `"
@@ -387,7 +387,7 @@ msgstr ""
msgid "Compute Dynamic parameters"
msgstr ""
-msgid "`test_dynamic_parameters `_"
+msgid "`test_dynamic_parameters `_"
msgstr ""
msgid ":py:func:`evaluate_fit `"
@@ -396,7 +396,7 @@ msgstr ""
msgid "Evaluate fit function from src1 on the x-axis of src2"
msgstr ""
-msgid "`test_signal_evaluate_fit `_"
+msgid "`test_signal_evaluate_fit `_"
msgstr ""
msgid ":py:func:`exp `"
@@ -405,7 +405,7 @@ msgstr ""
msgid "Compute exponential with :py:data:`numpy.exp`"
msgstr ""
-msgid "`test_signal_exp `_"
+msgid "`test_signal_exp `_"
msgstr ""
msgid ":py:func:`exponential_fit `"
@@ -414,7 +414,7 @@ msgstr ""
msgid "Compute exponential fit"
msgstr "Calculer l'ajustement exponentiel"
-msgid "`test_signal_exponential_fit `_"
+msgid "`test_signal_exponential_fit `_"
msgstr ""
msgid ":py:func:`extract_pulse_features `"
@@ -423,7 +423,7 @@ msgstr ""
msgid "Extract pulse features"
msgstr ""
-msgid "`test_signal_extract_pulse_features `_"
+msgid "`test_signal_extract_pulse_features `_"
msgstr ""
msgid ":py:func:`extract_roi `"
@@ -432,7 +432,7 @@ msgstr ""
msgid "Extract single region of interest from data"
msgstr ""
-msgid "`test_signal_extract_roi `_"
+msgid "`test_signal_extract_roi `_"
msgstr ""
msgid ":py:func:`extract_rois `"
@@ -441,7 +441,7 @@ msgstr ""
msgid "Extract multiple regions of interest from data"
msgstr ""
-msgid "`test_signal_extract_rois `_"
+msgid "`test_signal_extract_rois `_"
msgstr ""
msgid ":py:func:`fft `"
@@ -450,13 +450,13 @@ msgstr ""
msgid "Compute FFT"
msgstr "Calculer la FFT"
-msgid "`test_signal_fft `_"
+msgid "`test_signal_fft `_"
msgstr ""
msgid ":py:func:`full_width_at_y `"
msgstr ""
-msgid "`test_signal_full_width_at_y `_"
+msgid "`test_signal_full_width_at_y `_"
msgstr ""
msgid ":py:func:`fw1e2 `"
@@ -465,7 +465,7 @@ msgstr ""
msgid "Compute FW at 1/eÂČ"
msgstr ""
-msgid "`test_signal_fw1e2 `_"
+msgid "`test_signal_fw1e2 `_"
msgstr ""
msgid ":py:func:`fwhm `"
@@ -474,7 +474,7 @@ msgstr ""
msgid "Compute FWHM"
msgstr "Fonctions de calcul"
-msgid "`test_signal_fwhm `_"
+msgid "`test_signal_fwhm `_"
msgstr ""
msgid ":py:func:`gaussian_filter `"
@@ -483,7 +483,7 @@ msgstr ""
msgid "Compute gaussian filter"
msgstr ""
-msgid "`test_signal_gaussian_filter `_"
+msgid "`test_signal_gaussian_filter `_"
msgstr ""
msgid ":py:func:`gaussian_fit `"
@@ -492,7 +492,7 @@ msgstr ""
msgid "Compute Gaussian fit"
msgstr "Calculer la déviation d'Allan"
-msgid "`test_signal_gaussian_fit `_"
+msgid "`test_signal_gaussian_fit `_"
msgstr ""
msgid ":py:func:`hadamard_variance `"
@@ -501,7 +501,7 @@ msgstr ""
msgid "Compute Hadamard variance"
msgstr ""
-msgid "`test_signal_hadamard_variance `_"
+msgid "`test_signal_hadamard_variance `_"
msgstr ""
msgid ":py:func:`highpass `"
@@ -510,7 +510,7 @@ msgstr ""
msgid "Compute high-pass filter"
msgstr ""
-msgid "`test_signal_highpass `_"
+msgid "`test_signal_highpass `_"
msgstr ""
msgid ":py:func:`histogram `"
@@ -519,7 +519,7 @@ msgstr ""
msgid "Compute histogram"
msgstr "Calculer l'histogramme"
-msgid "`test_signal_histogram `_"
+msgid "`test_signal_histogram `_"
msgstr ""
msgid ":py:func:`ifft `"
@@ -528,7 +528,7 @@ msgstr ""
msgid "Compute the inverse FFT"
msgstr ""
-msgid "`test_signal_ifft `_"
+msgid "`test_signal_ifft `_"
msgstr ""
msgid ":py:func:`imag `"
@@ -537,7 +537,7 @@ msgstr ""
msgid "Compute imaginary part"
msgstr ""
-msgid "`test_signal_imag `_"
+msgid "`test_signal_imag `_"
msgstr ""
msgid ":py:func:`integral `"
@@ -546,7 +546,7 @@ msgstr ""
msgid "Compute integral"
msgstr "Calculer l'intégrale"
-msgid "`test_signal_integral `_"
+msgid "`test_signal_integral `_"
msgstr ""
msgid ":py:func:`interpolate `"
@@ -555,7 +555,7 @@ msgstr ""
msgid "Interpolate data"
msgstr ""
-msgid "`test_signal_interpolate `_"
+msgid "`test_signal_interpolate `_"
msgstr ""
msgid ":py:func:`inverse `"
@@ -564,7 +564,7 @@ msgstr ""
msgid "Compute the element-wise inverse of a signal"
msgstr ""
-msgid "`test_signal_inverse `_"
+msgid "`test_signal_inverse `_"
msgstr ""
msgid ":py:func:`linear_fit `"
@@ -573,7 +573,7 @@ msgstr ""
msgid "Compute linear fit"
msgstr "Calculer l'ajustement linéaire"
-msgid "`test_signal_linear_fit `_"
+msgid "`test_signal_linear_fit `_"
msgstr ""
msgid ":py:func:`log10 `"
@@ -582,7 +582,7 @@ msgstr ""
msgid "Compute Log10 with :py:data:`numpy.log10`"
msgstr ""
-msgid "`test_signal_log10 `_"
+msgid "`test_signal_log10 `_"
msgstr ""
msgid ":py:func:`lorentzian_fit `"
@@ -591,7 +591,7 @@ msgstr ""
msgid "Compute Lorentzian fit"
msgstr "Calculer l'ajustement lorentzien"
-msgid "`test_signal_lorentzian_fit `_"
+msgid "`test_signal_lorentzian_fit `_"
msgstr ""
msgid ":py:func:`lowpass `"
@@ -600,7 +600,7 @@ msgstr ""
msgid "Compute low-pass filter"
msgstr ""
-msgid "`test_signal_lowpass `_"
+msgid "`test_signal_lowpass `_"
msgstr ""
msgid ":py:func:`magnitude_spectrum `"
@@ -609,7 +609,7 @@ msgstr ""
msgid "Compute magnitude spectrum"
msgstr ""
-msgid "`test_signal_magnitude_spectrum `_"
+msgid "`test_signal_magnitude_spectrum `_"
msgstr ""
msgid ":py:func:`modified_allan_variance `"
@@ -618,7 +618,7 @@ msgstr ""
msgid "Compute Modified Allan variance"
msgstr ""
-msgid "`test_signal_modified_allan_variance `_"
+msgid "`test_signal_modified_allan_variance `_"
msgstr ""
msgid ":py:func:`moving_average `"
@@ -627,7 +627,7 @@ msgstr ""
msgid "Compute moving average"
msgstr ""
-msgid "`test_signal_moving_average `_"
+msgid "`test_signal_moving_average `_"
msgstr ""
msgid ":py:func:`moving_median `"
@@ -636,7 +636,7 @@ msgstr ""
msgid "Compute moving median"
msgstr ""
-msgid "`test_signal_moving_median `_"
+msgid "`test_signal_moving_median `_"
msgstr ""
msgid ":py:func:`normalize `"
@@ -645,7 +645,7 @@ msgstr ""
msgid "Normalize data"
msgstr ""
-msgid "`test_signal_normalize `_"
+msgid "`test_signal_normalize `_"
msgstr ""
msgid ":py:func:`offset_correction `"
@@ -654,7 +654,7 @@ msgstr ""
msgid "Correct offset: subtract the mean value of the signal in the specified range"
msgstr ""
-msgid "`test_signal_offset_correction `_"
+msgid "`test_signal_offset_correction `_"
msgstr ""
msgid ":py:func:`overlapping_allan_variance `"
@@ -663,7 +663,7 @@ msgstr ""
msgid "Compute Overlapping Allan variance"
msgstr ""
-msgid "`test_signal_overlapping_allan_variance `_"
+msgid "`test_signal_overlapping_allan_variance `_"
msgstr ""
msgid ":py:func:`peak_detection `"
@@ -672,7 +672,7 @@ msgstr ""
msgid "Peak detection"
msgstr ""
-msgid "`test_signal_peak_detection `_"
+msgid "`test_signal_peak_detection `_"
msgstr ""
msgid ":py:func:`phase `"
@@ -681,7 +681,7 @@ msgstr ""
msgid "Compute the phase (argument) of a complex signal"
msgstr ""
-msgid "`test_signal_phase `_"
+msgid "`test_signal_phase `_"
msgstr ""
msgid ":py:func:`phase_spectrum `"
@@ -690,7 +690,7 @@ msgstr ""
msgid "Compute phase spectrum"
msgstr ""
-msgid "`test_signal_phase_spectrum `_"
+msgid "`test_signal_phase_spectrum `_"
msgstr ""
msgid ":py:func:`piecewiseexponential_fit `"
@@ -699,7 +699,7 @@ msgstr ""
msgid "Compute piecewise exponential fit (raise-decay)"
msgstr "Calculer l'ajustement exponentiel par morceaux (augmentation-décroissance)"
-msgid "`test_signal_piecewiseexponential_fit `_"
+msgid "`test_signal_piecewiseexponential_fit `_"
msgstr ""
msgid ":py:func:`planckian_fit `"
@@ -708,7 +708,7 @@ msgstr ""
msgid "Compute Planckian fit"
msgstr "Calculer l'ajustement de Planck"
-msgid "`test_signal_planckian_fit `_"
+msgid "`test_signal_planckian_fit `_"
msgstr ""
msgid ":py:func:`polynomial_fit `"
@@ -717,7 +717,7 @@ msgstr ""
msgid "Compute polynomial fit"
msgstr "Calculer l'ajustement polynomial"
-msgid "`test_polynomial_fit `_"
+msgid "`test_polynomial_fit `_"
msgstr ""
msgid ":py:func:`power `"
@@ -726,7 +726,7 @@ msgstr ""
msgid "Compute power with :py:data:`numpy.power`"
msgstr ""
-msgid "`test_signal_power `_"
+msgid "`test_signal_power `_"
msgstr ""
msgid ":py:func:`product `"
@@ -735,7 +735,7 @@ msgstr ""
msgid "Compute the element-wise product of multiple signals"
msgstr ""
-msgid "`test_signal_product `_"
+msgid "`test_signal_product `_"
msgstr ""
msgid ":py:func:`product_constant `"
@@ -744,7 +744,7 @@ msgstr ""
msgid "Compute the product of a signal and a constant value"
msgstr ""
-msgid "`test_signal_product_constant `_"
+msgid "`test_signal_product_constant `_"
msgstr ""
msgid ":py:func:`psd `"
@@ -753,7 +753,7 @@ msgstr ""
msgid "Compute power spectral density"
msgstr ""
-msgid "`test_signal_psd `_"
+msgid "`test_signal_psd `_"
msgstr ""
msgid ":py:func:`quadratic_difference `"
@@ -762,7 +762,7 @@ msgstr ""
msgid "Compute the normalized difference between two signals"
msgstr ""
-msgid "`test_signal_quadratic_difference `_"
+msgid "`test_signal_quadratic_difference `_"
msgstr ""
msgid ":py:func:`real `"
@@ -771,7 +771,7 @@ msgstr ""
msgid "Compute real part"
msgstr "Calculer la partie réelle"
-msgid "`test_signal_real `_"
+msgid "`test_signal_real `_"
msgstr ""
msgid ":py:func:`replace_x_by_other_y `"
@@ -780,7 +780,7 @@ msgstr ""
msgid "Create a new signal using Y from src1 and Y from src2 as X coordinates"
msgstr ""
-msgid "`test_replace_x_by_other_y `_"
+msgid "`test_replace_x_by_other_y `_"
msgstr ""
msgid ":py:func:`resampling `"
@@ -789,7 +789,7 @@ msgstr ""
msgid "Resample data"
msgstr ""
-msgid "`test_signal_resampling `_"
+msgid "`test_signal_resampling `_"
msgstr ""
msgid ":py:func:`reverse_x `"
@@ -798,7 +798,7 @@ msgstr ""
msgid "Reverse x-axis"
msgstr ""
-msgid "`test_signal_reverse_x `_"
+msgid "`test_signal_reverse_x `_"
msgstr ""
msgid ":py:func:`sampling_rate_period `"
@@ -807,7 +807,7 @@ msgstr ""
msgid "Compute sampling rate and period"
msgstr ""
-msgid "`test_signal_sampling_rate_period `_"
+msgid "`test_signal_sampling_rate_period `_"
msgstr ""
msgid ":py:func:`sigmoid_fit `"
@@ -816,7 +816,7 @@ msgstr ""
msgid "Compute sigmoid fit"
msgstr "Calculer l'ajustement sigmoĂŻde"
-msgid "`test_signal_sigmoid_fit `_"
+msgid "`test_signal_sigmoid_fit `_"
msgstr ""
msgid ":py:func:`signals_to_image `"
@@ -825,7 +825,7 @@ msgstr ""
msgid "Combine multiple signals into an image"
msgstr ""
-msgid "`test_signal_signals_to_image `_"
+msgid "`test_signal_signals_to_image `_"
msgstr ""
msgid ":py:func:`sinusoidal_fit `"
@@ -834,7 +834,7 @@ msgstr ""
msgid "Compute sinusoidal fit"
msgstr "Calculer l'ajustement sinusoĂŻdal"
-msgid "`test_sinusoidal_fit `_"
+msgid "`test_sinusoidal_fit `_"
msgstr ""
msgid ":py:func:`sqrt `"
@@ -843,7 +843,7 @@ msgstr ""
msgid "Compute square root with :py:data:`numpy.sqrt`"
msgstr ""
-msgid "`test_signal_sqrt `_"
+msgid "`test_signal_sqrt `_"
msgstr ""
msgid ":py:func:`standard_deviation `"
@@ -852,7 +852,7 @@ msgstr ""
msgid "Compute the element-wise standard deviation of multiple signals"
msgstr ""
-msgid "`test_signal_standard_deviation `_"
+msgid "`test_signal_standard_deviation `_"
msgstr ""
msgid ":py:func:`stats `"
@@ -861,7 +861,7 @@ msgstr ""
msgid "Compute statistics on a signal"
msgstr ""
-msgid "`test_signal_stats_unit