Example #1
0
 def test_negativeMergedStatesOutput(self):
     obj = PlaceholderNVDAObject()
     obj.role = controlTypes.Role.CHECKBOX
     obj.states = {
         controlTypes.State.FOCUSABLE, controlTypes.State.FOCUSED,
         controlTypes.State.SELECTED, controlTypes.State.SELECTABLE
     }
     self.assertEqual(
         controlTypes.processAndLabelStates(obj.role, obj.states,
                                            controlTypes.OutputReason.FOCUS,
                                            obj.states, None),
         [controlTypes.State.CHECKED.negativeDisplayString])
Example #2
0
 def test_negativeMergedStatesOutput(self):
     obj = PlaceholderNVDAObject()
     obj.role = controlTypes.ROLE_CHECKBOX
     obj.states = {
         controlTypes.STATE_FOCUSABLE, controlTypes.STATE_FOCUSED,
         controlTypes.STATE_SELECTED, controlTypes.STATE_SELECTABLE
     }
     self.assertEqual(
         controlTypes.processAndLabelStates(obj.role, obj.states,
                                            controlTypes.REASON_FOCUS,
                                            obj.states, None),
         [controlTypes.negativeStateLabels[controlTypes.STATE_CHECKED]])
Example #3
0
def getSpeechTextForProperties(reason=controlTypes.REASON_QUERY,**propertyValues):
	oldTreeLevel = speech.oldTreeLevel
	oldTableID = speech.oldTableID
	oldRowNumber = speech.oldRowNumber
	oldRowSpan = speech.oldRowSpan
	oldColumnNumber = speech.oldColumnNumber
	oldColumnSpan = speech.oldColumnSpan

	global _enableTranslation

	if not _enableTranslation:
		return _nvdaGetSpeechTextForProperties(reason, **propertyValues)
	textList=[]
	name=propertyValues.get('name')
	if name:
		textList.append(translate(name.replace("&", "")))
	if 'role' in propertyValues:
		role=propertyValues['role']
		speakRole=True
	elif '_role' in propertyValues:
		speakRole=False
		role=propertyValues['_role']
	else:
		speakRole=False
		role=controlTypes.ROLE_UNKNOWN
	value = propertyValues.get('value') if role not in controlTypes.silentValuesForRoles else None
	cellCoordsText=propertyValues.get('cellCoordsText')
	rowNumber=propertyValues.get('rowNumber')
	columnNumber=propertyValues.get('columnNumber')
	includeTableCellCoords=propertyValues.get('includeTableCellCoords',True)
	if role==controlTypes.ROLE_CHARTELEMENT:
		speakRole=False
	roleText=propertyValues.get('roleText')
	if speakRole and (roleText or reason not in (controlTypes.REASON_SAYALL,controlTypes.REASON_CARET,controlTypes.REASON_FOCUS) or not (name or value or cellCoordsText or rowNumber or columnNumber) or role not in controlTypes.silentRolesOnFocus) and (role!=controlTypes.ROLE_MATH or reason not in (controlTypes.REASON_CARET,controlTypes.REASON_SAYALL)):
		textList.append(translate(roleText) if roleText else controlTypes.roleLabels[role])
	if value:
		textList.append(translate(value))
	states=propertyValues.get('states',set())
	realStates=propertyValues.get('_states',states)
	negativeStates=propertyValues.get('negativeStates',set())
	if states or negativeStates:
		textList.extend(controlTypes.processAndLabelStates(role, realStates, reason, states, negativeStates))
	if 'description' in propertyValues:
		textList.append(translate(propertyValues['description']))
	if 'keyboardShortcut' in propertyValues:
		textList.append(propertyValues['keyboardShortcut'])
	if includeTableCellCoords and cellCoordsText:
		textList.append(cellCoordsText)
	if cellCoordsText or rowNumber or columnNumber:
		tableID = propertyValues.get("_tableID")
		# Always treat the table as different if there is no tableID.
		sameTable = (tableID and tableID == oldTableID)
		# Don't update the oldTableID if no tableID was given.
		if tableID and not sameTable:
			oldTableID = tableID
			rowSpan = propertyValues.get("rowSpan")
			columnSpan = propertyValues.get("columnSpan")
			if rowNumber and (not sameTable or rowNumber != oldRowNumber or rowSpan != oldRowSpan):
				rowHeaderText = propertyValues.get("rowHeaderText")
				if rowHeaderText:
					textList.append(translate(rowHeaderText))
					if includeTableCellCoords and not cellCoordsText: 
						# Translators: Speaks current row number (example output: row 3).
						textList.append(_("row %s")%rowNumber)
						if rowSpan>1 and columnSpan<=1:
							# Translators: Speaks the row span added to the current row number (example output: through 5).
							textList.append(_("through %s")%(rowNumber+rowSpan-1))
					oldRowNumber = rowNumber
					oldRowSpan = rowSpan
			if columnNumber and (not sameTable or columnNumber != oldColumnNumber or columnSpan != oldColumnSpan):
				columnHeaderText = propertyValues.get("columnHeaderText")
				if columnHeaderText:
					textList.append(translate(columnHeaderText))
					if includeTableCellCoords and not cellCoordsText:
						# Translators: Speaks current column number (example output: column 3).
						textList.append(_("column %s")%columnNumber)
						if columnSpan>1 and rowSpan<=1:
							# Translators: Speaks the column span added to the current column number (example output: through 5).
							textList.append(_("through %s")%(columnNumber+columnSpan-1))
					oldColumnNumber = columnNumber
					oldColumnSpan = columnSpan
			if includeTableCellCoords and not cellCoordsText and rowSpan>1 and columnSpan>1:
				# Translators: Speaks the row and column span added to the current row and column numbers
				#					   (example output: through row 5 column 3).
				textList.append(_("through row {row} column {column}").format(
					row=rowNumber+rowSpan-1,
					column=columnNumber+columnSpan-1
				))
	rowCount=propertyValues.get('rowCount',0)
	columnCount=propertyValues.get('columnCount',0)
	if rowCount and columnCount:
		# Translators: Speaks number of columns and rows in a table (example output: with 3 rows and 2 columns).
		textList.append(_("with {rowCount} rows and {columnCount} columns").format(rowCount=rowCount,columnCount=columnCount))
	elif columnCount and not rowCount:
		# Translators: Speaks number of columns (example output: with 4 columns).
		textList.append(_("with %s columns")%columnCount)
	elif rowCount and not columnCount:
		# Translators: Speaks number of rows (example output: with 2 rows).
		textList.append(_("with %s rows")%rowCount)
	if rowCount or columnCount:
		# The caller is entering a table, so ensure that it is treated as a new table, even if the previous table was the same.
		oldTableID = None
	ariaCurrent = propertyValues.get('current', False)
	if ariaCurrent:
		try:
			textList.append(controlTypes.isCurrentLabels[ariaCurrent])
		except KeyError:
			log.debugWarning("Aria-current value not handled: %s"%ariaCurrent)
			textList.append(controlTypes.isCurrentLabels[True])
	placeholder = propertyValues.get('placeholder', None)
	if placeholder:
		textList.append(placeholder)
	indexInGroup=propertyValues.get('positionInfo_indexInGroup',0)
	similarItemsInGroup=propertyValues.get('positionInfo_similarItemsInGroup',0)
	if 0<indexInGroup<=similarItemsInGroup:
		# Translators: Spoken to indicate the position of an item in a group of items (such as a list).
		# {number} is replaced with the number of the item in the group.
		# {total} is replaced with the total number of items in the group.
		textList.append(_("{number} of {total}").format(number=indexInGroup, total=similarItemsInGroup))
	if 'positionInfo_level' in propertyValues:
		level=propertyValues.get('positionInfo_level',None)
		role=propertyValues.get('role',None)
		if level is not None:
			if role in (controlTypes.ROLE_TREEVIEWITEM,controlTypes.ROLE_LISTITEM) and level!=oldTreeLevel:
				textList.insert(0,_("level %s")%level)
				oldTreeLevel=level
			else:
				# Translators: Speaks the item level in treeviews (example output: level 2).
				textList.append(_('level %s')%propertyValues['positionInfo_level'])
	speech.oldTreeLevel = oldTreeLevel
	speech.oldTableID = oldTableID
	speech.oldRowNumber = oldRowNumber
	speech.oldRowSpan = oldRowSpan
	speech.oldColumnNumber = oldColumnNumber
	speech.oldColumnSpan = oldColumnSpan
	return speech.CHUNK_SEPARATOR.join([x for x in textList if x])
