Index: ChangeLog
===================================================================
--- ChangeLog	(revision 2280)
+++ ChangeLog	(working copy)
@@ -1,5 +1,24 @@
 2007-04-11  Willie Walker <william.walker@sun.com>
 
+	* src/orca/scripts/gedit.py, src/orca/scripts/liferea.py,
+	src/orca/scripts/Thunderbird.py, src/orca/scripts/gaim.py,
+	src/orca/scripts/acroread.py,
+	src/orca/scripts/gnome-search-tool.py,
+	src/orca/scripts/Evolution.py, src/orca/scripts/StarOffice.py,
+	src/orca/scripts/gnome-mud.py, src/orca/scripts/users-admin.py,
+	src/orca/phonnames.py: more work on bug 412200 to clarify things
+	for translators and to fix up some ngettext and other stuff.  The
+	remaining modules for 412200 are phonnames.py,
+	pronunciation_dict.py, and orca.py.  These might be a bit tricky
+	(phonenames because other languages may have military spelling for
+	more than just a-z, and pronunciation_dict because we may want to
+	allow translators to include common things for their language), so
+	I have a couple questions into gnome-i18n.  orca.py remains because
+	I also have a question into gnome-i18n about the appropriateness 
+	of translating command line options.
+
+2007-04-11  Willie Walker <william.walker@sun.com>
+
 	* src/orca/speechgenerator.py, src/orca/settings.py: more work
 	on bug 412200 to clarify things for translators.
 	
Index: src/orca/phonnames.py
===================================================================
--- src/orca/phonnames.py	(revision 2280)
+++ src/orca/phonnames.py	(working copy)
@@ -1,6 +1,6 @@
 # Orca
 #
-# Copyright 2006 Sun Microsystems Inc.
+# Copyright 2007 Sun Microsystems Inc.
 #
 # This library is free software; you can redistribute it and/or
 # modify it under the terms of the GNU Library General Public
@@ -23,7 +23,7 @@
 __id__        = "$Id$"
 __version__   = "$Revision$"
 __date__      = "$Date$"
-__copyright__ = "Copyright (c) 2005-2006 Sun Microsystems Inc."
+__copyright__ = "Copyright (c) 2005-2007 Sun Microsystems Inc."
 __license__   = "LGPL"
 
 from orca_i18n import _ # for gettext support
@@ -33,31 +33,135 @@
 # 'military' term used for the character.
 #
 __phonnames = {}
+
+# Translators: alpha is the spoken military/phonetic spelling for the
+# letter a
+#
 __phonnames["a"] = _("alpha")
+
+# Translators: bravo is the spoken military/phonetic spelling for the
+# letter b
+#
 __phonnames["b"] = _("bravo")
+
+# Translators: charlie is the spoken military/phonetic spelling for
+# the letter c
+#
 __phonnames["c"] = _("charlie")
+
+# Translators: delta is the spoken military/phonetic spelling for the
+# letter d
+#
 __phonnames["d"] = _("delta")
+
+# Translators: echo is the spoken military/phonetic spelling for the
+# letter e
+#
 __phonnames["e"] = _("echo")
+
+# Translators: foxtrot is the spoken military/phonetic spelling for
+# the letter f
+#
 __phonnames["f"] = _("foxtrot")
+
+# Translators: golf is the spoken military/phonetic spelling for the
+# letter g
+#
 __phonnames["g"] = _("golf")
+
+# Translators: hotel is the spoken military/phonetic spelling for the
+# letter h
+#
 __phonnames["h"] = _("hotel")
+
+# Translators: india is the spoken military/phonetic spelling for the
+# letter i
+#
 __phonnames["i"] = _("india")
+
+# Translators: juliet is the spoken military/phonetic spelling for the
+# letter j
+#
 __phonnames["j"] = _("juliet")
+
+# Translators: kilo is the spoken military/phonetic spelling for the
+# letter k
+#
 __phonnames["k"] = _("kilo")
+
+# Translators: lima is the spoken military/phonetic spelling for the
+# letter l
+#
 __phonnames["l"] = _("lima")
+
+# Translators: mike is the spoken military/phonetic spelling for the
+# letter m
+#
 __phonnames["m"] = _("mike")
+
+# Translators: november is the spoken military/phonetic spelling for
+# the letter n
+#
 __phonnames["n"] = _("november")
+
+# Translators: oscar is the spoken military/phonetic spelling for the
+# letter o
+#
 __phonnames["o"] = _("oscar")
+
+# Translators: papa is the spoken military/phonetic spelling for the
+# letter p
+#
 __phonnames["p"] = _("papa")
+
+# Translators: quebec is the spoken military/phonetic spelling for the
+# letter q
+#
 __phonnames["q"] = _("quebec")
+
+# Translators: romeo is the spoken military/phonetic spelling for the
+# letter r
+#
 __phonnames["r"] = _("romeo")
+
+# Translators: sierra is the spoken military/phonetic spelling for the
+# letter s
+#
 __phonnames["s"] = _("sierra")
+
+# Translators: tango is the spoken military/phonetic spelling for the
+# letter t
+#
 __phonnames["t"] = _("tango")
+
+# Translators: uniform is the spoken military/phonetic spelling for
+# the letter u
+#
 __phonnames["u"] = _("uniform")
+
+# Translators: victor is the spoken military/phonetic spelling for the
+# letter v
+#
 __phonnames["v"] = _("victor")
+
+# Translators: whiskey is the spoken military/phonetic spelling for
+# the letter w
+#
 __phonnames["w"] = _("whiskey")
+
+# Translators: xray is the spoken military/phonetic spelling for the
+# letter x
+#
 __phonnames["x"] = _("xray")
+
+# Translators: yankee is the spoken military/phonetic spelling for the
+# letter y
+#
 __phonnames["y"] = _("yankee")
+
+# Translators: zulu is the spoken military/phonetic spelling for the
+# letter z
+#
 __phonnames["z"] = _("zulu")
 
 def getPhoneticName(character):
Index: src/orca/scripts/gnome-mud.py
===================================================================
--- src/orca/scripts/gnome-mud.py	(revision 2280)
+++ src/orca/scripts/gnome-mud.py	(working copy)
@@ -170,7 +170,7 @@
             if self.flatReviewContext:
                 self.toggleFlatReviewMode()
             message=event.any_data
-            if message and message.isspace()==False and message != "\n":
+            if message and (not message.isspace()) and message != "\n":
                 debug.println(debug.LEVEL_FINEST, \
                     message + " inserted in ringlist:")
                 self.previousMessages.append(message)
Index: src/orca/scripts/gedit.py
===================================================================
--- src/orca/scripts/gedit.py	(revision 2280)
+++ src/orca/scripts/gedit.py	(working copy)
@@ -1,6 +1,6 @@
 # Orca
 #
-# Copyright 2004-2006 Sun Microsystems Inc.
+# Copyright 2004-2007 Sun Microsystems Inc.
 #
 # This library is free software; you can redistribute it and/or
 # modify it under the terms of the GNU Library General Public
@@ -22,7 +22,7 @@
 __id__        = "$Id$"
 __version__   = "$Revision$"
 __date__      = "$Date$"
-__copyright__ = "Copyright (c) 2005-2006 Sun Microsystems Inc."
+__copyright__ = "Copyright (c) 2005-2007 Sun Microsystems Inc."
 __license__   = "LGPL"
 
 import orca.debug as debug
