[nvda-addons] Re: Addon for MS access code review

  • From: "Joseph Lee" <joseph.lee22590@xxxxxxxxx>
  • To: <nvda-addons@xxxxxxxxxxxxx>
  • Date: Mon, 16 Jun 2014 17:57:20 -0700

Hi,
I think you've used an older version of the app module. I've attached the
current app module code just in case you wish to base your patch with it.
Cheers,
Joseph

-----Original Message-----
From: nvda-addons-bounce@xxxxxxxxxxxxx
[mailto:nvda-addons-bounce@xxxxxxxxxxxxx] On Behalf Of Dylan Neale
Sent: Monday, June 16, 2014 5:44 PM
To: nvda-addons@xxxxxxxxxxxxx
Subject: [nvda-addons] Re: Addon for MS access code review

Hi
I've attached the file, since I don't have a bitbucket or github account
yet.



On Tue, Jun 17, 2014 at 12:28 PM, Joseph Lee <joseph.lee22590@xxxxxxxxx>
wrote:
>
> Hello,
>
> Please send the code (the py file) as an attachment to this list, or if
you have Github or Bitbucket, please tell us where to get your code so we
can fork it and give you code review.C
>
> Cheers,
>
> Joseph
>
>
>
> From: nvda-addons-bounce@xxxxxxxxxxxxx
[mailto:nvda-addons-bounce@xxxxxxxxxxxxx] On Behalf Of Dylan Neale
> Sent: Monday, June 16, 2014 4:52 PM
> To: nvda-addons@xxxxxxxxxxxxx
> Subject: [nvda-addons] Addon for MS access code review
>
>
>
> Hi
>
> This is my first attempt at improving  an addon for NVDA, and most of the
code was already written. I have made some changes, and would like to get
these reviewed before submitting them to the repo.
>
> What I've done so far is quite hacky, mainly because I'm not aware of all
the NVDA functions yet. It works with access 2013, but not sure about
others.
>
> Do I email the code to this list for review/comments or submit it
somewhere else?
>
> Thanks.
# App module for Microsoft Access
# An add-on for NVDA
# Copyright 2013 Joseph Lee and NVDA contributors, released under GPL (see 
copying.txt for more information).
# Tested with Access 2010/2013; minimum compatible version should be Access 
2007.
# JL: Most of the code is not mine - I just pitched the ideas. Thank you Access 
users and developers for encouragement and contributions.

import addonHandler
import appModuleHandler
from NVDAObjects.IAccessible import IAccessible
# Not ready for translations; please remove this flag right before public beta 
1 release.
import eventHandler
import api
import ui
from controlTypes import STATE_SELECTED

class AppModule(appModuleHandler.AppModule):
        # The app module class for Microsoft Access.

        def getColumnHeader(self):
                # Locate the parent of this row, go through column headers and 
see if one of the columns matches the focus.name.
                # Does not work properly yet - tied to extra events being fired.
                col = api.getFocusObject()
                colHeader = col.parent.parent.firstChild
                colHeaderText = ""
                for colCompare in colHeader.children:
                        if colCompare.name in col.name:
                                colHeaderText = colCompare.value
                                break
                return colHeaderText

        class AccessTableGrid(IAccessible):
                # The class for table grid. So far, handle row selection 
announcement.
                # If column header announcement works, announce this alongside 
cell coordinates.

                def event_focusEntered(self):
                        # Ignore row selection messages.
                        obj = api.getFocusObject()
                        return

        class AccessCellEditableText(IAccessible):
                # The class for the cell edit field. Since one cannot infer 