Example #4
0
def getPropertiesSpeech(  # noqa: C901
        reason=controlTypes.OutputReason.QUERY, **propertyValues):
    global oldTreeLevel, oldTableID, oldRowNumber, oldRowSpan, oldColumnNumber, oldColumnSpan
    textList: List[str] = []
    name: Optional[str] = propertyValues.get('name')
    if name:
        textList.append(translate(name))
    if 'role' in propertyValues:
        role = propertyValues['role']
        speakRole = True
    elif '_role' in propertyValues:
        speakRole = False
        role = propertyValues['_role']
    else:
        speakRole = False
        role = controlTypes.ROLE_UNKNOWN
    value: Optional[str] = propertyValues.get(
        'value') if role not in controlTypes.silentValuesForRoles else None
    cellCoordsText: Optional[str] = propertyValues.get('cellCoordsText')
    rowNumber = propertyValues.get('rowNumber')
    columnNumber = propertyValues.get('columnNumber')
    includeTableCellCoords = propertyValues.get('includeTableCellCoords', True)

    if role == controlTypes.ROLE_CHARTELEMENT:
        speakRole = False
    roleText: Optional[str] = propertyValues.get('roleText')
    if (speakRole and
        (roleText or reason not in (controlTypes.OutputReason.SAYALL,
                                    controlTypes.OutputReason.CARET,
                                    controlTypes.OutputReason.FOCUS)
         or not (name or value or cellCoordsText or rowNumber or columnNumber)
         or role not in controlTypes.silentRolesOnFocus) and
        (role != controlTypes.ROLE_MATH or reason not in
         (controlTypes.OutputReason.CARET, controlTypes.OutputReason.SAYALL))):
        textList.append(
            translate(roleText) if roleText else controlTypes.roleLabels[role])
    if value:
        textList.append(translate(value))
    states = propertyValues.get('states', set())
    realStates = propertyValues.get('_states', states)
    negativeStates = propertyValues.get('negativeStates', set())
    if states or negativeStates:
        labelStates = controlTypes.processAndLabelStates(
            role, realStates, reason, states, negativeStates)
        textList.extend(labelStates)
    # sometimes description key is present but value is None
    description: Optional[str] = propertyValues.get('description')
    if description:
        textList.append(translate(description))
    # sometimes keyboardShortcut key is present but value is None
    keyboardShortcut: Optional[str] = propertyValues.get('keyboardShortcut')
    if keyboardShortcut:
        textList.append(keyboardShortcut)
    if includeTableCellCoords and cellCoordsText:
        textList.append(cellCoordsText)
    if cellCoordsText or rowNumber or columnNumber:
        tableID = propertyValues.get("_tableID")
        # Always treat the table as different if there is no tableID.
        sameTable = (tableID and tableID == oldTableID)
        # Don't update the oldTableID if no tableID was given.
        if tableID and not sameTable:
            oldTableID = tableID
        # When fetching row and column span
        # default the values to 1 to make further checks a lot simpler.
        # After all, a table cell that has no rowspan implemented is assumed to span one row.
        rowSpan = propertyValues.get("rowSpan") or 1
        columnSpan = propertyValues.get("columnSpan") or 1
        if rowNumber and (not sameTable or rowNumber != oldRowNumber
                          or rowSpan != oldRowSpan):
            rowHeaderText: Optional[str] = propertyValues.get("rowHeaderText")
            if rowHeaderText:
                textList.append(rowHeaderText)
            if includeTableCellCoords and not cellCoordsText:
                # Translators: Speaks current row number (example output: row 3).
                rowNumberTranslation: str = _("row %s") % rowNumber
                textList.append(rowNumberTranslation)
                if rowSpan > 1 and columnSpan <= 1:
                    # Translators: Speaks the row span added to the current row number (example output: through 5).
                    rowSpanAddedTranslation: str = _("through %s") % (
                        rowNumber + rowSpan - 1)
                    textList.append(rowSpanAddedTranslation)
            oldRowNumber = rowNumber
            oldRowSpan = rowSpan
        if columnNumber and (not sameTable or columnNumber != oldColumnNumber
                             or columnSpan != oldColumnSpan):
            columnHeaderText: Optional[str] = propertyValues.get(
                "columnHeaderText")
            if columnHeaderText:
                textList.append(translate(columnHeaderText))
            if includeTableCellCoords and not cellCoordsText:
                # Translators: Speaks current column number (example output: column 3).
                colNumberTranslation: str = _("column %s") % columnNumber
                textList.append(colNumberTranslation)
                if columnSpan > 1 and rowSpan <= 1:
                    # Translators: Speaks the column span added to the current column number (example output: through 5).
                    colSpanAddedTranslation: str = _("through %s") % (
                        columnNumber + columnSpan - 1)
                    textList.append(colSpanAddedTranslation)
            oldColumnNumber = columnNumber
            oldColumnSpan = columnSpan
        if includeTableCellCoords and not cellCoordsText and rowSpan > 1 and columnSpan > 1:
            # Translators: Speaks the row and column span added to the current row and column numbers
            #                        (example output: through row 5 column 3).
            rowColSpanTranslation: str = _(
                "through row {row} column {column}").format(
                    row=rowNumber + rowSpan - 1,
                    column=columnNumber + columnSpan - 1)
            textList.append(rowColSpanTranslation)
    rowCount = propertyValues.get('rowCount', 0)
    columnCount = propertyValues.get('columnCount', 0)
    if rowCount and columnCount:
        # Translators: Speaks number of columns and rows in a table (example output: with 3 rows and 2 columns).
        rowAndColCountTranslation: str = _(
            "with {rowCount} rows and {columnCount} columns").format(
                rowCount=rowCount, columnCount=columnCount)
        textList.append(rowAndColCountTranslation)
    elif columnCount and not rowCount:
        # Translators: Speaks number of columns (example output: with 4 columns).
        columnCountTransation: str = _("with %s columns") % columnCount
        textList.append(columnCountTransation)
    elif rowCount and not columnCount:
        # Translators: Speaks number of rows (example output: with 2 rows).
        rowCountTranslation: str = _("with %s rows") % rowCount
        textList.append(rowCountTranslation)
    if rowCount or columnCount:
        # The caller is entering a table, so ensure that it is treated as a new table, even if the previous table was the same.
        oldTableID = None
    ariaCurrent = propertyValues.get('current', False)
    if ariaCurrent:
        try:
            ariaCurrentLabel = controlTypes.isCurrentLabels[ariaCurrent]
            textList.append(ariaCurrentLabel)
        except KeyError:
            log.debugWarning("Aria-current value not handled: %s" %
                             ariaCurrent)
            ariaCurrentLabel = controlTypes.isCurrentLabels[True]
            textList.append(ariaCurrentLabel)
    placeholder: Optional[str] = propertyValues.get('placeholder', None)
    if placeholder:
        textList.append(translate(placeholder))
    indexInGroup = propertyValues.get('positionInfo_indexInGroup', 0)
    similarItemsInGroup = propertyValues.get(
        'positionInfo_similarItemsInGroup', 0)
    if 0 < indexInGroup <= similarItemsInGroup:
        # Translators: Spoken to indicate the position of an item in a group of items (such as a list).
        # {number} is replaced with the number of the item in the group.
        # {total} is replaced with the total number of items in the group.
        itemPosTranslation: str = _("{number} of {total}").format(
            number=indexInGroup, total=similarItemsInGroup)
        textList.append(itemPosTranslation)
    if 'positionInfo_level' in propertyValues:
        level = propertyValues.get('positionInfo_level', None)
        role = propertyValues.get('role', None)
        if level is not None:
            # Translators: Speaks the item level in treeviews (example output: level 2).
            levelTranslation: str = _('level %s') % level
            if role in (controlTypes.ROLE_TREEVIEWITEM,
                        controlTypes.ROLE_LISTITEM) and level != oldTreeLevel:
                textList.insert(0, levelTranslation)
                oldTreeLevel = level
            else:
                textList.append(levelTranslation)
    types.logBadSequenceTypes(textList)
    global _lastTranslatedText
    _lastTranslatedText = " ".join(e for e in textList)
    return textList
Example #5
0
	def test_negativeMergedStatesOutput(self):
		obj = PlaceholderNVDAObject()
		obj.role = controlTypes.ROLE_CHECKBOX
		obj.states = set((controlTypes.STATE_FOCUSABLE, controlTypes.STATE_FOCUSED, controlTypes.STATE_SELECTED, controlTypes.STATE_SELECTABLE))
		self.assertEqual(controlTypes.processAndLabelStates(obj.role, obj.states, controlTypes.REASON_FOCUS, obj.states, None), [controlTypes.stateLabels[controlTypes.STATE_SELECTED],controlTypes.negativeStateLabels[controlTypes.STATE_CHECKED]])