diff --git a/addon/appModules/captvty.py b/addon/appModules/captvty.py index 5112196..085561c 100644 --- a/addon/appModules/captvty.py +++ b/addon/appModules/captvty.py @@ -400,13 +400,13 @@ def get_program_info( try: program = Program(element.name) - program_info = f"{program.name} | Durée: {program.duration} | Sommaire: {program.summary}" + program_info = f"{program.name}{f' | Durée: {program.duration}' if program.duration else ''}{f' | Sommaire : {program.summary}' if program.summary else ''}" return program_info except ( AttributeError, IndexError, ): # The element is not a program - log.info("Nuh uh, not a program") + log.debug(f"Element is not a program: {element.name}") return None def selected_program_callback( diff --git a/addon/appModules/modules/helper_functions.py b/addon/appModules/modules/helper_functions.py index d45e89c..4e1aeef 100644 --- a/addon/appModules/modules/helper_functions.py +++ b/addon/appModules/modules/helper_functions.py @@ -8,7 +8,7 @@ import winUser from logHandler import log from NVDAObjects import NVDAObject -from NVDAObjects.IAccessible import IAccessible +from NVDAObjects.IAccessible import IAccessible, getNVDAObjectFromEvent class AppModes(IntEnum): @@ -379,3 +379,30 @@ def scroll_and_click_on_element( bounds_offset=bounds_offset, ) left_click_element_with_mouse(element, x_offset, y_offset) + + +def reacquire_element( + element: Union[NVDAObject, IAccessible] +) -> Union[IAccessible, None]: + """Reacquires the element by index in group. + This is useful when the element is not accessible from the current thread. + + Args: + element (Union[NVDAObject, IAccessible]): The element to reacquire. + + Returns: + Union[IAccessible, None]: The reacquired element or None if not found. + """ + position_info = getattr(element, "positionInfo", None) + + index_in_group = position_info.get("indexInGroup") if position_info else None + + if index_in_group: + reacquired_element = getNVDAObjectFromEvent( + element.windowHandle, + winUser.OBJID_CLIENT, + index_in_group, + ) + + return reacquired_element + return None diff --git a/addon/appModules/modules/list_elements.py b/addon/appModules/modules/list_elements.py index 184b0ba..933a1a9 100644 --- a/addon/appModules/modules/list_elements.py +++ b/addon/appModules/modules/list_elements.py @@ -1,15 +1,14 @@ import threading from typing import Any, Callable, List, Optional, Union -import winUser import wx from gui import guiHelper from logHandler import log from NVDAObjects import NVDAObject -from NVDAObjects.IAccessible import IAccessible, getNVDAObjectFromEvent +from NVDAObjects.IAccessible import IAccessible from NVDAObjects.IAccessible.sysListView32 import ListItem -from .helper_functions import normalize_str +from .helper_functions import normalize_str, reacquire_element class VirtualList(wx.ListCtrl): @@ -321,18 +320,9 @@ def worker(elements): new_element_names = [] for element in elements: - position_info = getattr(element, "positionInfo", None) - index_in_group = ( - position_info.get("indexInGroup") if position_info else None - ) - - if index_in_group: - # get the element by index so we can access the element within this thread. - element = getNVDAObjectFromEvent( - element.windowHandle, - winUser.OBJID_CLIENT, - index_in_group, - ) + if isinstance(element, (IAccessible, NVDAObject)): + element = reacquire_element(element) + # log.debug("Reacquired element: %s", element.name) self.element_names.append(self.element_name_getter(element)) diff --git a/addon/appModules/modules/program.py b/addon/appModules/modules/program.py index e6f7331..5123b4b 100644 --- a/addon/appModules/modules/program.py +++ b/addon/appModules/modules/program.py @@ -21,11 +21,28 @@ def __init__(self, unparsed_program: str) -> None: unparsed_program (str): Unparsed string containing program information. """ parsed_program: List[str] = unparsed_program.split("; ") - self.name: str = parsed_program[0] - self.channel: str = parsed_program[1][8:] # Remove "Chaîne: " prefix - self.published_at: str = parsed_program[2][24:] # "Diffusée ou publiée le: " - self.duration: str = parsed_program[3][7:] # "Durée: " - self.summary: str = parsed_program[4][8:] # "Résumé: " + + self.name: str = parsed_program.pop(0).strip() + + if "Chaîne" in parsed_program[0]: + self.channel = parsed_program.pop(0).split(":")[1].strip() + else: + self.channel = None + + if "Diffusée ou publiée le" in parsed_program[0]: + self.published_at = parsed_program.pop(0).split(":")[1].strip() + else: + self.published_at = None + + if "Durée" in parsed_program[0]: + self.duration = parsed_program.pop(0).split(":")[1].strip() + else: + self.duration = None + + if "Résumé" in parsed_program[0]: + self.summary = parsed_program.pop(0).split(":")[1].strip() + else: + self.summary = None def __str__(self) -> str: """