Index: test/keystrokes/gtk-demo/role_check_box.py
===================================================================
--- test/keystrokes/gtk-demo/role_check_box.py	(revision 3315)
+++ test/keystrokes/gtk-demo/role_check_box.py	(working copy)
@@ -48,8 +48,7 @@
     "Left resize check box unchecked Where Am I",
     ["BRAILLE LINE:  'gtk-demo Application Panes Frame Horizontal Panel < > Resize CheckBox'",
      "     VISIBLE:  '< > Resize CheckBox', cursor=1",
-     "SPEECH OUTPUT: 'Resize check box'",
-     "SPEECH OUTPUT: 'not checked'",
+     "SPEECH OUTPUT: 'Resize check box not checked'",
      "SPEECH OUTPUT: ' Alt r'"]))
 
 ########################################################################
@@ -78,8 +77,7 @@
     "Left resize check box checked Where Am I",
     ["BRAILLE LINE:  'gtk-demo Application Panes Frame Horizontal Panel <x> Resize CheckBox'",
      "     VISIBLE:  '<x> Resize CheckBox', cursor=1",
-     "SPEECH OUTPUT: 'Resize check box'",
-     "SPEECH OUTPUT: 'checked'",
+     "SPEECH OUTPUT: 'Resize check box checked'",
      "SPEECH OUTPUT: ' Alt r'"]))
 
 ########################################################################
Index: test/keystrokes/gtk-demo/role_tree_table.py
===================================================================
--- test/keystrokes/gtk-demo/role_tree_table.py	(revision 3315)
+++ test/keystrokes/gtk-demo/role_tree_table.py	(working copy)
@@ -181,17 +181,16 @@
 sequence.append(PauseAction(3000))
 sequence.append(utils.AssertPresentationAction(
     "Alex checkbox cell Where Am I",
-    ["BRAILLE LINE:  'gtk-demo Application Card planning sheet Frame ScrollPane TreeTable Alex ColumnHeader <x> Alex'",
-     "     VISIBLE:  '<x> Alex', cursor=1",
-     "SPEECH OUTPUT: ''",
-     "BUG? - checkbox state should be presented",
-     "SPEECH OUTPUT: 'cell'",
-     "SPEECH OUTPUT: 'New Years Day'",
-     "SPEECH OUTPUT: ''",
-     "SPEECH OUTPUT: ''",
-     "SPEECH OUTPUT: ''",
-     "SPEECH OUTPUT: ''",
-     "SPEECH OUTPUT: ''",
+    ["BRAILLE LINE:  'gtk-demo Application Card planning sheet Frame ScrollPane TreeTable Alex ColumnHeader <x> Alex'",
+     "     VISIBLE:  '<x> Alex', cursor=1",
+     "SPEECH OUTPUT: ''",
+     "SPEECH OUTPUT: 'cell'",
+     "SPEECH OUTPUT: 'New Years Day'",
+     "SPEECH OUTPUT: 'check box checked'",
+     "SPEECH OUTPUT: 'check box checked'",
+     "SPEECH OUTPUT: 'check box checked'",
+     "SPEECH OUTPUT: 'check box checked'",
+     "SPEECH OUTPUT: 'check box not checked'",
      "SPEECH OUTPUT: 'row 2 of 53'"]))
 
 ########################################################################
Index: src/orca/where_am_I.py
===================================================================
--- src/orca/where_am_I.py	(revision 3315)
+++ src/orca/where_am_I.py	(working copy)
@@ -157,23 +157,9 @@
         utterances = []
         text = self._getObjLabelAndName(obj) + " " + \
                rolenames.getSpeechForRoleName(obj)
+        text = text + " " + self._getCheckBoxState(obj)
         utterances.append(text)
 
-        state = obj.getState()
-        if state.contains(pyatspi.STATE_INDETERMINATE):
-            # Translators: this represents the state of a checkbox.
-            #
-            text = _("partially checked")
-        elif state.contains(pyatspi.STATE_CHECKED):
-            # Translators: this represents the state of a checkbox.
-            #
-            text = _("checked")
-        else:
-            # Translators: this represents the state of a checkbox.
-            #
-            text = _("not checked")
-        utterances.append(text)
-
         text = self._getObjMnemonic(obj)
         utterances.append(text)
 
@@ -1061,8 +1047,7 @@
         """Get the speech utterances for a single table cell.
         """
 
-        # Don't speak check box cells that area not checked.
-        notChecked = False
+        isToggle = False
         try:
             action = obj.queryAction()
         except NotImplementedError:
@@ -1070,21 +1055,54 @@
         else:
             for i in range(0, action.nActions):
                 if action.getName(i) == "toggle":
-                    state = obj.getState()
-                    if not state.contains(pyatspi.STATE_CHECKED):
-                        notChecked = True
+                    isToggle = True
                     break
 
-        if notChecked:
-            return ""
+        if isToggle:
+            text = rolenames.getSpeechForRoleName(obj, pyatspi.ROLE_CHECK_BOX)
+            text = text + " " + self._getCheckBoxState(obj)
+        else:
+            descendant = self._script.getRealActiveDescendant(obj)
+            text = self._script.getDisplayedText(descendant)
 
-        descendant = self._script.getRealActiveDescendant(obj)
-        text = self._script.getDisplayedText(descendant)
-
         debug.println(self._debugLevel, "cell=<%s>" % text)
 
         return text
 
+    def _getCheckBoxState(self, obj):
+        """Get the state of a checkbox/toggle-able table cell.
+        """
+
+        isToggle = (obj.getRole() == pyatspi.ROLE_CHECK_BOX)
+        if not isToggle:
+            try:
+                action = obj.queryAction()
+            except NotImplementedError:
+                pass
+            else:
+                for i in range(0, action.nActions):
+                    if action.getName(i) == "toggle":
+                        isToggle = True
+                        break
+        if not isToggle:
+            return ""
+
+        state = obj.getState()
+        if state.contains(pyatspi.STATE_INDETERMINATE):
+            # Translators: this represents the state of a checkbox.
+            #
+            text = _("partially checked")
+        elif state.contains(pyatspi.STATE_CHECKED):
+            # Translators: this represents the state of a checkbox.
+            #
+            text = _("checked")
+        else:
+            # Translators: this represents the state of a checkbox.
+            #
+            text = _("not checked")
+
+        return text
+
     def _getTextSelection(self, obj):
         """Get the text selection for the given object.
 
