Skip to content

Commit

Permalink
soffice: Report keyboard-triggered font size change
Browse files Browse the repository at this point in the history
 ### Link to issue number:

Partially implements feature requests from #6915

 ### Summary of the issue:

commit 46a3436
("soffice: Report keyboard-triggered formatting toggles in Writer (#16413)")
implemented announcement of formatting changes
triggered by keyboard shortcuts for formatting attributes
whose state is represented by toggle buttons in Writer's
formatting toolbar.
Issue #6915 requests announcement of further text formatting
attributes that are not represented by simple toggle buttons.
This includes decreasing/increasing the font size, which
can be done using the Ctrl+[ and Ctrl+] shortcuts when
using an English (US) UI and keyboard layout.

 ### Description of user facing changes

When decreasing or increasing the font size in LibreOffice
Writer using the corresponding keyboard shortcuts, NVDA
announces the new font size.

 ### Description of development approach

Extend the solution from the above-mentioned
commit 46a3436
to not only cover toggle buttons, but also
UI controls implementing the IAccessibleText
interface and handle the gestures/keyboard shortcuts
for changing the font size:

* Rename methods and variables introduced earlier
  to not have button-specific names.
* Extract some logic to helper methods/classes to
  avoid duplication in `SymphonyButton` and the
  newly introduced `SymphonyText` logic.
* Add Ctrl+[ and Ctrl+] to the list of keyboard gestures
  to handle.
* Add `SymphonyText.event_valueChange` override
  that announces the new value. This gets triggered
  when the value of the "Font Size" editable combobox
  in Writer's formatting toolbar changes after
  using the keyboard shortcut, and results in the
  new value being announced, e.g. "14 pt".
  This is comparable to the handling in
  `SymphonyButton.event_stateChange`
  introduced in the earlier above-mentioned commit.
* Increase the timeout for announcement of events
  from 0.15 to 2 seconds, as 0.15 seconds wasn't always
  sufficient when testing the new feature.

 ### Testing strategy:

1. start NVDA
2. start LibreOffice Writer (with English UI and
   keyboard layout)
3. Press Ctrl+[ to decrease the font size
4. Verify that NVDA announces the new font size,
   e.g. "10 pt" when using the default document template
5. Press Ctrl+] to increase the font size
4. Verify that NVDA announces the new font size,
   e.g. "12 pt" when using the default document template
5. repeat the tests mentioned in commit
   46a3436 to verify
   the toggle button case still works as expected

 ### Known issues with pull request:

None

 ### Code Review Checklist:

- [x] Documentation:
  - Change log entry
  - User Documentation
  - Developer / Technical Documentation
  - Context sensitive help for GUI changes
- [x] Testing:
  - Unit tests
  - System (end to end) tests
  - Manual testing
- [x] UX of all users considered:
  - Speech
  - Braille
  - Low Vision
  - Different web browsers
  - Localization in other languages / culture than English
- [x] API is compatible with existing add-ons.
- [x] Security precautions taken.
  • Loading branch information
michaelweghorn committed Sep 9, 2024
1 parent 88be74a commit 425b834
Show file tree
Hide file tree
Showing 2 changed files with 46 additions and 17 deletions.
62 changes: 45 additions & 17 deletions source/appModules/soffice.py
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,20 @@
import vision


class SymphonyUtils:
"""Helper class providing utility methods."""

@staticmethod
def is_toolbar_item(obj: NVDAObject) -> bool:
"""Whether the given object is part of a toolbar."""
parent = obj.parent
while parent:
if parent.role == controlTypes.Role.TOOLBAR:
return True
parent = parent.parent
return False


class SymphonyTextInfo(IA2TextTextInfo):
# C901 '_getFormatFieldFromLegacyAttributesString' is too complex
# Note: when working on _getFormatFieldFromLegacyAttributesString, look for opportunities to simplify
Expand Down Expand Up @@ -235,6 +249,17 @@ def _get_positionInfo(self):
return {"level": int(level)}
return super(SymphonyText, self).positionInfo

