Index: src/orca/default.py
===================================================================
--- src/orca/default.py	(revision 3496)
+++ src/orca/default.py	(working copy)
@@ -838,6 +838,8 @@
             self.onStateChanged
         listeners["object:state-changed:expanded"]          = \
             self.onStateChanged
+        listeners["object:state-changed:selected"]          = \
+            self.onStateChanged
         listeners["object:selection-changed"]               = \
             self.onSelectionChanged
         listeners["object:property-change:accessible-value"] = \
@@ -2434,6 +2436,22 @@
                 #
                 utterances.append(_("tree level %d") % (newNodeLevel + 1))
 
+            # If this is a table cell within a tree table and the item
+            # is focused but not selected, let the user know. See
+            # bug #486908 for more details.
+            #
+            state = newLocusOfFocus.getState()
+            if newLocusOfFocus.getRole() == pyatspi.ROLE_TABLE_CELL and \
+               (newLocusOfFocus.parent.getRole() == pyatspi.ROLE_TREE_TABLE or \
+                newLocusOfFocus.parent.getRole() == pyatspi.ROLE_TABLE) and \
+               not state.contains(pyatspi.STATE_SELECTED):
+                 # Translators: this is in reference to a table cell being
+                 # selected or not.
+                 #
+                 # ONLY TRANSLATE THE PART AFTER THE PIPE CHARACTER |
+                 #
+                 utterances.append(Q_("tablecell| not selected"))
+
             # We might be automatically speaking the unbound labels
             # in a dialog box as the result of the dialog box suddenly
             # appearing.  If so, don't interrupt this because of a
@@ -3155,6 +3173,30 @@
                 self.find()
                 return
 
+        if event.type.startswith("object:state-changed:selected"):
+            # If this selection state change is for the object which 
+            # currently has the locus of focus, then let the user know. 
+            # See bug #486908 for more details.
+            #
+            state = orca_state.locusOfFocus.getState()
+            if state.contains(pyatspi.STATE_FOCUSED):
+                if self.isSameObject(event.source, orca_state.locusOfFocus):
+                    if event.detail1:
+                        # Translators: this object is now selected.
+                        # Let the user know this.
+                        #
+                        # ONLY TRANSLATE THE PART AFTER THE PIPE CHARACTER |
+                        #
+                        speech.speak(Q_("text|selected"), None, False)
+                    else:
+                        # Translators: this object is now unselected.
+                        # Let the user know this.
+                        #
+                        # ONLY TRANSLATE THE PART AFTER THE PIPE CHARACTER |
+                        #
+                        speech.speak(Q_("text|unselected"), None, False)
+                    return
+
         if event.type.startswith("object:state-changed:focused"):
             iconified = False
             try:
