From 50bfc8b0d1e6aaf9c82f209fb319ea864320989e Mon Sep 17 00:00:00 2001 From: buddsean Date: Thu, 24 Jun 2021 21:04:13 +1000 Subject: [PATCH 1/2] split controlTypes.py into submodules (#12510) The file controlTypes.py is already very complex and long, and the code can easily be divided into 5 groups. With the desire to group constants into Enums and maintain backwards compatibility, which adds length and complexity, it is a canidate to be split into submodules. Actions: - move controlTypes role data and functions to role.py - move controlTypes state data and functions to state.py - move isCurrent class to isCurrent.py - move outputReason to outputReason.py - move processing states functions to processAndLabelStates.py --- source/controlTypes.py | 869 ------------------- source/controlTypes/__init__.py | 0 source/controlTypes/isCurrent.py | 55 ++ source/controlTypes/outputReason.py | 31 + source/controlTypes/processAndLabelStates.py | 180 ++++ source/controlTypes/role.py | 490 +++++++++++ source/controlTypes/state.py | 147 ++++ 7 files changed, 903 insertions(+), 869 deletions(-) delete mode 100644 source/controlTypes.py create mode 100644 source/controlTypes/__init__.py create mode 100644 source/controlTypes/isCurrent.py create mode 100644 source/controlTypes/outputReason.py create mode 100644 source/controlTypes/processAndLabelStates.py create mode 100644 source/controlTypes/role.py create mode 100644 source/controlTypes/state.py diff --git a/source/controlTypes.py b/source/controlTypes.py deleted file mode 100644 index 54d1e535852..00000000000 --- a/source/controlTypes.py +++ /dev/null @@ -1,869 +0,0 @@ -# A part of NonVisual Desktop Access (NVDA) -# This file is covered by the GNU General Public License. -# See the file COPYING for more details. -# Copyright (C) 2007-2021 NV Access Limited, Babbage B.V. - -from typing import Dict, Union, Set, Any, Optional, List -from enum import Enum, auto - -from logHandler import log - -ROLE_UNKNOWN=0 -ROLE_WINDOW=1 -ROLE_TITLEBAR=2 -ROLE_PANE=3 -ROLE_DIALOG=4 -ROLE_CHECKBOX=5 -ROLE_RADIOBUTTON=6 -ROLE_STATICTEXT=7 -ROLE_EDITABLETEXT=8 -ROLE_BUTTON=9 -ROLE_MENUBAR=10 -ROLE_MENUITEM=11 -ROLE_POPUPMENU=12 -ROLE_COMBOBOX=13 -ROLE_LIST=14 -ROLE_LISTITEM=15 -ROLE_GRAPHIC=16 -ROLE_HELPBALLOON=17 -ROLE_TOOLTIP=18 -ROLE_LINK=19 -ROLE_TREEVIEW=20 -ROLE_TREEVIEWITEM=21 -ROLE_TAB=22 -ROLE_TABCONTROL=23 -ROLE_SLIDER=24 -ROLE_PROGRESSBAR=25 -ROLE_SCROLLBAR=26 -ROLE_STATUSBAR=27 -ROLE_TABLE=28 -ROLE_TABLECELL=29 -ROLE_TABLECOLUMN=30 -ROLE_TABLEROW=31 -ROLE_TABLECOLUMNHEADER=32 -ROLE_TABLEROWHEADER=33 -ROLE_FRAME=34 -ROLE_TOOLBAR=35 -ROLE_DROPDOWNBUTTON=36 -ROLE_CLOCK=37 -ROLE_SEPARATOR=38 -ROLE_FORM=39 -ROLE_HEADING=40 -ROLE_HEADING1=41 -ROLE_HEADING2=42 -ROLE_HEADING3=43 -ROLE_HEADING4=44 -ROLE_HEADING5=45 -ROLE_HEADING6=46 -ROLE_PARAGRAPH=47 -ROLE_BLOCKQUOTE=48 -ROLE_TABLEHEADER=49 -ROLE_TABLEBODY=50 -ROLE_TABLEFOOTER=51 -ROLE_DOCUMENT=52 -ROLE_ANIMATION=53 -ROLE_APPLICATION=54 -ROLE_BOX=55 -ROLE_GROUPING=56 -ROLE_PROPERTYPAGE=57 -ROLE_CANVAS=58 -ROLE_CAPTION=59 -ROLE_CHECKMENUITEM=60 -ROLE_DATEEDITOR=61 -ROLE_ICON=62 -ROLE_DIRECTORYPANE=63 -ROLE_EMBEDDEDOBJECT=64 -ROLE_ENDNOTE=65 -ROLE_FOOTER=66 -ROLE_FOOTNOTE=67 -ROLE_GLASSPANE=69 -ROLE_HEADER=70 -ROLE_IMAGEMAP=71 -ROLE_INPUTWINDOW=72 -ROLE_LABEL=73 -ROLE_NOTE=74 -ROLE_PAGE=75 -ROLE_RADIOMENUITEM=76 -ROLE_LAYEREDPANE=77 -ROLE_REDUNDANTOBJECT=78 -ROLE_ROOTPANE=79 -ROLE_EDITBAR=80 -ROLE_TERMINAL=82 -ROLE_RICHEDIT=83 -ROLE_RULER=84 -ROLE_SCROLLPANE=85 -ROLE_SECTION=86 -ROLE_SHAPE=87 -ROLE_SPLITPANE=88 -ROLE_VIEWPORT=89 -ROLE_TEAROFFMENU=90 -ROLE_TEXTFRAME=91 -ROLE_TOGGLEBUTTON=92 -ROLE_BORDER=93 -ROLE_CARET=94 -ROLE_CHARACTER=95 -ROLE_CHART=96 -ROLE_CURSOR=97 -ROLE_DIAGRAM=98 -ROLE_DIAL=99 -ROLE_DROPLIST=100 -ROLE_SPLITBUTTON=101 -ROLE_MENUBUTTON=102 -ROLE_DROPDOWNBUTTONGRID=103 -ROLE_MATH=104 -ROLE_GRIP=105 -ROLE_HOTKEYFIELD=106 -ROLE_INDICATOR=107 -ROLE_SPINBUTTON=108 -ROLE_SOUND=109 -ROLE_WHITESPACE=110 -ROLE_TREEVIEWBUTTON=111 -ROLE_IPADDRESS=112 -ROLE_DESKTOPICON=113 -ROLE_INTERNALFRAME=115 -ROLE_DESKTOPPANE=116 -ROLE_OPTIONPANE=117 -ROLE_COLORCHOOSER=118 -ROLE_FILECHOOSER=119 -ROLE_FILLER=120 -ROLE_MENU=121 -ROLE_PANEL=122 -ROLE_PASSWORDEDIT=123 -ROLE_FONTCHOOSER=124 -ROLE_LINE=125 -ROLE_FONTNAME=126 -ROLE_FONTSIZE=127 -ROLE_BOLD=128 -ROLE_ITALIC=129 -ROLE_UNDERLINE=130 -ROLE_FGCOLOR=131 -ROLE_BGCOLOR=132 -ROLE_SUPERSCRIPT=133 -ROLE_SUBSCRIPT=134 -ROLE_STYLE=135 -ROLE_INDENT=136 -ROLE_ALIGNMENT=137 -ROLE_ALERT=138 -ROLE_DATAGRID=139 -ROLE_DATAITEM=140 -ROLE_HEADERITEM=141 -ROLE_THUMB=142 -ROLE_CALENDAR=143 -ROLE_VIDEO=144 -ROLE_AUDIO=145 -ROLE_CHARTELEMENT=146 -ROLE_DELETED_CONTENT=147 -ROLE_INSERTED_CONTENT=148 -ROLE_LANDMARK = 149 -ROLE_ARTICLE = 150 -ROLE_REGION = 151 -ROLE_FIGURE = 152 -ROLE_MARKED_CONTENT = 153 - -STATE_UNAVAILABLE=0X1 -STATE_FOCUSED=0X2 -STATE_SELECTED=0X4 -STATE_BUSY=0X8 -STATE_PRESSED=0X10 -STATE_CHECKED=0X20 -STATE_HALFCHECKED=0X40 -STATE_READONLY=0X80 -STATE_EXPANDED=0X100 -STATE_COLLAPSED=0X200 -STATE_INVISIBLE=0X400 -STATE_VISITED=0X800 -STATE_LINKED=0X1000 -STATE_HASPOPUP=0X2000 -STATE_PROTECTED=0X4000 -STATE_REQUIRED=0X8000 -STATE_DEFUNCT=0X10000 -STATE_INVALID_ENTRY=0X20000 -STATE_MODAL=0X40000 -STATE_AUTOCOMPLETE=0x80000 -STATE_MULTILINE=0X100000 -STATE_ICONIFIED=0x200000 -STATE_OFFSCREEN=0x400000 -STATE_SELECTABLE=0x800000 -STATE_FOCUSABLE=0x1000000 -STATE_CLICKABLE=0x2000000 -STATE_EDITABLE=0x4000000 -STATE_CHECKABLE=0x8000000 -STATE_DRAGGABLE=0x10000000 -STATE_DRAGGING=0x20000000 -STATE_DROPTARGET=0x40000000 -STATE_SORTED=0x80000000 -STATE_SORTED_ASCENDING=0x100000000 -STATE_SORTED_DESCENDING=0x200000000 -STATES_SORTED=frozenset([STATE_SORTED,STATE_SORTED_ASCENDING,STATE_SORTED_DESCENDING]) -STATE_HASLONGDESC=0x400000000 -STATE_PINNED=0x800000000 -STATE_HASFORMULA=0x1000000000 #Mostly for spreadsheets -STATE_HASCOMMENT=0X2000000000 -STATE_OBSCURED=0x4000000000 -STATE_CROPPED=0x8000000000 -STATE_OVERFLOWING=0x10000000000 -STATE_UNLOCKED=0x20000000000 -STATE_HAS_ARIA_DETAILS = 0x40000000000 - -roleLabels: Dict[int, str] = { - # Translators: The word for an unknown control type. - ROLE_UNKNOWN:_("unknown"), - # Translators: The word for window of a program such as document window. - ROLE_WINDOW:_("window"), - # Translators: Used to identify title bar of a program. - ROLE_TITLEBAR:_("title bar"), - # Translators: The word used for pane such as desktop pane. - ROLE_PANE:_("pane"), - # Translators: The word used to denote a dialog box such as open dialog. - ROLE_DIALOG:_("dialog"), - # Translators: The text used to identify check boxes such as select check box. - ROLE_CHECKBOX:_("check box"), - # Translators: The text used to identify radio buttons such as yes or no radio button. - ROLE_RADIOBUTTON:_("radio button"), - # Translators: The word used to identify a static text such as dialog text. - ROLE_STATICTEXT:_("text"), - # Translators: The word used to identify edit fields such as subject edit field. - ROLE_EDITABLETEXT:_("edit"), - # Translators: The word used to identify a button such as OK button. - ROLE_BUTTON:_("button"), - # Translators: Text used to identify menu bar of a program. - ROLE_MENUBAR:_("menu bar"), - # Translators: Used to identify a menu item such as an item in file menu. - ROLE_MENUITEM:_("menu item"), - # Translators: The word used for menus such as edit menu. - ROLE_POPUPMENU:_("menu"), - # Translators: Used to identify combo boxes such as file type combo box. - ROLE_COMBOBOX:_("combo box"), - # Translators: The word used for lists such as folder list. - ROLE_LIST:_("list"), - # Translators: Used to identify a list item such as email list items. - ROLE_LISTITEM:_("list item"), - # Translators: The word used to identify graphics such as webpage graphics. - ROLE_GRAPHIC:_("graphic"), - # Translators: Used to identify help balloon (a circular window with helpful text such as notification text). - ROLE_HELPBALLOON:_("help balloon"), - # Translators: Used to identify a tooltip (a small window with additional text about selected item such as file information). - ROLE_TOOLTIP:_("tool tip"), - # Translators: Identifies a link in webpage documents. - ROLE_LINK:_("link"), - # Translators: Identifies a treeview (a tree-like structure such as treeviews for subfolders). - ROLE_TREEVIEW:_("tree view"), - # Translators: Identifies a tree view item. - ROLE_TREEVIEWITEM:_("tree view item"), - # Translators: The word presented for tabs in a tab enabled window. - ROLE_TAB: pgettext("controlType", "tab"), - # Translators: Identifies a tab control such as webpage tabs in web browsers. - ROLE_TABCONTROL:_("tab control"), - # Translators: Identifies a slider such as volume slider. - ROLE_SLIDER:_("slider"), - # Translators: Identifies a progress bar such as NvDA update progress. - ROLE_PROGRESSBAR:_("progress bar"), - # Translators: Identifies a scroll bar. - ROLE_SCROLLBAR:_("scroll bar"), - # Translators: Identifies a status bar (text at the bottom bar of the screen such as cursor position in a document). - ROLE_STATUSBAR:_("status bar"), - # Translators: Identifies a table such as ones used in various websites. - ROLE_TABLE:_("table"), - # Translators: Identifies a cell in a table. - ROLE_TABLECELL:_("cell"), - # Translators: Identifies a column (a group of vertical cells in a table). - ROLE_TABLECOLUMN:_("column"), - # Translators: Identifies a row (a group of horizontal cells in a table). - ROLE_TABLEROW:_("row"), - # Translators: Identifies a frame (a smaller window in a webpage or a document). - ROLE_FRAME:_("frame"), - # Translators: Identifies a tool bar. - ROLE_TOOLBAR:_("tool bar"), - # Translators: Identifies a column header in tables and spreadsheets. - ROLE_TABLECOLUMNHEADER:_("column header"), - # Translators: Identifies a row header in tables and spreadsheets. - ROLE_TABLEROWHEADER:_("row header"), - # Translators: Identifies a drop down button (a button that, when clicked, opens a menu of its own). - ROLE_DROPDOWNBUTTON:_("drop down button"), - # Translators: Identifies an element. - ROLE_CLOCK:_("clock"), - # Translators: Identifies a separator (a horizontal line drawn on the screen). - ROLE_SEPARATOR:_("separator"), - # Translators: Identifies a form (controls such as edit boxes, combo boxes and so on). - ROLE_FORM:_("form"), - # Translators: Identifies a heading (a bold text used for identifying a section). - ROLE_HEADING:_("heading"), - # Translators: Identifies a heading level. - ROLE_HEADING1:_("heading 1"), - # Translators: Identifies a heading level. - ROLE_HEADING2:_("heading 2"), - # Translators: Identifies a heading level. - ROLE_HEADING3:_("heading 3"), - # Translators: Identifies a heading level. - ROLE_HEADING4:_("heading 4"), - # Translators: Identifies a heading level. - ROLE_HEADING5:_("heading 5"), - # Translators: Identifies a heading level. - ROLE_HEADING6:_("heading 6"), - # Translators: Identifies a paragraph (a group of text surrounded by blank lines). - ROLE_PARAGRAPH:_("paragraph"), - # Translators: Presented for a section in a document which is a block quotation; - # i.e. a long quotation in a separate paragraph distinguished by indentation, etc. - # See http://en.wikipedia.org/wiki/Block_quotation - ROLE_BLOCKQUOTE:_("block quote"), - # Translators: Identifies a table header (a short text at the start of a table which describes what the table is about). - ROLE_TABLEHEADER:_("table header"), - # Translators: Identifies a table body (the main body of the table). - ROLE_TABLEBODY:_("table body"), - # Translators: Identifies a table footer (text placed at the end of the table). - ROLE_TABLEFOOTER:_("table footer"), - # Translators: Identifies a document (for example, a webpage document). - ROLE_DOCUMENT:_("document"), - # Translators: Identifies an animation in a document or a webpage. - ROLE_ANIMATION:_("animation"), - # Translators: Identifies an application in webpages. - ROLE_APPLICATION:_("application"), - # Translators: Identifies a box element. - ROLE_BOX:_("box"), - # Translators: Identifies a grouping (a number of related items grouped together, such as related options in dialogs). - ROLE_GROUPING:_("grouping"), - # Translators: Identifies a property page such as drive properties dialog. - ROLE_PROPERTYPAGE:_("property page"), - # Translators: Identifies a canvas element on webpages (a box with some background color with some text drawn on the box, like a canvas). - ROLE_CANVAS:_("canvas"), - # Translators: Identifies a caption (usually a short text identifying a picture or a graphic on websites). - ROLE_CAPTION:_("caption"), - # Translators: Identifies a check menu item (a menu item with a checkmark as part of the menu item's name). - ROLE_CHECKMENUITEM:_("check menu item"), - # Translators: Identifies a data edit field. - ROLE_DATEEDITOR:_("date edit"), - # Translators: Identifies an icon. - ROLE_ICON:_("icon"), - # Translators: Identifies a directory pane. - ROLE_DIRECTORYPANE:_("directory pane"), - # Translators: Identifies an object that is embedded in a document. - ROLE_EMBEDDEDOBJECT:_("embedded object"), - # Translators: Identifies an end note. - ROLE_ENDNOTE:_("end note"), - # Translators: Identifies a footer (usually text). - ROLE_FOOTER:_("footer"), - # Translators: Identifies a foot note (text at the end of a passage or used for anotations). - ROLE_FOOTNOTE:_("foot note"), - # Translators: Reported for an object which is a glass pane; i.e. - # a pane that is guaranteed to be on top of all panes beneath it. - ROLE_GLASSPANE:_("glass pane"), - # Translators: Identifies a header (usually text at top of documents or on tops of pages). - ROLE_HEADER:_("header"), - # Translators: Identifies an image map (a type of graphical link). - ROLE_IMAGEMAP:_("image map"), - # Translators: Identifies an input window. - ROLE_INPUTWINDOW:_("input window"), - # Translators: Identifies a label. - ROLE_LABEL:_("label"), - # Translators: Identifies a note field. - ROLE_NOTE:_("note"), - # Translators: Identifies a page. - ROLE_PAGE:_("page"), - # Translators: Identifies a radio menu item. - ROLE_RADIOMENUITEM:_("radio menu item"), - # Translators: Identifies a layered pane. - ROLE_LAYEREDPANE:_("layered pane"), - # Translators: Identifies a redundant object. - ROLE_REDUNDANTOBJECT:_("redundant object"), - # Translators: Identifies a root pane. - ROLE_ROOTPANE:_("root pane"), - # Translators: May be reported for an editable text object in a toolbar. - # This is deprecated and is not often (if ever) used. - ROLE_EDITBAR:_("edit bar"), - # Translators: Identifies a terminal window such as command prompt. - ROLE_TERMINAL:_("terminal"), - # Translators: Identifies a rich edit box (an edit box which allows entering formatting commands in addition to text; encountered on webpages and NvDA log viewer). - ROLE_RICHEDIT:_("rich edit"), - # Translators: Identifies a ruler object (commonly seen on some webpages and in some Office programs). - ROLE_RULER:_("ruler"), - # Translators: Identifies a scroll pane. - ROLE_SCROLLPANE:_("scroll pane"), - # Translators: Identifies a section of text. - ROLE_SECTION:_("section"), - # Translators: Identifies a shape. - ROLE_SHAPE:_("shape"), - # Translators: Identifies a split pane. - ROLE_SPLITPANE:_("split pane"), - # Translators: Reported for a view port; i.e. an object usually used in a scroll pane - # which represents the portion of the entire data that the user can see. - # As the user manipulates the scroll bars, the contents of the view port can change. - ROLE_VIEWPORT:_("view port"), - # Translators: Reported for an object that forms part of a menu system - # but which can be undocked from or torn off the menu system - # to exist as a separate window. - ROLE_TEAROFFMENU:_("tear off menu"), - # Translators: Identifies a text frame (a frame window which contains text). - ROLE_TEXTFRAME:_("text frame"), - # Translators: Identifies a toggle button (a button used to toggle something). - ROLE_TOGGLEBUTTON:_("toggle button"), - ROLE_BORDER:_("border"), - # Translators: Identifies a caret object. - ROLE_CARET:_("caret"), - # Translators: Identifies a character field (should not be confused with edit fields). - ROLE_CHARACTER:_("character"), - # Translators: Identifies a chart (commonly seen on some websites and in some Office documents). - ROLE_CHART:_("chart"), - # Translators: Identifies a cursor object. - ROLE_CURSOR:_("cursor"), - # Translators: Identifies a diagram (seen on some websites and on Office documents). - ROLE_DIAGRAM:_("diagram"), - # Translators: Identifies a dial object. - ROLE_DIAL:_("dial"), - # Translators: Identifies a drop list. - ROLE_DROPLIST:_("drop list"), - # Translators: Identifies a split button (a control which performs different actions when different parts are clicked). - ROLE_SPLITBUTTON:_("split button"), - # Translators: Identifies a menu button (a button which opens a menu of items). - ROLE_MENUBUTTON:_("menu button"), - # Translators: Reported for a button which expands a grid when it is pressed. - ROLE_DROPDOWNBUTTONGRID:_("drop down button grid"), - # Translators: Identifies mathematical content. - ROLE_MATH:_("math"), - # Translators: Identifies a grip control. - ROLE_GRIP:_("grip"), - # Translators: Identifies a hot key field (a field where one can enter a hot key for something, such as assigning shortcut for icons on the desktop). - ROLE_HOTKEYFIELD:_("hot key field"), - # Translators: Identifies an indicator control. - ROLE_INDICATOR:_("indicator"), - # Translators: Identifies a spin button (a button used to go through options in a spinning fashion). - ROLE_SPINBUTTON:_("spin button"), - # Translators: Identifies a sound clip on websites. - ROLE_SOUND:_("sound"), - # Translators: Identifies a whitespace. - ROLE_WHITESPACE:_("white space"), - # Translators: Identifies a tree view button. - ROLE_TREEVIEWBUTTON:_("tree view button"), - # Translators: Identifies an IP address (an IP address field element). - ROLE_IPADDRESS:_("IP address"), - # Translators: Identifies a desktop icon (the icons on the desktop such as computer and various shortcuts for programs). - ROLE_DESKTOPICON:_("desktop icon"), - # Translators: Identifies an internal frame. This is usually a frame on a web page; i.e. a web page embedded within a web page. - ROLE_INTERNALFRAME:_("frame"), - # Translators: Identifies desktop pane (the desktop window). - ROLE_DESKTOPPANE:_("desktop pane"), - # Translators: Identifies an option pane. - ROLE_OPTIONPANE:_("option pane"), - # Translators: Identifies a color chooser. - ROLE_COLORCHOOSER:_("color chooser"), - # Translators: Identifies a file chooser (to select a file or groups of files from a list). - ROLE_FILECHOOSER:_("file chooser"), - ROLE_FILLER:_("filler"), - # Translators: Identifies a menu such as file menu. - ROLE_MENU:_("menu"), - # Translators: Identifies a panel control for grouping related options. - ROLE_PANEL:_("panel"), - # Translators: Identifies a password field (a protected edit field for entering passwords such as when logging into web-based email sites). - ROLE_PASSWORDEDIT:_("password edit"), - # Translators: Identifies a font chooser. - ROLE_FONTCHOOSER:_("font chooser"), - ROLE_LINE:_("line"), - # Translators: Identifies a font name. - ROLE_FONTNAME:_("font name"), - # Translators: Identifies font size. - ROLE_FONTSIZE:_("font size"), - # Translators: Describes text formatting. - ROLE_BOLD:_("bold"), - # Translators: Describes text formatting. - ROLE_ITALIC:_("italic"), - # Translators: Describes text formatting. - ROLE_UNDERLINE:_("underline"), - # Translators: Describes text formatting. - ROLE_FGCOLOR:_("foreground color"), - # Translators: Describes text formatting. - ROLE_BGCOLOR:_("background color"), - # Translators: Describes text formatting. - ROLE_SUPERSCRIPT:_("superscript"), - # Translators: Describes text formatting. - ROLE_SUBSCRIPT:_("subscript"), - # Translators: Describes style of text. - ROLE_STYLE:_("style"), - # Translators: Describes text formatting. - ROLE_INDENT:_("indent"), - # Translators: Describes text formatting. - ROLE_ALIGNMENT:_("alignment"), - # Translators: Identifies an alert window or bar (usually on Internet Explorer 9 and above for alerts such as file downloads or pop-up blocker). - ROLE_ALERT:_("alert"), - # Translators: Identifies a data grid control (a grid which displays data). - ROLE_DATAGRID:_("data grid"), - ROLE_DATAITEM:_("data item"), - ROLE_HEADERITEM:_("header item"), - # Translators: Identifies a thumb control (a button-like control for changing options). - ROLE_THUMB:_("thumb control"), - ROLE_CALENDAR:_("calendar"), - ROLE_VIDEO:_("video"), - ROLE_AUDIO:_("audio"), - # Translators: Identifies a chart element. - ROLE_CHARTELEMENT:_("chart element"), - # Translators: Identifies deleted content. - ROLE_DELETED_CONTENT:_("deleted"), - # Translators: Identifies inserted content. - ROLE_INSERTED_CONTENT:_("inserted"), - # Translators: Identifies a landmark. - ROLE_LANDMARK: _("landmark"), - # Translators: Identifies an article. - ROLE_ARTICLE: _("article"), - # Translators: Identifies a region. - ROLE_REGION: _("region"), - # Translators: Identifies a figure (commonly seen on some websites). - ROLE_FIGURE: _("figure"), - # Translators: Identifies marked (highlighted) content - ROLE_MARKED_CONTENT: _("marked content"), -} - -stateLabels: Dict[int, str] = { - # Translators: This is presented when a control or document is unavailable. - STATE_UNAVAILABLE:_("unavailable"), - # Translators: This is presented when a control has focus. - STATE_FOCUSED:_("focused"), - # Translators: This is presented when the control is selected. - STATE_SELECTED:_("selected"), - # Translators: This is presented when a document is busy. - STATE_BUSY:_("busy"), - # Translators: This is presented when a button is pressed. - STATE_PRESSED:_("pressed"), - # Translators: This is presented when a check box is checked. - STATE_CHECKED:_("checked"), - # Translators: This is presented when a three state check box is half checked. - STATE_HALFCHECKED:_("half checked"), - # Translators: This is presented when the control is a read-only control such as read-only edit box. - STATE_READONLY:_("read only"), - # Translators: This is presented when a tree view or submenu item is expanded. - STATE_EXPANDED:_("expanded"), - # Translators: This is presented when a tree view or submenu is collapsed. - STATE_COLLAPSED:_("collapsed"), - # Translators: This is presented when a control or a document becomes invisible. - STATE_INVISIBLE:_("invisible"), - # Translators: This is presented when a visited link is encountered. - STATE_VISITED:_("visited"), - # Translators: This is presented when a link is encountered. - STATE_LINKED:_("linked"), - # Translators: This is presented when the control menu item has a submenu. - STATE_HASPOPUP:_("subMenu"), - # Translators: This is presented when a protected control or a document is encountered. - STATE_PROTECTED:_("protected"), - # Translators: This is presented when a required form field is encountered. - STATE_REQUIRED:_("required"), - # Translators: Reported when an object no longer exists in the user interface; - # i.e. it is dead and is no longer usable. - STATE_DEFUNCT:_("defunct"), - # Translators: This is presented when an invalid entry has been made. - STATE_INVALID_ENTRY:_("invalid entry"), - STATE_MODAL:_("modal"), - # Translators: This is presented when a field supports auto completion of entered text such as email address field in Microsoft Outlook. - STATE_AUTOCOMPLETE:_("has auto complete"), - # Translators: This is presented when an edit field allows typing multiple lines of text such as comment fields on websites. - STATE_MULTILINE:_("multi line"), - STATE_ICONIFIED:_("iconified"), - # Translators: Presented when the current control is located off screen. - STATE_OFFSCREEN:_("off screen"), - # Translators: Presented when the control allows selection such as text fields. - STATE_SELECTABLE:_("selectable"), - # Translators: Presented when a control can be moved to using system focus. - STATE_FOCUSABLE:_("focusable"), - # Translators: Presented when a control allows clicking via mouse (mostly presented on web controls). - STATE_CLICKABLE:_("clickable"), - STATE_EDITABLE:_("editable"), - STATE_CHECKABLE:_("checkable"), - STATE_DRAGGABLE:_("draggable"), - STATE_DRAGGING:_("dragging"), - # Translators: Reported where an object which is being dragged can be dropped. - # This is only reported for objects that support accessible drag and drop. - STATE_DROPTARGET:_("drop target"), - STATE_SORTED:_("sorted"), - STATE_SORTED_ASCENDING:_("sorted ascending"), - STATE_SORTED_DESCENDING:_("sorted descending"), - # Translators: a state that denotes that an object (usually a graphic) has a long description. - STATE_HASLONGDESC:_("has long description"), - # Translators: a state that denotes that an object has additional details (such as a comment section). - STATE_HAS_ARIA_DETAILS: _("has details"), - # Translators: a state that denotes that an object is pinned in its current location - STATE_PINNED:_("pinned"), - # Translators: a state that denotes the existance of a formula on a spreadsheet cell - STATE_HASFORMULA:_("has formula"), - # Translators: a state that denotes the existance of a comment. - STATE_HASCOMMENT:_("has comment"), - # Translators: a state that denotes that the object is covered partially or fully by another object - STATE_OBSCURED:_("obscured"), - # Translators: a state that denotes that the object(text) is cropped as it couldn't be accommodated in the allocated/available space - STATE_CROPPED:_("cropped"), - # Translators: a state that denotes that the object(text) is overflowing into the adjacent space - STATE_OVERFLOWING:_("overflowing"), - # Translators: a state that denotes that the object is unlocked (such as an unlocked cell in a protected Excel spreadsheet). - STATE_UNLOCKED:_("unlocked"), -} - -negativeStateLabels={ - # Translators: This is presented when a selectable object (e.g. a list item) is not selected. - STATE_SELECTED:_("not selected"), - # Translators: This is presented when a button is not pressed. - STATE_PRESSED:_("not pressed"), - # Translators: This is presented when a checkbox is not checked. - STATE_CHECKED:_("not checked"), - # Translators: This is presented when drag and drop is finished. - # This is only reported for objects which support accessible drag and drop. - STATE_DROPTARGET:_("done dragging"), -} - -silentRolesOnFocus={ - ROLE_PANE, - ROLE_ROOTPANE, - ROLE_FRAME, - ROLE_UNKNOWN, - ROLE_APPLICATION, - ROLE_TABLECELL, - ROLE_LISTITEM, - ROLE_MENUITEM, - ROLE_CHECKMENUITEM, - ROLE_TREEVIEWITEM, - ROLE_STATICTEXT, - ROLE_BORDER, -} - -silentValuesForRoles={ - ROLE_CHECKBOX, - ROLE_RADIOBUTTON, - ROLE_LINK, - ROLE_MENUITEM, - ROLE_APPLICATION, -} - - -class OutputReason(Enum): - """Specify the reason that a given piece of output was generated. - """ - #: An object to be reported due to a focus change or similar. - FOCUS = auto() - #: An ancestor of the focus object to be reported due to a focus change or similar. - FOCUSENTERED = auto() - #: An item under the mouse. - MOUSE = auto() - #: A response to a user query. - QUERY = auto() - #: Reporting a change to an object. - CHANGE = auto() - #: A generic, screen reader specific message. - MESSAGE = auto() - #: Text reported as part of a say all. - SAYALL = auto() - #: Content reported due to caret movement or similar. - CARET = auto() - #: No output, but any state should be cached as if output had occurred. - ONLYCACHE = auto() - - QUICKNAV = auto() - - -class IsCurrent(Enum): - """Values to use within NVDA to denote 'current' values. - These describe if an item is the current item within a particular kind of selection. - EG aria-current - """ - NO = "false" - YES = "true" - PAGE = "page" - STEP = "step" - LOCATION = "location" - DATE = "date" - TIME = "time" - - @property - def displayString(self): - """ - @return: The translated UI display string that should be used for this value of the IsCurrent enum - """ - try: - return _isCurrentLabels[self] - except KeyError: - log.debugWarning(f"No translation mapping for: {self}") - # there is a value for 'current' but NVDA hasn't learned about it yet, - # at least describe in the general sense that this item is 'current' - return _isCurrentLabels[IsCurrent.YES] - - -#: Text to use for 'current' values. These describe if an item is the current item -#: within a particular kind of selection. EG aria-current -_isCurrentLabels: Dict[Enum, str] = { - IsCurrent.NO: "", # There is nothing extra to say for items that are not current. - # Translators: Presented when an item is marked as current in a collection of items - IsCurrent.YES: _("current"), - # Translators: Presented when a page item is marked as current in a collection of page items - IsCurrent.PAGE: _("current page"), - # Translators: Presented when a step item is marked as current in a collection of step items - IsCurrent.STEP: _("current step"), - # Translators: Presented when a location item is marked as current in a collection of location items - IsCurrent.LOCATION: _("current location"), - # Translators: Presented when a date item is marked as current in a collection of date items - IsCurrent.DATE: _("current date"), - # Translators: Presented when a time item is marked as current in a collection of time items - IsCurrent.TIME: _("current time"), -} - - -def processPositiveStates(role, states, reason: OutputReason, positiveStates=None): - """Processes the states for an object and returns the positive states to output for a specified reason. - For example, if C{STATE_CHECKED} is in the returned states, it means that the processed object is checked. - @param role: The role of the object to process states for (e.g. C{ROLE_CHECKBOX}. - @type role: int - @param states: The raw states for an object to process. - @type states: set - @param reason: The reason to process the states (e.g. C{OutputReason.FOCUS}. - @param positiveStates: Used for C{OutputReason.CHANGE}, specifies states changed from negative to positive; - @type positiveStates: set - @return: The processed positive states. - @rtype: set - """ - positiveStates = positiveStates.copy() if positiveStates is not None else states.copy() - # The user never cares about certain states. - if role==ROLE_EDITABLETEXT: - positiveStates.discard(STATE_EDITABLE) - if role!=ROLE_LINK: - positiveStates.discard(STATE_VISITED) - positiveStates.discard(STATE_SELECTABLE) - positiveStates.discard(STATE_FOCUSABLE) - positiveStates.discard(STATE_CHECKABLE) - if STATE_DRAGGING in positiveStates: - # It's obvious that the control is draggable if it's being dragged. - positiveStates.discard(STATE_DRAGGABLE) - if role == ROLE_COMBOBOX: - # Combo boxes inherently have a popup, so don't report it. - positiveStates.discard(STATE_HASPOPUP) - import config - if not config.conf['documentFormatting']['reportClickable'] or role in (ROLE_LINK, ROLE_BUTTON, ROLE_CHECKBOX, ROLE_RADIOBUTTON, ROLE_TOGGLEBUTTON, ROLE_MENUITEM, ROLE_TAB, ROLE_SLIDER, ROLE_DOCUMENT, ROLE_CHECKMENUITEM, ROLE_RADIOMENUITEM): - # This control is clearly clickable according to its role, - # or reporting clickable just isn't useful, - # or the user has explicitly requested no reporting clickable - positiveStates.discard(STATE_CLICKABLE) - if reason == OutputReason.QUERY: - return positiveStates - positiveStates.discard(STATE_DEFUNCT) - positiveStates.discard(STATE_MODAL) - positiveStates.discard(STATE_FOCUSED) - positiveStates.discard(STATE_OFFSCREEN) - positiveStates.discard(STATE_INVISIBLE) - if reason != OutputReason.CHANGE: - positiveStates.discard(STATE_LINKED) - if role in ( - ROLE_LISTITEM, - ROLE_TREEVIEWITEM, - ROLE_MENUITEM, - ROLE_TABLEROW, - ROLE_CHECKBOX, - ) and STATE_SELECTABLE in states: - positiveStates.discard(STATE_SELECTED) - if role not in (ROLE_EDITABLETEXT, ROLE_CHECKBOX): - positiveStates.discard(STATE_READONLY) - if role == ROLE_CHECKBOX: - positiveStates.discard(STATE_PRESSED) - if role == ROLE_MENUITEM and STATE_HASPOPUP in positiveStates: - # The user doesn't usually care if a submenu is expanded or collapsed. - positiveStates.discard(STATE_COLLAPSED) - positiveStates.discard(STATE_EXPANDED) - if STATE_FOCUSABLE not in states: - positiveStates.discard(STATE_EDITABLE) - if not config.conf["annotations"]["reportDetails"]: - # reading aria-details is an experimental feature still and should not always be reported. - positiveStates.discard(STATE_HAS_ARIA_DETAILS) - return positiveStates - - -def processNegativeStates(role, states, reason: OutputReason, negativeStates=None): - """Processes the states for an object and returns the negative states to output for a specified reason. - For example, if C{STATE_CHECKED} is in the returned states, it means that the processed object is not checked. - @param role: The role of the object to process states for (e.g. C{ROLE_CHECKBOX}. - @type role: int - @param states: The raw states for an object to process. - @type states: set - @param reason: The reason to process the states (e.g. C{OutputReason.FOCUS}. - @param negativeStates: Used for C{OutputReason.CHANGE}, specifies states changed from positive to negative; - @type negativeStates: set - @return: The processed negative states. - @rtype: set - """ - if reason == OutputReason.CHANGE and not isinstance(negativeStates, set): - raise TypeError("negativeStates must be a set for this reason") - speakNegatives = set() - # Add the negative selected state if the control is selectable, - # but only if it is reported for the reason of focus, or this is a change to the focused object. - # The condition stops "not selected" from being spoken in some broken controls - # when the state change for the previous focus is issued before the focus change. - if ( - # Only include if the object is actually selectable - STATE_SELECTABLE in states - # Only include if the object is focusable (E.g. ARIA grid cells, but not standard html tables) - and STATE_FOCUSABLE in states - # Only include if reporting the focus or when states are changing on the focus. - # This is to avoid exposing it for things like caret movement in browse mode. - and (reason == OutputReason.FOCUS or (reason == OutputReason.CHANGE and STATE_FOCUSED in states)) - and role in ( - ROLE_LISTITEM, - ROLE_TREEVIEWITEM, - ROLE_TABLEROW, - ROLE_TABLECELL, - ROLE_TABLECOLUMNHEADER, - ROLE_TABLEROWHEADER, - ROLE_CHECKBOX, - ) - ): - speakNegatives.add(STATE_SELECTED) - # Restrict "not checked" in a similar way to "not selected". - if( - (role in (ROLE_CHECKBOX, ROLE_RADIOBUTTON, ROLE_CHECKMENUITEM) or STATE_CHECKABLE in states) - and (STATE_HALFCHECKED not in states) - and (reason != OutputReason.CHANGE or STATE_FOCUSED in states) - ): - speakNegatives.add(STATE_CHECKED) - if role == ROLE_TOGGLEBUTTON: - speakNegatives.add(STATE_PRESSED) - if reason == OutputReason.CHANGE: - # We want to speak this state only if it is changing to negative. - speakNegatives.add(STATE_DROPTARGET) - # We were given states which have changed to negative. - # Return only those supplied negative states which should be spoken; - # i.e. the states in both sets. - speakNegatives &= negativeStates - # #6946: if HALFCHECKED is present but CHECKED isn't, we should make sure we add CHECKED to speakNegatives. - if (STATE_HALFCHECKED in negativeStates and STATE_CHECKED not in states): - speakNegatives.add(STATE_CHECKED) - if STATES_SORTED & negativeStates and not STATES_SORTED & states: - # If the object has just stopped being sorted, just report not sorted. - # The user doesn't care how it was sorted before. - speakNegatives.add(STATE_SORTED) - return speakNegatives - else: - # This is not a state change; only positive states were supplied. - # Return all negative states which should be spoken, excluding the positive states. - return speakNegatives - states - - -def processAndLabelStates( - role: int, - states: Set[Any], - reason: OutputReason, - positiveStates: Optional[Set[Any]] = None, - negativeStates: Optional[Set[Any]] = None, - positiveStateLabelDict: Dict[int, str] = {}, - negativeStateLabelDict: Dict[int, str] = {}, -) -> List[str]: - """Processes the states for an object and returns the appropriate state labels for both positive and negative states. - @param role: The role of the object to process states for (e.g. C{ROLE_CHECKBOX}. - @param states: The raw states for an object to process. - @param reason: The reason to process the states (e.g. C{OutputReason.FOCUS}. - @param positiveStates: Used for C{OutputReason.CHANGE}, specifies states changed from negative to positive; - @param negativeStates: Used for C{OutputReason.CHANGE}, specifies states changed from positive to negative; - @param positiveStateLabelDict: Dictionary containing state identifiers as keys and associated positive labels as their values. - @param negativeStateLabelDict: Dictionary containing state identifiers as keys and associated negative labels as their values. - @return: The labels of the relevant positive and negative states. - """ - mergedStateLabels=[] - positiveStates = processPositiveStates(role, states, reason, positiveStates) - negativeStates = processNegativeStates(role, states, reason, negativeStates) - for state in sorted(positiveStates | negativeStates): - if state in positiveStates: - mergedStateLabels.append(positiveStateLabelDict.get(state, stateLabels[state])) - elif state in negativeStates: - # Translators: Indicates that a particular state of an object is negated. - # Separate strings have now been defined for commonly negated states (e.g. not selected and not checked), - # but this still might be used in some other cases. - # %s will be replaced with the full identifier of the negated state (e.g. selected). - mergedStateLabels.append(negativeStateLabelDict.get(state, negativeStateLabels.get(state, _("not %s") % stateLabels[state]))) - return mergedStateLabels diff --git a/source/controlTypes/__init__.py b/source/controlTypes/__init__.py new file mode 100644 index 00000000000..e69de29bb2d diff --git a/source/controlTypes/isCurrent.py b/source/controlTypes/isCurrent.py new file mode 100644 index 00000000000..03f916a9c95 --- /dev/null +++ b/source/controlTypes/isCurrent.py @@ -0,0 +1,55 @@ +# A part of NonVisual Desktop Access (NVDA) +# This file is covered by the GNU General Public License. +# See the file COPYING for more details. +# Copyright (C) 2007-2021 NV Access Limited, Babbage B.V. + +from enum import Enum +from typing import Dict + +from logHandler import log + + +class IsCurrent(Enum): + """Values to use within NVDA to denote 'current' values. + These describe if an item is the current item within a particular kind of selection. + EG aria-current + """ + NO = "false" + YES = "true" + PAGE = "page" + STEP = "step" + LOCATION = "location" + DATE = "date" + TIME = "time" + + @property + def displayString(self): + """ + @return: The translated UI display string that should be used for this value of the IsCurrent enum + """ + try: + return _isCurrentLabels[self] + except KeyError: + log.debugWarning(f"No translation mapping for: {self}") + # there is a value for 'current' but NVDA hasn't learned about it yet, + # at least describe in the general sense that this item is 'current' + return _isCurrentLabels[IsCurrent.YES] + + +#: Text to use for 'current' values. These describe if an item is the current item +#: within a particular kind of selection. EG aria-current +_isCurrentLabels: Dict[Enum, str] = { + IsCurrent.NO: "", # There is nothing extra to say for items that are not current. + # Translators: Presented when an item is marked as current in a collection of items + IsCurrent.YES: _("current"), + # Translators: Presented when a page item is marked as current in a collection of page items + IsCurrent.PAGE: _("current page"), + # Translators: Presented when a step item is marked as current in a collection of step items + IsCurrent.STEP: _("current step"), + # Translators: Presented when a location item is marked as current in a collection of location items + IsCurrent.LOCATION: _("current location"), + # Translators: Presented when a date item is marked as current in a collection of date items + IsCurrent.DATE: _("current date"), + # Translators: Presented when a time item is marked as current in a collection of time items + IsCurrent.TIME: _("current time"), +} diff --git a/source/controlTypes/outputReason.py b/source/controlTypes/outputReason.py new file mode 100644 index 00000000000..a1a8435d9f8 --- /dev/null +++ b/source/controlTypes/outputReason.py @@ -0,0 +1,31 @@ +# A part of NonVisual Desktop Access (NVDA) +# This file is covered by the GNU General Public License. +# See the file COPYING for more details. +# Copyright (C) 2007-2021 NV Access Limited, Babbage B.V. + +from enum import Enum, auto + + +class OutputReason(Enum): + """Specify the reason that a given piece of output was generated. + """ + #: An object to be reported due to a focus change or similar. + FOCUS = auto() + #: An ancestor of the focus object to be reported due to a focus change or similar. + FOCUSENTERED = auto() + #: An item under the mouse. + MOUSE = auto() + #: A response to a user query. + QUERY = auto() + #: Reporting a change to an object. + CHANGE = auto() + #: A generic, screen reader specific message. + MESSAGE = auto() + #: Text reported as part of a say all. + SAYALL = auto() + #: Content reported due to caret movement or similar. + CARET = auto() + #: No output, but any state should be cached as if output had occurred. + ONLYCACHE = auto() + + QUICKNAV = auto() diff --git a/source/controlTypes/processAndLabelStates.py b/source/controlTypes/processAndLabelStates.py new file mode 100644 index 00000000000..53532385b3b --- /dev/null +++ b/source/controlTypes/processAndLabelStates.py @@ -0,0 +1,180 @@ +# A part of NonVisual Desktop Access (NVDA) +# This file is covered by the GNU General Public License. +# See the file COPYING for more details. +# Copyright (C) 2007-2021 NV Access Limited, Babbage B.V. + +from typing import Any, Dict, List, Optional, Set + +from .role import * +from .state import STATES_SORTED, negativeStateLabels, stateLabels, * +from .outputReason import OutputReason + + +def processPositiveStates(role, states, reason: OutputReason, positiveStates=None): + """Processes the states for an object and returns the positive states to output for a specified reason. + For example, if C{STATE_CHECKED} is in the returned states, it means that the processed object is checked. + @param role: The role of the object to process states for (e.g. C{ROLE_CHECKBOX}. + @type role: int + @param states: The raw states for an object to process. + @type states: set + @param reason: The reason to process the states (e.g. C{OutputReason.FOCUS}. + @param positiveStates: Used for C{OutputReason.CHANGE}, specifies states changed from negative to positive; + @type positiveStates: set + @return: The processed positive states. + @rtype: set + """ + positiveStates = positiveStates.copy() if positiveStates is not None else states.copy() + # The user never cares about certain states. + if role==ROLE_EDITABLETEXT: + positiveStates.discard(STATE_EDITABLE) + if role!=ROLE_LINK: + positiveStates.discard(STATE_VISITED) + positiveStates.discard(STATE_SELECTABLE) + positiveStates.discard(STATE_FOCUSABLE) + positiveStates.discard(STATE_CHECKABLE) + if STATE_DRAGGING in positiveStates: + # It's obvious that the control is draggable if it's being dragged. + positiveStates.discard(STATE_DRAGGABLE) + if role == ROLE_COMBOBOX: + # Combo boxes inherently have a popup, so don't report it. + positiveStates.discard(STATE_HASPOPUP) + import config + if not config.conf['documentFormatting']['reportClickable'] or role in (ROLE_LINK, ROLE_BUTTON, ROLE_CHECKBOX, ROLE_RADIOBUTTON, ROLE_TOGGLEBUTTON, ROLE_MENUITEM, ROLE_TAB, ROLE_SLIDER, ROLE_DOCUMENT, ROLE_CHECKMENUITEM, ROLE_RADIOMENUITEM): + # This control is clearly clickable according to its role, + # or reporting clickable just isn't useful, + # or the user has explicitly requested no reporting clickable + positiveStates.discard(STATE_CLICKABLE) + if reason == OutputReason.QUERY: + return positiveStates + positiveStates.discard(STATE_DEFUNCT) + positiveStates.discard(STATE_MODAL) + positiveStates.discard(STATE_FOCUSED) + positiveStates.discard(STATE_OFFSCREEN) + positiveStates.discard(STATE_INVISIBLE) + if reason != OutputReason.CHANGE: + positiveStates.discard(STATE_LINKED) + if role in ( + ROLE_LISTITEM, + ROLE_TREEVIEWITEM, + ROLE_MENUITEM, + ROLE_TABLEROW, + ROLE_CHECKBOX, + ) and STATE_SELECTABLE in states: + positiveStates.discard(STATE_SELECTED) + if role not in (ROLE_EDITABLETEXT, ROLE_CHECKBOX): + positiveStates.discard(STATE_READONLY) + if role == ROLE_CHECKBOX: + positiveStates.discard(STATE_PRESSED) + if role == ROLE_MENUITEM and STATE_HASPOPUP in positiveStates: + # The user doesn't usually care if a submenu is expanded or collapsed. + positiveStates.discard(STATE_COLLAPSED) + positiveStates.discard(STATE_EXPANDED) + if STATE_FOCUSABLE not in states: + positiveStates.discard(STATE_EDITABLE) + if not config.conf["annotations"]["reportDetails"]: + # reading aria-details is an experimental feature still and should not always be reported. + positiveStates.discard(STATE_HAS_ARIA_DETAILS) + return positiveStates + + +def processNegativeStates(role, states, reason: OutputReason, negativeStates=None): + """Processes the states for an object and returns the negative states to output for a specified reason. + For example, if C{STATE_CHECKED} is in the returned states, it means that the processed object is not checked. + @param role: The role of the object to process states for (e.g. C{ROLE_CHECKBOX}. + @type role: int + @param states: The raw states for an object to process. + @type states: set + @param reason: The reason to process the states (e.g. C{OutputReason.FOCUS}. + @param negativeStates: Used for C{OutputReason.CHANGE}, specifies states changed from positive to negative; + @type negativeStates: set + @return: The processed negative states. + @rtype: set + """ + if reason == OutputReason.CHANGE and not isinstance(negativeStates, set): + raise TypeError("negativeStates must be a set for this reason") + speakNegatives = set() + # Add the negative selected state if the control is selectable, + # but only if it is reported for the reason of focus, or this is a change to the focused object. + # The condition stops "not selected" from being spoken in some broken controls + # when the state change for the previous focus is issued before the focus change. + if ( + # Only include if the object is actually selectable + STATE_SELECTABLE in states + # Only include if the object is focusable (E.g. ARIA grid cells, but not standard html tables) + and STATE_FOCUSABLE in states + # Only include if reporting the focus or when states are changing on the focus. + # This is to avoid exposing it for things like caret movement in browse mode. + and (reason == OutputReason.FOCUS or (reason == OutputReason.CHANGE and STATE_FOCUSED in states)) + and role in ( + ROLE_LISTITEM, + ROLE_TREEVIEWITEM, + ROLE_TABLEROW, + ROLE_TABLECELL, + ROLE_TABLECOLUMNHEADER, + ROLE_TABLEROWHEADER, + ROLE_CHECKBOX, + ) + ): + speakNegatives.add(STATE_SELECTED) + # Restrict "not checked" in a similar way to "not selected". + if( + (role in (ROLE_CHECKBOX, ROLE_RADIOBUTTON, ROLE_CHECKMENUITEM) or STATE_CHECKABLE in states) + and (STATE_HALFCHECKED not in states) + and (reason != OutputReason.CHANGE or STATE_FOCUSED in states) + ): + speakNegatives.add(STATE_CHECKED) + if role == ROLE_TOGGLEBUTTON: + speakNegatives.add(STATE_PRESSED) + if reason == OutputReason.CHANGE: + # We want to speak this state only if it is changing to negative. + speakNegatives.add(STATE_DROPTARGET) + # We were given states which have changed to negative. + # Return only those supplied negative states which should be spoken; + # i.e. the states in both sets. + speakNegatives &= negativeStates + # #6946: if HALFCHECKED is present but CHECKED isn't, we should make sure we add CHECKED to speakNegatives. + if (STATE_HALFCHECKED in negativeStates and STATE_CHECKED not in states): + speakNegatives.add(STATE_CHECKED) + if STATES_SORTED & negativeStates and not STATES_SORTED & states: + # If the object has just stopped being sorted, just report not sorted. + # The user doesn't care how it was sorted before. + speakNegatives.add(STATE_SORTED) + return speakNegatives + else: + # This is not a state change; only positive states were supplied. + # Return all negative states which should be spoken, excluding the positive states. + return speakNegatives - states + + +def processAndLabelStates( + role: int, + states: Set[Any], + reason: OutputReason, + positiveStates: Optional[Set[Any]] = None, + negativeStates: Optional[Set[Any]] = None, + positiveStateLabelDict: Dict[int, str] = {}, + negativeStateLabelDict: Dict[int, str] = {}, +) -> List[str]: + """Processes the states for an object and returns the appropriate state labels for both positive and negative states. + @param role: The role of the object to process states for (e.g. C{ROLE_CHECKBOX}. + @param states: The raw states for an object to process. + @param reason: The reason to process the states (e.g. C{OutputReason.FOCUS}. + @param positiveStates: Used for C{OutputReason.CHANGE}, specifies states changed from negative to positive; + @param negativeStates: Used for C{OutputReason.CHANGE}, specifies states changed from positive to negative; + @param positiveStateLabelDict: Dictionary containing state identifiers as keys and associated positive labels as their values. + @param negativeStateLabelDict: Dictionary containing state identifiers as keys and associated negative labels as their values. + @return: The labels of the relevant positive and negative states. + """ + mergedStateLabels=[] + positiveStates = processPositiveStates(role, states, reason, positiveStates) + negativeStates = processNegativeStates(role, states, reason, negativeStates) + for state in sorted(positiveStates | negativeStates): + if state in positiveStates: + mergedStateLabels.append(positiveStateLabelDict.get(state, stateLabels[state])) + elif state in negativeStates: + # Translators: Indicates that a particular state of an object is negated. + # Separate strings have now been defined for commonly negated states (e.g. not selected and not checked), + # but this still might be used in some other cases. + # %s will be replaced with the full identifier of the negated state (e.g. selected). + mergedStateLabels.append(negativeStateLabelDict.get(state, negativeStateLabels.get(state, _("not %s") % stateLabels[state]))) + return mergedStateLabels diff --git a/source/controlTypes/role.py b/source/controlTypes/role.py new file mode 100644 index 00000000000..48fd9a871be --- /dev/null +++ b/source/controlTypes/role.py @@ -0,0 +1,490 @@ +# A part of NonVisual Desktop Access (NVDA) +# This file is covered by the GNU General Public License. +# See the file COPYING for more details. +# Copyright (C) 2007-2021 NV Access Limited, Babbage B.V. + +from typing import Dict + + +ROLE_UNKNOWN=0 +ROLE_WINDOW=1 +ROLE_TITLEBAR=2 +ROLE_PANE=3 +ROLE_DIALOG=4 +ROLE_CHECKBOX=5 +ROLE_RADIOBUTTON=6 +ROLE_STATICTEXT=7 +ROLE_EDITABLETEXT=8 +ROLE_BUTTON=9 +ROLE_MENUBAR=10 +ROLE_MENUITEM=11 +ROLE_POPUPMENU=12 +ROLE_COMBOBOX=13 +ROLE_LIST=14 +ROLE_LISTITEM=15 +ROLE_GRAPHIC=16 +ROLE_HELPBALLOON=17 +ROLE_TOOLTIP=18 +ROLE_LINK=19 +ROLE_TREEVIEW=20 +ROLE_TREEVIEWITEM=21 +ROLE_TAB=22 +ROLE_TABCONTROL=23 +ROLE_SLIDER=24 +ROLE_PROGRESSBAR=25 +ROLE_SCROLLBAR=26 +ROLE_STATUSBAR=27 +ROLE_TABLE=28 +ROLE_TABLECELL=29 +ROLE_TABLECOLUMN=30 +ROLE_TABLEROW=31 +ROLE_TABLECOLUMNHEADER=32 +ROLE_TABLEROWHEADER=33 +ROLE_FRAME=34 +ROLE_TOOLBAR=35 +ROLE_DROPDOWNBUTTON=36 +ROLE_CLOCK=37 +ROLE_SEPARATOR=38 +ROLE_FORM=39 +ROLE_HEADING=40 +ROLE_HEADING1=41 +ROLE_HEADING2=42 +ROLE_HEADING3=43 +ROLE_HEADING4=44 +ROLE_HEADING5=45 +ROLE_HEADING6=46 +ROLE_PARAGRAPH=47 +ROLE_BLOCKQUOTE=48 +ROLE_TABLEHEADER=49 +ROLE_TABLEBODY=50 +ROLE_TABLEFOOTER=51 +ROLE_DOCUMENT=52 +ROLE_ANIMATION=53 +ROLE_APPLICATION=54 +ROLE_BOX=55 +ROLE_GROUPING=56 +ROLE_PROPERTYPAGE=57 +ROLE_CANVAS=58 +ROLE_CAPTION=59 +ROLE_CHECKMENUITEM=60 +ROLE_DATEEDITOR=61 +ROLE_ICON=62 +ROLE_DIRECTORYPANE=63 +ROLE_EMBEDDEDOBJECT=64 +ROLE_ENDNOTE=65 +ROLE_FOOTER=66 +ROLE_FOOTNOTE=67 +ROLE_GLASSPANE=69 +ROLE_HEADER=70 +ROLE_IMAGEMAP=71 +ROLE_INPUTWINDOW=72 +ROLE_LABEL=73 +ROLE_NOTE=74 +ROLE_PAGE=75 +ROLE_RADIOMENUITEM=76 +ROLE_LAYEREDPANE=77 +ROLE_REDUNDANTOBJECT=78 +ROLE_ROOTPANE=79 +ROLE_EDITBAR=80 +ROLE_TERMINAL=82 +ROLE_RICHEDIT=83 +ROLE_RULER=84 +ROLE_SCROLLPANE=85 +ROLE_SECTION=86 +ROLE_SHAPE=87 +ROLE_SPLITPANE=88 +ROLE_VIEWPORT=89 +ROLE_TEAROFFMENU=90 +ROLE_TEXTFRAME=91 +ROLE_TOGGLEBUTTON=92 +ROLE_BORDER=93 +ROLE_CARET=94 +ROLE_CHARACTER=95 +ROLE_CHART=96 +ROLE_CURSOR=97 +ROLE_DIAGRAM=98 +ROLE_DIAL=99 +ROLE_DROPLIST=100 +ROLE_SPLITBUTTON=101 +ROLE_MENUBUTTON=102 +ROLE_DROPDOWNBUTTONGRID=103 +ROLE_MATH=104 +ROLE_GRIP=105 +ROLE_HOTKEYFIELD=106 +ROLE_INDICATOR=107 +ROLE_SPINBUTTON=108 +ROLE_SOUND=109 +ROLE_WHITESPACE=110 +ROLE_TREEVIEWBUTTON=111 +ROLE_IPADDRESS=112 +ROLE_DESKTOPICON=113 +ROLE_INTERNALFRAME=115 +ROLE_DESKTOPPANE=116 +ROLE_OPTIONPANE=117 +ROLE_COLORCHOOSER=118 +ROLE_FILECHOOSER=119 +ROLE_FILLER=120 +ROLE_MENU=121 +ROLE_PANEL=122 +ROLE_PASSWORDEDIT=123 +ROLE_FONTCHOOSER=124 +ROLE_LINE=125 +ROLE_FONTNAME=126 +ROLE_FONTSIZE=127 +ROLE_BOLD=128 +ROLE_ITALIC=129 +ROLE_UNDERLINE=130 +ROLE_FGCOLOR=131 +ROLE_BGCOLOR=132 +ROLE_SUPERSCRIPT=133 +ROLE_SUBSCRIPT=134 +ROLE_STYLE=135 +ROLE_INDENT=136 +ROLE_ALIGNMENT=137 +ROLE_ALERT=138 +ROLE_DATAGRID=139 +ROLE_DATAITEM=140 +ROLE_HEADERITEM=141 +ROLE_THUMB=142 +ROLE_CALENDAR=143 +ROLE_VIDEO=144 +ROLE_AUDIO=145 +ROLE_CHARTELEMENT=146 +ROLE_DELETED_CONTENT=147 +ROLE_INSERTED_CONTENT=148 +ROLE_LANDMARK = 149 +ROLE_ARTICLE = 150 +ROLE_REGION = 151 +ROLE_FIGURE = 152 +ROLE_MARKED_CONTENT = 153 + + +roleLabels: Dict[int, str] = { + # Translators: The word for an unknown control type. + ROLE_UNKNOWN:_("unknown"), + # Translators: The word for window of a program such as document window. + ROLE_WINDOW:_("window"), + # Translators: Used to identify title bar of a program. + ROLE_TITLEBAR:_("title bar"), + # Translators: The word used for pane such as desktop pane. + ROLE_PANE:_("pane"), + # Translators: The word used to denote a dialog box such as open dialog. + ROLE_DIALOG:_("dialog"), + # Translators: The text used to identify check boxes such as select check box. + ROLE_CHECKBOX:_("check box"), + # Translators: The text used to identify radio buttons such as yes or no radio button. + ROLE_RADIOBUTTON:_("radio button"), + # Translators: The word used to identify a static text such as dialog text. + ROLE_STATICTEXT:_("text"), + # Translators: The word used to identify edit fields such as subject edit field. + ROLE_EDITABLETEXT:_("edit"), + # Translators: The word used to identify a button such as OK button. + ROLE_BUTTON:_("button"), + # Translators: Text used to identify menu bar of a program. + ROLE_MENUBAR:_("menu bar"), + # Translators: Used to identify a menu item such as an item in file menu. + ROLE_MENUITEM:_("menu item"), + # Translators: The word used for menus such as edit menu. + ROLE_POPUPMENU:_("menu"), + # Translators: Used to identify combo boxes such as file type combo box. + ROLE_COMBOBOX:_("combo box"), + # Translators: The word used for lists such as folder list. + ROLE_LIST:_("list"), + # Translators: Used to identify a list item such as email list items. + ROLE_LISTITEM:_("list item"), + # Translators: The word used to identify graphics such as webpage graphics. + ROLE_GRAPHIC:_("graphic"), + # Translators: Used to identify help balloon (a circular window with helpful text such as notification text). + ROLE_HELPBALLOON:_("help balloon"), + # Translators: Used to identify a tooltip (a small window with additional text about selected item such as file information). + ROLE_TOOLTIP:_("tool tip"), + # Translators: Identifies a link in webpage documents. + ROLE_LINK:_("link"), + # Translators: Identifies a treeview (a tree-like structure such as treeviews for subfolders). + ROLE_TREEVIEW:_("tree view"), + # Translators: Identifies a tree view item. + ROLE_TREEVIEWITEM:_("tree view item"), + # Translators: The word presented for tabs in a tab enabled window. + ROLE_TAB: pgettext("controlType", "tab"), + # Translators: Identifies a tab control such as webpage tabs in web browsers. + ROLE_TABCONTROL:_("tab control"), + # Translators: Identifies a slider such as volume slider. + ROLE_SLIDER:_("slider"), + # Translators: Identifies a progress bar such as NvDA update progress. + ROLE_PROGRESSBAR:_("progress bar"), + # Translators: Identifies a scroll bar. + ROLE_SCROLLBAR:_("scroll bar"), + # Translators: Identifies a status bar (text at the bottom bar of the screen such as cursor position in a document). + ROLE_STATUSBAR:_("status bar"), + # Translators: Identifies a table such as ones used in various websites. + ROLE_TABLE:_("table"), + # Translators: Identifies a cell in a table. + ROLE_TABLECELL:_("cell"), + # Translators: Identifies a column (a group of vertical cells in a table). + ROLE_TABLECOLUMN:_("column"), + # Translators: Identifies a row (a group of horizontal cells in a table). + ROLE_TABLEROW:_("row"), + # Translators: Identifies a frame (a smaller window in a webpage or a document). + ROLE_FRAME:_("frame"), + # Translators: Identifies a tool bar. + ROLE_TOOLBAR:_("tool bar"), + # Translators: Identifies a column header in tables and spreadsheets. + ROLE_TABLECOLUMNHEADER:_("column header"), + # Translators: Identifies a row header in tables and spreadsheets. + ROLE_TABLEROWHEADER:_("row header"), + # Translators: Identifies a drop down button (a button that, when clicked, opens a menu of its own). + ROLE_DROPDOWNBUTTON:_("drop down button"), + # Translators: Identifies an element. + ROLE_CLOCK:_("clock"), + # Translators: Identifies a separator (a horizontal line drawn on the screen). + ROLE_SEPARATOR:_("separator"), + # Translators: Identifies a form (controls such as edit boxes, combo boxes and so on). + ROLE_FORM:_("form"), + # Translators: Identifies a heading (a bold text used for identifying a section). + ROLE_HEADING:_("heading"), + # Translators: Identifies a heading level. + ROLE_HEADING1:_("heading 1"), + # Translators: Identifies a heading level. + ROLE_HEADING2:_("heading 2"), + # Translators: Identifies a heading level. + ROLE_HEADING3:_("heading 3"), + # Translators: Identifies a heading level. + ROLE_HEADING4:_("heading 4"), + # Translators: Identifies a heading level. + ROLE_HEADING5:_("heading 5"), + # Translators: Identifies a heading level. + ROLE_HEADING6:_("heading 6"), + # Translators: Identifies a paragraph (a group of text surrounded by blank lines). + ROLE_PARAGRAPH:_("paragraph"), + # Translators: Presented for a section in a document which is a block quotation; + # i.e. a long quotation in a separate paragraph distinguished by indentation, etc. + # See http://en.wikipedia.org/wiki/Block_quotation + ROLE_BLOCKQUOTE:_("block quote"), + # Translators: Identifies a table header (a short text at the start of a table which describes what the table is about). + ROLE_TABLEHEADER:_("table header"), + # Translators: Identifies a table body (the main body of the table). + ROLE_TABLEBODY:_("table body"), + # Translators: Identifies a table footer (text placed at the end of the table). + ROLE_TABLEFOOTER:_("table footer"), + # Translators: Identifies a document (for example, a webpage document). + ROLE_DOCUMENT:_("document"), + # Translators: Identifies an animation in a document or a webpage. + ROLE_ANIMATION:_("animation"), + # Translators: Identifies an application in webpages. + ROLE_APPLICATION:_("application"), + # Translators: Identifies a box element. + ROLE_BOX:_("box"), + # Translators: Identifies a grouping (a number of related items grouped together, such as related options in dialogs). + ROLE_GROUPING:_("grouping"), + # Translators: Identifies a property page such as drive properties dialog. + ROLE_PROPERTYPAGE:_("property page"), + # Translators: Identifies a canvas element on webpages (a box with some background color with some text drawn on the box, like a canvas). + ROLE_CANVAS:_("canvas"), + # Translators: Identifies a caption (usually a short text identifying a picture or a graphic on websites). + ROLE_CAPTION:_("caption"), + # Translators: Identifies a check menu item (a menu item with a checkmark as part of the menu item's name). + ROLE_CHECKMENUITEM:_("check menu item"), + # Translators: Identifies a data edit field. + ROLE_DATEEDITOR:_("date edit"), + # Translators: Identifies an icon. + ROLE_ICON:_("icon"), + # Translators: Identifies a directory pane. + ROLE_DIRECTORYPANE:_("directory pane"), + # Translators: Identifies an object that is embedded in a document. + ROLE_EMBEDDEDOBJECT:_("embedded object"), + # Translators: Identifies an end note. + ROLE_ENDNOTE:_("end note"), + # Translators: Identifies a footer (usually text). + ROLE_FOOTER:_("footer"), + # Translators: Identifies a foot note (text at the end of a passage or used for anotations). + ROLE_FOOTNOTE:_("foot note"), + # Translators: Reported for an object which is a glass pane; i.e. + # a pane that is guaranteed to be on top of all panes beneath it. + ROLE_GLASSPANE:_("glass pane"), + # Translators: Identifies a header (usually text at top of documents or on tops of pages). + ROLE_HEADER:_("header"), + # Translators: Identifies an image map (a type of graphical link). + ROLE_IMAGEMAP:_("image map"), + # Translators: Identifies an input window. + ROLE_INPUTWINDOW:_("input window"), + # Translators: Identifies a label. + ROLE_LABEL:_("label"), + # Translators: Identifies a note field. + ROLE_NOTE:_("note"), + # Translators: Identifies a page. + ROLE_PAGE:_("page"), + # Translators: Identifies a radio menu item. + ROLE_RADIOMENUITEM:_("radio menu item"), + # Translators: Identifies a layered pane. + ROLE_LAYEREDPANE:_("layered pane"), + # Translators: Identifies a redundant object. + ROLE_REDUNDANTOBJECT:_("redundant object"), + # Translators: Identifies a root pane. + ROLE_ROOTPANE:_("root pane"), + # Translators: May be reported for an editable text object in a toolbar. + # This is deprecated and is not often (if ever) used. + ROLE_EDITBAR:_("edit bar"), + # Translators: Identifies a terminal window such as command prompt. + ROLE_TERMINAL:_("terminal"), + # Translators: Identifies a rich edit box (an edit box which allows entering formatting commands in addition to text; encountered on webpages and NvDA log viewer). + ROLE_RICHEDIT:_("rich edit"), + # Translators: Identifies a ruler object (commonly seen on some webpages and in some Office programs). + ROLE_RULER:_("ruler"), + # Translators: Identifies a scroll pane. + ROLE_SCROLLPANE:_("scroll pane"), + # Translators: Identifies a section of text. + ROLE_SECTION:_("section"), + # Translators: Identifies a shape. + ROLE_SHAPE:_("shape"), + # Translators: Identifies a split pane. + ROLE_SPLITPANE:_("split pane"), + # Translators: Reported for a view port; i.e. an object usually used in a scroll pane + # which represents the portion of the entire data that the user can see. + # As the user manipulates the scroll bars, the contents of the view port can change. + ROLE_VIEWPORT:_("view port"), + # Translators: Reported for an object that forms part of a menu system + # but which can be undocked from or torn off the menu system + # to exist as a separate window. + ROLE_TEAROFFMENU:_("tear off menu"), + # Translators: Identifies a text frame (a frame window which contains text). + ROLE_TEXTFRAME:_("text frame"), + # Translators: Identifies a toggle button (a button used to toggle something). + ROLE_TOGGLEBUTTON:_("toggle button"), + ROLE_BORDER:_("border"), + # Translators: Identifies a caret object. + ROLE_CARET:_("caret"), + # Translators: Identifies a character field (should not be confused with edit fields). + ROLE_CHARACTER:_("character"), + # Translators: Identifies a chart (commonly seen on some websites and in some Office documents). + ROLE_CHART:_("chart"), + # Translators: Identifies a cursor object. + ROLE_CURSOR:_("cursor"), + # Translators: Identifies a diagram (seen on some websites and on Office documents). + ROLE_DIAGRAM:_("diagram"), + # Translators: Identifies a dial object. + ROLE_DIAL:_("dial"), + # Translators: Identifies a drop list. + ROLE_DROPLIST:_("drop list"), + # Translators: Identifies a split button (a control which performs different actions when different parts are clicked). + ROLE_SPLITBUTTON:_("split button"), + # Translators: Identifies a menu button (a button which opens a menu of items). + ROLE_MENUBUTTON:_("menu button"), + # Translators: Reported for a button which expands a grid when it is pressed. + ROLE_DROPDOWNBUTTONGRID:_("drop down button grid"), + # Translators: Identifies mathematical content. + ROLE_MATH:_("math"), + # Translators: Identifies a grip control. + ROLE_GRIP:_("grip"), + # Translators: Identifies a hot key field (a field where one can enter a hot key for something, such as assigning shortcut for icons on the desktop). + ROLE_HOTKEYFIELD:_("hot key field"), + # Translators: Identifies an indicator control. + ROLE_INDICATOR:_("indicator"), + # Translators: Identifies a spin button (a button used to go through options in a spinning fashion). + ROLE_SPINBUTTON:_("spin button"), + # Translators: Identifies a sound clip on websites. + ROLE_SOUND:_("sound"), + # Translators: Identifies a whitespace. + ROLE_WHITESPACE:_("white space"), + # Translators: Identifies a tree view button. + ROLE_TREEVIEWBUTTON:_("tree view button"), + # Translators: Identifies an IP address (an IP address field element). + ROLE_IPADDRESS:_("IP address"), + # Translators: Identifies a desktop icon (the icons on the desktop such as computer and various shortcuts for programs). + ROLE_DESKTOPICON:_("desktop icon"), + # Translators: Identifies an internal frame. This is usually a frame on a web page; i.e. a web page embedded within a web page. + ROLE_INTERNALFRAME:_("frame"), + # Translators: Identifies desktop pane (the desktop window). + ROLE_DESKTOPPANE:_("desktop pane"), + # Translators: Identifies an option pane. + ROLE_OPTIONPANE:_("option pane"), + # Translators: Identifies a color chooser. + ROLE_COLORCHOOSER:_("color chooser"), + # Translators: Identifies a file chooser (to select a file or groups of files from a list). + ROLE_FILECHOOSER:_("file chooser"), + ROLE_FILLER:_("filler"), + # Translators: Identifies a menu such as file menu. + ROLE_MENU:_("menu"), + # Translators: Identifies a panel control for grouping related options. + ROLE_PANEL:_("panel"), + # Translators: Identifies a password field (a protected edit field for entering passwords such as when logging into web-based email sites). + ROLE_PASSWORDEDIT:_("password edit"), + # Translators: Identifies a font chooser. + ROLE_FONTCHOOSER:_("font chooser"), + ROLE_LINE:_("line"), + # Translators: Identifies a font name. + ROLE_FONTNAME:_("font name"), + # Translators: Identifies font size. + ROLE_FONTSIZE:_("font size"), + # Translators: Describes text formatting. + ROLE_BOLD:_("bold"), + # Translators: Describes text formatting. + ROLE_ITALIC:_("italic"), + # Translators: Describes text formatting. + ROLE_UNDERLINE:_("underline"), + # Translators: Describes text formatting. + ROLE_FGCOLOR:_("foreground color"), + # Translators: Describes text formatting. + ROLE_BGCOLOR:_("background color"), + # Translators: Describes text formatting. + ROLE_SUPERSCRIPT:_("superscript"), + # Translators: Describes text formatting. + ROLE_SUBSCRIPT:_("subscript"), + # Translators: Describes style of text. + ROLE_STYLE:_("style"), + # Translators: Describes text formatting. + ROLE_INDENT:_("indent"), + # Translators: Describes text formatting. + ROLE_ALIGNMENT:_("alignment"), + # Translators: Identifies an alert window or bar (usually on Internet Explorer 9 and above for alerts such as file downloads or pop-up blocker). + ROLE_ALERT:_("alert"), + # Translators: Identifies a data grid control (a grid which displays data). + ROLE_DATAGRID:_("data grid"), + ROLE_DATAITEM:_("data item"), + ROLE_HEADERITEM:_("header item"), + # Translators: Identifies a thumb control (a button-like control for changing options). + ROLE_THUMB:_("thumb control"), + ROLE_CALENDAR:_("calendar"), + ROLE_VIDEO:_("video"), + ROLE_AUDIO:_("audio"), + # Translators: Identifies a chart element. + ROLE_CHARTELEMENT:_("chart element"), + # Translators: Identifies deleted content. + ROLE_DELETED_CONTENT:_("deleted"), + # Translators: Identifies inserted content. + ROLE_INSERTED_CONTENT:_("inserted"), + # Translators: Identifies a landmark. + ROLE_LANDMARK: _("landmark"), + # Translators: Identifies an article. + ROLE_ARTICLE: _("article"), + # Translators: Identifies a region. + ROLE_REGION: _("region"), + # Translators: Identifies a figure (commonly seen on some websites). + ROLE_FIGURE: _("figure"), + # Translators: Identifies marked (highlighted) content + ROLE_MARKED_CONTENT: _("marked content"), +} + + +silentRolesOnFocus={ + ROLE_PANE, + ROLE_ROOTPANE, + ROLE_FRAME, + ROLE_UNKNOWN, + ROLE_APPLICATION, + ROLE_TABLECELL, + ROLE_LISTITEM, + ROLE_MENUITEM, + ROLE_CHECKMENUITEM, + ROLE_TREEVIEWITEM, + ROLE_STATICTEXT, + ROLE_BORDER, +} + + +silentValuesForRoles={ + ROLE_CHECKBOX, + ROLE_RADIOBUTTON, + ROLE_LINK, + ROLE_MENUITEM, + ROLE_APPLICATION, +} diff --git a/source/controlTypes/state.py b/source/controlTypes/state.py new file mode 100644 index 00000000000..763a1b66d64 --- /dev/null +++ b/source/controlTypes/state.py @@ -0,0 +1,147 @@ +# A part of NonVisual Desktop Access (NVDA) +# This file is covered by the GNU General Public License. +# See the file COPYING for more details. +# Copyright (C) 2007-2021 NV Access Limited, Babbage B.V. + +from typing import Dict + + +STATE_UNAVAILABLE=0X1 +STATE_FOCUSED=0X2 +STATE_SELECTED=0X4 +STATE_BUSY=0X8 +STATE_PRESSED=0X10 +STATE_CHECKED=0X20 +STATE_HALFCHECKED=0X40 +STATE_READONLY=0X80 +STATE_EXPANDED=0X100 +STATE_COLLAPSED=0X200 +STATE_INVISIBLE=0X400 +STATE_VISITED=0X800 +STATE_LINKED=0X1000 +STATE_HASPOPUP=0X2000 +STATE_PROTECTED=0X4000 +STATE_REQUIRED=0X8000 +STATE_DEFUNCT=0X10000 +STATE_INVALID_ENTRY=0X20000 +STATE_MODAL=0X40000 +STATE_AUTOCOMPLETE=0x80000 +STATE_MULTILINE=0X100000 +STATE_ICONIFIED=0x200000 +STATE_OFFSCREEN=0x400000 +STATE_SELECTABLE=0x800000 +STATE_FOCUSABLE=0x1000000 +STATE_CLICKABLE=0x2000000 +STATE_EDITABLE=0x4000000 +STATE_CHECKABLE=0x8000000 +STATE_DRAGGABLE=0x10000000 +STATE_DRAGGING=0x20000000 +STATE_DROPTARGET=0x40000000 +STATE_SORTED=0x80000000 +STATE_SORTED_ASCENDING=0x100000000 +STATE_SORTED_DESCENDING=0x200000000 +STATES_SORTED=frozenset([STATE_SORTED,STATE_SORTED_ASCENDING,STATE_SORTED_DESCENDING]) +STATE_HASLONGDESC=0x400000000 +STATE_PINNED=0x800000000 +STATE_HASFORMULA=0x1000000000 #Mostly for spreadsheets +STATE_HASCOMMENT=0X2000000000 +STATE_OBSCURED=0x4000000000 +STATE_CROPPED=0x8000000000 +STATE_OVERFLOWING=0x10000000000 +STATE_UNLOCKED=0x20000000000 +STATE_HAS_ARIA_DETAILS = 0x40000000000 + + +stateLabels: Dict[int, str] = { + # Translators: This is presented when a control or document is unavailable. + STATE_UNAVAILABLE:_("unavailable"), + # Translators: This is presented when a control has focus. + STATE_FOCUSED:_("focused"), + # Translators: This is presented when the control is selected. + STATE_SELECTED:_("selected"), + # Translators: This is presented when a document is busy. + STATE_BUSY:_("busy"), + # Translators: This is presented when a button is pressed. + STATE_PRESSED:_("pressed"), + # Translators: This is presented when a check box is checked. + STATE_CHECKED:_("checked"), + # Translators: This is presented when a three state check box is half checked. + STATE_HALFCHECKED:_("half checked"), + # Translators: This is presented when the control is a read-only control such as read-only edit box. + STATE_READONLY:_("read only"), + # Translators: This is presented when a tree view or submenu item is expanded. + STATE_EXPANDED:_("expanded"), + # Translators: This is presented when a tree view or submenu is collapsed. + STATE_COLLAPSED:_("collapsed"), + # Translators: This is presented when a control or a document becomes invisible. + STATE_INVISIBLE:_("invisible"), + # Translators: This is presented when a visited link is encountered. + STATE_VISITED:_("visited"), + # Translators: This is presented when a link is encountered. + STATE_LINKED:_("linked"), + # Translators: This is presented when the control menu item has a submenu. + STATE_HASPOPUP:_("subMenu"), + # Translators: This is presented when a protected control or a document is encountered. + STATE_PROTECTED:_("protected"), + # Translators: This is presented when a required form field is encountered. + STATE_REQUIRED:_("required"), + # Translators: Reported when an object no longer exists in the user interface; + # i.e. it is dead and is no longer usable. + STATE_DEFUNCT:_("defunct"), + # Translators: This is presented when an invalid entry has been made. + STATE_INVALID_ENTRY:_("invalid entry"), + STATE_MODAL:_("modal"), + # Translators: This is presented when a field supports auto completion of entered text such as email address field in Microsoft Outlook. + STATE_AUTOCOMPLETE:_("has auto complete"), + # Translators: This is presented when an edit field allows typing multiple lines of text such as comment fields on websites. + STATE_MULTILINE:_("multi line"), + STATE_ICONIFIED:_("iconified"), + # Translators: Presented when the current control is located off screen. + STATE_OFFSCREEN:_("off screen"), + # Translators: Presented when the control allows selection such as text fields. + STATE_SELECTABLE:_("selectable"), + # Translators: Presented when a control can be moved to using system focus. + STATE_FOCUSABLE:_("focusable"), + # Translators: Presented when a control allows clicking via mouse (mostly presented on web controls). + STATE_CLICKABLE:_("clickable"), + STATE_EDITABLE:_("editable"), + STATE_CHECKABLE:_("checkable"), + STATE_DRAGGABLE:_("draggable"), + STATE_DRAGGING:_("dragging"), + # Translators: Reported where an object which is being dragged can be dropped. + # This is only reported for objects that support accessible drag and drop. + STATE_DROPTARGET:_("drop target"), + STATE_SORTED:_("sorted"), + STATE_SORTED_ASCENDING:_("sorted ascending"), + STATE_SORTED_DESCENDING:_("sorted descending"), + # Translators: a state that denotes that an object (usually a graphic) has a long description. + STATE_HASLONGDESC:_("has long description"), + # Translators: a state that denotes that an object has additional details (such as a comment section). + STATE_HAS_ARIA_DETAILS: _("has details"), + # Translators: a state that denotes that an object is pinned in its current location + STATE_PINNED:_("pinned"), + # Translators: a state that denotes the existance of a formula on a spreadsheet cell + STATE_HASFORMULA:_("has formula"), + # Translators: a state that denotes the existance of a comment. + STATE_HASCOMMENT:_("has comment"), + # Translators: a state that denotes that the object is covered partially or fully by another object + STATE_OBSCURED:_("obscured"), + # Translators: a state that denotes that the object(text) is cropped as it couldn't be accommodated in the allocated/available space + STATE_CROPPED:_("cropped"), + # Translators: a state that denotes that the object(text) is overflowing into the adjacent space + STATE_OVERFLOWING:_("overflowing"), + # Translators: a state that denotes that the object is unlocked (such as an unlocked cell in a protected Excel spreadsheet). + STATE_UNLOCKED:_("unlocked"), +} + +negativeStateLabels={ + # Translators: This is presented when a selectable object (e.g. a list item) is not selected. + STATE_SELECTED:_("not selected"), + # Translators: This is presented when a button is not pressed. + STATE_PRESSED:_("not pressed"), + # Translators: This is presented when a checkbox is not checked. + STATE_CHECKED:_("not checked"), + # Translators: This is presented when drag and drop is finished. + # This is only reported for objects which support accessible drag and drop. + STATE_DROPTARGET:_("done dragging"), +} From 8353f5fa21a3b655f709fdfde4671de72d55d5a5 Mon Sep 17 00:00:00 2001 From: buddsean Date: Wed, 16 Jun 2021 14:16:12 +1000 Subject: [PATCH 2/2] Implement Enums for Role and State constants in controlTypes (#12510) In order to improve the NVDA API and internal typing, Enums are created for ROLE_* and STATE_* constants. Changes: - retain backwards compatibility until 2022.1 in controlTypes - improve type information for controlTypes processing - create a clickableRoles set in role.py for processAndLabelStates - update docstrings to reflect new types - lint controlTypes due to the mass changes - deprecate helper functions for processAndLabelStates - standardise members of the State enum from 0X[0-9]+ to 0x[0-9]+ - implement a displayStringEnumMixin - deprecate roleLabels, stateLabels, negativeStateLabels - update coding standards for enum usage and deprecations Co-authored-by: Leonard de Ruijter --- devDocs/codingStandards.md | 16 + devDocs/deprecations.md | 21 + source/controlTypes/__init__.py | 248 +++++++ source/controlTypes/isCurrent.py | 21 +- source/controlTypes/processAndLabelStates.py | 210 +++--- source/controlTypes/role.py | 714 ++++++++++--------- source/controlTypes/state.py | 223 +++--- source/utils/__init__.py | 0 source/utils/displayString.py | 71 ++ user_docs/en/changes.t2t | 6 + 10 files changed, 980 insertions(+), 550 deletions(-) create mode 100644 devDocs/deprecations.md create mode 100644 source/utils/__init__.py create mode 100644 source/utils/displayString.py diff --git a/devDocs/codingStandards.md b/devDocs/codingStandards.md index f504a1abb70..cb44faffa32 100644 --- a/devDocs/codingStandards.md +++ b/devDocs/codingStandards.md @@ -44,6 +44,7 @@ for more information. - E.G. `BrailleHandler`. * Constants should be all upper case, separating words with underscores; - E.G. `LANGS_WITH_CONJUNCT_CHARS`. + - Avoid unnecesary shared prefixes in constants. Instead, use an enum for related constants. * Event handlers are prefixed with "event_", subsequent words in camel case. Note, `object` and `action` are separated by underscores. - E.G.: `event_action` or `event_object_action`. @@ -59,6 +60,13 @@ for more information. - TBD. Ideally follows a similar style the others, and communicates if the filtering happens before or after some action. - It would also be nice to have a naming scheme that differentiates it from the others. +* Enums should be formatted using the expected mix of above eg: + ```python + class ExampleGroupOfData(Enum): + CONSTANT_VALUE_MEMBER = auto() + @property + def _formatMember(self): pass + ``` ### Translatable Strings * All strings that could be presented to the user should be marked as translatable using the `_()` @@ -86,3 +94,11 @@ self.copySettingsButton = wx.Button( ) ) ``` + +### Imports +* Unused imports should be removed where possible. + - Anything imported into a (sub)module can also be imported from that submodule. + - As a result, removing unused imports may break compatibility, and should be done in compatibility breaking releases (see `deprecations.md`). +* Unused imports will give a lint warning. These can be handled the following ways: + - If these imports are inteded to be imported from other modules, they can be done included in a definition for `__all__`. This will override and define the symbols imported when performing a star import, eg `from module import *`. + - Otherwise, with a comment like `# noqa: `. diff --git a/devDocs/deprecations.md b/devDocs/deprecations.md new file mode 100644 index 00000000000..2610caa431c --- /dev/null +++ b/devDocs/deprecations.md @@ -0,0 +1,21 @@ +The NVDA API must maintain compatibility with add-ons throughout yearly development cycles. +The first release of a year, i.e. `20XX.1`, is when the NVDA API can introduce breaking changes. + +In order to improve the NVDA API, changes that will break future compatibility can be implemented, as long they retain backwards compatibility until the `20XX.1` release. + +This can be done by using a version check to automate deprecation. For example, if you wish to replace usages of `foo` with `bar`. When we begin work on `NEXT_YEAR`, `foo` will no longer be part of the NVDA API and all internal usages must be removed prior. +```python +from buildVersion import version_year +if version_year < NEXT_YEAR: + foo = bar +``` + +To ensure a module retains the same symbol names being importable, check across versions what is imported using the NVDA python console. +```python +import controlTypes +dir(controlTypes) +``` + +Changes different to moving or renaming symbols need to be considered carefully with a different approach. + +Any API breaking changes such as deprecations marked for removal should be commented with the year of intended removal, and notes on how to implement the API change as an add-on developer and NVDA developer. diff --git a/source/controlTypes/__init__.py b/source/controlTypes/__init__.py index e69de29bb2d..7a1cd35cdd4 100644 --- a/source/controlTypes/__init__.py +++ b/source/controlTypes/__init__.py @@ -0,0 +1,248 @@ +# A part of NonVisual Desktop Access (NVDA) +# This file is covered by the GNU General Public License. +# See the file COPYING for more details. +# Copyright (C) 2007-2021 NV Access Limited, Babbage B.V. + +from buildVersion import version_year + +from .isCurrent import IsCurrent +from .outputReason import OutputReason +from .processAndLabelStates import processAndLabelStates +from .role import Role, silentRolesOnFocus, silentValuesForRoles +from .state import State, STATES_SORTED + + +# To maintain backwards compatibility, all symbols are exported from the package until 2022.1 +if version_year >= 2022: + # Override (and limit) the symbols exported by the controlTypes package + # These are the symbols available when `from controlTypes import *` is used. + __all__ = [ + "IsCurrent", + "OutputReason", + "processAndLabelStates", + "Role", + "silentRolesOnFocus", + "silentValuesForRoles", + "State", + "STATES_SORTED", + ] + + +# Added to maintain backwards compatibility, marked for deprecation to be removed in 2022.1 +# usages to be avoided or replaced by .processAndLabelStates.[_processNegativeStates|_processPositiveStates] +if version_year < 2022: + from .processAndLabelStates import _processNegativeStates, _processPositiveStates + processNegativeStates = _processNegativeStates + processPositiveStates = _processPositiveStates + + +# Added to maintain backwards compatibility, marked for deprecation to be removed in 2022.1 +# usages to be replaced by Role.*.displayString and State.*.displayString +if version_year < 2022: + from .role import _roleLabels + from .state import _stateLabels, _negativeStateLabels + roleLabels = _roleLabels + stateLabels = _stateLabels + negativeStateLabels = _negativeStateLabels + + +# Added to maintain backwards compatibility, marked for deprecation to be removed in 2022.1 +if version_year < 2022: + ROLE_UNKNOWN = Role.UNKNOWN + ROLE_WINDOW = Role.WINDOW + ROLE_TITLEBAR = Role.TITLEBAR + ROLE_PANE = Role.PANE + ROLE_DIALOG = Role.DIALOG + ROLE_CHECKBOX = Role.CHECKBOX + ROLE_RADIOBUTTON = Role.RADIOBUTTON + ROLE_STATICTEXT = Role.STATICTEXT + ROLE_EDITABLETEXT = Role.EDITABLETEXT + ROLE_BUTTON = Role.BUTTON + ROLE_MENUBAR = Role.MENUBAR + ROLE_MENUITEM = Role.MENUITEM + ROLE_POPUPMENU = Role.POPUPMENU + ROLE_COMBOBOX = Role.COMBOBOX + ROLE_LIST = Role.LIST + ROLE_LISTITEM = Role.LISTITEM + ROLE_GRAPHIC = Role.GRAPHIC + ROLE_HELPBALLOON = Role.HELPBALLOON + ROLE_TOOLTIP = Role.TOOLTIP + ROLE_LINK = Role.LINK + ROLE_TREEVIEW = Role.TREEVIEW + ROLE_TREEVIEWITEM = Role.TREEVIEWITEM + ROLE_TAB = Role.TAB + ROLE_TABCONTROL = Role.TABCONTROL + ROLE_SLIDER = Role.SLIDER + ROLE_PROGRESSBAR = Role.PROGRESSBAR + ROLE_SCROLLBAR = Role.SCROLLBAR + ROLE_STATUSBAR = Role.STATUSBAR + ROLE_TABLE = Role.TABLE + ROLE_TABLECELL = Role.TABLECELL + ROLE_TABLECOLUMN = Role.TABLECOLUMN + ROLE_TABLEROW = Role.TABLEROW + ROLE_TABLECOLUMNHEADER = Role.TABLECOLUMNHEADER + ROLE_TABLEROWHEADER = Role.TABLEROWHEADER + ROLE_FRAME = Role.FRAME + ROLE_TOOLBAR = Role.TOOLBAR + ROLE_DROPDOWNBUTTON = Role.DROPDOWNBUTTON + ROLE_CLOCK = Role.CLOCK + ROLE_SEPARATOR = Role.SEPARATOR + ROLE_FORM = Role.FORM + ROLE_HEADING = Role.HEADING + ROLE_HEADING1 = Role.HEADING1 + ROLE_HEADING2 = Role.HEADING2 + ROLE_HEADING3 = Role.HEADING3 + ROLE_HEADING4 = Role.HEADING4 + ROLE_HEADING5 = Role.HEADING5 + ROLE_HEADING6 = Role.HEADING6 + ROLE_PARAGRAPH = Role.PARAGRAPH + ROLE_BLOCKQUOTE = Role.BLOCKQUOTE + ROLE_TABLEHEADER = Role.TABLEHEADER + ROLE_TABLEBODY = Role.TABLEBODY + ROLE_TABLEFOOTER = Role.TABLEFOOTER + ROLE_DOCUMENT = Role.DOCUMENT + ROLE_ANIMATION = Role.ANIMATION + ROLE_APPLICATION = Role.APPLICATION + ROLE_BOX = Role.BOX + ROLE_GROUPING = Role.GROUPING + ROLE_PROPERTYPAGE = Role.PROPERTYPAGE + ROLE_CANVAS = Role.CANVAS + ROLE_CAPTION = Role.CAPTION + ROLE_CHECKMENUITEM = Role.CHECKMENUITEM + ROLE_DATEEDITOR = Role.DATEEDITOR + ROLE_ICON = Role.ICON + ROLE_DIRECTORYPANE = Role.DIRECTORYPANE + ROLE_EMBEDDEDOBJECT = Role.EMBEDDEDOBJECT + ROLE_ENDNOTE = Role.ENDNOTE + ROLE_FOOTER = Role.FOOTER + ROLE_FOOTNOTE = Role.FOOTNOTE + ROLE_GLASSPANE = Role.GLASSPANE + ROLE_HEADER = Role.HEADER + ROLE_IMAGEMAP = Role.IMAGEMAP + ROLE_INPUTWINDOW = Role.INPUTWINDOW + ROLE_LABEL = Role.LABEL + ROLE_NOTE = Role.NOTE + ROLE_PAGE = Role.PAGE + ROLE_RADIOMENUITEM = Role.RADIOMENUITEM + ROLE_LAYEREDPANE = Role.LAYEREDPANE + ROLE_REDUNDANTOBJECT = Role.REDUNDANTOBJECT + ROLE_ROOTPANE = Role.ROOTPANE + ROLE_EDITBAR = Role.EDITBAR + ROLE_TERMINAL = Role.TERMINAL + ROLE_RICHEDIT = Role.RICHEDIT + ROLE_RULER = Role.RULER + ROLE_SCROLLPANE = Role.SCROLLPANE + ROLE_SECTION = Role.SECTION + ROLE_SHAPE = Role.SHAPE + ROLE_SPLITPANE = Role.SPLITPANE + ROLE_VIEWPORT = Role.VIEWPORT + ROLE_TEAROFFMENU = Role.TEAROFFMENU + ROLE_TEXTFRAME = Role.TEXTFRAME + ROLE_TOGGLEBUTTON = Role.TOGGLEBUTTON + ROLE_BORDER = Role.BORDER + ROLE_CARET = Role.CARET + ROLE_CHARACTER = Role.CHARACTER + ROLE_CHART = Role.CHART + ROLE_CURSOR = Role.CURSOR + ROLE_DIAGRAM = Role.DIAGRAM + ROLE_DIAL = Role.DIAL + ROLE_DROPLIST = Role.DROPLIST + ROLE_SPLITBUTTON = Role.SPLITBUTTON + ROLE_MENUBUTTON = Role.MENUBUTTON + ROLE_DROPDOWNBUTTONGRID = Role.DROPDOWNBUTTONGRID + ROLE_MATH = Role.MATH + ROLE_GRIP = Role.GRIP + ROLE_HOTKEYFIELD = Role.HOTKEYFIELD + ROLE_INDICATOR = Role.INDICATOR + ROLE_SPINBUTTON = Role.SPINBUTTON + ROLE_SOUND = Role.SOUND + ROLE_WHITESPACE = Role.WHITESPACE + ROLE_TREEVIEWBUTTON = Role.TREEVIEWBUTTON + ROLE_IPADDRESS = Role.IPADDRESS + ROLE_DESKTOPICON = Role.DESKTOPICON + ROLE_INTERNALFRAME = Role.INTERNALFRAME + ROLE_DESKTOPPANE = Role.DESKTOPPANE + ROLE_OPTIONPANE = Role.OPTIONPANE + ROLE_COLORCHOOSER = Role.COLORCHOOSER + ROLE_FILECHOOSER = Role.FILECHOOSER + ROLE_FILLER = Role.FILLER + ROLE_MENU = Role.MENU + ROLE_PANEL = Role.PANEL + ROLE_PASSWORDEDIT = Role.PASSWORDEDIT + ROLE_FONTCHOOSER = Role.FONTCHOOSER + ROLE_LINE = Role.LINE + ROLE_FONTNAME = Role.FONTNAME + ROLE_FONTSIZE = Role.FONTSIZE + ROLE_BOLD = Role.BOLD + ROLE_ITALIC = Role.ITALIC + ROLE_UNDERLINE = Role.UNDERLINE + ROLE_FGCOLOR = Role.FGCOLOR + ROLE_BGCOLOR = Role.BGCOLOR + ROLE_SUPERSCRIPT = Role.SUPERSCRIPT + ROLE_SUBSCRIPT = Role.SUBSCRIPT + ROLE_STYLE = Role.STYLE + ROLE_INDENT = Role.INDENT + ROLE_ALIGNMENT = Role.ALIGNMENT + ROLE_ALERT = Role.ALERT + ROLE_DATAGRID = Role.DATAGRID + ROLE_DATAITEM = Role.DATAITEM + ROLE_HEADERITEM = Role.HEADERITEM + ROLE_THUMB = Role.THUMB + ROLE_CALENDAR = Role.CALENDAR + ROLE_VIDEO = Role.VIDEO + ROLE_AUDIO = Role.AUDIO + ROLE_CHARTELEMENT = Role.CHARTELEMENT + ROLE_DELETED_CONTENT = Role.DELETED_CONTENT + ROLE_INSERTED_CONTENT = Role.INSERTED_CONTENT + ROLE_LANDMARK = Role.LANDMARK + ROLE_ARTICLE = Role.ARTICLE + ROLE_REGION = Role.REGION + ROLE_FIGURE = Role.FIGURE + ROLE_MARKED_CONTENT = Role.MARKED_CONTENT + + +# Added to maintain backwards compatibility, marked for deprecation to be removed in 2022.1 +if version_year < 2022: + STATE_UNAVAILABLE = State.UNAVAILABLE + STATE_FOCUSED = State.FOCUSED + STATE_SELECTED = State.SELECTED + STATE_BUSY = State.BUSY + STATE_PRESSED = State.PRESSED + STATE_CHECKED = State.CHECKED + STATE_HALFCHECKED = State.HALFCHECKED + STATE_READONLY = State.READONLY + STATE_EXPANDED = State.EXPANDED + STATE_COLLAPSED = State.COLLAPSED + STATE_INVISIBLE = State.INVISIBLE + STATE_VISITED = State.VISITED + STATE_LINKED = State.LINKED + STATE_HASPOPUP = State.HASPOPUP + STATE_PROTECTED = State.PROTECTED + STATE_REQUIRED = State.REQUIRED + STATE_DEFUNCT = State.DEFUNCT + STATE_INVALID_ENTRY = State.INVALID_ENTRY + STATE_MODAL = State.MODAL + STATE_AUTOCOMPLETE = State.AUTOCOMPLETE + STATE_MULTILINE = State.MULTILINE + STATE_ICONIFIED = State.ICONIFIED + STATE_OFFSCREEN = State.OFFSCREEN + STATE_SELECTABLE = State.SELECTABLE + STATE_FOCUSABLE = State.FOCUSABLE + STATE_CLICKABLE = State.CLICKABLE + STATE_EDITABLE = State.EDITABLE + STATE_CHECKABLE = State.CHECKABLE + STATE_DRAGGABLE = State.DRAGGABLE + STATE_DRAGGING = State.DRAGGING + STATE_DROPTARGET = State.DROPTARGET + STATE_SORTED = State.SORTED + STATE_SORTED_ASCENDING = State.SORTED_ASCENDING + STATE_SORTED_DESCENDING = State.SORTED_DESCENDING + STATE_HASLONGDESC = State.HASLONGDESC + STATE_PINNED = State.PINNED + STATE_HASFORMULA = State.HASFORMULA + STATE_HASCOMMENT = State.HASCOMMENT + STATE_OBSCURED = State.OBSCURED + STATE_CROPPED = State.CROPPED + STATE_OVERFLOWING = State.OVERFLOWING + STATE_UNLOCKED = State.UNLOCKED + STATE_HAS_ARIA_DETAILS = State.HAS_ARIA_DETAILS diff --git a/source/controlTypes/isCurrent.py b/source/controlTypes/isCurrent.py index 03f916a9c95..d6288b421ea 100644 --- a/source/controlTypes/isCurrent.py +++ b/source/controlTypes/isCurrent.py @@ -3,13 +3,12 @@ # See the file COPYING for more details. # Copyright (C) 2007-2021 NV Access Limited, Babbage B.V. -from enum import Enum from typing import Dict -from logHandler import log +from utils.displayString import DisplayStringStrEnum -class IsCurrent(Enum): +class IsCurrent(DisplayStringStrEnum): """Values to use within NVDA to denote 'current' values. These describe if an item is the current item within a particular kind of selection. EG aria-current @@ -22,23 +21,21 @@ class IsCurrent(Enum): DATE = "date" TIME = "time" + @property + def _displayStringLabels(self): + return _isCurrentLabels + @property def displayString(self): - """ - @return: The translated UI display string that should be used for this value of the IsCurrent enum - """ try: - return _isCurrentLabels[self] + return super().displayString except KeyError: - log.debugWarning(f"No translation mapping for: {self}") - # there is a value for 'current' but NVDA hasn't learned about it yet, - # at least describe in the general sense that this item is 'current' - return _isCurrentLabels[IsCurrent.YES] + return self.YES.displayString #: Text to use for 'current' values. These describe if an item is the current item #: within a particular kind of selection. EG aria-current -_isCurrentLabels: Dict[Enum, str] = { +_isCurrentLabels: Dict[IsCurrent, str] = { IsCurrent.NO: "", # There is nothing extra to say for items that are not current. # Translators: Presented when an item is marked as current in a collection of items IsCurrent.YES: _("current"), diff --git a/source/controlTypes/processAndLabelStates.py b/source/controlTypes/processAndLabelStates.py index 53532385b3b..34b0ffadfc1 100644 --- a/source/controlTypes/processAndLabelStates.py +++ b/source/controlTypes/processAndLabelStates.py @@ -3,142 +3,147 @@ # See the file COPYING for more details. # Copyright (C) 2007-2021 NV Access Limited, Babbage B.V. -from typing import Any, Dict, List, Optional, Set +from typing import Dict, List, Optional, Set -from .role import * -from .state import STATES_SORTED, negativeStateLabels, stateLabels, * +from .role import Role, clickableRoles +from .state import State, STATES_SORTED from .outputReason import OutputReason -def processPositiveStates(role, states, reason: OutputReason, positiveStates=None): +def _processPositiveStates( + role: Role, + states: Set[State], + reason: OutputReason, + positiveStates: Optional[Set[State]] = None +) -> Set[State]: """Processes the states for an object and returns the positive states to output for a specified reason. - For example, if C{STATE_CHECKED} is in the returned states, it means that the processed object is checked. - @param role: The role of the object to process states for (e.g. C{ROLE_CHECKBOX}. - @type role: int + For example, if C{State.CHECKED} is in the returned states, it means that the processed object is checked. + @param role: The role of the object to process states for (e.g. C{Role.CHECKBOX}). @param states: The raw states for an object to process. - @type states: set - @param reason: The reason to process the states (e.g. C{OutputReason.FOCUS}. - @param positiveStates: Used for C{OutputReason.CHANGE}, specifies states changed from negative to positive; - @type positiveStates: set + @param reason: The reason to process the states (e.g. C{OutputReason.FOCUS}). + @param positiveStates: Used for C{OutputReason.CHANGE}, specifies states changed from negative to + positive. @return: The processed positive states. - @rtype: set """ positiveStates = positiveStates.copy() if positiveStates is not None else states.copy() # The user never cares about certain states. - if role==ROLE_EDITABLETEXT: - positiveStates.discard(STATE_EDITABLE) - if role!=ROLE_LINK: - positiveStates.discard(STATE_VISITED) - positiveStates.discard(STATE_SELECTABLE) - positiveStates.discard(STATE_FOCUSABLE) - positiveStates.discard(STATE_CHECKABLE) - if STATE_DRAGGING in positiveStates: + if role == Role.EDITABLETEXT: + positiveStates.discard(State.EDITABLE) + if role != Role.LINK: + positiveStates.discard(State.VISITED) + positiveStates.discard(State.SELECTABLE) + positiveStates.discard(State.FOCUSABLE) + positiveStates.discard(State.CHECKABLE) + if State.DRAGGING in positiveStates: # It's obvious that the control is draggable if it's being dragged. - positiveStates.discard(STATE_DRAGGABLE) - if role == ROLE_COMBOBOX: + positiveStates.discard(State.DRAGGABLE) + if role == Role.COMBOBOX: # Combo boxes inherently have a popup, so don't report it. - positiveStates.discard(STATE_HASPOPUP) + positiveStates.discard(State.HASPOPUP) import config - if not config.conf['documentFormatting']['reportClickable'] or role in (ROLE_LINK, ROLE_BUTTON, ROLE_CHECKBOX, ROLE_RADIOBUTTON, ROLE_TOGGLEBUTTON, ROLE_MENUITEM, ROLE_TAB, ROLE_SLIDER, ROLE_DOCUMENT, ROLE_CHECKMENUITEM, ROLE_RADIOMENUITEM): + if not config.conf['documentFormatting']['reportClickable'] or role in clickableRoles: # This control is clearly clickable according to its role, # or reporting clickable just isn't useful, # or the user has explicitly requested no reporting clickable - positiveStates.discard(STATE_CLICKABLE) + positiveStates.discard(State.CLICKABLE) if reason == OutputReason.QUERY: return positiveStates - positiveStates.discard(STATE_DEFUNCT) - positiveStates.discard(STATE_MODAL) - positiveStates.discard(STATE_FOCUSED) - positiveStates.discard(STATE_OFFSCREEN) - positiveStates.discard(STATE_INVISIBLE) + positiveStates.discard(State.DEFUNCT) + positiveStates.discard(State.MODAL) + positiveStates.discard(State.FOCUSED) + positiveStates.discard(State.OFFSCREEN) + positiveStates.discard(State.INVISIBLE) if reason != OutputReason.CHANGE: - positiveStates.discard(STATE_LINKED) + positiveStates.discard(State.LINKED) if role in ( - ROLE_LISTITEM, - ROLE_TREEVIEWITEM, - ROLE_MENUITEM, - ROLE_TABLEROW, - ROLE_CHECKBOX, - ) and STATE_SELECTABLE in states: - positiveStates.discard(STATE_SELECTED) - if role not in (ROLE_EDITABLETEXT, ROLE_CHECKBOX): - positiveStates.discard(STATE_READONLY) - if role == ROLE_CHECKBOX: - positiveStates.discard(STATE_PRESSED) - if role == ROLE_MENUITEM and STATE_HASPOPUP in positiveStates: + Role.LISTITEM, + Role.TREEVIEWITEM, + Role.MENUITEM, + Role.TABLEROW, + Role.CHECKBOX, + ) and State.SELECTABLE in states: + positiveStates.discard(State.SELECTED) + if role not in (Role.EDITABLETEXT, Role.CHECKBOX): + positiveStates.discard(State.READONLY) + if role == Role.CHECKBOX: + positiveStates.discard(State.PRESSED) + if role == Role.MENUITEM and State.HASPOPUP in positiveStates: # The user doesn't usually care if a submenu is expanded or collapsed. - positiveStates.discard(STATE_COLLAPSED) - positiveStates.discard(STATE_EXPANDED) - if STATE_FOCUSABLE not in states: - positiveStates.discard(STATE_EDITABLE) + positiveStates.discard(State.COLLAPSED) + positiveStates.discard(State.EXPANDED) + if State.FOCUSABLE not in states: + positiveStates.discard(State.EDITABLE) if not config.conf["annotations"]["reportDetails"]: # reading aria-details is an experimental feature still and should not always be reported. - positiveStates.discard(STATE_HAS_ARIA_DETAILS) + positiveStates.discard(State.HAS_ARIA_DETAILS) return positiveStates -def processNegativeStates(role, states, reason: OutputReason, negativeStates=None): +def _processNegativeStates( + role: Role, + states: Set[State], + reason: OutputReason, + negativeStates: Optional[Set[State]] = None +) -> Set[State]: """Processes the states for an object and returns the negative states to output for a specified reason. - For example, if C{STATE_CHECKED} is in the returned states, it means that the processed object is not checked. - @param role: The role of the object to process states for (e.g. C{ROLE_CHECKBOX}. - @type role: int + For example, if C{State.CHECKED} is in the returned states, it means that the processed object is not + checked. + @param role: The role of the object to process states for (e.g. C{Role.CHECKBOX}). @param states: The raw states for an object to process. - @type states: set - @param reason: The reason to process the states (e.g. C{OutputReason.FOCUS}. - @param negativeStates: Used for C{OutputReason.CHANGE}, specifies states changed from positive to negative; - @type negativeStates: set + @param reason: The reason to process the states (e.g. C{OutputReason.FOCUS)}. + @param negativeStates: Used for C{OutputReason.CHANGE}, specifies states changed from positive to + negative. @return: The processed negative states. - @rtype: set """ if reason == OutputReason.CHANGE and not isinstance(negativeStates, set): raise TypeError("negativeStates must be a set for this reason") speakNegatives = set() # Add the negative selected state if the control is selectable, - # but only if it is reported for the reason of focus, or this is a change to the focused object. + # but only if it is reported for the reason of focus, or this is a change to the focused object. # The condition stops "not selected" from being spoken in some broken controls # when the state change for the previous focus is issued before the focus change. if ( # Only include if the object is actually selectable - STATE_SELECTABLE in states + State.SELECTABLE in states # Only include if the object is focusable (E.g. ARIA grid cells, but not standard html tables) - and STATE_FOCUSABLE in states + and State.FOCUSABLE in states # Only include if reporting the focus or when states are changing on the focus. - # This is to avoid exposing it for things like caret movement in browse mode. - and (reason == OutputReason.FOCUS or (reason == OutputReason.CHANGE and STATE_FOCUSED in states)) + # This is to avoid exposing it for things like caret movement in browse mode. + and (reason == OutputReason.FOCUS or (reason == OutputReason.CHANGE and State.FOCUSED in states)) and role in ( - ROLE_LISTITEM, - ROLE_TREEVIEWITEM, - ROLE_TABLEROW, - ROLE_TABLECELL, - ROLE_TABLECOLUMNHEADER, - ROLE_TABLEROWHEADER, - ROLE_CHECKBOX, + Role.LISTITEM, + Role.TREEVIEWITEM, + Role.TABLEROW, + Role.TABLECELL, + Role.TABLECOLUMNHEADER, + Role.TABLEROWHEADER, + Role.CHECKBOX, ) ): - speakNegatives.add(STATE_SELECTED) + speakNegatives.add(State.SELECTED) # Restrict "not checked" in a similar way to "not selected". if( - (role in (ROLE_CHECKBOX, ROLE_RADIOBUTTON, ROLE_CHECKMENUITEM) or STATE_CHECKABLE in states) - and (STATE_HALFCHECKED not in states) - and (reason != OutputReason.CHANGE or STATE_FOCUSED in states) + (role in (Role.CHECKBOX, Role.RADIOBUTTON, Role.CHECKMENUITEM) or State.CHECKABLE in states) + and (State.HALFCHECKED not in states) + and (reason != OutputReason.CHANGE or State.FOCUSED in states) ): - speakNegatives.add(STATE_CHECKED) - if role == ROLE_TOGGLEBUTTON: - speakNegatives.add(STATE_PRESSED) + speakNegatives.add(State.CHECKED) + if role == Role.TOGGLEBUTTON: + speakNegatives.add(State.PRESSED) if reason == OutputReason.CHANGE: # We want to speak this state only if it is changing to negative. - speakNegatives.add(STATE_DROPTARGET) + speakNegatives.add(State.DROPTARGET) # We were given states which have changed to negative. # Return only those supplied negative states which should be spoken; # i.e. the states in both sets. speakNegatives &= negativeStates # #6946: if HALFCHECKED is present but CHECKED isn't, we should make sure we add CHECKED to speakNegatives. - if (STATE_HALFCHECKED in negativeStates and STATE_CHECKED not in states): - speakNegatives.add(STATE_CHECKED) + if (State.HALFCHECKED in negativeStates and State.CHECKED not in states): + speakNegatives.add(State.CHECKED) if STATES_SORTED & negativeStates and not STATES_SORTED & states: # If the object has just stopped being sorted, just report not sorted. # The user doesn't care how it was sorted before. - speakNegatives.add(STATE_SORTED) + speakNegatives.add(State.SORTED) return speakNegatives else: # This is not a state change; only positive states were supplied. @@ -147,34 +152,35 @@ def processNegativeStates(role, states, reason: OutputReason, negativeStates=Non def processAndLabelStates( - role: int, - states: Set[Any], + role: Role, + states: Set[State], reason: OutputReason, - positiveStates: Optional[Set[Any]] = None, - negativeStates: Optional[Set[Any]] = None, - positiveStateLabelDict: Dict[int, str] = {}, - negativeStateLabelDict: Dict[int, str] = {}, + positiveStates: Optional[Set[State]] = None, + negativeStates: Optional[Set[State]] = None, + positiveStateLabelDict: Dict[State, str] = {}, + negativeStateLabelDict: Dict[State, str] = {}, ) -> List[str]: - """Processes the states for an object and returns the appropriate state labels for both positive and negative states. - @param role: The role of the object to process states for (e.g. C{ROLE_CHECKBOX}. + """Processes the states for an object and returns the appropriate state labels for both positive and + negative states. + @param role: The role of the object to process states for (e.g. C{Role.CHECKBOX}). @param states: The raw states for an object to process. - @param reason: The reason to process the states (e.g. C{OutputReason.FOCUS}. - @param positiveStates: Used for C{OutputReason.CHANGE}, specifies states changed from negative to positive; - @param negativeStates: Used for C{OutputReason.CHANGE}, specifies states changed from positive to negative; - @param positiveStateLabelDict: Dictionary containing state identifiers as keys and associated positive labels as their values. - @param negativeStateLabelDict: Dictionary containing state identifiers as keys and associated negative labels as their values. + @param reason: The reason to process the states (e.g. C{OutputReason.FOCUS}). + @param positiveStates: Used for C{OutputReason.CHANGE}, specifies states changed from negative to + positive. + @param negativeStates: Used for C{OutputReason.CHANGE}, specifies states changed from positive to + negative. + @param positiveStateLabelDict: Dictionary containing state identifiers as keys and associated positive + labels as their values. + @param negativeStateLabelDict: Dictionary containing state identifiers as keys and associated negative + labels as their values. @return: The labels of the relevant positive and negative states. """ - mergedStateLabels=[] - positiveStates = processPositiveStates(role, states, reason, positiveStates) - negativeStates = processNegativeStates(role, states, reason, negativeStates) + mergedStateLabels = [] + positiveStates = _processPositiveStates(role, states, reason, positiveStates) + negativeStates = _processNegativeStates(role, states, reason, negativeStates) for state in sorted(positiveStates | negativeStates): if state in positiveStates: - mergedStateLabels.append(positiveStateLabelDict.get(state, stateLabels[state])) + mergedStateLabels.append(positiveStateLabelDict.get(state, state.displayString)) elif state in negativeStates: - # Translators: Indicates that a particular state of an object is negated. - # Separate strings have now been defined for commonly negated states (e.g. not selected and not checked), - # but this still might be used in some other cases. - # %s will be replaced with the full identifier of the negated state (e.g. selected). - mergedStateLabels.append(negativeStateLabelDict.get(state, negativeStateLabels.get(state, _("not %s") % stateLabels[state]))) + mergedStateLabels.append(negativeStateLabelDict.get(state, state.negativeDisplayString)) return mergedStateLabels diff --git a/source/controlTypes/role.py b/source/controlTypes/role.py index 48fd9a871be..2c668da2667 100644 --- a/source/controlTypes/role.py +++ b/source/controlTypes/role.py @@ -3,488 +3,524 @@ # See the file COPYING for more details. # Copyright (C) 2007-2021 NV Access Limited, Babbage B.V. -from typing import Dict +from typing import Dict, Set +from utils.displayString import DisplayStringIntEnum -ROLE_UNKNOWN=0 -ROLE_WINDOW=1 -ROLE_TITLEBAR=2 -ROLE_PANE=3 -ROLE_DIALOG=4 -ROLE_CHECKBOX=5 -ROLE_RADIOBUTTON=6 -ROLE_STATICTEXT=7 -ROLE_EDITABLETEXT=8 -ROLE_BUTTON=9 -ROLE_MENUBAR=10 -ROLE_MENUITEM=11 -ROLE_POPUPMENU=12 -ROLE_COMBOBOX=13 -ROLE_LIST=14 -ROLE_LISTITEM=15 -ROLE_GRAPHIC=16 -ROLE_HELPBALLOON=17 -ROLE_TOOLTIP=18 -ROLE_LINK=19 -ROLE_TREEVIEW=20 -ROLE_TREEVIEWITEM=21 -ROLE_TAB=22 -ROLE_TABCONTROL=23 -ROLE_SLIDER=24 -ROLE_PROGRESSBAR=25 -ROLE_SCROLLBAR=26 -ROLE_STATUSBAR=27 -ROLE_TABLE=28 -ROLE_TABLECELL=29 -ROLE_TABLECOLUMN=30 -ROLE_TABLEROW=31 -ROLE_TABLECOLUMNHEADER=32 -ROLE_TABLEROWHEADER=33 -ROLE_FRAME=34 -ROLE_TOOLBAR=35 -ROLE_DROPDOWNBUTTON=36 -ROLE_CLOCK=37 -ROLE_SEPARATOR=38 -ROLE_FORM=39 -ROLE_HEADING=40 -ROLE_HEADING1=41 -ROLE_HEADING2=42 -ROLE_HEADING3=43 -ROLE_HEADING4=44 -ROLE_HEADING5=45 -ROLE_HEADING6=46 -ROLE_PARAGRAPH=47 -ROLE_BLOCKQUOTE=48 -ROLE_TABLEHEADER=49 -ROLE_TABLEBODY=50 -ROLE_TABLEFOOTER=51 -ROLE_DOCUMENT=52 -ROLE_ANIMATION=53 -ROLE_APPLICATION=54 -ROLE_BOX=55 -ROLE_GROUPING=56 -ROLE_PROPERTYPAGE=57 -ROLE_CANVAS=58 -ROLE_CAPTION=59 -ROLE_CHECKMENUITEM=60 -ROLE_DATEEDITOR=61 -ROLE_ICON=62 -ROLE_DIRECTORYPANE=63 -ROLE_EMBEDDEDOBJECT=64 -ROLE_ENDNOTE=65 -ROLE_FOOTER=66 -ROLE_FOOTNOTE=67 -ROLE_GLASSPANE=69 -ROLE_HEADER=70 -ROLE_IMAGEMAP=71 -ROLE_INPUTWINDOW=72 -ROLE_LABEL=73 -ROLE_NOTE=74 -ROLE_PAGE=75 -ROLE_RADIOMENUITEM=76 -ROLE_LAYEREDPANE=77 -ROLE_REDUNDANTOBJECT=78 -ROLE_ROOTPANE=79 -ROLE_EDITBAR=80 -ROLE_TERMINAL=82 -ROLE_RICHEDIT=83 -ROLE_RULER=84 -ROLE_SCROLLPANE=85 -ROLE_SECTION=86 -ROLE_SHAPE=87 -ROLE_SPLITPANE=88 -ROLE_VIEWPORT=89 -ROLE_TEAROFFMENU=90 -ROLE_TEXTFRAME=91 -ROLE_TOGGLEBUTTON=92 -ROLE_BORDER=93 -ROLE_CARET=94 -ROLE_CHARACTER=95 -ROLE_CHART=96 -ROLE_CURSOR=97 -ROLE_DIAGRAM=98 -ROLE_DIAL=99 -ROLE_DROPLIST=100 -ROLE_SPLITBUTTON=101 -ROLE_MENUBUTTON=102 -ROLE_DROPDOWNBUTTONGRID=103 -ROLE_MATH=104 -ROLE_GRIP=105 -ROLE_HOTKEYFIELD=106 -ROLE_INDICATOR=107 -ROLE_SPINBUTTON=108 -ROLE_SOUND=109 -ROLE_WHITESPACE=110 -ROLE_TREEVIEWBUTTON=111 -ROLE_IPADDRESS=112 -ROLE_DESKTOPICON=113 -ROLE_INTERNALFRAME=115 -ROLE_DESKTOPPANE=116 -ROLE_OPTIONPANE=117 -ROLE_COLORCHOOSER=118 -ROLE_FILECHOOSER=119 -ROLE_FILLER=120 -ROLE_MENU=121 -ROLE_PANEL=122 -ROLE_PASSWORDEDIT=123 -ROLE_FONTCHOOSER=124 -ROLE_LINE=125 -ROLE_FONTNAME=126 -ROLE_FONTSIZE=127 -ROLE_BOLD=128 -ROLE_ITALIC=129 -ROLE_UNDERLINE=130 -ROLE_FGCOLOR=131 -ROLE_BGCOLOR=132 -ROLE_SUPERSCRIPT=133 -ROLE_SUBSCRIPT=134 -ROLE_STYLE=135 -ROLE_INDENT=136 -ROLE_ALIGNMENT=137 -ROLE_ALERT=138 -ROLE_DATAGRID=139 -ROLE_DATAITEM=140 -ROLE_HEADERITEM=141 -ROLE_THUMB=142 -ROLE_CALENDAR=143 -ROLE_VIDEO=144 -ROLE_AUDIO=145 -ROLE_CHARTELEMENT=146 -ROLE_DELETED_CONTENT=147 -ROLE_INSERTED_CONTENT=148 -ROLE_LANDMARK = 149 -ROLE_ARTICLE = 150 -ROLE_REGION = 151 -ROLE_FIGURE = 152 -ROLE_MARKED_CONTENT = 153 +class Role(DisplayStringIntEnum): + @property + def _displayStringLabels(self): + return _roleLabels -roleLabels: Dict[int, str] = { + UNKNOWN = 0 + WINDOW = 1 + TITLEBAR = 2 + PANE = 3 + DIALOG = 4 + CHECKBOX = 5 + RADIOBUTTON = 6 + STATICTEXT = 7 + EDITABLETEXT = 8 + BUTTON = 9 + MENUBAR = 10 + MENUITEM = 11 + POPUPMENU = 12 + COMBOBOX = 13 + LIST = 14 + LISTITEM = 15 + GRAPHIC = 16 + HELPBALLOON = 17 + TOOLTIP = 18 + LINK = 19 + TREEVIEW = 20 + TREEVIEWITEM = 21 + TAB = 22 + TABCONTROL = 23 + SLIDER = 24 + PROGRESSBAR = 25 + SCROLLBAR = 26 + STATUSBAR = 27 + TABLE = 28 + TABLECELL = 29 + TABLECOLUMN = 30 + TABLEROW = 31 + TABLECOLUMNHEADER = 32 + TABLEROWHEADER = 33 + FRAME = 34 + TOOLBAR = 35 + DROPDOWNBUTTON = 36 + CLOCK = 37 + SEPARATOR = 38 + FORM = 39 + HEADING = 40 + HEADING1 = 41 + HEADING2 = 42 + HEADING3 = 43 + HEADING4 = 44 + HEADING5 = 45 + HEADING6 = 46 + PARAGRAPH = 47 + BLOCKQUOTE = 48 + TABLEHEADER = 49 + TABLEBODY = 50 + TABLEFOOTER = 51 + DOCUMENT = 52 + ANIMATION = 53 + APPLICATION = 54 + BOX = 55 + GROUPING = 56 + PROPERTYPAGE = 57 + CANVAS = 58 + CAPTION = 59 + CHECKMENUITEM = 60 + DATEEDITOR = 61 + ICON = 62 + DIRECTORYPANE = 63 + EMBEDDEDOBJECT = 64 + ENDNOTE = 65 + FOOTER = 66 + FOOTNOTE = 67 + GLASSPANE = 69 + HEADER = 70 + IMAGEMAP = 71 + INPUTWINDOW = 72 + LABEL = 73 + NOTE = 74 + PAGE = 75 + RADIOMENUITEM = 76 + LAYEREDPANE = 77 + REDUNDANTOBJECT = 78 + ROOTPANE = 79 + EDITBAR = 80 + TERMINAL = 82 + RICHEDIT = 83 + RULER = 84 + SCROLLPANE = 85 + SECTION = 86 + SHAPE = 87 + SPLITPANE = 88 + VIEWPORT = 89 + TEAROFFMENU = 90 + TEXTFRAME = 91 + TOGGLEBUTTON = 92 + BORDER = 93 + CARET = 94 + CHARACTER = 95 + CHART = 96 + CURSOR = 97 + DIAGRAM = 98 + DIAL = 99 + DROPLIST = 100 + SPLITBUTTON = 101 + MENUBUTTON = 102 + DROPDOWNBUTTONGRID = 103 + MATH = 104 + GRIP = 105 + HOTKEYFIELD = 106 + INDICATOR = 107 + SPINBUTTON = 108 + SOUND = 109 + WHITESPACE = 110 + TREEVIEWBUTTON = 111 + IPADDRESS = 112 + DESKTOPICON = 113 + INTERNALFRAME = 115 + DESKTOPPANE = 116 + OPTIONPANE = 117 + COLORCHOOSER = 118 + FILECHOOSER = 119 + FILLER = 120 + MENU = 121 + PANEL = 122 + PASSWORDEDIT = 123 + FONTCHOOSER = 124 + LINE = 125 + FONTNAME = 126 + FONTSIZE = 127 + BOLD = 128 + ITALIC = 129 + UNDERLINE = 130 + FGCOLOR = 131 + BGCOLOR = 132 + SUPERSCRIPT = 133 + SUBSCRIPT = 134 + STYLE = 135 + INDENT = 136 + ALIGNMENT = 137 + ALERT = 138 + DATAGRID = 139 + DATAITEM = 140 + HEADERITEM = 141 + THUMB = 142 + CALENDAR = 143 + VIDEO = 144 + AUDIO = 145 + CHARTELEMENT = 146 + DELETED_CONTENT = 147 + INSERTED_CONTENT = 148 + LANDMARK = 149 + ARTICLE = 150 + REGION = 151 + FIGURE = 152 + MARKED_CONTENT = 153 + + +_roleLabels: Dict[Role, str] = { # Translators: The word for an unknown control type. - ROLE_UNKNOWN:_("unknown"), + Role.UNKNOWN: _("unknown"), # Translators: The word for window of a program such as document window. - ROLE_WINDOW:_("window"), + Role.WINDOW: _("window"), # Translators: Used to identify title bar of a program. - ROLE_TITLEBAR:_("title bar"), + Role.TITLEBAR: _("title bar"), # Translators: The word used for pane such as desktop pane. - ROLE_PANE:_("pane"), + Role.PANE: _("pane"), # Translators: The word used to denote a dialog box such as open dialog. - ROLE_DIALOG:_("dialog"), + Role.DIALOG: _("dialog"), # Translators: The text used to identify check boxes such as select check box. - ROLE_CHECKBOX:_("check box"), + Role.CHECKBOX: _("check box"), # Translators: The text used to identify radio buttons such as yes or no radio button. - ROLE_RADIOBUTTON:_("radio button"), + Role.RADIOBUTTON: _("radio button"), # Translators: The word used to identify a static text such as dialog text. - ROLE_STATICTEXT:_("text"), + Role.STATICTEXT: _("text"), # Translators: The word used to identify edit fields such as subject edit field. - ROLE_EDITABLETEXT:_("edit"), + Role.EDITABLETEXT: _("edit"), # Translators: The word used to identify a button such as OK button. - ROLE_BUTTON:_("button"), + Role.BUTTON: _("button"), # Translators: Text used to identify menu bar of a program. - ROLE_MENUBAR:_("menu bar"), + Role.MENUBAR: _("menu bar"), # Translators: Used to identify a menu item such as an item in file menu. - ROLE_MENUITEM:_("menu item"), + Role.MENUITEM: _("menu item"), # Translators: The word used for menus such as edit menu. - ROLE_POPUPMENU:_("menu"), + Role.POPUPMENU: _("menu"), # Translators: Used to identify combo boxes such as file type combo box. - ROLE_COMBOBOX:_("combo box"), + Role.COMBOBOX: _("combo box"), # Translators: The word used for lists such as folder list. - ROLE_LIST:_("list"), + Role.LIST: _("list"), # Translators: Used to identify a list item such as email list items. - ROLE_LISTITEM:_("list item"), + Role.LISTITEM: _("list item"), # Translators: The word used to identify graphics such as webpage graphics. - ROLE_GRAPHIC:_("graphic"), - # Translators: Used to identify help balloon (a circular window with helpful text such as notification text). - ROLE_HELPBALLOON:_("help balloon"), - # Translators: Used to identify a tooltip (a small window with additional text about selected item such as file information). - ROLE_TOOLTIP:_("tool tip"), + Role.GRAPHIC: _("graphic"), + # Translators: Used to identify help balloon (a circular window with helpful text such as notification + # text). + Role.HELPBALLOON: _("help balloon"), + # Translators: Used to identify a tooltip (a small window with additional text about selected item such as + # file information). + Role.TOOLTIP: _("tool tip"), # Translators: Identifies a link in webpage documents. - ROLE_LINK:_("link"), + Role.LINK: _("link"), # Translators: Identifies a treeview (a tree-like structure such as treeviews for subfolders). - ROLE_TREEVIEW:_("tree view"), + Role.TREEVIEW: _("tree view"), # Translators: Identifies a tree view item. - ROLE_TREEVIEWITEM:_("tree view item"), + Role.TREEVIEWITEM: _("tree view item"), # Translators: The word presented for tabs in a tab enabled window. - ROLE_TAB: pgettext("controlType", "tab"), + Role.TAB: pgettext("controlType", "tab"), # Translators: Identifies a tab control such as webpage tabs in web browsers. - ROLE_TABCONTROL:_("tab control"), + Role.TABCONTROL: _("tab control"), # Translators: Identifies a slider such as volume slider. - ROLE_SLIDER:_("slider"), + Role.SLIDER: _("slider"), # Translators: Identifies a progress bar such as NvDA update progress. - ROLE_PROGRESSBAR:_("progress bar"), + Role.PROGRESSBAR: _("progress bar"), # Translators: Identifies a scroll bar. - ROLE_SCROLLBAR:_("scroll bar"), - # Translators: Identifies a status bar (text at the bottom bar of the screen such as cursor position in a document). - ROLE_STATUSBAR:_("status bar"), + Role.SCROLLBAR: _("scroll bar"), + # Translators: Identifies a status bar (text at the bottom bar of the screen such as cursor position in a + # document). + Role.STATUSBAR: _("status bar"), # Translators: Identifies a table such as ones used in various websites. - ROLE_TABLE:_("table"), + Role.TABLE: _("table"), # Translators: Identifies a cell in a table. - ROLE_TABLECELL:_("cell"), + Role.TABLECELL: _("cell"), # Translators: Identifies a column (a group of vertical cells in a table). - ROLE_TABLECOLUMN:_("column"), + Role.TABLECOLUMN: _("column"), # Translators: Identifies a row (a group of horizontal cells in a table). - ROLE_TABLEROW:_("row"), + Role.TABLEROW: _("row"), # Translators: Identifies a frame (a smaller window in a webpage or a document). - ROLE_FRAME:_("frame"), + Role.FRAME: _("frame"), # Translators: Identifies a tool bar. - ROLE_TOOLBAR:_("tool bar"), + Role.TOOLBAR: _("tool bar"), # Translators: Identifies a column header in tables and spreadsheets. - ROLE_TABLECOLUMNHEADER:_("column header"), + Role.TABLECOLUMNHEADER: _("column header"), # Translators: Identifies a row header in tables and spreadsheets. - ROLE_TABLEROWHEADER:_("row header"), + Role.TABLEROWHEADER: _("row header"), # Translators: Identifies a drop down button (a button that, when clicked, opens a menu of its own). - ROLE_DROPDOWNBUTTON:_("drop down button"), + Role.DROPDOWNBUTTON: _("drop down button"), # Translators: Identifies an element. - ROLE_CLOCK:_("clock"), + Role.CLOCK: _("clock"), # Translators: Identifies a separator (a horizontal line drawn on the screen). - ROLE_SEPARATOR:_("separator"), + Role.SEPARATOR: _("separator"), # Translators: Identifies a form (controls such as edit boxes, combo boxes and so on). - ROLE_FORM:_("form"), + Role.FORM: _("form"), # Translators: Identifies a heading (a bold text used for identifying a section). - ROLE_HEADING:_("heading"), + Role.HEADING: _("heading"), # Translators: Identifies a heading level. - ROLE_HEADING1:_("heading 1"), + Role.HEADING1: _("heading 1"), # Translators: Identifies a heading level. - ROLE_HEADING2:_("heading 2"), + Role.HEADING2: _("heading 2"), # Translators: Identifies a heading level. - ROLE_HEADING3:_("heading 3"), + Role.HEADING3: _("heading 3"), # Translators: Identifies a heading level. - ROLE_HEADING4:_("heading 4"), + Role.HEADING4: _("heading 4"), # Translators: Identifies a heading level. - ROLE_HEADING5:_("heading 5"), + Role.HEADING5: _("heading 5"), # Translators: Identifies a heading level. - ROLE_HEADING6:_("heading 6"), + Role.HEADING6: _("heading 6"), # Translators: Identifies a paragraph (a group of text surrounded by blank lines). - ROLE_PARAGRAPH:_("paragraph"), + Role.PARAGRAPH: _("paragraph"), # Translators: Presented for a section in a document which is a block quotation; # i.e. a long quotation in a separate paragraph distinguished by indentation, etc. # See http://en.wikipedia.org/wiki/Block_quotation - ROLE_BLOCKQUOTE:_("block quote"), - # Translators: Identifies a table header (a short text at the start of a table which describes what the table is about). - ROLE_TABLEHEADER:_("table header"), + Role.BLOCKQUOTE: _("block quote"), + # Translators: Identifies a table header (a short text at the start of a table which describes what the + # table is about). + Role.TABLEHEADER: _("table header"), # Translators: Identifies a table body (the main body of the table). - ROLE_TABLEBODY:_("table body"), + Role.TABLEBODY: _("table body"), # Translators: Identifies a table footer (text placed at the end of the table). - ROLE_TABLEFOOTER:_("table footer"), + Role.TABLEFOOTER: _("table footer"), # Translators: Identifies a document (for example, a webpage document). - ROLE_DOCUMENT:_("document"), + Role.DOCUMENT: _("document"), # Translators: Identifies an animation in a document or a webpage. - ROLE_ANIMATION:_("animation"), + Role.ANIMATION: _("animation"), # Translators: Identifies an application in webpages. - ROLE_APPLICATION:_("application"), + Role.APPLICATION: _("application"), # Translators: Identifies a box element. - ROLE_BOX:_("box"), - # Translators: Identifies a grouping (a number of related items grouped together, such as related options in dialogs). - ROLE_GROUPING:_("grouping"), + Role.BOX: _("box"), + # Translators: Identifies a grouping (a number of related items grouped together, such as related options + # in dialogs). + Role.GROUPING: _("grouping"), # Translators: Identifies a property page such as drive properties dialog. - ROLE_PROPERTYPAGE:_("property page"), - # Translators: Identifies a canvas element on webpages (a box with some background color with some text drawn on the box, like a canvas). - ROLE_CANVAS:_("canvas"), + Role.PROPERTYPAGE: _("property page"), + # Translators: Identifies a canvas element on webpages (a box with some background color with some text + # drawn on the box, like a canvas). + Role.CANVAS: _("canvas"), # Translators: Identifies a caption (usually a short text identifying a picture or a graphic on websites). - ROLE_CAPTION:_("caption"), - # Translators: Identifies a check menu item (a menu item with a checkmark as part of the menu item's name). - ROLE_CHECKMENUITEM:_("check menu item"), + Role.CAPTION: _("caption"), + # Translators: Identifies a check menu item (a menu item with a checkmark as part of the menu item's + # name). + Role.CHECKMENUITEM: _("check menu item"), # Translators: Identifies a data edit field. - ROLE_DATEEDITOR:_("date edit"), + Role.DATEEDITOR: _("date edit"), # Translators: Identifies an icon. - ROLE_ICON:_("icon"), + Role.ICON: _("icon"), # Translators: Identifies a directory pane. - ROLE_DIRECTORYPANE:_("directory pane"), + Role.DIRECTORYPANE: _("directory pane"), # Translators: Identifies an object that is embedded in a document. - ROLE_EMBEDDEDOBJECT:_("embedded object"), + Role.EMBEDDEDOBJECT: _("embedded object"), # Translators: Identifies an end note. - ROLE_ENDNOTE:_("end note"), + Role.ENDNOTE: _("end note"), # Translators: Identifies a footer (usually text). - ROLE_FOOTER:_("footer"), + Role.FOOTER: _("footer"), # Translators: Identifies a foot note (text at the end of a passage or used for anotations). - ROLE_FOOTNOTE:_("foot note"), + Role.FOOTNOTE: _("foot note"), # Translators: Reported for an object which is a glass pane; i.e. # a pane that is guaranteed to be on top of all panes beneath it. - ROLE_GLASSPANE:_("glass pane"), + Role.GLASSPANE: _("glass pane"), # Translators: Identifies a header (usually text at top of documents or on tops of pages). - ROLE_HEADER:_("header"), + Role.HEADER: _("header"), # Translators: Identifies an image map (a type of graphical link). - ROLE_IMAGEMAP:_("image map"), + Role.IMAGEMAP: _("image map"), # Translators: Identifies an input window. - ROLE_INPUTWINDOW:_("input window"), + Role.INPUTWINDOW: _("input window"), # Translators: Identifies a label. - ROLE_LABEL:_("label"), + Role.LABEL: _("label"), # Translators: Identifies a note field. - ROLE_NOTE:_("note"), + Role.NOTE: _("note"), # Translators: Identifies a page. - ROLE_PAGE:_("page"), + Role.PAGE: _("page"), # Translators: Identifies a radio menu item. - ROLE_RADIOMENUITEM:_("radio menu item"), + Role.RADIOMENUITEM: _("radio menu item"), # Translators: Identifies a layered pane. - ROLE_LAYEREDPANE:_("layered pane"), + Role.LAYEREDPANE: _("layered pane"), # Translators: Identifies a redundant object. - ROLE_REDUNDANTOBJECT:_("redundant object"), + Role.REDUNDANTOBJECT: _("redundant object"), # Translators: Identifies a root pane. - ROLE_ROOTPANE:_("root pane"), + Role.ROOTPANE: _("root pane"), # Translators: May be reported for an editable text object in a toolbar. # This is deprecated and is not often (if ever) used. - ROLE_EDITBAR:_("edit bar"), + Role.EDITBAR: _("edit bar"), # Translators: Identifies a terminal window such as command prompt. - ROLE_TERMINAL:_("terminal"), - # Translators: Identifies a rich edit box (an edit box which allows entering formatting commands in addition to text; encountered on webpages and NvDA log viewer). - ROLE_RICHEDIT:_("rich edit"), + Role.TERMINAL: _("terminal"), + # Translators: Identifies a rich edit box (an edit box which allows entering formatting commands in + # addition to text; encountered on webpages and NvDA log viewer). + Role.RICHEDIT: _("rich edit"), # Translators: Identifies a ruler object (commonly seen on some webpages and in some Office programs). - ROLE_RULER:_("ruler"), + Role.RULER: _("ruler"), # Translators: Identifies a scroll pane. - ROLE_SCROLLPANE:_("scroll pane"), + Role.SCROLLPANE: _("scroll pane"), # Translators: Identifies a section of text. - ROLE_SECTION:_("section"), + Role.SECTION: _("section"), # Translators: Identifies a shape. - ROLE_SHAPE:_("shape"), + Role.SHAPE: _("shape"), # Translators: Identifies a split pane. - ROLE_SPLITPANE:_("split pane"), + Role.SPLITPANE: _("split pane"), # Translators: Reported for a view port; i.e. an object usually used in a scroll pane # which represents the portion of the entire data that the user can see. # As the user manipulates the scroll bars, the contents of the view port can change. - ROLE_VIEWPORT:_("view port"), + Role.VIEWPORT: _("view port"), # Translators: Reported for an object that forms part of a menu system # but which can be undocked from or torn off the menu system # to exist as a separate window. - ROLE_TEAROFFMENU:_("tear off menu"), + Role.TEAROFFMENU: _("tear off menu"), # Translators: Identifies a text frame (a frame window which contains text). - ROLE_TEXTFRAME:_("text frame"), + Role.TEXTFRAME: _("text frame"), # Translators: Identifies a toggle button (a button used to toggle something). - ROLE_TOGGLEBUTTON:_("toggle button"), - ROLE_BORDER:_("border"), + Role.TOGGLEBUTTON: _("toggle button"), + Role.BORDER: _("border"), # Translators: Identifies a caret object. - ROLE_CARET:_("caret"), + Role.CARET: _("caret"), # Translators: Identifies a character field (should not be confused with edit fields). - ROLE_CHARACTER:_("character"), + Role.CHARACTER: _("character"), # Translators: Identifies a chart (commonly seen on some websites and in some Office documents). - ROLE_CHART:_("chart"), + Role.CHART: _("chart"), # Translators: Identifies a cursor object. - ROLE_CURSOR:_("cursor"), + Role.CURSOR: _("cursor"), # Translators: Identifies a diagram (seen on some websites and on Office documents). - ROLE_DIAGRAM:_("diagram"), + Role.DIAGRAM: _("diagram"), # Translators: Identifies a dial object. - ROLE_DIAL:_("dial"), + Role.DIAL: _("dial"), # Translators: Identifies a drop list. - ROLE_DROPLIST:_("drop list"), - # Translators: Identifies a split button (a control which performs different actions when different parts are clicked). - ROLE_SPLITBUTTON:_("split button"), + Role.DROPLIST: _("drop list"), + # Translators: Identifies a split button (a control which performs different actions when different parts + # are clicked). + Role.SPLITBUTTON: _("split button"), # Translators: Identifies a menu button (a button which opens a menu of items). - ROLE_MENUBUTTON:_("menu button"), + Role.MENUBUTTON: _("menu button"), # Translators: Reported for a button which expands a grid when it is pressed. - ROLE_DROPDOWNBUTTONGRID:_("drop down button grid"), + Role.DROPDOWNBUTTONGRID: _("drop down button grid"), # Translators: Identifies mathematical content. - ROLE_MATH:_("math"), + Role.MATH: _("math"), # Translators: Identifies a grip control. - ROLE_GRIP:_("grip"), - # Translators: Identifies a hot key field (a field where one can enter a hot key for something, such as assigning shortcut for icons on the desktop). - ROLE_HOTKEYFIELD:_("hot key field"), + Role.GRIP: _("grip"), + # Translators: Identifies a hot key field (a field where one can enter a hot key for something, such as + # assigning shortcut for icons on the desktop). + Role.HOTKEYFIELD: _("hot key field"), # Translators: Identifies an indicator control. - ROLE_INDICATOR:_("indicator"), + Role.INDICATOR: _("indicator"), # Translators: Identifies a spin button (a button used to go through options in a spinning fashion). - ROLE_SPINBUTTON:_("spin button"), + Role.SPINBUTTON: _("spin button"), # Translators: Identifies a sound clip on websites. - ROLE_SOUND:_("sound"), + Role.SOUND: _("sound"), # Translators: Identifies a whitespace. - ROLE_WHITESPACE:_("white space"), + Role.WHITESPACE: _("white space"), # Translators: Identifies a tree view button. - ROLE_TREEVIEWBUTTON:_("tree view button"), + Role.TREEVIEWBUTTON: _("tree view button"), # Translators: Identifies an IP address (an IP address field element). - ROLE_IPADDRESS:_("IP address"), - # Translators: Identifies a desktop icon (the icons on the desktop such as computer and various shortcuts for programs). - ROLE_DESKTOPICON:_("desktop icon"), - # Translators: Identifies an internal frame. This is usually a frame on a web page; i.e. a web page embedded within a web page. - ROLE_INTERNALFRAME:_("frame"), + Role.IPADDRESS: _("IP address"), + # Translators: Identifies a desktop icon (the icons on the desktop such as computer and various shortcuts + # for programs). + Role.DESKTOPICON: _("desktop icon"), + # Translators: Identifies an internal frame. This is usually a frame on a web page; i.e. a web page + # embedded within a web page. + Role.INTERNALFRAME: _("frame"), # Translators: Identifies desktop pane (the desktop window). - ROLE_DESKTOPPANE:_("desktop pane"), + Role.DESKTOPPANE: _("desktop pane"), # Translators: Identifies an option pane. - ROLE_OPTIONPANE:_("option pane"), + Role.OPTIONPANE: _("option pane"), # Translators: Identifies a color chooser. - ROLE_COLORCHOOSER:_("color chooser"), + Role.COLORCHOOSER: _("color chooser"), # Translators: Identifies a file chooser (to select a file or groups of files from a list). - ROLE_FILECHOOSER:_("file chooser"), - ROLE_FILLER:_("filler"), + Role.FILECHOOSER: _("file chooser"), + Role.FILLER: _("filler"), # Translators: Identifies a menu such as file menu. - ROLE_MENU:_("menu"), + Role.MENU: _("menu"), # Translators: Identifies a panel control for grouping related options. - ROLE_PANEL:_("panel"), - # Translators: Identifies a password field (a protected edit field for entering passwords such as when logging into web-based email sites). - ROLE_PASSWORDEDIT:_("password edit"), + Role.PANEL: _("panel"), + # Translators: Identifies a password field (a protected edit field for entering passwords such as when + # logging into web-based email sites). + Role.PASSWORDEDIT: _("password edit"), # Translators: Identifies a font chooser. - ROLE_FONTCHOOSER:_("font chooser"), - ROLE_LINE:_("line"), + Role.FONTCHOOSER: _("font chooser"), + Role.LINE: _("line"), # Translators: Identifies a font name. - ROLE_FONTNAME:_("font name"), + Role.FONTNAME: _("font name"), # Translators: Identifies font size. - ROLE_FONTSIZE:_("font size"), + Role.FONTSIZE: _("font size"), # Translators: Describes text formatting. - ROLE_BOLD:_("bold"), + Role.BOLD: _("bold"), # Translators: Describes text formatting. - ROLE_ITALIC:_("italic"), + Role.ITALIC: _("italic"), # Translators: Describes text formatting. - ROLE_UNDERLINE:_("underline"), + Role.UNDERLINE: _("underline"), # Translators: Describes text formatting. - ROLE_FGCOLOR:_("foreground color"), + Role.FGCOLOR: _("foreground color"), # Translators: Describes text formatting. - ROLE_BGCOLOR:_("background color"), + Role.BGCOLOR: _("background color"), # Translators: Describes text formatting. - ROLE_SUPERSCRIPT:_("superscript"), + Role.SUPERSCRIPT: _("superscript"), # Translators: Describes text formatting. - ROLE_SUBSCRIPT:_("subscript"), + Role.SUBSCRIPT: _("subscript"), # Translators: Describes style of text. - ROLE_STYLE:_("style"), + Role.STYLE: _("style"), # Translators: Describes text formatting. - ROLE_INDENT:_("indent"), + Role.INDENT: _("indent"), # Translators: Describes text formatting. - ROLE_ALIGNMENT:_("alignment"), - # Translators: Identifies an alert window or bar (usually on Internet Explorer 9 and above for alerts such as file downloads or pop-up blocker). - ROLE_ALERT:_("alert"), + Role.ALIGNMENT: _("alignment"), + # Translators: Identifies an alert window or bar (usually on Internet Explorer 9 and above for alerts such + # as file downloads or pop-up blocker). + Role.ALERT: _("alert"), # Translators: Identifies a data grid control (a grid which displays data). - ROLE_DATAGRID:_("data grid"), - ROLE_DATAITEM:_("data item"), - ROLE_HEADERITEM:_("header item"), + Role.DATAGRID: _("data grid"), + Role.DATAITEM: _("data item"), + Role.HEADERITEM: _("header item"), # Translators: Identifies a thumb control (a button-like control for changing options). - ROLE_THUMB:_("thumb control"), - ROLE_CALENDAR:_("calendar"), - ROLE_VIDEO:_("video"), - ROLE_AUDIO:_("audio"), + Role.THUMB: _("thumb control"), + Role.CALENDAR: _("calendar"), + Role.VIDEO: _("video"), + Role.AUDIO: _("audio"), # Translators: Identifies a chart element. - ROLE_CHARTELEMENT:_("chart element"), - # Translators: Identifies deleted content. - ROLE_DELETED_CONTENT:_("deleted"), - # Translators: Identifies inserted content. - ROLE_INSERTED_CONTENT:_("inserted"), + Role.CHARTELEMENT: _("chart element"), + # Translators: Identifies deleted content. + Role.DELETED_CONTENT: _("deleted"), + # Translators: Identifies inserted content. + Role.INSERTED_CONTENT: _("inserted"), # Translators: Identifies a landmark. - ROLE_LANDMARK: _("landmark"), + Role.LANDMARK: _("landmark"), # Translators: Identifies an article. - ROLE_ARTICLE: _("article"), + Role.ARTICLE: _("article"), # Translators: Identifies a region. - ROLE_REGION: _("region"), + Role.REGION: _("region"), # Translators: Identifies a figure (commonly seen on some websites). - ROLE_FIGURE: _("figure"), + Role.FIGURE: _("figure"), # Translators: Identifies marked (highlighted) content - ROLE_MARKED_CONTENT: _("marked content"), + Role.MARKED_CONTENT: _("marked content"), +} + + +silentRolesOnFocus: Set[Role] = { + Role.PANE, + Role.ROOTPANE, + Role.FRAME, + Role.UNKNOWN, + Role.APPLICATION, + Role.TABLECELL, + Role.LISTITEM, + Role.MENUITEM, + Role.CHECKMENUITEM, + Role.TREEVIEWITEM, + Role.STATICTEXT, + Role.BORDER, } -silentRolesOnFocus={ - ROLE_PANE, - ROLE_ROOTPANE, - ROLE_FRAME, - ROLE_UNKNOWN, - ROLE_APPLICATION, - ROLE_TABLECELL, - ROLE_LISTITEM, - ROLE_MENUITEM, - ROLE_CHECKMENUITEM, - ROLE_TREEVIEWITEM, - ROLE_STATICTEXT, - ROLE_BORDER, +silentValuesForRoles: Set[Role] = { + Role.CHECKBOX, + Role.RADIOBUTTON, + Role.LINK, + Role.MENUITEM, + Role.APPLICATION, } -silentValuesForRoles={ - ROLE_CHECKBOX, - ROLE_RADIOBUTTON, - ROLE_LINK, - ROLE_MENUITEM, - ROLE_APPLICATION, +clickableRoles: Set[Role] = { + Role.LINK, + Role.BUTTON, + Role.CHECKBOX, + Role.RADIOBUTTON, + Role.TOGGLEBUTTON, + Role.MENUITEM, + Role.TAB, + Role.SLIDER, + Role.DOCUMENT, + Role.CHECKMENUITEM, + Role.RADIOMENUITEM, } diff --git a/source/controlTypes/state.py b/source/controlTypes/state.py index 763a1b66d64..e062a535679 100644 --- a/source/controlTypes/state.py +++ b/source/controlTypes/state.py @@ -5,143 +5,172 @@ from typing import Dict +from utils.displayString import DisplayStringIntEnum -STATE_UNAVAILABLE=0X1 -STATE_FOCUSED=0X2 -STATE_SELECTED=0X4 -STATE_BUSY=0X8 -STATE_PRESSED=0X10 -STATE_CHECKED=0X20 -STATE_HALFCHECKED=0X40 -STATE_READONLY=0X80 -STATE_EXPANDED=0X100 -STATE_COLLAPSED=0X200 -STATE_INVISIBLE=0X400 -STATE_VISITED=0X800 -STATE_LINKED=0X1000 -STATE_HASPOPUP=0X2000 -STATE_PROTECTED=0X4000 -STATE_REQUIRED=0X8000 -STATE_DEFUNCT=0X10000 -STATE_INVALID_ENTRY=0X20000 -STATE_MODAL=0X40000 -STATE_AUTOCOMPLETE=0x80000 -STATE_MULTILINE=0X100000 -STATE_ICONIFIED=0x200000 -STATE_OFFSCREEN=0x400000 -STATE_SELECTABLE=0x800000 -STATE_FOCUSABLE=0x1000000 -STATE_CLICKABLE=0x2000000 -STATE_EDITABLE=0x4000000 -STATE_CHECKABLE=0x8000000 -STATE_DRAGGABLE=0x10000000 -STATE_DRAGGING=0x20000000 -STATE_DROPTARGET=0x40000000 -STATE_SORTED=0x80000000 -STATE_SORTED_ASCENDING=0x100000000 -STATE_SORTED_DESCENDING=0x200000000 -STATES_SORTED=frozenset([STATE_SORTED,STATE_SORTED_ASCENDING,STATE_SORTED_DESCENDING]) -STATE_HASLONGDESC=0x400000000 -STATE_PINNED=0x800000000 -STATE_HASFORMULA=0x1000000000 #Mostly for spreadsheets -STATE_HASCOMMENT=0X2000000000 -STATE_OBSCURED=0x4000000000 -STATE_CROPPED=0x8000000000 -STATE_OVERFLOWING=0x10000000000 -STATE_UNLOCKED=0x20000000000 -STATE_HAS_ARIA_DETAILS = 0x40000000000 +class State(DisplayStringIntEnum): + @property + def _displayStringLabels(self): + return _stateLabels -stateLabels: Dict[int, str] = { + @property + def negativeDisplayString(self) -> str: + """ + @return: The translated UI display string that should be used for when referring to this value of + the enum in the negative. + """ + try: + return _negativeStateLabels[self] + except KeyError: + # Translators: Indicates that a particular state of an object is negated. + # Separate strings have now been defined for commonly negated states (e.g. not selected and not + # checked), but this still might be used in some other cases. + # %s will be replaced with the full identifier of the negated state (e.g. selected). + return _("not %s") % self.displayString + + UNAVAILABLE = 0x1 + FOCUSED = 0x2 + SELECTED = 0x4 + BUSY = 0x8 + PRESSED = 0x10 + CHECKED = 0x20 + HALFCHECKED = 0x40 + READONLY = 0x80 + EXPANDED = 0x100 + COLLAPSED = 0x200 + INVISIBLE = 0x400 + VISITED = 0x800 + LINKED = 0x1000 + HASPOPUP = 0x2000 + PROTECTED = 0x4000 + REQUIRED = 0x8000 + DEFUNCT = 0x10000 + INVALID_ENTRY = 0x20000 + MODAL = 0x40000 + AUTOCOMPLETE = 0x80000 + MULTILINE = 0x100000 + ICONIFIED = 0x200000 + OFFSCREEN = 0x400000 + SELECTABLE = 0x800000 + FOCUSABLE = 0x1000000 + CLICKABLE = 0x2000000 + EDITABLE = 0x4000000 + CHECKABLE = 0x8000000 + DRAGGABLE = 0x10000000 + DRAGGING = 0x20000000 + DROPTARGET = 0x40000000 + SORTED = 0x80000000 + SORTED_ASCENDING = 0x100000000 + SORTED_DESCENDING = 0x200000000 + HASLONGDESC = 0x400000000 + PINNED = 0x800000000 + HASFORMULA = 0x1000000000 # Mostly for spreadsheets + HASCOMMENT = 0x2000000000 + OBSCURED = 0x4000000000 + CROPPED = 0x8000000000 + OVERFLOWING = 0x10000000000 + UNLOCKED = 0x20000000000 + HAS_ARIA_DETAILS = 0x40000000000 + + +STATES_SORTED = frozenset([State.SORTED, State.SORTED_ASCENDING, State.SORTED_DESCENDING]) + + +_stateLabels: Dict[State, str] = { # Translators: This is presented when a control or document is unavailable. - STATE_UNAVAILABLE:_("unavailable"), + State.UNAVAILABLE: _("unavailable"), # Translators: This is presented when a control has focus. - STATE_FOCUSED:_("focused"), + State.FOCUSED: _("focused"), # Translators: This is presented when the control is selected. - STATE_SELECTED:_("selected"), + State.SELECTED: _("selected"), # Translators: This is presented when a document is busy. - STATE_BUSY:_("busy"), + State.BUSY: _("busy"), # Translators: This is presented when a button is pressed. - STATE_PRESSED:_("pressed"), + State.PRESSED: _("pressed"), # Translators: This is presented when a check box is checked. - STATE_CHECKED:_("checked"), + State.CHECKED: _("checked"), # Translators: This is presented when a three state check box is half checked. - STATE_HALFCHECKED:_("half checked"), + State.HALFCHECKED: _("half checked"), # Translators: This is presented when the control is a read-only control such as read-only edit box. - STATE_READONLY:_("read only"), + State.READONLY: _("read only"), # Translators: This is presented when a tree view or submenu item is expanded. - STATE_EXPANDED:_("expanded"), + State.EXPANDED: _("expanded"), # Translators: This is presented when a tree view or submenu is collapsed. - STATE_COLLAPSED:_("collapsed"), + State.COLLAPSED: _("collapsed"), # Translators: This is presented when a control or a document becomes invisible. - STATE_INVISIBLE:_("invisible"), + State.INVISIBLE: _("invisible"), # Translators: This is presented when a visited link is encountered. - STATE_VISITED:_("visited"), + State.VISITED: _("visited"), # Translators: This is presented when a link is encountered. - STATE_LINKED:_("linked"), + State.LINKED: _("linked"), # Translators: This is presented when the control menu item has a submenu. - STATE_HASPOPUP:_("subMenu"), + State.HASPOPUP: _("subMenu"), # Translators: This is presented when a protected control or a document is encountered. - STATE_PROTECTED:_("protected"), + State.PROTECTED: _("protected"), # Translators: This is presented when a required form field is encountered. - STATE_REQUIRED:_("required"), + State.REQUIRED: _("required"), # Translators: Reported when an object no longer exists in the user interface; # i.e. it is dead and is no longer usable. - STATE_DEFUNCT:_("defunct"), + State.DEFUNCT: _("defunct"), # Translators: This is presented when an invalid entry has been made. - STATE_INVALID_ENTRY:_("invalid entry"), - STATE_MODAL:_("modal"), - # Translators: This is presented when a field supports auto completion of entered text such as email address field in Microsoft Outlook. - STATE_AUTOCOMPLETE:_("has auto complete"), - # Translators: This is presented when an edit field allows typing multiple lines of text such as comment fields on websites. - STATE_MULTILINE:_("multi line"), - STATE_ICONIFIED:_("iconified"), + State.INVALID_ENTRY: _("invalid entry"), + State.MODAL: _("modal"), + # Translators: This is presented when a field supports auto completion of entered text such as email + # address field in Microsoft Outlook. + State.AUTOCOMPLETE: _("has auto complete"), + # Translators: This is presented when an edit field allows typing multiple lines of text such as comment + # fields on websites. + State.MULTILINE: _("multi line"), + State.ICONIFIED: _("iconified"), # Translators: Presented when the current control is located off screen. - STATE_OFFSCREEN:_("off screen"), + State.OFFSCREEN: _("off screen"), # Translators: Presented when the control allows selection such as text fields. - STATE_SELECTABLE:_("selectable"), + State.SELECTABLE: _("selectable"), # Translators: Presented when a control can be moved to using system focus. - STATE_FOCUSABLE:_("focusable"), + State.FOCUSABLE: _("focusable"), # Translators: Presented when a control allows clicking via mouse (mostly presented on web controls). - STATE_CLICKABLE:_("clickable"), - STATE_EDITABLE:_("editable"), - STATE_CHECKABLE:_("checkable"), - STATE_DRAGGABLE:_("draggable"), - STATE_DRAGGING:_("dragging"), + State.CLICKABLE: _("clickable"), + State.EDITABLE: _("editable"), + State.CHECKABLE: _("checkable"), + State.DRAGGABLE: _("draggable"), + State.DRAGGING: _("dragging"), # Translators: Reported where an object which is being dragged can be dropped. # This is only reported for objects that support accessible drag and drop. - STATE_DROPTARGET:_("drop target"), - STATE_SORTED:_("sorted"), - STATE_SORTED_ASCENDING:_("sorted ascending"), - STATE_SORTED_DESCENDING:_("sorted descending"), + State.DROPTARGET: _("drop target"), + State.SORTED: _("sorted"), + State.SORTED_ASCENDING: _("sorted ascending"), + State.SORTED_DESCENDING: _("sorted descending"), # Translators: a state that denotes that an object (usually a graphic) has a long description. - STATE_HASLONGDESC:_("has long description"), + State.HASLONGDESC: _("has long description"), # Translators: a state that denotes that an object has additional details (such as a comment section). - STATE_HAS_ARIA_DETAILS: _("has details"), + State.HAS_ARIA_DETAILS: _("has details"), # Translators: a state that denotes that an object is pinned in its current location - STATE_PINNED:_("pinned"), + State.PINNED: _("pinned"), # Translators: a state that denotes the existance of a formula on a spreadsheet cell - STATE_HASFORMULA:_("has formula"), + State.HASFORMULA: _("has formula"), # Translators: a state that denotes the existance of a comment. - STATE_HASCOMMENT:_("has comment"), + State.HASCOMMENT: _("has comment"), # Translators: a state that denotes that the object is covered partially or fully by another object - STATE_OBSCURED:_("obscured"), - # Translators: a state that denotes that the object(text) is cropped as it couldn't be accommodated in the allocated/available space - STATE_CROPPED:_("cropped"), + State.OBSCURED: _("obscured"), + # Translators: a state that denotes that the object(text) is cropped as it couldn't be accommodated in the + # allocated/available space + State.CROPPED: _("cropped"), # Translators: a state that denotes that the object(text) is overflowing into the adjacent space - STATE_OVERFLOWING:_("overflowing"), - # Translators: a state that denotes that the object is unlocked (such as an unlocked cell in a protected Excel spreadsheet). - STATE_UNLOCKED:_("unlocked"), + State.OVERFLOWING: _("overflowing"), + # Translators: a state that denotes that the object is unlocked (such as an unlocked cell in a protected + # Excel spreadsheet). + State.UNLOCKED: _("unlocked"), } -negativeStateLabels={ + +_negativeStateLabels: Dict[State, str] = { # Translators: This is presented when a selectable object (e.g. a list item) is not selected. - STATE_SELECTED:_("not selected"), + State.SELECTED: _("not selected"), # Translators: This is presented when a button is not pressed. - STATE_PRESSED:_("not pressed"), + State.PRESSED: _("not pressed"), # Translators: This is presented when a checkbox is not checked. - STATE_CHECKED:_("not checked"), + State.CHECKED: _("not checked"), # Translators: This is presented when drag and drop is finished. # This is only reported for objects which support accessible drag and drop. - STATE_DROPTARGET:_("done dragging"), + State.DROPTARGET: _("done dragging"), } diff --git a/source/utils/__init__.py b/source/utils/__init__.py new file mode 100644 index 00000000000..e69de29bb2d diff --git a/source/utils/displayString.py b/source/utils/displayString.py new file mode 100644 index 00000000000..5cae0488e4f --- /dev/null +++ b/source/utils/displayString.py @@ -0,0 +1,71 @@ +# A part of NonVisual Desktop Access (NVDA) +# This file is covered by the GNU General Public License. +# See the file COPYING for more details. +# Copyright (C) 2021 NV Access Limited. + +from abc import ABC, ABCMeta, abstractproperty +from enum import Enum, EnumMeta, IntEnum +from typing import Dict + +from logHandler import log + + +class _DisplayStringEnumMixinMeta(ABCMeta, EnumMeta): + """ + This helps correct the Method Resolution Order (MRO) when using the `_DisplayStringEnumMixin`. + When creating an Enum with a Mixin, Python suggest an ordering of + `class EnumWithMixin(Mixin, type, EnumClass):`. + This creates a metaclass conflict as both _DisplayStringEnumMixin and Enum both have metaclasses, + ABCMeta and EnumMeta. This requires a new MetaClass which subclasses both of these. This follows the + same ordering of the EnumWithMixin usage. + See `_DisplayStringEnumMixin`. + """ + pass + + +class _DisplayStringEnumMixin(ABC): + """ + This mixin can be used with a class which subclasses Enum to provided translated display strings for + members of the enum. The abstract properties must be overridden. + To be used with `_DisplayStringEnumMixinMeta`. + Usage for python 3.7 is as follows: + ``` + class ExampleEnum(_DisplayStringEnumMixin, str, Enum, metaclass=_DisplayStringEnumMixinMeta): + pass + + class ExampleIntEnum(_DisplayStringEnumMixin, IntEnum, metaclass=_DisplayStringEnumMixinMeta): + pass + ``` + """ + @abstractproperty + def _displayStringLabels(self) -> Dict[Enum, str]: + """ + Specify a dictionary which takes members of the Enum and returns the translated display string. + """ + pass + + @property + def displayString(self) -> str: + """ + @return: The translated UI display string that should be used for this value of the enum. + """ + try: + return self._displayStringLabels[self] + except KeyError as e: + log.error(f"No translation mapping for: {self}") + raise e + + +class DisplayStringEnum(_DisplayStringEnumMixin, Enum, metaclass=_DisplayStringEnumMixinMeta): + """An Enum class that adds a displayString property defined by _displayStringLabels""" + pass + + +class DisplayStringStrEnum(_DisplayStringEnumMixin, str, Enum, metaclass=_DisplayStringEnumMixinMeta): + """A str Enum class that adds a displayString property defined by _displayStringLabels""" + pass + + +class DisplayStringIntEnum(_DisplayStringEnumMixin, IntEnum, metaclass=_DisplayStringEnumMixinMeta): + """An IntEnum class that adds a displayString property defined by _displayStringLabels""" + pass diff --git a/user_docs/en/changes.t2t b/user_docs/en/changes.t2t index b795d150daa..ca8aff0ae83 100644 --- a/user_docs/en/changes.t2t +++ b/user_docs/en/changes.t2t @@ -32,6 +32,12 @@ What's New in NVDA == Changes for Developers == +- `controlTypes` has been split up into various submodules, symbols marked for deprecation must be replaced before 2022.1. (#12510) + - `ROLE_*` and `STATE_*` constants should be replaced to their equivalent `Role.*` and `State.*`. + - `roleLabels`, `stateLabels` and `negativeStateLabels` have been deprecated, usages such as `roleLabels[ROLE_*]` should be replaced to their equivalent `Role.*.displayString` or `State.*.negativeDisplayString`. + - `processPositiveStates` and `processNegativeStates` have been deprecated for removal. + - +- = 2021.1 =