Skip to content

Commit a6b775b

Browse files
authored
Merge c96dd4a into 72545d7
2 parents 72545d7 + c96dd4a commit a6b775b

11 files changed

Lines changed: 196 additions & 98 deletions

File tree

nvdaHelper/remote/WinWord/Constants.h

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
/*
22
This file is a part of the NVDA project.
33
URL: http://www.nvda-project.org/
4-
Copyright 2016 NVDA contributers.
4+
Copyright 2016-2023 NVDA contributors.
55
This program is free software: you can redistribute it and/or modify
66
it under the terms of the GNU General Public License version 2.0, as published by
77
the Free Software Foundation.
@@ -186,10 +186,12 @@ constexpr int wdMaximumNumberOfColumns = 18;
186186
constexpr int wdHorizontalPositionRelativeToPage = 5;
187187

188188
// WdParagraphAlignment Enumeration
189+
// (see https://docs.microsoft.com/en-us/office/vba/api/word.wdparagraphalignment)
189190
constexpr int wdAlignParagraphLeft = 0;
190191
constexpr int wdAlignParagraphCenter = 1;
191192
constexpr int wdAlignParagraphRight = 2;
192193
constexpr int wdAlignParagraphJustify = 3;
194+
constexpr int wdAlignParagraphDistribute = 4;
193195

194196
// WdLanguageID Enumeration
195197
constexpr int wdLanguageNone = 0; //&H0

nvdaHelper/remote/winword.cpp

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
/*
22
This file is a part of the NVDA project.
33
URL: http://www.nvda-project.org/
4-
Copyright 2006-2010 NVDA contributers.
4+
Copyright 2006-2023 NVDA contributors.
55
This program is free software: you can redistribute it and/or modify
66
it under the terms of the GNU General Public License version 2.0, as published by
77
the Free Software Foundation.
@@ -561,7 +561,10 @@ void generateXMLAttribsForFormatting(IDispatch* pDispatchRange, int startOffset,
561561
formatAttribsStream<<L"text-align=\"right\" ";
562562
break;
563563
case wdAlignParagraphJustify:
564-
formatAttribsStream<<L"text-align=\"justified\" ";
564+
formatAttribsStream<<L"text-align=\"justify\" ";
565+
break;
566+
case wdAlignParagraphDistribute:
567+
formatAttribsStream<<L"text-align=\"distribute\" ";
565568
break;
566569
}
567570
}

source/NVDAObjects/IAccessible/__init__.py

Lines changed: 15 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -50,7 +50,7 @@
5050
import config
5151
import controlTypes
5252
from controlTypes import TextPosition
53-
from controlTypes.formatFields import FontSize
53+
from controlTypes.formatFields import FontSize, TextAlign
5454
from NVDAObjects.window import Window
5555
from NVDAObjects import NVDAObject, NVDAObjectTextInfo, InvalidNVDAObject
5656
import NVDAObjects.JAB
@@ -86,11 +86,23 @@ def getNVDAObjectFromPoint(x,y):
8686
FORMAT_OBJECT_ATTRIBS = frozenset({"text-align"})
8787
def normalizeIA2TextFormatField(formatField):
8888
try:
89-
textAlign=formatField.pop("text-align")
89+
val = formatField.pop("text-align")
9090
except KeyError:
9191
textAlign=None
92+
else:
93+
mozillaTextAlign = {
94+
'-moz-left': 'left',
95+
'-moz-center': 'center',
96+
'-moz-right': 'right',
97+
}
98+
val = mozillaTextAlign.get(val, val)
99+
try:
100+
textAlign = TextAlign(val)
101+
except ValueError:
102+
log.debugWarning(f'Unsupported value for text-align attribute: "{val}"')
103+
textAlign = None
92104
if textAlign:
93-
formatField["text-align"]=textAlign
105+
formatField["text-align"] = textAlign
94106
try:
95107
fontWeight=formatField.pop("font-weight")
96108
except KeyError:

source/NVDAObjects/UIA/__init__.py

Lines changed: 15 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@
2424
import UIAHandler.customProps
2525
import UIAHandler.customAnnotations
2626
import controlTypes
27-
from controlTypes import TextPosition
27+
from controlTypes import TextPosition, TextAlign
2828
import config
2929
import speech
3030
import api
@@ -71,6 +71,13 @@
7171
UIAHandler.UIA_IndentationTrailingAttributeId,
7272
}
7373

74+
textAlignLabels = {
75+
UIAHandler.HorizontalTextAlignment_Left: TextAlign.LEFT,
76+
UIAHandler.HorizontalTextAlignment_Centered: TextAlign.CENTER,
77+
UIAHandler.HorizontalTextAlignment_Right: TextAlign.RIGHT,
78+
UIAHandler.HorizontalTextAlignment_Justified: TextAlign.JUSTIFY,
79+
}
80+
7481

7582
class UIATextInfo(textInfos.TextInfo):
7683
_rangeObj: IUIAutomationTextRangeT
@@ -270,19 +277,13 @@ def _getFormatFieldAtRange( # noqa: C901
270277
if formatConfig["reportParagraphIndentation"]:
271278
formatField.update(self._getFormatFieldIndent(fetcher, ignoreMixedValues=ignoreMixedValues))
272279
if formatConfig["reportAlignment"]:
273-
val=fetcher.getValue(UIAHandler.UIA_HorizontalTextAlignmentAttributeId,ignoreMixedValues=ignoreMixedValues)
274-
if val==UIAHandler.HorizontalTextAlignment_Left:
275-
val="left"
276-
elif val==UIAHandler.HorizontalTextAlignment_Centered:
277-
val="center"
278-
elif val==UIAHandler.HorizontalTextAlignment_Right:
279-
val="right"
280-
elif val==UIAHandler.HorizontalTextAlignment_Justified:
281-
val="justify"
282-
else:
283-
val=None
284-
if val:
285-
formatField['text-align']=val
280+
val = fetcher.getValue(
281+
UIAHandler.UIA_HorizontalTextAlignmentAttributeId,
282+
ignoreMixedValues=ignoreMixedValues,
283+
)
284+
textAlign = textAlignLabels.get(val)
285+
if textAlign:
286+
formatField['text-align'] = textAlign
286287
if formatConfig["reportColor"]:
287288
val=fetcher.getValue(UIAHandler.UIA_BackgroundColorAttributeId,ignoreMixedValues=ignoreMixedValues)
288289
if isinstance(val,int):

source/NVDAObjects/window/edit.py

Lines changed: 9 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
# A part of NonVisual Desktop Access (NVDA)
2-
# Copyright (C) 2006-2022 NV Access Limited, Babbage B.V., Cyrille Bougot
2+
# Copyright (C) 2006-2023 NV Access Limited, Babbage B.V., Cyrille Bougot
33
# This file is covered by the GNU General Public License.
44
# See the file COPYING for more details.
55

@@ -28,7 +28,7 @@
2828
import textInfos
2929
import textInfos.offsets
3030
import controlTypes
31-
from controlTypes import TextPosition
31+
from controlTypes import TextPosition, TextAlign
3232
from . import Window
3333
from ..behaviors import EditableTextWithAutoSelectDetection
3434
import watchdog
@@ -520,13 +520,16 @@ def _getFormatFieldAtRange(self, textRange, formatConfig): # noqa: C901
520520
paraFormatObj = textRange.para
521521
alignment=paraFormatObj.alignment
522522
if alignment==comInterfaces.tom.tomAlignLeft:
523-
formatField["text-align"]="left"
523+
formatField["text-align"] = TextAlign.LEFT
524524
elif alignment==comInterfaces.tom.tomAlignCenter:
525-
formatField["text-align"]="center"
525+
formatField["text-align"] = TextAlign.CENTER
526526
elif alignment==comInterfaces.tom.tomAlignRight:
527-
formatField["text-align"]="right"
527+
formatField["text-align"] = TextAlign.RIGHT
528528
elif alignment==comInterfaces.tom.tomAlignJustify:
529-
formatField["text-align"]="justify"
529+
formatField["text-align"] = TextAlign.JUSTIFY
530+
else:
531+
log.debugWarning(f'Unsupported text-align: {alignment}')
532+
formatField["text-align"] = TextAlign.UNDEFINED
530533
if formatConfig["reportLineNumber"]:
531534
formatField["line-number"] = textRange.getIndex(comInterfaces.tom.tomLine)
532535
if formatConfig["reportFontName"]:

source/NVDAObjects/window/excel.py

Lines changed: 39 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,7 @@
3939
import mouseHandler
4040
from displayModel import DisplayModelTextInfo
4141
import controlTypes
42-
from controlTypes import TextPosition
42+
from controlTypes import TextPosition, TextAlign, VerticalTextAlign
4343
from . import Window
4444
from .. import NVDAObjectTextInfo
4545
import scriptHandler
@@ -54,28 +54,48 @@
5454
xlNone=-4142
5555
xlSimple=-4154
5656
xlExtended=3
57-
xlCenter=-4108
58-
xlJustify=-4130
59-
xlLeft=-4131
60-
xlRight=-4152
61-
xlDistributed=-4117
62-
xlBottom=-4107
63-
xlTop=-4160
57+
58+
# XlHAlign enumeration from https://docs.microsoft.com/en-us/office/vba/api/excel.xlhalign
59+
xlHAlignCenter = -4108
60+
xlHAlignCenterAcrossSelection = 7
61+
xlHAlignDistributed = -4117
62+
xlHAlignFil = 5
63+
xlHAlignGeneral = 1
64+
xlHAlignJustify = -4130
65+
xlHAlignLeft = -4131
66+
xlHAlignRight = -4152
67+
68+
# XlVAlign enumeration from https://docs.microsoft.com/en-us/office/vba/api/excel.xlvalign
69+
xlVAlignBottom = -4107
70+
xlVAlignCenter = -4108
71+
xlVAlignDistributed = -4117
72+
xlVAlignJustify = -4130
73+
xlVAlignTop = -4160
74+
6475
xlDown=-4121
6576
xlToLeft=-4159
6677
xlToRight=-4161
6778
xlUp=-4162
6879
xlCellWidthUnitToPixels = 7.5919335705812574139976275207592
6980
xlSheetVisible=-1
70-
alignmentLabels={
71-
xlCenter:"center",
72-
xlJustify:"justify",
73-
xlLeft:"left",
74-
xlRight:"right",
75-
xlDistributed:"distributed",
76-
xlBottom:"botom",
77-
xlTop:"top",
78-
1:"default",
81+
82+
horizontalAlignmentLabels = {
83+
xlHAlignCenter: TextAlign.CENTER,
84+
xlHAlignCenterAcrossSelection: TextAlign.CENTER_ACROSS_SELECTION,
85+
xlHAlignDistributed: TextAlign.DISTRIBUTE,
86+
xlHAlignFil: TextAlign.FILL,
87+
xlHAlignGeneral: TextAlign.GENERAL,
88+
xlHAlignJustify: TextAlign.JUSTIFY,
89+
xlHAlignLeft: TextAlign.LEFT,
90+
xlHAlignRight: TextAlign.RIGHT,
91+
}
92+
93+
verticalAlignmentLabels = {
94+
xlVAlignBottom: VerticalTextAlign.BOTTOM,
95+
xlVAlignCenter: VerticalTextAlign.CENTER,
96+
xlVAlignDistributed: VerticalTextAlign.DISTRIBUTE,
97+
xlVAlignJustify: VerticalTextAlign.JUSTIFY,
98+
xlVAlignTop: VerticalTextAlign.TOP,
7999
}
80100

81101
xlA1 = 1
@@ -1097,10 +1117,10 @@ def _getFormatFieldAndOffsets(self,offset,formatConfig,calculateOffsets=True):
10971117
cellObj=self.obj.excelCellObject
10981118
fontObj=cellObj.font
10991119
if formatConfig['reportAlignment']:
1100-
value=alignmentLabels.get(self.obj.excelCellObject.horizontalAlignment)
1120+
value = horizontalAlignmentLabels.get(self.obj.excelCellObject.horizontalAlignment)
11011121
if value:
11021122
formatField['text-align']=value
1103-
value=alignmentLabels.get(self.obj.excelCellObject.verticalAlignment)
1123+
value = verticalAlignmentLabels.get(self.obj.excelCellObject.verticalAlignment)
11041124
if value:
11051125
formatField['vertical-align']=value
11061126
if formatConfig['reportFontName']:

source/NVDAObjects/window/winword.py

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@
3232
import colors
3333
import controlTypes
3434
from controlTypes import TextPosition
35+
from controlTypes.formatFields import TextAlign
3536
import treeInterceptorHandler
3637
import browseMode
3738
import review
@@ -972,6 +973,9 @@ def _normalizeFormatField(self,field,extraDetail=False):
972973
if fontSize is not None:
973974
# Translators: Abbreviation for points, a measurement of font size.
974975
field["font-size"] = pgettext("font size", "%s pt") % fontSize
976+
textAlign = field.pop('text-align', None)
977+
if textAlign:
978+
field['text-align'] = TextAlign(textAlign)
975979
return field
976980

977981
def expand(self,unit):

source/controlTypes/__init__.py

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,9 @@
11
# A part of NonVisual Desktop Access (NVDA)
22
# This file is covered by the GNU General Public License.
33
# See the file COPYING for more details.
4-
# Copyright (C) 2007-2021 NV Access Limited, Babbage B.V.
4+
# Copyright (C) 2007-2023 NV Access Limited, Babbage B.V., Cyrille Bougot
55

6-
from .formatFields import TextPosition
6+
from .formatFields import TextPosition, TextAlign, VerticalTextAlign
77
from .isCurrent import IsCurrent
88
from .outputReason import OutputReason
99
from .processAndLabelStates import processAndLabelStates
@@ -31,7 +31,9 @@
3131
"State",
3232
"STATES_SORTED",
3333
"DescriptionFrom",
34+
"TextAlign",
3435
"TextPosition",
3536
"transformRoleStates",
37+
"VerticalTextAlign",
3638
*deprecatedAliases.__all__
3739
]

source/controlTypes/formatFields.py

Lines changed: 81 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
# A part of NonVisual Desktop Access (NVDA)
22
# This file is covered by the GNU General Public License.
33
# See the file COPYING for more details.
4-
# Copyright (C) 2021-2022 NV Access Limited, Cyrille Bougot
4+
# Copyright (C) 2021-2023 NV Access Limited, Cyrille Bougot
55

66
import re
77
from typing import Dict
@@ -99,3 +99,83 @@ def translateFromAttribute(fontSize: str) -> str:
9999
return FontSize._unitToTranslatableString[measurementUnit] % measurement
100100
log.debugWarning(f"Unknown font-size value, can't translate '{fontSize}'")
101101
return fontSize
102+
103+
104+
class TextAlign(DisplayStringStrEnum):
105+
"""Values to use for 'text-align' NVDA format field.
106+
These describe the horizontal paragraph position.
107+
"""
108+
UNDEFINED = 'undefined'
109+
LEFT = 'left'
110+
CENTER = 'center'
111+
RIGHT = 'right'
112+
JUSTIFY = 'justify'
113+
DISTRIBUTE = 'distribute'
114+
CENTER_ACROSS_SELECTION = 'center-across-selection'
115+
GENERAL = 'general'
116+
FILL = 'fill'
117+
118+
@property
119+
def _displayStringLabels(self):
120+
return _textAlignLabels
121+
122+
123+
#: Text to use for 'text-align format field values. These describe the horizontal position of a paragraph
124+
#: or a cell's content.
125+
_textAlignLabels: Dict[TextAlign, str] = {
126+
TextAlign.UNDEFINED: "", # There is nothing to report if no alignment is defined.
127+
# Translators: Reported when text is left-aligned.
128+
TextAlign.LEFT: _("align left"),
129+
# Translators: Reported when text is centered.
130+
TextAlign.CENTER: _("align center"),
131+
# Translators: Reported when text is right-aligned.
132+
TextAlign.RIGHT: _("align right"),
133+
# Translators: Reported when text is justified.
134+
# See http://en.wikipedia.org/wiki/Typographic_alignment#Justified
135+
TextAlign.JUSTIFY: _("align justify"),
136+
# Translators: Reported when text is justified with character spacing (Japanese etc)
137+
# See http://kohei.us/2010/01/21/distributed-text-justification/
138+
TextAlign.DISTRIBUTE: _("align distributed"),
139+
# Translators: Reported when text is centered across multiple cells.
140+
TextAlign.CENTER_ACROSS_SELECTION: _("align center across multiple cells"),
141+
# Translators: Reported in Excel when text is formatted with "General" alignment, i.e. the name of the
142+
# alignment in Excel aligning the cell's content depending on its type: text left and numbers right.
143+
TextAlign.GENERAL: _("align general"),
144+
# Translators: Reported in Excel when text is formatted with "Fill" alignment, i.e. the name of the
145+
# alignment in Excel repeating the cell's content for the width of the cell.
146+
TextAlign.FILL: _("align fill"),
147+
}
148+
149+
150+
class VerticalTextAlign(DisplayStringStrEnum):
151+
"""Values to use for 'vertical-align' NVDA format field.
152+
These describe the vertical text position, e.g. in a table cell.
153+
"""
154+
UNDEFINED = 'undefined'
155+
TOP = 'top'
156+
CENTER = 'center'
157+
BOTTOM = 'bottom'
158+
JUSTIFY = 'justify'
159+
DISTRIBUTE = 'distributed'
160+
161+
@property
162+
def _displayStringLabels(self):
163+
return _verticalTextAlignLabels
164+
165+
166+
#: Text to use for 'vertical-align' format field values. These describe the vertical position
167+
#: of a cell's content.
168+
_verticalTextAlignLabels: Dict[VerticalTextAlign, str] = {
169+
VerticalTextAlign.UNDEFINED: "", # There is nothing to report if no vertical alignment is defined.
170+
# Translators: Reported when text is vertically top-aligned.
171+
VerticalTextAlign.TOP: _("vertical align top"),
172+
# Translators: Reported when text is vertically middle aligned.
173+
VerticalTextAlign.CENTER: _("vertical align middle"),
174+
# Translators: Reported when text is vertically bottom-aligned.
175+
VerticalTextAlign.BOTTOM: _("vertical align bottom"),
176+
# Translators: Reported when text is vertically justified.
177+
VerticalTextAlign.JUSTIFY: _("vertical align justified"),
178+
# Translators: Reported when text is vertically justified but with character spacing
179+
# (For some Asian content).
180+
VerticalTextAlign.DISTRIBUTE: _("vertical align distributed"),
181+
}

0 commit comments

Comments
 (0)