@@ -166,13 +166,13 @@
         while not done:
             lastEndOffset = -1
             while offset < length:
-                [str, start, end] = text.getTextAtOffset(offset,
+                [mystr, start, end] = text.getTextAtOffset(offset,
                           atspi.Accessibility.TEXT_BOUNDARY_SENTENCE_END)
 
-                if len(str) != 0:
-                    string += str
+                if len(mystr) != 0:
+                    string += mystr
 
-                if len(str) == 0 or str[len(str)-1] in '.?!':
+                if len(mystr) == 0 or mystr[len(mystr)-1] in '.?!':
                     endOffset = end
 
                     string = self.adjustForRepeats(string)
@@ -187,7 +187,7 @@
                     string = ""
                     startOffset = endOffset
 
-                if len(str) == 0:
+                if len(mystr) == 0:
                     break
                 else:
                     offset = end
@@ -249,6 +249,11 @@
         #
         allLabels = self.findByRole(panel, rolenames.ROLE_LABEL)
         for label in allLabels:
+            # Translators: these are labels from the gedit spell checking
+            # dialog and must be the same strings gedit uses.  We hate
+            # keying off stuff like this, but we're forced to do so in
+            # in this case.
+            #
             if label.name.startswith(_("Change to:")) or \
                label.name.startswith(_("Misspelled word:")):
                 continue
@@ -278,7 +283,11 @@
             # The indication that spell checking is complete is when the
             # "misspelt" word is set to "Completed spell checking". Ugh!
             # Try to detect this and let the user know.
-
+            #
+            # Translators: this string must be the same that is used by
+            # gedit.  We hate keying off stuff like this, but we're
+            # forced to do so in this case.
+            #
             if badWord == _("Completed spell checking"):
                 utterance = _("Spell checking is complete.")
                 speech.speak(utterance)
@@ -324,6 +333,11 @@
                      rolenames.ROLE_DIALOG,
                      rolenames.ROLE_APPLICATION]
 
+        # Translators: this is used to tell us if the focus is on the
+        # "Find" button in gedit's Find dialog.  It must match what
+        # gedit is using.  We hate keying off stuff like this, but
+        # we're forced to do so in this case.
+        #
         if (self.isDesiredFocusedItem(obj, rolesList1) \
             and obj.name == _("Find")) \
             or (self.isDesiredFocusedItem(obj, rolesList2) \
@@ -396,6 +410,11 @@
                      rolenames.ROLE_FRAME]
         if self.isDesiredFocusedItem(event.source, rolesList):
             frame = event.source.parent.parent.parent.parent
+            # Translators: this is the name of the "Check Spelling" window
+            # in gedit and must be the same as what gedit uses.  We hate
+            # keying off stuff like this, but we're forced to do so in this
+            # case.
+            #
             if frame.name.startswith(_("Check Spelling")):
                 debug.println(self.debugLevel,
                         "gedit.locusOfFocusChanged - check spelling dialog.")
@@ -450,6 +469,11 @@
                      rolenames.ROLE_FRAME]
         if self.isDesiredFocusedItem(event.source, rolesList):
             frame = event.source.parent.parent.parent
+            # Translators: this is the name of the "Check Spelling" window
+            # in gedit and must be the same as what gedit uses.  We hate
+            # keying off stuff like this, but we're forced to do so in this
+            # case.
+            #
             if frame.name.startswith(_("Check Spelling")):
                 debug.println(self.debugLevel,
                       "gedit.onNameChanged - check spelling dialog.")
@@ -469,6 +493,11 @@
         # apparently get two identical "object:property-change:accessible-name"
         # events.]]]
 
+        # Translators: the "Phrase not found" is the result of a failed
+        # find command.  It must be the same as what gedit uses.  We hate
+        # keying off stuff like this, but we're forced to do so in this
+        # case.
+        #
         if event.source.role == rolenames.ROLE_STATUSBAR \
            and self.isFocusOnFindDialog() \
            and orca_state.lastInputEvent.event_string == "Return" \
@@ -535,6 +564,9 @@
             [text, caretOffset, startOffset] = \
                 self.getTextLineAtCaret(event.source)
             if text.lower().find(phrase) != -1:
+                # Translators: this indicates a find command succeeded in
+                # finding something.
+                #
                 speech.speak(_("Phrase found."))
                 utterances = self.speechGenerator.getSpeech(event.source, True)
                 speech.speakUtterances(utterances)
Index: src/orca/scripts/liferea.py
===================================================================
--- src/orca/scripts/liferea.py	(revision 2280)
+++ src/orca/scripts/liferea.py	(working copy)
@@ -1,6 +1,6 @@
 # Orca
 #
-# Copyright 2005-2006 Sun Microsystems Inc.
+# Copyright 2005-2007 Sun Microsystems Inc.
 #
 # This library is free software; you can redistribute it and/or
 # modify it under the terms of the GNU Library General Public
@@ -37,7 +37,7 @@
 __id__        = "$Id:$"
 __version__   = "$Revision:$"
 __date__      = "$Date:$"
-__copyright__ = "Copyright (c) 2005-2006 Sun Microsystems Inc."
+__copyright__ = "Copyright (c) 2005-2007 Sun Microsystems Inc."
 __license__   = "LGPL"
 
 
Index: src/orca/scripts/Thunderbird.py
===================================================================
--- src/orca/scripts/Thunderbird.py	(revision 2280)
+++ src/orca/scripts/Thunderbird.py	(working copy)
@@ -33,9 +33,7 @@
 import orca.rolenames as rolenames
 import orca.settings as settings
 import orca.braille as braille
-import orca.braillegenerator as braillegenerator
 import orca.speech as speech
-import orca.speechgenerator as speechgenerator
 import orca.Gecko as Gecko
 
 from orca.orca_i18n import _
@@ -116,7 +114,7 @@
 
         # Don't speak chrome URLs.
         #
-        if obj.name.startswith(_("chrome://")):
+        if obj.name.startswith("chrome://"):
             return
 
         # This is a better fix for bug #405541. Thunderbird gives
@@ -196,7 +194,7 @@
             return
 
         if parent.name != "" \
-            and (not parent.name.startswith(_("chrome://"))) \
+            and (not parent.name.startswith("chrome://")) \
             and (parent.role == rolenames.ROLE_PANEL):
 
             # Speak the parent panel name, but only once.
@@ -204,6 +202,8 @@
             if parent.name != self._containingPanelName:
                 self._containingPanelName = parent.name
                 utterances = []
+                # Translators: this is the name of a panel in Thunderbird.
+                #
                 text = _("%s panel") % parent.name
                 utterances.append(text)
                 speech.speakUtterances(utterances)
@@ -211,7 +211,7 @@
             grandparent = parent.parent
             if grandparent \
                 and (grandparent.name != "") \
-                and (not grandparent.name.startswith(_("chrome://"))) \
+                and (not grandparent.name.startswith("chrome://")) \
                 and (grandparent.role == rolenames.ROLE_PANEL):
 
                 # Speak the grandparent panel name, but only once.
@@ -219,6 +219,8 @@
                 if grandparent.name != self._containingPanelName:
                     self._containingPanelName = grandparent.name
                     utterances = []
