-
-
Notifications
You must be signed in to change notification settings - Fork 655
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Vocalize word formatting shortcuts #10283
Vocalize word formatting shortcuts #10283
Conversation
PR introduces Flake8 errors 😲 See test results for Failed build of commit 2f1a97d5a9 |
PR introduces Flake8 errors 😲 See test results for Failed build of commit 554b3f3958 |
Ctrl+U Toggle single underline Ctrl+Shift+D Toggle double underline Ctrl+Shift+W: Toggle word only underline Ctrl+shift+A: Toggle between All cap and No cap Ctrl+shift+K: Toggle between Small cap and No cap. Shift+F3: Toggle between Upper case, lower case and Capitalize first letter.
26c2d34
to
c2dbc96
Compare
is there any progress here? |
On my side, the PR is ready. |
…ate) shortcut key for toggleSuperscriptSubscript script.
I am adding two additional shortcut keys for toggleSuperscriptSubscript script:
I will update the initial description of this PR accordingly. |
…aseOutlookWordDocument class introduced by nvaccess#11925.
See test results for failed build of commit 7c017fd5ac |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What about if the users customizes keyboard shortcuts in word?
source/NVDAObjects/window/winword.py
Outdated
# Under Outlook, calling the script quickly a second time gives strange results. | ||
# Case value passes sometimes through an intermediate value. | ||
# So poll the value a second time. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It may be that the first operation hasn't yet completed. It would probably be best if nvda scripts queued subsequent runs until the first is complete. Could you see if you can confirm if that is happening here?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
How do you perform this? I.e. how do you delay the second script until the end of the first?
Moreover, I have tried to reproduce the issue with only one polling, but I cannot anymore. I will try on another version of Word later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I have just tested on another Word and Outlook version and I cannot reproduce the issue either. Both Office are 2016, but one of them was not up-to-date.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
How do you perform this? I.e. how do you delay the second script until the end of the first?
We'd need to first confirm that is what is happening, my suggestion was really just a guess. Since I didn't know, I have done some investigation, the short version is that it seems unlikely that the script is being called again before it completes. The long answer follows:
To work it out we can look at how the gestures are called.
It all starts with the hookThreadFunc
in source/winInputHook.py
. This runs in it's own thread, it registers a Low level hook function for the keyboard. Unfortunately this is where the questions start:
- Is this callback
keyboardHook
called only in the context of the thread that installed it?This hook is called in the context of the thread that installed it. The call is made by sending a message to the thread that installed the hook. Therefore, the thread that installed the hook must have a message loop.
- But the "Hooks Overview" docs say the following, please note that
WH_KEYBOARD_LL
is a "global only" install:
A global hook procedure can be called in the context of any application in the same desktop as the calling thread, so the procedure must be in a separate DLL module.
- Can this callback be re-entered by the Windows system?
- I couldn't find any information about this.
Another interesting piece of advice from the docs for "LowLevelKeyboardProc callback function" which we are apparently ignoring is:
Note Debug hooks cannot track this type of low level keyboard hooks. If the application must use low level hooks, it should run the hooks on a dedicated thread that passes the work off to a worker thread and then immediately returns. In most cases where the application needs to use low level hooks, it should monitor raw input instead. This is because raw input can asynchronously monitor mouse and keyboard messages that are targeted for other threads more effectively than low level hooks can. For more information on raw input, see Raw Input.
Ok, well I say "ignoring", but it looks like most paths result in adding an event to the event queue. The logic is complicated enough that it is hard to confirm this happens for all paths. If we assume it does happen for all paths, then I think we can be fairly confident that the script can't be called until it is exited.
I'm going to call on @michaelDCurran to take a look at this to see if there is anything I might have missed here, or if he can clarify anything further.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@feerrenrut thanks for your detailed explanations (and also for the summary!).
I have tried again but I cannot reproduce the issue anymore, This PR is quite old (it was one of my first PRs) and I do not remember exactly which type of stress test may have produced the issue; I also do not remember for example if I had tried to restart my computer.
I have thus removed this double polling. If an issue occur we my investigate on this new basis.
However, I keep this conversation open expecting @michaelDCurran's point of view.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@feerrenrut, have you had the opportunity to discuss with @michaelDCurran on the double script call potential issue.
Since I have removed the double-polling anyway, this conversation is not blocked anymore IMO. Do you agree?
@feerrenrut wrote:
This is not supported in this PR. This PR uses more or less the same strategy than what already exists in NVDA to report text formatting shortcuts in Word such as italic, underline and bold. Thus it suffers from the same limitations. If the user changes the default shortcuts in Word, the result of the new shortcut will not be reported. |
Ok, fair point this is not a new concern. |
@feerrenrut @michaelDCurran Would it be possible to move this PR forward? |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Overall the code looks good.
But testing this locally looking speech viewer:
- Pressing
ctrl+u
shows two lines :Underline Single Underline On
- Pressing
ctrl+b
shows two lines, note the difference in case:Bold on Bold On
Only the second sequence is heard, meaning that some information is lost in the underline case.
I haven't tested the other shortcuts yet, but I think this should be addressed.
Hi, the seemingly duplicate lines are caused by UIA notification event (see #10950 for details). Thanks.
|
Regarding duplicate format reporting, the issue is not specific to this PR, as explained by @josephsl. Looking again at this old PR, I am not so happy with the announcement "Underline single" instead of today's "Underline on". Maybe in the case of much more common single underline we can just keep "Underline on". |
Even though it is not specific to this PR, it is a conflict in the UI. The new messages may not be heard, it is also causing NVDA to do more than it needs to.
I'm not sure, I assume that the other values might be "underline double", any others? This provides more information than just "underline on". |
I may have not been clear enough in my previous comment. Let me give some more details:
So IMO, this PR can be progressed independantly from #10990. |
OK I let you the final decision on this point. So unless there is another comment regarding this topic, I keep the announcement "Underline single". |
OK. Thanks for this clarification.
Regarding this point, the situation is the following in the current version of NVDA (unchanged with this PR):
|
Closing as abandoned |
@seanbudd, this PR is not abandoned but blocked by #10990. I agree that this is quite old. In the meantime we have been able to see the evolution of UIA notifications regarding text formatting. After all these years, Microsoft has not added new notifications, i.e. only bold, italic and underline are being reported by UIA notifications. So to progress this PR, I propose to remove the changes related to bold, italic and underline and underline, i.e. all the shortcuts conflicting with UIA notifications, since it's the goal of #10990. @seanbudd do you agree with this plan? If not, why? Reopening and removing the "Abandoned" label. We may close again after discussion if needed. |
this plan makes sense, my assumption was that the work was abandoned. thanks |
I'm marking this as ready for review with the note that it is currently blocked |
WalkthroughThe primary changes include adding new enumerations for underline styles and character case types in Microsoft Word, updating scripts to toggle formatting, and improving the narration of formatting states in NVDA when using keyboard shortcuts in Word. Also, specific keyboard shortcuts handling has been enhanced for Outlook integration. Changes
Sequence Diagram(s)sequenceDiagram
participant User
participant NVDA
participant Word/Outlook
User->>Word/Outlook: Press formatting shortcut (e.g., Ctrl+B)
Word/Outlook-->>NVDA: Send formatting state change (e.g., bold on)
NVDA-->>User: Announce formatting state change (e.g., "Bold on")
Assessment against linked issues
Recent review detailsConfiguration used: .coderabbit.yml Files selected for processing (3)
Files skipped from review due to trivial changes (1)
Additional context usedPath-based instructions (2)
Thank you for using CodeRabbit. We offer it for free to the OSS community and would appreciate your support in helping us grow. If you find it useful, would you consider giving us a shout-out on your favorite social media? TipsChatThere are 3 ways to chat with CodeRabbit:
Note: Be mindful of the bot's finite context window. It's strongly recommended to break down tasks such as reading entire modules into smaller chunks. For a focused discussion, use review comments to chat about specific files and their changes, instead of using the PR comments. CodeRabbit Commands (invoked as PR comments)
Additionally, you can add CodeRabbit Configration File (
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 5
__gestures = { | ||
"kb:control+shift+w": None, # Shortcut existing in Word but not in Outlook | ||
"kb:control+shift+b": None, # Shortcut existing in Word but opens address book in Outlook | ||
"kb:control+shift+a": "changeCase", # In Outlook Ctrl+Shift+A is equivalent to Shift+F3 | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Refactor the __gestures
dictionary for clarity and maintainability.
The __gestures
dictionary is used to map keyboard shortcuts to their corresponding actions. The current implementation uses None
to signify shortcuts that are not applicable in Outlook, which might confuse future maintainers. Consider using a more descriptive placeholder or a comment to explain why these shortcuts are set to None
.
__gestures = {
+ # Shortcuts that are specific to Word and have different meanings in Outlook
"kb:control+shift+w": None, # Shortcut existing in Word but not in Outlook
"kb:control+shift+b": None, # Shortcut existing in Word but opens address book in Outlook
"kb:control+shift+a": "changeCase", # In Outlook Ctrl+Shift+A is equivalent to Shift+F3
}
Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
__gestures = { | |
"kb:control+shift+w": None, # Shortcut existing in Word but not in Outlook | |
"kb:control+shift+b": None, # Shortcut existing in Word but opens address book in Outlook | |
"kb:control+shift+a": "changeCase", # In Outlook Ctrl+Shift+A is equivalent to Shift+F3 | |
} | |
__gestures = { | |
# Shortcuts that are specific to Word and have different meanings in Outlook | |
"kb:control+shift+w": None, # Shortcut existing in Word but not in Outlook | |
"kb:control+shift+b": None, # Shortcut existing in Word but opens address book in Outlook | |
"kb:control+shift+a": "changeCase", # In Outlook Ctrl+Shift+A is equivalent to Shift+F3 | |
} |
wdUnderlineNone = 0 | ||
wdUnderlineSingle = 1 | ||
wdUnderlineWords = 2 | ||
wdUnderlineDouble = 3 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Documentation suggestion for enumerations.
The enumerations for underline styles (wdUnderlineNone
, wdUnderlineSingle
, etc.) and their corresponding descriptions (wdUnderlineTypeDescriptions
) are well-defined. However, adding a comment at the top of these enumerations explaining how and where these constants can be found or updated would improve maintainability. This aligns with the feedback from feerrenrut
in the previous comments.
+ # These constants represent the underline styles used in Microsoft Word. For updates or additions, refer to the official Microsoft Office VBA documentation.
Also applies to: 354-389
@script(gesture="kb:shift+f3") | ||
def script_changeCase(self, gesture): | ||
if not self.WinwordSelectionObject: | ||
# We cannot fetch the Word object model, so we therefore cannot report the format change. | ||
# The object model may be unavailable because this is a pure UIA implementation such as Windows 10 Mail, | ||
# or its within Windows Defender Application Guard. | ||
# For now, just let the gesture through and don't report anything. | ||
return gesture.send() | ||
val = self._WaitForValueChangeForAction( | ||
lambda: gesture.send(), | ||
lambda: self.WinwordSelectionObject.Range.Case | ||
) | ||
# Translators: a message when changing case in Microsoft Word | ||
ui.message(wdCharacterCaseTypeLabels.get(val)) | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Add error handling for script_changeCase
.
The method script_changeCase
retrieves the case of the text and displays it, but does not handle the case where val
may not be in wdCharacterCaseTypeLabels
.
- ui.message(wdCharacterCaseTypeLabels.get(val))
+ case_message = wdCharacterCaseTypeLabels.get(val, _("Unknown case"))
+ ui.message(case_message)
Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
@script(gesture="kb:shift+f3") | |
def script_changeCase(self, gesture): | |
if not self.WinwordSelectionObject: | |
# We cannot fetch the Word object model, so we therefore cannot report the format change. | |
# The object model may be unavailable because this is a pure UIA implementation such as Windows 10 Mail, | |
# or its within Windows Defender Application Guard. | |
# For now, just let the gesture through and don't report anything. | |
return gesture.send() | |
val = self._WaitForValueChangeForAction( | |
lambda: gesture.send(), | |
lambda: self.WinwordSelectionObject.Range.Case | |
) | |
# Translators: a message when changing case in Microsoft Word | |
ui.message(wdCharacterCaseTypeLabels.get(val)) | |
@script(gesture="kb:shift+f3") | |
def script_changeCase(self, gesture): | |
if not self.WinwordSelectionObject: | |
# We cannot fetch the Word object model, so we therefore cannot report the format change. | |
# The object model may be unavailable because this is a pure UIA implementation such as Windows 10 Mail, | |
# or its within Windows Defender Application Guard. | |
# For now, just let the gesture through and don't report anything. | |
return gesture.send() | |
val = self._WaitForValueChangeForAction( | |
lambda: gesture.send(), | |
lambda: self.WinwordSelectionObject.Range.Case | |
) | |
# Translators: a message when changing case in Microsoft Word | |
case_message = wdCharacterCaseTypeLabels.get(val, _("Unknown case")) | |
ui.message(case_message) |
def script_toggleUnderline(self, gesture): | ||
if not self.WinwordSelectionObject: | ||
# We cannot fetch the Word object model, so we therefore cannot report the format change. | ||
# The object model may be unavailable because this is a pure UIA implementation such as Windows 10 Mail, or its within Windows Defender Application Guard. | ||
# Eventually UIA will have its own way of detecting format changes at the cursor. For now, just let the gesture through and don't erport anything. | ||
# The object model may be unavailable because this is a pure UIA implementation such as Windows 10 Mail, | ||
# or its within Windows Defender Application Guard. | ||
# Eventually UIA will have its own way of detecting format changes at the cursor. | ||
# For now, just let the gesture through and don't report anything. | ||
return gesture.send() | ||
val=self._WaitForValueChangeForAction(lambda: gesture.send(),lambda: self.WinwordSelectionObject.font.underline) | ||
if val: | ||
# Translators: a message when toggling formatting in Microsoft word | ||
ui.message(_("Underline on")) | ||
val = self._WaitForValueChangeForAction( | ||
lambda: gesture.send(), | ||
lambda: self.WinwordSelectionObject.font.underline | ||
) | ||
if val != wdUnderlineNone: | ||
msg = wdUnderlineTypeDescriptions.get(val) | ||
if msg: | ||
# Translators: a message when toggling formatting in Microsoft word | ||
ui.message(_("Underline {style}").format(style=msg)) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ensure robust handling of multiple underline styles.
The method script_toggleUnderline
handles toggling of various underline styles. It correctly checks if the underline style is not wdUnderlineNone
and retrieves the message from wdUnderlineTypeDescriptions
. However, the method should robustly handle the case where val
might not be in wdUnderlineTypeDescriptions
, which could potentially lead to a KeyError
.
- msg = wdUnderlineTypeDescriptions.get(val)
+ msg = wdUnderlineTypeDescriptions.get(val, _("Unknown style"))
Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
def script_toggleUnderline(self, gesture): | |
if not self.WinwordSelectionObject: | |
# We cannot fetch the Word object model, so we therefore cannot report the format change. | |
# The object model may be unavailable because this is a pure UIA implementation such as Windows 10 Mail, or its within Windows Defender Application Guard. | |
# Eventually UIA will have its own way of detecting format changes at the cursor. For now, just let the gesture through and don't erport anything. | |
# The object model may be unavailable because this is a pure UIA implementation such as Windows 10 Mail, | |
# or its within Windows Defender Application Guard. | |
# Eventually UIA will have its own way of detecting format changes at the cursor. | |
# For now, just let the gesture through and don't report anything. | |
return gesture.send() | |
val=self._WaitForValueChangeForAction(lambda: gesture.send(),lambda: self.WinwordSelectionObject.font.underline) | |
if val: | |
# Translators: a message when toggling formatting in Microsoft word | |
ui.message(_("Underline on")) | |
val = self._WaitForValueChangeForAction( | |
lambda: gesture.send(), | |
lambda: self.WinwordSelectionObject.font.underline | |
) | |
if val != wdUnderlineNone: | |
msg = wdUnderlineTypeDescriptions.get(val) | |
if msg: | |
# Translators: a message when toggling formatting in Microsoft word | |
ui.message(_("Underline {style}").format(style=msg)) | |
def script_toggleUnderline(self, gesture): | |
if not self.WinwordSelectionObject: | |
# We cannot fetch the Word object model, so we therefore cannot report the format change. | |
# The object model may be unavailable because this is a pure UIA implementation such as Windows 10 Mail, | |
# or its within Windows Defender Application Guard. | |
# Eventually UIA will have its own way of detecting format changes at the cursor. | |
# For now, just let the gesture through and don't report anything. | |
return gesture.send() | |
val = self._WaitForValueChangeForAction( | |
lambda: gesture.send(), | |
lambda: self.WinwordSelectionObject.font.underline | |
) | |
if val != wdUnderlineNone: | |
msg = wdUnderlineTypeDescriptions.get(val, _("Unknown style")) | |
if msg: | |
# Translators: a message when toggling formatting in Microsoft word | |
ui.message(_("Underline {style}").format(style=msg)) |
@script(gestures=["kb:control+shift+a", "kb:control+shift+k"]) | ||
def script_toggleCaps(self, gesture): | ||
if not self.WinwordSelectionObject: | ||
# We cannot fetch the Word object model, so we therefore cannot report the format change. | ||
# The object model may be unavailable because this is a pure UIA implementation such as Windows 10 Mail, | ||
# or it's within Windows Defender Application Guard. | ||
# or its within Windows Defender Application Guard. | ||
# Eventually UIA will have its own way of detecting format changes at the cursor. | ||
# For now, just let the gesture through and don't report anything. | ||
return gesture.send() | ||
margin = self.WinwordDocumentObject.PageSetup.LeftMargin | ||
val = self._WaitForValueChangeForAction( | ||
lambda: gesture.send(), | ||
lambda: self.WinwordSelectionObject.paragraphFormat.LeftIndent | ||
lambda: (self.WinwordSelectionObject.font.allcaps, self.WinwordSelectionObject.font.smallcaps) | ||
) | ||
msg = self.getLocalizedMeasurementTextForPointSize(margin + val) | ||
ui.message(msg) | ||
if val[0]: | ||
# Translators: a message when toggling formatting to 'all capital' in Microsoft word | ||
ui.message(_("All caps on")) | ||
elif val[1]: | ||
# Translators: a message when toggling formatting to 'small capital' in Microsoft word | ||
ui.message(_("Small caps on")) | ||
else: | ||
# Translators: a message when toggling formatting to 'No capital' in Microsoft word | ||
ui.message(_("Caps off")) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Refactor repeated code in script_toggleCaps
.
The method script_toggleCaps
has repeated checks and messages for toggling caps. This can be refactored to reduce redundancy and improve clarity.
- if val[0]:
- ui.message(_("All caps on"))
- elif val[1]:
- ui.message(_("Small caps on"))
- else:
- ui.message(_("Caps off"))
+ cap_styles = ["All caps", "Small caps", "No caps"]
+ cap_index = val.index(True) if True in val else 2 # Default to "No caps" if neither is True
+ ui.message(_("{style} on").format(style=cap_styles[cap_index]))
Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
@script(gestures=["kb:control+shift+a", "kb:control+shift+k"]) | |
def script_toggleCaps(self, gesture): | |
if not self.WinwordSelectionObject: | |
# We cannot fetch the Word object model, so we therefore cannot report the format change. | |
# The object model may be unavailable because this is a pure UIA implementation such as Windows 10 Mail, | |
# or it's within Windows Defender Application Guard. | |
# or its within Windows Defender Application Guard. | |
# Eventually UIA will have its own way of detecting format changes at the cursor. | |
# For now, just let the gesture through and don't report anything. | |
return gesture.send() | |
margin = self.WinwordDocumentObject.PageSetup.LeftMargin | |
val = self._WaitForValueChangeForAction( | |
lambda: gesture.send(), | |
lambda: self.WinwordSelectionObject.paragraphFormat.LeftIndent | |
lambda: (self.WinwordSelectionObject.font.allcaps, self.WinwordSelectionObject.font.smallcaps) | |
) | |
msg = self.getLocalizedMeasurementTextForPointSize(margin + val) | |
ui.message(msg) | |
if val[0]: | |
# Translators: a message when toggling formatting to 'all capital' in Microsoft word | |
ui.message(_("All caps on")) | |
elif val[1]: | |
# Translators: a message when toggling formatting to 'small capital' in Microsoft word | |
ui.message(_("Small caps on")) | |
else: | |
# Translators: a message when toggling formatting to 'No capital' in Microsoft word | |
ui.message(_("Caps off")) | |
@script(gestures=["kb:control+shift+a", "kb:control+shift+k"]) | |
def script_toggleCaps(self, gesture): | |
if not self.WinwordSelectionObject: | |
# We cannot fetch the Word object model, so we therefore cannot report the format change. | |
# The object model may be unavailable because this is a pure UIA implementation such as Windows 10 Mail, | |
# or its within Windows Defender Application Guard. | |
# Eventually UIA will have its own way of detecting format changes at the cursor. | |
# For now, just let the gesture through and don't report anything. | |
return gesture.send() | |
val = self._WaitForValueChangeForAction( | |
lambda: gesture.send(), | |
lambda: (self.WinwordSelectionObject.font.allcaps, self.WinwordSelectionObject.font.smallcaps) | |
) | |
cap_styles = ["All caps", "Small caps", "No caps"] | |
cap_index = val.index(True) if True in val else 2 # Default to "No caps" if neither is True | |
ui.message(_("{style} on").format(style=cap_styles[cap_index])) |
@seanbudd with my last changes, I do not consider this PR blocked anymore by #10990. However, I still have to re-test all the use cases; it seems to me that not all of them are functional. That's why I kept this PR as draft. I will also address the Rabbit's review and let you know when it is ready. Or was there any other reason why you consider this PR blocked? |
Thanks, good to know, it was a misunderstanding on my part |
@CyrilleB79 - do you plan to do any further work here? |
Fixes (at least partially) #10271 Supersedes #10283. Summary of the issue: User wants to have font formatting state announced when native font formatting shortcut are executed under Word and Outlook. Description of user facing changes The results of the following MS Word shortcuts are now reported: control+shift+D: Underline double control+shift+W: Underline words only control+shift+A: All caps ctrl+Shift+K: Small caps ctrl+shift+i, ctrl+shift+b and ctrl+shift+u: alternative gestures for toggle italic, bold and underline. When relevant, these shortcuts are also reported in Outlook. Notes about various capitalization shortcuts In Word, the Shift+F3 and Ctrl+Shift+A shortcuts are slightly different: Shift+F3 only modifies the case of the current selection (or the word under the cursor if there is no selection) Ctrl+Shift+A also modifies the case of selected text (or current word), but in addition, it modifies the case of the characters that will be typed at insertion point of the cursor. Outlook's Ctrl+Shift+A shortcut is equivalent to Word's Shift+F3, whereas Word's Ctrl+Shift+A has no equivalent under Outlook as far as I know. Messages Word's shortcuts Ctrl+Shift+A, Ctrl+Shift+K and Shift+F3 modify all the selection's (or current word's) capitalization. However, Ctrl+Shift+A and Ctrl+Shift+K also impact the next characters that will be typed. Thus for this shortcut "on" and "off" have been used in their announced message in order to denote a state change. On the contrary Shift+F3 announces only the result of a modification of current selection (or word); thus "on" and "off" have not been used in its message. Description of development approach Use object model and polling to check state change, as done for other formatting scripts.
Link to issue number:
Fixes #10271
Summary of the issue:
User wants to have font formatting state announced when native font formatting shortcut are executed under Word and Outlook.
Description of how this pull request fixes the issue:
General description
This PR allows to announce the new state of font formatting when the following shortcuts are executed in MS Word (English version):
control+shift+D
: Underline doublecontrol+shift+W
: Underline words onlycontrol+shift+A
: All capsMoreover it announce the result of the
shift+F3
shortcut that change character case.At last it include
control+plus
andcontrol+shift+plus
that are alternative shortcuts for subscript and superscript.Notes about various capitalization shortcuts
In Word, the Shift+F3 and Ctrl+Shift+A shortcuts are slightly different:
Outlook's Ctrl+Shift+A shortcut is equivalent to Word's Shift+F3, whereas Word's Ctrl+Shift+A has no equivalent under Outlook as far as I know.
Messages
Word's shortcuts Ctrl+Shift+A, Ctrl+Shift+K and Shift+F3 modify all the selection's (or current word's) capitalization. However, Ctrl+Shift+A and Ctrl+Shift+K also impact the next characters that will be typed. Thus for this shortcut "on" and "off" have been used in their announced message in order to denote a state change. On the contrary Shift+F3 announces only the result of a modification of current selection (or word); thus "on" and "off" have not been used in its message.
Testing performed:
Tested all combinations:
In Word and in Outlook message (edition), English version
For all previously listed shortcuts
With the following selections:
Regarding Shift+F3, I am using a Microsoft enumeration containing also values such as wdHalfWidth, wdFullWidth, wdKatakana and wdHiragana. Seems all concepts of far-east languages.
Is there a notion equivalent to case changing in these languages? Do Shift+F3 or other shortcuts unknown to me have an impact on far-east writing?
Maybe @josephsl and @nishimotz could comment and test.
Known issues with pull request:
gestures.ini
files in SRT repo (or elsewhere if the process changes) according to native Word or Outlook shortcuts in their language if these differ from English. I plan to inform them in detail when the beta translation freeze occurs.ctrl+shift+I
,ctrl+shift+b
andctrl+shift+U
are alternative shortcuts for italic, bold and underline. However, since they trigger UIA notifications. So, as per Vocalize word formatting shortcuts #10283 (comment), I do not include them in this PR. This can be revisited when Word 365: do not announce font attribute toggle messages if raised from UIA notification event #10990 is merged.Summary by CodeRabbit
New Features
Bug Fixes