def event_valueChange(self) -> None:
# announce new value to indicate formatting change if registered gesture
# triggered the change in toolbar item's value/text
if SymphonyDocument.isFormattingChangeAnnouncementEnabled() and SymphonyUtils.is_toolbar_item(self):
message = self.IAccessibleTextObject.text(0, -1)
ui.message(message)
# disable announcement until next registered keypress enables it again
SymphonyDocument.announceFormattingGestureChange = False

return super().event_valueChange()


class SymphonyTableCell(IAccessible):
"""Silences particular states, and redundant column/row numbers"""
Expand Down Expand Up @@ -355,16 +380,7 @@ class SymphonyButton(IAccessible):
def event_stateChange(self) -> None:
# announce new state of toggled toolbar button to indicate formatting change
# if registered gesture resulted in button state change
if (
SymphonyDocument.announceToolbarButtonToggle
and self.parent
and self.parent.role == controlTypes.Role.TOOLBAR
and time.time()
< (
SymphonyDocument.lastFormattingGestureEventTime
+ SymphonyDocument.GESTURE_ANNOUNCEMENT_TIMEOUT
)
):
if SymphonyDocument.isFormattingChangeAnnouncementEnabled() and SymphonyUtils.is_toolbar_item(self):
states = self.states
enabled = controlTypes.State.PRESSED in states or controlTypes.State.CHECKED in states
# button's accessible name is the font attribute, e.g. "Bold", "Italic"
Expand All @@ -376,7 +392,7 @@ def event_stateChange(self) -> None:
message = _("{textAttribute} off").format(textAttribute=self.name)
ui.message(message)
# disable announcement until next registered keypress enables it again
SymphonyDocument.announceToolbarButtonToggle = False
SymphonyDocument.announceFormattingGestureChange = False

return super().event_stateChange()

Expand Down Expand Up @@ -431,10 +447,16 @@ class SymphonyDocument(CompoundDocument):
TextInfo = SymphonyDocumentTextInfo

# variables used for handling announcements resulting from gestures
GESTURE_ANNOUNCEMENT_TIMEOUT = 0.15
announceToolbarButtonToggle = False
GESTURE_ANNOUNCEMENT_TIMEOUT = 2.0
announceFormattingGestureChange = False
lastFormattingGestureEventTime = 0

@staticmethod
def isFormattingChangeAnnouncementEnabled():
return SymphonyDocument.announceFormattingGestureChange and time.time() < (
SymphonyDocument.lastFormattingGestureEventTime + SymphonyDocument.GESTURE_ANNOUNCEMENT_TIMEOUT
)

# override base class implementation because that one assumes
# that the text retrieved from the text info for the text unit
# is the same as the text that actually gets removed, which at
Expand Down Expand Up @@ -489,13 +511,19 @@ def _backspaceScriptHelper(self, unit: str, gesture: inputCore.InputGesture):
"kb:control+r",
# justified
"kb:control+j",
# decrease font size
"kb:control+[",
# increase font size
"kb:control+]",
],
)
def script_toggleTextAttribute(self, gesture: inputCore.InputGesture):
"""Reset time and enable announcement of toggled toolbar buttons.
See :func:`SymphonyButton.event_stateChange`
def script_changeTextFormatting(self, gesture: inputCore.InputGesture):
"""Reset time and enable announcement of newly changed state/text of toolbar
items related to text formatting.
See also :func:`SymphonyButton.event_stateChange` and
:func:`SymphonyText.event_valueChange`.
"""
SymphonyDocument.announceToolbarButtonToggle = True
SymphonyDocument.announceFormattingGestureChange = True
SymphonyDocument.lastFormattingGestureEventTime = time.time()
# send gesture
gesture.send()
Expand Down
1 change: 1 addition & 0 deletions user_docs/en/changes.md
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ In order to use this feature, the application volume adjuster needs to be enable
* Added an action in the Add-on Store to cancel the install of add-ons. (#15578, @hwf1324)
* Added an action in the Add-on Store to retry the installation if the download/installation of an add-on fails. (#17090, @hwf1324)
* It is now possible to specify a mirror URL to use for the Add-on Store. (#14974)
* When decreasing or increasing the font size in LibreOffice Writer using the corresponding keyboard shortcuts, NVDA announces the new font size. (#16413, @michaelweghorn)

### Changes

Expand Down

0 comments on commit 425b834

Please sign in to comment.