+                    # Translators: this is the name of a panel in Thunderbird.
+                    #
                     text = _("%s panel") % grandparent.name
                     utterances.append(text)
                     speech.speakUtterances(utterances)
Index: src/orca/scripts/gaim.py
===================================================================
--- src/orca/scripts/gaim.py	(revision 2280)
+++ src/orca/scripts/gaim.py	(working copy)
@@ -1,6 +1,6 @@
 # Orca
 #
-# Copyright 2004-2006 Sun Microsystems Inc.
+# Copyright 2004-2007 Sun Microsystems Inc.
 #
 # This library is free software; you can redistribute it and/or
 # modify it under the terms of the GNU Library General Public
@@ -30,7 +30,7 @@
 __id__        = "$Id$"
 __version__   = "$Revision$"
 __date__      = "$Date$"
-__copyright__ = "Copyright (c) 2005-2006 Sun Microsystems Inc."
+__copyright__ = "Copyright (c) 2005-2007 Sun Microsystems Inc."
 __license__   = "LGPL"
 
 import orca.atspi as atspi
@@ -213,7 +213,7 @@
         text = ""
         if self.prefixChatMessage:
             if chatRoomName and chatRoomName != "":
-                text += _("Message from chat room ") + chatRoomName + " "
+                text += _("Message from chat room %s") % chatRoomName + " "
         if message and message != "":
             text += message
 
Index: src/orca/scripts/acroread.py
===================================================================
--- src/orca/scripts/acroread.py	(revision 2280)
+++ src/orca/scripts/acroread.py	(working copy)
@@ -64,16 +64,23 @@
         self.ROLE_DOCUMENT = "Document"
         rolenames.rolenames[self.ROLE_DOCUMENT] = \
             rolenames.Rolename(self.ROLE_DOCUMENT,
+                               # Translators: short braille for the
+                               # rolename of a document.
+                               #
                                _("doc"),
+                               # Translators: long braille for the
+                               # rolename of a document.
+                               #
                                _("Document"),
+                               # Translators: spoken words for the
+                               # rolename of a document.
+                               #
                                _("document"))
 
         self.ROLE_LINK = "Link"
         rolenames.rolenames[self.ROLE_LINK] = \
-            rolenames.Rolename(self.ROLE_LINK,
-                                _("lnk"),
-                                _("Link"),
-                                _("link"))
+            rolenames.rolenames[rolenames.ROLE_LINK]
+
         # To handle the multiple, identical object:text-caret-moved events
         # and possible focus events that result from a single key press
         #
@@ -270,14 +277,20 @@
                    self.getCellCoordinates(oldFocusIsTable, oldFocus)
             [newRow, newCol] = \
                    self.getCellCoordinates(newFocusIsTable, newFocus)
+            # We can't count on being in the first/last cell
+            # of the new row -- only the first/last cell of
+            # the new row that contains data.
+            #
             if newRow != oldRow:
-                # We can't count on being in the first/last cell
-                # of the new row -- only the first/last cell of
-                # the new row that contains data.
+                # Translators: this represents the row and column we're
+                # on in a table.
                 #
                 line = _("row %d, column %d") % (newRow, newCol)
                 speech.speak(line)
             elif newCol != oldCol:
+                # Translators: this represents the column we're
+                # on in a table.
+                #
                 line = _("column %d") % newCol
                 speech.speak(line)
 
Index: src/orca/scripts/gnome-search-tool.py
===================================================================
--- src/orca/scripts/gnome-search-tool.py	(revision 2280)
+++ src/orca/scripts/gnome-search-tool.py	(working copy)
@@ -1,6 +1,6 @@
 # Orca
 #
-# Copyright 2006 Sun Microsystems Inc.
+# Copyright 2006-2007 Sun Microsystems Inc.
 #
 # This library is free software; you can redistribute it and/or
 # modify it under the terms of the GNU Library General Public
@@ -22,7 +22,7 @@
 __id__        = "$Id$"
 __version__   = "$Revision$"
 __date__      = "$Date$"
-__copyright__ = "Copyright (c) 2005-2006 Sun Microsystems Inc."
+__copyright__ = "Copyright (c) 2005-2007 Sun Microsystems Inc."
 __license__   = "LGPL"
 
 import orca.debug as debug
@@ -34,7 +34,8 @@
 import orca.speech as speech
 import orca.settings as settings
 
-from orca.orca_i18n import _ # for gettext support
+from orca.orca_i18n import _        # for gettext support
+from orca.orca_i18n import ngettext # for gettext support
 
 import time
 import gobject
@@ -84,7 +85,7 @@
         timer to go off again and repeat this process.
         """
 
-        if self.searching == False:
+        if not self.searching:
             return False
 
         currentTime = time.time()
@@ -123,6 +124,10 @@
         # search progresses, regularly inform the user of this by speaking
         # "Searching" (assuming the search tool has focus).
         #
+        # Translators: the "Stop" string must match what gnome-search-tool
+        # is using.  We hate keying off stuff like this, but we're forced
+        # to do so in this case.
+        #
         if self.isDesiredFocusedItem(event.source, rolesList) and \
            event.source.name == _("Stop") and visible:
             debug.println(self.debugLevel,
@@ -147,6 +152,10 @@
         # have just stopped a search. Inform the user that the search is
         # complete and tell them how many files were found.
         #
+        # Translators: the "Find" string must match what gnome-search-tool
+        # is using.  We hate keying off stuff like this, but we're forced
+        # to do so in this case.
+        #
         if self.isDesiredFocusedItem(event.source, rolesList) and \
            event.source.name == _("Find") and visible and self.searching:
             debug.println(self.debugLevel,
@@ -159,7 +168,10 @@
                                atspi.Accessibility.STATE_SENSITIVE)
             if sensitive:
                 fileCount = self.fileTable.table.nRows
-                speech.speak(str(fileCount) + _(" files found"))
+                noFilesString = ngettext("%d file found",
+                                         "%d files found",
+                                         fileCount) % fileCount
+                speech.speak(noFilesString)
             else:
                 speech.speak(_("No files found."))
 
Index: src/orca/scripts/Evolution.py
===================================================================
--- src/orca/scripts/Evolution.py	(revision 2280)
+++ src/orca/scripts/Evolution.py	(working copy)
@@ -1,6 +1,6 @@
 # Orca
 #
-# Copyright 2005-2006 Sun Microsystems Inc.
+# Copyright 2005-2007 Sun Microsystems Inc.
 #
 # This library is free software; you can redistribute it and/or
 # modify it under the terms of the GNU Library General Public
@@ -22,7 +22,7 @@
 __id__        = "$Id$"
 __version__   = "$Revision$"
 __date__      = "$Date$"
-__copyright__ = "Copyright (c) 2005-2006 Sun Microsystems Inc."
+__copyright__ = "Copyright (c) 2005-2007 Sun Microsystems Inc."
 __license__   = "LGPL"
 
 import orca.debug as debug
@@ -88,18 +88,31 @@
         # to Orca for Speech and Braille output.
 
         rolenames.ROLE_CALENDAR_VIEW = "Calendar View"
-        rolenames.rolenames[rolenames.ROLE_CALENDAR_VIEW] = \
-            rolenames.Rolename(rolenames.ROLE_CALENDAR_VIEW,
-                               _("calv"),
-                               _("CalendarView"),
-                               _("calendar view"))
+        rolenames.rolenames[rolenames.ROLE_CALENDAR_VIEW] = rolenames.Rolename(
+            rolenames.ROLE_CALENDAR_VIEW,
+            # Translators: short braille for the rolename of a calendar view.
+            #
+            _("calv"),
+            # Translators: long braille for the rolename of a calendar view.
+            #
+            _("CalendarView"),
+            # Translators: spoken words for the rolename of a calendar view.
+            #
+            _("calendar view"))
 
         rolenames.ROLE_CALENDAR_EVENT = "Calendar Event"
         rolenames.rolenames[rolenames.ROLE_CALENDAR_EVENT] = \
-            rolenames.Rolename(rolenames.ROLE_CALENDAR_EVENT,
-                               _("cale"),
-                               _("CalendarEvent"),
-                               _("calendar event"))
+            rolenames.Rolename(
+            rolenames.ROLE_CALENDAR_EVENT,
+            # Translators: short braille for the rolename of a calendar event.
+            #
+            _("cale"),
+            # Translators: long braille for the rolename of a calendar event.
+            #
+            _("CalendarEvent"),
+            # Translators: spoken words for the rolename of a calendar event.
+            #
+            _("calendar event"))
 
     def setupInputEventHandlers(self):
         """Defines InputEventHandler fields for this script that can be