text itself, try using display model and some tricks.
                pass

        def chooseNVDAObjectOverlayClasses(self, obj, clsList):
                if obj.windowClassName == "OGrid": clsList.insert(0, 
self.AccessTableGrid)
                elif obj.windowClassName == "OKttbx": clsList.insert(0, 
self.AccessCellEditableText)





        # A number of utility functions to work with column selection.

        def isEdgeColumn(self, obj):
                # See if we're at the edge column (left-most or right-most).
                return obj.next == None or obj.previous.previous == None

        def getFirstSelectedCell(self):
                # Use linear forward search to find the first selected cell.
                finder = api.getNavigatorObject().firstChild.children[1]
                while finder != None:
                        if STATE_SELECTED in finder.states: break
                        else: finder = finder.next
                selectedCell = finder.firstChild.next
                while selectedCell != None:
                        if STATE_SELECTED in selectedCell.states: break
                        else: selectedCell = selectedCell.next
                return selectedCell

        def getLastSelectedCell(self):
                # Use reverse linear search (from last to first row) to find 
the last selected cell.
                finder = api.getNavigatorObject().firstChild.lastChild
                while finder != None:
                        if STATE_SELECTED in finder.states: break
                        else: finder = finder.previous
                selectedCell = finder.lastChild
                while selectedCell != None:
                        if STATE_SELECTED in selectedCell.states: break
                        else: selectedCell = selectedCell.previous
                return selectedCell

        # Column selection commands.

        def announceSelectedCells(self, first, last):
                selectedCell = ""
                if first == last: selectedCell = "Edge of Table: {edgeCell} 
{edgeCellContent selected".format(edgeCell = first.name, edgeCellContent = 
first.value)
                else: selectedCell = "{firstAddress} {firstContent} through 
{lastAddress} {lastContent} selected".format(firstAddress = first.name, 
firstContent = first.value, lastAddress = last.name, lastContent = last.value)
                ui.message(selectedCell)

        def script_selectRightColumn(self, gesture):
                gesture.send()
                obj = api.getNavigatorObject()
                if obj.name != "Grid":
                        self.announceSelectedCells(obj, obj) if obj.next == 
None else self.announceSelectedCells(obj, obj.next)
                else: self.announceSelectedCells(self.getFirstSelectedCell(), 
self.getLastSelectedCell())

        def script_selectLeftColumn(self, gesture):
                gesture.send()
                obj = api.getNavigatorObject()
                if obj.name != "Grid":
                        self.announceSelectedCells(obj, obj) if 
obj.previous.previous == None else self.announceSelectedCells(obj.previous, obj)
                else: self.announceSelectedCells(self.getFirstSelectedCell(), 
self.getLastSelectedCell())

        def findSuccessor(self, obj, nextCousin):
                # Next cousin tells whether we want the next row (true) or 
previous row (false).
                successor, row = obj, obj.parent.next if nextCousin else 
obj.parent.previous
                if row == None: return None
                # Retrieve the index.
                index = 0
                for i in obj.parent.children:
                        if i.name == obj.name: index = 
obj.parent.children.index(i)
                successor = row.children[index]
                return successor

        def script_selectColumnBelow(self, gesture):
                gesture.send()
                obj = api.getNavigatorObject()
                if obj.name != "Grid":
                        successor = self.findSuccessor(obj, True)
                        if obj.parent.next == None: 
self.announceSelectedCells(obj, obj)
                        if successor != None: self.announceSelectedCells(obj, 
successor)
                else: self.announceSelectedCells(self.getFirstSelectedCell(), 
self.getLastSelectedCell())

        def script_selectColumnAbove(self, gesture):
                gesture.send()
                obj = api.getNavigatorObject()
                if obj.name != "Grid":
                        successor = self.findSuccessor(obj, False)
                        if obj.parent.previous.previous == None: 
self.announceSelectedCells(obj, obj)
                        if successor != None: 
self.announceSelectedCells(successor, obj)
                else: self.announceSelectedCells(self.getFirstSelectedCell(), 
self.getLastSelectedCell())


        def script_selectColumns(self, gesture):
                gesture.send()
                ui.message("All columns selected")

        __gestures={
                "kb:shift+leftArrow":"selectLeftColumn", 
"kb:shift+rightArrow":"selectRightColumn",
                "kb:shift+upArrow":"selectColumnAbove", 
"kb:shift+downArrow":"selectColumnBelow",
                "kb:control+space":"selectColumns"
        }

Other related posts: