4
4
#This file is covered by the GNU General Public License.
5
5
#See the file COPYING for more details.
10
7
from comtypes import COMError
11
8
import comtypes.automation
14
import textInfos.offsets
15
13
import eventHandler
19
16
import controlTypes
21
from keyUtils import sendKey, key
22
17
from . import Window
23
18
from .. import NVDAObjectTextInfo
24
import appModuleHandler
26
re_dollaredAddress=re.compile(r"^\$?([a-zA-Z]+)\$?([0-9]+)")
28
class CellEditDialog(gui.scriptUI.ModalDialog):
30
def __init__(self,cell):
31
super(CellEditDialog,self).__init__(None)
34
def onCellTextChar(self,evt):
35
if evt.GetKeyCode() == wx.WXK_RETURN:
37
i=self._cellText.GetInsertionPoint()
38
self._cellText.Replace(i,i,"\n")
45
self._cell.formulaLocal=self._cellText.GetValue()
46
self.dialog.EndModal(wx.ID_OK)
49
d=wx.Dialog(gui.mainFrame, wx.ID_ANY, title=_("NVDA Excel Cell Editor"))
50
mainSizer = wx.BoxSizer(wx.VERTICAL)
51
mainSizer.Add(wx.StaticText(d,wx.ID_ANY, label=_("Enter cell contents")))
52
self._cellText=wx.TextCtrl(d, wx.ID_ANY, size=(300, 200), style=wx.TE_RICH|wx.TE_MULTILINE)
53
self._cellText.Bind(wx.EVT_KEY_DOWN, self.onCellTextChar)
54
self._cellText.SetValue(self._cell.formulaLocal)
55
mainSizer.Add(self._cellText)
56
mainSizer.Add(d.CreateButtonSizer(wx.OK|wx.CANCEL))
57
d.Bind(wx.EVT_BUTTON,self.onOk,id=wx.ID_OK)
59
self._cellText.SetFocus()
62
class ExcelWindow(Window):
63
"""A base that all Excel NVDAObjects inherit from, which contains some useful static methods."""
23
class ExcelBase(Window):
24
"""A base that all Excel NVDAObjects inherit from, which contains some useful methods."""
66
27
def excelWindowObjectFromWindow(windowHandle):
71
32
return comtypes.client.dynamic.Dispatch(pDispatch)
74
def getCellAddress(cell):
75
return re_dollaredAddress.sub(r"\1\2",cell.Address())
77
class Excel7Window(ExcelWindow):
35
def getCellAddress(cell, external=False):
36
return cell.Address(False, False, xlA1, external)
38
def fireFocusOnSelection(self):
39
selection=self.excelWindowObject.Selection
41
obj=ExcelSelection(windowHandle=self.windowHandle,excelWindowObject=self.excelWindowObject,excelRangeObject=selection)
43
obj=ExcelCell(windowHandle=self.windowHandle,excelWindowObject=self.excelWindowObject,excelCellObject=selection)
44
eventHandler.executeEvent("gainFocus",obj)
46
class Excel7Window(ExcelBase):
78
47
"""An overlay class for Window for the EXCEL7 window class, which simply bounces focus to the active excel cell."""
80
49
def _get_excelWindowObject(self):
81
50
return self.excelWindowObjectFromWindow(self.windowHandle)
83
52
def event_gainFocus(self):
84
activeCell=self.excelWindowObject.ActiveCell
85
obj=ExcelCell(windowHandle=self.windowHandle,excelWindowObject=self.excelWindowObject,excelCellObject=activeCell)
86
eventHandler.executeEvent("gainFocus",obj)
53
self.fireFocusOnSelection()
88
class ExcelWorksheet(ExcelWindow):
55
class ExcelWorksheet(ExcelBase):
90
57
role=controlTypes.ROLE_TABLE
93
60
self.excelWindowObject=excelWindowObject
94
61
self.excelWorksheetObject=excelWorksheetObject
95
62
super(ExcelWorksheet,self).__init__(windowHandle=windowHandle)
63
for gesture in self.__changeSelectionGestures:
64
self.bindGesture(gesture, "changeSelection")
97
66
def _get_name(self):
98
67
return self.excelWorksheetObject.name
69
def _isEqual(self, other):
70
if not super(ExcelWorksheet, self)._isEqual(other):
72
return self.excelWorksheetObject.index == other.excelWorksheetObject.index
100
74
def _get_firstChild(self):
101
75
cell=self.excelWorksheetObject.cells(1,1)
102
76
return ExcelCell(windowHandle=self.windowHandle,excelWindowObject=self.excelWindowObject,excelCellObject=cell)
105
def script_extendSelection(self,keyPress):
107
selection=self.excelWindowObject.Selection
108
if selection.Count>1:
109
obj=ExcelSelection(windowHandle=self.windowHandle,excelWindowObject=self.excelWindowObject,excelRangeObject=selection)
111
obj=ExcelCell(windowHandle=self.windowHandle,excelWindowObject=self.excelWindowObject,excelCellObject=selection)
112
eventHandler.executeEvent("gainFocus",obj)
113
script_extendSelection.__doc__=_("Extends the selection and speaks the last selected cell")
114
script_extendSelection.canPropagate=True
116
def script_moveByCell(self,keyPress):
117
"""Moves to a cell and speaks its coordinates and content"""
119
activeCell=self.excelWindowObject.ActiveCell
120
obj=ExcelCell(windowHandle=self.windowHandle,excelWindowObject=self.excelWindowObject,excelCellObject=activeCell)
121
eventHandler.executeEvent("gainFocus",obj)
122
script_moveByCell.__doc__=_("Moves to a cell and speaks its coordinates and content")
123
script_moveByCell.canPropagate=True
125
[ExcelWorksheet.bindKey(keyName,scriptName) for keyName,scriptName in [
126
("Tab","moveByCell"),
127
("Shift+Tab","moveByCell"),
128
("ExtendedUp","moveByCell"),
129
("ExtendedDown","moveByCell"),
130
("ExtendedLeft","moveByCell"),
131
("ExtendedRight","moveByCell"),
132
("Control+ExtendedUp","moveByCell"),
133
("Control+ExtendedDown","moveByCell"),
134
("Control+ExtendedLeft","moveByCell"),
135
("Control+ExtendedRight","moveByCell"),
136
("ExtendedHome","moveByCell"),
137
("ExtendedEnd","moveByCell"),
138
("Control+ExtendedHome","moveByCell"),
139
("Control+ExtendedEnd","moveByCell"),
140
("Shift+ExtendedUp","extendSelection"),
141
("Shift+ExtendedDown","extendSelection"),
142
("Shift+ExtendedLeft","extendSelection"),
143
("Shift+ExtendedRight","extendSelection"),
144
("Shift+Control+ExtendedUp","extendSelection"),
145
("Shift+Control+ExtendedDown","extendSelection"),
146
("Shift+Control+ExtendedLeft","extendSelection"),
147
("Shift+Control+ExtendedRight","extendSelection"),
148
("Shift+ExtendedHome","extendSelection"),
149
("Shift+ExtendedEnd","extendSelection"),
150
("Shift+Control+ExtendedHome","extendSelection"),
151
("Shift+Control+ExtendedEnd","extendSelection"),
154
class ExcelCellTextInfo(textInfos.offsets.OffsetsTextInfo):
78
def script_changeSelection(self,gesture):
80
if scriptHandler.isScriptWaiting():
81
# Prevent lag if keys are pressed rapidly.
83
self.fireFocusOnSelection()
84
script_changeSelection.canPropagate=True
86
__changeSelectionGestures = (
94
"kb:control+downArrow",
95
"kb:control+leftArrow",
96
"kb:control+rightArrow",
102
"kb:shift+downArrow",
103
"kb:shift+leftArrow",
104
"kb:shift+rightArrow",
105
"kb:shift+control+upArrow",
106
"kb:shift+control+downArrow",
107
"kb:shift+control+leftArrow",
108
"kb:shift+control+rightArrow",
111
"kb:shift+control+home",
112
"kb:shift+control+end",
116
"kb:control+pageDown",
120
class ExcelCellTextInfo(NVDAObjectTextInfo):
156
122
def _getFormatFieldAndOffsets(self,offset,formatConfig,calculateOffsets=True):
157
123
formatField=textInfos.FormatField()
234
209
return ExcelCell(windowHandle=self.windowHandle,excelWindowObject=self.excelWindowObject,excelCellObject=previous)
236
def script_editCell(self,keyPress):
237
cellEditDialog=CellEditDialog(self.excelWindowObject.ActiveCell)
240
ExcelCell.bindKey("f2","editCell")
242
class ExcelSelection(ExcelWindow):
244
role=controlTypes.ROLE_GROUPING
211
class ExcelSelection(ExcelBase):
213
role=controlTypes.ROLE_TABLECELL
246
215
def __init__(self,windowHandle=None,excelWindowObject=None,excelRangeObject=None):
247
216
self.excelWindowObject=excelWindowObject
248
217
self.excelRangeObject=excelRangeObject
249
218
super(ExcelSelection,self).__init__(windowHandle=windowHandle)
220
def _get_states(self):
221
states=super(ExcelSelection,self).states
222
states.add(controlTypes.STATE_SELECTED)
251
225
def _get_name(self):
252
return _("selection")
254
def _get_value(self):
255
226
firstCell=self.excelRangeObject.Item(1)
256
227
lastCell=self.excelRangeObject.Item(self.excelRangeObject.Count)
257
228
return _("%s %s through %s %s")%(self.getCellAddress(firstCell),firstCell.Text,self.getCellAddress(lastCell),lastCell.Text)