@@ -117,6 +130,10 @@
         self.inputEventHandlers["toggleReadMailHandler"] = \
             input_event.InputEventHandler(
                 Script.toggleReadMail,
+                # Translators: this tells Orca to act like 'biff', or let
+                # the user know when new mail has arrived, even if Evolution
+                # doesn't have focus.
+                #
                 _("Toggle whether we present new mail if we are not the active script."))
 
     def getKeyBindings(self):
@@ -147,9 +164,17 @@
 
         debug.println(self.debugLevel, "Evolution.toggleReadMail.")
 
+        # Translators: this tells Orca to act like 'biff', or let
+        # the user know when new mail has arrived, even if Evolution
+        # doesn't have focus.
+        #
         line = _("present new mail if this script is not active.")
         self.presentIfInactive = not self.presentIfInactive
         if not self.presentIfInactive:
+            # Translators: this tells Orca to act like 'biff', or let
+            # the user know when new mail has arrived, even if Evolution
+            # doesn't have focus.
+            #
             line = _("do not present new mail if this script is not active.")
 
         speech.speak(line)
@@ -197,7 +222,10 @@
                         # done so.
                         #
                         if text and not self.setupLabels.has_key(label):
-                            speech.speak(text + _(" screen"), None, False)
+                            # Translators: this is the name of a setup
+                            # assistant window/screen in Evolution.
+                            #
+                            speech.speak(_("%s screen") % text, None, False)
                             self.setupLabels[label] = True
 
                             # If the locus of focus is a push button that's
@@ -226,6 +254,10 @@
                 # starts with "Welcome". For the last screen, it starts
                 # with "Congratulations". Speak those too.
                 #
+                # Translators: we regret having to do this, but the
+                # translated string here has to match what the translated
+                # string is for Evolution.
+                #
                 if text.startswith(_("Please")) or \
                     text.startswith(_("Welcome")) or \
                     text.startswith(_("Congratulations")):
@@ -338,12 +370,12 @@
             length = text.characterCount
 
             while offset <= length:
-                [str, start, end] = textObj.text.getTextAtOffset(offset,
+                [mystr, start, end] = textObj.text.getTextAtOffset(offset,
                                atspi.Accessibility.TEXT_BOUNDARY_SENTENCE_END)
-                if len(str) != 0:
-                    string += str
+                if len(mystr) != 0:
+                    string += mystr
 
-                if len(str) == 0 or str[len(str)-1] in '.?!':
+                if len(mystr) == 0 or mystr[len(mystr)-1] in '.?!':
                     endOffset = end
 
                     string = self.adjustForRepeats(string)
@@ -361,7 +393,7 @@
                     string = ""
                     startOffset = endOffset
 
-                if len(str) == 0 or end == length:
+                if len(mystr) == 0 or end == length:
                     break
                 else:
                     offset = end
@@ -408,7 +440,7 @@
 
         debug.println(self.debugLevel, "evolution.sayAll.")
         if orca_state.locusOfFocus and orca_state.locusOfFocus.text:
-            speech.sayAll(self.textLines(orca_state.locusOfFocus), 
+            speech.sayAll(self.textLines(orca_state.locusOfFocus),
                           self.__sayAllProgressCallback)
         else:
             default.Script.sayAll(self, inputEvent)
@@ -474,10 +506,10 @@
             if settings.enableSpeechIndentation:
                 self.speakTextIndentation(event.source, string)
             line = self.adjustForRepeats(string)
-                
+
             if self.speakNewLine(event.source):
                 speech.speak(chnames.getCharacterName("\n"), None, False)
- 
+
             if self.speakBlankLine(event.source):
                 # Translators: "blank" is a short word to mean the
                 # user has navigated to an empty line.
@@ -487,8 +519,8 @@
                 speech.speak(line, None, False)
 
             return
-        
 
+
         # 2) Mail view: current message pane: "standard" mail header lines.
         #
         # Check if the focus is in the From:, To:, Subject: or Date: headers
@@ -646,6 +678,11 @@
                                 checked = cell.state.count( \
                                     atspi.Accessibility.STATE_CHECKED)
                                 if speakAll:
+                                    # Translators: this is the name of the
+                                    # status column header in the message
+                                    # list in Evolution.  The name needs to
+                                    # match what Evolution is using.
+                                    #
                                     if header.name == _("Status"):
                                         toRead = not checked
                                         break
@@ -693,11 +730,25 @@
                         [cellRegions, focusedRegion] = \
                                            brailleGen.getBrailleRegions(cell)
 
+                        # Translators: this is the name of the
+                        # status column header in the message
+                        # list in Evolution.  The name needs to
+                        # match what Evolution is using.
+                        #
                         if header.name == _("Status"):
+                            # Translators: we present this to the user to
+                            # indicate that an email message has not been
+                            # marked as having been read.
+                            #
                             text = _("unread")
                             utterances = [ text ]
                             brailleRegions.append(braille.Region(text))
                             brailleRegions.append(braille.Region(" "))
+                        # Translators: this is the name of the
+                        # attachment column header in the message
+                        # list in Evolution.  The name needs to
+                        # match what Evolution is using.
+                        #
                         elif header.name == _("Attachment"):
                             text = header.name
                             utterances = [ text ]
@@ -859,6 +910,9 @@
                 brailleRegions.append(braille.Region(startTime))
                 speech.speak(startTime)
 
+                # Translators: this means there are no scheduled entries
+                # in the calendar.
+                #
                 utterance = _("No appointments")
                 speech.speak(utterance)
                 brailleRegions.append(braille.Region(utterance))
@@ -933,6 +987,10 @@
                           + "attachment dialog: unlabelled button.")
 
             brailleRegions = []
+            # Translators: this is the unlabelled arrow button near the
+            # top of the mail view Insert Attachment dialog in Evolution.
+            # We give it a name.
+            #
             utterance = _("Directories button")
             speech.speak(utterance)
             brailleRegions.append(braille.Region(utterance))
@@ -961,7 +1019,7 @@
                           + "compose window: message area.")
 
             self.message_panel = event.source.parent.parent
