From 020cd6056c30105a870cfea99939282b6ec5640b Mon Sep 17 00:00:00 2001 From: Thiago Franco de Moraes Date: Mon, 5 Aug 2024 10:41:11 -0300 Subject: [PATCH 01/10] Removed eval from dicom.py (#820) --- invesalius/reader/dicom.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/invesalius/reader/dicom.py b/invesalius/reader/dicom.py index 3d327aa48..87225ba88 100644 --- a/invesalius/reader/dicom.py +++ b/invesalius/reader/dicom.py @@ -442,7 +442,7 @@ def GetImagePosition(self): except KeyError: return "" if data: - return [eval(value) for value in data.split("\\")] + return [float(value) for value in data.split("\\")] return "" def GetImageLocation(self): @@ -455,7 +455,7 @@ def GetImageLocation(self): """ data = self.data_image[str(0x020)][str(0x1041)] if data: - return eval(data) + return float(data) return "" def GetImageOffset(self): From 868fcf4132c0719e75c1618d71029de3dfdb3ab9 Mon Sep 17 00:00:00 2001 From: Hafsa-shoaib989 Date: Fri, 9 Aug 2024 12:02:15 +0500 Subject: [PATCH 02/10] Always link to new documentation --- invesalius/gui/frame.py | 10 +--------- 1 file changed, 1 insertion(+), 9 deletions(-) diff --git a/invesalius/gui/frame.py b/invesalius/gui/frame.py index 1a3cfbe13..39ed05bd3 100644 --- a/invesalius/gui/frame.py +++ b/invesalius/gui/frame.py @@ -790,15 +790,7 @@ def ShowGettingStarted(self): """ Show getting started window. """ - session = ses.Session() - if session.GetConfig("language") == "pt_BR": - user_guide = "user_guide_pt_BR.pdf" - path = os.path.join(inv_paths.DOC_DIR, user_guide) - if sys.platform == "darwin": - path = r"file://" + path - webbrowser.open(path) - else: - user_guide = webbrowser.open("https://invesalius.github.io/docs/user_guide/user_guide.html") + webbrowser.open("https://invesalius.github.io/docs/user_guide/user_guide.html") def ShowImportDicomPanel(self): """ From 740843f09d74cff7069e1fef2f649cf146c40c23 Mon Sep 17 00:00:00 2001 From: Hafsa Shoaib <112469577+Hafsa-shoaib989@users.noreply.github.com> Date: Mon, 12 Aug 2024 19:08:37 +0500 Subject: [PATCH 03/10] Always link to new documentation (#823) --- invesalius/gui/frame.py | 10 +--------- 1 file changed, 1 insertion(+), 9 deletions(-) diff --git a/invesalius/gui/frame.py b/invesalius/gui/frame.py index 1a3cfbe13..39ed05bd3 100644 --- a/invesalius/gui/frame.py +++ b/invesalius/gui/frame.py @@ -790,15 +790,7 @@ def ShowGettingStarted(self): """ Show getting started window. """ - session = ses.Session() - if session.GetConfig("language") == "pt_BR": - user_guide = "user_guide_pt_BR.pdf" - path = os.path.join(inv_paths.DOC_DIR, user_guide) - if sys.platform == "darwin": - path = r"file://" + path - webbrowser.open(path) - else: - user_guide = webbrowser.open("https://invesalius.github.io/docs/user_guide/user_guide.html") + webbrowser.open("https://invesalius.github.io/docs/user_guide/user_guide.html") def ShowImportDicomPanel(self): """ From 258890294d98f22b09991e7e4d0084226c12af5c Mon Sep 17 00:00:00 2001 From: Hafsa-shoaib989 Date: Mon, 12 Aug 2024 21:56:46 +0500 Subject: [PATCH 04/10] Fix positions of Coregistration fiducial buttons --- invesalius/gui/task_navigator.py | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/invesalius/gui/task_navigator.py b/invesalius/gui/task_navigator.py index 8279db5c4..c120d0d72 100644 --- a/invesalius/gui/task_navigator.py +++ b/invesalius/gui/task_navigator.py @@ -436,19 +436,19 @@ def __init__(self, parent, nav_hub): sizer = wx.GridBagSizer(5, 5) sizer.Add( - self.btns_set_fiducial[1], + self.btns_set_fiducial[0], # Left Ear wx.GBPosition(1, 0), span=wx.GBSpan(1, 2), flag=wx.ALIGN_CENTER_VERTICAL, ) sizer.Add( - self.btns_set_fiducial[2], + self.btns_set_fiducial[2], # Nasion wx.GBPosition(0, 2), span=wx.GBSpan(1, 2), flag=wx.ALIGN_CENTER_HORIZONTAL, ) sizer.Add( - self.btns_set_fiducial[0], + self.btns_set_fiducial[1], # Right Ear wx.GBPosition(1, 3), span=wx.GBSpan(1, 2), flag=wx.ALIGN_CENTER_VERTICAL, @@ -672,19 +672,19 @@ def __init__(self, parent, nav_hub): sizer = wx.GridBagSizer(5, 5) sizer.Add( - self.fiducial_buttons[1], + self.fiducial_buttons[0], # Left Ear wx.GBPosition(1, 0), span=wx.GBSpan(1, 2), flag=wx.ALIGN_CENTER_VERTICAL, ) sizer.Add( - self.fiducial_buttons[2], + self.fiducial_buttons[2], # Nasion wx.GBPosition(0, 2), span=wx.GBSpan(1, 2), flag=wx.ALIGN_CENTER_HORIZONTAL, ) sizer.Add( - self.fiducial_buttons[0], + self.fiducial_buttons[1], # Right Ear wx.GBPosition(1, 3), span=wx.GBSpan(1, 2), flag=wx.ALIGN_CENTER_VERTICAL, From 1f59027c218c834e76d3272eeed3da02724e5156 Mon Sep 17 00:00:00 2001 From: Omar Abdelgawad Date: Tue, 13 Aug 2024 16:37:55 +0300 Subject: [PATCH 05/10] Type hinted all of invesalius/data/bases.py, invesalius/data/converters.py, invesalius/data/poly_data_utils.py, invesalius/data/vtk_utils.py, invesalius/data/watershed_process.py, invesalius/session.py, invesalius/pubsub/pub.py, and invesalius/gui/dialogs.py and cython stubs * Added type annotations to function signatures * Annotated rest of widgets * Added more type defs excluded listctrl from ruff Fixed ruff errors in canvas_renderer * Added typings/utils for useful protocols * Changed Node to a dataclass using slots changed font to graphics font to avoid type conflict * Removed wx.dataview * resolved review comments * Type hinted session and inv_paths * Added stubs for cython * Type hinted root modules * Type hinted dialogs.py * Added event types * mv typings/wx/ typings/wx-stubs * mv invesalius_cy/*.pyi typings/invesalius_cy-stubs/ * ruff format invesalius/gui * Fix review comments * removed _FireSpin{Min,Max}{Change,Changed} * deleted unused modules * Fixing some mypy errors * Added cy_mesh.pyi and floodfill.pyi --- app.py | 2 +- invesalius/constants.py | 6 +- invesalius/control.py | 118 +- invesalius/data/bases.py | 33 +- invesalius/data/converters.py | 33 +- invesalius/data/coordinates.py | 70 +- invesalius/data/imagedata_utils.py | 2 +- invesalius/data/polydata_utils.py | 30 +- invesalius/data/record_coords.py | 6 +- invesalius/data/segmentation.py | 1 - invesalius/data/slice_.py | 76 +- invesalius/data/styles.py | 5 +- invesalius/data/transformations.py | 8 +- invesalius/data/vtk_utils.py | 105 +- invesalius/data/watershed_process.py | 34 +- invesalius/expanduser.py | 60 - invesalius/gui/bitmap_preview_panel.py | 2 +- invesalius/gui/data_notebook.py | 6 +- invesalius/gui/dialogs.py | 1306 ++--- invesalius/gui/dicom_preview_panel.py | 2 +- invesalius/gui/frame.py | 4 +- invesalius/gui/preferences.py | 2 +- invesalius/gui/task_slice.py | 2 +- invesalius/gui/task_surface.py | 2 +- invesalius/gui/widgets/canvas_renderer.py | 24 +- invesalius/gui/widgets/clut_raycasting.py | 13 +- invesalius/gui/widgets/gradient.py | 70 +- invesalius/gui/widgets/listctrl.py | 876 ---- invesalius/i18n.py | 15 +- invesalius/inv_paths.py | 8 +- invesalius/math_utils.py | 12 +- invesalius/plugins.py | 19 +- invesalius/project.py | 47 +- invesalius/pubsub/pub.py | 18 +- invesalius/session.py | 85 +- invesalius/version.py | 68 - pyproject.toml | 11 +- requirements.txt | 2 + typings/invesalius_cy-stubs/__init__.pyi | 0 typings/invesalius_cy-stubs/cy_mesh.pyi | 28 + typings/invesalius_cy-stubs/floodfill.pyi | 28 + typings/invesalius_cy-stubs/mips.pyi | 14 + typings/invesalius_cy-stubs/transforms.pyi | 13 + typings/{wx => wx-stubs}/__init__.pyi | 0 typings/{wx => wx-stubs}/core.pyi | 4968 +++++++++++--------- typings/wx-stubs/type_defs.pyi | 33 + typings/wx/type_defs.pyi | 18 - 47 files changed, 3897 insertions(+), 4388 deletions(-) delete mode 100644 invesalius/data/segmentation.py delete mode 100644 invesalius/expanduser.py delete mode 100644 invesalius/gui/widgets/listctrl.py delete mode 100644 invesalius/version.py create mode 100644 typings/invesalius_cy-stubs/__init__.pyi create mode 100644 typings/invesalius_cy-stubs/cy_mesh.pyi create mode 100644 typings/invesalius_cy-stubs/floodfill.pyi create mode 100644 typings/invesalius_cy-stubs/mips.pyi create mode 100644 typings/invesalius_cy-stubs/transforms.pyi rename typings/{wx => wx-stubs}/__init__.pyi (100%) rename typings/{wx => wx-stubs}/core.pyi (95%) create mode 100644 typings/wx-stubs/type_defs.pyi delete mode 100644 typings/wx/type_defs.pyi diff --git a/app.py b/app.py index 0983283d5..6ce84a0ff 100644 --- a/app.py +++ b/app.py @@ -167,7 +167,7 @@ def __init__(self): # except on win64, due to wxWidgets bug try: ok = dialog.ShowModal() == wx.ID_OK - except wx._core.PyAssertionError: + except wx.PyAssertionError: ok = True finally: if ok: diff --git a/invesalius/constants.py b/invesalius/constants.py index b860159bb..c6d2f448a 100644 --- a/invesalius/constants.py +++ b/invesalius/constants.py @@ -19,7 +19,7 @@ import itertools import sys -from typing import Dict, Optional, Tuple, Union +from typing import Dict, List, Optional, Tuple, Union import psutil import wx @@ -290,7 +290,7 @@ MASK_NAME_PATTERN = _("Mask %d") MASK_OPACITY = 0.40 # MASK_OPACITY = 0.35 -MASK_COLOUR = [ +MASK_COLOUR: List[List[float]] = [ [0.33, 1, 0.33], [1, 1, 0.33], [0.33, 0.91, 1], @@ -312,7 +312,7 @@ MEASURE_COLOUR = itertools.cycle([[1, 0, 0], [1, 0.4, 0], [0, 0, 1], [1, 0, 1], [0, 0.6, 0]]) -SURFACE_COLOUR = [ +SURFACE_COLOUR: List[Tuple[float, float, float]] = [ (0.33, 1, 0.33), (1, 1, 0.33), (0.33, 0.91, 1), diff --git a/invesalius/control.py b/invesalius/control.py index 99549f6d6..e81fe446a 100644 --- a/invesalius/control.py +++ b/invesalius/control.py @@ -21,13 +21,13 @@ import subprocess import sys import tempfile +from typing import TYPE_CHECKING, List, Literal, Optional, Sequence, Tuple import numpy as np import wx import invesalius.constants as const import invesalius.data.imagedata_utils as image_utils -import invesalius.data.mask as msk import invesalius.data.measures as measures import invesalius.data.slice_ as sl import invesalius.data.surface as srf @@ -46,6 +46,12 @@ from invesalius.i18n import tr as _ from invesalius.pubsub import pub as Publisher +if TYPE_CHECKING: + from pathlib import Path + + from invesalius.reader.dicom_grouper import DicomGroup + + DEFAULT_THRESH_MODE = 0 @@ -73,7 +79,7 @@ def __init__(self, frame): self.plugin_manager.find_plugins() - def __bind_events(self): + def __bind_events(self) -> None: Publisher.subscribe(self.OnImportMedicalImages, "Import directory") Publisher.subscribe(self.OnImportGroup, "Import group") Publisher.subscribe(self.OnImportFolder, "Import folder") @@ -118,42 +124,42 @@ def __bind_events(self): Publisher.subscribe(self.LoadProject, "Load project data") - def SetBitmapSpacing(self, spacing): + def SetBitmapSpacing(self, spacing: Tuple[float, float, float]) -> None: proj = prj.Project() proj.spacing = spacing - def OnCancelImport(self): + def OnCancelImport(self) -> None: # self.cancel_import = True Publisher.sendMessage("Hide import panel") - def OnCancelImportBitmap(self): + def OnCancelImportBitmap(self) -> None: # self.cancel_import = True Publisher.sendMessage("Hide import bitmap panel") ########################### ########################### - def OnShowDialogImportDirectory(self): + def OnShowDialogImportDirectory(self) -> None: self.ShowDialogImportDirectory() - def OnShowDialogImportOtherFiles(self, id_type): + def OnShowDialogImportOtherFiles(self, id_type: wx.WindowIDRef) -> None: self.ShowDialogImportOtherFiles(id_type) - def OnShowDialogOpenProject(self): + def OnShowDialogOpenProject(self) -> None: self.ShowDialogOpenProject() - def OnShowDialogSaveProject(self, save_as): + def OnShowDialogSaveProject(self, save_as: bool) -> None: self.ShowDialogSaveProject(save_as) - def OnShowDialogCloseProject(self): + def OnShowDialogCloseProject(self) -> None: self.ShowDialogCloseProject() - def OnShowBitmapFile(self): + def OnShowBitmapFile(self) -> None: self.ShowDialogImportBitmapFile() ########################### - def ShowDialogImportBitmapFile(self): + def ShowDialogImportBitmapFile(self) -> None: # Offer to save current project if necessary session = ses.Session() project_status = session.GetConfig("project_status") @@ -182,7 +188,7 @@ def ShowDialogImportBitmapFile(self): self.StartImportBitmapPanel(dirpath) # Publisher.sendMessage("Load data to import panel", dirpath) - def ShowDialogImportDirectory(self): + def ShowDialogImportDirectory(self) -> None: # Offer to save current project if necessary session = ses.Session() project_status = session.GetConfig("project_status") @@ -208,7 +214,7 @@ def ShowDialogImportDirectory(self): elif dirpath: self.StartImportPanel(dirpath) - def ShowDialogImportOtherFiles(self, id_type): + def ShowDialogImportOtherFiles(self, id_type: wx.WindowIDRef) -> None: # Offer to save current project if necessary session = ses.Session() project_status = session.GetConfig("project_status") @@ -228,14 +234,10 @@ def ShowDialogImportOtherFiles(self, id_type): Publisher.sendMessage("Stop Config Recording") Publisher.sendMessage("Enable style", style=const.STATE_DEFAULT) - # Warning for limited support to Analyze format - if id_type == const.ID_ANALYZE_IMPORT: - dialog.ImportAnalyzeWarning() - filepath = dialog.ShowImportOtherFilesDialog(id_type) Publisher.sendMessage("Open other files", filepath=filepath) - def ShowDialogOpenProject(self): + def ShowDialogOpenProject(self) -> None: # Offer to save current project if necessary session = ses.Session() project_status = session.GetConfig("project_status") @@ -257,7 +259,7 @@ def ShowDialogOpenProject(self): self.CloseProject() self.OpenProject(filepath) - def ShowDialogSaveProject(self, saveas=False): + def ShowDialogSaveProject(self, saveas: bool = False) -> None: session = ses.Session() if saveas or session.temp_item: proj = prj.Project() @@ -272,7 +274,7 @@ def ShowDialogSaveProject(self, saveas=False): self.SaveProject(filepath, compress) - def ShowDialogCloseProject(self): + def ShowDialogCloseProject(self) -> Optional[Literal[-1]]: session = ses.Session() project_status = session.GetConfig("project_status") if project_status == const.PROJECT_STATUS_CLOSED: @@ -315,10 +317,10 @@ def ShowDialogCloseProject(self): Publisher.sendMessage("Stop Config Recording") ########################### - def OnOpenProject(self, filepath): + def OnOpenProject(self, filepath: "str | Path") -> None: self.OpenProject(filepath) - def OnOpenRecentProject(self, filepath): + def OnOpenRecentProject(self, filepath: "str | Path") -> None: if os.path.exists(filepath): session = ses.Session() project_status = session.GetConfig("project_status") @@ -338,7 +340,7 @@ def OnOpenRecentProject(self, filepath): else: dialog.InexistentPath(filepath) - def OpenProject(self, filepath): + def OpenProject(self, filepath: "str | Path") -> None: Publisher.sendMessage("Begin busy cursor") path = os.path.abspath(filepath) @@ -365,10 +367,10 @@ def OpenProject(self, filepath): session.OpenProject(filepath) Publisher.sendMessage("Enable state project", state=True) - def OnSaveProject(self, filepath): + def OnSaveProject(self, filepath: Optional["str | Path"]) -> None: self.SaveProject(filepath) - def SaveProject(self, path=None, compress=False): + def SaveProject(self, path: Optional["str | Path"] = None, compress: bool = False) -> None: dialog.ProgressBarHandler(self.frame, "Saving Project", "Initializing...", max_value=100) try: @@ -394,17 +396,13 @@ def SaveProject(self, path=None, compress=False): except PermissionError as err: if wx.GetApp() is None: print( - "Error: Permission denied, you don't have permission to write at {}".format( - dirpath - ) + f"Error: Permission denied, you don't have permission to write at {dirpath}" ) else: dlg = dialogs.ErrorMessageBox( None, "Save project error", - "It was not possible to save because you don't have permission to write at {}\n{}".format( - dirpath, err - ), + f"It was not possible to save because you don't have permission to write at {dirpath}\n{err}", ) dlg.ShowModal() dlg.Destroy() @@ -425,7 +423,7 @@ def SaveProject(self, path=None, compress=False): finally: Publisher.sendMessage("Close Progress bar") - def CloseProject(self): + def CloseProject(self) -> None: Publisher.sendMessage("Enable style", style=const.STATE_DEFAULT) Publisher.sendMessage("Stop navigation") Publisher.sendMessage("Hide content panel") @@ -447,26 +445,26 @@ def CloseProject(self): ########################### - def StartImportBitmapPanel(self, path): + def StartImportBitmapPanel(self, path: "str | Path") -> None: # retrieve DICOM files splited into groups reader = bmp.ProgressBitmapReader() reader.SetWindowEvent(self.frame) reader.SetDirectoryPath(path) Publisher.sendMessage("End busy cursor") - def StartImportPanel(self, path): + def StartImportPanel(self, path: "str | Path") -> None: # retrieve DICOM files split into groups reader = dcm.ProgressDicomReader() reader.SetWindowEvent(self.frame) reader.SetDirectoryPath(path) Publisher.sendMessage("End busy cursor") - def Progress(self, data): + def Progress(self, data: Optional[Sequence[int]]) -> None: if data: message = _("Loading file %d of %d ...") % (data[0], data[1]) if not (self.progress_dialog): self.progress_dialog = vtk_utils.ProgressDialog( - parent=self.frame, maximum=data[1], abort=1 + parent=self.frame, maximum=data[1], abort=True ) else: if not (self.progress_dialog.Update(data[0], message)): @@ -479,21 +477,25 @@ def Progress(self, data): self.progress_dialog.Close() self.progress_dialog = None - def OnLoadImportPanel(self, patient_series): + def OnLoadImportPanel(self, patient_series: Optional[List]) -> None: ok = self.LoadImportPanel(patient_series) if ok: Publisher.sendMessage("Show import panel") Publisher.sendMessage("Show import panel in frame") self.img_type = 1 - def OnLoadImportBitmapPanel(self, data): + def OnLoadImportBitmapPanel( + self, data: List[Tuple[bytes, str, str, int, int, str, str, wx.WindowIDRef]] + ) -> None: ok = self.LoadImportBitmapPanel(data) if ok: Publisher.sendMessage("Show import bitmap panel in frame") self.img_type = 2 # Publisher.sendMessage("Show import panel in invesalius.gui.frame") as frame - def LoadImportBitmapPanel(self, data): + def LoadImportBitmapPanel( + self, data: List[Tuple[bytes, str, str, int, int, str, str, wx.WindowIDRef]] + ) -> bool: # if patient_series and isinstance(patient_series, list): # Publisher.sendMessage("Load import panel", patient_series) # first_patient = patient_series[0] @@ -505,7 +507,7 @@ def LoadImportBitmapPanel(self, data): dialog.ImportInvalidFiles("Bitmap") return False - def LoadImportPanel(self, patient_series): + def LoadImportPanel(self, patient_series: Optional[List]) -> bool: if patient_series and isinstance(patient_series, list): Publisher.sendMessage("Load import panel", dicom_groups=patient_series) first_patient = patient_series[0] @@ -517,10 +519,10 @@ def LoadImportPanel(self, patient_series): # ----------- to import by command line --------------------------------------------------- - def OnImportMedicalImages(self, directory, use_gui): + def OnImportMedicalImages(self, directory: str, use_gui: bool) -> None: self.ImportMedicalImages(directory, use_gui) - def ImportMedicalImages(self, directory, gui=True): + def ImportMedicalImages(self, directory: str, gui: bool = True) -> None: patients_groups = dcm.GetDicomGroups(directory) name = directory.rpartition("\\")[-1].split(".") @@ -553,10 +555,10 @@ def ImportMedicalImages(self, directory, gui=True): self.LoadProject() Publisher.sendMessage("Enable state project", state=True) - def OnImportGroup(self, group, use_gui): + def OnImportGroup(self, group: "DicomGroup", use_gui: bool): self.ImportGroup(group, use_gui) - def ImportGroup(self, group, gui=True): + def ImportGroup(self, group: "DicomGroup", gui: bool = True): matrix, matrix_filename, dicom = self.OpenDicomGroup(group, 0, [0, 0], gui=gui) if matrix is None: return @@ -627,7 +629,7 @@ def LoadProject(self): if len(proj.mask_dict): self.Slice.current_mask = None - mask_index = len(proj.mask_dict) - 1 + # mask_index = len(proj.mask_dict) - 1 for key, m in proj.mask_dict.items(): Publisher.sendMessage("Add mask", mask=m) if m.is_shown: @@ -853,7 +855,7 @@ def create_project_from_matrix( self.LoadProject() Publisher.sendMessage("Enable state project", state=True) - def OnOpenBitmapFiles(self, rec_data): + def OnOpenBitmapFiles(self, rec_data: Tuple[str, str, float, float, float, float]) -> None: bmp_data = bmp.BitmapData() if bmp_data.IsAllBitmapSameSize(): @@ -866,8 +868,10 @@ def OnOpenBitmapFiles(self, rec_data): else: dialogs.BitmapNotSameSize() - def OpenBitmapFiles(self, bmp_data, rec_data): - name = rec_data[0] + def OpenBitmapFiles( + self, bmp_data: "bmp.BitmapData", rec_data: Tuple[str, str, float, float, float, float] + ): + # name = rec_data[0] orientation = rec_data[1] sp_x = float(rec_data[2]) sp_y = float(rec_data[3]) @@ -946,9 +950,9 @@ def OnOpenDicomGroup(self, group, interval, file_range): self.LoadProject() Publisher.sendMessage("Enable state project", state=True) - def OnOpenOtherFiles(self, filepath): + def OnOpenOtherFiles(self, filepath: bytes) -> None: filepath = utils.decode(filepath, const.FS_ENCODE) - if not (filepath) == None: + if (filepath) is not None: name = os.path.basename(filepath).split(".")[0] group = oth.ReadOthers(filepath) if group: @@ -960,7 +964,13 @@ def OnOpenOtherFiles(self, filepath): else: dialog.ImportInvalidFiles(ftype="Others") - def OpenDicomGroup(self, dicom_group, interval, file_range, gui=True): + def OpenDicomGroup( + self, + dicom_group: "DicomGroup", + interval: int, + file_range: Optional[Sequence[int]], + gui: bool = True, + ): # Retrieve general DICOM headers dicom = dicom_group.GetDicomSample() @@ -1082,7 +1092,7 @@ def OpenOtherFiles(self, group): # this solves the visualization issue only for MRIs imported with NIfTI, but not # with DICOM wl = float((percentile_2 + percentile_98) * 0.5) - ww = float((percentile_98 - percentile_2)) + ww = float(percentile_98 - percentile_2) # Set wl and ww based on full scalar range. This causes some mri to be visualized # very dark due to presence of high pixel intensities @@ -1240,7 +1250,7 @@ def disable_mask_preview(self): Publisher.sendMessage("Remove mask preview", mask_3d_actor=mask.volume._actor) Publisher.sendMessage("Render volume viewer") - def update_mask_preview(self): + def update_mask_preview(self) -> None: mask = self.Slice.current_mask if mask is not None: mask._update_imagedata() diff --git a/invesalius/data/bases.py b/invesalius/data/bases.py index a60f27cb4..aaac61915 100644 --- a/invesalius/data/bases.py +++ b/invesalius/data/bases.py @@ -1,3 +1,5 @@ +from typing import Any, List, Optional, Sequence, Tuple, Union + import numpy as np import invesalius.data.coordinates as dco @@ -5,7 +7,7 @@ import invesalius.data.transformations as tr -def angle_calculation(ap_axis, coil_axis): +def angle_calculation(ap_axis: Sequence[Any], coil_axis: Sequence[Any]) -> float: """ Calculate angle between two given axis (in degrees) @@ -14,18 +16,19 @@ def angle_calculation(ap_axis, coil_axis): :return: angle between the two given axes """ - ap_axis = np.array([ap_axis[0], ap_axis[1]]) - coil_axis = np.array([float(coil_axis[0]), float(coil_axis[1])]) + ap_axis_nd = np.array([ap_axis[0], ap_axis[1]]) + coil_axis_nd = np.array([float(coil_axis[0]), float(coil_axis[1])]) angle = np.rad2deg( np.arccos( - (np.dot(ap_axis, coil_axis)) / (np.linalg.norm(ap_axis) * np.linalg.norm(coil_axis)) + (np.dot(ap_axis_nd, coil_axis_nd)) + / (np.linalg.norm(ap_axis_nd) * np.linalg.norm(coil_axis_nd)) ) ) return float(angle) -def base_creation_old(fiducials): +def base_creation_old(fiducials: np.ndarray) -> Tuple[np.matrix, np.ndarray, np.matrix]: """ Calculate the origin and matrix for coordinate system transformation. q: origin of coordinate system @@ -63,7 +66,9 @@ def base_creation_old(fiducials): return m, q, m_inv -def base_creation(fiducials): +def base_creation( + fiducials: np.ndarray, +) -> Tuple[np.ndarray, np.ndarray]: """ Calculate the origin and matrix for coordinate system transformation. @@ -103,7 +108,13 @@ def base_creation(fiducials): return m, q -def calculate_fre(fiducials_raw, fiducials, ref_mode_id, m_change, m_icp=None): +def calculate_fre( + fiducials_raw: np.ndarray, + fiducials: np.ndarray, + ref_mode_id: int, + m_change: np.ndarray, + m_icp: Optional[List[Union[int, np.ndarray]]] = None, +) -> float: """ Calculate the Fiducial Registration Error for neuronavigation. @@ -162,7 +173,7 @@ def calculate_fre(fiducials_raw, fiducials, ref_mode_id, m_change, m_icp=None): # return point_rot -def transform_icp(m_img, m_icp): +def transform_icp(m_img: np.ndarray, m_icp: np.ndarray) -> np.ndarray: coord_img = [m_img[0, -1], -m_img[1, -1], m_img[2, -1], 1] m_img[0, -1], m_img[1, -1], m_img[2, -1], _ = m_icp @ coord_img m_img[0, -1], m_img[1, -1], m_img[2, -1] = m_img[0, -1], -m_img[1, -1], m_img[2, -1] @@ -170,7 +181,7 @@ def transform_icp(m_img, m_icp): return m_img -def inverse_transform_icp(m_img, m_icp): +def inverse_transform_icp(m_img: np.ndarray, m_icp: np.ndarray) -> np.ndarray: coord_img = [m_img[0, -1], -m_img[1, -1], m_img[2, -1], 1] m_img[0, -1], m_img[1, -1], m_img[2, -1], _ = np.linalg.inv(m_icp) @ coord_img m_img[0, -1], m_img[1, -1], m_img[2, -1] = m_img[0, -1], -m_img[1, -1], m_img[2, -1] @@ -178,7 +189,9 @@ def inverse_transform_icp(m_img, m_icp): return m_img -def object_registration(fiducials, orients, coord_raw, m_change): +def object_registration( + fiducials: np.ndarray, orients: np.ndarray, coord_raw: np.ndarray, m_change: np.ndarray +) -> Tuple[np.ndarray, np.ndarray, np.ndarray, np.ndarray, np.ndarray, np.ndarray]: """ :param fiducials: 3x3 array of fiducials translations diff --git a/invesalius/data/converters.py b/invesalius/data/converters.py index 2a3a16167..46dcc6008 100644 --- a/invesalius/data/converters.py +++ b/invesalius/data/converters.py @@ -17,6 +17,8 @@ # detalhes. # -------------------------------------------------------------------------- +from typing import TYPE_CHECKING, Optional, Sequence, Tuple + import gdcm import numpy as np from vtkmodules.util import numpy_support @@ -25,15 +27,18 @@ ) from vtkmodules.vtkCommonDataModel import vtkCellArray, vtkImageData, vtkPolyData, vtkTriangle +if TYPE_CHECKING: + import os + def to_vtk( - n_array, - spacing=(1.0, 1.0, 1.0), - slice_number=0, - orientation="AXIAL", - origin=(0, 0, 0), - padding=(0, 0, 0), -): + n_array: np.ndarray, + spacing: Sequence[float] = (1.0, 1.0, 1.0), + slice_number: int = 0, + orientation: str = "AXIAL", + origin: Sequence[float] = (0, 0, 0), + padding: Tuple[int, int, int] = (0, 0, 0), +) -> vtkImageData: if orientation == "SAGITTAL": orientation = "SAGITAL" @@ -96,7 +101,11 @@ def to_vtk( return image_copy -def to_vtk_mask(n_array, spacing=(1.0, 1.0, 1.0), origin=(0.0, 0.0, 0.0)): +def to_vtk_mask( + n_array: np.ndarray, + spacing: Tuple[float, float, float] = (1.0, 1.0, 1.0), + origin: Tuple[float, float, float] = (0.0, 0.0, 0.0), +) -> vtkImageData: dz, dy, dx = n_array.shape ox, oy, oz = origin sx, sy, sz = spacing @@ -127,7 +136,7 @@ def to_vtk_mask(n_array, spacing=(1.0, 1.0, 1.0), origin=(0.0, 0.0, 0.0)): return image -def np_rgba_to_vtk(n_array, spacing=(1.0, 1.0, 1.0)): +def np_rgba_to_vtk(n_array: np.ndarray, spacing: Sequence[float] = (1.0, 1.0, 1.0)) -> vtkImageData: dy, dx, dc = n_array.shape v_image = numpy_support.numpy_to_vtk(n_array.reshape(dy * dx, dc)) @@ -150,7 +159,7 @@ def np_rgba_to_vtk(n_array, spacing=(1.0, 1.0, 1.0)): # Based on http://gdcm.sourceforge.net/html/ConvertNumpy_8py-example.html -def gdcm_to_numpy(image, apply_intercep_scale=True): +def gdcm_to_numpy(image: gdcm.Image, apply_intercep_scale: bool = True): map_gdcm_np = { gdcm.PixelFormat.SINGLEBIT: np.uint8, gdcm.PixelFormat.UINT8: np.uint8, @@ -194,7 +203,7 @@ def gdcm_to_numpy(image, apply_intercep_scale=True): return np_array -def convert_custom_bin_to_vtk(filename): +def convert_custom_bin_to_vtk(filename: "str | bytes | os.PathLike[str]") -> Optional[vtkPolyData]: import os if os.path.exists(filename): @@ -228,4 +237,4 @@ def convert_custom_bin_to_vtk(filename): return polydata else: print("File does not exists") - return + return None diff --git a/invesalius/data/coordinates.py b/invesalius/data/coordinates.py index 95b3e6bc9..68aa56fee 100644 --- a/invesalius/data/coordinates.py +++ b/invesalius/data/coordinates.py @@ -21,6 +21,7 @@ from math import cos, sin from random import uniform from time import sleep +from typing import TYPE_CHECKING, Any, List, Optional, Sequence, Tuple, Union import numpy as np import wx @@ -30,22 +31,25 @@ import invesalius.session as ses from invesalius.pubsub import pub as Publisher +if TYPE_CHECKING: + from invesalius.data.tracker_connection import TrackerConnection + class TrackerCoordinates: def __init__(self): - self.coord = None + self.coord: Optional[np.ndarray] = None self.marker_visibilities = [False, False, False] self.previous_marker_visibilities = self.marker_visibilities self.nav_status = False self.__bind_events() - def __bind_events(self): + def __bind_events(self) -> None: Publisher.subscribe(self.OnUpdateNavigationStatus, "Navigation status") - def OnUpdateNavigationStatus(self, nav_status, vis_status): + def OnUpdateNavigationStatus(self, nav_status: bool, vis_status) -> None: self.nav_status = nav_status - def SetCoordinates(self, coord, marker_visibilities): + def SetCoordinates(self, coord, marker_visibilities: List[bool]) -> None: self.coord = coord self.marker_visibilities = marker_visibilities if not self.nav_status: @@ -64,7 +68,7 @@ def SetCoordinates(self, coord, marker_visibilities): wx.CallAfter(Publisher.sendMessage, "Render volume viewer") self.previous_marker_visibilities = self.marker_visibilities - def GetCoordinates(self): + def GetCoordinates(self) -> Tuple[Optional[np.ndarray], List[bool]]: if self.nav_status: wx.CallAfter( Publisher.sendMessage, @@ -83,7 +87,9 @@ def GetCoordinates(self): return self.coord, self.marker_visibilities -def GetCoordinatesForThread(tracker_connection, tracker_id, ref_mode): +def GetCoordinatesForThread( + tracker_connection: "TrackerConnection", tracker_id: int, ref_mode: int +): """ Read coordinates from spatial tracking devices using @@ -114,7 +120,7 @@ def GetCoordinatesForThread(tracker_connection, tracker_id, ref_mode): return coord, marker_visibilities -def PolarisP4Coord(tracker_connection, tracker_id, ref_mode): +def PolarisP4Coord(tracker_connection: "TrackerConnection", tracker_id: int, ref_mode: int): trck = tracker_connection.GetConnection() trck.Run() @@ -158,7 +164,7 @@ def PolarisP4Coord(tracker_connection, tracker_id, ref_mode): return coord, [trck.probeID, trck.refID, trck.objID] -def OptitrackCoord(tracker_connection, tracker_id, ref_mode): +def OptitrackCoord(tracker_connection: "TrackerConnection", tracker_id: int, ref_mode: int): """ Obtains coordinates and angles of tracking rigid bodies (Measurement Probe, Coil, Head). Converts orientations from quaternion @@ -234,7 +240,7 @@ def OptitrackCoord(tracker_connection, tracker_id, ref_mode): return coord, [trck.probeID, trck.HeadID, trck.coilID] -def PolarisCoord(tracker_connection, tracker_id, ref_mode): +def PolarisCoord(tracker_connection: "TrackerConnection", tracker_id: int, ref_mode: int): trck = tracker_connection.GetConnection() trck.Run() @@ -258,14 +264,14 @@ def PolarisCoord(tracker_connection, tracker_id, ref_mode): return coord, [trck.probeID, trck.refID, trck.objID] -def CameraCoord(tracker_connection, tracker_id, ref_mode): +def CameraCoord(tracker_connection: "TrackerConnection", tracker_id: int, ref_mode): trck = tracker_connection.GetConnection() coord, probeID, refID, coilID = trck.Run() return coord, [probeID, refID, coilID] -def ClaronCoord(tracker_connection, tracker_id, ref_mode): +def ClaronCoord(tracker_connection: "TrackerConnection", tracker_id: int, ref_mode: int): trck = tracker_connection.GetConnection() trck.Run() @@ -309,7 +315,7 @@ def ClaronCoord(tracker_connection, tracker_id, ref_mode): return coord, [trck.probeID, trck.refID, trck.coilID] -def PolhemusCoord(tracker_connection, tracker_id, ref_mode): +def PolhemusCoord(tracker_connection: "TrackerConnection", tracker_id: int, ref_mode: int): lib_mode = tracker_connection.GetLibMode() coord = None @@ -326,7 +332,7 @@ def PolhemusCoord(tracker_connection, tracker_id, ref_mode): return coord, [True, True, True] -def PolhemusWrapperCoord(tracker_connection, tracker_id, ref_mode): +def PolhemusWrapperCoord(tracker_connection: "TrackerConnection", tracker_id: int, ref_mode: int): trck = tracker_connection.GetConnection() trck.Run() @@ -384,7 +390,7 @@ def PolhemusWrapperCoord(tracker_connection, tracker_id, ref_mode): return coord -def PolhemusUSBCoord(tracker_connection, tracker_id, ref_mode): +def PolhemusUSBCoord(tracker_connection: "TrackerConnection", tracker_id: int, ref_mode: int): trck = tracker_connection.GetConnection() endpoint = trck[0][(0, 0)][0] @@ -437,7 +443,7 @@ def PolhemusUSBCoord(tracker_connection, tracker_id, ref_mode): return coord -def PolhemusSerialCoord(tracker_connection, tracker_id, ref_mode): +def PolhemusSerialCoord(tracker_connection: "TrackerConnection", tracker_id: int, ref_mode: int): trck = tracker_connection.GetConnection() # mudanca para fastrak - ref 1 tem somente x, y, z @@ -482,7 +488,7 @@ def PolhemusSerialCoord(tracker_connection, tracker_id, ref_mode): return coord -def RobotCoord(tracker_connection, tracker_id, ref_mode): +def RobotCoord(tracker_connection: "TrackerConnection", tracker_id: int, ref_mode: int): tracker_id = tracker_connection.GetTrackerId() coord_tracker, marker_visibilities = GetCoordinatesForThread( @@ -492,7 +498,7 @@ def RobotCoord(tracker_connection, tracker_id, ref_mode): return np.vstack([coord_tracker[0], coord_tracker[1], coord_tracker[2]]), marker_visibilities -def DebugCoordRandom(tracker_connection, tracker_id, ref_mode): +def DebugCoordRandom(tracker_connection: "TrackerConnection", tracker_id: int, ref_mode: int): """ Method to simulate a tracking device for debug and error check. Generate a random x, y, z, alfa, beta and gama coordinates in interval [1, 200[ @@ -554,7 +560,11 @@ def DebugCoordRandom(tracker_connection, tracker_id, ref_mode): return np.vstack([coord1, coord2, coord3, coord4]), marker_visibilities -def coordinates_to_transformation_matrix(position, orientation, axes="sxyz"): +def coordinates_to_transformation_matrix( + position: Union[Sequence[float], np.ndarray], + orientation: Union[Sequence[float], np.ndarray], + axes: str = "sxyz", +) -> np.ndarray: """ Transform vectors consisting of position and orientation (in Euler angles) in 3d-space into a 4x4 transformation matrix that combines the rotation and translation. @@ -695,7 +705,7 @@ def dynamic_reference_m2(probe, reference): return coord_rot[0], coord_rot[1], coord_rot[2], np.degrees(al), np.degrees(be), np.degrees(ga) -def str2float(data): +def str2float(data: str) -> List[float]: """ Converts string detected wth Polhemus device to float array of coordinates. This method applies a correction for the minus sign in string that raises error while splitting the string into coordinates. @@ -709,13 +719,13 @@ def str2float(data): data = data[: i + count] + " " + data[i + count :] count += 1 - data = [s for s in data.split()] - data = [float(s) for s in data[1 : len(data)]] + new_data = [s for s in data.split()] + ret = [float(s) for s in new_data[1 : len(new_data)]] - return data + return ret -def offset_coordinate(p_old, norm_vec, offset): +def offset_coordinate(p_old: np.ndarray, norm_vec: np.ndarray, offset: float) -> np.ndarray: """ Translate the coordinates of a point along a vector :param p_old: (x, y, z) array with current point coordinates @@ -728,7 +738,13 @@ def offset_coordinate(p_old, norm_vec, offset): class ReceiveCoordinates(threading.Thread): - def __init__(self, tracker_connection, tracker_id, TrackerCoordinates, event): + def __init__( + self, + tracker_connection: "TrackerConnection", + tracker_id: int, + TrackerCoordinates: TrackerCoordinates, + event: threading.Event, + ): threading.Thread.__init__(self, name="ReceiveCoordinates") self.__bind_events() @@ -741,13 +757,13 @@ def __init__(self, tracker_connection, tracker_id, TrackerCoordinates, event): self.event = event self.TrackerCoordinates = TrackerCoordinates - def __bind_events(self): + def __bind_events(self) -> None: Publisher.subscribe(self.UpdateCoordSleep, "Update coord sleep") - def UpdateCoordSleep(self, data): + def UpdateCoordSleep(self, data) -> None: self.sleep_coord = data - def run(self): + def run(self) -> None: while not self.event.is_set(): coord_raw, marker_visibilities = GetCoordinatesForThread( self.tracker_connection, self.tracker_id, const.DEFAULT_REF_MODE diff --git a/invesalius/data/imagedata_utils.py b/invesalius/data/imagedata_utils.py index c3d5583dc..d08a1b49a 100644 --- a/invesalius/data/imagedata_utils.py +++ b/invesalius/data/imagedata_utils.py @@ -562,7 +562,7 @@ def get_LUT_value_255(data, window, level): return data -def get_LUT_value(data, window, level): +def get_LUT_value(data: np.ndarray, window: int, level: int) -> np.ndarray: shape = data.shape data_ = data.ravel() data = np.piecewise( diff --git a/invesalius/data/polydata_utils.py b/invesalius/data/polydata_utils.py index f323f39e0..6e3199df3 100644 --- a/invesalius/data/polydata_utils.py +++ b/invesalius/data/polydata_utils.py @@ -18,8 +18,8 @@ # -------------------------------------------------------------------------- import sys +from typing import Iterable, List -import wx from vtkmodules.vtkCommonDataModel import vtkPolyData from vtkmodules.vtkFiltersCore import ( vtkAppendPolyData, @@ -54,7 +54,7 @@ UpdateProgress = vu.ShowProgress() -def ApplyDecimationFilter(polydata, reduction_factor): +def ApplyDecimationFilter(polydata: vtkPolyData, reduction_factor: float) -> vtkPolyData: """ Reduce number of triangles of the given vtkPolyData, based on reduction_factor. @@ -72,7 +72,9 @@ def ApplyDecimationFilter(polydata, reduction_factor): return decimation.GetOutput() -def ApplySmoothFilter(polydata, iterations, relaxation_factor): +def ApplySmoothFilter( + polydata: vtkPolyData, iterations: int, relaxation_factor: float +) -> vtkPolyData: """ Smooth given vtkPolyData surface, based on iteration and relaxation_factor. """ @@ -91,7 +93,7 @@ def ApplySmoothFilter(polydata, iterations, relaxation_factor): return smoother.GetOutput() -def FillSurfaceHole(polydata): +def FillSurfaceHole(polydata: vtkPolyData) -> "vtkPolyData": """ Fill holes in the given polydata. """ @@ -103,7 +105,7 @@ def FillSurfaceHole(polydata): return filled_polydata.GetOutput() -def CalculateSurfaceVolume(polydata): +def CalculateSurfaceVolume(polydata: vtkPolyData) -> float: """ Calculate the volume from the given polydata """ @@ -113,7 +115,7 @@ def CalculateSurfaceVolume(polydata): return measured_polydata.GetVolume() -def CalculateSurfaceArea(polydata): +def CalculateSurfaceArea(polydata: vtkPolyData) -> float: """ Calculate the volume from the given polydata """ @@ -123,7 +125,7 @@ def CalculateSurfaceArea(polydata): return measured_polydata.GetSurfaceArea() -def Merge(polydata_list): +def Merge(polydata_list: Iterable[vtkPolyData]) -> vtkPolyData: append = vtkAppendPolyData() for polydata in polydata_list: @@ -140,7 +142,7 @@ def Merge(polydata_list): return append.GetOutput() -def Export(polydata, filename, bin=False): +def Export(polydata: vtkPolyData, filename: str, bin: bool = False) -> None: writer = vtkXMLPolyDataWriter() if _has_win32api: touch(filename) @@ -154,7 +156,7 @@ def Export(polydata, filename, bin=False): writer.Write() -def Import(filename): +def Import(filename: str) -> vtkPolyData: reader = vtkXMLPolyDataReader() try: reader.SetFileName(filename.encode()) @@ -164,7 +166,7 @@ def Import(filename): return reader.GetOutput() -def LoadPolydata(path): +def LoadPolydata(path: str) -> vtkPolyData: if path.lower().endswith(".stl"): reader = vtkSTLReader() @@ -187,7 +189,7 @@ def LoadPolydata(path): return polydata -def JoinSeedsParts(polydata, point_id_list): +def JoinSeedsParts(polydata: vtkPolyData, point_id_list: List[int]) -> vtkPolyData: """ The function require vtkPolyData and point id from vtkPolyData. @@ -212,7 +214,7 @@ def JoinSeedsParts(polydata, point_id_list): return result -def SelectLargestPart(polydata): +def SelectLargestPart(polydata: vtkPolyData) -> vtkPolyData: """ """ UpdateProgress = vu.ShowProgress(1) conn = vtkPolyDataConnectivityFilter() @@ -228,7 +230,7 @@ def SelectLargestPart(polydata): return result -def SplitDisconectedParts(polydata): +def SplitDisconectedParts(polydata: vtkPolyData) -> List[vtkPolyData]: """ """ conn = vtkPolyDataConnectivityFilter() conn.SetInputData(polydata) @@ -240,7 +242,7 @@ def SplitDisconectedParts(polydata): conn.SetExtractionModeToSpecifiedRegions() conn.Update() - polydata_collection = [] + polydata_collection: List[vtkPolyData] = [] # Update progress value in GUI progress = nregions - 1 diff --git a/invesalius/data/record_coords.py b/invesalius/data/record_coords.py index fecbef2c8..424bfe2ce 100644 --- a/invesalius/data/record_coords.py +++ b/invesalius/data/record_coords.py @@ -43,14 +43,14 @@ def __init__(self, nav_id, timestamp): self._pause_ = False self.start() - def __bind_events(self): + def __bind_events(self) -> None: # Publisher.subscribe(self.UpdateCurrentCoords, 'Co-registered points') Publisher.subscribe(self.UpdateCurrentCoords, "Set cross focal point") - def UpdateCurrentCoords(self, position): + def UpdateCurrentCoords(self, position) -> None: self.coord = asarray(position) - def stop(self): + def stop(self) -> None: self._pause_ = True # save coords dialog filename = dlg.ShowLoadSaveDialog( diff --git a/invesalius/data/segmentation.py b/invesalius/data/segmentation.py deleted file mode 100644 index a22b22b17..000000000 --- a/invesalius/data/segmentation.py +++ /dev/null @@ -1 +0,0 @@ -import numpy as np diff --git a/invesalius/data/slice_.py b/invesalius/data/slice_.py index 19d5aa137..aef2ef76a 100644 --- a/invesalius/data/slice_.py +++ b/invesalius/data/slice_.py @@ -18,9 +18,9 @@ # -------------------------------------------------------------------------- import os import tempfile +from typing import TYPE_CHECKING, Optional, Tuple, Union import numpy as np -from scipy import ndimage from vtkmodules.vtkCommonCore import vtkLookupTable from vtkmodules.vtkImagingColor import vtkImageMapToWindowLevelColors from vtkmodules.vtkImagingCore import ( @@ -46,37 +46,40 @@ from invesalius.pubsub import pub as Publisher from invesalius_cy import mips, transforms +if TYPE_CHECKING: + from vtkmodules.vtkCommonDataModel import vtkImageData + OTHER = 0 PLIST = 1 WIDGET = 2 -class SliceBuffer(object): +class SliceBuffer: """ This class is used as buffer that mantains the vtkImageData and numpy array from actual slices from each orientation. """ def __init__(self): - self.index = -1 - self.image = None - self.mask = None - self.vtk_image = None - self.vtk_mask = None + self.index: int = -1 + self.image: Optional[np.ndarray] = None + self.mask: Optional[np.ndarray] = None + self.vtk_image: Optional[vtkImageData] = None + self.vtk_mask: Optional[vtkImageData] = None - def discard_vtk_mask(self): + def discard_vtk_mask(self) -> None: self.vtk_mask = None - def discard_vtk_image(self): + def discard_vtk_image(self) -> None: self.vtk_image = None - def discard_mask(self): + def discard_mask(self) -> None: self.mask = None - def discard_image(self): + def discard_image(self) -> None: self.image = None - def discard_buffer(self): + def discard_buffer(self) -> None: self.index = -1 self.image = None self.mask = None @@ -89,15 +92,17 @@ def discard_buffer(self): # Therefore, we use Singleton design pattern for implementing it. class Slice(metaclass=utils.Singleton): def __init__(self): - self.current_mask = None + self.current_mask: Optional[Mask] = None self.blend_filter = None - self.histogram = None - self._matrix = None - self._affine = np.identity(4) - self._n_tracts = 0 + self.histogram: Optional[np.ndarray] = None + self._matrix: Optional[np.ndarray] = None + self._affine: np.ndarray = np.identity(4) + self._n_tracts: int = 0 self._tracker = None - self.aux_matrices = {} - self.aux_matrices_colours = {} + self.aux_matrices: dict[str, np.ndarray] = {} + self.aux_matrices_colours: dict[ + str, dict[Union[int, float], Tuple[float, float, float]] + ] = {} self.state = const.STATE_DEFAULT self.to_show_aux = "" @@ -131,14 +136,14 @@ def __init__(self): self.from_ = OTHER self.__bind_events() - self.opacity = 0.8 + self.opacity: float = 0.8 @property - def matrix(self): + def matrix(self) -> Optional[np.ndarray]: return self._matrix @matrix.setter - def matrix(self, value): + def matrix(self, value: np.ndarray) -> None: self._matrix = value i, e = value.min(), value.max() r = int(e) - int(i) @@ -146,28 +151,28 @@ def matrix(self, value): self.center = [(s * d / 2.0) for (d, s) in zip(self.matrix.shape[::-1], self.spacing)] @property - def spacing(self): + def spacing(self) -> Tuple[float, float, float]: return self._spacing @spacing.setter - def spacing(self, value): + def spacing(self, value: Tuple[float, float, float]) -> None: self._spacing = value self.center = [(s * d / 2.0) for (d, s) in zip(self.matrix.shape[::-1], self.spacing)] @property - def affine(self): + def affine(self) -> np.ndarray: return self._affine @affine.setter - def affine(self, value): + def affine(self, value: np.ndarray) -> None: self._affine = value @property - def n_tracts(self): + def n_tracts(self) -> int: return self._n_tracts @n_tracts.setter - def n_tracts(self, value): + def n_tracts(self, value: int) -> None: self._n_tracts = value @property @@ -178,7 +183,7 @@ def tracker(self): def tracker(self, value): self._tracker = value - def __bind_events(self): + def __bind_events(self) -> None: # General slice control Publisher.subscribe(self.CreateSurfaceFromIndex, "Create surface from index") # Mask control @@ -249,8 +254,8 @@ def __bind_events(self): Publisher.subscribe(self._set_interpolation_method, "Set interpolation method") - def GetMaxSliceNumber(self, orientation): - shape = self.matrix.shape + def GetMaxSliceNumber(self, orientation: str) -> int: + shape: Tuple[int, int, int] = self.matrix.shape # Because matrix indexing starts with 0 so the last slice is the shape # minu 1. @@ -260,8 +265,9 @@ def GetMaxSliceNumber(self, orientation): return shape[1] - 1 elif orientation == "SAGITAL": return shape[2] - 1 + raise ValueError(f"Invalid orientation: {orientation}") - def discard_all_buffers(self): + def discard_all_buffers(self) -> None: for buffer_ in self.buffer_slices.values(): buffer_.discard_vtk_mask() buffer_.discard_mask() @@ -1595,7 +1601,7 @@ def do_boolean_op(self, op, m1, m2): const.BOOLEAN_XOR: _("XOR"), } - name = "%s_%s_%s" % (name_ops[op], m1.name, m2.name) + name = f"{name_ops[op]}_{m1.name}_{m2.name}" proj = Project() mask_dict = proj.mask_dict names_list = [mask_dict[i].name for i in mask_dict.keys()] @@ -1844,11 +1850,11 @@ def calc_mask_area(self, mask=None): return area - def has_affine(self): + def has_affine(self) -> bool: return not np.allclose(self.affine, np.eye(4)) -def _conv_area(x, sx, sy, sz): +def _conv_area(x: np.ndarray, sx: float, sy: float, sz: float) -> float: x = x.reshape((3, 3, 3)) if x[1, 1, 1]: kernel = np.zeros((3, 3, 3)) diff --git a/invesalius/data/styles.py b/invesalius/data/styles.py index aba259f14..d3332cf39 100644 --- a/invesalius/data/styles.py +++ b/invesalius/data/styles.py @@ -22,6 +22,7 @@ import tempfile import time from concurrent import futures +from typing import Optional import numpy as np import wx @@ -2718,8 +2719,8 @@ def __init__(self): self.con_2d = 4 self.con_3d = 6 - self.t0 = None - self.t1 = None + self.t0: Optional[int] = None + self.t1: Optional[int] = None self.fill_value = 254 diff --git a/invesalius/data/transformations.py b/invesalius/data/transformations.py index 49e31dd3c..b50ecb1ea 100644 --- a/invesalius/data/transformations.py +++ b/invesalius/data/transformations.py @@ -196,8 +196,10 @@ from __future__ import division, print_function import math +from typing import Any, Sequence, Union import numpy +import numpy.typing __version__ = "2015.07.18" __docformat__ = "restructuredtext en" @@ -219,7 +221,7 @@ def identity_matrix(): return numpy.identity(4) -def translation_matrix(direction): +def translation_matrix(direction: Union[Sequence[float], numpy.ndarray]) -> numpy.ndarray: """Return matrix to translate by direction vector. >>> v = numpy.random.random(3) - 0.5 @@ -1885,7 +1887,9 @@ def inverse_matrix(matrix): return numpy.linalg.inv(matrix) -def concatenate_matrices(*matrices): +def concatenate_matrices( + *matrices: numpy.ndarray, +) -> numpy.ndarray: """Return concatenation of series of transformation matrices. >>> M = numpy.random.rand(16).reshape((4, 4)) - 0.5 diff --git a/invesalius/data/vtk_utils.py b/invesalius/data/vtk_utils.py index d62c35410..d9c9de843 100644 --- a/invesalius/data/vtk_utils.py +++ b/invesalius/data/vtk_utils.py @@ -18,6 +18,7 @@ # -------------------------------------------------------------------------- import os import sys +from typing import TYPE_CHECKING, Any, Callable, List, Optional, Sequence, SupportsInt, Tuple, Union import wx from vtkmodules.vtkCommonMath import vtkMatrix4x4 @@ -38,9 +39,15 @@ from invesalius.i18n import tr as _ from invesalius.pubsub import pub as Publisher +if TYPE_CHECKING: + import numpy as np + from vtkmodules.vtkCommonExecutionModel import vtkAlgorithm -class ProgressDialog(object): - def __init__(self, parent, maximum, abort=False): + from invesalius.gui.widgets.canvas_renderer import CanvasRendererCTX + + +class ProgressDialog: + def __init__(self, parent: Optional[wx.Window], maximum: int, abort: bool = False): self.title = "InVesalius 3" self.msg = _("Loading DICOM files") self.maximum = maximum @@ -56,21 +63,21 @@ def __init__(self, parent, maximum, abort=False): self.dlg.Bind(wx.EVT_BUTTON, self.Cancel) self.dlg.SetSize(wx.Size(250, 150)) - def Cancel(self, evt): + def Cancel(self, evt: wx.CommandEvent) -> None: Publisher.sendMessage("Cancel DICOM load") - def Update(self, value, message): + def Update(self, value: SupportsInt, message: str) -> Union[Tuple[bool, bool], bool]: if int(value) != self.maximum: try: return self.dlg.Update(int(value), message) # TODO: - # Exception in the Windows XP 64 Bits with wxPython 2.8.10 - except wx._core.PyAssertionError: + # Exception in the Wtindows XP 64 Bits with wxPython 2.8.10 + except wx.PyAssertionError: return True else: return False - def Close(self): + def Close(self) -> None: self.dlg.Destroy() @@ -95,18 +102,20 @@ def Close(self): # http://jjinux.blogspot.com/2006/10/python-modifying-counter-in-closure.html -def ShowProgress(number_of_filters=1, dialog_type="GaugeProgress"): +def ShowProgress( + number_of_filters: int = 1, dialog_type: str = "GaugeProgress" +) -> Callable[[Union[float, int, "vtkAlgorithm"], str], float]: """ To use this closure, do something like this: UpdateProgress = ShowProgress(NUM_FILTERS) UpdateProgress(vtkObject) """ - progress = [0] - last_obj_progress = [0] + progress: List[float] = [0] + last_obj_progress: List[float] = [0] if dialog_type == "ProgressDialog": try: dlg = ProgressDialog(wx.GetApp().GetTopWindow(), 100) - except (wx._core.PyNoAppError, AttributeError): + except (wx.PyNoAppError, AttributeError): return lambda obj, label: 0 # when the pipeline is larger than 1, we have to consider this object @@ -114,7 +123,7 @@ def ShowProgress(number_of_filters=1, dialog_type="GaugeProgress"): number_of_filters = max(number_of_filters, 1) ratio = 100.0 / number_of_filters - def UpdateProgress(obj, label=""): + def UpdateProgress(obj: Union[float, int, "vtkAlgorithm"], label: str = "") -> float: """ Show progress on GUI according to pipeline execution. """ @@ -152,9 +161,9 @@ def UpdateProgress(obj, label=""): return UpdateProgress -class Text(object): +class Text: def __init__(self): - self.layer = 99 + self.layer: int = 99 self.children = [] property = vtkTextProperty() property.SetFontSize(const.TEXT_SIZE) @@ -179,19 +188,19 @@ def __init__(self): self.SetPosition(const.TEXT_POS_LEFT_UP) - def SetColour(self, colour): + def SetColour(self, colour: Sequence[float]) -> None: self.property.SetColor(colour) - def ShadowOff(self): + def ShadowOff(self) -> None: self.property.ShadowOff() - def BoldOn(self): + def BoldOn(self) -> None: self.property.BoldOn() - def SetSize(self, size): + def SetSize(self, size: int) -> None: self.property.SetFontSize(size) - def SetValue(self, value): + def SetValue(self, value: Union[int, float, str]) -> None: if isinstance(value, int) or isinstance(value, float): value = str(value) if sys.platform == "win32": @@ -207,13 +216,13 @@ def SetValue(self, value): except UnicodeEncodeError: self.mapper.SetInput(value.encode("utf-8", errors="replace")) - def GetValue(self): + def GetValue(self) -> str: return self.mapper.GetInput() - def SetCoilDistanceValue(self, value): + def SetCoilDistanceValue(self, value: Union[int, float, str]) -> None: # TODO: Not being used anymore. Can be deleted. if isinstance(value, int) or isinstance(value, float): - value = "Dist: " + str("{:06.2f}".format(value)) + " mm" + value = "Dist: " + str(f"{value:06.2f}") + " mm" if sys.platform == "win32": value += "" # Otherwise 0 is not shown under win32 # With some encoding in some dicom fields (like name) raises a @@ -228,35 +237,35 @@ def SetCoilDistanceValue(self, value): except UnicodeEncodeError: self.mapper.SetInput(value.encode("utf-8")) - def SetPosition(self, position): + def SetPosition(self, position: Tuple[float, float]) -> None: self.actor.GetPositionCoordinate().SetValue(position[0], position[1]) - def GetPosition(self, position): - self.actor.GetPositionCoordinate().GetValue() + def GetPosition(self) -> Tuple[float, float, float]: + return self.actor.GetPositionCoordinate().GetValue() - def SetJustificationToRight(self): + def SetJustificationToRight(self) -> None: self.property.SetJustificationToRight() - def SetJustificationToCentered(self): + def SetJustificationToCentered(self) -> None: self.property.SetJustificationToCentered() - def SetVerticalJustificationToBottom(self): + def SetVerticalJustificationToBottom(self) -> None: self.property.SetVerticalJustificationToBottom() - def SetVerticalJustificationToCentered(self): + def SetVerticalJustificationToCentered(self) -> None: self.property.SetVerticalJustificationToCentered() - def Show(self, value=1): + def Show(self, value: bool = True) -> None: if value: self.actor.VisibilityOn() else: self.actor.VisibilityOff() - def Hide(self): + def Hide(self) -> None: self.actor.VisibilityOff() -class TextZero(object): +class TextZero: def __init__(self): self.layer = 99 self.children = [] @@ -283,20 +292,20 @@ def __init__(self): self.bottom_pos = False self.right_pos = False - def SetColour(self, colour): + def SetColour(self, colour: Sequence[float]) -> None: self.property.SetColor(colour) - def ShadowOff(self): + def ShadowOff(self) -> None: self.property.ShadowOff() - def SetSize(self, size): + def SetSize(self, size: int) -> None: self.property.SetFontSize(size) self.actor.GetTextProperty().ShallowCopy(self.property) - def SetSymbolicSize(self, size): + def SetSymbolicSize(self, size: int) -> None: self.symbolic_syze = size - def SetValue(self, value): + def SetValue(self, value: Union[int, float, str]) -> None: if isinstance(value, int) or isinstance(value, float): value = str(value) if sys.platform == "win32": @@ -311,35 +320,35 @@ def SetValue(self, value): self.text = value - def SetPosition(self, position): + def SetPosition(self, position: Tuple[float, float]) -> None: self.position = position self.actor.GetPositionCoordinate().SetValue(position[0], position[1]) - def GetPosition(self): + def GetPosition(self) -> Tuple[float, float, float]: return self.actor.GetPositionCoordinate().GetValue() - def SetJustificationToRight(self): + def SetJustificationToRight(self) -> None: self.property.SetJustificationToRight() - def SetJustificationToCentered(self): + def SetJustificationToCentered(self) -> None: self.property.SetJustificationToCentered() - def SetVerticalJustificationToBottom(self): + def SetVerticalJustificationToBottom(self) -> None: self.property.SetVerticalJustificationToBottom() - def SetVerticalJustificationToCentered(self): + def SetVerticalJustificationToCentered(self) -> None: self.property.SetVerticalJustificationToCentered() - def Show(self, value=1): + def Show(self, value: bool = True) -> None: if value: self.actor.VisibilityOn() else: self.actor.VisibilityOff() - def Hide(self): + def Hide(self) -> None: self.actor.VisibilityOff() - def draw_to_canvas(self, gc, canvas): + def draw_to_canvas(self, gc: wx.GraphicsContext, canvas: "CanvasRendererCTX") -> None: coord = vtkCoordinate() coord.SetCoordinateSystemToNormalizedDisplay() coord.SetValue(*self.position) @@ -356,7 +365,7 @@ def draw_to_canvas(self, gc, canvas): canvas.draw_text(self.text, (x, y), font=font) -def numpy_to_vtkMatrix4x4(affine): +def numpy_to_vtkMatrix4x4(affine: "np.ndarray") -> vtkMatrix4x4: """ Convert a numpy 4x4 array to a vtk 4x4 matrix :param affine: 4x4 array @@ -375,7 +384,7 @@ def numpy_to_vtkMatrix4x4(affine): # TODO: Use the SurfaceManager >> CreateSurfaceFromFile inside surface.py method instead of duplicating code -def CreateObjectPolyData(filename): +def CreateObjectPolyData(filename: str) -> Any: """ Coil for navigation rendered in volume viewer. """ diff --git a/invesalius/data/watershed_process.py b/invesalius/data/watershed_process.py index 180b36d57..1fe79f4a2 100644 --- a/invesalius/data/watershed_process.py +++ b/invesalius/data/watershed_process.py @@ -1,26 +1,34 @@ +from typing import TYPE_CHECKING, Tuple + import numpy as np from scipy import ndimage -from scipy.ndimage import generate_binary_structure, watershed_ift +from scipy.ndimage import watershed_ift + +from invesalius.data.imagedata_utils import get_LUT_value try: from skimage.segmentation import watershed except ImportError: from skimage.morphology import watershed - -def get_LUT_value(data, window, level): - shape = data.shape - data_ = data.ravel() - data = np.piecewise( - data_, - [data_ <= (level - 0.5 - (window - 1) / 2), data_ > (level - 0.5 + (window - 1) / 2)], - [0, window, lambda data_: ((data_ - (level - 0.5)) / (window - 1) + 0.5) * (window)], - ) - data.shape = shape - return data +if TYPE_CHECKING: + import os + from multiprocessing import Queue -def do_watershed(image, markers, tfile, shape, bstruct, algorithm, mg_size, use_ww_wl, wl, ww, q): +def do_watershed( + image: np.ndarray, + markers: np.ndarray, + tfile: "str | bytes | os.PathLike[str]", + shape: "int | tuple[int, ...] | None", + bstruct: "int | np.ndarray | None", + algorithm: str, + mg_size: Tuple[int, ...], + use_ww_wl: bool, + wl: int, + ww: int, + q: "Queue[int]", +) -> None: mask = np.memmap(tfile, shape=shape, dtype="uint8", mode="r+") if use_ww_wl: diff --git a/invesalius/expanduser.py b/invesalius/expanduser.py deleted file mode 100644 index 100e077f3..000000000 --- a/invesalius/expanduser.py +++ /dev/null @@ -1,60 +0,0 @@ -#!/usr/bin/python -# -*- coding: utf-8 -*- -# From http://bugs.python.org/file23442/expanduser.py - -import ctypes -from ctypes import windll, wintypes - - -class GUID(ctypes.Structure): - _fields_ = [ - ("Data1", wintypes.DWORD), - ("Data2", wintypes.WORD), - ("Data3", wintypes.WORD), - ("Data4", wintypes.BYTE * 8), - ] - - def __init__(self, l, w1, w2, b1, b2, b3, b4, b5, b6, b7, b8): - """Create a new GUID.""" - self.Data1 = l - self.Data2 = w1 - self.Data3 = w2 - self.Data4[:] = (b1, b2, b3, b4, b5, b6, b7, b8) - - def __repr__(self): - b1, b2, b3, b4, b5, b6, b7, b8 = self.Data4 - return "GUID(%x-%x-%x-%x%x%x%x%x%x%x%x)" % ( - self.Data1, - self.Data2, - self.Data3, - b1, - b2, - b3, - b4, - b5, - b6, - b7, - b8, - ) - - -# constants to be used according to the version on shell32 -CSIDL_PROFILE = 40 -FOLDERID_Profile = GUID(0x5E6C858F, 0x0E22, 0x4760, 0x9A, 0xFE, 0xEA, 0x33, 0x17, 0xB6, 0x71, 0x73) - - -def expand_user(): - # get the function that we can find from Vista up, not the one in XP - get_folder_path = getattr(windll.shell32, "SHGetKnownFolderPath", None) - # import pdb; pdb.set_trace() - if get_folder_path is not None: - # ok, we can use the new function which is recomended by the msdn - ptr = ctypes.c_wchar_p() - get_folder_path(ctypes.byref(FOLDERID_Profile), 0, 0, ctypes.byref(ptr)) - return ptr.value - else: - # use the deprecated one found in XP and on for compatibility reasons - get_folder_path = getattr(windll.shell32, "SHGetSpecialFolderPathW", None) - buf = ctypes.create_unicode_buffer(300) - get_folder_path(None, buf, CSIDL_PROFILE, False) - return buf.value diff --git a/invesalius/gui/bitmap_preview_panel.py b/invesalius/gui/bitmap_preview_panel.py index fe4f8dd57..c76531e36 100644 --- a/invesalius/gui/bitmap_preview_panel.py +++ b/invesalius/gui/bitmap_preview_panel.py @@ -575,7 +575,7 @@ def OnRun(self): wx.Yield() # TODO: temporary fix necessary in the Windows XP 64 Bits # BUG in wxWidgets http://trac.wxwidgets.org/ticket/10896 - except wx._core.PyAssertionError: + except wx.PyAssertionError: utils.debug("wx._core.PyAssertionError") finally: wx.CallAfter(self.OnRun) diff --git a/invesalius/gui/data_notebook.py b/invesalius/gui/data_notebook.py index 86e6ad37a..491938b9a 100644 --- a/invesalius/gui/data_notebook.py +++ b/invesalius/gui/data_notebook.py @@ -310,7 +310,7 @@ def OnNew(self): ok = 1 else: ok = 0 - except wx._core.PyAssertionError: # TODO FIX: win64 + except wx.PyAssertionError: # TODO FIX: win64 ok = 1 if ok: @@ -546,7 +546,7 @@ def OnChangeCurrentMask(self, index): try: self.SetItemImage(index, 1) self.current_index = index - except wx._core.PyAssertionError: + except wx.PyAssertionError: # in SetItem(): invalid item index in SetItem pass for key in self.mask_list_index.keys(): @@ -750,7 +750,7 @@ def OnNew(self): ok = 1 else: ok = 0 - except wx._core.PyAssertionError: # TODO FIX: win64 + except wx.PyAssertionError: # TODO FIX: win64 ok = 1 if ok: diff --git a/invesalius/gui/dialogs.py b/invesalius/gui/dialogs.py index 83ce452de..a4e44207f 100644 --- a/invesalius/gui/dialogs.py +++ b/invesalius/gui/dialogs.py @@ -26,6 +26,19 @@ import time from concurrent import futures from functools import partial +from typing import ( + TYPE_CHECKING, + Any, + Dict, + Iterable, + List, + Literal, + MutableSequence, + Optional, + Sequence, + Tuple, + Union, +) if sys.platform == "win32": try: @@ -37,16 +50,10 @@ else: _has_win32api = False -import wx -from scipy.spatial import distance - -try: - from wx.adv import BitmapComboBox -except ImportError: - from wx.combo import BitmapComboBox - import csv +import numpy as np +import wx import wx.lib.filebrowsebutton as filebrowse from vtkmodules.vtkCommonColor import vtkNamedColors from vtkmodules.vtkCommonComputationalGeometry import vtkParametricTorus @@ -82,18 +89,10 @@ ) from vtkmodules.vtkRenderingFreeType import vtkVectorText from vtkmodules.wx.wxVTKRenderWindowInteractor import wxVTKRenderWindowInteractor +from wx.adv import AboutBox, AboutDialogInfo, BitmapComboBox from wx.lib import masked from wx.lib.wordwrap import wordwrap -from invesalius.pubsub import pub as Publisher - -try: - from wx.adv import AboutBox, AboutDialogInfo -except ImportError: - from wx import AboutBox, AboutDialogInfo - -import numpy as np - import invesalius.constants as const import invesalius.data.coordinates as dco import invesalius.data.coregistration as dcr @@ -109,10 +108,29 @@ from invesalius.gui.widgets.inv_spinctrl import InvFloatSpinCtrl, InvSpinCtrl from invesalius.i18n import tr as _ from invesalius.math_utils import inner1d +from invesalius.pubsub import pub as Publisher + +if TYPE_CHECKING: + from invesalius.data.mask import Mask + from invesalius.data.styles import ( + CropMaskConfig, + FFillConfig, + FFillSegmentationConfig, + SelectPartConfig, + WatershedConfig, + ) + from invesalius.gui.widgets.clut_imagedata import CLUTEvent, Node + from invesalius.navigation.mtms import mTMS + from invesalius.navigation.navigation import Navigation + from invesalius.navigation.robot import Robot + from invesalius.navigation.tracker import Tracker + from invesalius.net.neuronavigation_api import NeuronavigationApi + from invesalius.net.pedal_connection import PedalConnector + from typings.wx.type_defs import ColourType # type: ignore class MaskEvent(wx.PyCommandEvent): - def __init__(self, evtType, id, mask_index): + def __init__(self, evtType: int, id: int, mask_index: int): wx.PyCommandEvent.__init__( self, evtType, @@ -126,7 +144,7 @@ def __init__(self, evtType, id, mask_index): class NumberDialog(wx.Dialog): - def __init__(self, message, value=0): + def __init__(self, message: str, value: int = 0): wx.Dialog.__init__( self, None, @@ -174,10 +192,10 @@ def __init__(self, message, value=0): self.Centre() - def SetValue(self, value): + def SetValue(self, value: int) -> None: self.num_ctrl.SetValue(value) - def GetValue(self): + def GetValue(self) -> Union[int, float, None]: return self.num_ctrl.GetValue() @@ -237,17 +255,17 @@ def __init__(self): # , message, value=0): self.Layout() self.Centre() - def SetValue(self, value): + def SetValue(self, value: Union[float, str]) -> None: self.num_ctrl_porcent.SetValue(value) - def GetValue(self): + def GetValue(self) -> int: return self.num_ctrl_porcent.GetValue() - def Close(self): + def Close(self) -> None: self.Destroy() -def ShowNumberDialog(message, value=0): +def ShowNumberDialog(message: str, value: int = 0) -> Union[int, float, None]: dlg = NumberDialog(message, value) dlg.SetValue(value) @@ -287,7 +305,7 @@ def ShowNumberDialog(message, value=0): WILDCARD_JSON_FILES = "JSON File format (*.json|*.json|" "All files (*.*)|*.*" -def ShowOpenProjectDialog(): +def ShowOpenProjectDialog() -> Union[str, None]: # Default system path current_dir = os.path.abspath(".") session = ses.Session() @@ -311,7 +329,7 @@ def ShowOpenProjectDialog(): if dlg.ShowModal() == wx.ID_OK: # This returns a Python list of files that were selected. filepath = dlg.GetPath() - except wx._core.PyAssertionError: # FIX: win64 + except wx.PyAssertionError: # FIX: win64 filepath = dlg.GetPath() if filepath: @@ -325,7 +343,7 @@ def ShowOpenProjectDialog(): return filepath -def ShowImportDirDialog(self): +def ShowImportDirDialog(self) -> Union[str, bytes, None]: current_dir = os.path.abspath(".") if sys.platform == "win32" or sys.platform.startswith("linux"): @@ -351,7 +369,7 @@ def ShowImportDirDialog(self): else: path = dlg.GetPath().encode("utf-8") - except wx._core.PyAssertionError: # TODO: error win64 + except wx.PyAssertionError: # TODO: error win64 if dlg.GetPath(): path = dlg.GetPath() @@ -366,7 +384,7 @@ def ShowImportDirDialog(self): return path -def ShowImportBitmapDirDialog(self): +def ShowImportBitmapDirDialog(self) -> Optional[str]: current_dir = os.path.abspath(".") session = ses.Session() @@ -386,7 +404,7 @@ def ShowImportBitmapDirDialog(self): # UnicodeEncodeError is raised. To avoid this, path is encoded in utf-8 path = dlg.GetPath() - except wx._core.PyAssertionError: # TODO: error win64 + except wx.PyAssertionError: # TODO: error win64 if dlg.GetPath(): path = dlg.GetPath() @@ -399,7 +417,9 @@ def ShowImportBitmapDirDialog(self): return path -def ShowImportOtherFilesDialog(id_type, msg="Import NIFTi 1 file"): +def ShowImportOtherFilesDialog( + id_type: wx.WindowIDRef, msg: str = "Import NIFTi 1 file" +) -> Union[str, bytes, None]: # Default system path session = ses.Session() last_directory = session.GetConfig("last_directory_%d" % id_type, "") @@ -449,7 +469,7 @@ def ShowImportOtherFilesDialog(id_type, msg="Import NIFTi 1 file"): else: filename = dlg.GetPath().encode("utf-8") - except wx._core.PyAssertionError: # TODO: error win64 + except wx.PyAssertionError: # TODO: error win64 if dlg.GetPath(): filename = dlg.GetPath() @@ -463,7 +483,7 @@ def ShowImportOtherFilesDialog(id_type, msg="Import NIFTi 1 file"): return filename -def ShowImportMeshFilesDialog(): +def ShowImportMeshFilesDialog() -> Optional[str]: from invesalius.data.slice_ import Slice # Default system path @@ -510,7 +530,7 @@ def ShowImportMeshFilesDialog(): convert_to_inv = conversion_radio_box.GetSelection() == const.SURFACE_SPACE_WORLD Publisher.sendMessage("Update convert_to_inv flag", convert_to_inv=convert_to_inv) - except wx._core.PyAssertionError: # TODO: error win64 + except wx.PyAssertionError: # TODO: error win64 if dlg.GetPath(): filename = dlg.GetPath() @@ -524,7 +544,7 @@ def ShowImportMeshFilesDialog(): return filename -def ImportMeshCoordSystem(): +def ImportMeshCoordSystem() -> bool: msg = _("Was the imported mesh created by InVesalius?") if sys.platform == "darwin": dlg = wx.MessageDialog(None, "", msg, wx.YES_NO) @@ -540,7 +560,7 @@ def ImportMeshCoordSystem(): return flag -def ShowSaveAsProjectDialog(default_filename=None): +def ShowSaveAsProjectDialog(default_filename: str) -> Tuple[Optional[str], bool]: current_dir = os.path.abspath(".") session = ses.Session() @@ -560,14 +580,10 @@ def ShowSaveAsProjectDialog(default_filename=None): try: if dlg.ShowModal() == wx.ID_OK: filename = dlg.GetPath() - ok = 1 - else: - ok = 0 - except wx._core.PyAssertionError: # TODO: fix win64 + except wx.PyAssertionError: # TODO: fix win64 filename = dlg.GetPath() - ok = 1 - if ok: + if filename is not None: extension = "inv3" if sys.platform != "win32": if filename.split(".")[-1] != extension: @@ -583,12 +599,12 @@ def ShowSaveAsProjectDialog(default_filename=None): def ShowLoadCSVDebugEfield( - message=_("Load debug CSV Enorm file"), - current_dir=os.path.abspath("."), - style=wx.FD_OPEN | wx.FD_CHANGE_DIR, - wildcard=_("(*.csv)|*.csv"), - default_filename="", -): + message: str = _("Load debug CSV Enorm file"), + current_dir: "str | bytes | os.PathLike[str]" = os.path.abspath("."), + style: int = wx.FD_OPEN | wx.FD_CHANGE_DIR, + wildcard: str = _("(*.csv)|*.csv"), + default_filename: str = "", +) -> Optional[np.ndarray]: dlg = wx.FileDialog( None, message=message, @@ -610,7 +626,7 @@ def ShowLoadCSVDebugEfield( else: filepath = dlg.GetPath().encode("utf-8") - except wx._core.PyAssertionError: # TODO: error win64 + except wx.PyAssertionError: # TODO: error win64 if dlg.GetPath(): filepath = dlg.GetPath() @@ -619,7 +635,7 @@ def ShowLoadCSVDebugEfield( dlg.Destroy() os.chdir(current_dir) if filepath: - with open(filepath, "r") as file: + with open(filepath) as file: my_reader = csv.reader(file, delimiter=",") rows = [] for row in my_reader: @@ -633,13 +649,13 @@ def ShowLoadCSVDebugEfield( def ShowLoadSaveDialog( - message=_("Load File"), - current_dir=os.path.abspath("."), - style=wx.FD_OPEN | wx.FD_CHANGE_DIR, - wildcard=_("Registration files (*.obr)|*.obr"), - default_filename="", - save_ext=None, -): + message: str = _("Load File"), + current_dir: "str | bytes | os.PathLike[str]" = os.path.abspath("."), + style: int = wx.FD_OPEN | wx.FD_CHANGE_DIR, + wildcard: str = _("Registration files (*.obr)|*.obr"), + default_filename: str = "", + save_ext: Optional[str] = None, +) -> Optional[str]: dlg = wx.FileDialog( None, message=message, @@ -657,15 +673,11 @@ def ShowLoadSaveDialog( if dlg.ShowModal() == wx.ID_OK: # This returns a Python list of files that were selected. filepath = dlg.GetPath() - ok_press = 1 - else: - ok_press = 0 - except wx._core.PyAssertionError: # FIX: win64 + except wx.PyAssertionError: # FIX: win64 filepath = dlg.GetPath() - ok_press = 1 # Change the extension if it was set to a value different than expected. - if save_ext and ok_press: + if save_ext and filepath is not None: extension = save_ext if sys.platform != "win32": if filepath.split(".")[-1] != extension: @@ -679,7 +691,7 @@ def ShowLoadSaveDialog( return filepath -def LoadConfigEfield(): +def LoadConfigEfield() -> Optional[str]: # Default system path current_dir = os.path.abspath(".") @@ -704,7 +716,7 @@ def LoadConfigEfield(): if dlg.ShowModal() == wx.ID_OK: filename = dlg.GetPath() - except wx._core.PyAssertionError: # TODO: error win64 + except wx.PyAssertionError: # TODO: error win64 if dlg.GetPath(): filename = dlg.GetPath() @@ -719,7 +731,7 @@ def LoadConfigEfield(): class MessageDialog(wx.Dialog): - def __init__(self, message): + def __init__(self, message: str): wx.Dialog.__init__( self, None, @@ -760,7 +772,7 @@ def __init__(self, message): class UpdateMessageDialog(wx.Dialog): - def __init__(self, url): + def __init__(self, url: str): msg = _( "A new version of InVesalius is available. Do you want to open the download website now?" ) @@ -806,26 +818,28 @@ def __init__(self, url): # Subscribing to the pubsub event which happens when InVesalius is closed. Publisher.subscribe(self._Exit, "Exit") - def _OnYes(self, evt): + def _OnYes(self, evt: wx.CommandEvent) -> None: # Launches the default browser with the url to download the new # InVesalius version. wx.LaunchDefaultBrowser(self.url) self.Close() self.Destroy() - def _OnNo(self, evt): + def _OnNo(self, evt: wx.CommandEvent) -> None: # Closes and destroy this dialog. self.Close() self.Destroy() - def _Exit(self): + def _Exit(self) -> None: # Closes and destroy this dialog. self.Close() self.Destroy() class MessageBox(wx.Dialog): - def __init__(self, parent, title, message, caption="InVesalius3 Error"): + def __init__( + self, parent: wx.Window, title: str, message: str, caption: str = "InVesalius3 Error" + ): wx.Dialog.__init__( self, parent, title=caption, style=wx.DEFAULT_DIALOG_STYLE | wx.RESIZE_BORDER ) @@ -855,7 +869,9 @@ def __init__(self, parent, title, message, caption="InVesalius3 Error"): class ErrorMessageBox(wx.Dialog): - def __init__(self, parent, title, message, caption="InVesalius3 Error"): + def __init__( + self, parent: wx.Window, title: str, message: str, caption: str = "InVesalius3 Error" + ): wx.Dialog.__init__( self, parent, title=caption, style=wx.DEFAULT_DIALOG_STYLE | wx.RESIZE_BORDER ) @@ -893,7 +909,7 @@ def __init__(self, parent, title, message, caption="InVesalius3 Error"): self.Center() -def SaveChangesDialog__Old(filename): +def SaveChangesDialog__Old(filename: str) -> Literal[-1, 0, 1]: message = _("The project %s has been modified.\nSave changes?") % filename dlg = MessageDialog(message) @@ -907,7 +923,7 @@ def SaveChangesDialog__Old(filename): return -1 -def ImportEmptyDirectory(dirpath): +def ImportEmptyDirectory(dirpath: bytes) -> None: msg = _("%s is an empty folder.") % dirpath.decode("utf-8") if sys.platform == "darwin": dlg = wx.MessageDialog(None, "", msg, wx.ICON_INFORMATION | wx.OK) @@ -917,7 +933,7 @@ def ImportEmptyDirectory(dirpath): dlg.Destroy() -def ImportOldFormatInvFile(): +def ImportOldFormatInvFile() -> None: msg = _( "File was created in a newer InVesalius version. Some functionalities may not work correctly." ) @@ -926,7 +942,7 @@ def ImportOldFormatInvFile(): dlg.Destroy() -def ImportInvalidFiles(ftype="DICOM"): +def ImportInvalidFiles(ftype: str = "DICOM") -> None: if ftype == "Bitmap": msg = _("There are no Bitmap, JPEG, PNG or TIFF files in the selected folder.") elif ftype == "DICOM": @@ -942,7 +958,7 @@ def ImportInvalidFiles(ftype="DICOM"): dlg.Destroy() -def WarningRescalePixelValues(): +def WarningRescalePixelValues() -> None: msg1 = _("Warning! Pixel values are smaller than 8 (possible float values).\n") msg2 = _("Pixel values have been rescaled from 0-255 for compatibility.") if sys.platform == "darwin": @@ -953,7 +969,7 @@ def WarningRescalePixelValues(): dlg.Destroy() -def ImagePixelRescaling(): +def ImagePixelRescaling() -> None: msg1 = _("Warning! InVesalius has limited support to Analyze format.\n") msg2 = _("Slices may be wrongly oriented and functions may not work properly.") if sys.platform == "darwin": @@ -964,7 +980,7 @@ def ImagePixelRescaling(): dlg.Destroy() -def InexistentMask(): +def InexistentMask() -> None: msg = _("A mask is needed to create a surface.") if sys.platform == "darwin": dlg = wx.MessageDialog(None, "", msg, wx.ICON_INFORMATION | wx.OK) @@ -974,7 +990,7 @@ def InexistentMask(): dlg.Destroy() -def MaskSelectionRequiredForRemoval(): +def MaskSelectionRequiredForRemoval() -> None: msg = _("No mask was selected for removal.") if sys.platform == "darwin": dlg = wx.MessageDialog(None, "", msg, wx.ICON_INFORMATION | wx.OK) @@ -984,7 +1000,7 @@ def MaskSelectionRequiredForRemoval(): dlg.Destroy() -def SurfaceSelectionRequiredForRemoval(): +def SurfaceSelectionRequiredForRemoval() -> None: msg = _("No surface was selected for removal.") if sys.platform == "darwin": dlg = wx.MessageDialog(None, "", msg, wx.ICON_INFORMATION | wx.OK) @@ -994,7 +1010,7 @@ def SurfaceSelectionRequiredForRemoval(): dlg.Destroy() -def MeasureSelectionRequiredForRemoval(): +def MeasureSelectionRequiredForRemoval() -> None: msg = _("No measure was selected for removal.") if sys.platform == "darwin": dlg = wx.MessageDialog(None, "", msg, wx.ICON_INFORMATION | wx.OK) @@ -1004,7 +1020,7 @@ def MeasureSelectionRequiredForRemoval(): dlg.Destroy() -def MaskSelectionRequiredForDuplication(): +def MaskSelectionRequiredForDuplication() -> None: msg = _("No mask was selected for duplication.") if sys.platform == "darwin": dlg = wx.MessageDialog(None, "", msg, wx.ICON_INFORMATION | wx.OK) @@ -1014,7 +1030,7 @@ def MaskSelectionRequiredForDuplication(): dlg.Destroy() -def SurfaceSelectionRequiredForDuplication(): +def SurfaceSelectionRequiredForDuplication() -> None: msg = _("No surface was selected for duplication.") if sys.platform == "darwin": dlg = wx.MessageDialog(None, "", msg, wx.ICON_INFORMATION | wx.OK) @@ -1028,7 +1044,7 @@ def SurfaceSelectionRequiredForDuplication(): # ---------------------------------- -def ShowNavigationTrackerWarning(trck_id, lib_mode): +def ShowNavigationTrackerWarning(trck_id: int, lib_mode: str) -> None: """ Spatial Tracker connection error """ @@ -1072,7 +1088,7 @@ def ShowNavigationTrackerWarning(trck_id, lib_mode): dlg.Destroy() -def Efield_connection_warning(): +def Efield_connection_warning() -> None: msg = _("No connection to E-field library") if sys.platform == "darwin": dlg = wx.MessageDialog(None, "", msg, wx.ICON_INFORMATION | wx.OK) @@ -1084,7 +1100,7 @@ def Efield_connection_warning(): dlg.Destroy() -def Efield_no_data_to_save_warning(): +def Efield_no_data_to_save_warning() -> None: msg = _("No Efield data to save") if sys.platform == "darwin": dlg = wx.MessageDialog(None, "", msg, wx.ICON_INFORMATION | wx.OK) @@ -1096,7 +1112,7 @@ def Efield_no_data_to_save_warning(): dlg.Destroy() -def Efield_debug_Enorm_warning(): +def Efield_debug_Enorm_warning() -> None: msg = _("The CSV Enorm file is not loaded.") if sys.platform == "darwin": dlg = wx.MessageDialog(None, "", msg, wx.ICON_INFORMATION | wx.OK) @@ -1108,7 +1124,7 @@ def Efield_debug_Enorm_warning(): dlg.Destroy() -def ICPcorregistration(fre): +def ICPcorregistration(fre: float) -> bool: msg = ( _("The fiducial registration error is: ") + str(round(fre, 2)) @@ -1129,7 +1145,7 @@ def ICPcorregistration(fre): return flag -def ReportICPerror(prev_error, final_error): +def ReportICPerror(prev_error: float, final_error: float) -> None: msg = ( _("Points to scalp distance: ") + str(round(final_error, 2)) @@ -1147,7 +1163,7 @@ def ReportICPerror(prev_error, final_error): dlg.Destroy() -def ReportICPPointError(): +def ReportICPPointError() -> None: msg = ( _("The last point is more than 20 mm away from the surface") + "\n\n" @@ -1161,7 +1177,7 @@ def ReportICPPointError(): dlg.Destroy() -def ReportICPDistributionError(): +def ReportICPDistributionError() -> None: msg = ( _("The distribution of the transformed points looks wrong.") + "\n\n" @@ -1175,7 +1191,7 @@ def ReportICPDistributionError(): dlg.Destroy() -def ShowEnterMarkerID(default): +def ShowEnterMarkerID(default: str) -> str: msg = _("Change label") dlg = wx.TextEntryDialog(None, msg, "InVesalius 3", value=default) dlg.ShowModal() @@ -1185,7 +1201,7 @@ def ShowEnterMarkerID(default): return result -def ShowConfirmationDialog(msg=_("Proceed?")): +def ShowConfirmationDialog(msg: str = _("Proceed?")) -> int: # msg = _("Do you want to delete all markers?") if sys.platform == "darwin": dlg = wx.MessageDialog(None, "", msg, wx.OK | wx.CANCEL | wx.ICON_QUESTION) @@ -1196,7 +1212,9 @@ def ShowConfirmationDialog(msg=_("Proceed?")): return result -def ShowColorDialog(color_current): +def ShowColorDialog( + color_current: "ColourType", +) -> Optional[Tuple[int, int, int]]: cdata = wx.ColourData() cdata.SetColour(wx.Colour(color_current)) dlg = wx.ColourDialog(None, data=cdata) @@ -1217,13 +1235,13 @@ def ShowColorDialog(color_current): class NewMask(wx.Dialog): def __init__( self, - parent=None, - ID=-1, - title="InVesalius 3", - size=wx.DefaultSize, - pos=wx.DefaultPosition, - style=wx.DEFAULT_DIALOG_STYLE, - useMetal=False, + parent: Optional[wx.Window] = None, + ID: int = -1, + title: str = "InVesalius 3", + size: wx.Size = wx.DefaultSize, + pos: wx.Point = wx.DefaultPosition, + style: int = wx.DEFAULT_DIALOG_STYLE, + useMetal: bool = False, ): import invesalius.constants as const import invesalius.data.mask as mask @@ -1325,7 +1343,7 @@ def __init__( self.Bind(grad.EVT_THRESHOLD_CHANGED, self.OnSlideChanged, self.gradient) self.combo_thresh.Bind(wx.EVT_COMBOBOX, self.OnComboThresh) - def OnComboThresh(self, evt): + def OnComboThresh(self, evt: wx.CommandEvent) -> None: import invesalius.project as prj proj = prj.Project() @@ -1333,7 +1351,7 @@ def OnComboThresh(self, evt): self.gradient.SetMinValue(thresh_min) self.gradient.SetMaxValue(thresh_max) - def OnSlideChanged(self, evt): + def OnSlideChanged(self, evt: wx.Event) -> None: import invesalius.project as prj thresh_min = self.gradient.GetMinValue() @@ -1348,7 +1366,7 @@ def OnSlideChanged(self, evt): index = self.thresh_list.index(_("Custom")) self.combo_thresh.SetSelection(index) - def GetValue(self): + def GetValue(self) -> Tuple[str, List[int], List[float]]: # mask_index = self.combo_mask.GetSelection() mask_name = self.text.GetValue() thresh_value = [self.gradient.GetMinValue(), self.gradient.GetMaxValue()] @@ -1359,7 +1377,7 @@ def GetValue(self): return mask_name, thresh_value, self.colour -def InexistentPath(path): +def InexistentPath(path: "str | bytes | os.PathLike[str]") -> None: msg = _("%s does not exist.") % (path) if sys.platform == "darwin": dlg = wx.MessageDialog(None, "", msg, wx.ICON_INFORMATION | wx.OK) @@ -1369,7 +1387,7 @@ def InexistentPath(path): dlg.Destroy() -def MissingFilesForReconstruction(): +def MissingFilesForReconstruction() -> None: msg = _("Please, provide more than one DICOM file for 3D reconstruction") if sys.platform == "darwin": dlg = wx.MessageDialog(None, "", msg, wx.ICON_INFORMATION | wx.OK) @@ -1379,7 +1397,7 @@ def MissingFilesForReconstruction(): dlg.Destroy() -def SaveChangesDialog(filename, parent): +def SaveChangesDialog(filename: "str | bytes | os.PathLike[str]", parent) -> Literal[-1, 0, 1]: current_dir = os.path.abspath(".") msg = _("The project %s has been modified.\nSave changes?") % filename if sys.platform == "darwin": @@ -1389,7 +1407,7 @@ def SaveChangesDialog(filename, parent): try: answer = dlg.ShowModal() - except wx._core.PyAssertionError: # TODO: FIX win64 + except wx.PyAssertionError: # TODO: FIX win64 answer = wx.ID_YES dlg.Destroy() @@ -1403,7 +1421,7 @@ def SaveChangesDialog(filename, parent): return -1 -def SaveChangesDialog2(filename): +def SaveChangesDialog2(filename: "str | bytes | os.PathLike[str]") -> Literal[0, 1]: current_dir = os.path.abspath(".") msg = _("The project %s has been modified.\nSave changes?") % filename if sys.platform == "darwin": @@ -1420,14 +1438,16 @@ def SaveChangesDialog2(filename): return 0 -def ShowAboutDialog(parent): +def ShowAboutDialog(parent: wx.Window) -> None: info = AboutDialogInfo() info.Name = "InVesalius" info.Version = const.INVESALIUS_VERSION - + year = datetime.date.today().year - info.Copyright = _("(c) 2007-"+ str(year) + " Center for Information Technology Renato Archer - CTI") + info.Copyright = _( + "(c) 2007-" + str(year) + " Center for Information Technology Renato Archer - CTI" + ) info.Description = wordwrap( _( "InVesalius is a medical imaging program for 3D reconstruction. It uses a sequence of 2D DICOM image files acquired with CT or MRI scanners. InVesalius allows exporting 3D volumes or surfaces as mesh files for creating physical models of a patient's anatomy using additive manufacturing (3D printing) technologies. The software is developed by Center for Information Technology Renato Archer (CTI), National Council for Scientific and Technological Development (CNPq) and the Brazilian Ministry of Health.\n\n InVesalius must be used only for research. The Center for Information Technology Renato Archer is not responsible for damages caused by the use of this software.\n\n Contact: invesalius@cti.gov.br" @@ -1506,14 +1526,14 @@ def ShowAboutDialog(parent): AboutBox(info) -def ShowSavePresetDialog(default_filename="raycasting"): +def ShowSavePresetDialog(default_filename: str = "raycasting") -> Optional[str]: dlg = wx.TextEntryDialog(None, _("Save raycasting preset as:"), "InVesalius 3") # dlg.SetFilterIndex(0) # default is VTI filename = None try: if dlg.ShowModal() == wx.ID_OK: filename = dlg.GetValue() - except wx._core.PyAssertionError: + except wx.PyAssertionError: filename = dlg.GetValue() return filename @@ -1522,13 +1542,13 @@ def ShowSavePresetDialog(default_filename="raycasting"): class NewSurfaceDialog(wx.Dialog): def __init__( self, - parent=None, - ID=-1, - title="InVesalius 3", - size=wx.DefaultSize, - pos=wx.DefaultPosition, - style=wx.DEFAULT_DIALOG_STYLE, - useMetal=False, + parent: Optional[wx.Window] = None, + ID: int = -1, + title: str = "InVesalius 3", + size: wx.Size = wx.DefaultSize, + pos: wx.Point = wx.DefaultPosition, + style: int = wx.DEFAULT_DIALOG_STYLE, + useMetal: bool = False, ): import invesalius.constants as const import invesalius.data.surface as surface @@ -1632,7 +1652,7 @@ def __init__( self.SetSizer(sizer) sizer.Fit(self) - def GetValue(self): + def GetValue(self) -> Tuple[int, str, str, bool, bool]: mask_index = self.combo_mask.GetSelection() surface_name = self.text.GetValue() quality = const.SURFACE_QUALITY_LIST[self.combo_quality.GetSelection()] @@ -1641,7 +1661,7 @@ def GetValue(self): return (mask_index, surface_name, quality, fill_holes, keep_largest) -def ExportPicture(type_=""): +def ExportPicture(type_: str = "") -> Union[Tuple[str, wx.WindowIDRef], Tuple[()]]: import invesalius.constants as const import invesalius.project as proj @@ -1676,13 +1696,13 @@ def ExportPicture(type_=""): session = ses.Session() last_directory = session.GetConfig("last_directory_screenshot", "") - project_name = "%s_%s" % (project.name, type_) - if not sys.platform in ("win32", "linux2", "linux"): + project_name = f"{project.name}_{type_}" + if sys.platform not in ("win32", "linux2", "linux"): project_name += ".jpg" dlg = wx.FileDialog( None, - "Save %s picture as..." % type_, + f"Save {type_} picture as...", last_directory, # last used directory project_name, # filename WILDCARD_SAVE_PICTURE, @@ -1720,7 +1740,7 @@ def __init__(self): self._build_widgets() self.CenterOnScreen() - def _build_widgets(self): + def _build_widgets(self) -> None: btn_ok = wx.Button(self, wx.ID_OK) btn_cancel = wx.Button(self, wx.ID_CANCEL) btn_sizer = wx.StdDialogButtonSizer() @@ -1737,10 +1757,10 @@ def _build_widgets(self): self.SetSizer(self.main_sizer) self.Fit() - def GetOptions(self): + def GetOptions(self) -> Dict[str, float]: return self.ca.GetOptions() - def GetAlgorithmSelected(self): + def GetAlgorithmSelected(self) -> str: return self.ca.GetAlgorithmSelected() @@ -1748,14 +1768,14 @@ def GetAlgorithmSelected(self): class SurfaceCreationDialog(wx.Dialog): def __init__( self, - parent=None, - ID=-1, - title=_("Surface creation"), - size=wx.DefaultSize, - pos=wx.DefaultPosition, - style=wx.DEFAULT_DIALOG_STYLE, - useMetal=False, - mask_edited=False, + parent: Optional[wx.Window] = None, + ID: int = -1, + title: str = _("Surface creation"), + size: wx.Size = wx.DefaultSize, + pos: wx.Point = wx.DefaultPosition, + style: int = wx.DEFAULT_DIALOG_STYLE, + useMetal: bool = False, + mask_edited: bool = False, ): wx.Dialog.__init__(self, parent, ID, title, pos, size, style) self.SetExtraStyle(wx.DIALOG_EX_CONTEXTHELP) @@ -1798,19 +1818,21 @@ def __init__( self.SetSizer(sizer) sizer.Fit(self) - def OnSetMask(self, evt): + def OnSetMask(self, evt: MaskEvent) -> None: import invesalius.project as proj mask = proj.Project().mask_dict[evt.mask_index] self.ca.mask_edited = mask.was_edited self.ca.ReloadMethodsOptions() - def GetValue(self): + def GetValue( + self, + ) -> "Dict[str, Dict[str, str | Dict[str, float]] | Dict[str, str | int | bool]]": return {"method": self.ca.GetValue(), "options": self.nsd.GetValue()} class SurfaceCreationOptionsPanel(wx.Panel): - def __init__(self, parent, ID=-1): + def __init__(self, parent: wx.Window, ID: int = -1): import invesalius.constants as const import invesalius.data.slice_ as slc import invesalius.data.surface as surface @@ -1903,11 +1925,11 @@ def __init__(self, parent, ID=-1): self.SetSizer(sizer) sizer.Fit(self) - def OnSetMask(self, evt): + def OnSetMask(self, evt: wx.CommandEvent) -> None: new_evt = MaskEvent(myEVT_MASK_SET, -1, self.combo_mask.GetSelection()) self.GetEventHandler().ProcessEvent(new_evt) - def GetValue(self): + def GetValue(self) -> Dict[str, Union[str, int, bool]]: mask_index = self.combo_mask.GetSelection() surface_name = self.text.GetValue() quality = const.SURFACE_QUALITY_LIST[self.combo_quality.GetSelection()] @@ -1926,8 +1948,10 @@ def GetValue(self): class SurfaceTransparencyDialog(wx.Dialog): - def __init__(self, parent, surface_index=0, transparency=0): - super(SurfaceTransparencyDialog, self).__init__(parent) + def __init__( + self, parent: Optional[wx.Window], surface_index: int = 0, transparency: int = 0 + ) -> None: + super().__init__(parent) self.surface_index = surface_index @@ -1967,7 +1991,7 @@ def __init__(self, parent, surface_index=0, transparency=0): self.Layout() self.CenterOnScreen() - def on_slider(self, event): + def on_slider(self, event: wx.CommandEvent) -> None: value = self.slider.GetValue() self.value_text.SetLabel(f"Surface transparency: {value}%") @@ -1975,10 +1999,10 @@ def on_slider(self, event): "Set surface transparency", surface_index=self.surface_index, transparency=value / 100.0 ) - def on_ok(self, event): + def on_ok(self, event: wx.CommandEvent) -> None: self.EndModal(wx.ID_OK) - def get_value(self): + def get_value(self) -> int: return self.slider.GetValue() @@ -1992,11 +2016,11 @@ class CAOptions(wx.Panel): Steps: The number of iterations the smoothing algorithm have to do. """ - def __init__(self, parent): + def __init__(self, parent: wx.Window): wx.Panel.__init__(self, parent, -1) self._build_widgets() - def _build_widgets(self): + def _build_widgets(self) -> None: sb = wx.StaticBox(self, -1, _("Options")) self.angle = InvFloatSpinCtrl( self, -1, value=0.7, min_value=0.0, max_value=1.0, increment=0.1, digits=1 @@ -2035,7 +2059,7 @@ class SurfaceMethodPanel(wx.Panel): `Context aware smoothing' """ - def __init__(self, parent, id, mask_edited=False): + def __init__(self, parent: wx.Window, id: int, mask_edited: bool = False): wx.Panel.__init__(self, parent, id) self.mask_edited = mask_edited @@ -2051,7 +2075,7 @@ def __init__(self, parent, id, mask_edited=False): self._build_widgets() self._bind_wx() - def _build_widgets(self): + def _build_widgets(self) -> None: self.ca_options = CAOptions(self) self.cb_types = wx.ComboBox( @@ -2092,23 +2116,20 @@ def _build_widgets(self): self.ca_options.Disable() self.method_sizer.Hide(self.bmp) - def _bind_wx(self): + def _bind_wx(self) -> None: self.cb_types.Bind(wx.EVT_COMBOBOX, self._set_cb_types) - def _set_cb_types(self, evt): + def _set_cb_types(self, evt: wx.CommandEvent) -> None: if self.alg_types[evt.GetString()] == "ca_smoothing": self.ca_options.Enable() else: self.ca_options.Disable() evt.Skip() - def GetAlgorithmSelected(self): - try: - return self.alg_types[self.cb_types.GetValue()] - except KeyError: - return self.alg_types[0] + def GetAlgorithmSelected(self) -> str: + return self.alg_types.get(self.cb_types.GetValue(), "Default") - def GetOptions(self): + def GetOptions(self) -> Dict[str, float]: if self.GetAlgorithmSelected() == "ca_smoothing": options = { "angle": self.ca_options.angle.GetValue(), @@ -2120,13 +2141,13 @@ def GetOptions(self): options = {} return options - def GetValue(self): + def GetValue(self) -> Dict[str, Union[str, Dict[str, float]]]: algorithm = self.GetAlgorithmSelected() options = self.GetOptions() return {"algorithm": algorithm, "options": options} - def ReloadMethodsOptions(self): + def ReloadMethodsOptions(self) -> None: self.cb_types.Clear() self.cb_types.AppendItems( [i for i in sorted(self.alg_types) if not (self.mask_edited and i in self.edited_imp)] @@ -2144,7 +2165,9 @@ def ReloadMethodsOptions(self): class ClutImagedataDialog(wx.Dialog): - def __init__(self, histogram, init, end, nodes=None): + def __init__( + self, histogram: np.ndarray, init: float, end: float, nodes: Optional[List["Node"]] = None + ): wx.Dialog.__init__( self, wx.GetApp().GetTopWindow(), @@ -2161,7 +2184,7 @@ def __init__(self, histogram, init, end, nodes=None): self.bind_events() self.bind_events_wx() - def _init_gui(self): + def _init_gui(self) -> None: self.clut_widget = CLUTImageDataWidget( self, -1, self.histogram, self.init, self.end, self.nodes ) @@ -2171,13 +2194,13 @@ def _init_gui(self): self.SetSizer(sizer) self.Fit() - def bind_events_wx(self): + def bind_events_wx(self) -> None: self.clut_widget.Bind(EVT_CLUT_NODE_CHANGED, self.OnClutChange) - def bind_events(self): + def bind_events(self) -> None: Publisher.subscribe(self._refresh_widget, "Update clut imagedata widget") - def OnClutChange(self, evt): + def OnClutChange(self, evt: "CLUTEvent") -> None: Publisher.sendMessage( "Change colour table from background image from widget", nodes=evt.GetNodes() ) @@ -2187,17 +2210,17 @@ def OnClutChange(self, evt): level=self.clut_widget.window_level, ) - def _refresh_widget(self): + def _refresh_widget(self) -> None: self.clut_widget.Refresh() - def Show(self, gen_evt=True, show=True): + def Show(self, gen_evt: bool = True, show: bool = True) -> None: super(wx.Dialog, self).Show(show) if gen_evt: self.clut_widget._generate_event() class WatershedOptionsPanel(wx.Panel): - def __init__(self, parent, config): + def __init__(self, parent: wx.Window, config: "WatershedConfig"): wx.Panel.__init__(self, parent) self.algorithms = ("Watershed", "Watershed IFT") @@ -2208,7 +2231,7 @@ def __init__(self, parent, config): self._init_gui() - def _init_gui(self): + def _init_gui(self) -> None: self.choice_algorithm = wx.RadioBox( self, -1, _("Method"), choices=self.algorithms, style=wx.NO_BORDER | wx.HORIZONTAL ) @@ -2253,7 +2276,7 @@ def _init_gui(self): sizer.Fit(self) self.Layout() - def apply_options(self): + def apply_options(self) -> None: self.config.algorithm = self.algorithms[self.choice_algorithm.GetSelection()] self.config.con_2d = self.con2d_choices[self.choice_2dcon.GetSelection()] self.config.con_3d = self.con3d_choices[self.choice_3dcon.GetSelection()] @@ -2263,10 +2286,10 @@ def apply_options(self): class WatershedOptionsDialog(wx.Dialog): def __init__( self, - config, - ID=-1, - title=_("Watershed"), - style=wx.DEFAULT_DIALOG_STYLE | wx.FRAME_FLOAT_ON_PARENT, + config: "WatershedConfig", + ID: int = -1, + title: str = _("Watershed"), + style: int = wx.DEFAULT_DIALOG_STYLE | wx.FRAME_FLOAT_ON_PARENT, ): wx.Dialog.__init__(self, wx.GetApp().GetTopWindow(), ID, title=title, style=style) @@ -2274,7 +2297,7 @@ def __init__( self._init_gui() - def _init_gui(self): + def _init_gui(self) -> None: wop = WatershedOptionsPanel(self, self.config) self.wop = wop @@ -2300,7 +2323,7 @@ def _init_gui(self): btn_ok.Bind(wx.EVT_BUTTON, self.OnOk) self.CenterOnScreen() - def OnOk(self, evt): + def OnOk(self, evt: wx.CommandEvent) -> None: self.wop.apply_options() evt.Skip() @@ -2308,17 +2331,17 @@ def OnOk(self, evt): class MaskBooleanDialog(wx.Dialog): def __init__( self, - masks, - ID=-1, - title=_("Boolean operations"), - style=wx.DEFAULT_DIALOG_STYLE | wx.FRAME_FLOAT_ON_PARENT, + masks: Dict[int, "Mask"], + ID: int = -1, + title: str = _("Boolean operations"), + style: int = wx.DEFAULT_DIALOG_STYLE | wx.FRAME_FLOAT_ON_PARENT, ): wx.Dialog.__init__(self, wx.GetApp().GetTopWindow(), ID, title=title, style=style) self._init_gui(masks) self.CenterOnScreen() - def _init_gui(self, masks): + def _init_gui(self, masks: Dict[int, "Mask"]) -> None: mask_choices = [(masks[i].name, masks[i]) for i in sorted(masks)] self.mask1 = wx.ComboBox(self, -1, mask_choices[0][0], choices=[]) self.mask2 = wx.ComboBox(self, -1, mask_choices[0][0], choices=[]) @@ -2377,7 +2400,7 @@ def _init_gui(self, masks): btn_ok.Bind(wx.EVT_BUTTON, self.OnOk) - def OnOk(self, evt): + def OnOk(self, evt: wx.CommandEvent) -> None: op = self.op_boolean.GetClientData(self.op_boolean.GetSelection()) m1 = self.mask1.GetClientData(self.mask1.GetSelection()) m2 = self.mask2.GetClientData(self.mask2.GetSelection()) @@ -2393,9 +2416,9 @@ def OnOk(self, evt): class ReorientImageDialog(wx.Dialog): def __init__( self, - ID=-1, - title=_("Image reorientation"), - style=wx.DEFAULT_DIALOG_STYLE | wx.FRAME_FLOAT_ON_PARENT, + ID: int = -1, + title: str = _("Image reorientation"), + style: int = wx.DEFAULT_DIALOG_STYLE | wx.FRAME_FLOAT_ON_PARENT, ): wx.Dialog.__init__(self, wx.GetApp().GetTopWindow(), ID, title=title, style=style) @@ -2409,7 +2432,7 @@ def __init__( self._bind_events() self._bind_events_wx() - def _init_gui(self): + def _init_gui(self) -> None: interp_methods_choices = ( (_("Nearest Neighbour"), 0), (_("Trilinear"), 1), @@ -2455,11 +2478,11 @@ def _init_gui(self): self.SetSizer(sizer) self.Fit() - def _bind_events(self): + def _bind_events(self) -> None: Publisher.subscribe(self._update_angles, "Update reorient angles") Publisher.subscribe(self._close_dialog, "Close reorient dialog") - def _bind_events_wx(self): + def _bind_events_wx(self) -> None: self.interp_method.Bind(wx.EVT_COMBOBOX, self.OnSelect) self.anglex.Bind(wx.EVT_KILL_FOCUS, self.OnLostFocus) @@ -2473,35 +2496,35 @@ def _bind_events_wx(self): self.btnapply.Bind(wx.EVT_BUTTON, self.apply_reorientation) self.Bind(wx.EVT_CLOSE, self.OnClose) - def _update_angles(self, angles): + def _update_angles(self, angles: Tuple[float, float, float]) -> None: anglex, angley, anglez = angles - self.anglex.SetValue("%.3f" % np.rad2deg(anglex)) - self.angley.SetValue("%.3f" % np.rad2deg(angley)) - self.anglez.SetValue("%.3f" % np.rad2deg(anglez)) + self.anglex.SetValue(f"{np.rad2deg(anglex):.3f}") + self.angley.SetValue(f"{np.rad2deg(angley):.3f}") + self.anglez.SetValue(f"{np.rad2deg(anglez):.3f}") - def _close_dialog(self): + def _close_dialog(self) -> None: self.Destroy() - def apply_reorientation(self, evt): + def apply_reorientation(self, evt: wx.CommandEvent) -> None: Publisher.sendMessage("Apply reorientation") self.Close() - def OnClose(self, evt): + def OnClose(self, evt: wx.CloseEvent) -> None: self._closed = True Publisher.sendMessage("Disable style", style=const.SLICE_STATE_REORIENT) Publisher.sendMessage("Enable style", style=const.STATE_DEFAULT) self.Destroy() - def OnSelect(self, evt): + def OnSelect(self, evt: wx.CommandEvent) -> None: im_code = self.interp_method.GetClientData(self.interp_method.GetSelection()) Publisher.sendMessage("Set interpolation method", interp_method=im_code) - def OnSetFocus(self, evt): + def OnSetFocus(self, evt: wx.FocusEvent) -> None: self._last_ax = self.anglex.GetValue() self._last_ay = self.angley.GetValue() self._last_az = self.anglez.GetValue() - def OnLostFocus(self, evt): + def OnLostFocus(self, evt: wx.FocusEvent) -> None: if not self._closed: try: ax = np.deg2rad(float(self.anglex.GetValue())) @@ -2516,8 +2539,6 @@ def OnLostFocus(self, evt): class ImportBitmapParameters(wx.Dialog): - from os import sys - def __init__(self): if sys.platform == "win32": size = wx.Size(380, 180) @@ -2533,13 +2554,13 @@ def __init__(self): style=wx.DEFAULT_DIALOG_STYLE | wx.FRAME_FLOAT_ON_PARENT, ) - self.interval = 0 + self.interval: int = 0 self._init_gui() self.bind_evts() self.CenterOnScreen() - def _init_gui(self): + def _init_gui(self) -> None: import invesalius.project as prj p = wx.Panel( @@ -2573,19 +2594,13 @@ def _init_gui(self): gbs.Add(stx_name, (0, 0), flag=flag_labels) gbs.Add(tx_name, (0, 1)) - try: - gbs.Add(0, 0, (1, 0)) - except TypeError: - gbs.AddStretchSpacer((1, 0)) + gbs.Add(0, 0, (1, 0)) gbs.Add(stx_orientation, (2, 0), flag=flag_labels) gbs.Add(cb_orientation, (2, 1)) gbs.Add(stx_spacing, (3, 0)) - try: - gbs.Add(0, 0, (4, 0)) - except TypeError: - gbs.AddStretchSpacer((4, 0)) + gbs.Add(0, 0, (4, 0)) # --- spacing -------------- gbs_spacing = wx.GridBagSizer(2, 6) @@ -2636,19 +2651,14 @@ def _init_gui(self): btn_cancel = wx.Button(p, wx.ID_CANCEL) - try: - gbs_button.Add(0, 0, (0, 2)) - except TypeError: - gbs_button.AddStretchSpacer((0, 2)) + gbs_button.Add(0, 0, (0, 2)) + gbs_button.Add(btn_cancel, (1, 2)) gbs_button.Add(btn_ok, (1, 3)) gbs_principal.Add(gbs, (0, 0), flag=wx.ALL | wx.EXPAND) gbs_principal.Add(gbs_spacing, (1, 0), flag=wx.ALL | wx.EXPAND) - try: - gbs_principal.Add(0, 0, (2, 0)) - except TypeError: - gbs_principal.AddStretchSpacer((2, 0)) + gbs_principal.Add(0, 0, (2, 0)) gbs_principal.Add(gbs_button, (3, 0), flag=wx.ALIGN_RIGHT) box = wx.BoxSizer() @@ -2658,13 +2668,13 @@ def _init_gui(self): box.Fit(self) self.Layout() - def bind_evts(self): + def bind_evts(self) -> None: self.btn_ok.Bind(wx.EVT_BUTTON, self.OnOk) - def SetInterval(self, v): + def SetInterval(self, v: int) -> None: self.interval = v - def OnOk(self, evt): + def OnOk(self, evt: wx.CommandEvent) -> None: orient_selection = self.cb_orientation.GetSelection() if orient_selection == 1: @@ -2688,7 +2698,7 @@ def OnOk(self, evt): self.Destroy() -def BitmapNotSameSize(): +def BitmapNotSameSize() -> None: dlg = wx.MessageDialog( None, _("All bitmaps files must be the same \n width and height size."), @@ -2701,26 +2711,22 @@ def BitmapNotSameSize(): class PanelTargeFFill(wx.Panel): - def __init__(self, parent, ID=-1, style=wx.TAB_TRAVERSAL | wx.NO_BORDER): + def __init__( + self, parent: wx.Window, ID: int = -1, style: int = wx.TAB_TRAVERSAL | wx.NO_BORDER + ): wx.Panel.__init__(self, parent, ID, style=style) self._init_gui() - def _init_gui(self): + def _init_gui(self) -> None: self.target_2d = wx.RadioButton(self, -1, _("2D - Actual slice"), style=wx.RB_GROUP) self.target_3d = wx.RadioButton(self, -1, _("3D - All slices")) sizer = wx.GridBagSizer(5, 5) - try: - sizer.Add(0, 0, (0, 0)) - except TypeError: - sizer.AddStretchSpacer((0, 0)) + sizer.Add(0, 0, (0, 0)) sizer.Add(self.target_2d, (1, 0), (1, 6), flag=wx.LEFT, border=5) sizer.Add(self.target_3d, (2, 0), (1, 6), flag=wx.LEFT, border=5) - try: - sizer.Add(0, 0, (3, 0)) - except TypeError: - sizer.AddStretchSpacer((3, 0)) + sizer.Add(0, 0, (3, 0)) self.SetSizer(sizer) sizer.Fit(self) @@ -2729,30 +2735,28 @@ def _init_gui(self): class Panel2DConnectivity(wx.Panel): def __init__( - self, parent, ID=-1, show_orientation=False, style=wx.TAB_TRAVERSAL | wx.NO_BORDER + self, + parent: wx.Window, + ID: int = -1, + show_orientation: bool = False, + style: int = wx.TAB_TRAVERSAL | wx.NO_BORDER, ): wx.Panel.__init__(self, parent, ID, style=style) self._init_gui(show_orientation) - def _init_gui(self, show_orientation): + def _init_gui(self, show_orientation: bool) -> None: self.conect2D_4 = wx.RadioButton(self, -1, "4", style=wx.RB_GROUP) self.conect2D_8 = wx.RadioButton(self, -1, "8") sizer = wx.GridBagSizer(5, 5) - try: - sizer.Add(0, 0, (0, 0)) - except TypeError: - sizer.AddStretchSpacer((0, 0)) + sizer.Add(0, 0, (0, 0)) sizer.Add( wx.StaticText(self, -1, _("2D Connectivity")), (1, 0), (1, 6), flag=wx.LEFT, border=5 ) sizer.Add(self.conect2D_4, (2, 0), flag=wx.LEFT, border=7) sizer.Add(self.conect2D_8, (2, 1), flag=wx.LEFT, border=7) - try: - sizer.Add(0, 0, (3, 0)) - except TypeError: - sizer.AddStretchSpacer((3, 0)) + sizer.Add(0, 0, (3, 0)) if show_orientation: self.cmb_orientation = wx.ComboBox( @@ -2770,59 +2774,52 @@ def _init_gui(self, show_orientation): sizer.Add( self.cmb_orientation, (5, 0), (1, 10), flag=wx.LEFT | wx.RIGHT | wx.EXPAND, border=7 ) - try: - sizer.Add(0, 0, (6, 0)) - except TypeError: - sizer.AddStretchSpacer((6, 0)) + sizer.Add(0, 0, (6, 0)) self.SetSizer(sizer) sizer.Fit(self) self.Layout() - def GetConnSelected(self): + def GetConnSelected(self) -> Literal[4, 8]: if self.conect2D_4.GetValue(): return 4 else: return 8 - def GetOrientation(self): + def GetOrientation(self) -> str: dic_ori = {_("Axial"): "AXIAL", _("Coronal"): "CORONAL", _("Sagital"): "SAGITAL"} return dic_ori[self.cmb_orientation.GetStringSelection()] class Panel3DConnectivity(wx.Panel): - def __init__(self, parent, ID=-1, style=wx.TAB_TRAVERSAL | wx.NO_BORDER): + def __init__( + self, parent: wx.Window, ID: int = -1, style: int = wx.TAB_TRAVERSAL | wx.NO_BORDER + ): wx.Panel.__init__(self, parent, ID, style=style) self._init_gui() - def _init_gui(self): + def _init_gui(self) -> None: self.conect3D_6 = wx.RadioButton(self, -1, "6", style=wx.RB_GROUP) self.conect3D_18 = wx.RadioButton(self, -1, "18") self.conect3D_26 = wx.RadioButton(self, -1, "26") sizer = wx.GridBagSizer(5, 5) - try: - sizer.Add(0, 0, (0, 0)) - except TypeError: - sizer.AddStretchSpacer((0, 0)) + sizer.Add(0, 0, (0, 0)) sizer.Add( wx.StaticText(self, -1, _("3D Connectivity")), (1, 0), (1, 6), flag=wx.LEFT, border=5 ) sizer.Add(self.conect3D_6, (2, 0), flag=wx.LEFT, border=9) sizer.Add(self.conect3D_18, (2, 1), flag=wx.LEFT, border=9) sizer.Add(self.conect3D_26, (2, 2), flag=wx.LEFT, border=9) - try: - sizer.Add(0, 0, (3, 0)) - except TypeError: - sizer.AddStretchSpacer((3, 0)) + sizer.Add(0, 0, (3, 0)) self.SetSizer(sizer) sizer.Fit(self) self.Layout() - def GetConnSelected(self): + def GetConnSelected(self) -> Literal[6, 18, 26]: if self.conect3D_6.GetValue(): return 6 elif self.conect3D_18.GetValue(): @@ -2832,14 +2829,20 @@ def GetConnSelected(self): class PanelFFillThreshold(wx.Panel): - def __init__(self, parent, config, ID=-1, style=wx.TAB_TRAVERSAL | wx.NO_BORDER): + def __init__( + self, + parent: wx.Window, + config: "FFillSegmentationConfig", + ID: int = -1, + style: int = wx.TAB_TRAVERSAL | wx.NO_BORDER, + ) -> None: wx.Panel.__init__(self, parent, ID, style=style) self.config = config self._init_gui() - def _init_gui(self): + def _init_gui(self) -> None: import invesalius.project as prj project = prj.Project() @@ -2864,21 +2867,27 @@ def _init_gui(self): self.Bind(grad.EVT_THRESHOLD_CHANGING, self.OnSlideChanged, self.threshold) self.Bind(grad.EVT_THRESHOLD_CHANGED, self.OnSlideChanged, self.threshold) - def OnSlideChanged(self, evt): + def OnSlideChanged(self, evt: wx.Event) -> None: self.config.t0 = int(self.threshold.GetMinValue()) self.config.t1 = int(self.threshold.GetMaxValue()) print(self.config.t0, self.config.t1) class PanelFFillDynamic(wx.Panel): - def __init__(self, parent, config, ID=-1, style=wx.TAB_TRAVERSAL | wx.NO_BORDER): + def __init__( + self, + parent: wx.Window, + config: "FFillSegmentationConfig", + ID: int = -1, + style: int = wx.TAB_TRAVERSAL | wx.NO_BORDER, + ): wx.Panel.__init__(self, parent, ID, style=style) self.config = config self._init_gui() - def _init_gui(self): + def _init_gui(self) -> None: self.use_ww_wl = wx.CheckBox(self, -1, _("Use WW&WL")) self.use_ww_wl.SetValue(self.config.use_ww_wl) @@ -2894,17 +2903,11 @@ def _init_gui(self): sizer = wx.GridBagSizer(5, 5) - try: - sizer.Add(0, 0, (0, 0)) - except TypeError: - sizer.AddStretchSpacer((0, 0)) + sizer.Add(0, 0, (0, 0)) sizer.Add(self.use_ww_wl, (1, 0), (1, 6), flag=wx.LEFT, border=5) - try: - sizer.Add(0, 0, (2, 0)) - except TypeError: - sizer.AddStretchSpacer((2, 0)) + sizer.Add(0, 0, (2, 0)) sizer.Add(wx.StaticText(self, -1, _("Deviation")), (3, 0), (1, 6), flag=wx.LEFT, border=5) @@ -2924,10 +2927,7 @@ def _init_gui(self): ) sizer.Add(self.deviation_max, (4, 3)) - try: - sizer.Add(0, 0, (5, 0)) - except TypeError: - sizer.AddStretchSpacer((5, 0)) + sizer.Add(0, 0, (5, 0)) self.SetSizer(sizer) sizer.Fit(self) @@ -2937,23 +2937,29 @@ def _init_gui(self): self.deviation_min.Bind(wx.EVT_SPINCTRL, self.OnSetDeviation) self.deviation_max.Bind(wx.EVT_SPINCTRL, self.OnSetDeviation) - def OnSetUseWWWL(self, evt): + def OnSetUseWWWL(self, evt: wx.CommandEvent) -> None: self.config.use_ww_wl = self.use_ww_wl.GetValue() - def OnSetDeviation(self, evt): + def OnSetDeviation(self, evt: wx.SpinEvent) -> None: self.config.dev_max = self.deviation_max.GetValue() self.config.dev_min = self.deviation_min.GetValue() class PanelFFillConfidence(wx.Panel): - def __init__(self, parent, config, ID=-1, style=wx.TAB_TRAVERSAL | wx.NO_BORDER): + def __init__( + self, + parent: wx.Window, + config: "FFillSegmentationConfig", + ID: int = -1, + style: int = wx.TAB_TRAVERSAL | wx.NO_BORDER, + ): wx.Panel.__init__(self, parent, ID, style=style) self.config = config self._init_gui() - def _init_gui(self): + def _init_gui(self) -> None: self.use_ww_wl = wx.CheckBox(self, -1, _("Use WW&WL")) self.use_ww_wl.SetValue(self.config.use_ww_wl) @@ -2977,17 +2983,11 @@ def _init_gui(self): sizer = wx.GridBagSizer(5, 5) - try: - sizer.Add(0, 0, (0, 0)) - except TypeError: - sizer.AddStretchSpacer((0, 0)) + sizer.Add(0, 0, (0, 0)) sizer.Add(self.use_ww_wl, (1, 0), (1, 6), flag=wx.LEFT, border=5) - try: - sizer.Add(0, 0, (2, 0)) - except TypeError: - sizer.AddStretchSpacer((2, 0)) + sizer.Add(0, 0, (2, 0)) sizer.Add( wx.StaticText(self, -1, _("Multiplier")), @@ -3007,10 +3007,7 @@ def _init_gui(self): ) sizer.Add(self.spin_iters, (4, 3), (1, 2)) - try: - sizer.Add(0, 0, (5, 0)) - except TypeError: - sizer.AddStretchSpacer((5, 0)) + sizer.Add(0, 0, (5, 0)) self.SetSizer(sizer) sizer.Fit(self) @@ -3020,22 +3017,24 @@ def _init_gui(self): self.spin_mult.Bind(wx.EVT_SPINCTRL, self.OnSetMult) self.spin_iters.Bind(wx.EVT_SPINCTRL, self.OnSetIters) - def OnSetUseWWWL(self, evt): + def OnSetUseWWWL(self, evt: wx.CommandEvent) -> None: self.config.use_ww_wl = self.use_ww_wl.GetValue() - def OnSetMult(self, evt): + def OnSetMult(self, evt: wx.SpinEvent) -> None: self.config.confid_mult = self.spin_mult.GetValue() - def OnSetIters(self, evt): + def OnSetIters(self, evt: wx.SpinEvent) -> None: self.config.confid_iters = self.spin_iters.GetValue() class PanelFFillProgress(wx.Panel): - def __init__(self, parent, ID=-1, style=wx.TAB_TRAVERSAL | wx.NO_BORDER): + def __init__( + self, parent: wx.Window, ID: int = -1, style: int = wx.TAB_TRAVERSAL | wx.NO_BORDER + ) -> None: wx.Panel.__init__(self, parent, ID, style=style) self._init_gui() - def _init_gui(self): + def _init_gui(self) -> None: self.progress = wx.Gauge(self, -1) self.lbl_progress_caption = wx.StaticText(self, -1, _("Elapsed time:")) self.lbl_time = wx.StaticText(self, -1, _("00:00:00")) @@ -3051,22 +3050,22 @@ def _init_gui(self): main_sizer.Fit(self) main_sizer.SetSizeHints(self) - def StartTimer(self): + def StartTimer(self) -> None: self.t0 = time.time() - def StopTimer(self): + def StopTimer(self) -> None: fmt = "%H:%M:%S" self.lbl_time.SetLabel(time.strftime(fmt, time.gmtime(time.time() - self.t0))) self.progress.SetValue(0) - def Pulse(self): + def Pulse(self) -> None: fmt = "%H:%M:%S" self.lbl_time.SetLabel(time.strftime(fmt, time.gmtime(time.time() - self.t0))) self.progress.Pulse() class FFillOptionsDialog(wx.Dialog): - def __init__(self, title, config): + def __init__(self, title: str, config: "FFillConfig"): wx.Dialog.__init__( self, wx.GetApp().GetTopWindow(), @@ -3079,7 +3078,7 @@ def __init__(self, title, config): self._init_gui() - def _init_gui(self): + def _init_gui(self) -> None: """ Create the widgets. """ @@ -3095,28 +3094,28 @@ def _init_gui(self): self.panel3dcon = Panel3DConnectivity(self, style=border_style | wx.TAB_TRAVERSAL) if self.config.target == "2D": - self.panel_target.target_2d.SetValue(1) - self.panel2dcon.Enable(1) - self.panel3dcon.Enable(0) + self.panel_target.target_2d.SetValue(True) + self.panel2dcon.Enable(True) + self.panel3dcon.Enable(False) else: - self.panel_target.target_3d.SetValue(1) - self.panel3dcon.Enable(1) - self.panel2dcon.Enable(0) + self.panel_target.target_3d.SetValue(True) + self.panel3dcon.Enable(True) + self.panel2dcon.Enable(False) # Connectivity 2D if self.config.con_2d == 8: - self.panel2dcon.conect2D_8.SetValue(1) + self.panel2dcon.conect2D_8.SetValue(True) else: - self.panel2dcon.conect2D_4.SetValue(1) + self.panel2dcon.conect2D_4.SetValue(True) self.config.con_2d = 4 # Connectivity 3D if self.config.con_3d == 18: - self.panel3dcon.conect3D_18.SetValue(1) + self.panel3dcon.conect3D_18.SetValue(True) elif self.config.con_3d == 26: - self.panel3dcon.conect3D_26.SetValue(1) + self.panel3dcon.conect3D_26.SetValue(True) else: - self.panel3dcon.conect3D_6.SetValue(1) + self.panel3dcon.conect3D_6.SetValue(True) self.close_btn = wx.Button(self, wx.ID_CLOSE) @@ -3143,19 +3142,19 @@ def _init_gui(self): self.Bind(wx.EVT_RADIOBUTTON, self.OnSetRadio) self.Bind(wx.EVT_CLOSE, self.OnClose) - def OnBtnClose(self, evt): + def OnBtnClose(self, evt: wx.CommandEvent) -> None: self.Close() - def OnSetRadio(self, evt): + def OnSetRadio(self, evt: wx.CommandEvent) -> None: # Target if self.panel_target.target_2d.GetValue(): self.config.target = "2D" - self.panel2dcon.Enable(1) - self.panel3dcon.Enable(0) + self.panel2dcon.Enable(True) + self.panel3dcon.Enable(False) else: self.config.target = "3D" - self.panel3dcon.Enable(1) - self.panel2dcon.Enable(0) + self.panel3dcon.Enable(True) + self.panel2dcon.Enable(False) # 2D if self.panel2dcon.conect2D_4.GetValue(): @@ -3171,7 +3170,7 @@ def OnSetRadio(self, evt): elif self.panel3dcon.conect3D_26.GetValue(): self.config.con_3d = 26 - def OnClose(self, evt): + def OnClose(self, evt: wx.CloseEvent) -> None: print("ONCLOSE") if self.config.dlg_visible: Publisher.sendMessage("Disable style", style=const.SLICE_STATE_MASK_FFILL) @@ -3180,7 +3179,7 @@ def OnClose(self, evt): class SelectPartsOptionsDialog(wx.Dialog): - def __init__(self, config): + def __init__(self, config: "SelectPartConfig"): wx.Dialog.__init__( self, wx.GetApp().GetTopWindow(), @@ -3195,18 +3194,18 @@ def __init__(self, config): self._init_gui() - def _init_gui(self): + def _init_gui(self) -> None: self.target_name = wx.TextCtrl(self, -1) self.target_name.SetValue(self.config.mask_name) # Connectivity 3D self.panel3dcon = Panel3DConnectivity(self) if self.config.con_3d == 18: - self.panel3dcon.conect3D_18.SetValue(1) + self.panel3dcon.conect3D_18.SetValue(True) elif self.config.con_3d == 26: - self.panel3dcon.conect3D_26.SetValue(1) + self.panel3dcon.conect3D_26.SetValue(True) else: - self.panel3dcon.conect3D_6.SetValue(1) + self.panel3dcon.conect3D_6.SetValue(True) self.btn_ok = wx.Button(self, wx.ID_OK) self.btn_cancel = wx.Button(self, wx.ID_CANCEL) @@ -3239,19 +3238,19 @@ def _init_gui(self): self.Bind(wx.EVT_RADIOBUTTON, self.OnSetRadio) self.Bind(wx.EVT_CLOSE, self.OnClose) - def OnOk(self, evt): + def OnOk(self, evt: wx.CommandEvent) -> None: self.SetReturnCode(wx.OK) self.Close() - def OnCancel(self, evt): + def OnCancel(self, evt: wx.CommandEvent) -> None: self.SetReturnCode(wx.CANCEL) self.Close() - def OnChar(self, evt): + def OnChar(self, evt: wx.KeyEvent) -> None: evt.Skip() self.config.mask_name = self.target_name.GetValue() - def OnSetRadio(self, evt): + def OnSetRadio(self, evt: wx.CommandEvent) -> None: if self.panel3dcon.conect3D_6.GetValue(): self.config.con_3d = 6 elif self.panel3dcon.conect3D_18.GetValue(): @@ -3259,7 +3258,7 @@ def OnSetRadio(self, evt): elif self.panel3dcon.conect3D_26.GetValue(): self.config.con_3d = 26 - def OnClose(self, evt): + def OnClose(self, evt: wx.CloseEvent) -> None: if self.config.dlg_visible: Publisher.sendMessage("Disable style", style=const.SLICE_STATE_SELECT_MASK_PARTS) evt.Skip() @@ -3269,10 +3268,10 @@ def OnClose(self, evt): class FFillSegmentationOptionsDialog(wx.Dialog): def __init__( self, - config, - ID=-1, - title=_("Region growing"), - style=wx.DEFAULT_DIALOG_STYLE | wx.FRAME_FLOAT_ON_PARENT, + config: "FFillSegmentationConfig", + ID: int = -1, + title: str = _("Region growing"), + style: int = wx.DEFAULT_DIALOG_STYLE | wx.FRAME_FLOAT_ON_PARENT, ): wx.Dialog.__init__(self, wx.GetApp().GetTopWindow(), ID, title=title, style=style) @@ -3280,11 +3279,10 @@ def __init__( self._init_gui() - def _init_gui(self): + def _init_gui(self) -> None: """ Create the widgets. """ - import invesalius.project as prj # Target if sys.platform == "win32": @@ -3297,28 +3295,28 @@ def _init_gui(self): self.panel3dcon = Panel3DConnectivity(self, style=border_style | wx.TAB_TRAVERSAL) if self.config.target == "2D": - self.panel_target.target_2d.SetValue(1) - self.panel2dcon.Enable(1) - self.panel3dcon.Enable(0) + self.panel_target.target_2d.SetValue(True) + self.panel2dcon.Enable(True) + self.panel3dcon.Enable(False) else: - self.panel_target.target_3d.SetValue(1) - self.panel3dcon.Enable(1) - self.panel2dcon.Enable(0) + self.panel_target.target_3d.SetValue(True) + self.panel3dcon.Enable(True) + self.panel2dcon.Enable(False) # Connectivity 2D if self.config.con_2d == 8: - self.panel2dcon.conect2D_8.SetValue(1) + self.panel2dcon.conect2D_8.SetValue(True) else: - self.panel2dcon.conect2D_4.SetValue(1) + self.panel2dcon.conect2D_4.SetValue(True) self.config.con_2d = 4 # Connectivity 3D if self.config.con_3d == 18: - self.panel3dcon.conect3D_18.SetValue(1) + self.panel3dcon.conect3D_18.SetValue(True) elif self.config.con_3d == 26: - self.panel3dcon.conect3D_26.SetValue(1) + self.panel3dcon.conect3D_26.SetValue(True) else: - self.panel3dcon.conect3D_6.SetValue(1) + self.panel3dcon.conect3D_6.SetValue(True) self.cmb_method = wx.ComboBox( self, -1, choices=(_("Dynamic"), _("Threshold"), _("Confidence")), style=wx.CB_READONLY @@ -3358,30 +3356,15 @@ def _init_gui(self): # Sizer sizer = wx.GridBagSizer(2, 2) - try: - sizer.Add(0, 0, (0, 0)) - except TypeError: - sizer.AddStretchSpacer((0, 0)) + sizer.Add(0, 0, (0, 0)) sizer.Add(wx.StaticText(self, -1, _("Parameters")), (1, 0), (1, 6), flag=wx.LEFT, border=5) - try: - sizer.Add(0, 0, (2, 0)) - except TypeError: - sizer.AddStretchSpacer((2, 0)) + sizer.Add(0, 0, (2, 0)) sizer.Add(self.panel_target, (3, 0), (1, 6), flag=wx.LEFT | wx.RIGHT | wx.EXPAND, border=7) - try: - sizer.Add(0, 0, (4, 0)) - except TypeError: - sizer.AddStretchSpacer((4, 0)) + sizer.Add(0, 0, (4, 0)) sizer.Add(self.panel2dcon, (5, 0), (1, 6), flag=wx.LEFT | wx.RIGHT | wx.EXPAND, border=7) - try: - sizer.Add(0, 0, (6, 0)) - except TypeError: - sizer.AddStretchSpacer((6, 0)) + sizer.Add(0, 0, (6, 0)) sizer.Add(self.panel3dcon, (7, 0), (1, 6), flag=wx.LEFT | wx.RIGHT | wx.EXPAND, border=7) - try: - sizer.Add(0, 0, (8, 0)) - except TypeError: - sizer.AddStretchSpacer((8, 0)) + sizer.Add(0, 0, (8, 0)) sizer.Add( wx.StaticText(self, -1, _("Method")), @@ -3392,10 +3375,7 @@ def _init_gui(self): ) sizer.Add(self.cmb_method, (9, 1), (1, 5), flag=wx.LEFT | wx.RIGHT | wx.EXPAND, border=7) - try: - sizer.Add(0, 0, (10, 0)) - except TypeError: - sizer.AddStretchSpacer((10, 0)) + sizer.Add(0, 0, (10, 0)) if self.config.method == "dynamic": self.cmb_method.SetSelection(0) @@ -3429,22 +3409,13 @@ def _init_gui(self): ) self.config.method = "threshold" - try: - sizer.Add(0, 0, (12, 0)) - except TypeError: - sizer.AddStretchSpacer((12, 0)) + sizer.Add(0, 0, (12, 0)) sizer.Add( self.panel_ffill_progress, (13, 0), (1, 6), flag=wx.ALIGN_RIGHT | wx.RIGHT, border=5 ) - try: - sizer.Add(0, 0, (14, 0)) - except TypeError: - sizer.AddStretchSpacer((14, 0)) + sizer.Add(0, 0, (14, 0)) sizer.Add(self.close_btn, (15, 0), (1, 6), flag=wx.ALIGN_RIGHT | wx.RIGHT, border=5) - try: - sizer.Add(0, 0, (16, 0)) - except TypeError: - sizer.AddStretchSpacer((16, 0)) + sizer.Add(0, 0, (16, 0)) self.SetSizer(sizer) sizer.Fit(self) @@ -3455,16 +3426,16 @@ def _init_gui(self): self.close_btn.Bind(wx.EVT_BUTTON, self.OnBtnClose) self.Bind(wx.EVT_CLOSE, self.OnClose) - def OnSetRadio(self, evt): + def OnSetRadio(self, evt: wx.CommandEvent) -> None: # Target if self.panel_target.target_2d.GetValue(): self.config.target = "2D" - self.panel2dcon.Enable(1) - self.panel3dcon.Enable(0) + self.panel2dcon.Enable(True) + self.panel3dcon.Enable(False) else: self.config.target = "3D" - self.panel3dcon.Enable(1) - self.panel2dcon.Enable(0) + self.panel3dcon.Enable(True) + self.panel2dcon.Enable(False) # 2D if self.panel2dcon.conect2D_4.GetValue(): @@ -3480,8 +3451,10 @@ def OnSetRadio(self, evt): elif self.panel3dcon.conect3D_26.GetValue(): self.config.con_3d = 26 - def OnSetMethod(self, evt): - item_panel = self.GetSizer().FindItemAtPosition((11, 0)).GetWindow() + def OnSetMethod(self, evt: wx.CommandEvent) -> None: + sizer = self.GetSizer() + assert isinstance(sizer, wx.GridBagSizer), "assigned sizer must be a wx.GridBagSizer" + item_panel = sizer.FindItemAtPosition((11, 0)).GetWindow() if self.cmb_method.GetSelection() == 0: self.config.method = "dynamic" @@ -3504,10 +3477,10 @@ def OnSetMethod(self, evt): self.GetSizer().Fit(self) self.Layout() - def OnBtnClose(self, evt): + def OnBtnClose(self, evt: wx.CommandEvent) -> None: self.Close() - def OnClose(self, evt): + def OnClose(self, evt: wx.CloseEvent) -> None: if self.config.dlg_visible: Publisher.sendMessage("Disable style", style=const.SLICE_STATE_MASK_FFILL) evt.Skip() @@ -3517,16 +3490,16 @@ def OnClose(self, evt): class CropOptionsDialog(wx.Dialog): def __init__( self, - config, - ID=-1, - title=_("Crop mask"), - style=wx.DEFAULT_DIALOG_STYLE | wx.FRAME_FLOAT_ON_PARENT, + config: "CropMaskConfig", + ID: int = -1, + title: str = _("Crop mask"), + style: int = wx.DEFAULT_DIALOG_STYLE | wx.FRAME_FLOAT_ON_PARENT, ): self.config = config wx.Dialog.__init__(self, wx.GetApp().GetTopWindow(), ID, title=title, style=style) self._init_gui() - def UpdateValues(self, limits): + def UpdateValues(self, limits: Iterable[float]) -> None: xi, xf, yi, yf, zi, zf = limits self.tx_axial_i.SetValue(str(zi)) @@ -3538,7 +3511,7 @@ def UpdateValues(self, limits): self.tx_coronal_i.SetValue(str(yi)) self.tx_coronal_f.SetValue(str(yf)) - def _init_gui(self): + def _init_gui(self) -> None: p = wx.Panel( self, -1, style=wx.TAB_TRAVERSAL | wx.CLIP_CHILDREN | wx.FULL_REPAINT_ON_RESIZE ) @@ -3600,12 +3573,9 @@ def _init_gui(self): gbs_button.Add(btn_ok, (0, 1)) gbs_principal.Add(gbs, (0, 0), flag=wx.ALL | wx.EXPAND) - try: - gbs_principal.Add(0, 0, (1, 0)) - gbs_principal.Add(0, 0, (2, 0)) - except TypeError: - gbs_principal.AddStretchSpacer((1, 0)) - gbs_principal.AddStretchSpacer((2, 0)) + gbs_principal.Add(0, 0, (1, 0)) + gbs_principal.Add(0, 0, (2, 0)) + gbs_principal.Add(gbs_button, (3, 0), flag=wx.ALIGN_RIGHT) box = wx.BoxSizer() @@ -3626,13 +3596,13 @@ def _init_gui(self): btn_cancel.Bind(wx.EVT_BUTTON, self.OnClose) self.Bind(wx.EVT_CLOSE, self.OnClose) - def OnOk(self, evt): + def OnOk(self, evt: wx.CommandEvent) -> None: self.config.dlg_visible = False Publisher.sendMessage("Crop mask") Publisher.sendMessage("Disable style", style=const.SLICE_STATE_CROP_MASK) evt.Skip() - def OnClose(self, evt): + def OnClose(self, evt: Union[wx.CommandEvent, wx.CloseEvent]) -> None: self.config.dlg_visible = False Publisher.sendMessage("Disable style", style=const.SLICE_STATE_CROP_MASK) evt.Skip() @@ -3640,7 +3610,7 @@ def OnClose(self, evt): class FillHolesAutoDialog(wx.Dialog): - def __init__(self, title): + def __init__(self, title: str): wx.Dialog.__init__( self, wx.GetApp().GetTopWindow(), @@ -3650,7 +3620,7 @@ def __init__(self, title): ) self._init_gui() - def _init_gui(self): + def _init_gui(self) -> None: if sys.platform == "win32": border_style = wx.SIMPLE_BORDER else: @@ -3663,12 +3633,12 @@ def _init_gui(self): ) self.panel3dcon = Panel3DConnectivity(self, style=border_style | wx.TAB_TRAVERSAL) - self.panel2dcon.Enable(1) - self.panel3dcon.Enable(0) + self.panel2dcon.Enable(True) + self.panel3dcon.Enable(False) - self.panel_target.target_2d.SetValue(1) - self.panel2dcon.conect2D_4.SetValue(1) - self.panel3dcon.conect3D_6.SetValue(1) + self.panel_target.target_2d.SetValue(True) + self.panel2dcon.conect2D_4.SetValue(True) + self.panel3dcon.conect3D_6.SetValue(True) self.apply_btn = wx.Button(self, wx.ID_APPLY) self.close_btn = wx.Button(self, wx.ID_CLOSE) @@ -3717,7 +3687,7 @@ def _init_gui(self): self.close_btn.Bind(wx.EVT_BUTTON, self.OnBtnClose) self.Bind(wx.EVT_RADIOBUTTON, self.OnSetRadio) - def OnApply(self, evt): + def OnApply(self, evt: wx.CommandEvent) -> None: if self.panel_target.target_2d.GetValue(): target = "2D" conn = self.panel2dcon.GetConnSelected() @@ -3736,22 +3706,22 @@ def OnApply(self, evt): Publisher.sendMessage("Fill holes automatically", parameters=parameters) - def OnBtnClose(self, evt): + def OnBtnClose(self, evt: wx.CommandEvent) -> None: self.Close() self.Destroy() - def OnSetRadio(self, evt): + def OnSetRadio(self, evt: wx.CommandEvent) -> None: # Target if self.panel_target.target_2d.GetValue(): - self.panel2dcon.Enable(1) - self.panel3dcon.Enable(0) + self.panel2dcon.Enable(True) + self.panel3dcon.Enable(False) else: - self.panel3dcon.Enable(1) - self.panel2dcon.Enable(0) + self.panel3dcon.Enable(True) + self.panel2dcon.Enable(False) class MaskDensityDialog(wx.Dialog): - def __init__(self, title): + def __init__(self, title: str) -> None: wx.Dialog.__init__( self, wx.GetApp().GetTopWindow(), @@ -3762,7 +3732,7 @@ def __init__(self, title): self._init_gui() self._bind_events() - def _init_gui(self): + def _init_gui(self) -> None: import invesalius.project as prj project = prj.Project() @@ -3835,16 +3805,16 @@ def _init_gui(self): self.CenterOnScreen() - def _create_selectable_label_text(self, text): + def _create_selectable_label_text(self, text: str) -> wx.TextCtrl: label = wx.TextCtrl(self, -1, style=wx.TE_READONLY) label.SetValue(text) # label.SetBackgroundColour(self.GetBackgroundColour()) return label - def _bind_events(self): + def _bind_events(self) -> None: self.calc_button.Bind(wx.EVT_BUTTON, self.OnCalcButton) - def OnCalcButton(self, evt): + def OnCalcButton(self, evt: wx.CommandEvent) -> None: from invesalius.data.slice_ import Slice mask = self.cmb_mask.GetClientData(self.cmb_mask.GetSelection()) @@ -3876,7 +3846,12 @@ def OnCalcButton(self, evt): class ObjectCalibrationDialog(wx.Dialog): - def __init__(self, tracker, pedal_connector, neuronavigation_api): + def __init__( + self, + tracker: "Tracker", + pedal_connector: "PedalConnector", + neuronavigation_api: "NeuronavigationApi", + ): self.tracker = tracker self.pedal_connector = pedal_connector self.neuronavigation_api = neuronavigation_api @@ -3903,7 +3878,7 @@ def __init__(self, tracker, pedal_connector, neuronavigation_api): self._init_pedal() self.InitializeObject() - def _init_gui(self): + def _init_gui(self) -> None: self.interactor = wxVTKRenderWindowInteractor(self, -1, size=self.GetSize()) self.interactor.Enable(1) self.ren = vtkRenderer() @@ -3911,8 +3886,8 @@ def _init_gui(self): # Initialize list of buttons and txtctrls for wx objects self.btns_coord = [None] * 4 - self.text_actors = [None] * 4 - self.ball_actors = [None] * 4 + self.text_actors: List[Optional[vtkFollower]] = [None] * 4 + self.ball_actors: List[Optional[vtkActor]] = [None] * 4 self.txt_coord = [list(), list(), list(), list()] # ComboBox for tracker reference mode @@ -3928,11 +3903,11 @@ def _init_gui(self): choice_ref.SetToolTip(tooltip) choice_ref.Bind(wx.EVT_COMBOBOX, self.OnChooseReferenceMode) choice_ref.SetSelection(1) - choice_ref.Enable(1) + choice_ref.Enable(True) if self.tracker_id == const.PATRIOT or self.tracker_id == const.ISOTRAKII: self.obj_ref_id = 0 choice_ref.SetSelection(0) - choice_ref.Enable(0) + choice_ref.Enable(False) # ComboBox for sensor selection for FASTRAK tooltip = _("Choose the FASTRAK sensor port") @@ -4014,7 +3989,7 @@ def _init_gui(self): self.SetSizer(main_sizer) main_sizer.Fit(self) - def _init_pedal(self): + def _init_pedal(self) -> None: def set_fiducial_callback(state): index = self.buttons.focused_index if state and index is not None: @@ -4025,7 +4000,7 @@ def set_fiducial_callback(state): ) self.Bind(wx.EVT_BUTTON, self.OnOk) - def ObjectImportDialog(self): + def ObjectImportDialog(self) -> Literal[0, 1]: msg = _("Would like to use InVesalius default object?") if sys.platform == "darwin": dlg = wx.MessageDialog(None, "", msg, wx.ICON_QUESTION | wx.YES_NO) @@ -4039,7 +4014,7 @@ def ObjectImportDialog(self): else: # answer == wx.ID_NO: return 0 - def ShowObject(self, polydata): + def ShowObject(self, polydata: vtkPolyData) -> None: if polydata.GetNumberOfPoints() == 0: wx.MessageBox( _("InVesalius was not able to import this surface"), _("Import surface error") @@ -4072,7 +4047,7 @@ def ShowObject(self, polydata): self.ball_actors[2], self.text_actors[2] = self.OnCreateObjectText("Anterior", (23, 0, 0)) # Match actor colors with fiducial buttons - def set_actor_colors(n, color_float): + def set_actor_colors(n: int, color_float: Sequence[float]) -> None: if n != const.OBJECT_FIDUCIAL_FIXED: self.ball_actors[n].GetProperty().SetColor(color_float) self.text_actors[n].GetProperty().SetColor(color_float) @@ -4086,7 +4061,7 @@ def set_actor_colors(n, color_float): self.interactor.Render() - def ConfigureObject(self): + def ConfigureObject(self) -> bool: use_default_coil = self.ObjectImportDialog() if use_default_coil: @@ -4114,7 +4089,7 @@ def ConfigureObject(self): return True - def InitializeObject(self): + def InitializeObject(self) -> None: success = self.ConfigureObject() if success: # XXX: Is this back and forth encoding and decoding needed? Maybe path could be encoded @@ -4124,7 +4099,7 @@ def InitializeObject(self): self.polydata = pu.LoadPolydata(path=object_path) self.ShowObject(polydata=self.polydata) - def OnCreateObjectText(self, name, coord): + def OnCreateObjectText(self, name: str, coord: Sequence[float]) -> Tuple[vtkActor, vtkFollower]: ball_source = vtkSphereSource() ball_source.SetRadius(3) mapper = vtkPolyDataMapper() @@ -4150,11 +4125,11 @@ def OnCreateObjectText(self, name, coord): self.ren.AddActor(ball_actor) return ball_actor, tactor - def IsObjectFiducialSet(self, fiducial_index): + def IsObjectFiducialSet(self, fiducial_index: int) -> bool: fiducial = self.obj_fiducials[fiducial_index] return not np.isnan(fiducial).any() - def OnObjectFiducialButton(self, index, evt): + def OnObjectFiducialButton(self, index: int, evt: wx.CommandEvent) -> None: button = self.buttons[index] if button is self.buttons.focused: @@ -4164,7 +4139,7 @@ def OnObjectFiducialButton(self, index, evt): else: self.buttons.Focus(index) - def SetObjectFiducial(self, fiducial_index): + def SetObjectFiducial(self, fiducial_index: int) -> None: if not self.tracker.IsTrackerInitialized(): ShowNavigationTrackerWarning(0, "choose") return @@ -4219,22 +4194,22 @@ def SetObjectFiducial(self, fiducial_index): if fiducial_index == const.OBJECT_FIDUCIAL_ANTERIOR and not self.show_sensor_options: self.SetObjectFiducial(const.OBJECT_FIDUCIAL_FIXED) - def ResetObjectFiducials(self): + def ResetObjectFiducials(self) -> None: for m in range(0, 4): self.ResetObjectFiducial(m) self.buttons.Update() - def ResetObjectFiducial(self, index): + def ResetObjectFiducial(self, index: int) -> None: self.obj_fiducials[index, :] = np.full([1, 3], np.nan) self.obj_orients[index, :] = np.full([1, 3], np.nan) for coord_index in range(0, 3): self.txt_coord[index][coord_index].SetLabel("-") self.buttons.Unset(index) - def OnReset(self, evt): + def OnReset(self, evt: wx.CommandEvent) -> None: self.ResetObjectFiducials() - def OnChooseReferenceMode(self, evt): + def OnChooseReferenceMode(self, evt: wx.CommandEvent) -> None: # When ref mode is changed the tracker coordinates are set to nan # This is for Polhemus FASTRAK wrapper, where the sensor attached to the object can be the stylus (Static # reference - Selection 0 - index 0 for coordinates) or can be a 3rd sensor (Dynamic reference - Selection 1 - @@ -4245,26 +4220,28 @@ def OnChooseReferenceMode(self, evt): if evt.GetSelection() == 1: self.obj_ref_id = 2 if self.tracker_id in const.TRACKERS_WITH_SENSOR_OPTIONS: - self.choice_sensor.Show(self.obj_ref_id) + self.choice_sensor.Show(True) else: self.obj_ref_id = 0 - self.choice_sensor.Show(self.obj_ref_id) + self.choice_sensor.Show(False) self.ResetObjectFiducials() # Used to update choice sensor controls self.Layout() - def OnChoiceFTSensor(self, evt): + def OnChoiceFTSensor(self, evt: wx.CommandEvent) -> None: if evt.GetSelection(): self.obj_ref_id = 3 else: self.obj_ref_id = 0 - def GetValue(self): + def GetValue( + self, + ) -> Tuple[np.ndarray, np.ndarray, int, Optional[bytes], Optional[vtkPolyData]]: return self.obj_fiducials, self.obj_orients, self.obj_ref_id, self.coil_path, self.polydata - def OnOk(self, evt): + def OnOk(self, evt: wx.CommandEvent) -> None: if evt.GetId() == wx.ID_OK: # This should always be called when the dialog is closed. Seems to be working correctly. self.pedal_connector.remove_callback("fiducial", panel=self) @@ -4273,7 +4250,7 @@ def OnOk(self, evt): class ICPCorregistrationDialog(wx.Dialog): - def __init__(self, navigation, tracker): + def __init__(self, navigation: "Navigation", tracker: "Tracker"): import invesalius.project as prj self.tracker = tracker @@ -4307,7 +4284,7 @@ def __init__(self, navigation, tracker): self._init_gui() - def _init_gui(self): + def _init_gui(self) -> None: self.interactor = wxVTKRenderWindowInteractor(self, -1, size=self.GetSize()) self.interactor.Enable(1) self.ren = vtkRenderer() @@ -4401,7 +4378,7 @@ def _init_gui(self): self.SetSizer(main_sizer) main_sizer.Fit(self) - def LoadActor(self): + def LoadActor(self) -> None: """ Load the selected actor from the project (self.surface) into the scene :return: @@ -4444,7 +4421,7 @@ def LoadActor(self): self.ren.ResetCamera() self.interactor.Render() - def RemoveAllActors(self): + def RemoveAllActors(self) -> None: self.ren.RemoveAllViewProps() self.actors_static_points = [] self.point_coord = [] @@ -4456,21 +4433,21 @@ def RemoveAllActors(self): self.ren.ResetCamera() self.interactor.Render() - def RemoveSinglePointActor(self): + def RemoveSinglePointActor(self) -> None: self.ren.RemoveActor(self.actors_static_points[-1]) self.actors_static_points.pop() self.point_coord.pop() self.collect_points.SetValue(str(int(self.collect_points.GetValue()) - 1)) self.interactor.Render() - def GetCurrentCoord(self): + def GetCurrentCoord(self) -> Tuple[Tuple, List[bool]]: coord_raw, marker_visibilities = self.tracker.TrackerCoordinates.GetCoordinates() coord, _ = dcr.corregistrate_dynamic( (self.m_change, 0), coord_raw, const.DEFAULT_REF_MODE, [None, None] ) return coord[:3], marker_visibilities - def AddMarker(self, size, colour, coord): + def AddMarker(self, size: int, colour: Tuple[int, int, int], coord: np.ndarray) -> None: """ Points are rendered into the scene. These points give visual information about the registration. :param size: value of the marker size @@ -4513,11 +4490,11 @@ def AddMarker(self, size, colour, coord): if self.progress.GetValue() != 0: self.SetProgress(0) - def SetProgress(self, progress): + def SetProgress(self, progress: float) -> None: self.progress.SetValue(int(progress * 100)) self.interactor.Render() - def vtkmatrix_to_numpy(self, matrix): + def vtkmatrix_to_numpy(self, matrix: vtkMatrix4x4) -> np.ndarray: """ Copies the elements of a vtkMatrix4x4 into a numpy array. @@ -4531,7 +4508,7 @@ def vtkmatrix_to_numpy(self, matrix): m[i, j] = matrix.GetElement(i, j) return m - def SetCameraVolume(self, position): + def SetCameraVolume(self, position: Sequence[float]) -> None: """ Positioning of the camera based on the acquired point :param position: x, y, z of the last acquired point @@ -4560,12 +4537,14 @@ def SetCameraVolume(self, position): self.interactor.Render() - def CheckTransformedPointsDistribution(self, points): + def CheckTransformedPointsDistribution( + self, points: Union[Sequence[float], np.ndarray] + ) -> np.floating: from scipy.spatial.distance import pdist return np.mean(pdist(points)) - def ErrorEstimation(self, surface, points): + def ErrorEstimation(self, surface, points: np.ndarray) -> np.floating: """ Estimation of the average squared distance between the cloud of points to the closest mesh :param surface: Surface polydata of the scene @@ -4589,7 +4568,7 @@ def ErrorEstimation(self, surface, points): return np.mean(error) - def DistanceBetweenPointAndSurface(self, surface, points): + def DistanceBetweenPointAndSurface(self, surface, points: np.ndarray) -> np.floating: """ Estimation of the squared distance between the point to the closest mesh :param surface: Surface polydata of the scene @@ -4610,7 +4589,7 @@ def DistanceBetweenPointAndSurface(self, surface, points): return np.sqrt(float(d)) - def OnComboName(self, evt): + def OnComboName(self, evt: wx.CommandEvent) -> None: surface_name = evt.GetString() surface_index = evt.GetSelection() self.surface = self.proj.surface_dict[surface_index].polydata @@ -4618,20 +4597,23 @@ def OnComboName(self, evt): self.RemoveAllActors() self.LoadActor() - def OnChoiceICPMethod(self, evt): + def OnChoiceICPMethod(self, evt: wx.CommandEvent) -> None: self.icp_mode = evt.GetSelection() - def OnContinuousAcquisitionButton(self, evt=None, btn=None): + def OnContinuousAcquisitionButton( + self, evt: Optional[wx.CommandEvent] = None, btn: Optional[wx.ToggleButton] = None + ) -> None: + assert btn is not None, "btn must be provided" value = btn.GetValue() if value: self.timer.Start(500) else: self.timer.Stop() - def HandleContinuousAcquisition(self, evt): + def HandleContinuousAcquisition(self, evt: wx.TimerEvent) -> None: self.CreatePoint() - def CreatePoint(self, evt=None): + def CreatePoint(self, evt: Optional[wx.CommandEvent] = None) -> None: current_coord, marker_visibilities = self.GetCurrentCoord() probe_visible, head_visible, _ = marker_visibilities @@ -4648,7 +4630,7 @@ def CreatePoint(self, evt=None): self.txt_markers_not_detected.VisibilityOn() self.interactor.Render() - def OnDeleteLastPoint(self): + def OnDeleteLastPoint(self) -> None: # Stop continuous acquisition if it is running. if self.cont_point: self.cont_point.SetValue(False) @@ -4656,7 +4638,7 @@ def OnDeleteLastPoint(self): self.RemoveSinglePointActor() - def OnResetPoints(self, evt): + def OnResetPoints(self, evt: wx.CommandEvent) -> None: # Stop continuous acquisition if it is running. if self.cont_point: self.cont_point.SetValue(False) @@ -4665,7 +4647,7 @@ def OnResetPoints(self, evt): self.RemoveAllActors() self.LoadActor() - def OnICP(self, evt): + def OnICP(self, evt: wx.CommandEvent) -> None: if self.cont_point: self.cont_point.SetValue(False) self.OnContinuousAcquisitionButton(evt=None, btn=self.cont_point) @@ -4713,7 +4695,7 @@ def OnICP(self, evt): icpTransformFilter.SetTransform(icp) icpTransformFilter.Update() - transformedSource = icpTransformFilter.GetOutput() + transformedSource: vtkPolyData = icpTransformFilter.GetOutput() transformed_points = [] @@ -4786,11 +4768,11 @@ def __init__(self): self.brain_surface = None self.scalp_surface = None - def _init_gui(self): + def _init_gui(self) -> None: tooltip = _("Load Brain Meshes") btn_act = wx.Button(self, -1, _("Load"), size=wx.Size(100, 23)) btn_act.SetToolTip(tooltip) - btn_act.Enable(1) + btn_act.Enable(True) btn_act.Bind(wx.EVT_BUTTON, self.OnAddMeshes) txt_brain_surface = wx.StaticText(self, -1, _("Select the brain surface:")) @@ -4850,17 +4832,17 @@ def _init_gui(self): self.SetSizer(main_sizer) main_sizer.Fit(self) - def OnComboNameBrainSurface(self, evt): + def OnComboNameBrainSurface(self, evt: wx.CommandEvent) -> Union[str, vtkPolyData]: surface_index = evt.GetSelection() self.brain_surface = self.proj.surface_dict[surface_index].polydata return self.brain_surface - def OnComboNameScalpSurface(self, evt): + def OnComboNameScalpSurface(self, evt: wx.CommandEvent) -> Union[str, vtkPolyData]: surface_index = evt.GetSelection() self.scalp_surface = self.proj.surface_dict[surface_index].polydata return self.scalp_surface - def OnAddMeshes(self, evt): + def OnAddMeshes(self, evt: wx.CommandEvent) -> None: filename = ShowImportMeshFilesDialog() if filename: convert_to_inv = ImportMeshCoordSystem() @@ -4869,7 +4851,13 @@ def OnAddMeshes(self, evt): class CreateBrainTargetDialog(wx.Dialog): - def __init__(self, marker, mTMS=None, brain_target=False, brain_actor=None): + def __init__( + self, + marker, + mTMS: Optional["mTMS"] = None, + brain_target: bool = False, + brain_actor: Optional[vtkActor] = None, + ): import invesalius.project as prj self.obj_actor = None @@ -4908,7 +4896,7 @@ def __init__(self, marker, mTMS=None, brain_target=False, brain_actor=None): self._init_gui() - def _init_gui(self): + def _init_gui(self) -> None: self.interactor = wxVTKRenderWindowInteractor(self, -1, size=self.GetSize()) self.interactor.Enable(1) self.ren = vtkRenderer() @@ -5102,7 +5090,7 @@ def _init_gui(self): self.SetSizer(main_sizer) main_sizer.Fit(self) - def get_vtk_mouse_position(self): + def get_vtk_mouse_position(self) -> Tuple[int, int]: """ Get Mouse position inside a wxVTKRenderWindowInteractorself. Return a tuple with X and Y position. @@ -5123,7 +5111,7 @@ def get_vtk_mouse_position(self): my *= scale return int(mx), int(my) - def OnCreateDummyCoil(self, target_actor): + def OnCreateDummyCoil(self, target_actor: vtkActor) -> None: if self.dummy_coil_actor: self.RemoveActor(self.dummy_coil_actor) @@ -5160,7 +5148,7 @@ def OnCreateDummyCoil(self, target_actor): self.dummy_coil_actor.PickableOff() self.ren.AddActor(self.dummy_coil_actor) - def OnWheelMouseClick(self, obj, evt): + def OnWheelMouseClick(self, obj, evt) -> None: x, y = self.get_vtk_mouse_position() self.picker.Pick(x, y, 0, self.ren) if self.picker.GetActor(): @@ -5179,7 +5167,7 @@ def OnWheelMouseClick(self, obj, evt): self.OnCreateDummyCoil(self.marker_actor) self.interactor.Render() - def OnCrossMouseClick(self, obj, evt): + def OnCrossMouseClick(self, obj, evt) -> None: if self.brain_target: self.obj_actor.PickableOn() if self.peel_brain_actor: @@ -5202,17 +5190,17 @@ def OnCrossMouseClick(self, obj, evt): self.peel_brain_actor.PickableOff() self.interactor.Render() - def OnCheckBoxScalp(self, evt=None): + def OnCheckBoxScalp(self, evt: Optional[wx.CommandEvent] = None) -> None: status = self.chk_show_surface.GetValue() self.obj_actor.SetVisibility(status) self.interactor.Render() - def OnCheckBoxBrain(self, evt=None): + def OnCheckBoxBrain(self, evt: Optional[wx.CommandEvent] = None) -> None: status = self.chk_show_brain_surface.GetValue() self.brain_actor.SetVisibility(status) self.interactor.Render() - def OnResetOrientation(self, evt=None): + def OnResetOrientation(self, evt: Optional[wx.CommandEvent] = None) -> None: self.rotationX = self.rotationY = self.rotationZ = 0 self.slider_rotation_x.SetValue(0) self.slider_rotation_y.SetValue(0) @@ -5220,22 +5208,22 @@ def OnResetOrientation(self, evt=None): self.marker_actor.SetOrientation(self.rotationX, self.rotationY, self.rotationZ) self.interactor.Render() - def OnRotationX(self, evt): + def OnRotationX(self, evt: wx.CommandEvent) -> None: self.rotationX = evt.GetInt() self.marker_actor.SetOrientation(self.rotationX, self.rotationY, self.rotationZ) self.interactor.Render() - def OnRotationY(self, evt): + def OnRotationY(self, evt: wx.CommandEvent) -> None: self.rotationY = evt.GetInt() self.marker_actor.SetOrientation(self.rotationX, self.rotationY, self.rotationZ) self.interactor.Render() - def OnRotationZ(self, evt): + def OnRotationZ(self, evt: wx.CommandEvent) -> None: self.rotationZ = evt.GetInt() self.marker_actor.SetOrientation(self.rotationX, self.rotationY, self.rotationZ) self.interactor.Render() - def OnDepth(self, evt): + def OnDepth(self, evt: wx.KeyEvent) -> None: if evt.GetKeyCode() == wx.WXK_UP: depth = 1 elif evt.GetKeyCode() == wx.WXK_DOWN: @@ -5245,30 +5233,30 @@ def OnDepth(self, evt): self.marker_actor.AddPosition(0, 0, depth) self.interactor.Render() - def OnPressLeftButton(self, evt, obj): + def OnPressLeftButton(self, evt, obj) -> None: self.spinning = True - def OnReleaseLeftButton(self, evt, obj): + def OnReleaseLeftButton(self, evt, obj) -> None: self.spinning = False - def OnSpinMove(self, evt, obj): + def OnSpinMove(self, evt, obj) -> None: self.interactor.SetInteractorStyle(self.actor_style) if self.spinning: evt.Spin() evt.OnRightButtonDown() - def OnZoomMove(self, evt, obj): + def OnZoomMove(self, evt, obj) -> None: self.interactor.SetInteractorStyle(self.camera_style) if obj == "MouseWheelForwardEvent": self.camera_style.OnMouseWheelForward() else: self.camera_style.OnMouseWheelBackward() - def OnChangeView(self, evt): + def OnChangeView(self, evt: wx.CommandEvent) -> None: self.ren.GetActiveCamera().Roll(90) self.interactor.Render() - def OnComboNameBrainSurface(self, evt): + def OnComboNameBrainSurface(self, evt: wx.CommandEvent) -> None: surface_index = evt.GetSelection() self.brain_surface = self.proj.surface_dict[surface_index].polydata if self.brain_actor: @@ -5276,7 +5264,7 @@ def OnComboNameBrainSurface(self, evt): self.brain_actor = self.LoadActor(self.brain_surface) self.chk_show_brain_surface.SetValue(True) - def OnComboNameScalpSurface(self, evt): + def OnComboNameScalpSurface(self, evt: wx.CommandEvent) -> None: surface_index = evt.GetSelection() self.surface = self.proj.surface_dict[surface_index].polydata if self.obj_actor: @@ -5293,7 +5281,11 @@ def OnComboNameScalpSurface(self, evt): self.coil_pose_actor = self.LoadTarget() self.chk_show_surface.SetValue(True) - def LoadCenterBrainTarget(self, coil_target_position, coil_target_orientation): + def LoadCenterBrainTarget( + self, + coil_target_position: Union[Sequence, np.ndarray], + coil_target_orientation: Union[Sequence, np.ndarray], + ) -> None: m_coil = dco.coordinates_to_transformation_matrix( position=coil_target_position, orientation=coil_target_orientation, @@ -5321,7 +5313,7 @@ def LoadCenterBrainTarget(self, coil_target_position, coil_target_orientation): print("Adding brain markers") - def LoadTarget(self): + def LoadTarget(self) -> vtkActor: coord_flip = list(self.marker) coord_flip[1] = -coord_flip[1] if self.brain_target: @@ -5356,7 +5348,7 @@ def LoadTarget(self): return marker_actor - def LoadActor(self, surface): + def LoadActor(self, surface: vtkPolyData) -> vtkActor: """ Load the selected actor from the project (self.surface) into the scene :return: @@ -5378,16 +5370,21 @@ def LoadActor(self, surface): return obj_actor - def RemoveActor(self, actor): + def RemoveActor(self, actor: vtkActor) -> None: self.ren.RemoveActor(actor) self.interactor.Render() - def RemoveAllActor(self): + def RemoveAllActor(self) -> None: self.ren.RemoveAllViewProps() self.ren.ResetCamera() self.interactor.Render() - def AddTarget(self, coord_flip, colour=[0.0, 0.0, 1.0], scale=10): + def AddTarget( + self, + coord_flip: Sequence[float], + colour: MutableSequence[float] = [0.0, 0.0, 1.0], + scale: float = 10, + ) -> Tuple[vtkActor, Tuple[float, float, float, float, float, float]]: rx, ry, rz = coord_flip[3:] if rx is None: coord = self.Versor(self.CenterOfMass(self.brain_surface), coord_flip[:3]) @@ -5485,7 +5482,7 @@ def CreateActorArrow(self, m_img_vtk, colour, size=const.ARROW_MARKER_SIZE): return actor - def vtkmatrix2numpy(self, matrix): + def vtkmatrix2numpy(self, matrix: vtkMatrix4x4) -> np.ndarray: """ Copies the elements of a vtkMatrix4x4 into a numpy array. param matrix: The matrix to be copied into an array. @@ -5498,7 +5495,9 @@ def vtkmatrix2numpy(self, matrix): m[i, j] = matrix.GetElement(i, j) return m - def ICP(self, coord, center, surface): + def ICP( + self, coord: Sequence[float], center: Sequence, surface: vtkPolyData + ) -> Tuple[int, int, int, None, None, None]: """ Apply ICP transforms to fit the spiral points to the surface Args: @@ -5569,14 +5568,14 @@ def ICP(self, coord, center, surface): # self.ActorCollection.AddItem(actor) # self.interactor.Render() # coord = p[0], p[1], p[2], center[3], center[4], center[5] - coord = p[0], p[1], p[2], None, None, None + ret = p[0], p[1], p[2], None, None, None - return coord + return ret # p[1] = -p[1] # self.icp_points.append(p) - def CreateSphere(self, center, radius): + def CreateSphere(self, center: Sequence[float], radius: float) -> vtkPolyData: point = vtkSphereSource() point.SetCenter(center) point.SetRadius(radius) @@ -5595,7 +5594,7 @@ def CreateSphere(self, center, radius): return point.GetOutput() - def CreateGrid(self, resolution, space_x, space_y): + def CreateGrid(self, resolution: int, space_x: float, space_y: float) -> List[np.ndarray]: minX, maxX, minY, maxY = -space_x, space_x, -space_y, space_y # create one-dimensional arrays for x and y x = np.linspace(minX, maxX, resolution) @@ -5603,7 +5602,7 @@ def CreateGrid(self, resolution, space_x, space_y): return np.meshgrid(x, y) - def OnCreateRandomTargetGrid(self, evt): + def OnCreateRandomTargetGrid(self, evt: wx.CommandEvent) -> None: vtkmat = self.coil_pose_actor.GetMatrix() narray = np.eye(4) vtkmat.DeepCopy(narray.ravel(), vtkmat) @@ -5658,7 +5657,7 @@ def OnCreateRandomTargetGrid(self, evt): self.interactor.Render() - def OnCreateTargetGrid(self, evt): + def OnCreateTargetGrid(self, evt: wx.CommandEvent) -> None: vtkmat = self.coil_pose_actor.GetMatrix() narray = np.eye(4) vtkmat.DeepCopy(narray.ravel(), vtkmat) @@ -5711,7 +5710,7 @@ def OnCreateTargetGrid(self, evt): self.interactor.Render() - def OnCreateBrainGrid(self, evt): + def OnCreateBrainGrid(self, evt: wx.CommandEvent) -> None: if self.coil_target_actor_list: for coil_target_actor in self.coil_target_actor_list: vtkmat = coil_target_actor.GetMatrix() @@ -5747,7 +5746,7 @@ def OnCreateBrainGrid(self, evt): self.brain_target_actor_list.append(brain_target_actor) print("Adding brain markers") - def OnSendMtms(self, evt=None): + def OnSendMtms(self, evt: Optional[wx.CommandEvent] = None) -> None: vtkmat = self.marker_actor.GetMatrix() narray = np.eye(4) vtkmat.DeepCopy(narray.ravel(), vtkmat) @@ -5757,7 +5756,12 @@ def OnSendMtms(self, evt=None): if self.mTMS: self.mTMS.UpdateTarget(coil_pose=self.marker, brain_target=position + orientation) - def CreateVTKObjectMatrix(self, direction, orientation, new_target): + def CreateVTKObjectMatrix( + self, + direction: "Sequence[float] | np.ndarray", + orientation: "Sequence[float] | np.ndarray", + new_target: bool, + ) -> Tuple[vtkMatrix4x4, float, float, float]: m_img = dco.coordinates_to_transformation_matrix( position=direction, orientation=orientation, @@ -5778,7 +5782,13 @@ def CreateVTKObjectMatrix(self, direction, orientation, new_target): return m_img_vtk_rotate, rx, ry, rz - def GetRotationMatrix(self, v1_start, v2_start, v1_target, v2_target): + def GetRotationMatrix( + self, + v1_start: np.ndarray, + v2_start: np.ndarray, + v1_target: np.ndarray, + v2_target: np.ndarray, + ) -> np.ndarray: """ based on https://stackoverflow.com/questions/15101103/euler-angles-between-two-3d-vectors calculating M the rotation matrix from base U to base V @@ -5801,7 +5811,9 @@ def GetRotationMatrix(self, v1_start, v2_start, v1_target, v2_target): return np.dot(V, np.linalg.inv(U)) - def GetEulerAnglesFromVectors(self, init_arrow_vector, target_arrow_vector): + def GetEulerAnglesFromVectors( + self, init_arrow_vector: np.ndarray, target_arrow_vector + ) -> np.ndarray: import invesalius.data.transformations as tr init_up_vector = self.GetPerpendicularVector(init_arrow_vector) @@ -5812,7 +5824,7 @@ def GetEulerAnglesFromVectors(self, init_arrow_vector, target_arrow_vector): return np.rad2deg(tr.euler_from_matrix(rot_mat, axes="sxyz")) - def CenterOfMass(self, surface): + def CenterOfMass(self, surface: vtkPolyData) -> List[float]: barycenter = [0.0, 0.0, 0.0] n = surface.GetNumberOfPoints() for i in range(n): @@ -5826,10 +5838,14 @@ def CenterOfMass(self, surface): return barycenter - def Normalize(self, v): + def Normalize(self, v: np.ndarray) -> np.ndarray: return v / np.linalg.norm(v) - def Versor(self, init_point, final_point): + def Versor( + self, + init_point: Union[Sequence[float], np.ndarray], + final_point: Union[Sequence[float], np.ndarray], + ) -> List[float]: init_point = np.array(init_point) final_point = np.array(final_point) norm = (sum((final_point - init_point) ** 2)) ** 0.5 @@ -5837,23 +5853,25 @@ def Versor(self, init_point, final_point): return versor_factor - def GetPerpendicularVector(self, vector): + def GetPerpendicularVector(self, vector: np.ndarray) -> np.ndarray: ez = np.array([0, 0, 1]) look_at_vector = self.Normalize(vector) up_vector = self.Normalize(ez - np.dot(look_at_vector, ez) * look_at_vector) return up_vector - def GetValue(self): + def GetValue( + self, + ) -> Tuple[List[List[np.float64]], List[np.ndarray], List[List[np.float64]], List[np.ndarray]]: self.ren.RemoveActor(self.peel_brain_actor) vtkmat = self.coil_pose_actor.GetMatrix() narray = np.eye(4) vtkmat.DeepCopy(narray.ravel(), vtkmat) - position = [narray[0][-1], -narray[1][-1], narray[2][-1]] + position: List[np.float64] = [narray[0][-1], -narray[1][-1], narray[2][-1]] m_rotation = [narray[0][:3], narray[1][:3], narray[2][:3]] coil_target_position = [position] coil_target_orientation = [np.rad2deg(tr.euler_from_matrix(m_rotation, axes="sxyz"))] - brain_target_position = [] + brain_target_position: List[List[np.float64]] = [] brain_target_orientation = [] for coil_target_actor in self.coil_target_actor_list: vtkmat = coil_target_actor.GetMatrix() @@ -5882,7 +5900,7 @@ def GetValue(self): brain_target_orientation, ) - def GetValueBrainTarget(self): + def GetValueBrainTarget(self) -> Tuple[List[List[np.float64]], List[np.ndarray]]: import invesalius.data.transformations as tr brain_target_position = [] @@ -5891,7 +5909,7 @@ def GetValueBrainTarget(self): vtkmat = brain_target_actor.GetMatrix() narray = np.eye(4) vtkmat.DeepCopy(narray.ravel(), vtkmat) - position = [narray[0][-1], -narray[1][-1], narray[2][-1]] + position: List[np.float64] = [narray[0][-1], -narray[1][-1], narray[2][-1]] m_rotation = [narray[0][:3], narray[1][:3], narray[2][:3]] orientation = np.rad2deg(tr.euler_from_matrix(m_rotation, axes="sxyz")) brain_target_position.append(position) @@ -5899,8 +5917,8 @@ def GetValueBrainTarget(self): return brain_target_position, brain_target_orientation -class TractographyProgressWindow(object): - def __init__(self, msg): +class TractographyProgressWindow: + def __init__(self, msg: str): self.title = "InVesalius 3" self.msg = msg self.style = wx.PD_APP_MODAL | wx.PD_APP_MODAL | wx.PD_CAN_ABORT @@ -5909,20 +5927,20 @@ def __init__(self, msg): self.error = None self.dlg.Show() - def WasCancelled(self): + def WasCancelled(self) -> bool: return self.dlg.WasCancelled() - def Update(self, msg=None, value=None): + def Update(self, msg: Optional[str] = None, value=None) -> None: if msg is None: self.dlg.Pulse() else: self.dlg.Pulse(msg) - def Close(self): + def Close(self) -> None: self.dlg.Destroy() -class SurfaceSmoothingProgressWindow(object): +class SurfaceSmoothingProgressWindow: def __init__(self): title = "InVesalius 3" message = _("Smoothing the surface...") @@ -5932,11 +5950,11 @@ def __init__(self): self.dlg = wx.ProgressDialog(title, message, parent=parent, style=style) self.dlg.Show() - def Close(self): + def Close(self) -> None: self.dlg.Destroy() -class SurfaceProgressWindow(object): +class SurfaceProgressWindow: def __init__(self): self.title = "InVesalius 3" self.msg = _("Creating 3D surface ...") @@ -5946,22 +5964,22 @@ def __init__(self): self.error = None self.dlg.Show() - def WasCancelled(self): + def WasCancelled(self) -> bool: # print("Cancelled?", self.dlg.WasCancelled()) return self.dlg.WasCancelled() - def Update(self, msg=None, value=None): + def Update(self, msg: Optional[str] = None, value=None) -> None: if msg is None: self.dlg.Pulse() else: self.dlg.Pulse(msg) - def Close(self): + def Close(self) -> None: self.dlg.Destroy() class GoToDialog(wx.Dialog): - def __init__(self, title=_("Go to slice ..."), init_orientation=const.AXIAL_STR): + def __init__(self, title: str = _("Go to slice ..."), init_orientation: str = const.AXIAL_STR): wx.Dialog.__init__( self, wx.GetApp().GetTopWindow(), @@ -5971,7 +5989,7 @@ def __init__(self, title=_("Go to slice ..."), init_orientation=const.AXIAL_STR) ) self._init_gui(init_orientation) - def _init_gui(self, init_orientation): + def _init_gui(self, init_orientation: str) -> None: orientations = ( (_("Axial"), const.AXIAL_STR), (_("Coronal"), const.CORONAL_STR), @@ -6026,10 +6044,10 @@ def _init_gui(self, init_orientation): btn_ok.Bind(wx.EVT_BUTTON, self.OnOk) - def __bind_events(self): + def __bind_events(self) -> None: Publisher.subscribe(self.SetNewFocalPoint, "Cross focal point") - def OnOk(self, evt): + def OnOk(self, evt: wx.CommandEvent) -> None: try: slice_number = int(self.goto_slice.GetValue()) orientation = self.orientation = self.goto_orientation.GetClientData( @@ -6043,7 +6061,7 @@ def OnOk(self, evt): pass self.Close() - def SetNewFocalPoint(self, coord, spacing): + def SetNewFocalPoint(self, coord: Iterable[int], spacing: Sequence[int]) -> None: newCoord = list(coord) if self.orientation == "AXIAL": newCoord[2] = int(self.goto_slice.GetValue()) * spacing[2] @@ -6054,13 +6072,13 @@ def SetNewFocalPoint(self, coord, spacing): Publisher.sendMessage("Update cross pos", coord=newCoord) - def Close(self): + def Close(self) -> None: wx.Dialog.Close(self) self.Destroy() class GoToDialogScannerCoord(wx.Dialog): - def __init__(self, title=_("Go to scanner coord...")): + def __init__(self, title: str = _("Go to scanner coord...")): wx.Dialog.__init__( self, wx.GetApp().GetTopWindow(), @@ -6070,7 +6088,7 @@ def __init__(self, title=_("Go to scanner coord...")): ) self._init_gui() - def _init_gui(self): + def _init_gui(self) -> None: self.goto_sagital = wx.TextCtrl(self, size=(50, -1)) self.goto_coronal = wx.TextCtrl(self, size=(50, -1)) self.goto_axial = wx.TextCtrl(self, size=(50, -1)) @@ -6116,13 +6134,13 @@ def _init_gui(self): btn_ok.Bind(wx.EVT_BUTTON, self.OnOk) - def __bind_events(self): + def __bind_events(self) -> None: Publisher.subscribe(self.SetNewFocalPoint, "Cross focal point") def SetNewFocalPoint(self, coord, spacing): Publisher.sendMessage("Update cross pos", coord=self.result * spacing) - def OnOk(self, evt): + def OnOk(self, evt: wx.CommandEvent) -> None: import invesalius.data.slice_ as slc try: @@ -6151,13 +6169,13 @@ def OnOk(self, evt): pass self.Close() - def Close(self): + def Close(self) -> None: wx.Dialog.Close(self) self.Destroy() class SelectNiftiVolumeDialog(wx.Dialog): - def __init__(self, volumes, title=_("Select NIfTI volume")): + def __init__(self, volumes: Sequence[str], title: str = _("Select NIfTI volume")): wx.Dialog.__init__( self, wx.GetApp().GetTopWindow(), @@ -6168,7 +6186,7 @@ def __init__(self, volumes, title=_("Select NIfTI volume")): self._init_gui(volumes) - def _init_gui(self, volumes): + def _init_gui(self, volumes: Sequence[str]) -> None: self.cmb_volume = wx.ComboBox( self, -1, choices=volumes, style=wx.CB_DROPDOWN | wx.CB_READONLY ) @@ -6201,13 +6219,13 @@ def _init_gui(self, volumes): # self.Layout() self.CenterOnParent() - def GetVolumeChoice(self): + def GetVolumeChoice(self) -> int: volume_choice = int(self.cmb_volume.GetString(self.cmb_volume.GetSelection())) - 1 return volume_choice -def DialogRescalePixelIntensity(max_intensity, unique_values): +def DialogRescalePixelIntensity(max_intensity: float, unique_values: Any) -> bool: msg = ( _("Maximum pixel intensity is: ") + str(round(max_intensity, 1)) @@ -6233,7 +6251,7 @@ def DialogRescalePixelIntensity(max_intensity, unique_values): class ConfigureOptitrackDialog(wx.Dialog): - def __init__(self, title=_("Configure Optitrack")): + def __init__(self, title: str = _("Configure Optitrack")): wx.Dialog.__init__( self, wx.GetApp().GetTopWindow(), @@ -6247,7 +6265,7 @@ def __init__(self, title=_("Configure Optitrack")): ) self._init_gui() - def _init_gui(self): + def _init_gui(self) -> None: session = ses.Session() last_optitrack_cal_dir = session.GetConfig("last_optitrack_cal_dir", "") last_optitrack_User_Profile_dir = session.GetConfig("last_optitrack_User_Profile_dir", "") @@ -6311,7 +6329,7 @@ def _init_gui(self): self.CenterOnParent() - def GetValue(self): + def GetValue(self) -> Tuple[str, str]: fn_cal = self.dir_cal.GetPath() fn_userprofile = self.dir_UserProfile.GetPath() @@ -6329,7 +6347,7 @@ class SetTrackerDeviceToRobot(wx.Dialog): A dialog pops up showing a combobox with all trackers but debugs and the robot itself (const.TRACKERS[:-3]) """ - def __init__(self, title=_("Set tracker device")): + def __init__(self, title: str = _("Set tracker device")): wx.Dialog.__init__( self, wx.GetApp().GetTopWindow(), @@ -6344,7 +6362,7 @@ def __init__(self, title=_("Set tracker device")): self.tracker_id = const.DEFAULT_TRACKER self._init_gui() - def _init_gui(self): + def _init_gui(self) -> None: # ComboBox for spatial tracker device selection tooltip = _("Choose the tracking device") trackers = const.TRACKERS.copy() @@ -6386,16 +6404,16 @@ def _init_gui(self): self.CenterOnParent() - def OnChoiceTracker(self, evt, ctrl): + def OnChoiceTracker(self, evt: wx.CommandEvent, ctrl: wx.ComboBox) -> None: choice = evt.GetSelection() self.tracker_id = choice - def GetValue(self): + def GetValue(self) -> int: return self.tracker_id class SetRobotIP(wx.Dialog): - def __init__(self, title=_("Set Robot IP")): + def __init__(self, title: str = _("Set Robot IP")): wx.Dialog.__init__( self, wx.GetApp().GetTopWindow(), @@ -6410,7 +6428,7 @@ def __init__(self, title=_("Set Robot IP")): self.robot_ip = None self._init_gui() - def _init_gui(self): + def _init_gui(self) -> None: # ComboBox for spatial tracker device selection tooltip = _("Choose or type the robot IP") robot_ip_options = [_("Select robot IP:")] + const.ROBOT_ElFIN_IP @@ -6447,18 +6465,23 @@ def _init_gui(self): self.CenterOnParent() - def OnTxt_Ent(self, evt, ctrl): + def OnTxt_Ent(self, evt: wx.CommandEvent, ctrl: wx.TextEntry) -> None: self.robot_ip = str(ctrl.GetValue()) - def OnChoiceIP(self, evt, ctrl): + def OnChoiceIP(self, evt: wx.CommandEvent, ctrl: wx.ComboBox) -> None: self.robot_ip = ctrl.GetStringSelection() - def GetValue(self): + def GetValue(self) -> Optional[str]: return self.robot_ip class RobotCoregistrationDialog(wx.Dialog): - def __init__(self, robot, tracker, title=_("Create transformation matrix to robot space")): + def __init__( + self, + robot: "Robot", + tracker: "Tracker", + title: str = _("Create transformation matrix to robot space"), + ): wx.Dialog.__init__( self, wx.GetApp().GetTopWindow(), @@ -6482,7 +6505,7 @@ def __init__(self, robot, tracker, title=_("Create transformation matrix to robo self._init_gui() - def _init_gui(self): + def _init_gui(self) -> None: # Buttons to acquire and remove points txt_acquisition = wx.StaticText(self, -1, _("Poses acquisition for robot registration:")) @@ -6594,7 +6617,7 @@ def _init_gui(self): self.CenterOnParent() self.__bind_events() - def __bind_events(self): + def __bind_events(self) -> None: Publisher.subscribe( self.UpdateRobotTransformationMatrix, "Robot to Neuronavigation: Update robot transformation matrix", @@ -6604,34 +6627,37 @@ def __bind_events(self): "Robot to Neuronavigation: Coordinates for the robot transformation matrix collected", ) - def OnContinuousAcquisitionButton(self, evt=None, btn=None): + def OnContinuousAcquisitionButton( + self, evt: Optional[wx.CommandEvent] = None, btn: Optional[wx.ToggleButton] = None + ) -> None: + assert btn is not None, "btn must be provided" value = btn.GetValue() if value: self.timer.Start(100) else: self.timer.Stop() - def StopContinuousAcquisition(self): + def StopContinuousAcquisition(self) -> None: if self.btn_cont_point: self.btn_cont_point.SetValue(False) self.OnContinuousAcquisitionButton(btn=self.btn_cont_point) - def HandleContinuousAcquisition(self, evt): + def HandleContinuousAcquisition(self, evt: wx.TimerEvent) -> None: self.CreatePoint() - def CreatePoint(self, evt=None): + def CreatePoint(self, evt: Optional[wx.CommandEvent] = None) -> None: Publisher.sendMessage( "Neuronavigation to Robot: Collect coordinates for the robot transformation matrix", data=None, ) - def GetAcquiredPoints(self): + def GetAcquiredPoints(self) -> int: return int(self.txt_number.GetLabel()) - def SetAcquiredPoints(self, num_points): + def SetAcquiredPoints(self, num_points: int) -> None: self.txt_number.SetLabel(str(num_points)) - def PointRegisteredByRobot(self): + def PointRegisteredByRobot(self) -> None: # Increment the number of acquired points. num_points = self.GetAcquiredPoints() num_points += 1 @@ -6641,7 +6667,7 @@ def PointRegisteredByRobot(self): if self.robot.IsConnected() and num_points >= 3: self.btn_apply_reg.Enable(True) - def ResetPoints(self, evt): + def ResetPoints(self, evt: wx.CommandEvent) -> None: Publisher.sendMessage( "Neuronavigation to Robot: Reset coordinates collection for the robot transformation matrix", data=None, @@ -6656,7 +6682,7 @@ def ResetPoints(self, evt): self.matrix_tracker_to_robot = [] - def ApplyRegistration(self, evt): + def ApplyRegistration(self, evt: wx.CommandEvent) -> None: self.StopContinuousAcquisition() Publisher.sendMessage( @@ -6668,10 +6694,10 @@ def ApplyRegistration(self, evt): # TODO: make a colored circle to sinalize that the transformation was made (green) (red if not) - def UpdateRobotTransformationMatrix(self, data): + def UpdateRobotTransformationMatrix(self, data: Any) -> None: self.matrix_tracker_to_robot = np.array(data) - def SaveRegistration(self, evt): + def SaveRegistration(self, evt: wx.CommandEvent) -> None: if self.matrix_tracker_to_robot is None: return @@ -6691,7 +6717,7 @@ def SaveRegistration(self, evt): writer = csv.writer(file, delimiter="\t") writer.writerows(np.vstack(self.matrix_tracker_to_robot).tolist()) - def LoadRegistration(self, evt): + def LoadRegistration(self, evt: wx.CommandEvent) -> None: # Open dialog to choose filename. filename = ShowLoadSaveDialog( message=_("Load robot transformation"), @@ -6701,7 +6727,7 @@ def LoadRegistration(self, evt): return # Load registration from file. - with open(filename, "r") as file: + with open(filename) as file: reader = csv.reader(file, delimiter="\t") content = [row for row in reader] @@ -6717,12 +6743,12 @@ def LoadRegistration(self, evt): if self.robot.IsConnected(): self.btn_ok.Enable(True) - def GetValue(self): + def GetValue(self) -> Optional[Union[np.ndarray, List]]: return self.matrix_tracker_to_robot class ConfigurePolarisDialog(wx.Dialog): - def __init__(self, title=_("Configure NDI Polaris")): + def __init__(self, title: str = _("Configure NDI Polaris")): wx.Dialog.__init__( self, wx.GetApp().GetTopWindow(), @@ -6736,14 +6762,14 @@ def __init__(self, title=_("Configure NDI Polaris")): ) self._init_gui() - def serial_ports(self): + def serial_ports(self) -> Tuple[List[str], List[int]]: """ Lists serial port names and pre-select the description containing NDI """ import serial.tools.list_ports - port_list = [] - desc_list = [] + port_list: List[str] = [] + desc_list: List[str] = [] ports = serial.tools.list_ports.comports() if sys.platform.startswith("win"): for port, desc, hwid in sorted(ports): @@ -6760,7 +6786,7 @@ def serial_ports(self): return port_list, port_selec - def _init_gui(self): + def _init_gui(self) -> None: com_ports = wx.ComboBox(self, -1, style=wx.CB_DROPDOWN) com_ports.Bind(wx.EVT_COMBOBOX, partial(self.OnChoicePort, ctrl=com_ports)) row_com = wx.BoxSizer(wx.VERTICAL) @@ -6858,10 +6884,10 @@ def _init_gui(self): self.CenterOnParent() - def OnChoicePort(self, evt, ctrl): + def OnChoicePort(self, evt: wx.CommandEvent, ctrl: wx.ComboBox) -> None: self.btn_ok.Enable(True) - def GetValue(self): + def GetValue(self) -> Tuple[str, str, str, str]: fn_probe = self.dir_probe.GetPath() fn_ref = self.dir_ref.GetPath() fn_obj = self.dir_obj.GetPath() @@ -6878,7 +6904,7 @@ def GetValue(self): class SetCOMPort(wx.Dialog): - def __init__(self, select_baud_rate, title=_("Select COM port")): + def __init__(self, select_baud_rate: bool, title: str = _("Select COM port")): wx.Dialog.__init__( self, wx.GetApp().GetTopWindow(), @@ -6890,7 +6916,7 @@ def __init__(self, select_baud_rate, title=_("Select COM port")): self.select_baud_rate = select_baud_rate self._init_gui() - def serial_ports(self): + def serial_ports(self) -> List[str]: """ Lists serial port names """ @@ -6899,10 +6925,10 @@ def serial_ports(self): if sys.platform.startswith("win"): ports = [comport.device for comport in serial.tools.list_ports.comports()] else: - raise EnvironmentError("Unsupported platform") + raise OSError("Unsupported platform") return ports - def _init_gui(self): + def _init_gui(self) -> None: # COM port selection ports = self.serial_ports() self.com_port_dropdown = wx.ComboBox( @@ -6962,11 +6988,11 @@ def _init_gui(self): self.CenterOnParent() - def GetCOMPort(self): + def GetCOMPort(self) -> str: com_port = self.com_port_dropdown.GetString(self.com_port_dropdown.GetSelection()) return com_port - def GetBaudRate(self): + def GetBaudRate(self) -> Optional[str]: if not self.select_baud_rate: return None @@ -6975,11 +7001,11 @@ def GetBaudRate(self): class ManualWWWLDialog(wx.Dialog): - def __init__(self, parent): + def __init__(self, parent: wx.Window): wx.Dialog.__init__(self, parent, -1, _("Set WW&WL manually")) self._init_gui() - def _init_gui(self): + def _init_gui(self) -> None: import invesalius.data.slice_ as slc ww = slc.Slice().window_width @@ -7020,7 +7046,7 @@ def _init_gui(self): self.Layout() self.Center() - def OnOK(self, evt): + def OnOK(self, evt: wx.CommandEvent) -> None: try: ww = int(self.txt_ww.GetValue()) wl = int(self.txt_wl.GetValue()) @@ -7038,22 +7064,22 @@ def OnOK(self, evt): self.Close() - def OnCancel(self, evt): + def OnCancel(self, evt: wx.CommandEvent) -> None: self.Close() - def OnClose(self, evt): + def OnClose(self, evt: wx.CloseEvent) -> None: self.Destroy() class SetSpacingDialog(wx.Dialog): def __init__( self, - parent, - sx, - sy, - sz, - title=_("Set spacing"), - style=wx.DEFAULT_DIALOG_STYLE | wx.FRAME_FLOAT_ON_PARENT, + parent: wx.Window, + sx: float, + sy: float, + sz: float, + title: str = _("Set spacing"), + style: int = wx.DEFAULT_DIALOG_STYLE | wx.FRAME_FLOAT_ON_PARENT, ): wx.Dialog.__init__(self, parent, -1, title=title, style=style) self.spacing_original_x = sx @@ -7063,7 +7089,7 @@ def __init__( self._init_gui() self._bind_events() - def _init_gui(self): + def _init_gui(self) -> None: self.txt_spacing_new_x = wx.TextCtrl(self, -1, value=str(self.spacing_original_x)) self.txt_spacing_new_y = wx.TextCtrl(self, -1, value=str(self.spacing_original_y)) self.txt_spacing_new_z = wx.TextCtrl(self, -1, value=str(self.spacing_original_z)) @@ -7105,7 +7131,7 @@ def _init_gui(self): main_sizer.Fit(self) self.Layout() - def _bind_events(self): + def _bind_events(self) -> None: self.txt_spacing_new_x.Bind(wx.EVT_KILL_FOCUS, self.OnSetNewSpacing) self.txt_spacing_new_y.Bind(wx.EVT_KILL_FOCUS, self.OnSetNewSpacing) self.txt_spacing_new_z.Bind(wx.EVT_KILL_FOCUS, self.OnSetNewSpacing) @@ -7113,7 +7139,7 @@ def _bind_events(self): self.button_ok.Bind(wx.EVT_BUTTON, self.OnOk) self.button_cancel.Bind(wx.EVT_BUTTON, self.OnCancel) - def OnSetNewSpacing(self, evt): + def OnSetNewSpacing(self, evt: wx.FocusEvent) -> None: try: new_spacing_x = float(self.txt_spacing_new_x.GetValue()) except ValueError: @@ -7131,7 +7157,7 @@ def OnSetNewSpacing(self, evt): self.set_new_spacing(new_spacing_x, new_spacing_y, new_spacing_z) - def set_new_spacing(self, sx, sy, sz): + def set_new_spacing(self, sx: float, sy: float, sz: float) -> None: self.spacing_new_x = sx self.spacing_new_y = sy self.spacing_new_z = sz @@ -7140,7 +7166,7 @@ def set_new_spacing(self, sx, sy, sz): self.txt_spacing_new_y.ChangeValue(str(sy)) self.txt_spacing_new_z.ChangeValue(str(sz)) - def OnOk(self, evt): + def OnOk(self, evt: wx.CommandEvent) -> None: if self.spacing_new_x == 0.0: self.txt_spacing_new_x.SetFocus() elif self.spacing_new_y == 0.0: @@ -7150,7 +7176,7 @@ def OnOk(self, evt): else: self.EndModal(wx.ID_OK) - def OnCancel(self, evt): + def OnCancel(self, evt: wx.CommandEvent) -> None: self.EndModal(wx.ID_CANCEL) @@ -7158,7 +7184,7 @@ class PeelsCreationDlg(wx.Dialog): FROM_MASK = 1 FROM_FILES = 2 - def __init__(self, parent, *args, **kwds): + def __init__(self, parent: wx.Window, *args, **kwds): wx.Dialog.__init__(self, parent, *args, **kwds) self.mask_path = "" @@ -7168,7 +7194,7 @@ def __init__(self, parent, *args, **kwds): self._bind_events_wx() self.get_all_masks() - def _init_gui(self): + def _init_gui(self) -> None: self.SetTitle(_("Create peel")) from_mask_stbox = self._from_mask_gui() @@ -7198,7 +7224,7 @@ def _init_gui(self): self.Layout() - def _from_mask_gui(self): + def _from_mask_gui(self) -> wx.StaticBoxSizer: mask_box = wx.StaticBox(self, -1, _("From mask")) from_mask_stbox = wx.StaticBoxSizer(mask_box, wx.VERTICAL) @@ -7213,7 +7239,7 @@ def _from_mask_gui(self): return from_mask_stbox - def _from_files_gui(self): + def _from_files_gui(self) -> wx.StaticBoxSizer: session = ses.Session() last_directory = session.GetConfig("last_directory_%d" % const.ID_NIFTI_IMPORT, "") @@ -7242,11 +7268,11 @@ def _from_files_gui(self): return from_files_stbox - def _bind_events_wx(self): + def _bind_events_wx(self) -> None: self.from_mask_rb.Bind(wx.EVT_RADIOBUTTON, self.on_select_method) self.from_files_rb.Bind(wx.EVT_RADIOBUTTON, self.on_select_method) - def get_all_masks(self): + def get_all_masks(self) -> None: import invesalius.project as prj inv_proj = prj.Project() @@ -7262,7 +7288,7 @@ def get_all_masks(self): self.cb_masks.SetValue(initial_value) self.btn_ok.Enable(enable) - def on_select_method(self, evt): + def on_select_method(self, evt: wx.CommandEvent) -> None: radio_selected = evt.GetEventObject() if radio_selected is self.from_mask_rb: self.method = self.FROM_MASK @@ -7277,7 +7303,7 @@ def on_select_method(self, evt): else: self.btn_ok.Enable(False) - def _set_files_callback(self, mask_path=""): + def _set_files_callback(self, mask_path: str = "") -> None: if mask_path: self.mask_path = mask_path if self.method == self.FROM_FILES: @@ -7286,12 +7312,12 @@ def _set_files_callback(self, mask_path=""): else: self.btn_ok.Enable(False) - def _check_if_files_exists(self): - return self.mask_path and os.path.exists(self.mask_path) + def _check_if_files_exists(self) -> bool: + return bool(self.mask_path and os.path.exists(self.mask_path)) class FileSelectionDialog(wx.Dialog): - def __init__(self, title, default_dir, wildcard): + def __init__(self, title: str, default_dir: str, wildcard: str): wx.Dialog.__init__(self, wx.GetApp().GetTopWindow()) self.SetTitle(title) @@ -7329,11 +7355,11 @@ def __init__(self, title, default_dir, wildcard): self.Layout() - def _from_files_gui(self): + def _from_files_gui(self) -> wx.StaticBoxSizer: files_box = wx.StaticBox(self, -1) from_files_static_box = wx.StaticBoxSizer(files_box, wx.VERTICAL) - def callback(evt): + def callback(evt) -> None: self._set_path(path=evt.GetString()) file_browse = filebrowse.FileBrowseButton( @@ -7355,21 +7381,25 @@ def callback(evt): return from_files_static_box - def _set_path(self, path=""): + def _set_path(self, path: str = "") -> None: self.path = path - def FitSizers(self): + def FitSizers(self) -> None: self._outer_sizer.Fit(self) - def GetPath(self): + def GetPath(self) -> str: return self.path class ProgressBarHandler(wx.ProgressDialog): - def __init__(self, parent, title="Progress Dialog", msg="Initializing...", max_value=None): - super(ProgressBarHandler, self).__init__( - title, msg, parent=parent, style=wx.PD_APP_MODAL | wx.PD_AUTO_HIDE - ) + def __init__( + self, + parent: wx.Window, + title: str = "Progress Dialog", + msg: str = "Initializing...", + max_value: Optional[float] = None, + ): + super().__init__(title, msg, parent=parent, style=wx.PD_APP_MODAL | wx.PD_AUTO_HIDE) self.max_value = max_value @@ -7378,15 +7408,15 @@ def __init__(self, parent, title="Progress Dialog", msg="Initializing...", max_v # self.Show() self.__bind_events() - def __bind_events(self): + def __bind_events(self) -> None: # Subscribe to pubsub messages Publisher.subscribe(self.update, "Update Progress bar") Publisher.subscribe(self.close, "Close Progress bar") - def was_cancelled(self): + def was_cancelled(self) -> bool: return super().WasCancelled() - def update(self, value, msg=None): + def update(self, value: float, msg: Optional[str] = None) -> None: if self.was_cancelled(): return @@ -7398,11 +7428,11 @@ def update(self, value, msg=None): value = self.max_value super().Update(int(value), msg) - def close(self): + def close(self) -> None: if self.IsShown(): self.Destroy() - def pulse(self, msg=None): + def pulse(self, msg: Optional[str] = None) -> None: # if self.IsShown(): if msg is None: super().Pulse() diff --git a/invesalius/gui/dicom_preview_panel.py b/invesalius/gui/dicom_preview_panel.py index f367243c1..83f3dea86 100644 --- a/invesalius/gui/dicom_preview_panel.py +++ b/invesalius/gui/dicom_preview_panel.py @@ -834,7 +834,7 @@ def OnRun(self): wx.Yield() # TODO: temporary fix necessary in the Windows XP 64 Bits # BUG in wxWidgets http://trac.wxwidgets.org/ticket/10896 - except wx._core.PyAssertionError: + except wx.PyAssertionError: utils.debug("wx._core.PyAssertionError") finally: wx.CallAfter(self.OnRun) diff --git a/invesalius/gui/frame.py b/invesalius/gui/frame.py index 39ed05bd3..2202786df 100644 --- a/invesalius/gui/frame.py +++ b/invesalius/gui/frame.py @@ -368,7 +368,7 @@ def _EndBusyCursor(self): """ try: wx.EndBusyCursor() - except wx._core.PyAssertionError: + except wx.PyAssertionError: # no matching wxBeginBusyCursor() for wxEndBusyCursor() pass @@ -1587,7 +1587,7 @@ def _SetProgressValue(self, value, label): try: # wx.SafeYield() wx.Yield() - except wx._core.PyAssertionError: + except wx.PyAssertionError: utils.debug("wx._core.PyAssertionError") def _SetProgressLabel(self, label): diff --git a/invesalius/gui/preferences.py b/invesalius/gui/preferences.py index 18fc9c057..cbca9968a 100644 --- a/invesalius/gui/preferences.py +++ b/invesalius/gui/preferences.py @@ -659,7 +659,7 @@ def OnCreateNewCoil(self, event=None): Publisher.sendMessage("Press target mode button", pressed=False) - except wx._core.PyAssertionError: # TODO FIX: win64 + except wx.PyAssertionError: # TODO FIX: win64 pass dialog.Destroy() else: diff --git a/invesalius/gui/task_slice.py b/invesalius/gui/task_slice.py index 274d4899f..e9ef6ccb2 100644 --- a/invesalius/gui/task_slice.py +++ b/invesalius/gui/task_slice.py @@ -223,7 +223,7 @@ def OnLinkNewMask(self, evt=None): ok = 1 else: ok = 0 - except wx._core.PyAssertionError: # TODO FIX: win64 + except wx.PyAssertionError: # TODO FIX: win64 ok = 1 if ok: diff --git a/invesalius/gui/task_surface.py b/invesalius/gui/task_surface.py index 78d076ec8..9729a001c 100644 --- a/invesalius/gui/task_surface.py +++ b/invesalius/gui/task_surface.py @@ -177,7 +177,7 @@ def OnLinkNewSurface(self, evt=None): ok = 1 else: ok = 0 - except wx._core.PyAssertionError: # TODO FIX: win64 + except wx.PyAssertionError: # TODO FIX: win64 ok = 1 if ok: diff --git a/invesalius/gui/widgets/canvas_renderer.py b/invesalius/gui/widgets/canvas_renderer.py index d97646f31..84737a04e 100644 --- a/invesalius/gui/widgets/canvas_renderer.py +++ b/invesalius/gui/widgets/canvas_renderer.py @@ -240,7 +240,7 @@ def OnMouseMove(self, evt: wx.MouseEvent) -> None: # self._drag_obj.mouse_move(evt_obj) else: was_over = self._over_obj - redraw = self.get_over_mouse_obj(x, y) or was_over + redraw = bool(self.get_over_mouse_obj(x, y) or was_over) if was_over and was_over != self._over_obj: try: @@ -995,7 +995,7 @@ def is_over(self, x: int, y: int) -> Optional[Self]: return self return None - def on_mouse_move(self, evt: Any) -> Literal[True]: + def on_mouse_move(self, evt: CanvasEvent) -> Literal[True]: mx, my = evt.position x, y, z = evt.viewer.get_coordinate_cursor(mx, my) self.position = [ @@ -1014,7 +1014,7 @@ def on_mouse_leave(self, evt: wx.Event) -> None: # self.layer = 0 self._highlight = False - def on_select(self, evt: Any) -> None: + def on_select(self, evt: CanvasEvent) -> None: mx, my = evt.position x, y, z = evt.viewer.get_coordinate_cursor(mx, my) self._last_position = (x, y, z) @@ -1063,7 +1063,7 @@ def draw_to_canvas(self, gc: wx.GraphicsContext, canvas: CanvasRendererCTX) -> N ) self.bbox = (x - w / 2, y - h / 2, x + w / 2, y + h / 2) - def on_mouse_move(self, evt: Any) -> Literal[True]: + def on_mouse_move(self, evt: CanvasEvent) -> Literal[True]: mx, my = evt.position if self.is_3d: x, y, z = evt.viewer.get_coordinate_cursor(mx, my) @@ -1157,7 +1157,7 @@ def append_point(self, point: Union[Tuple[float, float], Tuple[float, float]]) - self.handlers.append(handler) self.points.append(point) - def on_mouse_move(self, evt: Any) -> None: + def on_mouse_move(self, evt: CanvasEvent) -> None: if evt.root_event_obj is self: self.on_mouse_move2(evt) else: @@ -1169,7 +1169,7 @@ def is_over(self, x: int, y: int) -> Optional[Self]: if self.closed and self._path and self._path.Contains(x, -y): return self - def on_mouse_move2(self, evt: Any) -> Literal[True]: + def on_mouse_move2(self, evt: CanvasEvent) -> Literal[True]: mx, my = evt.position if self.is_3d: x, y, z = evt.viewer.get_coordinate_cursor(mx, my) @@ -1197,7 +1197,7 @@ def on_mouse_leave(self, evt: wx.Event) -> None: # self.interactive = False # self.layer = 0 - def on_select(self, evt: Any) -> None: + def on_select(self, evt: CanvasEvent) -> None: mx, my = evt.position self.interactive = True print("on_select", self.interactive) @@ -1346,14 +1346,14 @@ def set_point2(self, pos: Tuple) -> None: self.point2 = pos self.handler_2.position = pos - def on_mouse_move(self, evt: Any) -> None: + def on_mouse_move(self, evt: CanvasEvent) -> None: if evt.root_event_obj is self: self.on_mouse_move2(evt) else: self.move_p1(evt) self.move_p2(evt) - def move_p1(self, evt: Any) -> None: + def move_p1(self, evt: CanvasEvent) -> None: pos = self.handler_1.position if evt.viewer.orientation == "AXIAL": pos = pos[0], self.point1[1], self.point1[2] @@ -1372,7 +1372,7 @@ def move_p1(self, evt: Any) -> None: self.set_point2(tuple(point2)) - def move_p2(self, evt: Any) -> None: + def move_p2(self, evt: CanvasEvent) -> None: pos = self.handler_2.position if evt.viewer.orientation == "AXIAL": pos = self.point2[0], pos[1], self.point2[2] @@ -1404,7 +1404,7 @@ def is_over(self, x: float, y: float) -> Optional[Self]: if xi <= x <= xf and yi <= y <= yf: return self - def on_mouse_move2(self, evt: Any) -> Literal[True]: + def on_mouse_move2(self, evt: CanvasEvent) -> Literal[True]: mx, my = evt.position if self.is_3d: x, y, z = evt.viewer.get_coordinate_cursor(mx, my) @@ -1422,7 +1422,7 @@ def on_mouse_move2(self, evt: Any) -> Literal[True]: return True - def on_select(self, evt: Any) -> None: + def on_select(self, evt: CanvasEvent) -> None: self.interactive = True mx, my = evt.position if self.is_3d: diff --git a/invesalius/gui/widgets/clut_raycasting.py b/invesalius/gui/widgets/clut_raycasting.py index 51a664b02..6cdb5cb76 100644 --- a/invesalius/gui/widgets/clut_raycasting.py +++ b/invesalius/gui/widgets/clut_raycasting.py @@ -30,6 +30,9 @@ from invesalius.i18n import tr as _ from invesalius.pubsub import pub as Publisher +if TYPE_CHECKING: + from typings.utils import SupportsGetItem + if TYPE_CHECKING: import numpy as np @@ -150,10 +153,10 @@ def __init__(self, parent: wx.Window, id: int): self.to_render = False self.dragged = False self.middle_drag = False - self.to_draw_points = 0 + self.to_draw_points = False self.point_dragged: Optional[Tuple[int, int]] = None self.curve_dragged: Optional[int] = None - self.histogram_array = [100, 100] + self.histogram_array: Union[np.ndarray, List[int]] = [100, 100] self.CalculatePixelPoints() self.__bind_events_wx() self._build_buttons() @@ -731,14 +734,14 @@ def PixelToOpacity(self, y: int) -> float: def SetRaycastPreset(self, preset: Dict[str, List[List[Dict[str, float]]]]) -> None: if not preset: - self.to_draw_points = 0 + self.to_draw_points = False elif preset["advancedCLUT"]: - self.to_draw_points = 1 + self.to_draw_points = True self.points = preset["16bitClutCurves"] self.colours = preset["16bitClutColors"] self.CalculatePixelPoints() else: - self.to_draw_points = 0 + self.to_draw_points = False self.Refresh() def SetHistogramArray(self, h_array: "np.ndarray", range: Tuple[float, float]) -> None: diff --git a/invesalius/gui/widgets/gradient.py b/invesalius/gui/widgets/gradient.py index 9a8a18a90..4a5fa64bd 100644 --- a/invesalius/gui/widgets/gradient.py +++ b/invesalius/gui/widgets/gradient.py @@ -19,7 +19,7 @@ # detalhes. # -------------------------------------------------------------------------- import sys -from typing import Any, Iterable, List, Literal, Optional, Sequence, SupportsInt, Tuple, Union +from typing import Iterable, List, Literal, Optional, Sequence, SupportsInt, Tuple, Union import wx @@ -106,7 +106,7 @@ def _bind_events_wx(self) -> None: self.Bind(wx.EVT_MOTION, self.OnMotion) self.Bind(wx.EVT_SIZE, self.OnSize) - def OnLeaveWindow(self, evt: Union[wx.KeyEvent, wx.SetCursorEvent, wx.SplitterEvent]) -> None: + def OnLeaveWindow(self, evt: wx.MouseEvent) -> None: if self.selected == 0: return @@ -137,7 +137,7 @@ def OnLeaveWindow(self, evt: Union[wx.KeyEvent, wx.SetCursorEvent, wx.SplitterEv self._generate_event(myEVT_SLIDER_CHANGED) evt.Skip() - def OnPaint(self, evt: wx.Event) -> None: + def OnPaint(self, evt: wx.PaintEvent) -> None: # Where the magic happens. Here the controls are drawn. dc = wx.BufferedPaintDC(self) dc.Clear() @@ -211,11 +211,11 @@ def OnPaint(self, evt: wx.Event) -> None: # else: # dc.DrawBitmap(slider, self.min_position, 0, True) - def OnEraseBackGround(self, evt: wx.Event) -> None: + def OnEraseBackGround(self, evt: wx.EraseEvent) -> None: # Only to avoid this widget to flick. pass - def OnMotion(self, evt: Union[wx.KeyEvent, wx.SetCursorEvent, wx.SplitterEvent]) -> None: + def OnMotion(self, evt: wx.MouseEvent) -> None: x = evt.GetX() w, h = self.GetSize() @@ -283,7 +283,7 @@ def OnMotion(self, evt: Union[wx.KeyEvent, wx.SetCursorEvent, wx.SplitterEvent]) self.Refresh() evt.Skip() - def OnClick(self, evt: Union[wx.KeyEvent, wx.SetCursorEvent, wx.SplitterEvent]) -> None: + def OnClick(self, evt: wx.MouseEvent) -> None: x = evt.GetX() self.selected = self._is_over_what(x) if self.selected == 1: @@ -294,13 +294,13 @@ def OnClick(self, evt: Union[wx.KeyEvent, wx.SetCursorEvent, wx.SplitterEvent]) self._delta = x - self.min_position evt.Skip() - def OnRelease(self, evt: wx.Event) -> None: + def OnRelease(self, evt: wx.MouseEvent) -> None: if self.selected: self.selected = 0 self._generate_event(myEVT_SLIDER_CHANGED) evt.Skip() - def OnSize(self, evt: wx.Event) -> None: + def OnSize(self, evt: wx.SizeEvent) -> None: self.CalculateControlPositions() self.Refresh() evt.Skip() @@ -433,7 +433,7 @@ def _bind_events_wx(self) -> None: self.Bind(wx.EVT_PAINT, self.OutPaint) self.Bind(wx.EVT_ERASE_BACKGROUND, self.OnEraseBackGround) - def OutPaint(self, evt: wx.Event) -> None: + def OutPaint(self, evt: wx.PaintEvent) -> None: # Where the magic happens. Here the controls are drawn. dc = wx.BufferedPaintDC(self) dc.Clear() @@ -455,11 +455,11 @@ def OutPaint(self, evt: wx.Event) -> None: gc.StrokePath(path) gc.FillPath(path) - def OnEraseBackGround(self, evt: wx.Event) -> None: + def OnEraseBackGround(self, evt: wx.EraseEvent) -> None: # Only to avoid this widget to flick. pass - def OnMotion(self, evt: Union[wx.KeyEvent, wx.SetCursorEvent, wx.SplitterEvent]) -> None: + def OnMotion(self, evt: wx.MouseEvent) -> None: x = evt.GetX() w, h = self.GetSize() @@ -527,7 +527,7 @@ def OnMotion(self, evt: Union[wx.KeyEvent, wx.SetCursorEvent, wx.SplitterEvent]) self.Refresh() evt.Skip() - def OnClick(self, evt: Union[wx.KeyEvent, wx.SetCursorEvent, wx.SplitterEvent]) -> None: + def OnClick(self, evt: wx.MouseEvent) -> None: x = evt.GetX() self.selected = self._is_over_what(x) if self.selected == 1: @@ -538,13 +538,13 @@ def OnClick(self, evt: Union[wx.KeyEvent, wx.SetCursorEvent, wx.SplitterEvent]) self._delta = x - self.min_position evt.Skip() - def OnRelease(self, evt: wx.Event) -> None: + def OnRelease(self, evt: wx.MouseEvent) -> None: if self.selected: self.selected = 0 self._generate_event(myEVT_SLIDER_CHANGED) evt.Skip() - def OnSize(self, evt: wx.Event) -> None: + def OnSize(self, evt: wx.SizeEvent) -> None: self.CalculateControlPositions() self.Refresh() evt.Skip() @@ -709,51 +709,21 @@ def _bind_events_wx(self) -> None: self.spin_min.Bind(wx.EVT_SPINCTRL, self.OnMinMouseWheel) self.spin_max.Bind(wx.EVT_SPINCTRL, self.OnMaxMouseWheel) - def OnSlider(self, evt: Any) -> None: + def OnSlider(self, evt: SliderEvent) -> None: self.spin_min.SetValue(evt.minimun) self.spin_max.SetValue(evt.maximun) self.minimun = evt.minimun self.maximun = evt.maximun self._GenerateEvent(myEVT_THRESHOLD_CHANGED) - def OnSliding(self, evt: Any) -> None: + def OnSliding(self, evt: SliderEvent) -> None: self.spin_min.SetValue(evt.minimun) self.spin_max.SetValue(evt.maximun) self.minimun = evt.minimun self.maximun = evt.maximun self._GenerateEvent(myEVT_THRESHOLD_CHANGING) - def _FireSpinMinChange(self, evt: wx.Event) -> None: - evt.Skip() - value = int(self.spin_min.GetValue()) - if value < self.min_range or value > self.max_range: - self.spin_min.SetValue(self.minimun) - return - - if value != self.GetMinValue() or self.changed: - self.SetMinValue(value) - self._GenerateEvent(myEVT_THRESHOLD_CHANGED) - - def _FireSpinMinChanged(self, evt: wx.Event) -> None: - if self.changed: - self._GenerateEvent(myEVT_THRESHOLD_CHANGED) - - def _FireSpinMaxChange(self, evt: wx.Event) -> None: - evt.Skip() - value = int(self.spin_max.GetValue()) - if value < self.min_range or value > self.max_range: - self.spin_max.SetValue(self.maximun) - return - - if value != self.GetMaxValue() or self.changed: - self.SetMaxValue(value) - self._GenerateEvent(myEVT_THRESHOLD_CHANGED) - - def _FireSpinMaxChanged(self, evt: wx.Event) -> None: - if self.changed: - self._GenerateEvent(myEVT_THRESHOLD_CHANGED) - - def OnMinMouseWheel(self, e: Any) -> None: + def OnMinMouseWheel(self, e: wx.SpinEvent) -> None: """ When the user wheel the mouse over min texbox """ @@ -761,7 +731,7 @@ def OnMinMouseWheel(self, e: Any) -> None: self.SetMinValue(v) self._GenerateEvent(myEVT_THRESHOLD_CHANGED) - def OnMaxMouseWheel(self, e: Any) -> None: + def OnMaxMouseWheel(self, e: wx.SpinEvent) -> None: """ When the user wheel the mouse over max texbox """ @@ -896,12 +866,12 @@ def _draw_controls(self) -> None: def _bind_events_wx(self) -> None: return - def OnSlider(self, evt: Any) -> None: + def OnSlider(self, evt: SliderEvent) -> None: self.minimun = evt.minimun self.maximun = evt.maximun self._GenerateEvent(myEVT_THRESHOLD_CHANGED) - def OnSliding(self, evt: Any) -> None: + def OnSliding(self, evt: SliderEvent) -> None: self.minimun = evt.minimun self.maximun = evt.maximun self._GenerateEvent(myEVT_THRESHOLD_CHANGING) diff --git a/invesalius/gui/widgets/listctrl.py b/invesalius/gui/widgets/listctrl.py deleted file mode 100644 index 938304803..000000000 --- a/invesalius/gui/widgets/listctrl.py +++ /dev/null @@ -1,876 +0,0 @@ -# ---------------------------------------------------------------------------- -# Name: wxPython.lib.mixins.listctrl -# Purpose: Helpful mix-in classes for wxListCtrl -# -# Author: Robin Dunn -# -# Created: 15-May-2001 -# RCS-ID: $Id: listctrl.py 54544 2008-07-08 02:36:46Z RD $ -# Copyright: (c) 2001 by Total Control Software -# Licence: wxWindows license -# ---------------------------------------------------------------------------- -# 12/14/2003 - Jeff Grimmett (grimmtooth@softhome.net) -# -# o 2.5 compatability update. -# o ListCtrlSelectionManagerMix untested. -# -# 12/21/2003 - Jeff Grimmett (grimmtooth@softhome.net) -# -# o wxColumnSorterMixin -> ColumnSorterMixin -# o wxListCtrlAutoWidthMixin -> ListCtrlAutoWidthMixin -# ... -# 13/10/2004 - Pim Van Heuven (pim@think-wize.com) -# o wxTextEditMixin: Support Horizontal scrolling when TAB is pressed on long -# ListCtrls, support for WXK_DOWN, WXK_UP, performance improvements on -# very long ListCtrls, Support for virtual ListCtrls -# -# 15-Oct-2004 - Robin Dunn -# o wxTextEditMixin: Added Shift-TAB support -# -# 28/11/2008 - Tatiana Al-Chueyr Pereira Martins -# wxTextEditMixin: just works on column 1 - -import locale - -import wx - -# ---------------------------------------------------------------------------- - - -class ColumnSorterMixin: - """ - A mixin class that handles sorting of a wx.ListCtrl in REPORT mode when - the column header is clicked on. - - There are a few requirments needed in order for this to work genericly: - - 1. The combined class must have a GetListCtrl method that - returns the wx.ListCtrl to be sorted, and the list control - must exist at the time the wx.ColumnSorterMixin.__init__ - method is called because it uses GetListCtrl. - - 2. Items in the list control must have a unique data value set - with list.SetItemData. - - 3. The combined class must have an attribute named itemDataMap - that is a dictionary mapping the data values to a sequence of - objects representing the values in each column. These values - are compared in the column sorter to determine sort order. - - Interesting methods to override are GetColumnSorter, - GetSecondarySortValues, and GetSortImages. See below for details. - """ - - def __init__(self, numColumns): - self.SetColumnCount(numColumns) - list = self.GetListCtrl() - if not list: - raise ValueError("No wx.ListCtrl available") - list.Bind(wx.EVT_LIST_COL_CLICK, self.__OnColClick, list) - - def SetColumnCount(self, newNumColumns): - self._colSortFlag = [0] * newNumColumns - self._col = -1 - - def SortListItems(self, col=-1, ascending=1): - """Sort the list on demand. Can also be used to set the sort column and order.""" - oldCol = self._col - if col != -1: - self._col = col - self._colSortFlag[col] = ascending - self.GetListCtrl().SortItems(self.GetColumnSorter()) - self.__updateImages(oldCol) - - def GetColumnWidths(self): - """ - Returns a list of column widths. Can be used to help restore the current - view later. - """ - list = self.GetListCtrl() - rv = [] - for x in range(len(self._colSortFlag)): - rv.append(list.GetColumnWidth(x)) - return rv - - def GetSortImages(self): - """ - Returns a tuple of image list indexesthe indexes in the image list for an image to be put on the column - header when sorting in descending order. - """ - return (-1, -1) # (decending, ascending) image IDs - - def GetColumnSorter(self): - """Returns a callable object to be used for comparing column values when sorting.""" - return self.__ColumnSorter - - def GetSecondarySortValues(self, col, key1, key2): - """Returns a tuple of 2 values to use for secondary sort values when the - items in the selected column match equal. The default just returns the - item data values.""" - return (key1, key2) - - def __OnColClick(self, evt): - oldCol = self._col - self._col = col = evt.GetColumn() - self._colSortFlag[col] = int(not self._colSortFlag[col]) - self.GetListCtrl().SortItems(self.GetColumnSorter()) - if ( - wx.Platform != "__WXMAC__" - or wx.SystemOptions.GetOptionInt("mac.listctrl.always_use_generic") == 1 - ): - self.__updateImages(oldCol) - evt.Skip() - self.OnSortOrderChanged() - - def OnSortOrderChanged(self): - """ - Callback called after sort order has changed (whenever user - clicked column header). - """ - pass - - def __ColumnSorter(self, key1, key2): - col = self._col - ascending = self._colSortFlag[col] - item1 = self.itemDataMap[key1][col] - item2 = self.itemDataMap[key2][col] - - # --- Internationalization of string sorting with locale module - if type(item1) == type("") or type(item2) == type(""): - cmpVal = locale.strcoll(str(item1), str(item2)) - else: - cmpVal = cmp(item1, item2) - # --- - - # If the items are equal then pick something else to make the sort value unique - if cmpVal == 0: - cmpVal = apply(cmp, self.GetSecondarySortValues(col, key1, key2)) - - if ascending: - return cmpVal - else: - return -cmpVal - - def __updateImages(self, oldCol): - sortImages = self.GetSortImages() - if self._col != -1 and sortImages[0] != -1: - img = sortImages[self._colSortFlag[self._col]] - list = self.GetListCtrl() - if oldCol != -1: - list.ClearColumnImage(oldCol) - list.SetColumnImage(self._col, img) - - -# ---------------------------------------------------------------------------- -# ---------------------------------------------------------------------------- - - -class ListCtrlAutoWidthMixin: - """A mix-in class that automatically resizes the last column to take up - the remaining width of the wx.ListCtrl. - - This causes the wx.ListCtrl to automatically take up the full width of - the list, without either a horizontal scroll bar (unless absolutely - necessary) or empty space to the right of the last column. - - NOTE: This only works for report-style lists. - - WARNING: If you override the EVT_SIZE event in your wx.ListCtrl, make - sure you call event.Skip() to ensure that the mixin's - _OnResize method is called. - - This mix-in class was written by Erik Westra - """ - - def __init__(self): - """Standard initialiser.""" - self._resizeColMinWidth = None - self._resizeColStyle = "LAST" - self._resizeCol = 0 - self.Bind(wx.EVT_SIZE, self._onResize) - self.Bind(wx.EVT_LIST_COL_END_DRAG, self._onResize, self) - - def setResizeColumn(self, col): - """ - Specify which column that should be autosized. Pass either - 'LAST' or the column number. Default is 'LAST'. - """ - if col == "LAST": - self._resizeColStyle = "LAST" - else: - self._resizeColStyle = "COL" - self._resizeCol = col - - def resizeLastColumn(self, minWidth): - """Resize the last column appropriately. - - If the list's columns are too wide to fit within the window, we use - a horizontal scrollbar. Otherwise, we expand the right-most column - to take up the remaining free space in the list. - - This method is called automatically when the wx.ListCtrl is resized; - you can also call it yourself whenever you want the last column to - be resized appropriately (eg, when adding, removing or resizing - columns). - - 'minWidth' is the preferred minimum width for the last column. - """ - self.resizeColumn(minWidth) - - def resizeColumn(self, minWidth): - self._resizeColMinWidth = minWidth - self._doResize() - - # ===================== - # == Private Methods == - # ===================== - - def _onResize(self, event): - """Respond to the wx.ListCtrl being resized. - - We automatically resize the last column in the list. - """ - if "gtk2" in wx.PlatformInfo: - self._doResize() - else: - wx.CallAfter(self._doResize) - event.Skip() - - def _doResize(self): - """Resize the last column as appropriate. - - If the list's columns are too wide to fit within the window, we use - a horizontal scrollbar. Otherwise, we expand the right-most column - to take up the remaining free space in the list. - - We remember the current size of the last column, before resizing, - as the preferred minimum width if we haven't previously been given - or calculated a minimum width. This ensure that repeated calls to - _doResize() don't cause the last column to size itself too large. - """ - - if not self: # avoid a PyDeadObject error - return - - if self.GetSize().height < 32: - return # avoid an endless update bug when the height is small. - - numCols = self.GetColumnCount() - if numCols == 0: - return # Nothing to resize. - - if self._resizeColStyle == "LAST": - resizeCol = self.GetColumnCount() - else: - resizeCol = self._resizeCol - - if self._resizeColMinWidth == None: - self._resizeColMinWidth = self.GetColumnWidth(resizeCol - 1) - - # We're showing the vertical scrollbar -> allow for scrollbar width - # NOTE: on GTK, the scrollbar is included in the client size, but on - # Windows it is not included - listWidth = self.GetClientSize().width - if wx.Platform != "__WXMSW__": - if self.GetItemCount() > self.GetCountPerPage(): - scrollWidth = wx.SystemSettings_GetMetric(wx.SYS_VSCROLL_X) - listWidth = listWidth - scrollWidth - - totColWidth = 0 # Width of all columns except last one. - for col in range(numCols): - if col != (resizeCol - 1): - totColWidth = totColWidth + self.GetColumnWidth(col) - - resizeColWidth = self.GetColumnWidth(resizeCol - 1) - - if totColWidth + self._resizeColMinWidth > listWidth: - # We haven't got the width to show the last column at its minimum - # width -> set it to its minimum width and allow the horizontal - # scrollbar to show. - self.SetColumnWidth(resizeCol - 1, self._resizeColMinWidth) - return - - # Resize the last column to take up the remaining available space. - - self.SetColumnWidth(resizeCol - 1, listWidth - totColWidth) - - -# ---------------------------------------------------------------------------- -# ---------------------------------------------------------------------------- - -SEL_FOC = wx.LIST_STATE_SELECTED | wx.LIST_STATE_FOCUSED - - -def selectBeforePopup(event): - """Ensures the item the mouse is pointing at is selected before a popup. - - Works with both single-select and multi-select lists.""" - ctrl = event.GetEventObject() - if isinstance(ctrl, wx.ListCtrl): - n, flags = ctrl.HitTest(event.GetPosition()) - if n >= 0: - if not ctrl.GetItemState(n, wx.LIST_STATE_SELECTED): - for i in range(ctrl.GetItemCount()): - ctrl.SetItemState(i, 0, SEL_FOC) - # for i in getListCtrlSelection(ctrl, SEL_FOC): - # ctrl.SetItemState(i, 0, SEL_FOC) - ctrl.SetItemState(n, SEL_FOC, SEL_FOC) - - -def getListCtrlSelection(listctrl, state=wx.LIST_STATE_SELECTED): - """Returns list of item indexes of given state (selected by defaults)""" - res = [] - idx = -1 - while 1: - idx = listctrl.GetNextItem(idx, wx.LIST_NEXT_ALL, state) - if idx == -1: - break - res.append(idx) - return res - - -wxEVT_DOPOPUPMENU = wx.NewEventType() -EVT_DOPOPUPMENU = wx.PyEventBinder(wxEVT_DOPOPUPMENU, 0) - - -class ListCtrlSelectionManagerMix: - """Mixin that defines a platform independent selection policy - - As selection single and multi-select list return the item index or a - list of item indexes respectively. - """ - - _menu = None - - def __init__(self): - self.Bind(wx.EVT_RIGHT_DOWN, self.OnLCSMRightDown) - self.Bind(EVT_DOPOPUPMENU, self.OnLCSMDoPopup) - - # self.Connect(-1, -1, self.wxEVT_DOPOPUPMENU, self.OnLCSMDoPopup) - - def getPopupMenu(self): - """Override to implement dynamic menus (create)""" - return self._menu - - def setPopupMenu(self, menu): - """Must be set for default behaviour""" - self._menu = menu - - def afterPopupMenu(self, menu): - """Override to implement dynamic menus (destroy)""" - pass - - def getSelection(self): - res = getListCtrlSelection(self) - if self.GetWindowStyleFlag() & wx.LC_SINGLE_SEL: - if res: - return res[0] - else: - return -1 - else: - return res - - def OnLCSMRightDown(self, event): - selectBeforePopup(event) - event.Skip() - menu = self.getPopupMenu() - if menu: - evt = wx.PyEvent() - evt.SetEventType(wxEVT_DOPOPUPMENU) - evt.menu = menu - evt.pos = event.GetPosition() - wx.PostEvent(self, evt) - - def OnLCSMDoPopup(self, event): - self.PopupMenu(event.menu, event.pos) - self.afterPopupMenu(event.menu) - - -# ---------------------------------------------------------------------------- -# ---------------------------------------------------------------------------- -from bisect import bisect - - -class TextEditMixin: - """ - A mixin class that enables any text in any column of a - multi-column listctrl to be edited by clicking on the given row - and column. You close the text editor by hitting the ENTER key or - clicking somewhere else on the listctrl. You switch to the next - column by hiting TAB. - - To use the mixin you have to include it in the class definition - and call the __init__ function:: - - class TestListCtrl(wx.ListCtrl, TextEditMixin): - def __init__(self, parent, ID, pos=wx.DefaultPosition, - size=wx.DefaultSize, style=0): - wx.ListCtrl.__init__(self, parent, ID, pos, size, style) - TextEditMixin.__init__(self) - - - Authors: Steve Zatz, Pim Van Heuven (pim@think-wize.com) - """ - - editorBgColour = wx.Colour(255, 255, 175) # Yellow - editorFgColour = wx.Colour(0, 0, 0) # black - - def __init__(self, check_image=None, uncheck_image=None, imgsz=(16, 16)): - # editor = wx.TextCtrl(self, -1, pos=(-1,-1), size=(-1,-1), - # style=wx.TE_PROCESS_ENTER|wx.TE_PROCESS_TAB \ - # |wx.TE_RICH2) - - ################ here on - if check_image is not None: - imgsz = check_image.GetSize() - elif uncheck_image is not None: - imgsz = check_image.GetSize() - - self.__imagelist_ = wx.ImageList(*imgsz) - - # Create default checkbox images if none were specified - if check_image is None: - check_image = self.__CreateBitmap(wx.CONTROL_CHECKED, imgsz) - - if uncheck_image is None: - uncheck_image = self.__CreateBitmap(0, imgsz) - - self.uncheck_image = self.__imagelist_.Add(uncheck_image) - self.check_image = self.__imagelist_.Add(check_image) - self.SetImageList(self.__imagelist_, wx.IMAGE_LIST_SMALL) - self.__last_check_ = None - - # self.Bind(wx.EVT_LEFT_DOWN, self.__OnLeftDown_) - - # override the default methods of ListCtrl/ListView - self.InsertStringItem = self.__InsertStringItem_ - ################ until here - - self.make_editor() - self.Bind(wx.EVT_TEXT_ENTER, self.CloseEditor) - self.Bind(wx.EVT_LEFT_DOWN, self.OnLeftDown) - self.Bind(wx.EVT_LEFT_DCLICK, self.OnLeftDown) - self.Bind(wx.EVT_LIST_ITEM_SELECTED, self.OnItemSelected) - - ######### 2 down - def __CreateBitmap(self, flag=0, size=(16, 16)): - """Create a bitmap of the platforms native checkbox. The flag - is used to determine the checkboxes state (see wx.CONTROL_*) - - """ - bmp = wx.EmptyBitmap(*size) - dc = wx.MemoryDC(bmp) - dc.Clear() - wx.RendererNative.Get().DrawCheckBox(self, dc, (0, 0, size[0], size[1]), flag) - dc.SelectObject(wx.NullBitmap) - return bmp - - # NOTE: if you use InsertItem, InsertImageItem or InsertImageStringItem, - # you must set the image yourself. - def __InsertStringItem_(self, index, label): - index = self.InsertImageStringItem(index, label, 0) - return index - - def OnCheckItem(self, index, flag): - pass - - def IsChecked(self, index): - return self.GetItem(index).GetImage() == 1 - - def CheckItem(self, index, check=True): - img_idx = self.GetItem(index).GetImage() - if img_idx == 0 and check is True: - self.SetItemImage(index, 1) - self.OnCheckItem(index, True) - elif img_idx == 1 and check is False: - self.SetItemImage(index, 0) - self.OnCheckItem(index, False) - - def ToggleItem(self, index): - self.CheckItem(index, not self.IsChecked(index)) - - ######## 2 up - - def make_editor(self, col_style=wx.LIST_FORMAT_LEFT): - style = wx.TE_PROCESS_ENTER | wx.TE_PROCESS_TAB | wx.TE_RICH2 - style |= { - wx.LIST_FORMAT_LEFT: wx.TE_LEFT, - wx.LIST_FORMAT_RIGHT: wx.TE_RIGHT, - wx.LIST_FORMAT_CENTRE: wx.TE_CENTRE, - }[col_style] - - editor = wx.TextCtrl(self, -1, style=style) - editor.SetBackgroundColour(self.editorBgColour) - editor.SetForegroundColour(self.editorFgColour) - font = self.GetFont() - editor.SetFont(font) - - self.curRow = 0 - self.curCol = 0 - - editor.Hide() - if hasattr(self, "editor"): - self.editor.Destroy() - self.editor = editor - - self.col_style = col_style - self.editor.Bind(wx.EVT_CHAR, self.OnChar) - self.editor.Bind(wx.EVT_KILL_FOCUS, self.CloseEditor) - - def OnItemSelected(self, evt): - self.curRow = evt.GetIndex() - evt.Skip() - - def OnChar(self, event): - """Catch the TAB, Shift-TAB, cursor DOWN/UP key code - so we can open the editor at the next column (if any).""" - - keycode = event.GetKeyCode() - if keycode == wx.WXK_TAB and event.ShiftDown(): - self.CloseEditor() - if self.curCol - 1 >= 0: - self.OpenEditor(self.curCol - 1, self.curRow) - - elif keycode == wx.WXK_TAB: - self.CloseEditor() - if self.curCol + 1 < self.GetColumnCount(): - self.OpenEditor(self.curCol + 1, self.curRow) - - elif keycode == wx.WXK_ESCAPE: - self.CloseEditor() - - elif keycode == wx.WXK_DOWN: - self.CloseEditor() - if self.curRow + 1 < self.GetItemCount(): - self._SelectIndex(self.curRow + 1) - self.OpenEditor(self.curCol, self.curRow) - - elif keycode == wx.WXK_UP: - self.CloseEditor() - if self.curRow > 0: - self._SelectIndex(self.curRow - 1) - self.OpenEditor(self.curCol, self.curRow) - - else: - event.Skip() - - def OnLeftDown2(self, evt=None): - (index, flags) = self.HitTest(evt.GetPosition()) - if flags == wx.LIST_HITTEST_ONITEMICON: - img_idx = self.GetItem(index).GetImage() - flag_check = img_idx == 0 - begin_index = index - end_index = index - if self.__last_check_ is not None and wx.GetKeyState(wx.WXK_SHIFT): - last_index, last_flag_check = self.__last_check_ - if last_flag_check == flag_check: - # XXX what if the previous item is deleted or new items - # are inserted? - item_count = self.GetItemCount() - if last_index < item_count: - if last_index < index: - begin_index = last_index - end_index = index - elif last_index > index: - begin_index = index - end_index = last_index - else: - assert False - while begin_index <= end_index: - self.CheckItem(begin_index, flag_check) - begin_index += 1 - self.__last_check_ = (index, flag_check) - else: - evt.Skip() - - def OnLeftDown(self, evt=None): - """Examine the click and double - click events to see if a row has been click on twice. If so, - determine the current row and columnn and open the editor.""" - - if self.editor.IsShown(): - self.CloseEditor() - - x, y = evt.GetPosition() - row, flags = self.HitTest((x, y)) - - if row != self.curRow: # self.curRow keeps track of the current row - evt.Skip() - return - - # the following should really be done in the mixin's init but - # the wx.ListCtrl demo creates the columns after creating the - # ListCtrl (generally not a good idea) on the other hand, - # doing this here handles adjustable column widths - - self.col_locs = [0] - loc = 0 - for n in range(self.GetColumnCount()): - loc = loc + self.GetColumnWidth(n) - self.col_locs.append(loc) - - col = bisect(self.col_locs, x + self.GetScrollPos(wx.HORIZONTAL)) - 1 - if col == 1: - self.OpenEditor(col, row) - else: - self.OnLeftDown2(evt) - - def OpenEditor(self, col, row): - """Opens an editor at the current position.""" - - # give the derived class a chance to Allow/Veto this edit. - evt = wx.ListEvent(wx.wxEVT_COMMAND_LIST_BEGIN_LABEL_EDIT, self.GetId()) - try: - evt.SetIndex(row) - evt.SetColumn(col) - except AttributeError: - evt.m_itemIndex = row - evt.m_col = col - item = self.GetItem(row, col) - evt.Item.SetId(item.GetId()) - evt.Item.SetColumn(item.GetColumn()) - evt.Item.SetData(item.GetData()) - evt.Item.SetText(item.GetText()) - ret = self.GetEventHandler().ProcessEvent(evt) - if ret and not evt.IsAllowed(): - return # user code doesn't allow the edit. - - if self.GetColumn(col).Align != self.col_style: - self.make_editor(self.GetColumn(col).Align) - - x0 = self.col_locs[col] - x1 = self.col_locs[col + 1] - x0 - - scrolloffset = self.GetScrollPos(wx.HORIZONTAL) - - # scroll forward - if x0 + x1 - scrolloffset > self.GetSize()[0]: - if wx.Platform == "__WXMSW__": - # don't start scrolling unless we really need to - offset = x0 + x1 - self.GetSize()[0] - scrolloffset - # scroll a bit more than what is minimum required - # so we don't have to scroll everytime the user presses TAB - # which is very tireing to the eye - addoffset = self.GetSize()[0] / 4 - # but be careful at the end of the list - if addoffset + scrolloffset < self.GetSize()[0]: - offset += addoffset - - self.ScrollList(offset, 0) - scrolloffset = self.GetScrollPos(wx.HORIZONTAL) - else: - # Since we can not programmatically scroll the ListCtrl - # close the editor so the user can scroll and open the editor - # again - self.editor.SetValue(self.GetItem(row, col).GetText()) - self.curRow = row - self.curCol = col - self.CloseEditor() - return - - y0 = self.GetItemRect(row)[1] - - editor = self.editor - editor.SetDimensions(x0 - scrolloffset, y0, x1, -1) - - editor.SetValue(self.GetItem(row, col).GetText()) - editor.Show() - editor.Raise() - editor.SetSelection(-1, -1) - editor.SetFocus() - - self.curRow = row - self.curCol = col - - # FIXME: this function is usually called twice - second time because - # it is binded to wx.EVT_KILL_FOCUS. Can it be avoided? (MW) - def CloseEditor(self, evt=None): - """Close the editor and save the new value to the ListCtrl.""" - if not self.editor.IsShown(): - return - text = self.editor.GetValue() - self.editor.Hide() - self.SetFocus() - - # post wxEVT_COMMAND_LIST_END_LABEL_EDIT - # Event can be vetoed. It doesn't has SetEditCanceled(), what would - # require passing extra argument to CloseEditor() - evt = wx.ListEvent(wx.wxEVT_COMMAND_LIST_END_LABEL_EDIT, self.GetId()) - try: - evt.SetIndex(self.curRow) - evt.SetColumn(self.curCol) - except AttributeError: - evt.m_itemIndex = self.curRow - evt.m_col = self.curCol - item = self.GetItem(self.curRow, self.curCol) - evt.Item.SetId(item.GetId()) - evt.Item.SetColumn(item.GetColumn()) - evt.Item.SetData(item.GetData()) - evt.Item.SetText(text) # should be empty string if editor was canceled - ret = self.GetEventHandler().ProcessEvent(evt) - if not ret or evt.IsAllowed(): - if self.IsVirtual(): - # replace by whather you use to populate the virtual ListCtrl - # data source - self.SetVirtualData(self.curRow, self.curCol, text) - else: - self.SetItem(self.curRow, self.curCol, text) - self.RefreshItem(self.curRow) - - def _SelectIndex(self, row): - listlen = self.GetItemCount() - if row < 0 and not listlen: - return - if row > (listlen - 1): - row = listlen - 1 - - self.SetItemState(self.curRow, ~wx.LIST_STATE_SELECTED, wx.LIST_STATE_SELECTED) - self.EnsureVisible(row) - self.SetItemState(row, wx.LIST_STATE_SELECTED, wx.LIST_STATE_SELECTED) - - -# ---------------------------------------------------------------------------- -# ---------------------------------------------------------------------------- - -""" -FILENAME: CheckListCtrlMixin.py -AUTHOR: Bruce Who (bruce.who.hk at gmail.com) -DATE: 2006-02-09 -$Revision: 54544 $ -DESCRIPTION: - This script provide a mixin for ListCtrl which add a checkbox in the first - column of each row. It is inspired by limodou's CheckList.py(which can be - got from his NewEdit) and improved: - - You can just use InsertStringItem() to insert new items; - - Once a checkbox is checked/unchecked, the corresponding item is not - selected; - - You can use SetItemData() and GetItemData(); - - Interfaces are changed to OnCheckItem(), IsChecked(), CheckItem(). - - You should not set a imagelist for the ListCtrl once this mixin is used. - -HISTORY: -1.3 - You can check/uncheck a group of sequential items by : - First click(or ) item1 to check/uncheck it, then - Shift-click item2 to check/uncheck it, and you'll find that all - items between item1 and item2 are check/unchecked! -1.2 - Add ToggleItem() -1.1 - Initial version -""" - - -class CheckListCtrlMixin: - """ - This is a mixin for ListCtrl which add a checkbox in the first - column of each row. It is inspired by limodou's CheckList.py(which - can be got from his NewEdit) and improved: - - - You can just use InsertStringItem() to insert new items; - - - Once a checkbox is checked/unchecked, the corresponding item - is not selected; - - - You can use SetItemData() and GetItemData(); - - - Interfaces are changed to OnCheckItem(), IsChecked(), - CheckItem(). - - You should not set a imagelist for the ListCtrl once this mixin is used. - """ - - def __init__(self, check_image=None, uncheck_image=None, imgsz=(16, 16)): - if check_image is not None: - imgsz = check_image.GetSize() - elif uncheck_image is not None: - imgsz = check_image.GetSize() - - self.__imagelist_ = wx.ImageList(*imgsz) - - # Create default checkbox images if none were specified - if check_image is None: - check_image = self.__CreateBitmap(wx.CONTROL_CHECKED, imgsz) - - if uncheck_image is None: - uncheck_image = self.__CreateBitmap(0, imgsz) - - self.uncheck_image = self.__imagelist_.Add(uncheck_image) - self.check_image = self.__imagelist_.Add(check_image) - self.SetImageList(self.__imagelist_, wx.IMAGE_LIST_SMALL) - self.__last_check_ = None - - self.Bind(wx.EVT_LEFT_DOWN, self.__OnLeftDown_) - - """ - self.Bind(wx.EVT_TEXT_ENTER, self.CloseEditor) - self.Bind(wx.EVT_LEFT_DOWN, self.OnLeftDown) - self.Bind(wx.EVT_LEFT_DCLICK, self.OnLeftDown) - self.Bind(wx.EVT_LIST_ITEM_SELECTED, self.OnItemSelected) - """ - - # override the default methods of ListCtrl/ListView - self.InsertStringItem = self.__InsertStringItem_ - - def __CreateBitmap(self, flag=0, size=(16, 16)): - """Create a bitmap of the platforms native checkbox. The flag - is used to determine the checkboxes state (see wx.CONTROL_*) - - """ - bmp = wx.EmptyBitmap(*size) - dc = wx.MemoryDC(bmp) - dc.Clear() - wx.RendererNative.Get().DrawCheckBox(self, dc, (0, 0, size[0], size[1]), flag) - dc.SelectObject(wx.NullBitmap) - return bmp - - # NOTE: if you use InsertItem, InsertImageItem or InsertImageStringItem, - # you must set the image yourself. - def __InsertStringItem_(self, index, label): - index = self.InsertImageStringItem(index, label, 0) - return index - - def __OnLeftDown_(self, evt): - (index, flags) = self.HitTest(evt.GetPosition()) - if flags == wx.LIST_HITTEST_ONITEMICON: - img_idx = self.GetItem(index).GetImage() - flag_check = img_idx == 0 - begin_index = index - end_index = index - if self.__last_check_ is not None and wx.GetKeyState(wx.WXK_SHIFT): - last_index, last_flag_check = self.__last_check_ - if last_flag_check == flag_check: - # XXX what if the previous item is deleted or new items - # are inserted? - item_count = self.GetItemCount() - if last_index < item_count: - if last_index < index: - begin_index = last_index - end_index = index - elif last_index > index: - begin_index = index - end_index = last_index - else: - assert False - while begin_index <= end_index: - self.CheckItem(begin_index, flag_check) - begin_index += 1 - self.__last_check_ = (index, flag_check) - else: - evt.Skip() - - def OnCheckItem(self, index, flag): - pass - - def IsChecked(self, index): - return self.GetItem(index).GetImage() == 1 - - def CheckItem(self, index, check=True): - img_idx = self.GetItem(index).GetImage() - if img_idx == 0 and check is True: - self.SetItemImage(index, 1) - self.OnCheckItem(index, True) - elif img_idx == 1 and check is False: - self.SetItemImage(index, 0) - self.OnCheckItem(index, False) - - def ToggleItem(self, index): - self.CheckItem(index, not self.IsChecked(index)) diff --git a/invesalius/i18n.py b/invesalius/i18n.py index c60ec904f..bf3e588b4 100644 --- a/invesalius/i18n.py +++ b/invesalius/i18n.py @@ -19,22 +19,19 @@ # detalhes. # -------------------------------------------------------------------------- -try: - import configparser as ConfigParser -except ImportError: - import ConfigParser import gettext import locale import os import sys +from typing import Optional import invesalius.utils as utl from invesalius.inv_paths import LOCALE_DIR from invesalius.session import Session -def GetLocales(): +def GetLocales() -> utl.TwoWaysDictionary: """Return a dictionary which defines supported languages""" d = utl.TwoWaysDictionary( { @@ -62,7 +59,7 @@ def GetLocales(): return d -def GetLocaleOS(): +def GetLocaleOS() -> Optional[str]: """Return language of the operating system.""" if sys.platform == "darwin": # The app can't get the location then it has to set @@ -74,10 +71,10 @@ def GetLocaleOS(): return locale.getdefaultlocale()[0] -def InstallLanguage(language): +def InstallLanguage(language: str): file_path = os.path.split(__file__)[0] language_dir = LOCALE_DIR - if hasattr(sys, "frozen") and (sys.frozen == "windows_exe" or sys.frozen == "console_exe"): + if hasattr(sys, "frozen") and (sys.frozen == "windows_exe" or sys.frozen == "console_exe"): # type: ignore abs_file_path = os.path.abspath(file_path + os.sep + "..") abs_file_path = os.path.abspath(abs_file_path + os.sep + ".." + os.sep + "..") language_dir = os.path.join(abs_file_path, "locale") @@ -111,7 +108,7 @@ def __call__(self, message: str) -> str: self.gettext = InstallLanguage(lang) return self.gettext(message) - def reset(self): + def reset(self) -> None: self.gettext = None diff --git a/invesalius/inv_paths.py b/invesalius/inv_paths.py index 5bba97322..80e45d642 100644 --- a/invesalius/inv_paths.py +++ b/invesalius/inv_paths.py @@ -51,7 +51,9 @@ LOCALE_DIR = INV_TOP_DIR.joinpath("locale") # Inside the windows executable -if hasattr(sys, "frozen") and (sys.frozen == "windows_exe" or sys.frozen == "console_exe"): +if hasattr(sys, "frozen") and ( + sys.frozen == "windows_exe" or sys.frozen == "console_exe" # type: ignore +): abs_path = INV_TOP_DIR.parent.resolve() ICON_DIR = abs_path.joinpath("icons") SAMPLE_DIR = INV_TOP_DIR.joinpath("samples") @@ -90,7 +92,7 @@ DOC_DIR = INV_TOP_DIR.parent.parent.joinpath("docs").resolve() -def create_conf_folders(): +def create_conf_folders() -> None: USER_INV_DIR.mkdir(parents=True, exist_ok=True) USER_PRESET_DIR.mkdir(parents=True, exist_ok=True) USER_LOG_DIR.mkdir(parents=True, exist_ok=True) @@ -98,7 +100,7 @@ def create_conf_folders(): USER_PLUGINS_DIRECTORY.mkdir(parents=True, exist_ok=True) -def copy_old_files(): +def copy_old_files() -> None: for f in OLD_USER_INV_DIR.glob("*"): if f.is_file(): print( diff --git a/invesalius/math_utils.py b/invesalius/math_utils.py index 6475e5d23..31274c722 100644 --- a/invesalius/math_utils.py +++ b/invesalius/math_utils.py @@ -1,12 +1,10 @@ -# -*- coding: utf-8 -*- - import math -from typing import List, Tuple +from typing import Iterable, List, Sequence, Tuple import numpy as np -def calculate_distance(p1, p2): +def calculate_distance(p1: Iterable[float], p2: Iterable[float]) -> float: """ Calculates the euclidian distance between p1 and p2 points. @@ -19,7 +17,7 @@ def calculate_distance(p1, p2): return math.sqrt(sum([(j - i) ** 2 for i, j in zip(p1, p2)])) -def calculate_angle(v1, v2): +def calculate_angle(v1: Tuple[float, ...], v2: Tuple[float, ...]) -> float: """ Calculates the angle formed between vector v1 and v2. @@ -34,7 +32,7 @@ def calculate_angle(v1, v2): return angle -def calc_ellipse_area(a, b): +def calc_ellipse_area(a: float, b: float) -> float: """ Calculates the area of the ellipse with the given a and b radius. @@ -62,7 +60,7 @@ def calc_ellipse_circumference(a: float, b: float) -> float: return circumference -def calc_polygon_area(points): +def calc_polygon_area(points: Sequence[Tuple[float, float]]) -> float: """ Calculates the area from the polygon formed by given the points. diff --git a/invesalius/plugins.py b/invesalius/plugins.py index 9a286fe58..05af7ba4c 100644 --- a/invesalius/plugins.py +++ b/invesalius/plugins.py @@ -23,14 +23,23 @@ import pathlib import sys from itertools import chain +from types import ModuleType +from typing import TYPE_CHECKING from invesalius import inv_paths from invesalius.pubsub import pub as Publisher +if TYPE_CHECKING: + import os -def import_source(module_name, module_file_path): + +def import_source(module_name: str, module_file_path: "str | bytes | os.PathLike") -> ModuleType: module_spec = importlib.util.spec_from_file_location(module_name, module_file_path) + if module_spec is None: + raise ImportError(f"No module named {module_name}") module = importlib.util.module_from_spec(module_spec) + if module_spec.loader is None: + raise ImportError(f"Loader is None for module {module_name}") module_spec.loader.exec_module(module) return module @@ -40,10 +49,10 @@ def __init__(self): self.plugins = {} self.__bind_pubsub_evt() - def __bind_pubsub_evt(self): + def __bind_pubsub_evt(self) -> None: Publisher.subscribe(self.load_plugin, "Load plugin") - def find_plugins(self): + def find_plugins(self) -> None: self.plugins = {} for p in chain( glob.glob(str(inv_paths.PLUGIN_DIRECTORY.joinpath("**/plugin.json")), recursive=True), @@ -66,11 +75,11 @@ def find_plugins(self): "enable_startup": enable_startup, } except Exception as err: - print("It was not possible to load plugin. Error: {}".format(err)) + print(f"It was not possible to load plugin. Error: {err}") Publisher.sendMessage("Add plugins menu items", items=self.plugins) - def load_plugin(self, plugin_name): + def load_plugin(self, plugin_name: str) -> None: if plugin_name in self.plugins: plugin_module = import_source( plugin_name, self.plugins[plugin_name]["folder"].joinpath("__init__.py") diff --git a/invesalius/project.py b/invesalius/project.py index f1647c07e..b730e6a9a 100644 --- a/invesalius/project.py +++ b/invesalius/project.py @@ -18,26 +18,26 @@ # -------------------------------------------------------------------------- import datetime -import glob import os import plistlib import shutil import sys import tarfile import tempfile +from typing import TYPE_CHECKING, Dict, List, Union import numpy as np -import wx from vtkmodules.vtkCommonCore import vtkFileOutputWindow, vtkOutputWindow import invesalius.constants as const -import invesalius.data.polydata_utils as pu -import invesalius.version as version from invesalius import inv_paths from invesalius.data import imagedata_utils from invesalius.presets import Presets from invesalius.pubsub import pub as Publisher -from invesalius.utils import Singleton, TwoWaysDictionary, debug, decode, touch +from invesalius.utils import Singleton, TwoWaysDictionary, debug, decode + +if TYPE_CHECKING: + from invesalius.data.mask import Mask if sys.platform == "win32": try: @@ -97,14 +97,14 @@ def __init__(self): # TODO: Future + # Allow insertion of new surface quality modes - def Close(self): + def Close(self) -> None: for name in self.__dict__: attr = getattr(self, name) del attr self.__init__() - def AddMask(self, mask): + def AddMask(self, mask: "Mask") -> int: """ Insert new mask (Mask) into project data. @@ -119,7 +119,7 @@ def AddMask(self, mask): mask.index = index return index - def RemoveMask(self, index): + def RemoveMask(self, index: int) -> None: new_dict = TwoWaysDictionary() new_index = 0 for i in self.mask_dict: @@ -187,8 +187,8 @@ def SetAcquisitionModality(self, type_=None): debug("Different Acquisition Modality!!!") self.modality = type_ - def SetRaycastPreset(self, label): - path = os.path.join(RAYCASTING_PRESETS_DIRECTORY, label + ".plist") + def SetRaycastPreset(self, label: str) -> None: + path = os.path.join(inv_paths.RAYCASTING_PRESETS_DIRECTORY, label + ".plist") with open(path, "r+b") as f: preset = plistlib.load(f, fmt=plistlib.FMT_XML) Publisher.sendMessage("Set raycasting preset", preset) @@ -206,7 +206,7 @@ def SavePlistProject(self, dir_, filename, compress=False): self.compress = compress - filename_tmp = os.path.join(dir_temp, "matrix.dat") + # filename_tmp = os.path.join(dir_temp, "matrix.dat") filelist = {} project = { @@ -323,7 +323,7 @@ def load_from_folder(self, dirpath): self.compress = project.get("compress", True) # Opening the matrix containing the slices - filepath = os.path.join(dirpath, project["matrix"]["filename"]) + filepath: str = os.path.join(dirpath, project["matrix"]["filename"]) self.matrix_filename = filepath self.matrix_shape = project["matrix"]["shape"] self.matrix_dtype = project["matrix"]["dtype"] @@ -348,7 +348,7 @@ def load_from_folder(self, dirpath): self.mask_dict[m.index] = m # Opening the surfaces - self.surface_dict = {} + self.surface_dict: dict[int, srf.Surface] = {} for index in sorted(project.get("surfaces", []), key=lambda x: int(x)): filename = project["surfaces"][index] filepath = os.path.join(dirpath, filename) @@ -442,7 +442,7 @@ def export_project_to_hdf5(self, filename, save_masks=True): for index in self.mask_dict: mask = self.mask_dict[index] s.do_threshold_to_all_slices(mask) - key = "masks/{}".format(index) + key = f"masks/{index}" f[key + "/name"] = mask.name f[key + "/matrix"] = mask.matrix[1:, 1:, 1:] f[key + "/colour"] = mask.colour[:3] @@ -477,12 +477,17 @@ def export_project_to_nifti(self, filename, save_masks=True): else: ext = ".nii" basename = filename - nib.save(mask_nifti, "{}_mask_{}_{}{}".format(basename, mask.index, mask.name, ext)) + nib.save(mask_nifti, f"{basename}_mask_{mask.index}_{mask.name}{ext}") -def Compress(folder, filename, filelist, compress=False): +def Compress( + folder: Union[str, os.PathLike], + filename: Union[str, os.PathLike], + filelist: Dict[Union[str, os.PathLike], Union[str, os.PathLike]], + compress: bool = False, +) -> None: tmpdir, tmpdir_ = os.path.split(folder) - current_dir = os.path.abspath(".") + # current_dir = os.path.abspath(".") fd_inv3, temp_inv3 = tempfile.mkstemp() if _has_win32api: temp_inv3 = win32api.GetShortPathName(temp_inv3) @@ -502,7 +507,7 @@ def Compress(folder, filename, filelist, compress=False): # os.chdir(current_dir) -def Extract(filename, folder): +def Extract(filename: Union[str, bytes, os.PathLike], folder: Union[str, bytes, os.PathLike]): if _has_win32api: folder = win32api.GetShortPathName(folder) folder = decode(folder, const.FS_ENCODE) @@ -513,6 +518,8 @@ def Extract(filename, folder): filelist = [] for t in tar.getmembers(): fsrc = tar.extractfile(t) + if fsrc is None: + raise Exception("Error extracting file") fname = os.path.join(folder, decode(t.name, "utf-8")) fdst = open(fname, "wb") shutil.copyfileobj(fsrc, fdst) @@ -525,7 +532,9 @@ def Extract(filename, folder): return filelist -def Extract_(filename, folder): +def Extract_( + filename: Union[str, bytes, os.PathLike], folder: Union[str, os.PathLike] +) -> List[str]: tar = tarfile.open(filename, "r:gz") # tar.list(verbose=True) tar.extractall(folder) diff --git a/invesalius/pubsub/pub.py b/invesalius/pubsub/pub.py index 53a1efcab..2c26f49f4 100644 --- a/invesalius/pubsub/pub.py +++ b/invesalius/pubsub/pub.py @@ -17,10 +17,10 @@ # detalhes. # -------------------------------------------------------------------------- -from typing import Callable +from typing import Callable, Optional, Tuple from pubsub import pub as Publisher -from pubsub.core.listener import UserListener +from pubsub.core.listener import Listener, UserListener __all__ = [ # subscribing @@ -35,10 +35,10 @@ Hook = Callable[[str, dict], None] -sendMessage_hook: Hook = None +sendMessage_hook: Optional[Hook] = None -def add_sendMessage_hook(hook: Hook): +def add_sendMessage_hook(hook: Hook) -> None: """Add a hook for sending messages. The hook is a function that takes the topic name as the first parameter and the message dict as the second parameter, and returns None. @@ -49,23 +49,23 @@ def add_sendMessage_hook(hook: Hook): sendMessage_hook = hook -def subscribe(listener: UserListener, topicName: str, **curriedArgs): +def subscribe(listener: UserListener, topicName: str, **curriedArgs) -> Tuple[Listener, bool]: """Subscribe to a topic. :param listener: :param topicName: :param curriedArgs: """ - subscribedListener, success = Publisher.subscribe(listener, topicName, **curriedArgs) + subscribedListener, success = Publisher.subscribe(listener, topicName, **curriedArgs) # type: ignore This is a bug in PyPubSub return subscribedListener, success -def unsubscribe(*args, **kwargs): +def unsubscribe(*args, **kwargs) -> None: """Unsubscribe from a topic.""" Publisher.unsubscribe(*args, **kwargs) -def sendMessage(topicName: str, **msgdata): +def sendMessage(topicName: str, **msgdata) -> None: """Send a message in a given topic. :param topicName: @@ -76,7 +76,7 @@ def sendMessage(topicName: str, **msgdata): sendMessage_hook(topicName, msgdata) -def sendMessage_no_hook(topicName: str, **msgdata): +def sendMessage_no_hook(topicName: str, **msgdata) -> None: """Send a message in a given topic, but do not call the hook. :param topicName: diff --git a/invesalius/session.py b/invesalius/session.py index 8d782c712..39dfc33ae 100644 --- a/invesalius/session.py +++ b/invesalius/session.py @@ -17,28 +17,21 @@ # detalhes. # -------------------------------------------------------------------------- -try: - import configparser as ConfigParser -except ImportError: - import ConfigParser import codecs -import collections -import datetime +import configparser as ConfigParser import json import os -import shutil -import sys -import time from json.decoder import JSONDecodeError from random import randint -from threading import Thread - -import wx +from typing import TYPE_CHECKING, Any, Dict, List, Tuple, Union from invesalius import inv_paths from invesalius.pubsub import pub as Publisher -from invesalius.utils import Singleton, debug, decode, deep_merge_dict +from invesalius.utils import Singleton, debug, deep_merge_dict + +if TYPE_CHECKING: + from pathlib import Path CONFIG_PATH = os.path.join(inv_paths.USER_INV_DIR, "config.json") OLD_CONFIG_PATH = os.path.join(inv_paths.USER_INV_DIR, "config.cfg") @@ -54,7 +47,7 @@ class Session(metaclass=Singleton): def __init__(self): self.temp_item = False self.mask_3d_preview = False - self._config = { + self._config: Dict[str, Union[int, str, bool, List[Tuple[str, str]]]] = { "project_status": 3, "language": "", "auto_reload_preview": False, @@ -68,10 +61,10 @@ def __init__(self): self._exited_successfully_last_time = not self._ReadState() self.__bind_events() - def __bind_events(self): + def __bind_events(self) -> None: Publisher.subscribe(self._Exit, "Exit session") - def CreateConfig(self): + def CreateConfig(self) -> None: import invesalius.constants as const self._config = { @@ -98,46 +91,46 @@ def CreateConfig(self): } self.WriteConfigFile() - def CreateState(self): - self._state = {} + def CreateState(self) -> None: + self._state: Dict[str, Any] = {} self.WriteStateFile() - def DeleteStateFile(self): + def DeleteStateFile(self) -> None: if os.path.exists(STATE_PATH): os.remove(STATE_PATH) print("Successfully deleted state file.") else: print("State file does not exist.") - def ExitedSuccessfullyLastTime(self): + def ExitedSuccessfullyLastTime(self) -> bool: return self._exited_successfully_last_time - def SetConfig(self, key, value): + def SetConfig(self, key: str, value: Any) -> None: self._config[key] = value self.WriteConfigFile() - def GetConfig(self, key, default_value=None): + def GetConfig(self, key: str, default_value: Any = None) -> Any: if key in self._config: return self._config[key] else: return default_value - def SetState(self, key, value): + def SetState(self, key: str, value: Any) -> None: self._state[key] = value self.WriteStateFile() - def GetState(self, key, default_value=None): + def GetState(self, key: str, default_value: Any = None) -> Any: if key in self._state: return self._state[key] else: return default_value - def IsOpen(self): + def IsOpen(self) -> bool: import invesalius.constants as const return self.GetConfig("project_status") != const.PROJECT_STATUS_CLOSED - def CloseProject(self): + def CloseProject(self) -> None: import invesalius.constants as const debug("Session.CloseProject") @@ -146,7 +139,7 @@ def CloseProject(self): # self.mode = const.MODE_RP self.temp_item = False - def SaveProject(self, path=()): + def SaveProject(self, path: Union[Tuple[()], Tuple[str, str]] = ()) -> None: import invesalius.constants as const debug("Session.SaveProject") @@ -158,13 +151,13 @@ def SaveProject(self, path=()): self.SetConfig("project_status", const.PROJECT_STATUS_OPENED) - def ChangeProject(self): + def ChangeProject(self) -> None: import invesalius.constants as const debug("Session.ChangeProject") self.SetConfig("project_status", const.PROJECT_STATUS_CHANGED) - def CreateProject(self, filename): + def CreateProject(self, filename: str) -> None: import invesalius.constants as const debug("Session.CreateProject") @@ -180,7 +173,7 @@ def CreateProject(self, filename): self.SetConfig("project_status", const.PROJECT_STATUS_NEW) - def OpenProject(self, filepath): + def OpenProject(self, filepath: "str | Path") -> None: import invesalius.constants as const debug("Session.OpenProject") @@ -193,21 +186,21 @@ def OpenProject(self, filepath): self.SetState("project_path", project_path) self.SetConfig("project_status", const.PROJECT_STATUS_OPENED) - def WriteConfigFile(self): + def WriteConfigFile(self) -> None: self._write_to_json(self._config, CONFIG_PATH) - def WriteStateFile(self): + def WriteStateFile(self) -> None: self._write_to_json(self._state, STATE_PATH) - def _write_to_json(self, config_dict, config_filename): + def _write_to_json(self, config_dict: dict, config_filename: "str | Path") -> None: with open(config_filename, "w") as config_file: json.dump(config_dict, config_file, sort_keys=True, indent=4) - def _add_to_recent_projects(self, item): + def _add_to_recent_projects(self, item: Tuple[str, str]) -> None: import invesalius.constants as const # Recent projects list - recent_projects = self.GetConfig("recent_projects") + recent_projects: List[Tuple[str, str]] = self.GetConfig("recent_projects") item = list(item) # If item exists, remove it from list @@ -218,8 +211,8 @@ def _add_to_recent_projects(self, item): recent_projects.insert(0, item) self.SetConfig("recent_projects", recent_projects[: const.RECENT_PROJECTS_MAXIMUM]) - def _read_config_from_json(self, json_filename): - with open(json_filename, "r") as config_file: + def _read_config_from_json(self, json_filename: "str | Path") -> None: + with open(json_filename) as config_file: config_dict = json.load(config_file) self._config = deep_merge_dict(self._config.copy(), config_dict) @@ -227,7 +220,7 @@ def _read_config_from_json(self, json_filename): # isn't a recover session tool in InVesalius yet. self.project_status = 3 - def _read_config_from_ini(self, config_filename): + def _read_config_from_ini(self, config_filename: str) -> None: file = codecs.open(config_filename, "rb", SESSION_ENCODING) config = ConfigParser.ConfigParser() config.readfp(file) @@ -238,7 +231,7 @@ def _read_config_from_ini(self, config_filename): debug_efield = config.getboolean("session", "debug_efield") language = config.get("session", "language") last_dicom_folder = config.get("paths", "last_dicom_folder") - project_status = config.getint("session", "status") + # project_status = config.getint("session", "status") surface_interpolation = config.getint("session", "surface_interpolation") slice_interpolation = config.getint("session", "slice_interpolation") rendering = config.getint("session", "rendering") @@ -279,30 +272,30 @@ def _read_config_from_ini(self, config_filename): # TODO: Make also this function private so that it is run when the class constructor is run. # (Compare to _ReadState below.) - def ReadConfig(self): + def ReadConfig(self) -> bool: try: self._read_config_from_json(CONFIG_PATH) except Exception as e1: - debug(e1) + debug(str(e1)) try: self._read_config_from_ini(OLD_CONFIG_PATH) except Exception as e2: - debug(e2) + debug(str(e2)) return False self.WriteConfigFile() return True - def _ReadState(self): + def _ReadState(self) -> bool: success = False if os.path.exists(STATE_PATH): print("Restoring a previous state...") - state_file = open(STATE_PATH, "r") + state_file = open(STATE_PATH) try: self._state = json.load(state_file) success = True - except JSONDecodeError as e: + except JSONDecodeError: print("State file is corrupted. Deleting...") state_file.close() @@ -313,6 +306,6 @@ def _ReadState(self): return success - def _Exit(self): + def _Exit(self) -> None: self.CloseProject() self.DeleteStateFile() diff --git a/invesalius/version.py b/invesalius/version.py deleted file mode 100644 index 62c71fd50..000000000 --- a/invesalius/version.py +++ /dev/null @@ -1,68 +0,0 @@ -# -------------------------------------------------------------------------- -# Software: InVesalius - Software de Reconstrucao 3D de Imagens Medicas -# Copyright: (C) 2001 Centro de Pesquisas Renato Archer -# Homepage: http://www.softwarepublico.gov.br -# Contact: invesalius@cti.gov.br -# License: GNU - GPL 2 (LICENSE.txt/LICENCA.txt) -# -------------------------------------------------------------------------- -# Este programa e software livre; voce pode redistribui-lo e/ou -# modifica-lo sob os termos da Licenca Publica Geral GNU, conforme -# publicada pela Free Software Foundation; de acordo com a versao 2 -# da Licenca. -# -# Este programa eh distribuido na expectativa de ser util, mas SEM -# QUALQUER GARANTIA; sem mesmo a garantia implicita de -# COMERCIALIZACAO ou de ADEQUACAO A QUALQUER PROPOSITO EM -# PARTICULAR. Consulte a Licenca Publica Geral GNU para obter mais -# detalhes. -# -------------------------------------------------------------------------- - -# This file is based on Django code (version 10377): -# django/trunk/django/utils/version.py -# Available at http://code.djangoproject.com/ - -import os -import os.path -import re - - -# DEPRECATED. Check the use o Dunamai (https://github.com/mtkennerly/dunamai) to have git commit -def get_svn_revision(path=None): - """ - Returns the SVN revision in the form pspb-XXXX, - where XXXX is the revision number. - - Returns pspb-unknown if anything goes wrong, such as an unexpected - format of internal SVN files. - - If path is provided, it should be a directory whose SVN info you want to - inspect. If it's not provided, this will use the current - directory. - """ - rev = None - if path is None: - path = os.curdir - entries_path = "%s/.svn/entries" % path - - try: - entries = open(entries_path, "r").read() - except IOError: - pass - else: - # Versions >= 7 of the entries file are flat text. The first line is - # the version number. The next set of digits after 'dir' is the revision. - if re.match("(\d+)", entries): - rev_match = re.search("\d+\s+dir\s+(\d+)", entries) - if rev_match: - rev = rev_match.groups()[0] - # Older XML versions of the file specify revision as an attribute of - # the first entries node. - else: - from xml.dom import minidom - - dom = minidom.parse(entries_path) - rev = dom.getElementsByTagName("entry")[0].getAttribute("revision") - - if rev: - return "pspb-%s" % rev - return "pspb-unknown" diff --git a/pyproject.toml b/pyproject.toml index 0457adc22..1c73cbcc0 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -31,13 +31,10 @@ warn_return_any = false warn_unreachable = false warn_unused_configs = false no_implicit_reexport = false -follow_imports = "normal" +follow_imports = "skip" # change to normal later explicit_package_bases = true disable_error_code = ["attr-defined", "no-redef"] -[[tool.mypy.overrides]] -module = 'invesalius.gui.widgets.listctrl' -ignore_errors = true [[tool.mypy.overrides]] module = 'wx.*' disable_error_code = ["no-redef"] # because some classes are redefined in the stubs @@ -90,14 +87,12 @@ module = [ ignore_missing_imports = true [tool.ruff] -include = ["pyproject.toml", "invesalius/**/*.py",'setup.py','app.py'] -extend-exclude = ["./invesalius/gui/widgets/listctrl.py"] +include = ["pyproject.toml", "invesalius/**/*.py",'setup.py','app.py',"typings/**/*.pyi"] line-length = 100 # extend-exclude = ["plugins"] [tool.ruff.lint] -extend-select = ["UP","I"] # Introduces linting rules for pyupgrade -# We can extend the list with 'I' and 'PL' in the future +extend-select = ["UP","I"] # Introduces linting rules for pyupgrade and isort [tool.ruff.format] line-ending = "lf" diff --git a/requirements.txt b/requirements.txt index d27911d30..9d556e55a 100644 --- a/requirements.txt +++ b/requirements.txt @@ -23,3 +23,5 @@ psutil==6.0.0 pyserial==3.5 wxPython==4.2.1 pyacvd==0.2.11 +optitrack ; python_version == "3.8" and sys_platform == "windows" +pyclaron ; python_version == "3.8" and sys_platform == "windows" diff --git a/typings/invesalius_cy-stubs/__init__.pyi b/typings/invesalius_cy-stubs/__init__.pyi new file mode 100644 index 000000000..e69de29bb diff --git a/typings/invesalius_cy-stubs/cy_mesh.pyi b/typings/invesalius_cy-stubs/cy_mesh.pyi new file mode 100644 index 000000000..4cabdf0ee --- /dev/null +++ b/typings/invesalius_cy-stubs/cy_mesh.pyi @@ -0,0 +1,28 @@ +from vtk import vtkPolyData + +class Mesh: + def __init__(self, pd: vtkPolyData | None = None, other: Mesh | None = None) -> None: ... + def copy_to(self, other: Mesh) -> None: + """ + Copies self content to other. + """ + def to_vtk(self) -> vtkPolyData: + """ + Converts Mesh to vtkPolyData. + """ + +def ca_smoothing(mesh: Mesh, T: float, tmax: float, bmin: float, n_iters: int) -> None: + """ + This is a implementation of the paper "Context-aware mesh smoothing for + biomedical applications". It can be used to smooth meshes generated by + binary images to remove its staircase artifacts and keep the fine features. + + Params: + mesh: Mesh + T: Min angle (between vertex faces and stack_orientation) to consider a + vertex a staircase artifact + tmax: max distance the vertex must be to its nearest artifact vertex + to considered to calculate the weight + bmin: The minimum weight + n_iters: Number of iterations. + """ diff --git a/typings/invesalius_cy-stubs/floodfill.pyi b/typings/invesalius_cy-stubs/floodfill.pyi new file mode 100644 index 000000000..2de8bed0c --- /dev/null +++ b/typings/invesalius_cy-stubs/floodfill.pyi @@ -0,0 +1,28 @@ +from typing import Iterable + +import numpy as np + +def floodfill( + data: np.ndarray, + i: int, + j: int, + k: int, + v: int, + fill: int, + out: np.ndarray | None, +) -> np.ndarray | None: ... +def floodfill_threshold( + data: np.ndarray, + seeds: list[Iterable[int]], + t0: int, + t1: int, + fill: int, + strct: np.ndarray, + out: np.ndarray | None, +) -> np.ndarray | None: ... +def floodfill_auto_threshold( + data: np.ndarray, seeds: list[Iterable[int]], p: float, fill: int, out: np.ndarray | None +) -> np.ndarray | None: ... +def fill_holes_automatically( + mask: np.ndarray, labels: np.ndarray, nlabels: int, max_size: int +) -> bool: ... diff --git a/typings/invesalius_cy-stubs/mips.pyi b/typings/invesalius_cy-stubs/mips.pyi new file mode 100644 index 000000000..ef38e46c0 --- /dev/null +++ b/typings/invesalius_cy-stubs/mips.pyi @@ -0,0 +1,14 @@ +import numpy as np + +DTYPE = np.uint8 +DTYPE16 = np.uint16 +DTYPEF32 = np.float32 +DTYPE16_t = int + +def lmip( + image: np.ndarray, axis: int, tmin: DTYPE16_t, tmax: DTYPE16_t, out: np.ndarray +) -> None: ... +def mida(image: np.ndarray, axis: int, wl: DTYPE16_t, ww: DTYPE16_t, out: np.ndarray) -> None: ... +def fast_countour_mip( + image: np.ndarray, n: float, axis: int, wl: DTYPE16_t, ww: DTYPE16_t, tmip: int, out: np.ndarray +) -> None: ... diff --git a/typings/invesalius_cy-stubs/transforms.pyi b/typings/invesalius_cy-stubs/transforms.pyi new file mode 100644 index 000000000..485f7676a --- /dev/null +++ b/typings/invesalius_cy-stubs/transforms.pyi @@ -0,0 +1,13 @@ +import numpy as np + +def convolve_non_zero(volume: np.ndarray, kernel: np.ndarray, cval: float) -> np.ndarray: ... +def apply_view_matrix_transform( + volume: np.ndarray, + spacing, + M: np.ndarray, + n: int, + orientation: str, + minterpol: int, + cval: float, + out: np.ndarray, +) -> None: ... diff --git a/typings/wx/__init__.pyi b/typings/wx-stubs/__init__.pyi similarity index 100% rename from typings/wx/__init__.pyi rename to typings/wx-stubs/__init__.pyi diff --git a/typings/wx/core.pyi b/typings/wx-stubs/core.pyi similarity index 95% rename from typings/wx/core.pyi rename to typings/wx-stubs/core.pyi index bf52a4b23..da0b0dd6d 100644 --- a/typings/wx/core.pyi +++ b/typings/wx-stubs/core.pyi @@ -25,10 +25,30 @@ Everything you need for building typical GUI applications is here. # -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= # This code block was included from src/core_ex.py import sys as _sys +from typing import Any, Callable, Iterable, Iterator, Literal, NoReturn, Sequence, overload import numpy as np -from .type_defs import ColourType, Coord, EventType, PenCap, PenStyle, PolygonFillMode, SystemFont +from .type_defs import ( + ArtClient, + ArtID, + BitmapType, + ClientData, + ColourType, + Coord, + EventType, + GBPositionType, + GBSpanType, + PenCap, + PenStyle, + PolygonFillMode, + SizeType, + SystemFont, + WindowID, + WindowVariant, +) +from .type_defs import PyAssertionError as PyAssertionError +from .type_defs import PyNoAppError as PyNoAppError # Load version numbers from __version__ and some other initialization tasks... if "wxEVT_NULL" in dir(): @@ -57,7 +77,6 @@ else: wx = _sys.modules[__name__] import warnings -from typing import Any, Callable, Iterator, overload class wxPyDeprecationWarning(DeprecationWarning): pass @@ -164,13 +183,12 @@ EmptyString = "" # End of included code block # -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= -def version(): +def version() -> str: """ Returns a string containing version and port info """ - pass -def CallAfter(callableObj, *args, **kw): +def CallAfter(callableObj: Callable, *args, **kw) -> None: """ Call the specified function after the current and pending event handlers have been completed. This is also good for making GUI @@ -184,7 +202,6 @@ def CallAfter(callableObj, *args, **kw): .. seealso:: :ref:`wx.CallLater` """ - pass class CallLater: """ @@ -298,720 +315,720 @@ def IsMainThread(self): # -- end-_core --# # -- begin-defs --# -INT8_MIN = 0 -INT8_MAX = 0 -UINT8_MAX = 0 -INT16_MIN = 0 -INT16_MAX = 0 -UINT16_MAX = 0 -INT32_MIN = 0 -INT32_MAX = 0 -UINT32_MAX = 0 -INT64_MIN = 0 -INT64_MAX = 0 -UINT64_MAX = 0 -SIZE_AUTO_WIDTH = 0 -SIZE_AUTO_HEIGHT = 0 -SIZE_AUTO = 0 -SIZE_USE_EXISTING = 0 -SIZE_ALLOW_MINUS_ONE = 0 -SIZE_NO_ADJUSTMENTS = 0 -SIZE_FORCE = 0 -SIZE_FORCE_EVENT = 0 -VSCROLL = 0 -HSCROLL = 0 -CAPTION = 0 -DOUBLE_BORDER = 0 -SUNKEN_BORDER = 0 -RAISED_BORDER = 0 -BORDER = 0 -SIMPLE_BORDER = 0 -STATIC_BORDER = 0 -NO_BORDER = 0 -ALWAYS_SHOW_SB = 0 -CLIP_CHILDREN = 0 -CLIP_SIBLINGS = 0 -TRANSPARENT_WINDOW = 0 -TAB_TRAVERSAL = 0 -WANTS_CHARS = 0 -RETAINED = 0 -BACKINGSTORE = 0 -POPUP_WINDOW = 0 -FULL_REPAINT_ON_RESIZE = 0 -NO_FULL_REPAINT_ON_RESIZE = 0 -WINDOW_STYLE_MASK = 0 -WS_EX_BLOCK_EVENTS = 0 -WS_EX_TRANSIENT = 0 -WS_EX_THEMED_BACKGROUND = 0 -WS_EX_PROCESS_IDLE = 0 -WS_EX_PROCESS_UI_UPDATES = 0 -FRAME_EX_METAL = 0 -DIALOG_EX_METAL = 0 -WS_EX_CONTEXTHELP = 0 -FRAME_EX_CONTEXTHELP = 0 -DIALOG_EX_CONTEXTHELP = 0 -FRAME_DRAWER = 0 -FRAME_NO_WINDOW_MENU = 0 -MB_DOCKABLE = 0 -MENU_TEAROFF = 0 -COLOURED = 0 -FIXED_LENGTH = 0 -LB_SORT = 0 -LB_SINGLE = 0 -LB_MULTIPLE = 0 -LB_EXTENDED = 0 -LB_NEEDED_SB = 0 -LB_OWNERDRAW = 0 -LB_ALWAYS_SB = 0 -LB_NO_SB = 0 -LB_HSCROLL = 0 -LB_INT_HEIGHT = 0 -CB_SIMPLE = 0 -CB_SORT = 0 -CB_READONLY = 0 -CB_DROPDOWN = 0 -RA_LEFTTORIGHT = 0 -RA_TOPTOBOTTOM = 0 -RA_SPECIFY_COLS = 0 -RA_SPECIFY_ROWS = 0 -RA_HORIZONTAL = 0 -RA_VERTICAL = 0 -RB_GROUP = 0 -RB_SINGLE = 0 -SB_HORIZONTAL = 0 -SB_VERTICAL = 0 -SP_HORIZONTAL = 0 -SP_VERTICAL = 0 -SP_ARROW_KEYS = 0 -SP_WRAP = 0 -TC_RIGHTJUSTIFY = 0 -TC_FIXEDWIDTH = 0 -TC_TOP = 0 -TC_LEFT = 0 -TC_RIGHT = 0 -TC_BOTTOM = 0 -TC_MULTILINE = 0 -TC_OWNERDRAW = 0 -BI_EXPAND = 0 -LI_HORIZONTAL = 0 -LI_VERTICAL = 0 -YES = 0 -OK = 0 -NO = 0 -YES_NO = 0 -CANCEL = 0 -APPLY = 0 -CLOSE = 0 -OK_DEFAULT = 0 -YES_DEFAULT = 0 -NO_DEFAULT = 0 -CANCEL_DEFAULT = 0 -ICON_EXCLAMATION = 0 -ICON_HAND = 0 -ICON_WARNING = 0 -ICON_ERROR = 0 -ICON_QUESTION = 0 -ICON_INFORMATION = 0 -ICON_STOP = 0 -ICON_ASTERISK = 0 -HELP = 0 -FORWARD = 0 -BACKWARD = 0 -RESET = 0 -MORE = 0 -SETUP = 0 -ICON_NONE = 0 -ICON_AUTH_NEEDED = 0 -ICON_MASK = 0 -NOT_FOUND = 0 -PRINT_QUALITY_HIGH = 0 -PRINT_QUALITY_MEDIUM = 0 -PRINT_QUALITY_LOW = 0 -PRINT_QUALITY_DRAFT = 0 -STAY_ON_TOP = 0 -ICONIZE = 0 -MINIMIZE = 0 -MAXIMIZE = 0 -CLOSE_BOX = 0 -SYSTEM_MENU = 0 -MINIMIZE_BOX = 0 -MAXIMIZE_BOX = 0 -TINY_CAPTION = 0 -RESIZE_BORDER = 0 -CENTRE = 0 -CENTER = 0 -HORIZONTAL = 0 -VERTICAL = 0 -BOTH = 0 -ORIENTATION_MASK = 0 -LEFT = 0 -RIGHT = 0 -UP = 0 -DOWN = 0 -TOP = 0 -BOTTOM = 0 -NORTH = 0 -SOUTH = 0 -WEST = 0 -EAST = 0 -ALL = 0 -DIRECTION_MASK = 0 -ALIGN_INVALID = 0 -ALIGN_NOT = 0 -ALIGN_CENTER_HORIZONTAL = 0 -ALIGN_CENTRE_HORIZONTAL = 0 -ALIGN_LEFT = 0 -ALIGN_TOP = 0 -ALIGN_RIGHT = 0 -ALIGN_BOTTOM = 0 -ALIGN_CENTER_VERTICAL = 0 -ALIGN_CENTRE_VERTICAL = 0 -ALIGN_CENTER = 0 -ALIGN_CENTRE = 0 -ALIGN_MASK = 0 -FIXED_MINSIZE = 0 -RESERVE_SPACE_EVEN_IF_HIDDEN = 0 -SIZER_FLAG_BITS_MASK = 0 -STRETCH_NOT = 0 -SHRINK = 0 -GROW = 0 -EXPAND = 0 -SHAPED = 0 -TILE = 0 -STRETCH_MASK = 0 -BORDER_DEFAULT = 0 -BORDER_NONE = 0 -BORDER_STATIC = 0 -BORDER_SIMPLE = 0 -BORDER_RAISED = 0 -BORDER_SUNKEN = 0 -BORDER_DOUBLE = 0 -BORDER_THEME = 0 -BORDER_MASK = 0 -BG_STYLE_ERASE = 0 -BG_STYLE_SYSTEM = 0 -BG_STYLE_PAINT = 0 -BG_STYLE_COLOUR = 0 -BG_STYLE_TRANSPARENT = 0 -ID_AUTO_LOWEST = 0 -ID_AUTO_HIGHEST = 0 -ID_NONE = 0 -ID_SEPARATOR = 0 -ID_ANY = 0 -ID_LOWEST = 0 -ID_OPEN = 0 -ID_CLOSE = 0 -ID_NEW = 0 -ID_SAVE = 0 -ID_SAVEAS = 0 -ID_REVERT = 0 -ID_EXIT = 0 -ID_UNDO = 0 -ID_REDO = 0 -ID_HELP = 0 -ID_PRINT = 0 -ID_PRINT_SETUP = 0 -ID_PAGE_SETUP = 0 -ID_PREVIEW = 0 -ID_ABOUT = 0 -ID_HELP_CONTENTS = 0 -ID_HELP_INDEX = 0 -ID_HELP_SEARCH = 0 -ID_HELP_COMMANDS = 0 -ID_HELP_PROCEDURES = 0 -ID_HELP_CONTEXT = 0 -ID_CLOSE_ALL = 0 -ID_PREFERENCES = 0 -ID_EDIT = 0 -ID_CUT = 0 -ID_COPY = 0 -ID_PASTE = 0 -ID_CLEAR = 0 -ID_FIND = 0 -ID_DUPLICATE = 0 -ID_SELECTALL = 0 -ID_DELETE = 0 -ID_REPLACE = 0 -ID_REPLACE_ALL = 0 -ID_PROPERTIES = 0 -ID_VIEW_DETAILS = 0 -ID_VIEW_LARGEICONS = 0 -ID_VIEW_SMALLICONS = 0 -ID_VIEW_LIST = 0 -ID_VIEW_SORTDATE = 0 -ID_VIEW_SORTNAME = 0 -ID_VIEW_SORTSIZE = 0 -ID_VIEW_SORTTYPE = 0 -ID_FILE = 0 -ID_FILE1 = 0 -ID_FILE2 = 0 -ID_FILE3 = 0 -ID_FILE4 = 0 -ID_FILE5 = 0 -ID_FILE6 = 0 -ID_FILE7 = 0 -ID_FILE8 = 0 -ID_FILE9 = 0 -ID_OK = 0 -ID_CANCEL = 0 -ID_APPLY = 0 -ID_YES = 0 -ID_NO = 0 -ID_STATIC = 0 -ID_FORWARD = 0 -ID_BACKWARD = 0 -ID_DEFAULT = 0 -ID_MORE = 0 -ID_SETUP = 0 -ID_RESET = 0 -ID_CONTEXT_HELP = 0 -ID_YESTOALL = 0 -ID_NOTOALL = 0 -ID_ABORT = 0 -ID_RETRY = 0 -ID_IGNORE = 0 -ID_ADD = 0 -ID_REMOVE = 0 -ID_UP = 0 -ID_DOWN = 0 -ID_HOME = 0 -ID_REFRESH = 0 -ID_STOP = 0 -ID_INDEX = 0 -ID_BOLD = 0 -ID_ITALIC = 0 -ID_JUSTIFY_CENTER = 0 -ID_JUSTIFY_FILL = 0 -ID_JUSTIFY_RIGHT = 0 -ID_JUSTIFY_LEFT = 0 -ID_UNDERLINE = 0 -ID_INDENT = 0 -ID_UNINDENT = 0 -ID_ZOOM_100 = 0 -ID_ZOOM_FIT = 0 -ID_ZOOM_IN = 0 -ID_ZOOM_OUT = 0 -ID_UNDELETE = 0 -ID_REVERT_TO_SAVED = 0 -ID_CDROM = 0 -ID_CONVERT = 0 -ID_EXECUTE = 0 -ID_FLOPPY = 0 -ID_HARDDISK = 0 -ID_BOTTOM = 0 -ID_FIRST = 0 -ID_LAST = 0 -ID_TOP = 0 -ID_INFO = 0 -ID_JUMP_TO = 0 -ID_NETWORK = 0 -ID_SELECT_COLOR = 0 -ID_SELECT_FONT = 0 -ID_SORT_ASCENDING = 0 -ID_SORT_DESCENDING = 0 -ID_SPELL_CHECK = 0 -ID_STRIKETHROUGH = 0 -ID_SYSTEM_MENU = 0 -ID_CLOSE_FRAME = 0 -ID_MOVE_FRAME = 0 -ID_RESIZE_FRAME = 0 -ID_MAXIMIZE_FRAME = 0 -ID_ICONIZE_FRAME = 0 -ID_RESTORE_FRAME = 0 -ID_MDI_WINDOW_FIRST = 0 -ID_MDI_WINDOW_CASCADE = 0 -ID_MDI_WINDOW_TILE_HORZ = 0 -ID_MDI_WINDOW_TILE_VERT = 0 -ID_MDI_WINDOW_ARRANGE_ICONS = 0 -ID_MDI_WINDOW_PREV = 0 -ID_MDI_WINDOW_NEXT = 0 -ID_MDI_WINDOW_LAST = 0 -ID_FILEDLGG = 0 -ID_FILECTRL = 0 -ID_HIGHEST = 0 -ITEM_SEPARATOR = 0 -ITEM_NORMAL = 0 -ITEM_CHECK = 0 -ITEM_RADIO = 0 -ITEM_DROPDOWN = 0 -ITEM_MAX = 0 -HT_NOWHERE = 0 -HT_SCROLLBAR_FIRST = 0 -HT_SCROLLBAR_ARROW_LINE_1 = 0 -HT_SCROLLBAR_ARROW_LINE_2 = 0 -HT_SCROLLBAR_ARROW_PAGE_1 = 0 -HT_SCROLLBAR_ARROW_PAGE_2 = 0 -HT_SCROLLBAR_THUMB = 0 -HT_SCROLLBAR_BAR_1 = 0 -HT_SCROLLBAR_BAR_2 = 0 -HT_SCROLLBAR_LAST = 0 -HT_WINDOW_OUTSIDE = 0 -HT_WINDOW_INSIDE = 0 -HT_WINDOW_VERT_SCROLLBAR = 0 -HT_WINDOW_HORZ_SCROLLBAR = 0 -HT_WINDOW_CORNER = 0 -HT_MAX = 0 -DF_INVALID = 0 -DF_TEXT = 0 -DF_BITMAP = 0 -DF_METAFILE = 0 -DF_SYLK = 0 -DF_DIF = 0 -DF_TIFF = 0 -DF_OEMTEXT = 0 -DF_DIB = 0 -DF_PALETTE = 0 -DF_PENDATA = 0 -DF_RIFF = 0 -DF_WAVE = 0 -DF_UNICODETEXT = 0 -DF_ENHMETAFILE = 0 -DF_FILENAME = 0 -DF_LOCALE = 0 -DF_PRIVATE = 0 -DF_HTML = 0 -DF_PNG = 0 -DF_MAX = 0 -WXK_NONE = 0 -WXK_CONTROL_A = 0 -WXK_CONTROL_B = 0 -WXK_CONTROL_C = 0 -WXK_CONTROL_D = 0 -WXK_CONTROL_E = 0 -WXK_CONTROL_F = 0 -WXK_CONTROL_G = 0 -WXK_CONTROL_H = 0 -WXK_CONTROL_I = 0 -WXK_CONTROL_J = 0 -WXK_CONTROL_K = 0 -WXK_CONTROL_L = 0 -WXK_CONTROL_M = 0 -WXK_CONTROL_N = 0 -WXK_CONTROL_O = 0 -WXK_CONTROL_P = 0 -WXK_CONTROL_Q = 0 -WXK_CONTROL_R = 0 -WXK_CONTROL_S = 0 -WXK_CONTROL_T = 0 -WXK_CONTROL_U = 0 -WXK_CONTROL_V = 0 -WXK_CONTROL_W = 0 -WXK_CONTROL_X = 0 -WXK_CONTROL_Y = 0 -WXK_CONTROL_Z = 0 -WXK_BACK = 0 -WXK_TAB = 0 -WXK_RETURN = 0 -WXK_ESCAPE = 0 -WXK_SPACE = 0 -WXK_DELETE = 0 -WXK_START = 0 -WXK_LBUTTON = 0 -WXK_RBUTTON = 0 -WXK_CANCEL = 0 -WXK_MBUTTON = 0 -WXK_CLEAR = 0 -WXK_SHIFT = 0 -WXK_ALT = 0 -WXK_CONTROL = 0 -WXK_RAW_CONTROL = 0 -WXK_MENU = 0 -WXK_PAUSE = 0 -WXK_CAPITAL = 0 -WXK_END = 0 -WXK_HOME = 0 -WXK_LEFT = 0 -WXK_UP = 0 -WXK_RIGHT = 0 -WXK_DOWN = 0 -WXK_SELECT = 0 -WXK_PRINT = 0 -WXK_EXECUTE = 0 -WXK_SNAPSHOT = 0 -WXK_INSERT = 0 -WXK_HELP = 0 -WXK_NUMPAD0 = 0 -WXK_NUMPAD1 = 0 -WXK_NUMPAD2 = 0 -WXK_NUMPAD3 = 0 -WXK_NUMPAD4 = 0 -WXK_NUMPAD5 = 0 -WXK_NUMPAD6 = 0 -WXK_NUMPAD7 = 0 -WXK_NUMPAD8 = 0 -WXK_NUMPAD9 = 0 -WXK_MULTIPLY = 0 -WXK_ADD = 0 -WXK_SEPARATOR = 0 -WXK_SUBTRACT = 0 -WXK_DECIMAL = 0 -WXK_DIVIDE = 0 -WXK_F1 = 0 -WXK_F2 = 0 -WXK_F3 = 0 -WXK_F4 = 0 -WXK_F5 = 0 -WXK_F6 = 0 -WXK_F7 = 0 -WXK_F8 = 0 -WXK_F9 = 0 -WXK_F10 = 0 -WXK_F11 = 0 -WXK_F12 = 0 -WXK_F13 = 0 -WXK_F14 = 0 -WXK_F15 = 0 -WXK_F16 = 0 -WXK_F17 = 0 -WXK_F18 = 0 -WXK_F19 = 0 -WXK_F20 = 0 -WXK_F21 = 0 -WXK_F22 = 0 -WXK_F23 = 0 -WXK_F24 = 0 -WXK_NUMLOCK = 0 -WXK_SCROLL = 0 -WXK_PAGEUP = 0 -WXK_PAGEDOWN = 0 -WXK_NUMPAD_SPACE = 0 -WXK_NUMPAD_TAB = 0 -WXK_NUMPAD_ENTER = 0 -WXK_NUMPAD_F1 = 0 -WXK_NUMPAD_F2 = 0 -WXK_NUMPAD_F3 = 0 -WXK_NUMPAD_F4 = 0 -WXK_NUMPAD_HOME = 0 -WXK_NUMPAD_LEFT = 0 -WXK_NUMPAD_UP = 0 -WXK_NUMPAD_RIGHT = 0 -WXK_NUMPAD_DOWN = 0 -WXK_NUMPAD_PAGEUP = 0 -WXK_NUMPAD_PAGEDOWN = 0 -WXK_NUMPAD_END = 0 -WXK_NUMPAD_BEGIN = 0 -WXK_NUMPAD_INSERT = 0 -WXK_NUMPAD_DELETE = 0 -WXK_NUMPAD_EQUAL = 0 -WXK_NUMPAD_MULTIPLY = 0 -WXK_NUMPAD_ADD = 0 -WXK_NUMPAD_SEPARATOR = 0 -WXK_NUMPAD_SUBTRACT = 0 -WXK_NUMPAD_DECIMAL = 0 -WXK_NUMPAD_DIVIDE = 0 -WXK_WINDOWS_LEFT = 0 -WXK_WINDOWS_RIGHT = 0 -WXK_WINDOWS_MENU = 0 -WXK_COMMAND = 0 -WXK_SPECIAL1 = 0 -WXK_SPECIAL2 = 0 -WXK_SPECIAL3 = 0 -WXK_SPECIAL4 = 0 -WXK_SPECIAL5 = 0 -WXK_SPECIAL6 = 0 -WXK_SPECIAL7 = 0 -WXK_SPECIAL8 = 0 -WXK_SPECIAL9 = 0 -WXK_SPECIAL10 = 0 -WXK_SPECIAL11 = 0 -WXK_SPECIAL12 = 0 -WXK_SPECIAL13 = 0 -WXK_SPECIAL14 = 0 -WXK_SPECIAL15 = 0 -WXK_SPECIAL16 = 0 -WXK_SPECIAL17 = 0 -WXK_SPECIAL18 = 0 -WXK_SPECIAL19 = 0 -WXK_SPECIAL20 = 0 -WXK_BROWSER_BACK = 0 -WXK_BROWSER_FORWARD = 0 -WXK_BROWSER_REFRESH = 0 -WXK_BROWSER_STOP = 0 -WXK_BROWSER_SEARCH = 0 -WXK_BROWSER_FAVORITES = 0 -WXK_BROWSER_HOME = 0 -WXK_VOLUME_MUTE = 0 -WXK_VOLUME_DOWN = 0 -WXK_VOLUME_UP = 0 -WXK_MEDIA_NEXT_TRACK = 0 -WXK_MEDIA_PREV_TRACK = 0 -WXK_MEDIA_STOP = 0 -WXK_MEDIA_PLAY_PAUSE = 0 -WXK_LAUNCH_MAIL = 0 -WXK_LAUNCH_APP1 = 0 -WXK_LAUNCH_APP2 = 0 -WXK_LAUNCH_0 = 0 -WXK_LAUNCH_1 = 0 -WXK_LAUNCH_2 = 0 -WXK_LAUNCH_3 = 0 -WXK_LAUNCH_4 = 0 -WXK_LAUNCH_5 = 0 -WXK_LAUNCH_6 = 0 -WXK_LAUNCH_7 = 0 -WXK_LAUNCH_8 = 0 -WXK_LAUNCH_9 = 0 -WXK_LAUNCH_A = 0 -WXK_LAUNCH_B = 0 -WXK_LAUNCH_C = 0 -WXK_LAUNCH_D = 0 -WXK_LAUNCH_E = 0 -WXK_LAUNCH_F = 0 -MOD_NONE = 0 -MOD_ALT = 0 -MOD_CONTROL = 0 -MOD_ALTGR = 0 -MOD_SHIFT = 0 -MOD_META = 0 -MOD_WIN = 0 -MOD_RAW_CONTROL = 0 -MOD_CMD = 0 -MOD_ALL = 0 -PAPER_10X11 = 0 -PAPER_10X14 = 0 -PAPER_11X17 = 0 -PAPER_12X11 = 0 -PAPER_15X11 = 0 -PAPER_9X11 = 0 -PAPER_A2 = 0 -PAPER_A3 = 0 -PAPER_A3_EXTRA = 0 -PAPER_A3_EXTRA_TRANSVERSE = 0 -PAPER_A3_ROTATED = 0 -PAPER_A3_TRANSVERSE = 0 -PAPER_A4 = 0 -PAPER_A4SMALL = 0 -PAPER_A4_EXTRA = 0 -PAPER_A4_PLUS = 0 -PAPER_A4_ROTATED = 0 -PAPER_A4_TRANSVERSE = 0 -PAPER_A5 = 0 -PAPER_A5_EXTRA = 0 -PAPER_A5_ROTATED = 0 -PAPER_A5_TRANSVERSE = 0 -PAPER_A6 = 0 -PAPER_A6_ROTATED = 0 -PAPER_A_PLUS = 0 -PAPER_B4 = 0 -PAPER_B4_JIS_ROTATED = 0 -PAPER_B5 = 0 -PAPER_B5_EXTRA = 0 -PAPER_B5_JIS_ROTATED = 0 -PAPER_B5_TRANSVERSE = 0 -PAPER_B6_JIS = 0 -PAPER_B6_JIS_ROTATED = 0 -PAPER_B_PLUS = 0 -PAPER_CSHEET = 0 -PAPER_DBL_JAPANESE_POSTCARD = 0 -PAPER_DBL_JAPANESE_POSTCARD_ROTATED = 0 -PAPER_DSHEET = 0 -PAPER_ENV_10 = 0 -PAPER_ENV_11 = 0 -PAPER_ENV_12 = 0 -PAPER_ENV_14 = 0 -PAPER_ENV_9 = 0 -PAPER_ENV_B4 = 0 -PAPER_ENV_B5 = 0 -PAPER_ENV_B6 = 0 -PAPER_ENV_C3 = 0 -PAPER_ENV_C4 = 0 -PAPER_ENV_C5 = 0 -PAPER_ENV_C6 = 0 -PAPER_ENV_C65 = 0 -PAPER_ENV_DL = 0 -PAPER_ENV_INVITE = 0 -PAPER_ENV_ITALY = 0 -PAPER_ENV_MONARCH = 0 -PAPER_ENV_PERSONAL = 0 -PAPER_ESHEET = 0 -PAPER_EXECUTIVE = 0 -PAPER_FANFOLD_LGL_GERMAN = 0 -PAPER_FANFOLD_STD_GERMAN = 0 -PAPER_FANFOLD_US = 0 -PAPER_FOLIO = 0 -PAPER_ISO_B4 = 0 -PAPER_JAPANESE_POSTCARD = 0 -PAPER_JAPANESE_POSTCARD_ROTATED = 0 -PAPER_JENV_CHOU3 = 0 -PAPER_JENV_CHOU3_ROTATED = 0 -PAPER_JENV_CHOU4 = 0 -PAPER_JENV_CHOU4_ROTATED = 0 -PAPER_JENV_KAKU2 = 0 -PAPER_JENV_KAKU2_ROTATED = 0 -PAPER_JENV_KAKU3 = 0 -PAPER_JENV_KAKU3_ROTATED = 0 -PAPER_JENV_YOU4 = 0 -PAPER_JENV_YOU4_ROTATED = 0 -PAPER_LEDGER = 0 -PAPER_LEGAL = 0 -PAPER_LEGAL_EXTRA = 0 -PAPER_LETTER = 0 -PAPER_LETTERSMALL = 0 -PAPER_LETTER_EXTRA = 0 -PAPER_LETTER_EXTRA_TRANSVERSE = 0 -PAPER_LETTER_PLUS = 0 -PAPER_LETTER_ROTATED = 0 -PAPER_LETTER_TRANSVERSE = 0 -PAPER_NONE = 0 -PAPER_NOTE = 0 -PAPER_P16K = 0 -PAPER_P16K_ROTATED = 0 -PAPER_P32K = 0 -PAPER_P32KBIG = 0 -PAPER_P32KBIG_ROTATED = 0 -PAPER_P32K_ROTATED = 0 -PAPER_PENV_1 = 0 -PAPER_PENV_10 = 0 -PAPER_PENV_10_ROTATED = 0 -PAPER_PENV_1_ROTATED = 0 -PAPER_PENV_2 = 0 -PAPER_PENV_2_ROTATED = 0 -PAPER_PENV_3 = 0 -PAPER_PENV_3_ROTATED = 0 -PAPER_PENV_4 = 0 -PAPER_PENV_4_ROTATED = 0 -PAPER_PENV_5 = 0 -PAPER_PENV_5_ROTATED = 0 -PAPER_PENV_6 = 0 -PAPER_PENV_6_ROTATED = 0 -PAPER_PENV_7 = 0 -PAPER_PENV_7_ROTATED = 0 -PAPER_PENV_8 = 0 -PAPER_PENV_8_ROTATED = 0 -PAPER_PENV_9 = 0 -PAPER_PENV_9_ROTATED = 0 -PAPER_QUARTO = 0 -PAPER_STATEMENT = 0 -PAPER_TABLOID = 0 -PAPER_TABLOID_EXTRA = 0 -PORTRAIT = 0 -LANDSCAPE = 0 -DUPLEX_SIMPLEX = 0 -DUPLEX_HORIZONTAL = 0 -DUPLEX_VERTICAL = 0 -PRINT_MODE_NONE = 0 -PRINT_MODE_PREVIEW = 0 -PRINT_MODE_FILE = 0 -PRINT_MODE_PRINTER = 0 -PRINT_MODE_STREAM = 0 -UPDATE_UI_NONE = 0 -UPDATE_UI_RECURSE = 0 -UPDATE_UI_FROMIDLE = 0 -DefaultCoord = 0 -TextFileType_None = 0 -TextFileType_Unix = 0 -TextFileType_Dos = 0 -TextFileType_Mac = 0 -TextFileType_Os2 = 0 +INT8_MIN = -128 +INT8_MAX = 127 +UINT8_MAX = 255 +INT16_MIN = -32768 +INT16_MAX = 32767 +UINT16_MAX = 65535 +INT32_MIN = -2147483648 +INT32_MAX = 2147483647 +UINT32_MAX = 4294967295 +INT64_MIN = -9223372036854775808 +INT64_MAX = 9223372036854775807 +UINT64_MAX = 18446744073709551615 +SIZE_AUTO_WIDTH: int +SIZE_AUTO_HEIGHT: int +SIZE_AUTO: int +SIZE_USE_EXISTING: int +SIZE_ALLOW_MINUS_ONE: int +SIZE_NO_ADJUSTMENTS: int +SIZE_FORCE: int +SIZE_FORCE_EVENT: int +VSCROLL: int +HSCROLL: int +CAPTION: int +DOUBLE_BORDER: int +SUNKEN_BORDER: int +RAISED_BORDER: int +BORDER: int +SIMPLE_BORDER: int +STATIC_BORDER: int +NO_BORDER: int +ALWAYS_SHOW_SB: int +CLIP_CHILDREN: int +CLIP_SIBLINGS: int +TRANSPARENT_WINDOW: int +TAB_TRAVERSAL: int +WANTS_CHARS: int +RETAINED: int +BACKINGSTORE: int +POPUP_WINDOW: int +FULL_REPAINT_ON_RESIZE: int +NO_FULL_REPAINT_ON_RESIZE: int +WINDOW_STYLE_MASK: int +WS_EX_BLOCK_EVENTS: int +WS_EX_TRANSIENT: int +WS_EX_THEMED_BACKGROUND: int +WS_EX_PROCESS_IDLE: int +WS_EX_PROCESS_UI_UPDATES: int +FRAME_EX_METAL: int +DIALOG_EX_METAL: int +WS_EX_CONTEXTHELP: int +FRAME_EX_CONTEXTHELP: int +DIALOG_EX_CONTEXTHELP: int +FRAME_DRAWER: int +FRAME_NO_WINDOW_MENU: int +MB_DOCKABLE: int +MENU_TEAROFF: int +COLOURED: int +FIXED_LENGTH: int +LB_SORT: int +LB_SINGLE: int +LB_MULTIPLE: int +LB_EXTENDED: int +LB_NEEDED_SB: int +LB_OWNERDRAW: int +LB_ALWAYS_SB: int +LB_NO_SB: int +LB_HSCROLL: int +LB_INT_HEIGHT: int +CB_SIMPLE: int +CB_SORT: int +CB_READONLY: int +CB_DROPDOWN: int +RA_LEFTTORIGHT: int +RA_TOPTOBOTTOM: int +RA_SPECIFY_COLS: int +RA_SPECIFY_ROWS: int +RA_HORIZONTAL: int +RA_VERTICAL: int +RB_GROUP: int +RB_SINGLE: int +SB_HORIZONTAL: int +SB_VERTICAL: int +SP_HORIZONTAL: int +SP_VERTICAL: int +SP_ARROW_KEYS: int +SP_WRAP: int +TC_RIGHTJUSTIFY: int +TC_FIXEDWIDTH: int +TC_TOP: int +TC_LEFT: int +TC_RIGHT: int +TC_BOTTOM: int +TC_MULTILINE: int +TC_OWNERDRAW: int +BI_EXPAND: int +LI_HORIZONTAL: int +LI_VERTICAL: int +YES: int +OK: int +NO: int +YES_NO: int +CANCEL: int +APPLY: int +CLOSE: int +OK_DEFAULT: int +YES_DEFAULT: int +NO_DEFAULT: int +CANCEL_DEFAULT: int +ICON_EXCLAMATION: int +ICON_HAND: int +ICON_WARNING: int +ICON_ERROR: int +ICON_QUESTION: int +ICON_INFORMATION: int +ICON_STOP: int +ICON_ASTERISK: int +HELP: int +FORWARD: int +BACKWARD: int +RESET: int +MORE: int +SETUP: int +ICON_NONE: int +ICON_AUTH_NEEDED: int +ICON_MASK: int +NOT_FOUND: int +PRINT_QUALITY_HIGH: int +PRINT_QUALITY_MEDIUM: int +PRINT_QUALITY_LOW: int +PRINT_QUALITY_DRAFT: int +STAY_ON_TOP: int +ICONIZE: int +MINIMIZE: int +MAXIMIZE: int +CLOSE_BOX: int +SYSTEM_MENU: int +MINIMIZE_BOX: int +MAXIMIZE_BOX: int +TINY_CAPTION: int +RESIZE_BORDER: int +CENTRE: int +CENTER: int +HORIZONTAL: int +VERTICAL: int +BOTH: int +ORIENTATION_MASK: int +LEFT: int +RIGHT: int +UP: int +DOWN: int +TOP: int +BOTTOM: int +NORTH: int +SOUTH: int +WEST: int +EAST: int +ALL: int +DIRECTION_MASK: int +ALIGN_INVALID: int +ALIGN_NOT: int +ALIGN_CENTER_HORIZONTAL: int +ALIGN_CENTRE_HORIZONTAL: int +ALIGN_LEFT: int +ALIGN_TOP: int +ALIGN_RIGHT: int +ALIGN_BOTTOM: int +ALIGN_CENTER_VERTICAL: int +ALIGN_CENTRE_VERTICAL: int +ALIGN_CENTER: int +ALIGN_CENTRE: int +ALIGN_MASK: int +FIXED_MINSIZE: int +RESERVE_SPACE_EVEN_IF_HIDDEN: int +SIZER_FLAG_BITS_MASK: int +STRETCH_NOT: int +SHRINK: int +GROW: int +EXPAND: int +SHAPED: int +TILE: int +STRETCH_MASK: int +BORDER_DEFAULT: int +BORDER_NONE: int +BORDER_STATIC: int +BORDER_SIMPLE: int +BORDER_RAISED: int +BORDER_SUNKEN: int +BORDER_DOUBLE: int +BORDER_THEME: int +BORDER_MASK: int +BG_STYLE_ERASE: int +BG_STYLE_SYSTEM: int +BG_STYLE_PAINT: int +BG_STYLE_COLOUR: int +BG_STYLE_TRANSPARENT: int +ID_AUTO_LOWEST: int +ID_AUTO_HIGHEST: int +ID_NONE: int +ID_SEPARATOR: int +ID_ANY: int +ID_LOWEST: int +ID_OPEN: int +ID_CLOSE: int +ID_NEW: int +ID_SAVE: int +ID_SAVEAS: int +ID_REVERT: int +ID_EXIT: int +ID_UNDO: int +ID_REDO: int +ID_HELP: int +ID_PRINT: int +ID_PRINT_SETUP: int +ID_PAGE_SETUP: int +ID_PREVIEW: int +ID_ABOUT: int +ID_HELP_CONTENTS: int +ID_HELP_INDEX: int +ID_HELP_SEARCH: int +ID_HELP_COMMANDS: int +ID_HELP_PROCEDURES: int +ID_HELP_CONTEXT: int +ID_CLOSE_ALL: int +ID_PREFERENCES: int +ID_EDIT: int +ID_CUT: int +ID_COPY: int +ID_PASTE: int +ID_CLEAR: int +ID_FIND: int +ID_DUPLICATE: int +ID_SELECTALL: int +ID_DELETE: int +ID_REPLACE: int +ID_REPLACE_ALL: int +ID_PROPERTIES: int +ID_VIEW_DETAILS: int +ID_VIEW_LARGEICONS: int +ID_VIEW_SMALLICONS: int +ID_VIEW_LIST: int +ID_VIEW_SORTDATE: int +ID_VIEW_SORTNAME: int +ID_VIEW_SORTSIZE: int +ID_VIEW_SORTTYPE: int +ID_FILE: int +ID_FILE1: int +ID_FILE2: int +ID_FILE3: int +ID_FILE4: int +ID_FILE5: int +ID_FILE6: int +ID_FILE7: int +ID_FILE8: int +ID_FILE9: int +ID_OK: int +ID_CANCEL: int +ID_APPLY: int +ID_YES: int +ID_NO: int +ID_STATIC: int +ID_FORWARD: int +ID_BACKWARD: int +ID_DEFAULT: int +ID_MORE: int +ID_SETUP: int +ID_RESET: int +ID_CONTEXT_HELP: int +ID_YESTOALL: int +ID_NOTOALL: int +ID_ABORT: int +ID_RETRY: int +ID_IGNORE: int +ID_ADD: int +ID_REMOVE: int +ID_UP: int +ID_DOWN: int +ID_HOME: int +ID_REFRESH: int +ID_STOP: int +ID_INDEX: int +ID_BOLD: int +ID_ITALIC: int +ID_JUSTIFY_CENTER: int +ID_JUSTIFY_FILL: int +ID_JUSTIFY_RIGHT: int +ID_JUSTIFY_LEFT: int +ID_UNDERLINE: int +ID_INDENT: int +ID_UNINDENT: int +ID_ZOOM_100: int +ID_ZOOM_FIT: int +ID_ZOOM_IN: int +ID_ZOOM_OUT: int +ID_UNDELETE: int +ID_REVERT_TO_SAVED: int +ID_CDROM: int +ID_CONVERT: int +ID_EXECUTE: int +ID_FLOPPY: int +ID_HARDDISK: int +ID_BOTTOM: int +ID_FIRST: int +ID_LAST: int +ID_TOP: int +ID_INFO: int +ID_JUMP_TO: int +ID_NETWORK: int +ID_SELECT_COLOR: int +ID_SELECT_FONT: int +ID_SORT_ASCENDING: int +ID_SORT_DESCENDING: int +ID_SPELL_CHECK: int +ID_STRIKETHROUGH: int +ID_SYSTEM_MENU: int +ID_CLOSE_FRAME: int +ID_MOVE_FRAME: int +ID_RESIZE_FRAME: int +ID_MAXIMIZE_FRAME: int +ID_ICONIZE_FRAME: int +ID_RESTORE_FRAME: int +ID_MDI_WINDOW_FIRST: int +ID_MDI_WINDOW_CASCADE: int +ID_MDI_WINDOW_TILE_HORZ: int +ID_MDI_WINDOW_TILE_VERT: int +ID_MDI_WINDOW_ARRANGE_ICONS: int +ID_MDI_WINDOW_PREV: int +ID_MDI_WINDOW_NEXT: int +ID_MDI_WINDOW_LAST: int +ID_FILEDLGG: int +ID_FILECTRL: int +ID_HIGHEST: int +ITEM_SEPARATOR: int +ITEM_NORMAL: int +ITEM_CHECK: int +ITEM_RADIO: int +ITEM_DROPDOWN: int +ITEM_MAX: int +HT_NOWHERE: int +HT_SCROLLBAR_FIRST: int +HT_SCROLLBAR_ARROW_LINE_1: int +HT_SCROLLBAR_ARROW_LINE_2: int +HT_SCROLLBAR_ARROW_PAGE_1: int +HT_SCROLLBAR_ARROW_PAGE_2: int +HT_SCROLLBAR_THUMB: int +HT_SCROLLBAR_BAR_1: int +HT_SCROLLBAR_BAR_2: int +HT_SCROLLBAR_LAST: int +HT_WINDOW_OUTSIDE: int +HT_WINDOW_INSIDE: int +HT_WINDOW_VERT_SCROLLBAR: int +HT_WINDOW_HORZ_SCROLLBAR: int +HT_WINDOW_CORNER: int +HT_MAX: int +DF_INVALID: int +DF_TEXT: int +DF_BITMAP: int +DF_METAFILE: int +DF_SYLK: int +DF_DIF: int +DF_TIFF: int +DF_OEMTEXT: int +DF_DIB: int +DF_PALETTE: int +DF_PENDATA: int +DF_RIFF: int +DF_WAVE: int +DF_UNICODETEXT: int +DF_ENHMETAFILE: int +DF_FILENAME: int +DF_LOCALE: int +DF_PRIVATE: int +DF_HTML: int +DF_PNG: int +DF_MAX: int +WXK_NONE: int +WXK_CONTROL_A: int +WXK_CONTROL_B: int +WXK_CONTROL_C: int +WXK_CONTROL_D: int +WXK_CONTROL_E: int +WXK_CONTROL_F: int +WXK_CONTROL_G: int +WXK_CONTROL_H: int +WXK_CONTROL_I: int +WXK_CONTROL_J: int +WXK_CONTROL_K: int +WXK_CONTROL_L: int +WXK_CONTROL_M: int +WXK_CONTROL_N: int +WXK_CONTROL_O: int +WXK_CONTROL_P: int +WXK_CONTROL_Q: int +WXK_CONTROL_R: int +WXK_CONTROL_S: int +WXK_CONTROL_T: int +WXK_CONTROL_U: int +WXK_CONTROL_V: int +WXK_CONTROL_W: int +WXK_CONTROL_X: int +WXK_CONTROL_Y: int +WXK_CONTROL_Z: int +WXK_BACK: int +WXK_TAB: int +WXK_RETURN: int +WXK_ESCAPE: int +WXK_SPACE: int +WXK_DELETE: int +WXK_START: int +WXK_LBUTTON: int +WXK_RBUTTON: int +WXK_CANCEL: int +WXK_MBUTTON: int +WXK_CLEAR: int +WXK_SHIFT: int +WXK_ALT: int +WXK_CONTROL: int +WXK_RAW_CONTROL: int +WXK_MENU: int +WXK_PAUSE: int +WXK_CAPITAL: int +WXK_END: int +WXK_HOME: int +WXK_LEFT: int +WXK_UP: int +WXK_RIGHT: int +WXK_DOWN: int +WXK_SELECT: int +WXK_PRINT: int +WXK_EXECUTE: int +WXK_SNAPSHOT: int +WXK_INSERT: int +WXK_HELP: int +WXK_NUMPAD0: int +WXK_NUMPAD1: int +WXK_NUMPAD2: int +WXK_NUMPAD3: int +WXK_NUMPAD4: int +WXK_NUMPAD5: int +WXK_NUMPAD6: int +WXK_NUMPAD7: int +WXK_NUMPAD8: int +WXK_NUMPAD9: int +WXK_MULTIPLY: int +WXK_ADD: int +WXK_SEPARATOR: int +WXK_SUBTRACT: int +WXK_DECIMAL: int +WXK_DIVIDE: int +WXK_F1: int +WXK_F2: int +WXK_F3: int +WXK_F4: int +WXK_F5: int +WXK_F6: int +WXK_F7: int +WXK_F8: int +WXK_F9: int +WXK_F10: int +WXK_F11: int +WXK_F12: int +WXK_F13: int +WXK_F14: int +WXK_F15: int +WXK_F16: int +WXK_F17: int +WXK_F18: int +WXK_F19: int +WXK_F20: int +WXK_F21: int +WXK_F22: int +WXK_F23: int +WXK_F24: int +WXK_NUMLOCK: int +WXK_SCROLL: int +WXK_PAGEUP: int +WXK_PAGEDOWN: int +WXK_NUMPAD_SPACE: int +WXK_NUMPAD_TAB: int +WXK_NUMPAD_ENTER: int +WXK_NUMPAD_F1: int +WXK_NUMPAD_F2: int +WXK_NUMPAD_F3: int +WXK_NUMPAD_F4: int +WXK_NUMPAD_HOME: int +WXK_NUMPAD_LEFT: int +WXK_NUMPAD_UP: int +WXK_NUMPAD_RIGHT: int +WXK_NUMPAD_DOWN: int +WXK_NUMPAD_PAGEUP: int +WXK_NUMPAD_PAGEDOWN: int +WXK_NUMPAD_END: int +WXK_NUMPAD_BEGIN: int +WXK_NUMPAD_INSERT: int +WXK_NUMPAD_DELETE: int +WXK_NUMPAD_EQUAL: int +WXK_NUMPAD_MULTIPLY: int +WXK_NUMPAD_ADD: int +WXK_NUMPAD_SEPARATOR: int +WXK_NUMPAD_SUBTRACT: int +WXK_NUMPAD_DECIMAL: int +WXK_NUMPAD_DIVIDE: int +WXK_WINDOWS_LEFT: int +WXK_WINDOWS_RIGHT: int +WXK_WINDOWS_MENU: int +WXK_COMMAND: int +WXK_SPECIAL1: int +WXK_SPECIAL2: int +WXK_SPECIAL3: int +WXK_SPECIAL4: int +WXK_SPECIAL5: int +WXK_SPECIAL6: int +WXK_SPECIAL7: int +WXK_SPECIAL8: int +WXK_SPECIAL9: int +WXK_SPECIAL10: int +WXK_SPECIAL11: int +WXK_SPECIAL12: int +WXK_SPECIAL13: int +WXK_SPECIAL14: int +WXK_SPECIAL15: int +WXK_SPECIAL16: int +WXK_SPECIAL17: int +WXK_SPECIAL18: int +WXK_SPECIAL19: int +WXK_SPECIAL20: int +WXK_BROWSER_BACK: int +WXK_BROWSER_FORWARD: int +WXK_BROWSER_REFRESH: int +WXK_BROWSER_STOP: int +WXK_BROWSER_SEARCH: int +WXK_BROWSER_FAVORITES: int +WXK_BROWSER_HOME: int +WXK_VOLUME_MUTE: int +WXK_VOLUME_DOWN: int +WXK_VOLUME_UP: int +WXK_MEDIA_NEXT_TRACK: int +WXK_MEDIA_PREV_TRACK: int +WXK_MEDIA_STOP: int +WXK_MEDIA_PLAY_PAUSE: int +WXK_LAUNCH_MAIL: int +WXK_LAUNCH_APP1: int +WXK_LAUNCH_APP2: int +WXK_LAUNCH_0: int +WXK_LAUNCH_1: int +WXK_LAUNCH_2: int +WXK_LAUNCH_3: int +WXK_LAUNCH_4: int +WXK_LAUNCH_5: int +WXK_LAUNCH_6: int +WXK_LAUNCH_7: int +WXK_LAUNCH_8: int +WXK_LAUNCH_9: int +WXK_LAUNCH_A: int +WXK_LAUNCH_B: int +WXK_LAUNCH_C: int +WXK_LAUNCH_D: int +WXK_LAUNCH_E: int +WXK_LAUNCH_F: int +MOD_NONE: int +MOD_ALT: int +MOD_CONTROL: int +MOD_ALTGR: int +MOD_SHIFT: int +MOD_META: int +MOD_WIN: int +MOD_RAW_CONTROL: int +MOD_CMD: int +MOD_ALL: int +PAPER_10X11: int +PAPER_10X14: int +PAPER_11X17: int +PAPER_12X11: int +PAPER_15X11: int +PAPER_9X11: int +PAPER_A2: int +PAPER_A3: int +PAPER_A3_EXTRA: int +PAPER_A3_EXTRA_TRANSVERSE: int +PAPER_A3_ROTATED: int +PAPER_A3_TRANSVERSE: int +PAPER_A4: int +PAPER_A4SMALL: int +PAPER_A4_EXTRA: int +PAPER_A4_PLUS: int +PAPER_A4_ROTATED: int +PAPER_A4_TRANSVERSE: int +PAPER_A5: int +PAPER_A5_EXTRA: int +PAPER_A5_ROTATED: int +PAPER_A5_TRANSVERSE: int +PAPER_A6: int +PAPER_A6_ROTATED: int +PAPER_A_PLUS: int +PAPER_B4: int +PAPER_B4_JIS_ROTATED: int +PAPER_B5: int +PAPER_B5_EXTRA: int +PAPER_B5_JIS_ROTATED: int +PAPER_B5_TRANSVERSE: int +PAPER_B6_JIS: int +PAPER_B6_JIS_ROTATED: int +PAPER_B_PLUS: int +PAPER_CSHEET: int +PAPER_DBL_JAPANESE_POSTCARD: int +PAPER_DBL_JAPANESE_POSTCARD_ROTATED: int +PAPER_DSHEET: int +PAPER_ENV_10: int +PAPER_ENV_11: int +PAPER_ENV_12: int +PAPER_ENV_14: int +PAPER_ENV_9: int +PAPER_ENV_B4: int +PAPER_ENV_B5: int +PAPER_ENV_B6: int +PAPER_ENV_C3: int +PAPER_ENV_C4: int +PAPER_ENV_C5: int +PAPER_ENV_C6: int +PAPER_ENV_C65: int +PAPER_ENV_DL: int +PAPER_ENV_INVITE: int +PAPER_ENV_ITALY: int +PAPER_ENV_MONARCH: int +PAPER_ENV_PERSONAL: int +PAPER_ESHEET: int +PAPER_EXECUTIVE: int +PAPER_FANFOLD_LGL_GERMAN: int +PAPER_FANFOLD_STD_GERMAN: int +PAPER_FANFOLD_US: int +PAPER_FOLIO: int +PAPER_ISO_B4: int +PAPER_JAPANESE_POSTCARD: int +PAPER_JAPANESE_POSTCARD_ROTATED: int +PAPER_JENV_CHOU3: int +PAPER_JENV_CHOU3_ROTATED: int +PAPER_JENV_CHOU4: int +PAPER_JENV_CHOU4_ROTATED: int +PAPER_JENV_KAKU2: int +PAPER_JENV_KAKU2_ROTATED: int +PAPER_JENV_KAKU3: int +PAPER_JENV_KAKU3_ROTATED: int +PAPER_JENV_YOU4: int +PAPER_JENV_YOU4_ROTATED: int +PAPER_LEDGER: int +PAPER_LEGAL: int +PAPER_LEGAL_EXTRA: int +PAPER_LETTER: int +PAPER_LETTERSMALL: int +PAPER_LETTER_EXTRA: int +PAPER_LETTER_EXTRA_TRANSVERSE: int +PAPER_LETTER_PLUS: int +PAPER_LETTER_ROTATED: int +PAPER_LETTER_TRANSVERSE: int +PAPER_NONE: int +PAPER_NOTE: int +PAPER_P16K: int +PAPER_P16K_ROTATED: int +PAPER_P32K: int +PAPER_P32KBIG: int +PAPER_P32KBIG_ROTATED: int +PAPER_P32K_ROTATED: int +PAPER_PENV_1: int +PAPER_PENV_10: int +PAPER_PENV_10_ROTATED: int +PAPER_PENV_1_ROTATED: int +PAPER_PENV_2: int +PAPER_PENV_2_ROTATED: int +PAPER_PENV_3: int +PAPER_PENV_3_ROTATED: int +PAPER_PENV_4: int +PAPER_PENV_4_ROTATED: int +PAPER_PENV_5: int +PAPER_PENV_5_ROTATED: int +PAPER_PENV_6: int +PAPER_PENV_6_ROTATED: int +PAPER_PENV_7: int +PAPER_PENV_7_ROTATED: int +PAPER_PENV_8: int +PAPER_PENV_8_ROTATED: int +PAPER_PENV_9: int +PAPER_PENV_9_ROTATED: int +PAPER_QUARTO: int +PAPER_STATEMENT: int +PAPER_TABLOID: int +PAPER_TABLOID_EXTRA: int +PORTRAIT: int +LANDSCAPE: int +DUPLEX_SIMPLEX: int +DUPLEX_HORIZONTAL: int +DUPLEX_VERTICAL: int +PRINT_MODE_NONE: int +PRINT_MODE_PREVIEW: int +PRINT_MODE_FILE: int +PRINT_MODE_PRINTER: int +PRINT_MODE_STREAM: int +UPDATE_UI_NONE: int +UPDATE_UI_RECURSE: int +UPDATE_UI_FROMIDLE: int +DefaultCoord: int +TextFileType_None: int +TextFileType_Unix: int +TextFileType_Dos: int +TextFileType_Mac: int +TextFileType_Os2: int BG_STYLE_CUSTOM = BG_STYLE_PAINT -ADJUST_MINSIZE = 0 +ADJUST_MINSIZE: int -WS_EX_VALIDATE_RECURSIVELY = 0 +WS_EX_VALIDATE_RECURSIVELY: int # -- end-defs --# # -- begin-debug --# -def Abort(): +def Abort() -> NoReturn: """ Abort() @@ -1323,8 +1340,8 @@ class SharedClientDataContainer: # -- end-clntdatactnr --# # -- begin-wxdatetime --# -DefaultTimeSpanFormat = "" -DefaultDateTimeFormat = "" +DefaultTimeSpanFormat: bytes +DefaultDateTimeFormat: bytes class DateTime: """ @@ -1406,100 +1423,100 @@ class DateTime: # end of class Tm - Local = 0 - GMT_12 = 0 - GMT_11 = 0 - GMT_10 = 0 - GMT_9 = 0 - GMT_8 = 0 - GMT_7 = 0 - GMT_6 = 0 - GMT_5 = 0 - GMT_4 = 0 - GMT_3 = 0 - GMT_2 = 0 - GMT_1 = 0 - GMT0 = 0 - GMT1 = 0 - GMT2 = 0 - GMT3 = 0 - GMT4 = 0 - GMT5 = 0 - GMT6 = 0 - GMT7 = 0 - GMT8 = 0 - GMT9 = 0 - GMT10 = 0 - GMT11 = 0 - GMT12 = 0 - GMT13 = 0 - WET = 0 - WEST = 0 - CET = 0 - CEST = 0 - EET = 0 - EEST = 0 - MSK = 0 - MSD = 0 - AST = 0 - ADT = 0 - EST = 0 - EDT = 0 - CST = 0 - CDT = 0 - MST = 0 - MDT = 0 - PST = 0 - PDT = 0 - HST = 0 - AKST = 0 - AKDT = 0 - A_WST = 0 - A_CST = 0 - A_EST = 0 - A_ESST = 0 - NZST = 0 - NZDT = 0 - UTC = 0 - Gregorian = 0 - Julian = 0 - Country_Unknown = 0 - Country_Default = 0 - Country_WesternEurope_Start = 0 - Country_EEC = 0 - France = 0 - Germany = 0 - UK = 0 - Country_WesternEurope_End = 0 - Russia = 0 - USA = 0 - Jan = 0 - Feb = 0 - Mar = 0 - Apr = 0 - May = 0 - Jun = 0 - Jul = 0 - Aug = 0 - Sep = 0 - Oct = 0 - Nov = 0 - Dec = 0 - Inv_Month = 0 - Sun = 0 - Mon = 0 - Tue = 0 - Wed = 0 - Thu = 0 - Fri = 0 - Sat = 0 - Inv_WeekDay = 0 - Inv_Year = 0 - Name_Full = 0 - Name_Abbr = 0 - Default_First = 0 - Monday_First = 0 - Sunday_First = 0 + Local: int + GMT_12: int + GMT_11: int + GMT_10: int + GMT_9: int + GMT_8: int + GMT_7: int + GMT_6: int + GMT_5: int + GMT_4: int + GMT_3: int + GMT_2: int + GMT_1: int + GMT0: int + GMT1: int + GMT2: int + GMT3: int + GMT4: int + GMT5: int + GMT6: int + GMT7: int + GMT8: int + GMT9: int + GMT10: int + GMT11: int + GMT12: int + GMT13: int + WET: int + WEST: int + CET: int + CEST: int + EET: int + EEST: int + MSK: int + MSD: int + AST: int + ADT: int + EST: int + EDT: int + CST: int + CDT: int + MST: int + MDT: int + PST: int + PDT: int + HST: int + AKST: int + AKDT: int + A_WST: int + A_CST: int + A_EST: int + A_ESST: int + NZST: int + NZDT: int + UTC: int + Gregorian: int + Julian: int + Country_Unknown: int + Country_Default: int + Country_WesternEurope_Start: int + Country_EEC: int + France: int + Germany: int + UK: int + Country_WesternEurope_End: int + Russia: int + USA: int + Jan: int + Feb: int + Mar: int + Apr: int + May: int + Jun: int + Jul: int + Aug: int + Sep: int + Oct: int + Nov: int + Dec: int + Inv_Month: int + Sun: int + Mon: int + Tue: int + Wed: int + Thu: int + Fri: int + Sat: int + Inv_WeekDay: int + Inv_Year: int + Name_Full: int + Name_Abbr: int + Default_First: int + Monday_First: int + Sunday_First: int def __init__(self, *args, **kw): """ @@ -3097,43 +3114,43 @@ def NewIdRef(count: int) -> list[WindowIDRef]: ... # -- end-windowid --# # -- begin-platinfo --# -OS_UNKNOWN = 0 -OS_MAC_OS = 0 -OS_MAC_OSX_DARWIN = 0 -OS_MAC = 0 -OS_WINDOWS_NT = 0 -OS_WINDOWS = 0 -OS_UNIX_LINUX = 0 -OS_UNIX_FREEBSD = 0 -OS_UNIX_OPENBSD = 0 -OS_UNIX_NETBSD = 0 -OS_UNIX_SOLARIS = 0 -OS_UNIX_AIX = 0 -OS_UNIX_HPUX = 0 -OS_UNIX = 0 -PORT_UNKNOWN = 0 -PORT_BASE = 0 -PORT_MSW = 0 -PORT_MOTIF = 0 -PORT_GTK = 0 -PORT_DFB = 0 -PORT_X11 = 0 -PORT_MAC = 0 -PORT_COCOA = 0 -PORT_QT = 0 -BITNESS_INVALID = 0 -BITNESS_32 = 0 -BITNESS_64 = 0 -BITNESS_MAX = 0 -ARCH_INVALID = 0 -ARCH_32 = 0 -ARCH_64 = 0 -ARCH_MAX = 0 -ENDIAN_INVALID = 0 -ENDIAN_BIG = 0 -ENDIAN_LITTLE = 0 -ENDIAN_PDP = 0 -ENDIAN_MAX = 0 +OS_UNKNOWN: int +OS_MAC_OS: int +OS_MAC_OSX_DARWIN: int +OS_MAC: int +OS_WINDOWS_NT: int +OS_WINDOWS: int +OS_UNIX_LINUX: int +OS_UNIX_FREEBSD: int +OS_UNIX_OPENBSD: int +OS_UNIX_NETBSD: int +OS_UNIX_SOLARIS: int +OS_UNIX_AIX: int +OS_UNIX_HPUX: int +OS_UNIX: int +PORT_UNKNOWN: int +PORT_BASE: int +PORT_MSW: int +PORT_MOTIF: int +PORT_GTK: int +PORT_DFB: int +PORT_X11: int +PORT_MAC: int +PORT_COCOA: int +PORT_QT: int +BITNESS_INVALID: int +BITNESS_32: int +BITNESS_64: int +BITNESS_MAX: int +ARCH_INVALID: int +ARCH_32: int +ARCH_64: int +ARCH_MAX: int +ENDIAN_INVALID: int +ENDIAN_BIG: int +ENDIAN_LITTLE: int +ENDIAN_PDP: int +ENDIAN_MAX: int class PlatformInformation: """ @@ -3736,928 +3753,928 @@ class Display: # -- end-display --# # -- begin-intl --# -LANGUAGE_DEFAULT = 0 -LANGUAGE_UNKNOWN = 0 -LANGUAGE_ABKHAZIAN = 0 -LANGUAGE_AFAR = 0 -LANGUAGE_AFAR_DJIBOUTI = 0 -LANGUAGE_AFAR_ERITREA = 0 -LANGUAGE_AFAR_ETHIOPIA = 0 -LANGUAGE_AFRIKAANS = 0 -LANGUAGE_AFRIKAANS_NAMIBIA = 0 -LANGUAGE_AFRIKAANS_SOUTH_AFRICA = 0 -LANGUAGE_AGHEM = 0 -LANGUAGE_AGHEM_CAMEROON = 0 -LANGUAGE_AKAN = 0 -LANGUAGE_AKAN_GHANA = 0 -LANGUAGE_ALBANIAN = 0 -LANGUAGE_ALBANIAN_ALBANIA = 0 -LANGUAGE_ALBANIAN_KOSOVO = 0 -LANGUAGE_ALBANIAN_NORTH_MACEDONIA = 0 -LANGUAGE_ALSATIAN_FRANCE = 0 -LANGUAGE_AMHARIC = 0 -LANGUAGE_AMHARIC_ETHIOPIA = 0 -LANGUAGE_ARABIC = 0 -LANGUAGE_ARABIC_ALGERIA = 0 -LANGUAGE_ARABIC_BAHRAIN = 0 -LANGUAGE_ARABIC_CHAD = 0 -LANGUAGE_ARABIC_COMOROS = 0 -LANGUAGE_ARABIC_DJIBOUTI = 0 -LANGUAGE_ARABIC_EGYPT = 0 -LANGUAGE_ARABIC_ERITREA = 0 -LANGUAGE_ARABIC_IRAQ = 0 -LANGUAGE_ARABIC_ISRAEL = 0 -LANGUAGE_ARABIC_JORDAN = 0 -LANGUAGE_ARABIC_KUWAIT = 0 -LANGUAGE_ARABIC_LEBANON = 0 -LANGUAGE_ARABIC_LIBYA = 0 -LANGUAGE_ARABIC_MAURITANIA = 0 -LANGUAGE_ARABIC_MOROCCO = 0 -LANGUAGE_ARABIC_OMAN = 0 -LANGUAGE_ARABIC_PALESTINIAN_AUTHORITY = 0 -LANGUAGE_ARABIC_QATAR = 0 -LANGUAGE_ARABIC_SAUDI_ARABIA = 0 -LANGUAGE_ARABIC_SOMALIA = 0 -LANGUAGE_ARABIC_SOUTH_SUDAN = 0 -LANGUAGE_ARABIC_SUDAN = 0 -LANGUAGE_ARABIC_SYRIA = 0 -LANGUAGE_ARABIC_TUNISIA = 0 -LANGUAGE_ARABIC_UAE = 0 -LANGUAGE_ARABIC_WORLD = 0 -LANGUAGE_ARABIC_YEMEN = 0 -LANGUAGE_ARMENIAN = 0 -LANGUAGE_ARMENIAN_ARMENIA = 0 -LANGUAGE_ASSAMESE = 0 -LANGUAGE_ASSAMESE_INDIA = 0 -LANGUAGE_ASTURIAN = 0 -LANGUAGE_ASTURIAN_SPAIN = 0 -LANGUAGE_ASU = 0 -LANGUAGE_ASU_TANZANIA = 0 -LANGUAGE_AYMARA = 0 -LANGUAGE_AZERBAIJANI = 0 -LANGUAGE_AZERBAIJANI_CYRILLIC = 0 -LANGUAGE_AZERBAIJANI_CYRILLIC_AZERBAIJAN = 0 -LANGUAGE_AZERBAIJANI_LATIN = 0 -LANGUAGE_AZERBAIJANI_LATIN_AZERBAIJAN = 0 -LANGUAGE_BAFIA = 0 -LANGUAGE_BAFIA_CAMEROON = 0 -LANGUAGE_BAMANANKAN = 0 -LANGUAGE_BAMANANKAN_LATIN = 0 -LANGUAGE_BAMANANKAN_LATIN_MALI = 0 -LANGUAGE_BANGLA = 0 -LANGUAGE_BANGLA_BANGLADESH = 0 -LANGUAGE_BANGLA_INDIA = 0 -LANGUAGE_BASAA = 0 -LANGUAGE_BASAA_CAMEROON = 0 -LANGUAGE_BASHKIR = 0 -LANGUAGE_BASHKIR_RUSSIA = 0 -LANGUAGE_BASQUE = 0 -LANGUAGE_BASQUE_SPAIN = 0 -LANGUAGE_BELARUSIAN = 0 -LANGUAGE_BELARUSIAN_BELARUS = 0 -LANGUAGE_BEMBA = 0 -LANGUAGE_BEMBA_ZAMBIA = 0 -LANGUAGE_BENA = 0 -LANGUAGE_BENA_TANZANIA = 0 -LANGUAGE_BIHARI = 0 -LANGUAGE_BISLAMA = 0 -LANGUAGE_BLIN = 0 -LANGUAGE_BLIN_ERITREA = 0 -LANGUAGE_BODO = 0 -LANGUAGE_BODO_INDIA = 0 -LANGUAGE_BOSNIAN = 0 -LANGUAGE_BOSNIAN_CYRILLIC = 0 -LANGUAGE_BOSNIAN_CYRILLIC_BOSNIA_AND_HERZEGOVINA = 0 -LANGUAGE_BOSNIAN_LATIN = 0 -LANGUAGE_BOSNIAN_LATIN_BOSNIA_AND_HERZEGOVINA = 0 -LANGUAGE_BRETON = 0 -LANGUAGE_BRETON_FRANCE = 0 -LANGUAGE_BULGARIAN = 0 -LANGUAGE_BULGARIAN_BULGARIA = 0 -LANGUAGE_BURMESE = 0 -LANGUAGE_BURMESE_MYANMAR = 0 -LANGUAGE_CATALAN = 0 -LANGUAGE_CATALAN_ANDORRA = 0 -LANGUAGE_CATALAN_FRANCE = 0 -LANGUAGE_CATALAN_ITALY = 0 -LANGUAGE_CATALAN_SPAIN = 0 -LANGUAGE_CEBUANO = 0 -LANGUAGE_CEBUANO_LATIN = 0 -LANGUAGE_CEBUANO_LATIN_PHILIPPINES = 0 -LANGUAGE_CENTRAL_ATLAS_TAMAZIGHT = 0 -LANGUAGE_CENTRAL_ATLAS_TAMAZIGHT_ARABIC = 0 -LANGUAGE_CENTRAL_ATLAS_TAMAZIGHT_ARABIC_MOROCCO = 0 -LANGUAGE_CENTRAL_ATLAS_TAMAZIGHT_LATIN = 0 -LANGUAGE_CENTRAL_ATLAS_TAMAZIGHT_LATIN_ALGERIA = 0 -LANGUAGE_CENTRAL_ATLAS_TAMAZIGHT_LATIN_MOROCCO = 0 -LANGUAGE_CENTRAL_ATLAS_TAMAZIGHT_TIFINAGH = 0 -LANGUAGE_CENTRAL_ATLAS_TAMAZIGHT_TIFINAGH_MOROCCO = 0 -LANGUAGE_CENTRAL_KURDISH = 0 -LANGUAGE_CENTRAL_KURDISH_IRAQ = 0 -LANGUAGE_CHAKMA = 0 -LANGUAGE_CHAKMA_CHAKMA = 0 -LANGUAGE_CHAKMA_CHAKMA_BANGLADESH = 0 -LANGUAGE_CHAKMA_CHAKMA_INDIA = 0 -LANGUAGE_CHECHEN = 0 -LANGUAGE_CHECHEN_RUSSIA = 0 -LANGUAGE_CHEROKEE = 0 -LANGUAGE_CHEROKEE_CHEROKEE = 0 -LANGUAGE_CHEROKEE_US = 0 -LANGUAGE_CHIGA = 0 -LANGUAGE_CHIGA_UGANDA = 0 -LANGUAGE_CHINESE = 0 -LANGUAGE_CHINESE_CHINA = 0 -LANGUAGE_CHINESE_HONGKONG = 0 -LANGUAGE_CHINESE_MACAO = 0 -LANGUAGE_CHINESE_SIMPLIFIED_EXPLICIT = 0 -LANGUAGE_CHINESE_SIMPLIFIED_HONGKONG = 0 -LANGUAGE_CHINESE_SIMPLIFIED_MACAO = 0 -LANGUAGE_CHINESE_SINGAPORE = 0 -LANGUAGE_CHINESE_TAIWAN = 0 -LANGUAGE_CHINESE_TRADITIONAL_EXPLICIT = 0 -LANGUAGE_CHURCH_SLAVIC = 0 -LANGUAGE_CHURCH_SLAVIC_RUSSIA = 0 -LANGUAGE_COLOGNIAN = 0 -LANGUAGE_COLOGNIAN_GERMANY = 0 -LANGUAGE_CORNISH = 0 -LANGUAGE_CORNISH_UK = 0 -LANGUAGE_CORSICAN = 0 -LANGUAGE_CORSICAN_FRANCE = 0 -LANGUAGE_CROATIAN = 0 -LANGUAGE_CROATIAN_BOSNIA_AND_HERZEGOVINA = 0 -LANGUAGE_CROATIAN_CROATIA = 0 -LANGUAGE_CZECH = 0 -LANGUAGE_CZECH_CZECHIA = 0 -LANGUAGE_DANISH = 0 -LANGUAGE_DANISH_DENMARK = 0 -LANGUAGE_DANISH_GREENLAND = 0 -LANGUAGE_DARI = 0 -LANGUAGE_DARI_AFGHANISTAN = 0 -LANGUAGE_DIVEHI = 0 -LANGUAGE_DIVEHI_MALDIVES = 0 -LANGUAGE_DUALA = 0 -LANGUAGE_DUALA_CAMEROON = 0 -LANGUAGE_DUTCH = 0 -LANGUAGE_DUTCH_ARUBA = 0 -LANGUAGE_DUTCH_BELGIAN = 0 -LANGUAGE_DUTCH_BONAIRE_SINT_EUSTATIUS_AND_SABA = 0 -LANGUAGE_DUTCH_CURACAO = 0 -LANGUAGE_DUTCH_NETHERLANDS = 0 -LANGUAGE_DUTCH_SINT_MAARTEN = 0 -LANGUAGE_DUTCH_SURINAME = 0 -LANGUAGE_DZONGKHA = 0 -LANGUAGE_DZONGKHA_BHUTAN = 0 -LANGUAGE_EDO = 0 -LANGUAGE_EDO_NIGERIA = 0 -LANGUAGE_EMBU = 0 -LANGUAGE_EMBU_KENYA = 0 -LANGUAGE_ENGLISH = 0 -LANGUAGE_ENGLISH_AMERICAN_SAMOA = 0 -LANGUAGE_ENGLISH_ANGUILLA = 0 -LANGUAGE_ENGLISH_ANTIGUA_AND_BARBUDA = 0 -LANGUAGE_ENGLISH_AUSTRALIA = 0 -LANGUAGE_ENGLISH_AUSTRIA = 0 -LANGUAGE_ENGLISH_BAHAMAS = 0 -LANGUAGE_ENGLISH_BARBADOS = 0 -LANGUAGE_ENGLISH_BELGIUM = 0 -LANGUAGE_ENGLISH_BELIZE = 0 -LANGUAGE_ENGLISH_BERMUDA = 0 -LANGUAGE_ENGLISH_BOTSWANA = 0 -LANGUAGE_ENGLISH_BRITISH_INDIAN_OCEAN_TERRITORY = 0 -LANGUAGE_ENGLISH_BRITISH_VIRGIN_ISLANDS = 0 -LANGUAGE_ENGLISH_BURUNDI = 0 -LANGUAGE_ENGLISH_CAMEROON = 0 -LANGUAGE_ENGLISH_CANADA = 0 -LANGUAGE_ENGLISH_CARIBBEAN = 0 -LANGUAGE_ENGLISH_CARIBBEAN_CB = 0 -LANGUAGE_ENGLISH_CAYMAN_ISLANDS = 0 -LANGUAGE_ENGLISH_CHRISTMAS_ISLAND = 0 -LANGUAGE_ENGLISH_COCOS_KEELING_ISLANDS = 0 -LANGUAGE_ENGLISH_COOK_ISLANDS = 0 -LANGUAGE_ENGLISH_CYPRUS = 0 -LANGUAGE_ENGLISH_DENMARK = 0 -LANGUAGE_ENGLISH_DOMINICA = 0 -LANGUAGE_ENGLISH_EIRE = 0 -LANGUAGE_ENGLISH_ERITREA = 0 -LANGUAGE_ENGLISH_ESWATINI = 0 -LANGUAGE_ENGLISH_EUROPE = 0 -LANGUAGE_ENGLISH_FALKLAND_ISLANDS = 0 -LANGUAGE_ENGLISH_FIJI = 0 -LANGUAGE_ENGLISH_FINLAND = 0 -LANGUAGE_ENGLISH_GAMBIA = 0 -LANGUAGE_ENGLISH_GERMANY = 0 -LANGUAGE_ENGLISH_GHANA = 0 -LANGUAGE_ENGLISH_GIBRALTAR = 0 -LANGUAGE_ENGLISH_GRENADA = 0 -LANGUAGE_ENGLISH_GUAM = 0 -LANGUAGE_ENGLISH_GUERNSEY = 0 -LANGUAGE_ENGLISH_GUYANA = 0 -LANGUAGE_ENGLISH_HONG_KONG_SAR = 0 -LANGUAGE_ENGLISH_INDIA = 0 -LANGUAGE_ENGLISH_INDONESIA = 0 -LANGUAGE_ENGLISH_ISLE_OF_MAN = 0 -LANGUAGE_ENGLISH_ISRAEL = 0 -LANGUAGE_ENGLISH_JAMAICA = 0 -LANGUAGE_ENGLISH_JERSEY = 0 -LANGUAGE_ENGLISH_KENYA = 0 -LANGUAGE_ENGLISH_KIRIBATI = 0 -LANGUAGE_ENGLISH_LESOTHO = 0 -LANGUAGE_ENGLISH_LIBERIA = 0 -LANGUAGE_ENGLISH_MACAO_SAR = 0 -LANGUAGE_ENGLISH_MADAGASCAR = 0 -LANGUAGE_ENGLISH_MALAWI = 0 -LANGUAGE_ENGLISH_MALAYSIA = 0 -LANGUAGE_ENGLISH_MALTA = 0 -LANGUAGE_ENGLISH_MARSHALL_ISLANDS = 0 -LANGUAGE_ENGLISH_MAURITIUS = 0 -LANGUAGE_ENGLISH_MICRONESIA = 0 -LANGUAGE_ENGLISH_MONTSERRAT = 0 -LANGUAGE_ENGLISH_NAMIBIA = 0 -LANGUAGE_ENGLISH_NAURU = 0 -LANGUAGE_ENGLISH_NETHERLANDS = 0 -LANGUAGE_ENGLISH_NEW_ZEALAND = 0 -LANGUAGE_ENGLISH_NIGERIA = 0 -LANGUAGE_ENGLISH_NIUE = 0 -LANGUAGE_ENGLISH_NORFOLK_ISLAND = 0 -LANGUAGE_ENGLISH_NORTHERN_MARIANA_ISLANDS = 0 -LANGUAGE_ENGLISH_PAKISTAN = 0 -LANGUAGE_ENGLISH_PALAU = 0 -LANGUAGE_ENGLISH_PAPUA_NEW_GUINEA = 0 -LANGUAGE_ENGLISH_PHILIPPINES = 0 -LANGUAGE_ENGLISH_PITCAIRN_ISLANDS = 0 -LANGUAGE_ENGLISH_PUERTO_RICO = 0 -LANGUAGE_ENGLISH_RWANDA = 0 -LANGUAGE_ENGLISH_SAMOA = 0 -LANGUAGE_ENGLISH_SEYCHELLES = 0 -LANGUAGE_ENGLISH_SIERRA_LEONE = 0 -LANGUAGE_ENGLISH_SINGAPORE = 0 -LANGUAGE_ENGLISH_SINT_MAARTEN = 0 -LANGUAGE_ENGLISH_SLOVENIA = 0 -LANGUAGE_ENGLISH_SOLOMON_ISLANDS = 0 -LANGUAGE_ENGLISH_SOUTH_AFRICA = 0 -LANGUAGE_ENGLISH_SOUTH_SUDAN = 0 -LANGUAGE_ENGLISH_ST_HELENA_ASCENSION_TRISTAN_DA_CUNHA = 0 -LANGUAGE_ENGLISH_ST_KITTS_AND_NEVIS = 0 -LANGUAGE_ENGLISH_ST_LUCIA = 0 -LANGUAGE_ENGLISH_ST_VINCENT_AND_GRENADINES = 0 -LANGUAGE_ENGLISH_SUDAN = 0 -LANGUAGE_ENGLISH_SWEDEN = 0 -LANGUAGE_ENGLISH_SWITZERLAND = 0 -LANGUAGE_ENGLISH_TANZANIA = 0 -LANGUAGE_ENGLISH_TOKELAU = 0 -LANGUAGE_ENGLISH_TONGA = 0 -LANGUAGE_ENGLISH_TRINIDAD = 0 -LANGUAGE_ENGLISH_TURKS_AND_CAICOS_ISLANDS = 0 -LANGUAGE_ENGLISH_TUVALU = 0 -LANGUAGE_ENGLISH_UGANDA = 0 -LANGUAGE_ENGLISH_UK = 0 -LANGUAGE_ENGLISH_UNITED_ARAB_EMIRATES = 0 -LANGUAGE_ENGLISH_US = 0 -LANGUAGE_ENGLISH_US_OUTLYING_ISLANDS = 0 -LANGUAGE_ENGLISH_US_VIRGIN_ISLANDS = 0 -LANGUAGE_ENGLISH_VANUATU = 0 -LANGUAGE_ENGLISH_WORLD = 0 -LANGUAGE_ENGLISH_ZAMBIA = 0 -LANGUAGE_ENGLISH_ZIMBABWE = 0 -LANGUAGE_ESPERANTO = 0 -LANGUAGE_ESPERANTO_WORLD = 0 -LANGUAGE_ESTONIAN = 0 -LANGUAGE_ESTONIAN_ESTONIA = 0 -LANGUAGE_EWE = 0 -LANGUAGE_EWE_GHANA = 0 -LANGUAGE_EWE_TOGO = 0 -LANGUAGE_EWONDO = 0 -LANGUAGE_EWONDO_CAMEROON = 0 -LANGUAGE_FAEROESE = 0 -LANGUAGE_FAEROESE_DENMARK = 0 -LANGUAGE_FAEROESE_FAROE_ISLANDS = 0 -LANGUAGE_FARSI = 0 -LANGUAGE_FIJI = 0 -LANGUAGE_FILIPINO = 0 -LANGUAGE_FILIPINO_PHILIPPINES = 0 -LANGUAGE_FINNISH = 0 -LANGUAGE_FINNISH_FINLAND = 0 -LANGUAGE_FRENCH = 0 -LANGUAGE_FRENCH_ALGERIA = 0 -LANGUAGE_FRENCH_BELGIAN = 0 -LANGUAGE_FRENCH_BENIN = 0 -LANGUAGE_FRENCH_BURKINA_FASO = 0 -LANGUAGE_FRENCH_BURUNDI = 0 -LANGUAGE_FRENCH_CAMEROON = 0 -LANGUAGE_FRENCH_CANADIAN = 0 -LANGUAGE_FRENCH_CARIBBEAN = 0 -LANGUAGE_FRENCH_CENTRAL_AFRICAN_REPUBLIC = 0 -LANGUAGE_FRENCH_CHAD = 0 -LANGUAGE_FRENCH_COMOROS = 0 -LANGUAGE_FRENCH_CONGO = 0 -LANGUAGE_FRENCH_CONGO_DRC = 0 -LANGUAGE_FRENCH_COTE_DIVOIRE = 0 -LANGUAGE_FRENCH_DJIBOUTI = 0 -LANGUAGE_FRENCH_EQUATORIAL_GUINEA = 0 -LANGUAGE_FRENCH_FRANCE = 0 -LANGUAGE_FRENCH_FRENCH_GUIANA = 0 -LANGUAGE_FRENCH_FRENCH_POLYNESIA = 0 -LANGUAGE_FRENCH_GABON = 0 -LANGUAGE_FRENCH_GUADELOUPE = 0 -LANGUAGE_FRENCH_GUINEA = 0 -LANGUAGE_FRENCH_HAITI = 0 -LANGUAGE_FRENCH_LUXEMBOURG = 0 -LANGUAGE_FRENCH_MADAGASCAR = 0 -LANGUAGE_FRENCH_MALI = 0 -LANGUAGE_FRENCH_MARTINIQUE = 0 -LANGUAGE_FRENCH_MAURITANIA = 0 -LANGUAGE_FRENCH_MAURITIUS = 0 -LANGUAGE_FRENCH_MAYOTTE = 0 -LANGUAGE_FRENCH_MONACO = 0 -LANGUAGE_FRENCH_MOROCCO = 0 -LANGUAGE_FRENCH_NEW_CALEDONIA = 0 -LANGUAGE_FRENCH_NIGER = 0 -LANGUAGE_FRENCH_REUNION = 0 -LANGUAGE_FRENCH_RWANDA = 0 -LANGUAGE_FRENCH_SENEGAL = 0 -LANGUAGE_FRENCH_SEYCHELLES = 0 -LANGUAGE_FRENCH_ST_BARTHELEMY = 0 -LANGUAGE_FRENCH_ST_MARTIN = 0 -LANGUAGE_FRENCH_ST_PIERRE_AND_MIQUELON = 0 -LANGUAGE_FRENCH_SWISS = 0 -LANGUAGE_FRENCH_SYRIA = 0 -LANGUAGE_FRENCH_TOGO = 0 -LANGUAGE_FRENCH_TUNISIA = 0 -LANGUAGE_FRENCH_VANUATU = 0 -LANGUAGE_FRENCH_WALLIS_AND_FUTUNA = 0 -LANGUAGE_FRISIAN = 0 -LANGUAGE_FRISIAN_NETHERLANDS = 0 -LANGUAGE_FRIULIAN = 0 -LANGUAGE_FRIULIAN_ITALY = 0 -LANGUAGE_FULAH = 0 -LANGUAGE_FULAH_LATIN = 0 -LANGUAGE_FULAH_LATIN_BURKINA_FASO = 0 -LANGUAGE_FULAH_LATIN_CAMEROON = 0 -LANGUAGE_FULAH_LATIN_GAMBIA = 0 -LANGUAGE_FULAH_LATIN_GHANA = 0 -LANGUAGE_FULAH_LATIN_GUINEA = 0 -LANGUAGE_FULAH_LATIN_GUINEA_BISSAU = 0 -LANGUAGE_FULAH_LATIN_LIBERIA = 0 -LANGUAGE_FULAH_LATIN_MAURITANIA = 0 -LANGUAGE_FULAH_LATIN_NIGER = 0 -LANGUAGE_FULAH_LATIN_NIGERIA = 0 -LANGUAGE_FULAH_LATIN_SENEGAL = 0 -LANGUAGE_FULAH_LATIN_SIERRA_LEONE = 0 -LANGUAGE_GALICIAN = 0 -LANGUAGE_GALICIAN_SPAIN = 0 -LANGUAGE_GANDA = 0 -LANGUAGE_GANDA_UGANDA = 0 -LANGUAGE_GEORGIAN = 0 -LANGUAGE_GEORGIAN_GEORGIA = 0 -LANGUAGE_GERMAN = 0 -LANGUAGE_GERMAN_AUSTRIAN = 0 -LANGUAGE_GERMAN_BELGIUM = 0 -LANGUAGE_GERMAN_GERMANY = 0 -LANGUAGE_GERMAN_ITALY = 0 -LANGUAGE_GERMAN_LIECHTENSTEIN = 0 -LANGUAGE_GERMAN_LUXEMBOURG = 0 -LANGUAGE_GERMAN_SWISS = 0 -LANGUAGE_GREEK = 0 -LANGUAGE_GREEK_CYPRUS = 0 -LANGUAGE_GREEK_GREECE = 0 -LANGUAGE_GREENLANDIC = 0 -LANGUAGE_GUARANI = 0 -LANGUAGE_GUARANI_PARAGUAY = 0 -LANGUAGE_GUJARATI = 0 -LANGUAGE_GUJARATI_INDIA = 0 -LANGUAGE_GUSII = 0 -LANGUAGE_GUSII_KENYA = 0 -LANGUAGE_HAUSA = 0 -LANGUAGE_HAUSA_LATIN = 0 -LANGUAGE_HAUSA_LATIN_GHANA = 0 -LANGUAGE_HAUSA_LATIN_NIGER = 0 -LANGUAGE_HAUSA_LATIN_NIGERIA = 0 -LANGUAGE_HAWAIIAN = 0 -LANGUAGE_HAWAIIAN_US = 0 -LANGUAGE_HEBREW = 0 -LANGUAGE_HEBREW_ISRAEL = 0 -LANGUAGE_HINDI = 0 -LANGUAGE_HINDI_INDIA = 0 -LANGUAGE_HUNGARIAN = 0 -LANGUAGE_HUNGARIAN_HUNGARY = 0 -LANGUAGE_IBIBIO = 0 -LANGUAGE_IBIBIO_NIGERIA = 0 -LANGUAGE_ICELANDIC = 0 -LANGUAGE_ICELANDIC_ICELAND = 0 -LANGUAGE_IGBO = 0 -LANGUAGE_IGBO_NIGERIA = 0 -LANGUAGE_INDONESIAN = 0 -LANGUAGE_INDONESIAN_INDONESIA = 0 -LANGUAGE_INTERLINGUA = 0 -LANGUAGE_INTERLINGUA_WORLD = 0 -LANGUAGE_INTERLINGUE = 0 -LANGUAGE_INUKTITUT = 0 -LANGUAGE_INUKTITUT_LATIN = 0 -LANGUAGE_INUKTITUT_LATIN_CANADA = 0 -LANGUAGE_INUKTITUT_SYLLABICS = 0 -LANGUAGE_INUKTITUT_SYLLABICS_CANADA = 0 -LANGUAGE_INUPIAK = 0 -LANGUAGE_IRISH = 0 -LANGUAGE_IRISH_IRELAND = 0 -LANGUAGE_ITALIAN = 0 -LANGUAGE_ITALIAN_ITALY = 0 -LANGUAGE_ITALIAN_SAN_MARINO = 0 -LANGUAGE_ITALIAN_SWISS = 0 -LANGUAGE_ITALIAN_VATICAN_CITY = 0 -LANGUAGE_JAPANESE = 0 -LANGUAGE_JAPANESE_JAPAN = 0 -LANGUAGE_JAVANESE = 0 -LANGUAGE_JAVANESE_INDONESIA = 0 -LANGUAGE_JAVANESE_JAVANESE = 0 -LANGUAGE_JAVANESE_JAVANESE_INDONESIA = 0 -LANGUAGE_JOLA_FONYI = 0 -LANGUAGE_JOLA_FONYI_SENEGAL = 0 -LANGUAGE_KABUVERDIANU = 0 -LANGUAGE_KABUVERDIANU_CABO_VERDE = 0 -LANGUAGE_KABYLE = 0 -LANGUAGE_KABYLE_ALGERIA = 0 -LANGUAGE_KAKO = 0 -LANGUAGE_KAKO_CAMEROON = 0 -LANGUAGE_KALAALLISUT = 0 -LANGUAGE_KALENJIN = 0 -LANGUAGE_KALENJIN_KENYA = 0 -LANGUAGE_KAMBA = 0 -LANGUAGE_KAMBA_KENYA = 0 -LANGUAGE_KANNADA = 0 -LANGUAGE_KANNADA_INDIA = 0 -LANGUAGE_KANURI = 0 -LANGUAGE_KANURI_LATIN = 0 -LANGUAGE_KANURI_NIGERIA = 0 -LANGUAGE_KASHMIRI = 0 -LANGUAGE_KASHMIRI_DEVANAGARI = 0 -LANGUAGE_KASHMIRI_DEVANAGARI_INDIA = 0 -LANGUAGE_KASHMIRI_INDIA = 0 -LANGUAGE_KASHMIRI_PERSO_ARABIC = 0 -LANGUAGE_KASHMIRI_PERSO_ARABIC_INDIA = 0 -LANGUAGE_KAZAKH = 0 -LANGUAGE_KAZAKH_KAZAKHSTAN = 0 -LANGUAGE_KHMER = 0 -LANGUAGE_KHMER_CAMBODIA = 0 -LANGUAGE_KICHE = 0 -LANGUAGE_KICHE_GUATEMALA = 0 -LANGUAGE_KICHE_LATIN = 0 -LANGUAGE_KIKUYU = 0 -LANGUAGE_KIKUYU_KENYA = 0 -LANGUAGE_KINYARWANDA = 0 -LANGUAGE_KINYARWANDA_RWANDA = 0 -LANGUAGE_KIRGHIZ = 0 -LANGUAGE_KIRGHIZ_KYRGYZSTAN = 0 -LANGUAGE_KIRUNDI = 0 -LANGUAGE_KIRUNDI_BURUNDI = 0 -LANGUAGE_KONKANI = 0 -LANGUAGE_KONKANI_INDIA = 0 -LANGUAGE_KOREAN = 0 -LANGUAGE_KOREAN_KOREA = 0 -LANGUAGE_KOREAN_NORTH_KOREA = 0 -LANGUAGE_KOYRABORO_SENNI = 0 -LANGUAGE_KOYRABORO_SENNI_MALI = 0 -LANGUAGE_KOYRA_CHIINI = 0 -LANGUAGE_KOYRA_CHIINI_MALI = 0 -LANGUAGE_KURDISH = 0 -LANGUAGE_KURDISH_PERSO_ARABIC_IRAN = 0 -LANGUAGE_KWASIO = 0 -LANGUAGE_KWASIO_CAMEROON = 0 -LANGUAGE_LAKOTA = 0 -LANGUAGE_LAKOTA_US = 0 -LANGUAGE_LANGI = 0 -LANGUAGE_LANGI_TANZANIA = 0 -LANGUAGE_LAOTHIAN = 0 -LANGUAGE_LAOTHIAN_LAOS = 0 -LANGUAGE_LATIN = 0 -LANGUAGE_LATIN_WORLD = 0 -LANGUAGE_LATVIAN = 0 -LANGUAGE_LATVIAN_LATVIA = 0 -LANGUAGE_LINGALA = 0 -LANGUAGE_LINGALA_ANGOLA = 0 -LANGUAGE_LINGALA_CENTRAL_AFRICAN_REPUBLIC = 0 -LANGUAGE_LINGALA_CONGO = 0 -LANGUAGE_LINGALA_CONGO_DRC = 0 -LANGUAGE_LITHUANIAN = 0 -LANGUAGE_LITHUANIAN_LITHUANIA = 0 -LANGUAGE_LOWER_SORBIAN = 0 -LANGUAGE_LOWER_SORBIAN_GERMANY = 0 -LANGUAGE_LOW_GERMAN = 0 -LANGUAGE_LOW_GERMAN_GERMANY = 0 -LANGUAGE_LOW_GERMAN_NETHERLANDS = 0 -LANGUAGE_LUBA_KATANGA = 0 -LANGUAGE_LUBA_KATANGA_CONGO_DRC = 0 -LANGUAGE_LUO = 0 -LANGUAGE_LUO_KENYA = 0 -LANGUAGE_LUXEMBOURGISH = 0 -LANGUAGE_LUXEMBOURGISH_LUXEMBOURG = 0 -LANGUAGE_LUYIA = 0 -LANGUAGE_LUYIA_KENYA = 0 -LANGUAGE_MACEDONIAN = 0 -LANGUAGE_MACEDONIAN_NORTH_MACEDONIA = 0 -LANGUAGE_MACHAME = 0 -LANGUAGE_MACHAME_TANZANIA = 0 -LANGUAGE_MAKHUWA_MEETTO = 0 -LANGUAGE_MAKHUWA_MEETTO_MOZAMBIQUE = 0 -LANGUAGE_MAKONDE = 0 -LANGUAGE_MAKONDE_TANZANIA = 0 -LANGUAGE_MALAGASY = 0 -LANGUAGE_MALAGASY_MADAGASCAR = 0 -LANGUAGE_MALAY = 0 -LANGUAGE_MALAYALAM = 0 -LANGUAGE_MALAYALAM_INDIA = 0 -LANGUAGE_MALAY_BRUNEI = 0 -LANGUAGE_MALAY_MALAYSIA = 0 -LANGUAGE_MALAY_SINGAPORE = 0 -LANGUAGE_MALTESE = 0 -LANGUAGE_MALTESE_MALTA = 0 -LANGUAGE_MANIPURI = 0 -LANGUAGE_MANIPURI_INDIA = 0 -LANGUAGE_MANX = 0 -LANGUAGE_MANX_ISLE_OF_MAN = 0 -LANGUAGE_MAORI = 0 -LANGUAGE_MAORI_NEW_ZEALAND = 0 -LANGUAGE_MAPUCHE = 0 -LANGUAGE_MAPUCHE_CHILE = 0 -LANGUAGE_MARATHI = 0 -LANGUAGE_MARATHI_INDIA = 0 -LANGUAGE_MASAI = 0 -LANGUAGE_MASAI_KENYA = 0 -LANGUAGE_MASAI_TANZANIA = 0 -LANGUAGE_MAZANDERANI = 0 -LANGUAGE_MAZANDERANI_IRAN = 0 -LANGUAGE_MERU = 0 -LANGUAGE_MERU_KENYA = 0 -LANGUAGE_META = 0 -LANGUAGE_META_CAMEROON = 0 -LANGUAGE_MOHAWK = 0 -LANGUAGE_MOHAWK_CANADA = 0 -LANGUAGE_MOLDAVIAN = 0 -LANGUAGE_MONGOLIAN = 0 -LANGUAGE_MONGOLIAN_CYRILLIC = 0 -LANGUAGE_MONGOLIAN_MONGOLIA = 0 -LANGUAGE_MONGOLIAN_TRADITIONAL = 0 -LANGUAGE_MONGOLIAN_TRADITIONAL_CHINA = 0 -LANGUAGE_MONGOLIAN_TRADITIONAL_MONGOLIA = 0 -LANGUAGE_MORISYEN = 0 -LANGUAGE_MORISYEN_MAURITIUS = 0 -LANGUAGE_MUNDANG = 0 -LANGUAGE_MUNDANG_CAMEROON = 0 -LANGUAGE_NAMA = 0 -LANGUAGE_NAMA_NAMIBIA = 0 -LANGUAGE_NAURU = 0 -LANGUAGE_NEPALI = 0 -LANGUAGE_NEPALI_INDIA = 0 -LANGUAGE_NEPALI_NEPAL = 0 -LANGUAGE_NGIEMBOON = 0 -LANGUAGE_NGIEMBOON_CAMEROON = 0 -LANGUAGE_NGOMBA = 0 -LANGUAGE_NGOMBA_CAMEROON = 0 -LANGUAGE_NKO = 0 -LANGUAGE_NKO_GUINEA = 0 -LANGUAGE_NORTHERN_LURI = 0 -LANGUAGE_NORTHERN_LURI_IRAN = 0 -LANGUAGE_NORTHERN_LURI_IRAQ = 0 -LANGUAGE_NORTH_NDEBELE = 0 -LANGUAGE_NORTH_NDEBELE_ZIMBABWE = 0 -LANGUAGE_NORWEGIAN = 0 -LANGUAGE_NORWEGIAN_BOKMAL = 0 -LANGUAGE_NORWEGIAN_BOKMAL_NORWAY = 0 -LANGUAGE_NORWEGIAN_BOKMAL_SVALBARD_AND_JAN_MAYEN = 0 -LANGUAGE_NORWEGIAN_NYNORSK = 0 -LANGUAGE_NORWEGIAN_NYNORSK_NORWAY = 0 -LANGUAGE_NUER = 0 -LANGUAGE_NUER_SOUTH_SUDAN = 0 -LANGUAGE_NYANKOLE = 0 -LANGUAGE_NYANKOLE_UGANDA = 0 -LANGUAGE_OCCITAN = 0 -LANGUAGE_OCCITAN_FRANCE = 0 -LANGUAGE_ODIA = 0 -LANGUAGE_ODIA_INDIA = 0 -LANGUAGE_OROMO = 0 -LANGUAGE_OROMO_ETHIOPIA = 0 -LANGUAGE_OROMO_KENYA = 0 -LANGUAGE_OSSETIC = 0 -LANGUAGE_OSSETIC_GEORGIA = 0 -LANGUAGE_OSSETIC_RUSSIA = 0 -LANGUAGE_PAPIAMENTO = 0 -LANGUAGE_PAPIAMENTO_CARIBBEAN = 0 -LANGUAGE_PASHTO = 0 -LANGUAGE_PASHTO_AFGHANISTAN = 0 -LANGUAGE_PASHTO_PAKISTAN = 0 -LANGUAGE_PERSIAN_IRAN = 0 -LANGUAGE_POLISH = 0 -LANGUAGE_POLISH_POLAND = 0 -LANGUAGE_PORTUGUESE = 0 -LANGUAGE_PORTUGUESE_ANGOLA = 0 -LANGUAGE_PORTUGUESE_BRAZILIAN = 0 -LANGUAGE_PORTUGUESE_CABO_VERDE = 0 -LANGUAGE_PORTUGUESE_EQUATORIAL_GUINEA = 0 -LANGUAGE_PORTUGUESE_GUINEA_BISSAU = 0 -LANGUAGE_PORTUGUESE_LUXEMBOURG = 0 -LANGUAGE_PORTUGUESE_MACAO_SAR = 0 -LANGUAGE_PORTUGUESE_MOZAMBIQUE = 0 -LANGUAGE_PORTUGUESE_PORTUGAL = 0 -LANGUAGE_PORTUGUESE_SAO_TOME_AND_PRINCIPE = 0 -LANGUAGE_PORTUGUESE_SWITZERLAND = 0 -LANGUAGE_PORTUGUESE_TIMOR_LESTE = 0 -LANGUAGE_PRUSSIAN = 0 -LANGUAGE_PRUSSIAN_WORLD = 0 -LANGUAGE_PUNJABI = 0 -LANGUAGE_PUNJABI_ARABIC = 0 -LANGUAGE_PUNJABI_GURMUKHI = 0 -LANGUAGE_PUNJABI_INDIA = 0 -LANGUAGE_PUNJABI_PAKISTAN = 0 -LANGUAGE_QUECHUA = 0 -LANGUAGE_QUECHUA_BOLIVIA = 0 -LANGUAGE_QUECHUA_ECUADOR = 0 -LANGUAGE_QUECHUA_MACRO = 0 -LANGUAGE_QUECHUA_PERU = 0 -LANGUAGE_RHAETO_ROMANCE = 0 -LANGUAGE_RHAETO_ROMANCE_SWITZERLAND = 0 -LANGUAGE_ROMANIAN = 0 -LANGUAGE_ROMANIAN_MOLDOVA = 0 -LANGUAGE_ROMANIAN_ROMANIA = 0 -LANGUAGE_ROMBO = 0 -LANGUAGE_ROMBO_TANZANIA = 0 -LANGUAGE_RUSSIAN = 0 -LANGUAGE_RUSSIAN_BELARUS = 0 -LANGUAGE_RUSSIAN_KAZAKHSTAN = 0 -LANGUAGE_RUSSIAN_KYRGYZSTAN = 0 -LANGUAGE_RUSSIAN_MOLDOVA = 0 -LANGUAGE_RUSSIAN_RUSSIA = 0 -LANGUAGE_RUSSIAN_UKRAINE = 0 -LANGUAGE_RWA = 0 -LANGUAGE_RWA_TANZANIA = 0 -LANGUAGE_SAHO = 0 -LANGUAGE_SAHO_ERITREA = 0 -LANGUAGE_SAKHA = 0 -LANGUAGE_SAKHA_RUSSIA = 0 -LANGUAGE_SAMBURU = 0 -LANGUAGE_SAMBURU_KENYA = 0 -LANGUAGE_SAMI = 0 -LANGUAGE_SAMI_FINLAND = 0 -LANGUAGE_SAMI_INARI = 0 -LANGUAGE_SAMI_INARI_FINLAND = 0 -LANGUAGE_SAMI_LULE = 0 -LANGUAGE_SAMI_LULE_NORWAY = 0 -LANGUAGE_SAMI_LULE_SWEDEN = 0 -LANGUAGE_SAMI_NORWAY = 0 -LANGUAGE_SAMI_SKOLT = 0 -LANGUAGE_SAMI_SKOLT_FINLAND = 0 -LANGUAGE_SAMI_SOUTHERN = 0 -LANGUAGE_SAMI_SOUTHERN_NORWAY = 0 -LANGUAGE_SAMI_SOUTHERN_SWEDEN = 0 -LANGUAGE_SAMI_SWEDEN = 0 -LANGUAGE_SAMOAN = 0 -LANGUAGE_SANGHO = 0 -LANGUAGE_SANGHO_CENTRAL_AFRICAN_REPUBLIC = 0 -LANGUAGE_SANGU = 0 -LANGUAGE_SANGU_TANZANIA = 0 -LANGUAGE_SANSKRIT = 0 -LANGUAGE_SANSKRIT_INDIA = 0 -LANGUAGE_SCOTS_GAELIC = 0 -LANGUAGE_SCOTS_GAELIC_UK = 0 -LANGUAGE_SENA = 0 -LANGUAGE_SENA_MOZAMBIQUE = 0 -LANGUAGE_SERBIAN = 0 -LANGUAGE_SERBIAN_CYRILLIC = 0 -LANGUAGE_SERBIAN_CYRILLIC_BOSNIA_AND_HERZEGOVINA = 0 -LANGUAGE_SERBIAN_CYRILLIC_KOSOVO = 0 -LANGUAGE_SERBIAN_CYRILLIC_MONTENEGRO = 0 -LANGUAGE_SERBIAN_CYRILLIC_SERBIA = 0 -LANGUAGE_SERBIAN_CYRILLIC_YU = 0 -LANGUAGE_SERBIAN_LATIN = 0 -LANGUAGE_SERBIAN_LATIN_BOSNIA_AND_HERZEGOVINA = 0 -LANGUAGE_SERBIAN_LATIN_KOSOVO = 0 -LANGUAGE_SERBIAN_LATIN_MONTENEGRO = 0 -LANGUAGE_SERBIAN_LATIN_SERBIA = 0 -LANGUAGE_SERBIAN_LATIN_YU = 0 -LANGUAGE_SERBIAN_SERBIA = 0 -LANGUAGE_SERBIAN_YU = 0 -LANGUAGE_SERBO_CROATIAN = 0 -LANGUAGE_SESOTHO = 0 -LANGUAGE_SESOTHO_LESOTHO = 0 -LANGUAGE_SESOTHO_SA_LEBOA = 0 -LANGUAGE_SESOTHO_SA_LEBOA_SOUTH_AFRICA = 0 -LANGUAGE_SESOTHO_SOUTH_AFRICA = 0 -LANGUAGE_SETSWANA = 0 -LANGUAGE_SETSWANA_BOTSWANA = 0 -LANGUAGE_SETSWANA_SOUTH_AFRICA = 0 -LANGUAGE_SHAMBALA = 0 -LANGUAGE_SHAMBALA_TANZANIA = 0 -LANGUAGE_SHONA = 0 -LANGUAGE_SHONA_LATIN = 0 -LANGUAGE_SHONA_LATIN_ZIMBABWE = 0 -LANGUAGE_SINDHI = 0 -LANGUAGE_SINDHI_ARABIC = 0 -LANGUAGE_SINDHI_DEVANAGARI = 0 -LANGUAGE_SINDHI_DEVANAGARI_INDIA = 0 -LANGUAGE_SINDHI_PAKISTAN = 0 -LANGUAGE_SINHALESE = 0 -LANGUAGE_SINHALESE_SRI_LANKA = 0 -LANGUAGE_SISWATI = 0 -LANGUAGE_SISWATI_ESWATINI = 0 -LANGUAGE_SISWATI_SOUTH_AFRICA = 0 -LANGUAGE_SLOVAK = 0 -LANGUAGE_SLOVAK_SLOVAKIA = 0 -LANGUAGE_SLOVENIAN = 0 -LANGUAGE_SLOVENIAN_SLOVENIA = 0 -LANGUAGE_SOGA = 0 -LANGUAGE_SOGA_UGANDA = 0 -LANGUAGE_SOMALI = 0 -LANGUAGE_SOMALI_DJIBOUTI = 0 -LANGUAGE_SOMALI_ETHIOPIA = 0 -LANGUAGE_SOMALI_KENYA = 0 -LANGUAGE_SOMALI_SOMALIA = 0 -LANGUAGE_SOUTH_NDEBELE = 0 -LANGUAGE_SOUTH_NDEBELE_SOUTH_AFRICA = 0 -LANGUAGE_SPANISH = 0 -LANGUAGE_SPANISH_ARGENTINA = 0 -LANGUAGE_SPANISH_BELIZE = 0 -LANGUAGE_SPANISH_BOLIVIA = 0 -LANGUAGE_SPANISH_BRAZIL = 0 -LANGUAGE_SPANISH_CHILE = 0 -LANGUAGE_SPANISH_COLOMBIA = 0 -LANGUAGE_SPANISH_COSTA_RICA = 0 -LANGUAGE_SPANISH_CUBA = 0 -LANGUAGE_SPANISH_DOMINICAN_REPUBLIC = 0 -LANGUAGE_SPANISH_ECUADOR = 0 -LANGUAGE_SPANISH_EL_SALVADOR = 0 -LANGUAGE_SPANISH_EQUATORIAL_GUINEA = 0 -LANGUAGE_SPANISH_GUATEMALA = 0 -LANGUAGE_SPANISH_HONDURAS = 0 -LANGUAGE_SPANISH_LATIN_AMERICA = 0 -LANGUAGE_SPANISH_MEXICAN = 0 -LANGUAGE_SPANISH_NICARAGUA = 0 -LANGUAGE_SPANISH_PANAMA = 0 -LANGUAGE_SPANISH_PARAGUAY = 0 -LANGUAGE_SPANISH_PERU = 0 -LANGUAGE_SPANISH_PHILIPPINES = 0 -LANGUAGE_SPANISH_PUERTO_RICO = 0 -LANGUAGE_SPANISH_SPAIN = 0 -LANGUAGE_SPANISH_URUGUAY = 0 -LANGUAGE_SPANISH_US = 0 -LANGUAGE_SPANISH_VENEZUELA = 0 -LANGUAGE_STANDARD_MOROCCAN_TAMAZIGHT = 0 -LANGUAGE_STANDARD_MOROCCAN_TAMAZIGHT_TIFINAGH = 0 -LANGUAGE_STANDARD_MOROCCAN_TAMAZIGHT_TIFINAGH_MOROCCO = 0 -LANGUAGE_SUNDANESE = 0 -LANGUAGE_SWAHILI = 0 -LANGUAGE_SWAHILI_CONGO_DRC = 0 -LANGUAGE_SWAHILI_KENYA = 0 -LANGUAGE_SWAHILI_TANZANIA = 0 -LANGUAGE_SWAHILI_UGANDA = 0 -LANGUAGE_SWEDISH = 0 -LANGUAGE_SWEDISH_ALAND_ISLANDS = 0 -LANGUAGE_SWEDISH_FINLAND = 0 -LANGUAGE_SWEDISH_SWEDEN = 0 -LANGUAGE_SWISS_GERMAN = 0 -LANGUAGE_SWISS_GERMAN_LIECHTENSTEIN = 0 -LANGUAGE_SWISS_GERMAN_SWITZERLAND = 0 -LANGUAGE_SYRIAC = 0 -LANGUAGE_SYRIAC_SYRIA = 0 -LANGUAGE_TACHELHIT = 0 -LANGUAGE_TACHELHIT_LATIN = 0 -LANGUAGE_TACHELHIT_LATIN_MOROCCO = 0 -LANGUAGE_TACHELHIT_TIFINAGH = 0 -LANGUAGE_TACHELHIT_TIFINAGH_MOROCCO = 0 -LANGUAGE_TAGALOG = 0 -LANGUAGE_TAITA = 0 -LANGUAGE_TAITA_KENYA = 0 -LANGUAGE_TAJIK = 0 -LANGUAGE_TAJIK_CYRILLIC = 0 -LANGUAGE_TAJIK_CYRILLIC_TAJIKISTAN = 0 -LANGUAGE_TAMIL = 0 -LANGUAGE_TAMIL_INDIA = 0 -LANGUAGE_TAMIL_MALAYSIA = 0 -LANGUAGE_TAMIL_SINGAPORE = 0 -LANGUAGE_TAMIL_SRI_LANKA = 0 -LANGUAGE_TASAWAQ = 0 -LANGUAGE_TASAWAQ_NIGER = 0 -LANGUAGE_TATAR = 0 -LANGUAGE_TATAR_RUSSIA = 0 -LANGUAGE_TELUGU = 0 -LANGUAGE_TELUGU_INDIA = 0 -LANGUAGE_TESO = 0 -LANGUAGE_TESO_KENYA = 0 -LANGUAGE_TESO_UGANDA = 0 -LANGUAGE_THAI = 0 -LANGUAGE_THAI_THAILAND = 0 -LANGUAGE_TIBETAN = 0 -LANGUAGE_TIBETAN_CHINA = 0 -LANGUAGE_TIBETAN_INDIA = 0 -LANGUAGE_TIGRE = 0 -LANGUAGE_TIGRE_ERITREA = 0 -LANGUAGE_TIGRINYA = 0 -LANGUAGE_TIGRINYA_ERITREA = 0 -LANGUAGE_TIGRINYA_ETHIOPIA = 0 -LANGUAGE_TONGA = 0 -LANGUAGE_TONGA_TONGA = 0 -LANGUAGE_TSONGA = 0 -LANGUAGE_TSONGA_SOUTH_AFRICA = 0 -LANGUAGE_TURKISH = 0 -LANGUAGE_TURKISH_CYPRUS = 0 -LANGUAGE_TURKISH_TURKEY = 0 -LANGUAGE_TURKMEN = 0 -LANGUAGE_TURKMEN_TURKMENISTAN = 0 -LANGUAGE_TWI = 0 -LANGUAGE_UIGHUR = 0 -LANGUAGE_UIGHUR_CHINA = 0 -LANGUAGE_UKRAINIAN = 0 -LANGUAGE_UKRAINIAN_UKRAINE = 0 -LANGUAGE_UPPER_SORBIAN = 0 -LANGUAGE_UPPER_SORBIAN_GERMANY = 0 -LANGUAGE_URDU = 0 -LANGUAGE_URDU_INDIA = 0 -LANGUAGE_URDU_PAKISTAN = 0 -LANGUAGE_UZBEK = 0 -LANGUAGE_UZBEK_CYRILLIC = 0 -LANGUAGE_UZBEK_CYRILLIC_UZBEKISTAN = 0 -LANGUAGE_UZBEK_LATIN = 0 -LANGUAGE_UZBEK_LATIN_UZBEKISTAN = 0 -LANGUAGE_UZBEK_PERSO_ARABIC = 0 -LANGUAGE_UZBEK_PERSO_ARABIC_AFGHANISTAN = 0 -LANGUAGE_VAI = 0 -LANGUAGE_VAI_LATIN = 0 -LANGUAGE_VAI_LATIN_LIBERIA = 0 -LANGUAGE_VAI_VAI = 0 -LANGUAGE_VAI_VAI_LIBERIA = 0 -LANGUAGE_VALENCIAN = 0 -LANGUAGE_VENDA = 0 -LANGUAGE_VENDA_SOUTH_AFRICA = 0 -LANGUAGE_VIETNAMESE = 0 -LANGUAGE_VIETNAMESE_VIETNAM = 0 -LANGUAGE_VOLAPUK = 0 -LANGUAGE_VOLAPUK_WORLD = 0 -LANGUAGE_VUNJO = 0 -LANGUAGE_VUNJO_TANZANIA = 0 -LANGUAGE_WALSER = 0 -LANGUAGE_WALSER_SWITZERLAND = 0 -LANGUAGE_WELSH = 0 -LANGUAGE_WELSH_UK = 0 -LANGUAGE_WOLAYTTA = 0 -LANGUAGE_WOLAYTTA_ETHIOPIA = 0 -LANGUAGE_WOLOF = 0 -LANGUAGE_WOLOF_SENEGAL = 0 -LANGUAGE_XHOSA = 0 -LANGUAGE_XHOSA_SOUTH_AFRICA = 0 -LANGUAGE_YANGBEN = 0 -LANGUAGE_YANGBEN_CAMEROON = 0 -LANGUAGE_YI = 0 -LANGUAGE_YIDDISH = 0 -LANGUAGE_YIDDISH_WORLD = 0 -LANGUAGE_YI_CHINA = 0 -LANGUAGE_YORUBA = 0 -LANGUAGE_YORUBA_BENIN = 0 -LANGUAGE_YORUBA_NIGERIA = 0 -LANGUAGE_ZARMA = 0 -LANGUAGE_ZARMA_NIGER = 0 -LANGUAGE_ZHUANG = 0 -LANGUAGE_ZULU = 0 -LANGUAGE_ZULU_SOUTH_AFRICA = 0 -LANGUAGE_USER_DEFINED = 0 -LANGUAGE_AZERI = 0 -LANGUAGE_AZERI_CYRILLIC = 0 -LANGUAGE_AZERI_LATIN = 0 -LANGUAGE_BENGALI = 0 -LANGUAGE_BENGALI_BANGLADESH = 0 -LANGUAGE_BENGALI_INDIA = 0 -LANGUAGE_BHUTANI = 0 -LANGUAGE_CHINESE_SIMPLIFIED = 0 -LANGUAGE_CHINESE_TRADITIONAL = 0 -LANGUAGE_CHINESE_MACAU = 0 -LANGUAGE_KERNEWEK = 0 -LANGUAGE_MALAY_BRUNEI_DARUSSALAM = 0 -LANGUAGE_ORIYA = 0 -LANGUAGE_ORIYA_INDIA = 0 -LANGUAGE_SPANISH_MODERN = 0 -LANGUAGE_CAMBODIAN = 0 -Layout_Default = 0 -Layout_LeftToRight = 0 -Layout_RightToLeft = 0 -LOCALE_TAGTYPE_DEFAULT = 0 -LOCALE_TAGTYPE_SYSTEM = 0 -LOCALE_TAGTYPE_BCP47 = 0 -LOCALE_TAGTYPE_MACOS = 0 -LOCALE_TAGTYPE_POSIX = 0 -LOCALE_TAGTYPE_WINDOWS = 0 -LOCALE_CAT_NUMBER = 0 -LOCALE_CAT_DATE = 0 -LOCALE_CAT_MONEY = 0 -LOCALE_CAT_DEFAULT = 0 -LOCALE_THOUSANDS_SEP = 0 -LOCALE_DECIMAL_POINT = 0 -LOCALE_SHORT_DATE_FMT = 0 -LOCALE_LONG_DATE_FMT = 0 -LOCALE_DATE_TIME_FMT = 0 -LOCALE_TIME_FMT = 0 -LOCALE_NAME_LOCALE = 0 -LOCALE_NAME_LANGUAGE = 0 -LOCALE_NAME_COUNTRY = 0 -LOCALE_FORM_NATIVE = 0 -LOCALE_FORM_ENGLISH = 0 -LOCALE_DONT_LOAD_DEFAULT = 0 -LOCALE_LOAD_DEFAULT = 0 +LANGUAGE_DEFAULT: int +LANGUAGE_UNKNOWN: int +LANGUAGE_ABKHAZIAN: int +LANGUAGE_AFAR: int +LANGUAGE_AFAR_DJIBOUTI: int +LANGUAGE_AFAR_ERITREA: int +LANGUAGE_AFAR_ETHIOPIA: int +LANGUAGE_AFRIKAANS: int +LANGUAGE_AFRIKAANS_NAMIBIA: int +LANGUAGE_AFRIKAANS_SOUTH_AFRICA: int +LANGUAGE_AGHEM: int +LANGUAGE_AGHEM_CAMEROON: int +LANGUAGE_AKAN: int +LANGUAGE_AKAN_GHANA: int +LANGUAGE_ALBANIAN: int +LANGUAGE_ALBANIAN_ALBANIA: int +LANGUAGE_ALBANIAN_KOSOVO: int +LANGUAGE_ALBANIAN_NORTH_MACEDONIA: int +LANGUAGE_ALSATIAN_FRANCE: int +LANGUAGE_AMHARIC: int +LANGUAGE_AMHARIC_ETHIOPIA: int +LANGUAGE_ARABIC: int +LANGUAGE_ARABIC_ALGERIA: int +LANGUAGE_ARABIC_BAHRAIN: int +LANGUAGE_ARABIC_CHAD: int +LANGUAGE_ARABIC_COMOROS: int +LANGUAGE_ARABIC_DJIBOUTI: int +LANGUAGE_ARABIC_EGYPT: int +LANGUAGE_ARABIC_ERITREA: int +LANGUAGE_ARABIC_IRAQ: int +LANGUAGE_ARABIC_ISRAEL: int +LANGUAGE_ARABIC_JORDAN: int +LANGUAGE_ARABIC_KUWAIT: int +LANGUAGE_ARABIC_LEBANON: int +LANGUAGE_ARABIC_LIBYA: int +LANGUAGE_ARABIC_MAURITANIA: int +LANGUAGE_ARABIC_MOROCCO: int +LANGUAGE_ARABIC_OMAN: int +LANGUAGE_ARABIC_PALESTINIAN_AUTHORITY: int +LANGUAGE_ARABIC_QATAR: int +LANGUAGE_ARABIC_SAUDI_ARABIA: int +LANGUAGE_ARABIC_SOMALIA: int +LANGUAGE_ARABIC_SOUTH_SUDAN: int +LANGUAGE_ARABIC_SUDAN: int +LANGUAGE_ARABIC_SYRIA: int +LANGUAGE_ARABIC_TUNISIA: int +LANGUAGE_ARABIC_UAE: int +LANGUAGE_ARABIC_WORLD: int +LANGUAGE_ARABIC_YEMEN: int +LANGUAGE_ARMENIAN: int +LANGUAGE_ARMENIAN_ARMENIA: int +LANGUAGE_ASSAMESE: int +LANGUAGE_ASSAMESE_INDIA: int +LANGUAGE_ASTURIAN: int +LANGUAGE_ASTURIAN_SPAIN: int +LANGUAGE_ASU: int +LANGUAGE_ASU_TANZANIA: int +LANGUAGE_AYMARA: int +LANGUAGE_AZERBAIJANI: int +LANGUAGE_AZERBAIJANI_CYRILLIC: int +LANGUAGE_AZERBAIJANI_CYRILLIC_AZERBAIJAN: int +LANGUAGE_AZERBAIJANI_LATIN: int +LANGUAGE_AZERBAIJANI_LATIN_AZERBAIJAN: int +LANGUAGE_BAFIA: int +LANGUAGE_BAFIA_CAMEROON: int +LANGUAGE_BAMANANKAN: int +LANGUAGE_BAMANANKAN_LATIN: int +LANGUAGE_BAMANANKAN_LATIN_MALI: int +LANGUAGE_BANGLA: int +LANGUAGE_BANGLA_BANGLADESH: int +LANGUAGE_BANGLA_INDIA: int +LANGUAGE_BASAA: int +LANGUAGE_BASAA_CAMEROON: int +LANGUAGE_BASHKIR: int +LANGUAGE_BASHKIR_RUSSIA: int +LANGUAGE_BASQUE: int +LANGUAGE_BASQUE_SPAIN: int +LANGUAGE_BELARUSIAN: int +LANGUAGE_BELARUSIAN_BELARUS: int +LANGUAGE_BEMBA: int +LANGUAGE_BEMBA_ZAMBIA: int +LANGUAGE_BENA: int +LANGUAGE_BENA_TANZANIA: int +LANGUAGE_BIHARI: int +LANGUAGE_BISLAMA: int +LANGUAGE_BLIN: int +LANGUAGE_BLIN_ERITREA: int +LANGUAGE_BODO: int +LANGUAGE_BODO_INDIA: int +LANGUAGE_BOSNIAN: int +LANGUAGE_BOSNIAN_CYRILLIC: int +LANGUAGE_BOSNIAN_CYRILLIC_BOSNIA_AND_HERZEGOVINA: int +LANGUAGE_BOSNIAN_LATIN: int +LANGUAGE_BOSNIAN_LATIN_BOSNIA_AND_HERZEGOVINA: int +LANGUAGE_BRETON: int +LANGUAGE_BRETON_FRANCE: int +LANGUAGE_BULGARIAN: int +LANGUAGE_BULGARIAN_BULGARIA: int +LANGUAGE_BURMESE: int +LANGUAGE_BURMESE_MYANMAR: int +LANGUAGE_CATALAN: int +LANGUAGE_CATALAN_ANDORRA: int +LANGUAGE_CATALAN_FRANCE: int +LANGUAGE_CATALAN_ITALY: int +LANGUAGE_CATALAN_SPAIN: int +LANGUAGE_CEBUANO: int +LANGUAGE_CEBUANO_LATIN: int +LANGUAGE_CEBUANO_LATIN_PHILIPPINES: int +LANGUAGE_CENTRAL_ATLAS_TAMAZIGHT: int +LANGUAGE_CENTRAL_ATLAS_TAMAZIGHT_ARABIC: int +LANGUAGE_CENTRAL_ATLAS_TAMAZIGHT_ARABIC_MOROCCO: int +LANGUAGE_CENTRAL_ATLAS_TAMAZIGHT_LATIN: int +LANGUAGE_CENTRAL_ATLAS_TAMAZIGHT_LATIN_ALGERIA: int +LANGUAGE_CENTRAL_ATLAS_TAMAZIGHT_LATIN_MOROCCO: int +LANGUAGE_CENTRAL_ATLAS_TAMAZIGHT_TIFINAGH: int +LANGUAGE_CENTRAL_ATLAS_TAMAZIGHT_TIFINAGH_MOROCCO: int +LANGUAGE_CENTRAL_KURDISH: int +LANGUAGE_CENTRAL_KURDISH_IRAQ: int +LANGUAGE_CHAKMA: int +LANGUAGE_CHAKMA_CHAKMA: int +LANGUAGE_CHAKMA_CHAKMA_BANGLADESH: int +LANGUAGE_CHAKMA_CHAKMA_INDIA: int +LANGUAGE_CHECHEN: int +LANGUAGE_CHECHEN_RUSSIA: int +LANGUAGE_CHEROKEE: int +LANGUAGE_CHEROKEE_CHEROKEE: int +LANGUAGE_CHEROKEE_US: int +LANGUAGE_CHIGA: int +LANGUAGE_CHIGA_UGANDA: int +LANGUAGE_CHINESE: int +LANGUAGE_CHINESE_CHINA: int +LANGUAGE_CHINESE_HONGKONG: int +LANGUAGE_CHINESE_MACAO: int +LANGUAGE_CHINESE_SIMPLIFIED_EXPLICIT: int +LANGUAGE_CHINESE_SIMPLIFIED_HONGKONG: int +LANGUAGE_CHINESE_SIMPLIFIED_MACAO: int +LANGUAGE_CHINESE_SINGAPORE: int +LANGUAGE_CHINESE_TAIWAN: int +LANGUAGE_CHINESE_TRADITIONAL_EXPLICIT: int +LANGUAGE_CHURCH_SLAVIC: int +LANGUAGE_CHURCH_SLAVIC_RUSSIA: int +LANGUAGE_COLOGNIAN: int +LANGUAGE_COLOGNIAN_GERMANY: int +LANGUAGE_CORNISH: int +LANGUAGE_CORNISH_UK: int +LANGUAGE_CORSICAN: int +LANGUAGE_CORSICAN_FRANCE: int +LANGUAGE_CROATIAN: int +LANGUAGE_CROATIAN_BOSNIA_AND_HERZEGOVINA: int +LANGUAGE_CROATIAN_CROATIA: int +LANGUAGE_CZECH: int +LANGUAGE_CZECH_CZECHIA: int +LANGUAGE_DANISH: int +LANGUAGE_DANISH_DENMARK: int +LANGUAGE_DANISH_GREENLAND: int +LANGUAGE_DARI: int +LANGUAGE_DARI_AFGHANISTAN: int +LANGUAGE_DIVEHI: int +LANGUAGE_DIVEHI_MALDIVES: int +LANGUAGE_DUALA: int +LANGUAGE_DUALA_CAMEROON: int +LANGUAGE_DUTCH: int +LANGUAGE_DUTCH_ARUBA: int +LANGUAGE_DUTCH_BELGIAN: int +LANGUAGE_DUTCH_BONAIRE_SINT_EUSTATIUS_AND_SABA: int +LANGUAGE_DUTCH_CURACAO: int +LANGUAGE_DUTCH_NETHERLANDS: int +LANGUAGE_DUTCH_SINT_MAARTEN: int +LANGUAGE_DUTCH_SURINAME: int +LANGUAGE_DZONGKHA: int +LANGUAGE_DZONGKHA_BHUTAN: int +LANGUAGE_EDO: int +LANGUAGE_EDO_NIGERIA: int +LANGUAGE_EMBU: int +LANGUAGE_EMBU_KENYA: int +LANGUAGE_ENGLISH: int +LANGUAGE_ENGLISH_AMERICAN_SAMOA: int +LANGUAGE_ENGLISH_ANGUILLA: int +LANGUAGE_ENGLISH_ANTIGUA_AND_BARBUDA: int +LANGUAGE_ENGLISH_AUSTRALIA: int +LANGUAGE_ENGLISH_AUSTRIA: int +LANGUAGE_ENGLISH_BAHAMAS: int +LANGUAGE_ENGLISH_BARBADOS: int +LANGUAGE_ENGLISH_BELGIUM: int +LANGUAGE_ENGLISH_BELIZE: int +LANGUAGE_ENGLISH_BERMUDA: int +LANGUAGE_ENGLISH_BOTSWANA: int +LANGUAGE_ENGLISH_BRITISH_INDIAN_OCEAN_TERRITORY: int +LANGUAGE_ENGLISH_BRITISH_VIRGIN_ISLANDS: int +LANGUAGE_ENGLISH_BURUNDI: int +LANGUAGE_ENGLISH_CAMEROON: int +LANGUAGE_ENGLISH_CANADA: int +LANGUAGE_ENGLISH_CARIBBEAN: int +LANGUAGE_ENGLISH_CARIBBEAN_CB: int +LANGUAGE_ENGLISH_CAYMAN_ISLANDS: int +LANGUAGE_ENGLISH_CHRISTMAS_ISLAND: int +LANGUAGE_ENGLISH_COCOS_KEELING_ISLANDS: int +LANGUAGE_ENGLISH_COOK_ISLANDS: int +LANGUAGE_ENGLISH_CYPRUS: int +LANGUAGE_ENGLISH_DENMARK: int +LANGUAGE_ENGLISH_DOMINICA: int +LANGUAGE_ENGLISH_EIRE: int +LANGUAGE_ENGLISH_ERITREA: int +LANGUAGE_ENGLISH_ESWATINI: int +LANGUAGE_ENGLISH_EUROPE: int +LANGUAGE_ENGLISH_FALKLAND_ISLANDS: int +LANGUAGE_ENGLISH_FIJI: int +LANGUAGE_ENGLISH_FINLAND: int +LANGUAGE_ENGLISH_GAMBIA: int +LANGUAGE_ENGLISH_GERMANY: int +LANGUAGE_ENGLISH_GHANA: int +LANGUAGE_ENGLISH_GIBRALTAR: int +LANGUAGE_ENGLISH_GRENADA: int +LANGUAGE_ENGLISH_GUAM: int +LANGUAGE_ENGLISH_GUERNSEY: int +LANGUAGE_ENGLISH_GUYANA: int +LANGUAGE_ENGLISH_HONG_KONG_SAR: int +LANGUAGE_ENGLISH_INDIA: int +LANGUAGE_ENGLISH_INDONESIA: int +LANGUAGE_ENGLISH_ISLE_OF_MAN: int +LANGUAGE_ENGLISH_ISRAEL: int +LANGUAGE_ENGLISH_JAMAICA: int +LANGUAGE_ENGLISH_JERSEY: int +LANGUAGE_ENGLISH_KENYA: int +LANGUAGE_ENGLISH_KIRIBATI: int +LANGUAGE_ENGLISH_LESOTHO: int +LANGUAGE_ENGLISH_LIBERIA: int +LANGUAGE_ENGLISH_MACAO_SAR: int +LANGUAGE_ENGLISH_MADAGASCAR: int +LANGUAGE_ENGLISH_MALAWI: int +LANGUAGE_ENGLISH_MALAYSIA: int +LANGUAGE_ENGLISH_MALTA: int +LANGUAGE_ENGLISH_MARSHALL_ISLANDS: int +LANGUAGE_ENGLISH_MAURITIUS: int +LANGUAGE_ENGLISH_MICRONESIA: int +LANGUAGE_ENGLISH_MONTSERRAT: int +LANGUAGE_ENGLISH_NAMIBIA: int +LANGUAGE_ENGLISH_NAURU: int +LANGUAGE_ENGLISH_NETHERLANDS: int +LANGUAGE_ENGLISH_NEW_ZEALAND: int +LANGUAGE_ENGLISH_NIGERIA: int +LANGUAGE_ENGLISH_NIUE: int +LANGUAGE_ENGLISH_NORFOLK_ISLAND: int +LANGUAGE_ENGLISH_NORTHERN_MARIANA_ISLANDS: int +LANGUAGE_ENGLISH_PAKISTAN: int +LANGUAGE_ENGLISH_PALAU: int +LANGUAGE_ENGLISH_PAPUA_NEW_GUINEA: int +LANGUAGE_ENGLISH_PHILIPPINES: int +LANGUAGE_ENGLISH_PITCAIRN_ISLANDS: int +LANGUAGE_ENGLISH_PUERTO_RICO: int +LANGUAGE_ENGLISH_RWANDA: int +LANGUAGE_ENGLISH_SAMOA: int +LANGUAGE_ENGLISH_SEYCHELLES: int +LANGUAGE_ENGLISH_SIERRA_LEONE: int +LANGUAGE_ENGLISH_SINGAPORE: int +LANGUAGE_ENGLISH_SINT_MAARTEN: int +LANGUAGE_ENGLISH_SLOVENIA: int +LANGUAGE_ENGLISH_SOLOMON_ISLANDS: int +LANGUAGE_ENGLISH_SOUTH_AFRICA: int +LANGUAGE_ENGLISH_SOUTH_SUDAN: int +LANGUAGE_ENGLISH_ST_HELENA_ASCENSION_TRISTAN_DA_CUNHA: int +LANGUAGE_ENGLISH_ST_KITTS_AND_NEVIS: int +LANGUAGE_ENGLISH_ST_LUCIA: int +LANGUAGE_ENGLISH_ST_VINCENT_AND_GRENADINES: int +LANGUAGE_ENGLISH_SUDAN: int +LANGUAGE_ENGLISH_SWEDEN: int +LANGUAGE_ENGLISH_SWITZERLAND: int +LANGUAGE_ENGLISH_TANZANIA: int +LANGUAGE_ENGLISH_TOKELAU: int +LANGUAGE_ENGLISH_TONGA: int +LANGUAGE_ENGLISH_TRINIDAD: int +LANGUAGE_ENGLISH_TURKS_AND_CAICOS_ISLANDS: int +LANGUAGE_ENGLISH_TUVALU: int +LANGUAGE_ENGLISH_UGANDA: int +LANGUAGE_ENGLISH_UK: int +LANGUAGE_ENGLISH_UNITED_ARAB_EMIRATES: int +LANGUAGE_ENGLISH_US: int +LANGUAGE_ENGLISH_US_OUTLYING_ISLANDS: int +LANGUAGE_ENGLISH_US_VIRGIN_ISLANDS: int +LANGUAGE_ENGLISH_VANUATU: int +LANGUAGE_ENGLISH_WORLD: int +LANGUAGE_ENGLISH_ZAMBIA: int +LANGUAGE_ENGLISH_ZIMBABWE: int +LANGUAGE_ESPERANTO: int +LANGUAGE_ESPERANTO_WORLD: int +LANGUAGE_ESTONIAN: int +LANGUAGE_ESTONIAN_ESTONIA: int +LANGUAGE_EWE: int +LANGUAGE_EWE_GHANA: int +LANGUAGE_EWE_TOGO: int +LANGUAGE_EWONDO: int +LANGUAGE_EWONDO_CAMEROON: int +LANGUAGE_FAEROESE: int +LANGUAGE_FAEROESE_DENMARK: int +LANGUAGE_FAEROESE_FAROE_ISLANDS: int +LANGUAGE_FARSI: int +LANGUAGE_FIJI: int +LANGUAGE_FILIPINO: int +LANGUAGE_FILIPINO_PHILIPPINES: int +LANGUAGE_FINNISH: int +LANGUAGE_FINNISH_FINLAND: int +LANGUAGE_FRENCH: int +LANGUAGE_FRENCH_ALGERIA: int +LANGUAGE_FRENCH_BELGIAN: int +LANGUAGE_FRENCH_BENIN: int +LANGUAGE_FRENCH_BURKINA_FASO: int +LANGUAGE_FRENCH_BURUNDI: int +LANGUAGE_FRENCH_CAMEROON: int +LANGUAGE_FRENCH_CANADIAN: int +LANGUAGE_FRENCH_CARIBBEAN: int +LANGUAGE_FRENCH_CENTRAL_AFRICAN_REPUBLIC: int +LANGUAGE_FRENCH_CHAD: int +LANGUAGE_FRENCH_COMOROS: int +LANGUAGE_FRENCH_CONGO: int +LANGUAGE_FRENCH_CONGO_DRC: int +LANGUAGE_FRENCH_COTE_DIVOIRE: int +LANGUAGE_FRENCH_DJIBOUTI: int +LANGUAGE_FRENCH_EQUATORIAL_GUINEA: int +LANGUAGE_FRENCH_FRANCE: int +LANGUAGE_FRENCH_FRENCH_GUIANA: int +LANGUAGE_FRENCH_FRENCH_POLYNESIA: int +LANGUAGE_FRENCH_GABON: int +LANGUAGE_FRENCH_GUADELOUPE: int +LANGUAGE_FRENCH_GUINEA: int +LANGUAGE_FRENCH_HAITI: int +LANGUAGE_FRENCH_LUXEMBOURG: int +LANGUAGE_FRENCH_MADAGASCAR: int +LANGUAGE_FRENCH_MALI: int +LANGUAGE_FRENCH_MARTINIQUE: int +LANGUAGE_FRENCH_MAURITANIA: int +LANGUAGE_FRENCH_MAURITIUS: int +LANGUAGE_FRENCH_MAYOTTE: int +LANGUAGE_FRENCH_MONACO: int +LANGUAGE_FRENCH_MOROCCO: int +LANGUAGE_FRENCH_NEW_CALEDONIA: int +LANGUAGE_FRENCH_NIGER: int +LANGUAGE_FRENCH_REUNION: int +LANGUAGE_FRENCH_RWANDA: int +LANGUAGE_FRENCH_SENEGAL: int +LANGUAGE_FRENCH_SEYCHELLES: int +LANGUAGE_FRENCH_ST_BARTHELEMY: int +LANGUAGE_FRENCH_ST_MARTIN: int +LANGUAGE_FRENCH_ST_PIERRE_AND_MIQUELON: int +LANGUAGE_FRENCH_SWISS: int +LANGUAGE_FRENCH_SYRIA: int +LANGUAGE_FRENCH_TOGO: int +LANGUAGE_FRENCH_TUNISIA: int +LANGUAGE_FRENCH_VANUATU: int +LANGUAGE_FRENCH_WALLIS_AND_FUTUNA: int +LANGUAGE_FRISIAN: int +LANGUAGE_FRISIAN_NETHERLANDS: int +LANGUAGE_FRIULIAN: int +LANGUAGE_FRIULIAN_ITALY: int +LANGUAGE_FULAH: int +LANGUAGE_FULAH_LATIN: int +LANGUAGE_FULAH_LATIN_BURKINA_FASO: int +LANGUAGE_FULAH_LATIN_CAMEROON: int +LANGUAGE_FULAH_LATIN_GAMBIA: int +LANGUAGE_FULAH_LATIN_GHANA: int +LANGUAGE_FULAH_LATIN_GUINEA: int +LANGUAGE_FULAH_LATIN_GUINEA_BISSAU: int +LANGUAGE_FULAH_LATIN_LIBERIA: int +LANGUAGE_FULAH_LATIN_MAURITANIA: int +LANGUAGE_FULAH_LATIN_NIGER: int +LANGUAGE_FULAH_LATIN_NIGERIA: int +LANGUAGE_FULAH_LATIN_SENEGAL: int +LANGUAGE_FULAH_LATIN_SIERRA_LEONE: int +LANGUAGE_GALICIAN: int +LANGUAGE_GALICIAN_SPAIN: int +LANGUAGE_GANDA: int +LANGUAGE_GANDA_UGANDA: int +LANGUAGE_GEORGIAN: int +LANGUAGE_GEORGIAN_GEORGIA: int +LANGUAGE_GERMAN: int +LANGUAGE_GERMAN_AUSTRIAN: int +LANGUAGE_GERMAN_BELGIUM: int +LANGUAGE_GERMAN_GERMANY: int +LANGUAGE_GERMAN_ITALY: int +LANGUAGE_GERMAN_LIECHTENSTEIN: int +LANGUAGE_GERMAN_LUXEMBOURG: int +LANGUAGE_GERMAN_SWISS: int +LANGUAGE_GREEK: int +LANGUAGE_GREEK_CYPRUS: int +LANGUAGE_GREEK_GREECE: int +LANGUAGE_GREENLANDIC: int +LANGUAGE_GUARANI: int +LANGUAGE_GUARANI_PARAGUAY: int +LANGUAGE_GUJARATI: int +LANGUAGE_GUJARATI_INDIA: int +LANGUAGE_GUSII: int +LANGUAGE_GUSII_KENYA: int +LANGUAGE_HAUSA: int +LANGUAGE_HAUSA_LATIN: int +LANGUAGE_HAUSA_LATIN_GHANA: int +LANGUAGE_HAUSA_LATIN_NIGER: int +LANGUAGE_HAUSA_LATIN_NIGERIA: int +LANGUAGE_HAWAIIAN: int +LANGUAGE_HAWAIIAN_US: int +LANGUAGE_HEBREW: int +LANGUAGE_HEBREW_ISRAEL: int +LANGUAGE_HINDI: int +LANGUAGE_HINDI_INDIA: int +LANGUAGE_HUNGARIAN: int +LANGUAGE_HUNGARIAN_HUNGARY: int +LANGUAGE_IBIBIO: int +LANGUAGE_IBIBIO_NIGERIA: int +LANGUAGE_ICELANDIC: int +LANGUAGE_ICELANDIC_ICELAND: int +LANGUAGE_IGBO: int +LANGUAGE_IGBO_NIGERIA: int +LANGUAGE_INDONESIAN: int +LANGUAGE_INDONESIAN_INDONESIA: int +LANGUAGE_INTERLINGUA: int +LANGUAGE_INTERLINGUA_WORLD: int +LANGUAGE_INTERLINGUE: int +LANGUAGE_INUKTITUT: int +LANGUAGE_INUKTITUT_LATIN: int +LANGUAGE_INUKTITUT_LATIN_CANADA: int +LANGUAGE_INUKTITUT_SYLLABICS: int +LANGUAGE_INUKTITUT_SYLLABICS_CANADA: int +LANGUAGE_INUPIAK: int +LANGUAGE_IRISH: int +LANGUAGE_IRISH_IRELAND: int +LANGUAGE_ITALIAN: int +LANGUAGE_ITALIAN_ITALY: int +LANGUAGE_ITALIAN_SAN_MARINO: int +LANGUAGE_ITALIAN_SWISS: int +LANGUAGE_ITALIAN_VATICAN_CITY: int +LANGUAGE_JAPANESE: int +LANGUAGE_JAPANESE_JAPAN: int +LANGUAGE_JAVANESE: int +LANGUAGE_JAVANESE_INDONESIA: int +LANGUAGE_JAVANESE_JAVANESE: int +LANGUAGE_JAVANESE_JAVANESE_INDONESIA: int +LANGUAGE_JOLA_FONYI: int +LANGUAGE_JOLA_FONYI_SENEGAL: int +LANGUAGE_KABUVERDIANU: int +LANGUAGE_KABUVERDIANU_CABO_VERDE: int +LANGUAGE_KABYLE: int +LANGUAGE_KABYLE_ALGERIA: int +LANGUAGE_KAKO: int +LANGUAGE_KAKO_CAMEROON: int +LANGUAGE_KALAALLISUT: int +LANGUAGE_KALENJIN: int +LANGUAGE_KALENJIN_KENYA: int +LANGUAGE_KAMBA: int +LANGUAGE_KAMBA_KENYA: int +LANGUAGE_KANNADA: int +LANGUAGE_KANNADA_INDIA: int +LANGUAGE_KANURI: int +LANGUAGE_KANURI_LATIN: int +LANGUAGE_KANURI_NIGERIA: int +LANGUAGE_KASHMIRI: int +LANGUAGE_KASHMIRI_DEVANAGARI: int +LANGUAGE_KASHMIRI_DEVANAGARI_INDIA: int +LANGUAGE_KASHMIRI_INDIA: int +LANGUAGE_KASHMIRI_PERSO_ARABIC: int +LANGUAGE_KASHMIRI_PERSO_ARABIC_INDIA: int +LANGUAGE_KAZAKH: int +LANGUAGE_KAZAKH_KAZAKHSTAN: int +LANGUAGE_KHMER: int +LANGUAGE_KHMER_CAMBODIA: int +LANGUAGE_KICHE: int +LANGUAGE_KICHE_GUATEMALA: int +LANGUAGE_KICHE_LATIN: int +LANGUAGE_KIKUYU: int +LANGUAGE_KIKUYU_KENYA: int +LANGUAGE_KINYARWANDA: int +LANGUAGE_KINYARWANDA_RWANDA: int +LANGUAGE_KIRGHIZ: int +LANGUAGE_KIRGHIZ_KYRGYZSTAN: int +LANGUAGE_KIRUNDI: int +LANGUAGE_KIRUNDI_BURUNDI: int +LANGUAGE_KONKANI: int +LANGUAGE_KONKANI_INDIA: int +LANGUAGE_KOREAN: int +LANGUAGE_KOREAN_KOREA: int +LANGUAGE_KOREAN_NORTH_KOREA: int +LANGUAGE_KOYRABORO_SENNI: int +LANGUAGE_KOYRABORO_SENNI_MALI: int +LANGUAGE_KOYRA_CHIINI: int +LANGUAGE_KOYRA_CHIINI_MALI: int +LANGUAGE_KURDISH: int +LANGUAGE_KURDISH_PERSO_ARABIC_IRAN: int +LANGUAGE_KWASIO: int +LANGUAGE_KWASIO_CAMEROON: int +LANGUAGE_LAKOTA: int +LANGUAGE_LAKOTA_US: int +LANGUAGE_LANGI: int +LANGUAGE_LANGI_TANZANIA: int +LANGUAGE_LAOTHIAN: int +LANGUAGE_LAOTHIAN_LAOS: int +LANGUAGE_LATIN: int +LANGUAGE_LATIN_WORLD: int +LANGUAGE_LATVIAN: int +LANGUAGE_LATVIAN_LATVIA: int +LANGUAGE_LINGALA: int +LANGUAGE_LINGALA_ANGOLA: int +LANGUAGE_LINGALA_CENTRAL_AFRICAN_REPUBLIC: int +LANGUAGE_LINGALA_CONGO: int +LANGUAGE_LINGALA_CONGO_DRC: int +LANGUAGE_LITHUANIAN: int +LANGUAGE_LITHUANIAN_LITHUANIA: int +LANGUAGE_LOWER_SORBIAN: int +LANGUAGE_LOWER_SORBIAN_GERMANY: int +LANGUAGE_LOW_GERMAN: int +LANGUAGE_LOW_GERMAN_GERMANY: int +LANGUAGE_LOW_GERMAN_NETHERLANDS: int +LANGUAGE_LUBA_KATANGA: int +LANGUAGE_LUBA_KATANGA_CONGO_DRC: int +LANGUAGE_LUO: int +LANGUAGE_LUO_KENYA: int +LANGUAGE_LUXEMBOURGISH: int +LANGUAGE_LUXEMBOURGISH_LUXEMBOURG: int +LANGUAGE_LUYIA: int +LANGUAGE_LUYIA_KENYA: int +LANGUAGE_MACEDONIAN: int +LANGUAGE_MACEDONIAN_NORTH_MACEDONIA: int +LANGUAGE_MACHAME: int +LANGUAGE_MACHAME_TANZANIA: int +LANGUAGE_MAKHUWA_MEETTO: int +LANGUAGE_MAKHUWA_MEETTO_MOZAMBIQUE: int +LANGUAGE_MAKONDE: int +LANGUAGE_MAKONDE_TANZANIA: int +LANGUAGE_MALAGASY: int +LANGUAGE_MALAGASY_MADAGASCAR: int +LANGUAGE_MALAY: int +LANGUAGE_MALAYALAM: int +LANGUAGE_MALAYALAM_INDIA: int +LANGUAGE_MALAY_BRUNEI: int +LANGUAGE_MALAY_MALAYSIA: int +LANGUAGE_MALAY_SINGAPORE: int +LANGUAGE_MALTESE: int +LANGUAGE_MALTESE_MALTA: int +LANGUAGE_MANIPURI: int +LANGUAGE_MANIPURI_INDIA: int +LANGUAGE_MANX: int +LANGUAGE_MANX_ISLE_OF_MAN: int +LANGUAGE_MAORI: int +LANGUAGE_MAORI_NEW_ZEALAND: int +LANGUAGE_MAPUCHE: int +LANGUAGE_MAPUCHE_CHILE: int +LANGUAGE_MARATHI: int +LANGUAGE_MARATHI_INDIA: int +LANGUAGE_MASAI: int +LANGUAGE_MASAI_KENYA: int +LANGUAGE_MASAI_TANZANIA: int +LANGUAGE_MAZANDERANI: int +LANGUAGE_MAZANDERANI_IRAN: int +LANGUAGE_MERU: int +LANGUAGE_MERU_KENYA: int +LANGUAGE_META: int +LANGUAGE_META_CAMEROON: int +LANGUAGE_MOHAWK: int +LANGUAGE_MOHAWK_CANADA: int +LANGUAGE_MOLDAVIAN: int +LANGUAGE_MONGOLIAN: int +LANGUAGE_MONGOLIAN_CYRILLIC: int +LANGUAGE_MONGOLIAN_MONGOLIA: int +LANGUAGE_MONGOLIAN_TRADITIONAL: int +LANGUAGE_MONGOLIAN_TRADITIONAL_CHINA: int +LANGUAGE_MONGOLIAN_TRADITIONAL_MONGOLIA: int +LANGUAGE_MORISYEN: int +LANGUAGE_MORISYEN_MAURITIUS: int +LANGUAGE_MUNDANG: int +LANGUAGE_MUNDANG_CAMEROON: int +LANGUAGE_NAMA: int +LANGUAGE_NAMA_NAMIBIA: int +LANGUAGE_NAURU: int +LANGUAGE_NEPALI: int +LANGUAGE_NEPALI_INDIA: int +LANGUAGE_NEPALI_NEPAL: int +LANGUAGE_NGIEMBOON: int +LANGUAGE_NGIEMBOON_CAMEROON: int +LANGUAGE_NGOMBA: int +LANGUAGE_NGOMBA_CAMEROON: int +LANGUAGE_NKO: int +LANGUAGE_NKO_GUINEA: int +LANGUAGE_NORTHERN_LURI: int +LANGUAGE_NORTHERN_LURI_IRAN: int +LANGUAGE_NORTHERN_LURI_IRAQ: int +LANGUAGE_NORTH_NDEBELE: int +LANGUAGE_NORTH_NDEBELE_ZIMBABWE: int +LANGUAGE_NORWEGIAN: int +LANGUAGE_NORWEGIAN_BOKMAL: int +LANGUAGE_NORWEGIAN_BOKMAL_NORWAY: int +LANGUAGE_NORWEGIAN_BOKMAL_SVALBARD_AND_JAN_MAYEN: int +LANGUAGE_NORWEGIAN_NYNORSK: int +LANGUAGE_NORWEGIAN_NYNORSK_NORWAY: int +LANGUAGE_NUER: int +LANGUAGE_NUER_SOUTH_SUDAN: int +LANGUAGE_NYANKOLE: int +LANGUAGE_NYANKOLE_UGANDA: int +LANGUAGE_OCCITAN: int +LANGUAGE_OCCITAN_FRANCE: int +LANGUAGE_ODIA: int +LANGUAGE_ODIA_INDIA: int +LANGUAGE_OROMO: int +LANGUAGE_OROMO_ETHIOPIA: int +LANGUAGE_OROMO_KENYA: int +LANGUAGE_OSSETIC: int +LANGUAGE_OSSETIC_GEORGIA: int +LANGUAGE_OSSETIC_RUSSIA: int +LANGUAGE_PAPIAMENTO: int +LANGUAGE_PAPIAMENTO_CARIBBEAN: int +LANGUAGE_PASHTO: int +LANGUAGE_PASHTO_AFGHANISTAN: int +LANGUAGE_PASHTO_PAKISTAN: int +LANGUAGE_PERSIAN_IRAN: int +LANGUAGE_POLISH: int +LANGUAGE_POLISH_POLAND: int +LANGUAGE_PORTUGUESE: int +LANGUAGE_PORTUGUESE_ANGOLA: int +LANGUAGE_PORTUGUESE_BRAZILIAN: int +LANGUAGE_PORTUGUESE_CABO_VERDE: int +LANGUAGE_PORTUGUESE_EQUATORIAL_GUINEA: int +LANGUAGE_PORTUGUESE_GUINEA_BISSAU: int +LANGUAGE_PORTUGUESE_LUXEMBOURG: int +LANGUAGE_PORTUGUESE_MACAO_SAR: int +LANGUAGE_PORTUGUESE_MOZAMBIQUE: int +LANGUAGE_PORTUGUESE_PORTUGAL: int +LANGUAGE_PORTUGUESE_SAO_TOME_AND_PRINCIPE: int +LANGUAGE_PORTUGUESE_SWITZERLAND: int +LANGUAGE_PORTUGUESE_TIMOR_LESTE: int +LANGUAGE_PRUSSIAN: int +LANGUAGE_PRUSSIAN_WORLD: int +LANGUAGE_PUNJABI: int +LANGUAGE_PUNJABI_ARABIC: int +LANGUAGE_PUNJABI_GURMUKHI: int +LANGUAGE_PUNJABI_INDIA: int +LANGUAGE_PUNJABI_PAKISTAN: int +LANGUAGE_QUECHUA: int +LANGUAGE_QUECHUA_BOLIVIA: int +LANGUAGE_QUECHUA_ECUADOR: int +LANGUAGE_QUECHUA_MACRO: int +LANGUAGE_QUECHUA_PERU: int +LANGUAGE_RHAETO_ROMANCE: int +LANGUAGE_RHAETO_ROMANCE_SWITZERLAND: int +LANGUAGE_ROMANIAN: int +LANGUAGE_ROMANIAN_MOLDOVA: int +LANGUAGE_ROMANIAN_ROMANIA: int +LANGUAGE_ROMBO: int +LANGUAGE_ROMBO_TANZANIA: int +LANGUAGE_RUSSIAN: int +LANGUAGE_RUSSIAN_BELARUS: int +LANGUAGE_RUSSIAN_KAZAKHSTAN: int +LANGUAGE_RUSSIAN_KYRGYZSTAN: int +LANGUAGE_RUSSIAN_MOLDOVA: int +LANGUAGE_RUSSIAN_RUSSIA: int +LANGUAGE_RUSSIAN_UKRAINE: int +LANGUAGE_RWA: int +LANGUAGE_RWA_TANZANIA: int +LANGUAGE_SAHO: int +LANGUAGE_SAHO_ERITREA: int +LANGUAGE_SAKHA: int +LANGUAGE_SAKHA_RUSSIA: int +LANGUAGE_SAMBURU: int +LANGUAGE_SAMBURU_KENYA: int +LANGUAGE_SAMI: int +LANGUAGE_SAMI_FINLAND: int +LANGUAGE_SAMI_INARI: int +LANGUAGE_SAMI_INARI_FINLAND: int +LANGUAGE_SAMI_LULE: int +LANGUAGE_SAMI_LULE_NORWAY: int +LANGUAGE_SAMI_LULE_SWEDEN: int +LANGUAGE_SAMI_NORWAY: int +LANGUAGE_SAMI_SKOLT: int +LANGUAGE_SAMI_SKOLT_FINLAND: int +LANGUAGE_SAMI_SOUTHERN: int +LANGUAGE_SAMI_SOUTHERN_NORWAY: int +LANGUAGE_SAMI_SOUTHERN_SWEDEN: int +LANGUAGE_SAMI_SWEDEN: int +LANGUAGE_SAMOAN: int +LANGUAGE_SANGHO: int +LANGUAGE_SANGHO_CENTRAL_AFRICAN_REPUBLIC: int +LANGUAGE_SANGU: int +LANGUAGE_SANGU_TANZANIA: int +LANGUAGE_SANSKRIT: int +LANGUAGE_SANSKRIT_INDIA: int +LANGUAGE_SCOTS_GAELIC: int +LANGUAGE_SCOTS_GAELIC_UK: int +LANGUAGE_SENA: int +LANGUAGE_SENA_MOZAMBIQUE: int +LANGUAGE_SERBIAN: int +LANGUAGE_SERBIAN_CYRILLIC: int +LANGUAGE_SERBIAN_CYRILLIC_BOSNIA_AND_HERZEGOVINA: int +LANGUAGE_SERBIAN_CYRILLIC_KOSOVO: int +LANGUAGE_SERBIAN_CYRILLIC_MONTENEGRO: int +LANGUAGE_SERBIAN_CYRILLIC_SERBIA: int +LANGUAGE_SERBIAN_CYRILLIC_YU: int +LANGUAGE_SERBIAN_LATIN: int +LANGUAGE_SERBIAN_LATIN_BOSNIA_AND_HERZEGOVINA: int +LANGUAGE_SERBIAN_LATIN_KOSOVO: int +LANGUAGE_SERBIAN_LATIN_MONTENEGRO: int +LANGUAGE_SERBIAN_LATIN_SERBIA: int +LANGUAGE_SERBIAN_LATIN_YU: int +LANGUAGE_SERBIAN_SERBIA: int +LANGUAGE_SERBIAN_YU: int +LANGUAGE_SERBO_CROATIAN: int +LANGUAGE_SESOTHO: int +LANGUAGE_SESOTHO_LESOTHO: int +LANGUAGE_SESOTHO_SA_LEBOA: int +LANGUAGE_SESOTHO_SA_LEBOA_SOUTH_AFRICA: int +LANGUAGE_SESOTHO_SOUTH_AFRICA: int +LANGUAGE_SETSWANA: int +LANGUAGE_SETSWANA_BOTSWANA: int +LANGUAGE_SETSWANA_SOUTH_AFRICA: int +LANGUAGE_SHAMBALA: int +LANGUAGE_SHAMBALA_TANZANIA: int +LANGUAGE_SHONA: int +LANGUAGE_SHONA_LATIN: int +LANGUAGE_SHONA_LATIN_ZIMBABWE: int +LANGUAGE_SINDHI: int +LANGUAGE_SINDHI_ARABIC: int +LANGUAGE_SINDHI_DEVANAGARI: int +LANGUAGE_SINDHI_DEVANAGARI_INDIA: int +LANGUAGE_SINDHI_PAKISTAN: int +LANGUAGE_SINHALESE: int +LANGUAGE_SINHALESE_SRI_LANKA: int +LANGUAGE_SISWATI: int +LANGUAGE_SISWATI_ESWATINI: int +LANGUAGE_SISWATI_SOUTH_AFRICA: int +LANGUAGE_SLOVAK: int +LANGUAGE_SLOVAK_SLOVAKIA: int +LANGUAGE_SLOVENIAN: int +LANGUAGE_SLOVENIAN_SLOVENIA: int +LANGUAGE_SOGA: int +LANGUAGE_SOGA_UGANDA: int +LANGUAGE_SOMALI: int +LANGUAGE_SOMALI_DJIBOUTI: int +LANGUAGE_SOMALI_ETHIOPIA: int +LANGUAGE_SOMALI_KENYA: int +LANGUAGE_SOMALI_SOMALIA: int +LANGUAGE_SOUTH_NDEBELE: int +LANGUAGE_SOUTH_NDEBELE_SOUTH_AFRICA: int +LANGUAGE_SPANISH: int +LANGUAGE_SPANISH_ARGENTINA: int +LANGUAGE_SPANISH_BELIZE: int +LANGUAGE_SPANISH_BOLIVIA: int +LANGUAGE_SPANISH_BRAZIL: int +LANGUAGE_SPANISH_CHILE: int +LANGUAGE_SPANISH_COLOMBIA: int +LANGUAGE_SPANISH_COSTA_RICA: int +LANGUAGE_SPANISH_CUBA: int +LANGUAGE_SPANISH_DOMINICAN_REPUBLIC: int +LANGUAGE_SPANISH_ECUADOR: int +LANGUAGE_SPANISH_EL_SALVADOR: int +LANGUAGE_SPANISH_EQUATORIAL_GUINEA: int +LANGUAGE_SPANISH_GUATEMALA: int +LANGUAGE_SPANISH_HONDURAS: int +LANGUAGE_SPANISH_LATIN_AMERICA: int +LANGUAGE_SPANISH_MEXICAN: int +LANGUAGE_SPANISH_NICARAGUA: int +LANGUAGE_SPANISH_PANAMA: int +LANGUAGE_SPANISH_PARAGUAY: int +LANGUAGE_SPANISH_PERU: int +LANGUAGE_SPANISH_PHILIPPINES: int +LANGUAGE_SPANISH_PUERTO_RICO: int +LANGUAGE_SPANISH_SPAIN: int +LANGUAGE_SPANISH_URUGUAY: int +LANGUAGE_SPANISH_US: int +LANGUAGE_SPANISH_VENEZUELA: int +LANGUAGE_STANDARD_MOROCCAN_TAMAZIGHT: int +LANGUAGE_STANDARD_MOROCCAN_TAMAZIGHT_TIFINAGH: int +LANGUAGE_STANDARD_MOROCCAN_TAMAZIGHT_TIFINAGH_MOROCCO: int +LANGUAGE_SUNDANESE: int +LANGUAGE_SWAHILI: int +LANGUAGE_SWAHILI_CONGO_DRC: int +LANGUAGE_SWAHILI_KENYA: int +LANGUAGE_SWAHILI_TANZANIA: int +LANGUAGE_SWAHILI_UGANDA: int +LANGUAGE_SWEDISH: int +LANGUAGE_SWEDISH_ALAND_ISLANDS: int +LANGUAGE_SWEDISH_FINLAND: int +LANGUAGE_SWEDISH_SWEDEN: int +LANGUAGE_SWISS_GERMAN: int +LANGUAGE_SWISS_GERMAN_LIECHTENSTEIN: int +LANGUAGE_SWISS_GERMAN_SWITZERLAND: int +LANGUAGE_SYRIAC: int +LANGUAGE_SYRIAC_SYRIA: int +LANGUAGE_TACHELHIT: int +LANGUAGE_TACHELHIT_LATIN: int +LANGUAGE_TACHELHIT_LATIN_MOROCCO: int +LANGUAGE_TACHELHIT_TIFINAGH: int +LANGUAGE_TACHELHIT_TIFINAGH_MOROCCO: int +LANGUAGE_TAGALOG: int +LANGUAGE_TAITA: int +LANGUAGE_TAITA_KENYA: int +LANGUAGE_TAJIK: int +LANGUAGE_TAJIK_CYRILLIC: int +LANGUAGE_TAJIK_CYRILLIC_TAJIKISTAN: int +LANGUAGE_TAMIL: int +LANGUAGE_TAMIL_INDIA: int +LANGUAGE_TAMIL_MALAYSIA: int +LANGUAGE_TAMIL_SINGAPORE: int +LANGUAGE_TAMIL_SRI_LANKA: int +LANGUAGE_TASAWAQ: int +LANGUAGE_TASAWAQ_NIGER: int +LANGUAGE_TATAR: int +LANGUAGE_TATAR_RUSSIA: int +LANGUAGE_TELUGU: int +LANGUAGE_TELUGU_INDIA: int +LANGUAGE_TESO: int +LANGUAGE_TESO_KENYA: int +LANGUAGE_TESO_UGANDA: int +LANGUAGE_THAI: int +LANGUAGE_THAI_THAILAND: int +LANGUAGE_TIBETAN: int +LANGUAGE_TIBETAN_CHINA: int +LANGUAGE_TIBETAN_INDIA: int +LANGUAGE_TIGRE: int +LANGUAGE_TIGRE_ERITREA: int +LANGUAGE_TIGRINYA: int +LANGUAGE_TIGRINYA_ERITREA: int +LANGUAGE_TIGRINYA_ETHIOPIA: int +LANGUAGE_TONGA: int +LANGUAGE_TONGA_TONGA: int +LANGUAGE_TSONGA: int +LANGUAGE_TSONGA_SOUTH_AFRICA: int +LANGUAGE_TURKISH: int +LANGUAGE_TURKISH_CYPRUS: int +LANGUAGE_TURKISH_TURKEY: int +LANGUAGE_TURKMEN: int +LANGUAGE_TURKMEN_TURKMENISTAN: int +LANGUAGE_TWI: int +LANGUAGE_UIGHUR: int +LANGUAGE_UIGHUR_CHINA: int +LANGUAGE_UKRAINIAN: int +LANGUAGE_UKRAINIAN_UKRAINE: int +LANGUAGE_UPPER_SORBIAN: int +LANGUAGE_UPPER_SORBIAN_GERMANY: int +LANGUAGE_URDU: int +LANGUAGE_URDU_INDIA: int +LANGUAGE_URDU_PAKISTAN: int +LANGUAGE_UZBEK: int +LANGUAGE_UZBEK_CYRILLIC: int +LANGUAGE_UZBEK_CYRILLIC_UZBEKISTAN: int +LANGUAGE_UZBEK_LATIN: int +LANGUAGE_UZBEK_LATIN_UZBEKISTAN: int +LANGUAGE_UZBEK_PERSO_ARABIC: int +LANGUAGE_UZBEK_PERSO_ARABIC_AFGHANISTAN: int +LANGUAGE_VAI: int +LANGUAGE_VAI_LATIN: int +LANGUAGE_VAI_LATIN_LIBERIA: int +LANGUAGE_VAI_VAI: int +LANGUAGE_VAI_VAI_LIBERIA: int +LANGUAGE_VALENCIAN: int +LANGUAGE_VENDA: int +LANGUAGE_VENDA_SOUTH_AFRICA: int +LANGUAGE_VIETNAMESE: int +LANGUAGE_VIETNAMESE_VIETNAM: int +LANGUAGE_VOLAPUK: int +LANGUAGE_VOLAPUK_WORLD: int +LANGUAGE_VUNJO: int +LANGUAGE_VUNJO_TANZANIA: int +LANGUAGE_WALSER: int +LANGUAGE_WALSER_SWITZERLAND: int +LANGUAGE_WELSH: int +LANGUAGE_WELSH_UK: int +LANGUAGE_WOLAYTTA: int +LANGUAGE_WOLAYTTA_ETHIOPIA: int +LANGUAGE_WOLOF: int +LANGUAGE_WOLOF_SENEGAL: int +LANGUAGE_XHOSA: int +LANGUAGE_XHOSA_SOUTH_AFRICA: int +LANGUAGE_YANGBEN: int +LANGUAGE_YANGBEN_CAMEROON: int +LANGUAGE_YI: int +LANGUAGE_YIDDISH: int +LANGUAGE_YIDDISH_WORLD: int +LANGUAGE_YI_CHINA: int +LANGUAGE_YORUBA: int +LANGUAGE_YORUBA_BENIN: int +LANGUAGE_YORUBA_NIGERIA: int +LANGUAGE_ZARMA: int +LANGUAGE_ZARMA_NIGER: int +LANGUAGE_ZHUANG: int +LANGUAGE_ZULU: int +LANGUAGE_ZULU_SOUTH_AFRICA: int +LANGUAGE_USER_DEFINED: int +LANGUAGE_AZERI: int +LANGUAGE_AZERI_CYRILLIC: int +LANGUAGE_AZERI_LATIN: int +LANGUAGE_BENGALI: int +LANGUAGE_BENGALI_BANGLADESH: int +LANGUAGE_BENGALI_INDIA: int +LANGUAGE_BHUTANI: int +LANGUAGE_CHINESE_SIMPLIFIED: int +LANGUAGE_CHINESE_TRADITIONAL: int +LANGUAGE_CHINESE_MACAU: int +LANGUAGE_KERNEWEK: int +LANGUAGE_MALAY_BRUNEI_DARUSSALAM: int +LANGUAGE_ORIYA: int +LANGUAGE_ORIYA_INDIA: int +LANGUAGE_SPANISH_MODERN: int +LANGUAGE_CAMBODIAN: int +Layout_Default: int +Layout_LeftToRight: int +Layout_RightToLeft: int +LOCALE_TAGTYPE_DEFAULT: int +LOCALE_TAGTYPE_SYSTEM: int +LOCALE_TAGTYPE_BCP47: int +LOCALE_TAGTYPE_MACOS: int +LOCALE_TAGTYPE_POSIX: int +LOCALE_TAGTYPE_WINDOWS: int +LOCALE_CAT_NUMBER: int +LOCALE_CAT_DATE: int +LOCALE_CAT_MONEY: int +LOCALE_CAT_DEFAULT: int +LOCALE_THOUSANDS_SEP: int +LOCALE_DECIMAL_POINT: int +LOCALE_SHORT_DATE_FMT: int +LOCALE_LONG_DATE_FMT: int +LOCALE_DATE_TIME_FMT: int +LOCALE_TIME_FMT: int +LOCALE_NAME_LOCALE: int +LOCALE_NAME_LANGUAGE: int +LOCALE_NAME_COUNTRY: int +LOCALE_FORM_NATIVE: int +LOCALE_FORM_ENGLISH: int +LOCALE_DONT_LOAD_DEFAULT: int +LOCALE_LOAD_DEFAULT: int class LanguageInfo: """ @@ -5097,21 +5114,21 @@ def GetTranslation(*args, **kw): # -- end-translation --# # -- begin-cmndata --# -PRINTBIN_DEFAULT = 0 -PRINTBIN_ONLYONE = 0 -PRINTBIN_LOWER = 0 -PRINTBIN_MIDDLE = 0 -PRINTBIN_MANUAL = 0 -PRINTBIN_ENVELOPE = 0 -PRINTBIN_ENVMANUAL = 0 -PRINTBIN_AUTO = 0 -PRINTBIN_TRACTOR = 0 -PRINTBIN_SMALLFMT = 0 -PRINTBIN_LARGEFMT = 0 -PRINTBIN_LARGECAPACITY = 0 -PRINTBIN_CASSETTE = 0 -PRINTBIN_FORMSOURCE = 0 -PRINTBIN_USER = 0 +PRINTBIN_DEFAULT: int +PRINTBIN_ONLYONE: int +PRINTBIN_LOWER: int +PRINTBIN_MIDDLE: int +PRINTBIN_MANUAL: int +PRINTBIN_ENVELOPE: int +PRINTBIN_ENVMANUAL: int +PRINTBIN_AUTO: int +PRINTBIN_TRACTOR: int +PRINTBIN_SMALLFMT: int +PRINTBIN_LARGEFMT: int +PRINTBIN_LARGECAPACITY: int +PRINTBIN_CASSETTE: int +PRINTBIN_FORMSOURCE: int +PRINTBIN_USER: int class PageSetupDialogData(Object): """ @@ -5799,69 +5816,69 @@ class PrintDialogData(Object): # -- end-cmndata --# # -- begin-gdicmn --# -BITMAP_TYPE_INVALID = 0 -BITMAP_TYPE_BMP = 0 -BITMAP_TYPE_ICO = 0 -BITMAP_TYPE_CUR = 0 -BITMAP_TYPE_XBM = 0 -BITMAP_TYPE_XBM_DATA = 0 -BITMAP_TYPE_XPM = 0 -BITMAP_TYPE_XPM_DATA = 0 -BITMAP_TYPE_TIFF = 0 -BITMAP_TYPE_TIF = 0 -BITMAP_TYPE_GIF = 0 -BITMAP_TYPE_PNG = 0 -BITMAP_TYPE_JPEG = 0 -BITMAP_TYPE_PNM = 0 -BITMAP_TYPE_PCX = 0 -BITMAP_TYPE_PICT = 0 -BITMAP_TYPE_ICON = 0 -BITMAP_TYPE_ANI = 0 -BITMAP_TYPE_IFF = 0 -BITMAP_TYPE_TGA = 0 -BITMAP_TYPE_MACCURSOR = 0 -BITMAP_TYPE_ANY = 0 -ODDEVEN_RULE = 0 -WINDING_RULE = 0 -CURSOR_NONE = 0 -CURSOR_ARROW = 0 -CURSOR_RIGHT_ARROW = 0 -CURSOR_BULLSEYE = 0 -CURSOR_CHAR = 0 -CURSOR_CROSS = 0 -CURSOR_HAND = 0 -CURSOR_IBEAM = 0 -CURSOR_LEFT_BUTTON = 0 -CURSOR_MAGNIFIER = 0 -CURSOR_MIDDLE_BUTTON = 0 -CURSOR_NO_ENTRY = 0 -CURSOR_PAINT_BRUSH = 0 -CURSOR_PENCIL = 0 -CURSOR_POINT_LEFT = 0 -CURSOR_POINT_RIGHT = 0 -CURSOR_QUESTION_ARROW = 0 -CURSOR_RIGHT_BUTTON = 0 -CURSOR_SIZENESW = 0 -CURSOR_SIZENS = 0 -CURSOR_SIZENWSE = 0 -CURSOR_SIZEWE = 0 -CURSOR_SIZING = 0 -CURSOR_SPRAYCAN = 0 -CURSOR_WAIT = 0 -CURSOR_WATCH = 0 -CURSOR_BLANK = 0 -CURSOR_DEFAULT = 0 -CURSOR_COPY_ARROW = 0 -CURSOR_ARROWWAIT = 0 -CURSOR_MAX = 0 -ELLIPSIZE_FLAGS_NONE = 0 -ELLIPSIZE_FLAGS_PROCESS_MNEMONICS = 0 -ELLIPSIZE_FLAGS_EXPAND_TABS = 0 -ELLIPSIZE_FLAGS_DEFAULT = 0 -ELLIPSIZE_NONE = 0 -ELLIPSIZE_START = 0 -ELLIPSIZE_MIDDLE = 0 -ELLIPSIZE_END = 0 +BITMAP_TYPE_INVALID: int +BITMAP_TYPE_BMP: int +BITMAP_TYPE_ICO: int +BITMAP_TYPE_CUR: int +BITMAP_TYPE_XBM: int +BITMAP_TYPE_XBM_DATA: int +BITMAP_TYPE_XPM: int +BITMAP_TYPE_XPM_DATA: int +BITMAP_TYPE_TIFF: int +BITMAP_TYPE_TIF: int +BITMAP_TYPE_GIF: int +BITMAP_TYPE_PNG: int +BITMAP_TYPE_JPEG: int +BITMAP_TYPE_PNM: int +BITMAP_TYPE_PCX: int +BITMAP_TYPE_PICT: int +BITMAP_TYPE_ICON: int +BITMAP_TYPE_ANI: int +BITMAP_TYPE_IFF: int +BITMAP_TYPE_TGA: int +BITMAP_TYPE_MACCURSOR: int +BITMAP_TYPE_ANY: int +ODDEVEN_RULE: int +WINDING_RULE: int +CURSOR_NONE: int +CURSOR_ARROW: int +CURSOR_RIGHT_ARROW: int +CURSOR_BULLSEYE: int +CURSOR_CHAR: int +CURSOR_CROSS: int +CURSOR_HAND: int +CURSOR_IBEAM: int +CURSOR_LEFT_BUTTON: int +CURSOR_MAGNIFIER: int +CURSOR_MIDDLE_BUTTON: int +CURSOR_NO_ENTRY: int +CURSOR_PAINT_BRUSH: int +CURSOR_PENCIL: int +CURSOR_POINT_LEFT: int +CURSOR_POINT_RIGHT: int +CURSOR_QUESTION_ARROW: int +CURSOR_RIGHT_BUTTON: int +CURSOR_SIZENESW: int +CURSOR_SIZENS: int +CURSOR_SIZENWSE: int +CURSOR_SIZEWE: int +CURSOR_SIZING: int +CURSOR_SPRAYCAN: int +CURSOR_WAIT: int +CURSOR_WATCH: int +CURSOR_BLANK: int +CURSOR_DEFAULT: int +CURSOR_COPY_ARROW: int +CURSOR_ARROWWAIT: INT8_MIN +CURSOR_MAX: int +ELLIPSIZE_FLAGS_NONE: int +ELLIPSIZE_FLAGS_PROCESS_MNEMONICS: int +ELLIPSIZE_FLAGS_EXPAND_TABS: int +ELLIPSIZE_FLAGS_DEFAULT: int +ELLIPSIZE_NONE: int +ELLIPSIZE_START: int +ELLIPSIZE_MIDDLE: int +ELLIPSIZE_END: int class Point: """ @@ -5892,7 +5909,7 @@ class Point: def __isub__(self, *args, **kw): """ """ - def IsFullySpecified(self): + def IsFullySpecified(self) -> bool: """ IsFullySpecified() -> bool @@ -5900,15 +5917,15 @@ class Point: wxDefaultCoord. """ - def SetDefaults(self, pt): + def SetDefaults(self, pt: Point) -> None: """ SetDefaults(pt) Combine this object with another one replacing the uninitialized values. """ - x = property(None, None) - y = property(None, None) + x: int + y: int def __eq__(self, other): """ @@ -5920,14 +5937,14 @@ class Point: __ne__(other) -> bool """ - def Get(self): + def Get(self) -> tuple[int, int]: """ Get() -> (x,y) Return the x and y properties as a tuple. """ - def GetIM(self): + def GetIM(self) -> _im_Point: """ Returns an immutable representation of the ``wx.Point`` object, based on ``namedtuple``. @@ -5936,10 +5953,10 @@ class Point: with a simple statement like this: ``obj = wx.Point(imObj)``. """ - def __str__(self): + def __str__(self) -> str: """ """ - def __repr__(self): + def __repr__(self) -> str: """ """ def __len__(self) -> int: ... @@ -5956,7 +5973,7 @@ class Point: """ """ __safe_for_unpickling__ = True - IM = property(None, None) + IM: _im_Point # end of class Point @@ -5967,16 +5984,18 @@ class Size: A wxSize is a useful data structure for graphics operations. """ - - def __init__(self, *args, **kw): + @overload + def __init__(self) -> None: """ Size() Size(width, height) A wxSize is a useful data structure for graphics operations. """ - - def DecBy(self, *args, **kw): + @overload + def __init__(self, width: int, height: int) -> None: ... + @overload + def DecBy(self, pt: Point) -> None: """ DecBy(pt) DecBy(size) @@ -5985,8 +6004,14 @@ class Size: Decreases the size in both x and y directions. """ - - def IncBy(self, *args, **kw): + @overload + def DecBy(self, size: Size) -> None: ... + @overload + def DecBy(self, dx: int, dy: int) -> None: ... + @overload + def DecBy(self, d: int) -> None: ... + @overload + def IncBy(self, pt: Point) -> None: """ IncBy(pt) IncBy(size) @@ -5995,7 +6020,12 @@ class Size: Increases the size in both x and y directions. """ - + @overload + def IncBy(self, size: Size) -> None: ... + @overload + def IncBy(self, dx: int, dy: int) -> None: ... + @overload + def IncBy(self, d: int) -> None: ... def __iadd__(self): """ """ @@ -6008,7 +6038,7 @@ class Size: def __imul__(self): """ """ - def DecTo(self, size): + def DecTo(self, size: Size) -> None: """ DecTo(size) @@ -6016,7 +6046,7 @@ class Size: than the corresponding dimensions of the size. """ - def DecToIfSpecified(self, size): + def DecToIfSpecified(self, size: Size) -> None: """ DecToIfSpecified(size) @@ -6774,11 +6804,11 @@ def IntersectRect(self, r1, r2): # -- end-gdicmn --# # -- begin-geometry --# -Inside = 0 -OutLeft = 0 -OutRight = 0 -OutTop = 0 -OutBottom = 0 +Inside: int +OutLeft: int +OutRight: int +OutTop: int +OutBottom: int class Point2D: """ @@ -7596,11 +7626,11 @@ _im_Position = namedtuple("_im_Position", ["Row", "Col"]) del namedtuple # -- end-position --# # -- begin-colour --# -C2S_NAME = 0 -C2S_CSS_SYNTAX = 0 -C2S_HTML_SYNTAX = 0 -ALPHA_TRANSPARENT = 0 -ALPHA_OPAQUE = 0 +C2S_NAME: int +C2S_CSS_SYNTAX: int +C2S_HTML_SYNTAX: int +ALPHA_TRANSPARENT: int +ALPHA_OPAQUE: int class Colour(Object): """ @@ -7613,8 +7643,8 @@ class Colour(Object): Blue (RGB) intensity values and an Alpha value, and is used to determine drawing colours. """ - - def __init__(self, *args, **kw): + @overload + def __init__(self): """ Colour() Colour(red, green, blue, alpha=ALPHA_OPAQUE) @@ -7625,9 +7655,14 @@ class Colour(Object): Blue (RGB) intensity values and an Alpha value, and is used to determine drawing colours. """ - + @overload + def __init__(self, red: int, green: int, blue: int, alpha: int = ALPHA_OPAQUE): ... + @overload + def __init__(self, colRGB: int): ... + @overload + def __init__(self, colour: ColourType): ... def SetRGB(self, colRGB): - """ + """d SetRGB(colRGB) Sets the RGB or RGBA colour values from a single 32 bit value. @@ -7814,15 +7849,18 @@ class Colour(Object): For internal use only. """ - - def Get(self, includeAlpha=True): + @overload + def Get(self, includeAlpha: Literal[False]) -> tuple[int, int, int]: ... + @overload + def Get(self, includeAlpha: Literal[True] = True) -> tuple[int, int, int, int]: ... + @overload + def Get(self, includeAlpha: bool = True) -> tuple[int, int, int] | tuple[int, int, int, int]: """ Get(includeAlpha=True) -> (r,g,b) or (r,g,b,a) Returns the RGB intensity values as a tuple, optionally the alpha value as well. """ - def GetIM(self): """ Returns an immutable representation of the ``wx.Colour`` object, based on ``namedtuple``. @@ -7890,13 +7928,13 @@ del namedtuple NamedColour = wx.deprecated(Colour, "Use Colour instead.") # -- end-colour --# # -- begin-stream --# -STREAM_NO_ERROR = 0 -STREAM_EOF = 0 -STREAM_WRITE_ERROR = 0 -STREAM_READ_ERROR = 0 -FromStart = 0 -FromCurrent = 0 -FromEnd = 0 +STREAM_NO_ERROR: int +STREAM_EOF: int +STREAM_WRITE_ERROR: int +STREAM_READ_ERROR: int +FromStart: int +FromCurrent: int +FromEnd: int class StreamBase: """ @@ -8200,8 +8238,8 @@ class OutputStream(StreamBase): # -- end-stream --# # -- begin-filesys --# -FS_READ = 0 -FS_SEEKABLE = 0 +FS_READ: int +FS_SEEKABLE: int class FileSystem(Object): """ @@ -8563,33 +8601,33 @@ class InternetFSHandler(FileSystemHandler): ZipFSHandler = wx.deprecated(ArchiveFSHandler, "Use ArchiveFSHandler instead.") # -- end-filesys --# # -- begin-image --# -IMAGE_RESOLUTION_NONE = 0 -IMAGE_RESOLUTION_INCHES = 0 -IMAGE_RESOLUTION_CM = 0 -IMAGE_QUALITY_NEAREST = 0 -IMAGE_QUALITY_BILINEAR = 0 -IMAGE_QUALITY_BICUBIC = 0 -IMAGE_QUALITY_BOX_AVERAGE = 0 -IMAGE_QUALITY_NORMAL = 0 -IMAGE_QUALITY_HIGH = 0 -IMAGE_ALPHA_BLEND_OVER = 0 -IMAGE_ALPHA_BLEND_COMPOSE = 0 -PNG_TYPE_COLOUR = 0 -PNG_TYPE_GREY = 0 -PNG_TYPE_GREY_RED = 0 -PNG_TYPE_PALETTE = 0 -BMP_24BPP = 0 -BMP_8BPP = 0 -BMP_8BPP_GREY = 0 -BMP_8BPP_GRAY = 0 -BMP_8BPP_RED = 0 -BMP_8BPP_PALETTE = 0 -BMP_4BPP = 0 -BMP_1BPP = 0 -BMP_1BPP_BW = 0 -IMAGE_ALPHA_TRANSPARENT = 0 -IMAGE_ALPHA_OPAQUE = 0 -IMAGE_ALPHA_THRESHOLD = 0 +IMAGE_RESOLUTION_NONE: int +IMAGE_RESOLUTION_INCHES: int +IMAGE_RESOLUTION_CM: int +IMAGE_QUALITY_NEAREST: int +IMAGE_QUALITY_BILINEAR: int +IMAGE_QUALITY_BICUBIC: int +IMAGE_QUALITY_BOX_AVERAGE: int +IMAGE_QUALITY_NORMAL: int +IMAGE_QUALITY_HIGH: int +IMAGE_ALPHA_BLEND_OVER: int +IMAGE_ALPHA_BLEND_COMPOSE: int +PNG_TYPE_COLOUR: int +PNG_TYPE_GREY: int +PNG_TYPE_GREY_RED: int +PNG_TYPE_PALETTE: int +BMP_24BPP: int +BMP_8BPP: int +BMP_8BPP_GREY: int +BMP_8BPP_GRAY: int +BMP_8BPP_RED: int +BMP_8BPP_PALETTE: int +BMP_4BPP: int +BMP_1BPP: int +BMP_1BPP_BW: int +IMAGE_ALPHA_TRANSPARENT: int +IMAGE_ALPHA_OPAQUE: int +IMAGE_ALPHA_THRESHOLD: int class Image(Object): """ @@ -10023,11 +10061,11 @@ class GDIObject(Object): # -- end-gdiobj --# # -- begin-bitmap --# -BitmapBufferFormat_RGB = 0 -BitmapBufferFormat_RGBA = 0 -BitmapBufferFormat_RGB32 = 0 -BitmapBufferFormat_ARGB32 = 0 -BITMAP_SCREEN_DEPTH = 0 +BitmapBufferFormat_RGB: int +BitmapBufferFormat_RGBA: int +BitmapBufferFormat_RGB32: int +BitmapBufferFormat_ARGB32: int +BITMAP_SCREEN_DEPTH: int class Bitmap(GDIObject): """ @@ -10803,7 +10841,7 @@ class BitmapBundleImpl(RefCounter): # -- end-bmpbndl --# # -- begin-icon --# -ICON_SCREEN_DEPTH = 0 +ICON_SCREEN_DEPTH: int class Icon(GDIObject): """ @@ -10816,8 +10854,8 @@ class Icon(GDIObject): An icon is a small rectangular bitmap usually used for denoting a minimized application. """ - - def __init__(self, *args, **kw): + @overload + def __init__(self): """ Icon() Icon(icon) @@ -10828,7 +10866,20 @@ class Icon(GDIObject): An icon is a small rectangular bitmap usually used for denoting a minimized application. """ - + @overload + def __init__(self, icon: Icon): ... + @overload + def __init__( + self, + name: str, + type: BitmapType = BITMAP_TYPE_ANY, + desiredWidth: int = -1, + desiredHeight: int = -1, + ): ... + @overload + def __init__(self, loc: IconLocation): ... + @overload + def __init__(self, bmp: Bitmap): ... def CreateFromHICON(self, hicon): """ CreateFromHICON(hicon) -> bool @@ -11117,151 +11168,151 @@ class IconBundle(GDIObject): NullIconBundle = IconBundle() # -- end-iconbndl --# # -- begin-font --# -FONTFAMILY_DEFAULT = 0 -FONTFAMILY_DECORATIVE = 0 -FONTFAMILY_ROMAN = 0 -FONTFAMILY_SCRIPT = 0 -FONTFAMILY_SWISS = 0 -FONTFAMILY_MODERN = 0 -FONTFAMILY_TELETYPE = 0 -FONTFAMILY_MAX = 0 -FONTFAMILY_UNKNOWN = 0 -FONTSTYLE_NORMAL = 0 -FONTSTYLE_ITALIC = 0 -FONTSTYLE_SLANT = 0 -FONTSTYLE_MAX = 0 -FONTWEIGHT_INVALID = 0 -FONTWEIGHT_THIN = 0 -FONTWEIGHT_EXTRALIGHT = 0 -FONTWEIGHT_LIGHT = 0 -FONTWEIGHT_NORMAL = 0 -FONTWEIGHT_MEDIUM = 0 -FONTWEIGHT_SEMIBOLD = 0 -FONTWEIGHT_BOLD = 0 -FONTWEIGHT_EXTRABOLD = 0 -FONTWEIGHT_HEAVY = 0 -FONTWEIGHT_EXTRAHEAVY = 0 -FONTWEIGHT_MAX = 0 -FONTSIZE_XX_SMALL = 0 -FONTSIZE_X_SMALL = 0 -FONTSIZE_SMALL = 0 -FONTSIZE_MEDIUM = 0 -FONTSIZE_LARGE = 0 -FONTSIZE_X_LARGE = 0 -FONTSIZE_XX_LARGE = 0 -FONTFLAG_DEFAULT = 0 -FONTFLAG_ITALIC = 0 -FONTFLAG_SLANT = 0 -FONTFLAG_LIGHT = 0 -FONTFLAG_BOLD = 0 -FONTFLAG_ANTIALIASED = 0 -FONTFLAG_NOT_ANTIALIASED = 0 -FONTFLAG_UNDERLINED = 0 -FONTFLAG_STRIKETHROUGH = 0 -FONTFLAG_MASK = 0 -FONTENCODING_SYSTEM = 0 -FONTENCODING_DEFAULT = 0 -FONTENCODING_ISO8859_1 = 0 -FONTENCODING_ISO8859_2 = 0 -FONTENCODING_ISO8859_3 = 0 -FONTENCODING_ISO8859_4 = 0 -FONTENCODING_ISO8859_5 = 0 -FONTENCODING_ISO8859_6 = 0 -FONTENCODING_ISO8859_7 = 0 -FONTENCODING_ISO8859_8 = 0 -FONTENCODING_ISO8859_9 = 0 -FONTENCODING_ISO8859_10 = 0 -FONTENCODING_ISO8859_11 = 0 -FONTENCODING_ISO8859_12 = 0 -FONTENCODING_ISO8859_13 = 0 -FONTENCODING_ISO8859_14 = 0 -FONTENCODING_ISO8859_15 = 0 -FONTENCODING_ISO8859_MAX = 0 -FONTENCODING_KOI8 = 0 -FONTENCODING_KOI8_U = 0 -FONTENCODING_ALTERNATIVE = 0 -FONTENCODING_BULGARIAN = 0 -FONTENCODING_CP437 = 0 -FONTENCODING_CP850 = 0 -FONTENCODING_CP852 = 0 -FONTENCODING_CP855 = 0 -FONTENCODING_CP866 = 0 -FONTENCODING_CP874 = 0 -FONTENCODING_CP932 = 0 -FONTENCODING_CP936 = 0 -FONTENCODING_CP949 = 0 -FONTENCODING_CP950 = 0 -FONTENCODING_CP1250 = 0 -FONTENCODING_CP1251 = 0 -FONTENCODING_CP1252 = 0 -FONTENCODING_CP1253 = 0 -FONTENCODING_CP1254 = 0 -FONTENCODING_CP1255 = 0 -FONTENCODING_CP1256 = 0 -FONTENCODING_CP1257 = 0 -FONTENCODING_CP1258 = 0 -FONTENCODING_CP1361 = 0 -FONTENCODING_CP12_MAX = 0 -FONTENCODING_UTF7 = 0 -FONTENCODING_UTF8 = 0 -FONTENCODING_EUC_JP = 0 -FONTENCODING_UTF16BE = 0 -FONTENCODING_UTF16LE = 0 -FONTENCODING_UTF32BE = 0 -FONTENCODING_UTF32LE = 0 -FONTENCODING_MACROMAN = 0 -FONTENCODING_MACJAPANESE = 0 -FONTENCODING_MACCHINESETRAD = 0 -FONTENCODING_MACKOREAN = 0 -FONTENCODING_MACARABIC = 0 -FONTENCODING_MACHEBREW = 0 -FONTENCODING_MACGREEK = 0 -FONTENCODING_MACCYRILLIC = 0 -FONTENCODING_MACDEVANAGARI = 0 -FONTENCODING_MACGURMUKHI = 0 -FONTENCODING_MACGUJARATI = 0 -FONTENCODING_MACORIYA = 0 -FONTENCODING_MACBENGALI = 0 -FONTENCODING_MACTAMIL = 0 -FONTENCODING_MACTELUGU = 0 -FONTENCODING_MACKANNADA = 0 -FONTENCODING_MACMALAJALAM = 0 -FONTENCODING_MACSINHALESE = 0 -FONTENCODING_MACBURMESE = 0 -FONTENCODING_MACKHMER = 0 -FONTENCODING_MACTHAI = 0 -FONTENCODING_MACLAOTIAN = 0 -FONTENCODING_MACGEORGIAN = 0 -FONTENCODING_MACARMENIAN = 0 -FONTENCODING_MACCHINESESIMP = 0 -FONTENCODING_MACTIBETAN = 0 -FONTENCODING_MACMONGOLIAN = 0 -FONTENCODING_MACETHIOPIC = 0 -FONTENCODING_MACCENTRALEUR = 0 -FONTENCODING_MACVIATNAMESE = 0 -FONTENCODING_MACARABICEXT = 0 -FONTENCODING_MACSYMBOL = 0 -FONTENCODING_MACDINGBATS = 0 -FONTENCODING_MACTURKISH = 0 -FONTENCODING_MACCROATIAN = 0 -FONTENCODING_MACICELANDIC = 0 -FONTENCODING_MACROMANIAN = 0 -FONTENCODING_MACCELTIC = 0 -FONTENCODING_MACGAELIC = 0 -FONTENCODING_MACKEYBOARD = 0 -FONTENCODING_ISO2022_JP = 0 -FONTENCODING_MAX = 0 -FONTENCODING_MACMIN = 0 -FONTENCODING_MACMAX = 0 -FONTENCODING_UTF16 = 0 -FONTENCODING_UTF32 = 0 -FONTENCODING_UNICODE = 0 -FONTENCODING_GB2312 = 0 -FONTENCODING_BIG5 = 0 -FONTENCODING_SHIFT_JIS = 0 -FONTENCODING_EUC_KR = 0 -FONTENCODING_JOHAB = 0 -FONTENCODING_VIETNAMESE = 0 +FONTFAMILY_DEFAULT: int +FONTFAMILY_DECORATIVE: int +FONTFAMILY_ROMAN: int +FONTFAMILY_SCRIPT: int +FONTFAMILY_SWISS: int +FONTFAMILY_MODERN: int +FONTFAMILY_TELETYPE: int +FONTFAMILY_MAX: int +FONTFAMILY_UNKNOWN: int +FONTSTYLE_NORMAL: int +FONTSTYLE_ITALIC: int +FONTSTYLE_SLANT: int +FONTSTYLE_MAX: int +FONTWEIGHT_INVALID: int +FONTWEIGHT_THIN: int +FONTWEIGHT_EXTRALIGHT: int +FONTWEIGHT_LIGHT: int +FONTWEIGHT_NORMAL: int +FONTWEIGHT_MEDIUM: int +FONTWEIGHT_SEMIBOLD: int +FONTWEIGHT_BOLD: int +FONTWEIGHT_EXTRABOLD: int +FONTWEIGHT_HEAVY: int +FONTWEIGHT_EXTRAHEAVY: int +FONTWEIGHT_MAX: int +FONTSIZE_XX_SMALL: int +FONTSIZE_X_SMALL: int +FONTSIZE_SMALL: int +FONTSIZE_MEDIUM: int +FONTSIZE_LARGE: int +FONTSIZE_X_LARGE: int +FONTSIZE_XX_LARGE: int +FONTFLAG_DEFAULT: int +FONTFLAG_ITALIC: int +FONTFLAG_SLANT: int +FONTFLAG_LIGHT: int +FONTFLAG_BOLD: int +FONTFLAG_ANTIALIASED: int +FONTFLAG_NOT_ANTIALIASED: int +FONTFLAG_UNDERLINED: int +FONTFLAG_STRIKETHROUGH: int +FONTFLAG_MASK: int +FONTENCODING_SYSTEM: int +FONTENCODING_DEFAULT: int +FONTENCODING_ISO8859_1: int +FONTENCODING_ISO8859_2: int +FONTENCODING_ISO8859_3: int +FONTENCODING_ISO8859_4: int +FONTENCODING_ISO8859_5: int +FONTENCODING_ISO8859_6: int +FONTENCODING_ISO8859_7: int +FONTENCODING_ISO8859_8: int +FONTENCODING_ISO8859_9: int +FONTENCODING_ISO8859_10: int +FONTENCODING_ISO8859_11: int +FONTENCODING_ISO8859_12: int +FONTENCODING_ISO8859_13: int +FONTENCODING_ISO8859_14: int +FONTENCODING_ISO8859_15: int +FONTENCODING_ISO8859_MAX: int +FONTENCODING_KOI8: int +FONTENCODING_KOI8_U: int +FONTENCODING_ALTERNATIVE: int +FONTENCODING_BULGARIAN: int +FONTENCODING_CP437: int +FONTENCODING_CP850: int +FONTENCODING_CP852: int +FONTENCODING_CP855: int +FONTENCODING_CP866: int +FONTENCODING_CP874: int +FONTENCODING_CP932: int +FONTENCODING_CP936: int +FONTENCODING_CP949: int +FONTENCODING_CP950: int +FONTENCODING_CP1250: int +FONTENCODING_CP1251: int +FONTENCODING_CP1252: int +FONTENCODING_CP1253: int +FONTENCODING_CP1254: int +FONTENCODING_CP1255: int +FONTENCODING_CP1256: int +FONTENCODING_CP1257: int +FONTENCODING_CP1258: int +FONTENCODING_CP1361: int +FONTENCODING_CP12_MAX: int +FONTENCODING_UTF7: int +FONTENCODING_UTF8: int +FONTENCODING_EUC_JP: int +FONTENCODING_UTF16BE: int +FONTENCODING_UTF16LE: int +FONTENCODING_UTF32BE: int +FONTENCODING_UTF32LE: int +FONTENCODING_MACROMAN: int +FONTENCODING_MACJAPANESE: int +FONTENCODING_MACCHINESETRAD: int +FONTENCODING_MACKOREAN: int +FONTENCODING_MACARABIC: int +FONTENCODING_MACHEBREW: int +FONTENCODING_MACGREEK: int +FONTENCODING_MACCYRILLIC: int +FONTENCODING_MACDEVANAGARI: int +FONTENCODING_MACGURMUKHI: int +FONTENCODING_MACGUJARATI: int +FONTENCODING_MACORIYA: int +FONTENCODING_MACBENGALI: int +FONTENCODING_MACTAMIL: int +FONTENCODING_MACTELUGU: int +FONTENCODING_MACKANNADA: int +FONTENCODING_MACMALAJALAM: int +FONTENCODING_MACSINHALESE: int +FONTENCODING_MACBURMESE: int +FONTENCODING_MACKHMER: int +FONTENCODING_MACTHAI: int +FONTENCODING_MACLAOTIAN: int +FONTENCODING_MACGEORGIAN: int +FONTENCODING_MACARMENIAN: int +FONTENCODING_MACCHINESESIMP: int +FONTENCODING_MACTIBETAN: int +FONTENCODING_MACMONGOLIAN: int +FONTENCODING_MACETHIOPIC: int +FONTENCODING_MACCENTRALEUR: int +FONTENCODING_MACVIATNAMESE: int +FONTENCODING_MACARABICEXT: int +FONTENCODING_MACSYMBOL: int +FONTENCODING_MACDINGBATS: int +FONTENCODING_MACTURKISH: int +FONTENCODING_MACCROATIAN: int +FONTENCODING_MACICELANDIC: int +FONTENCODING_MACROMANIAN: int +FONTENCODING_MACCELTIC: int +FONTENCODING_MACGAELIC: int +FONTENCODING_MACKEYBOARD: int +FONTENCODING_ISO2022_JP: int +FONTENCODING_MAX: int +FONTENCODING_MACMIN: int +FONTENCODING_MACMAX: int +FONTENCODING_UTF16: int +FONTENCODING_UTF32: int +FONTENCODING_UNICODE: int +FONTENCODING_GB2312: int +FONTENCODING_BIG5: int +FONTENCODING_SHIFT_JIS: int +FONTENCODING_EUC_KR: int +FONTENCODING_JOHAB: int +FONTENCODING_VIETNAMESE: int class FontInfo: """ @@ -12083,36 +12134,36 @@ class NativeFontInfo: # -- end-fontutil --# # -- begin-pen --# -PENSTYLE_INVALID = 0 -PENSTYLE_SOLID = 0 -PENSTYLE_DOT = 0 -PENSTYLE_LONG_DASH = 0 -PENSTYLE_SHORT_DASH = 0 -PENSTYLE_DOT_DASH = 0 -PENSTYLE_USER_DASH = 0 -PENSTYLE_TRANSPARENT = 0 -PENSTYLE_STIPPLE_MASK_OPAQUE = 0 -PENSTYLE_STIPPLE_MASK = 0 -PENSTYLE_STIPPLE = 0 -PENSTYLE_BDIAGONAL_HATCH = 0 -PENSTYLE_CROSSDIAG_HATCH = 0 -PENSTYLE_FDIAGONAL_HATCH = 0 -PENSTYLE_CROSS_HATCH = 0 -PENSTYLE_HORIZONTAL_HATCH = 0 -PENSTYLE_VERTICAL_HATCH = 0 -PENSTYLE_FIRST_HATCH = 0 -PENSTYLE_LAST_HATCH = 0 -PEN_QUALITY_DEFAULT = 0 -PEN_QUALITY_LOW = 0 -PEN_QUALITY_HIGH = 0 -JOIN_INVALID = 0 -JOIN_BEVEL = 0 -JOIN_MITER = 0 -JOIN_ROUND = 0 -CAP_INVALID = 0 -CAP_ROUND = 0 -CAP_PROJECTING = 0 -CAP_BUTT = 0 +PENSTYLE_INVALID: int +PENSTYLE_SOLID: int +PENSTYLE_DOT: int +PENSTYLE_LONG_DASH: int +PENSTYLE_SHORT_DASH: int +PENSTYLE_DOT_DASH: int +PENSTYLE_USER_DASH: int +PENSTYLE_TRANSPARENT: int +PENSTYLE_STIPPLE_MASK_OPAQUE: int +PENSTYLE_STIPPLE_MASK: int +PENSTYLE_STIPPLE: int +PENSTYLE_BDIAGONAL_HATCH: int +PENSTYLE_CROSSDIAG_HATCH: int +PENSTYLE_FDIAGONAL_HATCH: int +PENSTYLE_CROSS_HATCH: int +PENSTYLE_HORIZONTAL_HATCH: int +PENSTYLE_VERTICAL_HATCH: int +PENSTYLE_FIRST_HATCH: int +PENSTYLE_LAST_HATCH: int +PEN_QUALITY_DEFAULT: int +PEN_QUALITY_LOW: int +PEN_QUALITY_HIGH: int +JOIN_INVALID: int +JOIN_BEVEL: int +JOIN_MITER: int +JOIN_ROUND: int +CAP_INVALID: int +CAP_ROUND: int +CAP_PROJECTING: int +CAP_BUTT: int class PenInfo: """ @@ -12458,20 +12509,20 @@ USER_DASH = int(wx.PENSTYLE_USER_DASH) TRANSPARENT = int(wx.PENSTYLE_TRANSPARENT) # -- end-pen --# # -- begin-brush --# -BRUSHSTYLE_INVALID = 0 -BRUSHSTYLE_SOLID = 0 -BRUSHSTYLE_TRANSPARENT = 0 -BRUSHSTYLE_STIPPLE_MASK_OPAQUE = 0 -BRUSHSTYLE_STIPPLE_MASK = 0 -BRUSHSTYLE_STIPPLE = 0 -BRUSHSTYLE_BDIAGONAL_HATCH = 0 -BRUSHSTYLE_CROSSDIAG_HATCH = 0 -BRUSHSTYLE_FDIAGONAL_HATCH = 0 -BRUSHSTYLE_CROSS_HATCH = 0 -BRUSHSTYLE_HORIZONTAL_HATCH = 0 -BRUSHSTYLE_VERTICAL_HATCH = 0 -BRUSHSTYLE_FIRST_HATCH = 0 -BRUSHSTYLE_LAST_HATCH = 0 +BRUSHSTYLE_INVALID: int +BRUSHSTYLE_SOLID: int +BRUSHSTYLE_TRANSPARENT: int +BRUSHSTYLE_STIPPLE_MASK_OPAQUE: int +BRUSHSTYLE_STIPPLE_MASK: int +BRUSHSTYLE_STIPPLE: int +BRUSHSTYLE_BDIAGONAL_HATCH: int +BRUSHSTYLE_CROSSDIAG_HATCH: int +BRUSHSTYLE_FDIAGONAL_HATCH: int +BRUSHSTYLE_CROSS_HATCH: int +BRUSHSTYLE_HORIZONTAL_HATCH: int +BRUSHSTYLE_VERTICAL_HATCH: int +BRUSHSTYLE_FIRST_HATCH: int +BRUSHSTYLE_LAST_HATCH: int class Brush(GDIObject): """ @@ -12722,9 +12773,9 @@ StockCursor = wx.deprecated(Cursor, "Use Cursor instead.") CursorFromImage = wx.deprecated(Cursor, "Use Cursor instead.") # -- end-cursor --# # -- begin-region --# -OutRegion = 0 -PartRegion = 0 -InRegion = 0 +OutRegion: int +PartRegion: int +InRegion: int class RegionIterator(Object): """ @@ -12996,29 +13047,29 @@ class Region(GDIObject): # -- end-region --# # -- begin-dc --# -CLEAR = 0 -XOR = 0 -INVERT = 0 -OR_REVERSE = 0 -AND_REVERSE = 0 -COPY = 0 -AND = 0 -AND_INVERT = 0 -NO_OP = 0 -NOR = 0 -EQUIV = 0 -SRC_INVERT = 0 -OR_INVERT = 0 -NAND = 0 -OR = 0 -SET = 0 -FLOOD_SURFACE = 0 -FLOOD_BORDER = 0 -MM_TEXT = 0 -MM_METRIC = 0 -MM_LOMETRIC = 0 -MM_TWIPS = 0 -MM_POINTS = 0 +CLEAR: int +XOR: int +INVERT: int +OR_REVERSE: int +AND_REVERSE: int +COPY: int +AND: int +AND_INVERT: int +NO_OP: int +NOR: int +EQUIV: int +SRC_INVERT: int +OR_INVERT: int +NAND: int +OR: int +SET: int +FLOOD_SURFACE: int +FLOOD_BORDER: int +MM_TEXT: int +MM_METRIC: int +MM_LOMETRIC: int +MM_TWIPS: int +MM_POINTS: int class FontMetrics: """ @@ -14392,7 +14443,7 @@ class ClientDC(WindowDC): window from outside EVT_PAINT() handler. """ - def __init__(self, window): + def __init__(self, window: Window): """ ClientDC(window) @@ -14469,9 +14520,9 @@ class MemoryDC(DC): # -- end-dcmemory --# # -- begin-dcbuffer --# -BUFFER_VIRTUAL_AREA = 0 -BUFFER_CLIENT_AREA = 0 -BUFFER_USES_SHARED_BUFFER = 0 +BUFFER_VIRTUAL_AREA: int +BUFFER_CLIENT_AREA: int +BUFFER_USES_SHARED_BUFFER: int class BufferedDC(MemoryDC): """ @@ -21115,8 +21166,8 @@ class EvtHandler(Object, Trackable): def Bind( self, event: PyEventBinder, - handler: Callable[[Any], None], - source: Window | None = None, + handler: Callable, + source: EvtHandler | None = None, id: int = wx.ID_ANY, id2: int = wx.ID_ANY, ) -> None: @@ -21431,7 +21482,7 @@ class CommandEvent(Event): deselection), or a boolean value representing the value of a checkbox. """ - def GetSelection(self): + def GetSelection(self) -> int: """ GetSelection() -> int @@ -21439,7 +21490,7 @@ class CommandEvent(Event): for a deselection). """ - def GetString(self): + def GetString(self) -> str: """ GetString() -> String @@ -24251,7 +24302,7 @@ class SizerItem(Object): Get the userData item attribute. """ - def GetWindow(self): + def GetWindow(self) -> Window: """ GetWindow() -> Window @@ -24582,8 +24633,8 @@ class Sizer(Object): Set an item's minimum size by window, sizer, or position. """ - - def Add(self, *args, **kw): + @overload + def Add(self, window: Window, flags: SizerFlags) -> SizerItem: """ Add(window, flags) -> SizerItem Add(window, proportion=0, flag=0, border=0, userData=None) -> SizerItem @@ -24597,7 +24648,51 @@ class Sizer(Object): Appends a child to the sizer. """ - + @overload + def Add( + self, + window: Window, + proportion: int = 0, + flag: int = 0, + border: int = 0, + userData: Any = None, + ) -> SizerItem: ... + @overload + def Add(self, sizer: Sizer, flags: SizerFlags) -> SizerItem: ... + @overload + def Add( + self, + sizer: Sizer, + proportion: int = 0, + flag: int = 0, + border: int = 0, + userData: Any = None, + ) -> SizerItem: ... + @overload + def Add( + self, + width: int, + height: int, + proportion: int = 0, + flag: int = 0, + border: int = 0, + userData: Any = None, + ) -> SizerItem: ... + @overload + def Add(self, width: int, height: int, flags: SizerFlags) -> SizerItem: ... + @overload + def Add(self, item: SizerItem) -> SizerItem: ... + @overload + def Add( + self, + size: SizeType, + proportion: int = 0, + flag: int = 0, + border: int = 0, + Transfer: Any = None, + ) -> SizerItem: ... + @overload + def Add(self, size: Size, flags: SizerFlags) -> SizerItem: ... def AddSpacer(self, size): """ AddSpacer(size) -> SizerItem @@ -24606,7 +24701,7 @@ class Sizer(Object): and vertical orientation of the sizer. """ - def AddStretchSpacer(self, prop=1): + def AddStretchSpacer(self, prop: int = 1) -> SizerItem: """ AddStretchSpacer(prop=1) -> SizerItem @@ -24653,7 +24748,7 @@ class Sizer(Object): Detach the child window from the sizer without destroying it. """ - def Fit(self, window): + def Fit(self, window: Window) -> Size: """ Fit(window) -> Size @@ -24879,7 +24974,7 @@ class Sizer(Object): Call this to give the sizer a minimal size. """ - def SetSizeHints(self, window): + def SetSizeHints(self, window: Window): """ SetSizeHints(window) @@ -24903,7 +24998,7 @@ class Sizer(Object): Show or hide all items managed by the sizer. """ - def AddMany(self, items): + def AddMany(self, items: Iterable[tuple[Any, ...] | Any]) -> None: """ :meth:`AddMany` is a convenience method for adding several items to a sizer at one time. Simply pass it a list of tuples, where each tuple @@ -24944,7 +25039,7 @@ class BoxSizer(Sizer): column or several hierarchies of either. """ - def __init__(self, orient=HORIZONTAL): + def __init__(self, orient: int = HORIZONTAL): """ BoxSizer(orient=HORIZONTAL) @@ -24953,21 +25048,21 @@ class BoxSizer(Sizer): column or several hierarchies of either. """ - def AddSpacer(self, size): + def AddSpacer(self, size: int) -> SizerItem: """ AddSpacer(size) -> SizerItem Adds non-stretchable space to the main orientation of the sizer only. """ - def CalcMin(self): + def CalcMin(self) -> Size: """ CalcMin() -> Size Implements the calculation of a box sizer's minimal. """ - def GetOrientation(self): + def GetOrientation(self) -> int: """ GetOrientation() -> int @@ -24975,7 +25070,7 @@ class BoxSizer(Sizer): wxHORIZONTAL. """ - def SetOrientation(self, orient): + def SetOrientation(self, orient: int) -> None: """ SetOrientation(orient) @@ -24983,7 +25078,7 @@ class BoxSizer(Sizer): wxHORIZONTAL. """ - def RepositionChildren(self, minSize): + def RepositionChildren(self, minSize: Size) -> None: """ RepositionChildren(minSize) @@ -25001,8 +25096,8 @@ class StaticBoxSizer(BoxSizer): wxStaticBoxSizer is a sizer derived from wxBoxSizer but adds a static box around the sizer. """ - - def __init__(self, *args, **kw): + @overload + def __init__(self, box: StaticBox, orient: int = HORIZONTAL): """ StaticBoxSizer(box, orient=HORIZONTAL) StaticBoxSizer(orient, parent, label=EmptyString) @@ -25010,7 +25105,8 @@ class StaticBoxSizer(BoxSizer): wxStaticBoxSizer is a sizer derived from wxBoxSizer but adds a static box around the sizer. """ - + @overload + def __init__(self, orient: int, parent: Window, label: str = ""): ... def GetStaticBox(self): """ GetStaticBox() -> StaticBox @@ -25172,8 +25268,8 @@ class FlexGridSizer(GridSizer): rows or all columns are not necessarily the same height or width as in the wxGridSizer. """ - - def __init__(self, *args, **kw): + @overload + def __init__(self, cols: int, vgap: int, hgap: int): """ FlexGridSizer(cols, vgap, hgap) FlexGridSizer(cols, gap=Size(0,0)) @@ -25186,8 +25282,13 @@ class FlexGridSizer(GridSizer): rows or all columns are not necessarily the same height or width as in the wxGridSizer. """ - - def AddGrowableCol(self, idx, proportion=0): + @overload + def __init__(self, cols: int, gap: SizeType = Size(0, 0)): ... + @overload + def __init__(self, rows: int, cols: int, vgap: int, hgap: int): ... + @overload + def __init__(self, rows: int, cols: int, gap: SizeType): ... + def AddGrowableCol(self, idx: int, proportion: int = 0) -> None: """ AddGrowableCol(idx, proportion=0) @@ -25319,14 +25420,32 @@ class StdDialogButtonSizer(BoxSizer): interface guidelines (if such things exist). """ - def AddButton(self, button): + def AddButton(self, button: Button) -> None: """ AddButton(button) Adds a button to the wxStdDialogButtonSizer. + The button must have one of the following identifiers: + wx.ID_OK + + wx.ID_YES + + wx.ID_SAVE + + wx.ID_APPLY + + wx.ID_CLOSE + + wx.ID_NO + + wx.ID_CANCEL + + wx.ID_HELP + + wx.ID_CONTEXT_HELP """ - def Realize(self): + def Realize(self) -> None: """ Realize() @@ -25334,35 +25453,35 @@ class StdDialogButtonSizer(BoxSizer): make them match the platform or toolkit's interface guidelines. """ - def SetAffirmativeButton(self, button): + def SetAffirmativeButton(self, button: Button) -> None: """ SetAffirmativeButton(button) Sets the affirmative button for the sizer. """ - def SetCancelButton(self, button): + def SetCancelButton(self, button: Button) -> None: """ SetCancelButton(button) Sets the cancel button for the sizer. """ - def SetNegativeButton(self, button): + def SetNegativeButton(self, button: Button) -> None: """ SetNegativeButton(button) Sets the negative button for the sizer. """ - def RepositionChildren(self, minSize): + def RepositionChildren(self, minSize: Size) -> None: """ RepositionChildren(minSize) Method which must be overridden in the derived sizer classes. """ - def CalcMin(self): + def CalcMin(self) -> Size: """ CalcMin() -> Size @@ -25579,6 +25698,8 @@ class GBSpan: rowspan = property(None, None) colspan = property(None, None) +DefaultSpan = GBSpan() + # end of class GBSpan class GBSizerItem(SizerItem): @@ -25673,7 +25794,7 @@ class GridBagSizer(FlexGridSizer): one row and/or column using wxGBSpan. """ - def __init__(self, vgap=0, hgap=0): + def __init__(self, vgap: int = 0, hgap: int = 0): """ GridBagSizer(vgap=0, hgap=0) @@ -25682,8 +25803,16 @@ class GridBagSizer(FlexGridSizer): allowed using wxGBPosition, and items can optionally span more than one row and/or column using wxGBSpan. """ - - def Add(self, *args, **kw): + @overload + def Add( + self, + window: Window, + pos: GBPositionType, + span: GBSpanType = DefaultSpan, + flag: int = 0, + border: int = 0, + userData: Any = None, + ) -> SizerItem: """ Add(window, pos, span=DefaultSpan, flag=0, border=0, userData=None) -> SizerItem Add(sizer, pos, span=DefaultSpan, flag=0, border=0, userData=None) -> SizerItem @@ -25693,7 +25822,39 @@ class GridBagSizer(FlexGridSizer): Adds the given item to the given position. """ - + @overload + def Add( + self, + sizer: Sizer, + pos: GBPositionType, + span: GBSpanType = DefaultSpan, + flag: int = 0, + border: int = 0, + userData: Any = None, + ) -> SizerItem: ... + @overload + def Add(self, item: GBSizerItem) -> SizerItem: ... + @overload + def Add( + self, + width: int, + height: int, + pos: GBPositionType, + span: GBSpanType = DefaultSpan, + flag: int = 0, + border: int = 0, + userData: Any = None, + ) -> SizerItem: ... + @overload + def Add( + self, + size: Size, + pos: GBPositionType, + span: GBSpanType = DefaultSpan, + flag: int = 0, + border: int = 0, + Transfer: Any = None, + ) -> SizerItem: ... def CheckForIntersection(self, *args, **kw): """ CheckForIntersection(item, excludeItem=None) -> bool @@ -25764,7 +25925,7 @@ class GridBagSizer(FlexGridSizer): there is no item at that point. """ - def FindItemAtPosition(self, pos): + def FindItemAtPosition(self, pos: GBPositionType) -> GBSizerItem: """ FindItemAtPosition(pos) -> GBSizerItem @@ -25816,8 +25977,6 @@ class GridBagSizer(FlexGridSizer): # end of class GridBagSizer -DefaultSpan = GBSpan() - from collections import namedtuple _im_GBPosition = namedtuple("_im_GBPosition", ["row", "col"]) @@ -26944,11 +27103,12 @@ class PyApp(AppConsole): # end of class PyApp -def GetApp(): +def GetApp() -> App: # This is an intentionally wrong signature """ GetApp() -> AppConsole Returns the current application object. + The annotated App return type is intentionally wrong for removing some errors for the time being. """ def HandleFatalExceptions(doIt=True): @@ -28071,8 +28231,8 @@ class Window(WindowBase): Sets the minimum size of the window, to indicate to the sizer layout mechanism that this is the minimum required size. """ - - def SetSize(self, *args, **kw): + @overload + def SetSize(self, x: int, y: int, width: int, height: int, sizeFlags: int = SIZE_AUTO) -> None: """ SetSize(x, y, width, height, sizeFlags=SIZE_AUTO) SetSize(rect) @@ -28081,7 +28241,12 @@ class Window(WindowBase): Sets the size of the window in pixels. """ - + @overload + def SetSize(self, rect: Rect) -> None: ... + @overload + def SetSize(self, size: SizeType) -> None: ... + @overload + def SetSize(self, width: int, height: int) -> None: ... def SetSizeHints(self, *args, **kw): """ SetSizeHints(minSize, maxSize=DefaultSize, incSize=DefaultSize) @@ -28106,7 +28271,7 @@ class Window(WindowBase): A synonym for Centre(). """ - def CenterOnParent(self, dir=BOTH): + def CenterOnParent(self, dir: int = BOTH) -> None: """ CenterOnParent(dir=BOTH) @@ -28349,7 +28514,7 @@ class Window(WindowBase): background. """ - def Refresh(self, eraseBackground=True, rect=None): + def Refresh(self, eraseBackground: bool = True, rect: Rect | None = None): """ Refresh(eraseBackground=True, rect=None) @@ -28365,7 +28530,7 @@ class Window(WindowBase): will be repainted. """ - def Update(self): + def Update(self) -> None: """ Update() @@ -28635,7 +28800,7 @@ class Window(WindowBase): Returns true if the window has the given flag bit set. """ - def SetExtraStyle(self, exStyle): + def SetExtraStyle(self, exStyle: int) -> None: """ SetExtraStyle(exStyle) @@ -28747,7 +28912,7 @@ class Window(WindowBase): Returns true if the window is shown, false if it has been hidden. """ - def IsShownOnScreen(self): + def IsShownOnScreen(self) -> bool: """ IsShownOnScreen() -> bool @@ -28763,14 +28928,14 @@ class Window(WindowBase): Disables the window. """ - def Enable(self, enable=True): + def Enable(self, enable: bool = True) -> bool: """ Enable(enable=True) -> bool Enable or disable the window for user input. """ - def Show(self, show=True): + def Show(self, show: bool = True) -> bool: """ Show(show=True) -> bool @@ -28793,7 +28958,7 @@ class Window(WindowBase): window. """ - def SetHelpText(self, helpText): + def SetHelpText(self, helpText: str) -> None: """ SetHelpText(helpText) @@ -28822,15 +28987,16 @@ class Window(WindowBase): Get the text of the associated tooltip or empty string if none. """ - - def SetToolTip(self, *args, **kw): + @overload + def SetToolTip(self, tipString: str) -> None: """ SetToolTip(tipString) SetToolTip(tip) Attach a tooltip to the window. """ - + @overload + def SetToolTip(self, tip: ToolTip) -> None: ... def UnsetToolTip(self): """ UnsetToolTip() @@ -28969,7 +29135,7 @@ class Window(WindowBase): Sets the window's name. """ - def SetWindowVariant(self, variant): + def SetWindowVariant(self, variant: WindowVariant) -> None: """ SetWindowVariant(variant) @@ -29004,7 +29170,7 @@ class Window(WindowBase): Sets the accessible for this window. """ - def Close(self, force=False): + def Close(self, force: bool = False) -> bool: """ Close(force=False) -> bool @@ -29055,7 +29221,7 @@ class Window(WindowBase): NULL. """ - def GetSizer(self): + def GetSizer(self) -> Sizer: """ GetSizer() -> Sizer @@ -29063,7 +29229,7 @@ class Window(WindowBase): SetSizer(), or NULL. """ - def SetSizer(self, sizer, deleteOld=True): + def SetSizer(self, sizer: Sizer, deleteOld: bool = True) -> None: """ SetSizer(sizer, deleteOld=True) @@ -29797,15 +29963,24 @@ class Panel(Window): A panel is a window on which controls are placed. """ - - def __init__(self, *args, **kw): + @overload + def __init__(self): """ Panel() Panel(parent, id=ID_ANY, pos=DefaultPosition, size=DefaultSize, style=TAB_TRAVERSAL, name=PanelNameStr) A panel is a window on which controls are placed. """ - + @overload + def __init__( + self, + parent: Window, + id: WindowID = ID_ANY, + pos: Point = DefaultPosition, + size: SizeType = DefaultSize, + style: int = TAB_TRAVERSAL, + name: str = PanelNameStr, + ): ... def AcceptsFocus(self): """ AcceptsFocus() -> bool @@ -32086,8 +32261,8 @@ class ItemContainer(ItemContainerImmutable): contain several items such as wxListBox, wxCheckListBox, wxComboBox or wxChoice. """ - - def Append(self, *args, **kw): + @overload + def Append(self, item: str) -> int: """ Append(item) -> int Append(item, clientData) -> int @@ -32095,8 +32270,11 @@ class ItemContainer(ItemContainerImmutable): Appends item into the control. """ - - def GetClientData(self, n): + @overload + def Append(self, item: str, clientData: ClientData) -> int: ... + @overload + def Append(self, items: list[str]) -> int: ... + def GetClientData(self, n: int) -> ClientData: """ GetClientData(n) -> ClientData @@ -32113,8 +32291,8 @@ class ItemContainer(ItemContainerImmutable): explicitly by using Delete() or implicitly when the control itself is destroyed). """ - - def Insert(self, *args, **kw): + @overload + def Insert(self, item: str, pos: int) -> int: """ Insert(item, pos) -> int Insert(item, pos, clientData) -> int @@ -32122,7 +32300,10 @@ class ItemContainer(ItemContainerImmutable): Inserts item into the control. """ - + @overload + def Insert(self, item: str, pos: int, clientData: ClientData) -> int: ... + @overload + def Insert(self, items: Sequence[str], pos: int) -> int: ... def Set(self, items): """ Set(items) @@ -32130,7 +32311,7 @@ class ItemContainer(ItemContainerImmutable): Replaces the current control contents with the given items. """ - def Clear(self): + def Clear(self) -> None: """ Clear() @@ -32186,7 +32367,7 @@ class ItemContainer(ItemContainerImmutable): Alias for :meth:`SetClientData` """ - def AppendItems(self, items): + def AppendItems(self, items: list[str]) -> int: """ Alias for :meth:`Append` """ @@ -32196,7 +32377,7 @@ class ItemContainer(ItemContainerImmutable): Alias for :meth:`GetStrings` """ - def SetItems(self, items): + def SetItems(self, items: Iterable[str]) -> None: """ Alias for :meth:`Set` """ @@ -32229,14 +32410,25 @@ class StaticBitmap(Control): Scale_AspectFit = 0 Scale_AspectFill = 0 - def __init__(self, *args, **kw): + @overload + def __init__(self): """ StaticBitmap() StaticBitmap(parent, id=ID_ANY, bitmap=NullBitmap, pos=DefaultPosition, size=DefaultSize, style=0, name=StaticBitmapNameStr) A static bitmap control displays a bitmap. """ - + @overload + def __init__( + self, + parent: Window, + id: WindowID = ID_ANY, + bitmap: Bitmap = NullBitmap, # the documentation is wrong, it should be Bitmap not BitmapBundle + pos: Point = DefaultPosition, + size: Size = DefaultSize, + style: int = 0, + name: str = StaticBitmapNameStr, + ): ... def Create( self, parent, @@ -32409,15 +32601,25 @@ class StaticText(Control): A static text control displays one or more lines of read-only text. """ - - def __init__(self, *args, **kw): + @overload + def __init__(self): """ StaticText() StaticText(parent, id=ID_ANY, label=EmptyString, pos=DefaultPosition, size=DefaultSize, style=0, name=StaticTextNameStr) A static text control displays one or more lines of read-only text. """ - + @overload + def __init__( + self, + parent: Window, + id: WindowID = ID_ANY, + label: str = EmptyString, + pos: Point = DefaultPosition, + size: Size = DefaultSize, + style: int = 0, + name: str = StaticTextNameStr, + ): ... def Create( self, parent, @@ -32434,7 +32636,7 @@ class StaticText(Control): Creation function, for two-step construction. """ - def IsEllipsized(self): + def IsEllipsized(self) -> bool: """ IsEllipsized() -> bool @@ -32443,7 +32645,7 @@ class StaticText(Control): styles. """ - def SetLabel(self, label): + def SetLabel(self, label: str) -> None: """ SetLabel(label) @@ -33000,8 +33202,8 @@ class Button(AnyButton): A button is a control that contains a text string, and is one of the most common elements of a GUI. """ - - def __init__(self, *args, **kw): + @overload + def __init__(self): """ Button() Button(parent, id=ID_ANY, label=EmptyString, pos=DefaultPosition, size=DefaultSize, style=0, validator=DefaultValidator, name=ButtonNameStr) @@ -33009,7 +33211,18 @@ class Button(AnyButton): A button is a control that contains a text string, and is one of the most common elements of a GUI. """ - + @overload + def __init__( + self, + parent: Window, + id: WindowID = ID_ANY, + label: str = EmptyString, + pos: Point = DefaultPosition, + size: Size = DefaultSize, + style: int = 0, + validator: Validator = DefaultValidator, + name: str = ButtonNameStr, + ): ... def Create( self, parent, @@ -33050,7 +33263,7 @@ class Button(AnyButton): the button. """ - def SetDefault(self): + def SetDefault(self) -> Window: """ SetDefault() -> Window @@ -35421,15 +35634,26 @@ class TextCtrl(Control, TextEntry): A text control allows text to be displayed and edited. """ - - def __init__(self, *args, **kw): + @overload + def __init__(self): """ TextCtrl() TextCtrl(parent, id=ID_ANY, value=EmptyString, pos=DefaultPosition, size=DefaultSize, style=0, validator=DefaultValidator, name=TextCtrlNameStr) A text control allows text to be displayed and edited. """ - + @overload + def __init__( + self, + parent: Window, + id: WindowID = ID_ANY, + value: str = EmptyString, + pos: Point = DefaultPosition, + size: SizeType = DefaultSize, + style: int = 0, + validator: Validator = DefaultValidator, + name: str = TextCtrlNameStr, + ): ... def OSXEnableNewLineReplacement(self, enable): """ OSXEnableNewLineReplacement(enable) @@ -35757,15 +35981,27 @@ class ComboBox(Control, ItemContainer, TextEntry): A combobox is like a combination of an edit control and a listbox. """ - - def __init__(self, *args, **kw): + @overload + def __init__(self): """ ComboBox() ComboBox(parent, id=ID_ANY, value=EmptyString, pos=DefaultPosition, size=DefaultSize, choices=[], style=0, validator=DefaultValidator, name=ComboBoxNameStr) A combobox is like a combination of an edit control and a listbox. """ - + @overload + def __init__( + self, + parent: Window | None, + id: WindowID = ID_ANY, + value: str = EmptyString, + pos: Point = DefaultPosition, + size: SizeType = DefaultSize, + choices: Sequence[str] = [], + style: int = 0, + validator: Validator = DefaultValidator, + name: str = ComboBoxNameStr, + ): ... def Create( self, parent, @@ -35811,15 +36047,16 @@ class ComboBox(Control, ItemContainer, TextEntry): Returns true if the text of the combobox is empty. """ - - def SetSelection(self, *args, **kw): + @overload + def SetSelection(self, from_: int, to_: int) -> None: """ SetSelection(from_, to_) SetSelection(n) Same as wxTextEntry::SetSelection(). """ - + @overload + def SetSelection(self, n: int) -> None: ... def SetTextSelection(self, from_, to_): """ SetTextSelection(from_, to_) @@ -35827,7 +36064,7 @@ class ComboBox(Control, ItemContainer, TextEntry): Same as wxTextEntry::SetSelection(). """ - def SetValue(self, text): + def SetValue(self, text: str) -> None: """ SetValue(text) @@ -35848,7 +36085,7 @@ class ComboBox(Control, ItemContainer, TextEntry): Hides the list box portion of the combo box. """ - def GetSelection(self): + def GetSelection(self) -> int: """ GetSelection() -> int @@ -35870,14 +36107,14 @@ class ComboBox(Control, ItemContainer, TextEntry): Finds an item whose label matches the given string. """ - def GetString(self, n): + def GetString(self, n: int) -> str: """ GetString(n) -> String Returns the label of the item with the given index. """ - def GetStringSelection(self): + def GetStringSelection(self) -> str: """ GetStringSelection() -> String @@ -35933,8 +36170,8 @@ class CheckBox(Control): A checkbox is a labelled box which by default is either on (checkmark is visible) or off (no checkmark). """ - - def __init__(self, *args, **kw): + @overload + def __init__(self): """ CheckBox() CheckBox(parent, id=ID_ANY, label=EmptyString, pos=DefaultPosition, size=DefaultSize, style=0, validator=DefaultValidator, name=CheckBoxNameStr) @@ -35942,7 +36179,18 @@ class CheckBox(Control): A checkbox is a labelled box which by default is either on (checkmark is visible) or off (no checkmark). """ - + @overload + def __init__( + self, + parent: Window, + id: WindowID = ID_ANY, + label: str = EmptyString, + pos: Point = DefaultPosition, + size: SizeType = DefaultSize, + style: int = 0, + validator: Validator = DefaultValidator, + name: str = CheckBoxNameStr, + ): ... def Create( self, parent, @@ -35960,7 +36208,7 @@ class CheckBox(Control): Creates the checkbox for two-step construction. """ - def GetValue(self): + def GetValue(self) -> bool: """ GetValue() -> bool @@ -35998,7 +36246,7 @@ class CheckBox(Control): otherwise. """ - def SetValue(self, state): + def SetValue(self, state: bool) -> None: """ SetValue(state) @@ -36349,8 +36597,8 @@ class Gauge(Control): A gauge is a horizontal or vertical bar which shows a quantity (often time). """ - - def __init__(self, *args, **kw): + @overload + def __init__(self): """ Gauge() Gauge(parent, id=ID_ANY, range=100, pos=DefaultPosition, size=DefaultSize, style=GA_HORIZONTAL, validator=DefaultValidator, name=GaugeNameStr) @@ -36358,7 +36606,18 @@ class Gauge(Control): A gauge is a horizontal or vertical bar which shows a quantity (often time). """ - + @overload + def __init__( + self, + parent: Window, + id: WindowID = ID_ANY, + range: int = 100, + pos: Point = DefaultPosition, + size: SizeType = DefaultSize, + style: int = GA_HORIZONTAL, + validator: Validator = DefaultValidator, + name: str = GaugeNameStr, + ): ... def Create( self, parent, @@ -36383,7 +36642,7 @@ class Gauge(Control): Returns the maximum position of the gauge. """ - def GetValue(self): + def GetValue(self) -> int: """ GetValue() -> int @@ -36398,7 +36657,7 @@ class Gauge(Control): false otherwise. """ - def Pulse(self): + def Pulse(self) -> None: """ Pulse() @@ -36414,7 +36673,7 @@ class Gauge(Control): Sets the range (maximum value) of the gauge. """ - def SetValue(self, pos): + def SetValue(self, pos: int) -> None: """ SetValue(pos) @@ -37664,7 +37923,7 @@ EVT_SEARCHCTRL_CANCEL_BTN = wx.PyEventBinder(wxEVT_SEARCHCTRL_CANCEL_BTN, 1) EVT_SEARCHCTRL_SEARCH_BTN = wx.PyEventBinder(wxEVT_SEARCHCTRL_SEARCH_BTN, 1) # -- end-srchctrl --# # -- begin-radiobox --# -RadioBoxNameStr = "" +RadioBoxNameStr: str class RadioBox(Control, ItemContainerImmutable): """ @@ -37675,7 +37934,8 @@ class RadioBox(Control, ItemContainerImmutable): choices. """ - def __init__(self, *args, **kw): + @overload + def __init__(self): """ RadioBox() RadioBox(parent, id=ID_ANY, label=EmptyString, pos=DefaultPosition, size=DefaultSize, choices=[], majorDimension=0, style=RA_SPECIFY_COLS, validator=DefaultValidator, name=RadioBoxNameStr) @@ -37683,7 +37943,20 @@ class RadioBox(Control, ItemContainerImmutable): A radio box item is used to select one of number of mutually exclusive choices. """ - + @overload + def __init__( + self, + parent: Window, + id: WindowID = ID_ANY, + label: str = EmptyString, + pos: Point = DefaultPosition, + size: SizeType = DefaultSize, + choices: Sequence[str] = [], + majorDimension: int = 0, + style: int = RA_SPECIFY_COLS, + validator: Validator = DefaultValidator, + name: str = RadioBoxNameStr, + ): ... def Create( self, parent, @@ -37785,7 +38058,7 @@ class RadioBox(Control, ItemContainerImmutable): Sets the tooltip text for the specified item in the radio group. """ - def SetSelection(self, n): + def SetSelection(self, n: int) -> None: """ SetSelection(n) @@ -37820,7 +38093,7 @@ class RadioBox(Control, ItemContainerImmutable): Sets the label for the given item. """ - def GetSelection(self): + def GetSelection(self) -> int: """ GetSelection() -> int @@ -37865,8 +38138,8 @@ class RadioButton(Control): A radio button item is a button which usually denotes one of several mutually exclusive options. """ - - def __init__(self, *args, **kw): + @overload + def __init__(self): """ RadioButton() RadioButton(parent, id=ID_ANY, label=EmptyString, pos=DefaultPosition, size=DefaultSize, style=0, validator=DefaultValidator, name=RadioButtonNameStr) @@ -37874,7 +38147,18 @@ class RadioButton(Control): A radio button item is a button which usually denotes one of several mutually exclusive options. """ - + @overload + def __init__( + self, + parent: Window, + id: WindowID = ID_ANY, + label: str = EmptyString, + pos: Point = DefaultPosition, + size: SizeType = DefaultSize, + style: int = 0, + validator: Validator = DefaultValidator, + name: str = RadioButtonNameStr, + ): ... def Create( self, parent, @@ -37892,14 +38176,14 @@ class RadioButton(Control): Creates the choice for two-step construction. """ - def GetValue(self): + def GetValue(self) -> bool: """ GetValue() -> bool Returns true if the radio button is checked, false otherwise. """ - def SetValue(self, value): + def SetValue(self, value: bool) -> None: """ SetValue(value) @@ -37975,8 +38259,8 @@ class Slider(Control): A slider is a control with a handle which can be pulled back and forth to change the value. """ - - def __init__(self, *args, **kw): + @overload + def __init__(self): """ Slider() Slider(parent, id=ID_ANY, value=0, minValue=0, maxValue=100, pos=DefaultPosition, size=DefaultSize, style=SL_HORIZONTAL, validator=DefaultValidator, name=SliderNameStr) @@ -37984,7 +38268,20 @@ class Slider(Control): A slider is a control with a handle which can be pulled back and forth to change the value. """ - + @overload + def __init__( + self, + parent: Window, + id: WindowID = ID_ANY, + value: int = 0, + minValue: int = 0, + maxValue: int = 100, + pos: Point = DefaultPosition, + size: SizeType = DefaultSize, + style: int = SL_HORIZONTAL, + validator: Validator = DefaultValidator, + name: str = SliderNameStr, + ): ... def ClearSel(self): """ ClearSel() @@ -38074,7 +38371,7 @@ class Slider(Control): Returns the tick frequency. """ - def GetValue(self): + def GetValue(self) -> int: """ GetValue() -> int @@ -38669,14 +38966,14 @@ class ToggleButton(AnyButton): Creates the toggle button for two-step construction. """ - def GetValue(self): + def GetValue(self) -> bool: """ GetValue() -> bool Gets the state of the toggle button. """ - def SetValue(self, state): + def SetValue(self, state: bool) -> None: """ SetValue(state) @@ -42407,7 +42704,7 @@ class FilePickerCtrl(PickerBase): Creates this widget with the given parameters. """ - def GetPath(self): + def GetPath(self) -> str: """ GetPath() -> String @@ -44592,14 +44889,14 @@ class TopLevelWindow(NonOwnedWindow): Returns true if the platform supports making the window translucent. """ - def CenterOnScreen(self, direction=BOTH): + def CenterOnScreen(self, direction: int = BOTH) -> None: """ CenterOnScreen(direction=BOTH) A synonym for CentreOnScreen(). """ - def CentreOnScreen(self, direction=BOTH): + def CentreOnScreen(self, direction: int = BOTH) -> None: """ CentreOnScreen(direction=BOTH) @@ -44706,7 +45003,7 @@ class TopLevelWindow(NonOwnedWindow): Returns true if the window is maximized. """ - def Layout(self): + def Layout(self) -> bool: """ Layout() -> bool @@ -44805,7 +45102,7 @@ class TopLevelWindow(NonOwnedWindow): size increments. """ - def SetTitle(self, title): + def SetTitle(self, title: str) -> None: """ SetTitle(title) @@ -44951,8 +45248,8 @@ class Dialog(TopLevelWindow): A dialog box is a window with a title bar and sometimes a system menu, which can be moved around the screen. """ - - def __init__(self, *args, **kw): + @overload + def __init__(self): """ Dialog() Dialog(parent, id=ID_ANY, title=EmptyString, pos=DefaultPosition, size=DefaultSize, style=DEFAULT_DIALOG_STYLE, name=DialogNameStr) @@ -44960,7 +45257,17 @@ class Dialog(TopLevelWindow): A dialog box is a window with a title bar and sometimes a system menu, which can be moved around the screen. """ - + @overload + def __init__( + self, + parent: Window | None, + id: WindowID = ID_ANY, + title: str = EmptyString, + pos: Point = DefaultPosition, + size: SizeType = DefaultSize, + style: int = DEFAULT_DIALOG_STYLE, + name: str = DialogNameStr, + ): ... def AddMainButtonId(self, id): """ AddMainButtonId(id) @@ -44978,7 +45285,7 @@ class Dialog(TopLevelWindow): on the display. """ - def Centre(self, direction=BOTH): + def Centre(self, direction: int = BOTH) -> None: """ Centre(direction=BOTH) @@ -45198,7 +45505,7 @@ class Dialog(TopLevelWindow): Sets the adaptation mode, overriding the global adaptation flag. """ - def SetReturnCode(self, retCode): + def SetReturnCode(self, retCode: int) -> None: """ SetReturnCode(retCode) @@ -45212,7 +45519,7 @@ class Dialog(TopLevelWindow): Hides or shows the dialog. """ - def ShowModal(self): + def ShowModal(self) -> int: """ ShowModal() -> int @@ -45375,13 +45682,13 @@ class DirDialog(Dialog): def __init__( self, - parent, - message=DirSelectorPromptStr, - defaultPath=EmptyString, - style=DD_DEFAULT_STYLE, - pos=DefaultPosition, - size=DefaultSize, - name=DirDialogNameStr, + parent: Window, + message: str = DirSelectorPromptStr, + defaultPath: str = EmptyString, + style: int = DD_DEFAULT_STYLE, + pos: Point = DefaultPosition, + size: Size = DefaultSize, + name: str = DirDialogNameStr, ): """ DirDialog(parent, message=DirSelectorPromptStr, defaultPath=EmptyString, style=DD_DEFAULT_STYLE, pos=DefaultPosition, size=DefaultSize, name=DirDialogNameStr) @@ -45396,7 +45703,7 @@ class DirDialog(Dialog): Returns the message that will be displayed on the dialog. """ - def GetPath(self): + def GetPath(self) -> str: """ GetPath() -> String @@ -45424,7 +45731,7 @@ class DirDialog(Dialog): Sets the default path. """ - def ShowModal(self): + def ShowModal(self) -> int: """ ShowModal() -> int @@ -45803,7 +46110,7 @@ class FileDialog(Dialog): use GetFilename for the others. """ - def GetFilterIndex(self): + def GetFilterIndex(self) -> int: """ GetFilterIndex() -> int @@ -45818,14 +46125,14 @@ class FileDialog(Dialog): Returns the message that will be displayed on the dialog. """ - def GetPath(self): + def GetPath(self) -> str: """ GetPath() -> String Returns the full path (directory and filename) of the selected file. """ - def GetPaths(self): + def GetPaths(self) -> list[str]: """ GetPaths() -> ArrayString @@ -45862,7 +46169,7 @@ class FileDialog(Dialog): Sets the default filename. """ - def SetFilterIndex(self, filterIndex): + def SetFilterIndex(self, filterIndex: int) -> None: """ SetFilterIndex(filterIndex) @@ -45892,7 +46199,7 @@ class FileDialog(Dialog): "BMP files (*.bmp)|*.bmp|GIF files (*.gif)|*.gif". """ - def ShowModal(self): + def ShowModal(self) -> int: """ ShowModal() -> int @@ -46402,7 +46709,12 @@ class MessageDialog(Dialog): """ def __init__( - self, parent, message, caption=MessageBoxCaptionStr, style=OK | CENTRE, pos=DefaultPosition + self, + parent: Window | None, + message: str, + caption: str = MessageBoxCaptionStr, + style: int = OK | CENTRE, + pos: Point = DefaultPosition, ): """ MessageDialog(parent, message, caption=MessageBoxCaptionStr, style=OK|CENTRE, pos=DefaultPosition) @@ -46462,7 +46774,7 @@ class MessageDialog(Dialog): Overrides the default labels of the Yes and No buttons. """ - def ShowModal(self): + def ShowModal(self) -> int: """ ShowModal() -> int @@ -46544,12 +46856,12 @@ class MessageDialog(Dialog): # end of class MessageDialog def MessageBox( - message, - caption=MessageBoxCaptionStr, - style=OK | CENTRE, - parent=None, - x=DefaultCoord, - y=DefaultCoord, + message: str, + caption: str = MessageBoxCaptionStr, + style: int = OK | CENTRE, + parent: Window | None = None, + x: int = DefaultCoord, + y: int = DefaultCoord, ): """ MessageBox(message, caption=MessageBoxCaptionStr, style=OK|CENTRE, parent=None, x=DefaultCoord, y=DefaultCoord) -> int @@ -46940,7 +47252,14 @@ class ProgressDialog(GenericProgressDialog): wxGenericProgressDialog. """ - def __init__(self, title, message, maximum=100, parent=None, style=PD_APP_MODAL | PD_AUTO_HIDE): + def __init__( + self, + title: str, + message: str, + maximum: int = 100, + parent: Window | None = None, + style: int = PD_APP_MODAL | PD_AUTO_HIDE, + ): """ ProgressDialog(title, message, maximum=100, parent=None, style=PD_APP_MODAL|PD_AUTO_HIDE) @@ -46974,7 +47293,7 @@ class ProgressDialog(GenericProgressDialog): the constructor is returned. """ - def Pulse(self, newmsg=EmptyString): + def Pulse(self, newmsg: str = EmptyString) -> tuple[bool, bool]: """ Pulse(newmsg=EmptyString) -> (bool, skip) @@ -46997,7 +47316,7 @@ class ProgressDialog(GenericProgressDialog): constructor. """ - def WasCancelled(self): + def WasCancelled(self) -> bool: """ WasCancelled() -> bool @@ -47011,7 +47330,7 @@ class ProgressDialog(GenericProgressDialog): Returns true if the "Skip" button was pressed. """ - def Update(self, value, newmsg=EmptyString): + def Update(self, value: int, newmsg: str = EmptyString) -> tuple[bool, bool]: """ Update(value, newmsg=EmptyString) -> (bool, skip) @@ -47200,7 +47519,7 @@ class ColourData(Object): opacity selector. """ - def GetColour(self): + def GetColour(self) -> Colour: """ GetColour() -> Colour @@ -47214,7 +47533,7 @@ class ColourData(Object): Returns custom colours associated with the colour dialog. """ - def SetChooseFull(self, flag): + def SetChooseFull(self, flag: bool) -> None: """ SetChooseFull(flag) @@ -47230,7 +47549,7 @@ class ColourData(Object): (slider). """ - def SetColour(self, colour): + def SetColour(self, colour: ColourType) -> None: """ SetColour(colour) @@ -47272,7 +47591,7 @@ class ColourDialog(Dialog): This class represents the colour chooser dialog. """ - def __init__(self, parent, data=None): + def __init__(self, parent: Window | None, data: ColourData | None = None): """ ColourDialog(parent, data=None) @@ -47286,14 +47605,14 @@ class ColourDialog(Dialog): Same as wxColourDialog(). """ - def GetColourData(self): + def GetColourData(self) -> ColourData: """ GetColourData() -> ColourData Returns the colour data associated with the colour dialog. """ - def ShowModal(self): + def ShowModal(self) -> int: """ ShowModal() -> int @@ -47425,7 +47744,7 @@ class SingleChoiceDialog(Dialog): allows the user to select one. """ - def GetSelection(self): + def GetSelection(self) -> int: """ GetSelection() -> int @@ -48346,8 +48665,8 @@ class TextEntryDialog(Dialog): This class represents a dialog that requests a one-line text string from the user. """ - - def __init__(self, *args, **kw): + @overload + def __init__(self): """ TextEntryDialog() TextEntryDialog(parent, message, caption=GetTextFromUserPromptStr, value=EmptyString, style=TextEntryDialogStyle, pos=DefaultPosition) @@ -48355,7 +48674,16 @@ class TextEntryDialog(Dialog): This class represents a dialog that requests a one-line text string from the user. """ - + @overload + def __init__( + self, + parent: Window | None, + message: str, + caption: str = GetTextFromUserPromptStr, + value: str = EmptyString, + style: int = TextEntryDialogStyle, + pos: Point = DefaultPosition, + ): ... def Create( self, parent, @@ -48369,7 +48697,7 @@ class TextEntryDialog(Dialog): Create(parent, message, caption=GetTextFromUserPromptStr, value=EmptyString, style=TextEntryDialogStyle, pos=DefaultPosition) -> bool """ - def GetValue(self): + def GetValue(self) -> str: """ GetValue() -> String @@ -48400,7 +48728,7 @@ class TextEntryDialog(Dialog): upper case. """ - def ShowModal(self): + def ShowModal(self) -> int: """ ShowModal() -> int @@ -48763,7 +49091,7 @@ def GetKeyState(key): For normal keys, returns true if the specified key is currently down. """ -def GetMousePosition(): +def GetMousePosition() -> Point: """ GetMousePosition() -> Point @@ -48821,7 +49149,7 @@ def LaunchDefaultApplication(document, flags=0): this type. """ -def LaunchDefaultBrowser(url, flags=0): +def LaunchDefaultBrowser(url: str, flags: int = 0) -> bool: """ LaunchDefaultBrowser(url, flags=0) -> bool @@ -50169,7 +50497,9 @@ class ArtProvider(Object): """ @staticmethod - def GetBitmap(id, client=ART_OTHER, size=DefaultSize): + def GetBitmap( + id: ArtID, client: ArtClient = ART_OTHER, size: SizeType | tuple[float, float] = DefaultSize + ) -> Bitmap: """ GetBitmap(id, client=ART_OTHER, size=DefaultSize) -> Bitmap diff --git a/typings/wx-stubs/type_defs.pyi b/typings/wx-stubs/type_defs.pyi new file mode 100644 index 000000000..9c942c32b --- /dev/null +++ b/typings/wx-stubs/type_defs.pyi @@ -0,0 +1,33 @@ +from typing import Any + +import wx + +SystemFont = int +Coord = int +EventType = int +PolygonFillMode = int +PenStyle = int +PenCap = int +BrushStyle = int +WindowID = int +ArtID = str +ArtClient = str +WindowVariant = int +BitmapType = int +ClientData = Any + +ColourType = ( + tuple[int, int, int] + | tuple[int, int, int, int] + | list[int] + | wx.Colour + | tuple[float, float, float, float] + | str +) +SizeType = tuple[int, int] | list[int] | wx.Size +GBPositionType = tuple[int, int] | list[int] | wx.GBPosition +GBSpanType = tuple[int, int] | list[int] | wx.GBSpan + +class wxAssertionError(AssertionError): ... +class PyAssertionError(wxAssertionError): ... +class PyNoAppError(RuntimeError): ... diff --git a/typings/wx/type_defs.pyi b/typings/wx/type_defs.pyi deleted file mode 100644 index 9f2de419e..000000000 --- a/typings/wx/type_defs.pyi +++ /dev/null @@ -1,18 +0,0 @@ -import wx - -SystemFont = int -Coord = int -EventType = int -PolygonFillMode = int -PenStyle = int -PenCap = int -BrushStyle = int - -ColourType = ( - tuple[int, int, int] - | tuple[int, int, int, int] - | list[int] - | wx.Colour - | tuple[float, float, float, float] - | str -) From 3a381718d50ebeafefa6bfcad159ddd0e5f22412 Mon Sep 17 00:00:00 2001 From: Henrik Kauppi Date: Tue, 27 Aug 2024 13:29:49 +0300 Subject: [PATCH 06/10] ENH: Remove unnecessary text next to the new, load, and save buttons in TMS coil preferences --- invesalius/gui/preferences.py | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/invesalius/gui/preferences.py b/invesalius/gui/preferences.py index cbca9968a..ddae6e350 100644 --- a/invesalius/gui/preferences.py +++ b/invesalius/gui/preferences.py @@ -504,9 +504,9 @@ def __init__(self, parent, navigation, tracker, pedal_connector, neuronavigation lbl = wx.StaticText(self, -1, _("Current Configuration:")) lbl.SetFont(wx.Font(9, wx.DEFAULT, wx.NORMAL, wx.BOLD)) - lbl_new = wx.StaticText(self, -1, _("Create new configuration: ")) - lbl_load = wx.StaticText(self, -1, _("Load configuration from file: ")) - lbl_save = wx.StaticText(self, -1, _("Save configuration to file: ")) + + # Empty cell for the grid sizer + empty_cell = (0, 0) load_sizer = wx.StaticBoxSizer(wx.VERTICAL, self, _("TMS coil registration")) inner_load_sizer = wx.FlexGridSizer(2, 4, 5) @@ -514,12 +514,12 @@ def __init__(self, parent, navigation, tracker, pedal_connector, neuronavigation [ (lbl, 1, wx.EXPAND | wx.ALIGN_CENTER_VERTICAL, 5), (config_txt, 1, wx.EXPAND | wx.ALIGN_CENTER_VERTICAL, 5), - (lbl_new, 1, wx.EXPAND | wx.ALIGN_CENTER_VERTICAL, 5), (btn_new, 1, wx.EXPAND | wx.ALIGN_CENTER_VERTICAL, 5), - (lbl_load, 1, wx.EXPAND | wx.ALIGN_CENTER_VERTICAL, 5), + empty_cell, (btn_load, 1, wx.EXPAND | wx.ALIGN_CENTER_VERTICAL, 5), - (lbl_save, 1, wx.EXPAND | wx.ALIGN_CENTER_VERTICAL, 5), + empty_cell, (btn_save, 1, wx.EXPAND | wx.ALIGN_CENTER_VERTICAL, 5), + empty_cell, ] ) load_sizer.Add(inner_load_sizer, 0, wx.ALL | wx.EXPAND, 10) From 2d8ae4665c55f97c8a81e8fb42d9fff04f302ca5 Mon Sep 17 00:00:00 2001 From: Henrik Kauppi Date: Tue, 27 Aug 2024 13:41:34 +0300 Subject: [PATCH 07/10] ENH: Rename 'Start neuronavigation' button as 'Start navigation' --- invesalius/gui/task_navigator.py | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/invesalius/gui/task_navigator.py b/invesalius/gui/task_navigator.py index c120d0d72..8b3aeeb15 100644 --- a/invesalius/gui/task_navigator.py +++ b/invesalius/gui/task_navigator.py @@ -1165,7 +1165,7 @@ def __init__(self, parent, nav_hub): # Toggle button for neuronavigation tooltip = _("Start navigation") - btn_nav = wx.ToggleButton(self, -1, _("Start neuronavigation"), size=wx.Size(80, -1)) + btn_nav = wx.ToggleButton(self, -1, _("Start navigation"), size=wx.Size(80, -1)) btn_nav.SetFont(wx.Font(9, wx.DEFAULT, wx.NORMAL, wx.BOLD)) btn_nav.SetToolTip(tooltip) self.btn_nav = btn_nav @@ -1491,15 +1491,15 @@ def OnStartNavigationButton(self, evt, btn_nav): nav_id = btn_nav.GetValue() if not nav_id: wx.CallAfter(Publisher.sendMessage, "Stop navigation") - tooltip = _("Start neuronavigation") + tooltip = _("Start navigation") btn_nav.SetToolTip(tooltip) - btn_nav.SetLabelText(_("Start neuronavigation")) + btn_nav.SetLabelText(_("Start navigation")) else: Publisher.sendMessage("Start navigation") if self.nav_status: - tooltip = _("Stop neuronavigation") + tooltip = _("Stop navigation") btn_nav.SetToolTip(tooltip) - btn_nav.SetLabelText(_("Stop neuronavigation")) + btn_nav.SetLabelText(_("Stop navigation")) else: btn_nav.SetValue(False) From 71c843d4a169dc7b2a7f02a873c763b605620409 Mon Sep 17 00:00:00 2001 From: Henrik Kauppi Date: Tue, 27 Aug 2024 14:29:08 +0300 Subject: [PATCH 08/10] ENH: Clicking start patient registration when tracker is not selected opens tracker selection in preferemces --- invesalius/gui/task_navigator.py | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-) diff --git a/invesalius/gui/task_navigator.py b/invesalius/gui/task_navigator.py index 8b3aeeb15..66633f462 100644 --- a/invesalius/gui/task_navigator.py +++ b/invesalius/gui/task_navigator.py @@ -436,19 +436,19 @@ def __init__(self, parent, nav_hub): sizer = wx.GridBagSizer(5, 5) sizer.Add( - self.btns_set_fiducial[0], # Left Ear + self.btns_set_fiducial[0], # Left Ear wx.GBPosition(1, 0), span=wx.GBSpan(1, 2), flag=wx.ALIGN_CENTER_VERTICAL, ) sizer.Add( - self.btns_set_fiducial[2], # Nasion + self.btns_set_fiducial[2], # Nasion wx.GBPosition(0, 2), span=wx.GBSpan(1, 2), flag=wx.ALIGN_CENTER_HORIZONTAL, ) sizer.Add( - self.btns_set_fiducial[1], # Right Ear + self.btns_set_fiducial[1], # Right Ear wx.GBPosition(1, 3), span=wx.GBSpan(1, 2), flag=wx.ALIGN_CENTER_VERTICAL, @@ -672,19 +672,19 @@ def __init__(self, parent, nav_hub): sizer = wx.GridBagSizer(5, 5) sizer.Add( - self.fiducial_buttons[0], # Left Ear + self.fiducial_buttons[0], # Left Ear wx.GBPosition(1, 0), span=wx.GBSpan(1, 2), flag=wx.ALIGN_CENTER_VERTICAL, ) sizer.Add( - self.fiducial_buttons[2], # Nasion + self.fiducial_buttons[2], # Nasion wx.GBPosition(0, 2), span=wx.GBSpan(1, 2), flag=wx.ALIGN_CENTER_HORIZONTAL, ) sizer.Add( - self.fiducial_buttons[1], # Right Ear + self.fiducial_buttons[1], # Right Ear wx.GBPosition(1, 3), span=wx.GBSpan(1, 2), flag=wx.ALIGN_CENTER_VERTICAL, @@ -730,7 +730,9 @@ def UpdateElements(self): def StartRegistration(self): if not self.tracker.IsTrackerInitialized(): self.start_button.SetValue(False) - dlg.ShowNavigationTrackerWarning(0, "choose") + # Open the tracker page in preferences + Publisher.sendMessage("Open preferences menu", page=2) + self.StartRegistration() return self.registration_on = True From b968592b9a553b049dd26d5464e233cf7142d11b Mon Sep 17 00:00:00 2001 From: rmatsuda Date: Wed, 28 Aug 2024 13:04:48 +0300 Subject: [PATCH 09/10] REM: robot ros in api for back compatibility --- invesalius/net/neuronavigation_api.py | 68 +++++++++++++-------------- 1 file changed, 34 insertions(+), 34 deletions(-) diff --git a/invesalius/net/neuronavigation_api.py b/invesalius/net/neuronavigation_api.py index 47f39659c..83b89152e 100644 --- a/invesalius/net/neuronavigation_api.py +++ b/invesalius/net/neuronavigation_api.py @@ -76,32 +76,32 @@ def __bind_events(self): Publisher.subscribe(self.update_tracker_poses, "From Neuronavigation: Update tracker poses") Publisher.subscribe(self.update_target_orientation, "Update target orientation") Publisher.subscribe(self.connect_to_robot, "Neuronavigation to Robot: Connect to robot") - Publisher.subscribe(self.set_target, "Neuronavigation to Robot: Set target") - Publisher.subscribe(self.unset_target, "Neuronavigation to Robot: Unset target") - Publisher.subscribe( - self.set_tracker_fiducials, "Neuronavigation to Robot: Set tracker fiducials" - ) - Publisher.subscribe( - self.collect_robot_pose, - "Neuronavigation to Robot: Collect coordinates for the robot transformation matrix", - ) - Publisher.subscribe( - self.reset_robot_transformation_matrix, - "Neuronavigation to Robot: Reset coordinates collection for the robot transformation matrix", - ) - Publisher.subscribe( - self.estimate_robot_transformation_matrix, - "Neuronavigation to Robot: Estimate robot transformation matrix", - ) - Publisher.subscribe( - self.set_robot_transformation_matrix, - "Neuronavigation to Robot: Set robot transformation matrix", - ) - Publisher.subscribe( - self.update_displacement_to_target, - "Neuronavigation to Robot: Update displacement to target", - ) - Publisher.subscribe(self.set_objective, "Neuronavigation to Robot: Set objective") + # Publisher.subscribe(self.set_target, "Neuronavigation to Robot: Set target") + # Publisher.subscribe(self.unset_target, "Neuronavigation to Robot: Unset target") + # Publisher.subscribe( + # self.set_tracker_fiducials, "Neuronavigation to Robot: Set tracker fiducials" + # ) + # Publisher.subscribe( + # self.collect_robot_pose, + # "Neuronavigation to Robot: Collect coordinates for the robot transformation matrix", + # ) + # Publisher.subscribe( + # self.reset_robot_transformation_matrix, + # "Neuronavigation to Robot: Reset coordinates collection for the robot transformation matrix", + # ) + # Publisher.subscribe( + # self.estimate_robot_transformation_matrix, + # "Neuronavigation to Robot: Estimate robot transformation matrix", + # ) + # Publisher.subscribe( + # self.set_robot_transformation_matrix, + # "Neuronavigation to Robot: Set robot transformation matrix", + # ) + # Publisher.subscribe( + # self.update_displacement_to_target, + # "Neuronavigation to Robot: Update displacement to target", + # ) + # Publisher.subscribe(self.set_objective, "Neuronavigation to Robot: Set objective") # Functions for InVesalius to send updates. @@ -309,14 +309,14 @@ def update_efield_vectorROIMax(self, position, orientation, T_rot, id_list): def __set_callbacks(self, connection): connection.set_callback__open_orientation_dialog(self.open_orientation_dialog) connection.set_callback__stimulation_pulse_received(self.stimulation_pulse_received) - connection.set_callback__update_robot_status(self.update_robot_status) - connection.set_callback__robot_connection_status(self.robot_connection_status) - connection.set_callback__robot_pose_collected(self.robot_pose_collected) - connection.set_callback__set_objective(self.set_objective_to_neuronavigation) - connection.set_callback__close_robot_dialog(self.close_robot_dialog) - connection.set_callback__update_robot_transformation_matrix( - self.update_robot_transformation_matrix - ) + # connection.set_callback__update_robot_status(self.update_robot_status) + # connection.set_callback__robot_connection_status(self.robot_connection_status) + # connection.set_callback__robot_pose_collected(self.robot_pose_collected) + # connection.set_callback__set_objective(self.set_objective_to_neuronavigation) + # connection.set_callback__close_robot_dialog(self.close_robot_dialog) + # connection.set_callback__update_robot_transformation_matrix( + # self.update_robot_transformation_matrix + # ) connection.set_callback__set_vector_field(self.set_vector_field) def add_pedal_callback(self, name, callback, remove_when_released=False): From ce7aa71f49216a109f05e96c4d67efdef379fd4d Mon Sep 17 00:00:00 2001 From: rmatsuda Date: Wed, 28 Aug 2024 13:23:43 +0300 Subject: [PATCH 10/10] REM: robot ros in api for back compatibility, missing connecttorobot --- invesalius/net/neuronavigation_api.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/invesalius/net/neuronavigation_api.py b/invesalius/net/neuronavigation_api.py index 83b89152e..30534f912 100644 --- a/invesalius/net/neuronavigation_api.py +++ b/invesalius/net/neuronavigation_api.py @@ -75,7 +75,7 @@ def __bind_events(self): Publisher.subscribe(self.update_coil_at_target, "Coil at target") Publisher.subscribe(self.update_tracker_poses, "From Neuronavigation: Update tracker poses") Publisher.subscribe(self.update_target_orientation, "Update target orientation") - Publisher.subscribe(self.connect_to_robot, "Neuronavigation to Robot: Connect to robot") + # Publisher.subscribe(self.connect_to_robot, "Neuronavigation to Robot: Connect to robot") # Publisher.subscribe(self.set_target, "Neuronavigation to Robot: Set target") # Publisher.subscribe(self.unset_target, "Neuronavigation to Robot: Unset target") # Publisher.subscribe(