-            
+
             if self.speakNewLine(event.source):
                 speech.speak(chnames.getCharacterName("\n"), None, False)
 
@@ -972,7 +1030,7 @@
                 #
                 speech.speak(_("blank"), None, False)
 
-                
+
         # 9) Spell Checking Dialog
         #
         # This works in conjunction with code in section 8). Check to see if
@@ -1082,6 +1140,12 @@
 
         obj = event.source.parent
         while obj and obj.role != rolenames.ROLE_APPLICATION:
+            # Translators: this is the ending of the name of the
+            # Evolution Setup Assistant window.  The translated
+            # form has to match what Evolution is using.  We hate
+            # keying off stuff like this, but we're forced to do
+            # so in this case.
+            #
             if obj.role == rolenames.ROLE_FRAME and \
                 obj.name.endswith(_("Assistant")):
                 debug.println(self.debugLevel,
@@ -1115,7 +1179,7 @@
         if not (orca_state.lastInputEvent and \
                 orca_state.lastInputEvent.__dict__.has_key("event_string")):
             return False
-        
+
         lastKey = orca_state.lastInputEvent.event_string
         if lastKey != "Left" and lastKey != "Right":
             return False
@@ -1123,14 +1187,14 @@
         # Was a control key pressed?
         mods = orca_state.lastInputEvent.modifiers
         isControlKey = mods & (1 << atspi.Accessibility.MODIFIER_CONTROL)
-        
+
         # Get the line containing the caret
         caretOffset = text.caretOffset
         line = text.getTextAtOffset(caretOffset, \
             atspi.Accessibility.TEXT_BOUNDARY_LINE_START)
         lineStart = line[1]
         lineEnd = line[2]
-        
+
         if isControlKey:  # control-right-arrow or control-left-arrow
 
             # Get the word containing the caret.
@@ -1138,20 +1202,20 @@
                 atspi.Accessibility.TEXT_BOUNDARY_WORD_START)
             wordStart = word[1]
             wordEnd = word[2]
-            
+
             if lastKey == "Right":
                 if wordStart == lineStart:
                     return True
-            else: 
+            else:
                 if wordEnd == lineEnd:
                     return True
-                
+
         else:  # right arrow or left arrow
-            
+
             if lastKey == "Right":
                 if caretOffset == lineStart:
                     return True
-            else: 
+            else:
                 if caretOffset == lineEnd:
                     return True
 
@@ -1160,8 +1224,8 @@
         """Returns True if a blank line should be spoken.
         Otherwise, returns False.
         """
-        
-        # Get the the AccessibleText interrface. 
+
+        # Get the the AccessibleText interrface.
         text = obj.text
         if not text:
             return False
@@ -1180,7 +1244,7 @@
         else:
             return False
 
-        
+
     def onStateChanged(self, event):
         """Called whenever an object's state changes.  We are only
         interested in "object:state-changed:showing" events for any
@@ -1200,6 +1264,12 @@
             #
             obj = event.source.parent
             while obj and obj.role != rolenames.ROLE_APPLICATION:
+                # Translators: this is the ending of the name of the
+                # Evolution Setup Assistant window.  The translated
+                # form has to match what Evolution is using.  We hate
+                # keying off stuff like this, but we're forced to do
+                # so in this case.
+                #
                 if obj.role == rolenames.ROLE_FRAME and \
                     obj.name.endswith(_("Assistant")):
                     debug.println(self.debugLevel,
Index: src/orca/scripts/StarOffice.py
===================================================================
--- src/orca/scripts/StarOffice.py	(revision 2280)
+++ src/orca/scripts/StarOffice.py	(working copy)
@@ -1,6 +1,6 @@
 # Orca
 #
-# Copyright 2005-2006 Sun Microsystems Inc.
+# Copyright 2005-2007 Sun Microsystems Inc.
 #
 # This library is free software; you can redistribute it and/or
 # modify it under the terms of the GNU Library General Public
@@ -22,7 +22,7 @@
 __id__        = "$Id$"
 __version__   = "$Revision$"
 __date__      = "$Date$"
-__copyright__ = "Copyright (c) 2005-2006 Sun Microsystems Inc."
+__copyright__ = "Copyright (c) 2005-2007 Sun Microsystems Inc."
 __license__   = "LGPL"
 
 import orca.debug as debug
@@ -75,11 +75,18 @@
         """
 
         utterances = []
-        utterances.append(_("Cell"))
+        utterances.append(_("cell"))
 
         table = obj.parent.table
+
+        # Translators: this represents the column we're
+        # on in a table.
+        #
         text = _("column %d") % (table.getColumnAtIndex(obj.index) + 1)
         utterances.append(text)
+
+        # Translators: this represents the row number of a table.
+        #
         text = _("row %d") % (table.getRowAtIndex(obj.index) + 1)
         utterances.append(text)
 
@@ -106,7 +113,7 @@
         """
 
         utterances = []
-        utterances.append(_("Cell"))
+        utterances.append(_("cell"))
 
         # No way to get cell coordinates?
 
@@ -129,7 +136,7 @@
         """Returns the Calc frame and sheet
         """
 
-        list = [None, None]
+        mylist = [None, None]
 
         parent = obj.parent
         while parent and (parent.parent != parent):
@@ -137,12 +144,12 @@
             #               "_getCalcFrameAndSheet: parent=%s, %s" % \
             #               (parent.role, self._getObjLabelAndName(parent)))
             if parent.role == rolenames.ROLE_FRAME:
-                list[0] = parent
+                mylist[0] = parent
             if parent.role == rolenames.ROLE_TABLE:
-                list[1] = parent
+                mylist[1] = parent
             parent = parent.parent
 
-        return list
+        return mylist
 
     def _speakCalcStatusBar(self):
         """Speaks the OpenOffice Calc statusbar.
@@ -154,7 +161,7 @@
         utterances = []
         for i in range(0, self._statusBar.childCount):
             child = self._statusBar.child(i)
-            text = _("%s") % self._getObjName(child)
+            text = self._getObjName(child)
             utterances.append(text)
 
         debug.println(self._debugLevel, "Calc statusbar utterances=%s" % \
@@ -177,19 +184,19 @@
 
         utterances = []
 
-        list = self._getCalcFrameAndSheet(obj)
+        mylist = self._getCalcFrameAndSheet(obj)
         if doubleClick:
-            if list[0]:
+            if mylist[0]:
                 self._statusBar = None
-                self._getStatusBar(list[0])
+                self._getStatusBar(mylist[0])
                 if self._statusBar:
                     self._speakCalcStatusBar()
         else:
-            if list[0]:
-                text = self._getObjLabelAndName(list[0])
+            if mylist[0]:
+                text = self._getObjLabelAndName(mylist[0])
                 utterances.append(text)
-            if list[1]:
-                text = self._getObjLabelAndName(list[1])
+            if mylist[1]:
+                text = self._getObjLabelAndName(mylist[1])
                 utterances.append(text)
 
             debug.println(self._debugLevel,
@@ -348,7 +355,7 @@
 
             # If the spread sheet table cell has something in it, then we
             # want to append the name of the cell (which will be its location).
-            # Note that if the cell was empty, then 
+            # Note that if the cell was empty, then
             # self._script.getDisplayedText will have already done this for us.
             #
             if obj.text:
@@ -363,7 +370,7 @@
             # just one (or none), then pass it on to the superclass to be
             # processed.
             #
-            # If it's more than one, then get the braille regions for each 
+            # If it's more than one, then get the braille regions for each
             # child, and call this method again.
             #
             if obj.childCount <= 1:
@@ -483,7 +490,7 @@
                parent.lastRow != parent.table.getRowAtIndex(obj.index):
                 if self._script.dynamicRowHeaders.has_key(table):
                     column = self._script.dynamicRowHeaders[table]
-                    header = self._script.getDynamicColumnHeaderCell(obj, 
+                    header = self._script.getDynamicColumnHeaderCell(obj,
                                                                      column)
                     if header.childCount > 0:
                         for i in range(0, header.childCount):
@@ -564,7 +571,7 @@
             utterances.append(nameList[1])
         else:
             # Check to see how many children this table cell has. If it's
-            # just one (or none), then pass it on to the superclass to be 
+            # just one (or none), then pass it on to the superclass to be
             # processed.
             #
             # If it's more than one, then get the speech for each child,
@@ -703,7 +710,7 @@
 
         # [[[TODO: JD - HACK because we won't get events from toggle
         # buttons on the Formatting toolbar until we "tickle/poke"
-        # the hierarchy. But we only want to do it once.  
+        # the hierarchy. But we only want to do it once.
         # See bug #363830 and OOo issue #70872.]]]
         #
         self.tickled = None
@@ -738,16 +745,25 @@
         self.inputEventHandlers["speakInputLineHandler"] = \
             input_event.InputEventHandler(
                 Script.speakInputLine,
+                # Translators: this is the input line of a spreadsheet
+                # (i.e., the place where enter formulas)
+                #
                 _("Speaks the contents of the input line."))
 
         self.inputEventHandlers["setDynamicColumnHeadersHandler"] = \
             input_event.InputEventHandler(
                 Script.setDynamicColumnHeaders,
+                # Translators: Orca allows you to dynamically define which
+                # row of a spreadsheet or table counts as column headers.
+                #
                 _("Set the row to use as dynamic column headers when speaking calc cells."))
 
         self.inputEventHandlers["setDynamicRowHeadersHandler"] = \
             input_event.InputEventHandler(
                 Script.setDynamicRowHeaders,
+                # Translators: Orca allows you to dynamically define which
+                # column of a spreadsheet or table counts as row headers.
+                #
                 _("Set the column to use as dynamic row headers to use when speaking calc cells."))
 
     def getKeyBindings(self):
@@ -783,14 +799,14 @@
         return keyBindings
 
     def adjustForWriterTable(self, obj):
-        """Check to see if we are in Writer, where the object with focus 
-        is a paragraph, and the parent is the table cell. If it is, then, 
+        """Check to see if we are in Writer, where the object with focus
+        is a paragraph, and the parent is the table cell. If it is, then,
         return the parent table cell otherwise return the current object.
 
         Arguments:
         - obj: the accessible object to check.
 
-        Returns parent table cell (if in a Writer table ) or the current 
+        Returns parent table cell (if in a Writer table ) or the current
         object.
         """
 
@@ -818,14 +834,14 @@
         return table
 
     def getDynamicColumnHeaderCell(self, obj, column):
-        """Given a table cell, return the dynamic column header cell 
+        """Given a table cell, return the dynamic column header cell
         associated with it.
 
         Arguments:
         - obj: the table cell.
         - column: the column that this dynamic header is on.
 
-        Return the dynamic column header cell associated with the given 
+        Return the dynamic column header cell associated with the given
         table cell.
         """
 
@@ -840,14 +856,14 @@
         return accCell
 
     def getDynamicRowHeaderCell(self, obj, row):
-        """Given a table cell, return the dynamic row header cell 
+        """Given a table cell, return the dynamic row header cell
         associated with it.
 
         Arguments:
         - obj: the table cell.
         - row: the row that this dynamic header is on.
 
-        Return the dynamic row header cell associated with the given 
+        Return the dynamic row header cell associated with the given
         table cell.
         """
 
@@ -858,7 +874,7 @@
             column = parent.table.getColumnAtIndex(obj.index)
             cell = parent.table.getAccessibleAt(row, column)
             accCell = atspi.Accessible.makeAccessible(cell)
-    
+
         return accCell
 
     def locateInputLine(self, obj):
@@ -875,7 +891,7 @@
         Returns the spread sheet input line component.
         """
 
-        inputLine = None 
+        inputLine = None
         panel = obj.parent.parent.parent.parent
         if panel and panel.role == rolenames.ROLE_PANEL:
             allParagraphs = self.findByRole(panel, rolenames.ROLE_PARAGRAPH)
@@ -884,7 +900,7 @@
             else:
                 debug.println(debug.LEVEL_SEVERE,
                     "StarOffice: locateInputLine: incorrect paragraph count.")
-        else: 
+        else:
             debug.println(debug.LEVEL_SEVERE,
                   "StarOffice: locateInputLine: couldn't find common panel.")
 
@@ -916,6 +932,12 @@
             #
             current = obj.parent
             while current.role != rolenames.ROLE_APPLICATION:
+                # Translators: this represents a match on a window title.
+                # We're looking for frame that ends in "Calc", representing
+                # an OpenOffice or StarOffice spreadsheet window.  We
+                # really try to avoid doing this kind of thing, but sometimes
+                # it is necessary and we apologize.
+                #
                 if current.role == rolenames.ROLE_FRAME and \
                    (current.name and current.name.endswith(_("Calc"))):
                     found = True
@@ -936,12 +958,12 @@
         if oldFocus == None or newFocus == None:
             return
 
-        oldFocusIsTable = None 
+        oldFocusIsTable = None
         while oldFocus.role != rolenames.ROLE_APPLICATION:
             if oldFocus.role == rolenames.ROLE_TABLE:
                 oldFocusIsTable = oldFocus
                 break
-            oldFocus = oldFocus.parent 
+            oldFocus = oldFocus.parent
 
         newFocusIsTable = None
         while newFocus.role != rolenames.ROLE_APPLICATION:
@@ -953,9 +975,13 @@
         if oldFocusIsTable == None and newFocusIsTable != None:
             rows = newFocusIsTable.table.nRows
             columns = newFocusIsTable.table.nColumns
+            # We've entered a table.  Announce the dimensions.
+            #
             line = _("table with %d rows and %d columns.") % (rows, columns)
             speech.speak(line)
         elif oldFocusIsTable != None and newFocusIsTable == None:
+            # We've left a table.  Announce this fact.
+            #
             speech.speak(_("leaving table."))
 
     def speakInputLine(self, inputEvent):
@@ -978,6 +1004,9 @@
             if self.inputLineForCell and self.inputLineForCell.text:
                 inputLine = self.getText(self.inputLineForCell, 0, -1)
                 if not inputLine:
+                    # Translators: this is used to announce that the
+                    # current input line in a spreadsheet is blank/empty.
+                    #
                     inputLine = _("empty")
                 debug.println(self.debugLevel,
                         "StarOffice.speakInputLine: contents: %s" % inputLine)
@@ -1045,6 +1074,9 @@
             if clickCount == 2:
                 try:
                     del self.dynamicColumnHeaders[table]
+                    # Translators: Orca allows you to dynamically define which
+                    # row of a spreadsheet or table counts as column headers.
+                    #
                     line = _("Dynamic column header cleared.")
                     speech.speak(line)
                     braille.displayMessage(line)
@@ -1052,6 +1084,9 @@
                     pass
             else:
                 self.dynamicColumnHeaders[table] = row
+                # Translators: Orca allows you to dynamically define which
+                # row of a spreadsheet or table counts as column headers.
+                #
                 line = _("Dynamic column header set for row ") + str(row+1)
                 speech.speak(line)
                 braille.displayMessage(line)
@@ -1106,6 +1141,9 @@
             if clickCount == 2:
                 try:
                     del self.dynamicRowHeaders[table]
+                    # Translators: Orca allows you to dynamically define which
+                    # column of a spreadsheet or table counts as row headers.
+                    #
                     line = _("Dynamic row header cleared.")
                     speech.speak(line)
                     braille.displayMessage(line)
@@ -1113,8 +1151,11 @@
                     pass
             else:
                 self.dynamicRowHeaders[table] = column
-                line = _("Dynamic row header set for column %s") % \
-                       self.columnConvert(column+1)
+                # Translators: Orca allows you to dynamically define which
+                # column of a spreadsheet or table counts as row headers.
+                #
+                line = _("Dynamic row header set for column %s") \
+                       % self.columnConvert(column+1)
                 speech.speak(line)
                 braille.displayMessage(line)
 
@@ -1258,6 +1299,12 @@
 
         found = False
         while obj and obj.role != rolenames.ROLE_APPLICATION:
+            # Translators: this is the title of the window that
+            # you get when starting StarOffice.  The translated
+            # form has to match what StarOffice/OpenOffice is
+            # using.  We hate keying off stuff like this, but
+            # we're forced to do so in this case.
+            #
             if obj.role == rolenames.ROLE_DIALOG and \
                 (obj.name and obj.name.startswith(_("Welcome to StarOffice"))):
                 debug.println(self.debugLevel,
@@ -1318,7 +1365,7 @@
 
         # 0) Writer: find command
         #
-        # Check to see if this is this is for the find command. See 
+        # Check to see if this is this is for the find command. See
         # comment #18 of bug #354463.
         #
         if self.findCommandRun and \
@@ -1353,6 +1400,13 @@
             result = self.getTextLineAtCaret(event.source)
             result[0] = result[0].decode("UTF-8")
 
+            # Translators: this is the name of the menu item people
+            # use in StarOffice to create a new text document.  It's
+            # at File->New->Text Document.  The translated form has to
+            # match what StarOffice/OpenOffice is using. We hate
+            # keying off stuff like this, but we're forced to do so in
+            # this case.
+            #
             if oldLocusOfFocus.role == rolenames.ROLE_MENU_ITEM and \
                oldLocusOfFocus.name == _("Text Document") and \
                len(result[0]) == 0:
@@ -1414,6 +1468,12 @@
                      rolenames.ROLE_APPLICATION]
         if self.isDesiredFocusedItem(event.source, rolesList):
             pane = event.source.parent
+            # Translators: this is what the name of spell checking
+            # window in StarOffice begins with.  The translated form
+            # has to match what StarOffice/OpenOffice is using.  We
+            # hate keying off stuff like this, but we're forced to do
+            # so in this case.
+            #
             if pane.name.startswith(_("Spellcheck:")):
                 debug.println(self.debugLevel,
                     "StarOffice.locusOfFocusChanged - " \
@@ -1478,6 +1538,12 @@
                         rolenames.ROLE_OPTION_PANE, \
                         rolenames.ROLE_DIALOG, \
                         rolenames.ROLE_APPLICATION]
+            # Translators: this is the name of the field in the StarOffice
+            # setup dialog that is asking for the first name of the user.
+            # The translated form has to match what StarOffice/OpenOffice
+            # is using.  We hate keying off stuff like this, but we're
+            # forced to in this case.
+            #
             if self.isDesiredFocusedItem(event.source, rolesList) and \
                event.source.name == _("First name"):
                 debug.println(self.debugLevel,
@@ -1534,7 +1600,7 @@
         #
         # Check to see if the focus has just moved to the Name Box combo
         # box in Calc. If so, then replace the non-existent name with a
-        # simple one before falling through and calling the default 
+        # simple one before falling through and calling the default
         # locusOfFocusChanged method, which in turn will result in our
         # _getSpeechForComboBox() method being called.
         #
@@ -1549,7 +1615,10 @@
             and (not event.source.name or len(event.source.name) == 0):
             debug.println(self.debugLevel, "StarOffice.locusOfFocusChanged - " \
                           + "Calc: name box.")
-
+            # Translators: this is our made up name for the nameless field
+            # in StarOffice/OpenOffice calc that allows you to type in a
+            # cell coordinate (e.g., A4) and then move to it.
+            #
             event.source.name = _("Move to cell")
 
         # Pass the event onto the parent class to be handled in the default way.
@@ -1635,6 +1704,12 @@
                      rolenames.ROLE_APPLICATION]
         if self.isDesiredFocusedItem(event.source, rolesList):
             pane = event.source
+            # Translators: this is what the name of spell checking
+            # window in StarOffice begins with.  The translated form
+            # has to match what StarOffice/OpenOffice is using.  We
+            # hate keying off stuff like this, but we're forced to do
+            # so in this case.
+            #
             if pane.name.startswith(_("Spellcheck:")):
                 debug.println(self.debugLevel,
                       "StarOffice.onNameChanged - Writer: spell check dialog.")
@@ -1649,10 +1724,10 @@
 
 
     def onFocus(self, event):
-        """Called whenever an object gets focus. Overridden in this script 
-        so that we can adjust "focus:" events for children of a combo-box 
-        to just set the focus to the combo box. This is needed to help 
-        reduce the verbosity of focusing on the Calc Name combo box (see 
+        """Called whenever an object gets focus. Overridden in this script
+        so that we can adjust "focus:" events for children of a combo-box
+        to just set the focus to the combo box. This is needed to help
+        reduce the verbosity of focusing on the Calc Name combo box (see
         bug #364407).
 
         Arguments:
@@ -1684,15 +1759,22 @@
         - event: the Event
         """
 
-        # If this is a state change "focused" event that we care about, and 
+        # If this is a state change "focused" event that we care about, and
         # we are in Writer, check to see if we are entering or leaving a table.
         #
         if event.type == "object:state-changed:focused" and event.detail1 == 1:
             current = event.source.parent
             while current.role != rolenames.ROLE_APPLICATION:
+                # Translators: this is the title of the window that
+                # you get when using StarOffice Writer.  The
+                # translated form has to match what
+                # StarOffice/OpenOffice is using.  We hate keying off
+                # stuff like this, but we're forced to do so in this
+                # case.
+                #
                 if current.role == rolenames.ROLE_FRAME and \
                    (current.name and current.name.endswith(_("Writer"))):
-                    self.checkForTableBoundry(orca_state.locusOfFocus, 
+                    self.checkForTableBoundry(orca_state.locusOfFocus,
                                               event.source)
                     break
                 current = current.parent
@@ -1726,7 +1808,7 @@
                 weToggledIt = event.source.component.contains(x, y, 0)
 
             elif isinstance(orca_state.lastInputEvent, input_event.KeyboardEvent):
-                keyString = orca_state.lastInputEvent.event_string  
+                keyString = orca_state.lastInputEvent.event_string
                 navKeys = ["Up", "Down", "Page_Up", "Page_Down", "Home", "End"]
                 wasCommand = orca_state.lastInputEvent.modifiers \
                              & (1 << atspi.Accessibility.MODIFIER_CONTROL \
@@ -1774,7 +1856,7 @@
         # (in the form of object:state-changed:focused
         # instead of focus:). The second is a caret-moved
         # event. Just set the locusOfFocus for the first event.
-        # 
+        #
         if event.type == "object:state-changed:focused" and \
            event.source.role == rolenames.ROLE_PARAGRAPH and \
            event.source != self.currentParagraph:
@@ -1782,9 +1864,9 @@
             orca.setLocusOfFocus(event, event.source, False)
             return
 
-        # If we get "object:state-changed:focused" events for children of 
-        # a combo-box, just set the focus to the combo box. This is needed 
-        # to help reduce the verbosity of focusing on the Calc Name combo 
+        # If we get "object:state-changed:focused" events for children of
+        # a combo-box, just set the focus to the combo box. This is needed
+        # to help reduce the verbosity of focusing on the Calc Name combo
         # box (see bug #364407).
         #
         if event.source.parent and \
@@ -1845,18 +1927,21 @@
                             if self.inputLineForCell and \
                                self.inputLineForCell.text:
                                 inputLine = self.getText(self.inputLineForCell,0,-1)
-                                if inputLine and \
-                                    (len(inputLine) > 1) and \
-                                    (inputLine[0] == "="):
-                                        hf = _(" has formula")
-                                        speech.speak(hf, None, False)
+                                if inputLine and (len(inputLine) > 1) \
+                                    and (inputLine[0] == "="):
+                                    # Translators: this means a particular
+                                    # cell in a spreadsheet has a formula
+                                    # (e.g., "=sum(a1:d1)")
+                                    #
+                                    hf = " " + _("has formula")
+                                    speech.speak(hf, None, False)
 
-                                        line = braille.getShowingLine()
-                                        line.addRegion(braille.Region(hf))
-                                        braille.refresh()
-                                        #
-                                        # Fall-thru to process the event with
-                                        # the default handler.
+                                    line = braille.getShowingLine()
+                                    line.addRegion(braille.Region(hf))
+                                    braille.refresh()
+                                    #
+                                    # Fall-thru to process the event with
+                                    # the default handler.
 
         default.Script.onSelectionChanged(self, event)
 
@@ -1894,7 +1979,9 @@
         - name: the name of the cell
         """
 
-        line = _("Cell ") + name
+        # Translators: this is the name of a cell in a spreadsheet.
+        #
+        line = _("Cell %s") % name
         speech.speak(line)
 
     def onCaretMoved(self, event):
@@ -1905,8 +1992,8 @@
         """
 
         # If we are FOCUSED on a paragraph inside a table cell (in Writer),
-        # then just return (modulo the special cases below). Speaking and 
-        # brailling will have been done in the onStateChanged() routine 
+        # then just return (modulo the special cases below). Speaking and
+        # brailling will have been done in the onStateChanged() routine
         # (see bug #382415).
         #
         if event.source.role == rolenames.ROLE_PARAGRAPH and \
@@ -1919,7 +2006,7 @@
             # just return.
             #
             if (event_string == "Up" or event_string == "Down"):
-                if settings.readTableCellRow == False:
+                if not settings.readTableCellRow:
                     if event.detail1 != -1:
                         self.speakCellName(event.source.parent.name)
                 return
@@ -1934,9 +2021,9 @@
             caretOffset = event.source.text.caretOffset
             len = event.source.text.characterCount
 
-            # If you are in a table cell and you arrow Right, the caret 
-            # will focus at the end of the current paragraph before moving 
-            # into the next cell. To be similar to the way that caret 
+            # If you are in a table cell and you arrow Right, the caret
+            # will focus at the end of the current paragraph before moving
+            # into the next cell. To be similar to the way that caret
             # navigation works in other paragraphs in OOo, just return.
             #
             if event_string == "Right" and caretOffset == len:
@@ -1945,14 +2032,14 @@
             # If we have moved left and the caret position is at the end of
             # the paragraph or if we have moved right and the caret position
             # is at the start of the text string, or the last key input was
-            # Tab or Shift-Tab, and if we are speaking-by-cell (as opposed 
-            # to by-row), then speak the cell name, otherwise just return 
+            # Tab or Shift-Tab, and if we are speaking-by-cell (as opposed
+            # to by-row), then speak the cell name, otherwise just return
             # (see bug #382418).
             #
             if (event_string == "Left" and caretOffset == len) or \
                (event_string == "Right" and caretOffset == 0) or \
                (event_string == "Tab" or event_string == "ISO_Left_Tab"):
-                if settings.readTableCellRow == False:
+                if not settings.readTableCellRow:
                     if event.detail1 != -1:
                         self.speakCellName(event.source.parent.name)
 
@@ -1992,7 +2079,7 @@
         if not (orca_state.lastInputEvent and \
                 orca_state.lastInputEvent.__dict__.has_key("event_string")):
             return False
-        
+
         lastKey = orca_state.lastInputEvent.event_string
         if lastKey != "Left" and lastKey != "Right":
             return False
@@ -2000,7 +2087,7 @@
         # Was a control key pressed?
         mods = orca_state.lastInputEvent.modifiers
         isControlKey = mods & (1 << atspi.Accessibility.MODIFIER_CONTROL)
-        
+
         # Get the line containing the caret
         caretOffset = text.caretOffset
         line = text.getTextAtOffset(caretOffset, \
@@ -2015,20 +2102,20 @@
                 atspi.Accessibility.TEXT_BOUNDARY_WORD_START)
             wordStart = word[1]
             wordEnd = word[2]
-            
+
             if lastKey == "Right":
                 if wordStart == lineStart:
                     return True
-            else: 
+            else:
                 if wordEnd == lineEnd:
                     return True
-                
+
         else:  # right arrow or left arrow
-            
+
             if lastKey == "Right":
                 if caretOffset == lineStart:
                     return True
-            else: 
+            else:
                 if caretOffset == lineEnd:
                     return True
 
@@ -2039,8 +2126,8 @@
         """Returns True if a blank line should be spoken.
         Otherwise, returns False.
         """
-        
-        # Get the the AccessibleText interrface. 
+
+        # Get the the AccessibleText interrface.
         text = obj.text
         if not text:
             return False
@@ -2069,7 +2156,7 @@
         # will return without speaking the text that was pasted.
         #
         text = event.any_data
-        if isinstance(orca_state.lastInputEvent, 
+        if isinstance(orca_state.lastInputEvent,
                         input_event.MouseButtonEvent) and \
              orca_state.lastInputEvent.button == "2":
             if text.isupper():
Index: src/orca/scripts/users-admin.py
===================================================================
--- src/orca/scripts/users-admin.py	(revision 2280)
+++ src/orca/scripts/users-admin.py	(working copy)
@@ -127,7 +127,7 @@
                 i -= 1
         else:
             utterances = speechGen._getSpeechForTableCell(self, \
-                           self.getRealActiveDescendant(obj), already_focused)
+                self._script.getRealActiveDescendant(obj), already_focused)
 
         return utterances
 
