Index: test/harness/utils.py
===================================================================
--- test/harness/utils.py	(revision 4130)
+++ test/harness/utils.py	(working copy)
@@ -30,7 +30,8 @@
 
 #OOO_VERSION="OpenOffice 2.4"
 #OOO_VERSION="StarOffice 8"
-OOO_VERSION="DEV300_m25"
+#OOO_VERSION="DEV300_m25"
+OOO_VERSION="DEV300_m29"
 
 def getOOoName(app):
     if OOO_VERSION == "OpenOffice 2.4":
@@ -39,6 +40,8 @@
         return "StarOffice %s" % app
     elif OOO_VERSION == "DEV300_m25":
         return "OOo-dev %s Beta" % app
+    elif OOO_VERSION == "DEV300_m29":
+        return "OOo-dev %s" % app
         
 def getOOoBrailleLine(app, title, remainder):
     if OOO_VERSION == "OpenOffice 2.4":
@@ -47,6 +50,8 @@
         return "soffice Application " + title + " - StarOffice " + app + " Frame " +  title + " - StarOffice " + app + " RootPane ScrollPane Document view " + remainder
     elif OOO_VERSION == "DEV300_m25":
         return "soffice Application " + title + " - OOo-dev " + app + " Beta Frame " +  title + " - OOo-dev " + app + " Beta RootPane ScrollPane Document view " + remainder
+    elif OOO_VERSION == "DEV300_m29":
+        return "soffice Application " + title + " - OOo-dev " + app + " Frame " +  title + " - OOo-dev " + app + " RootPane ScrollPane Document view " + remainder
 
 createDiffs = True
 try:
Index: test/keystrokes/oowriter/bug_384893.py
===================================================================
--- test/keystrokes/oowriter/bug_384893.py	(revision 4130)
+++ test/keystrokes/oowriter/bug_384893.py	(working copy)
@@ -55,9 +55,9 @@
 # 5. Enter Insert-f to get text information on the underlined word.
 #
 sequence.append(utils.StartRecordingAction())
-sequence.append(KeyPressAction (0, 106,"Insert"))      # Press Insert
+sequence.append(KeyPressAction(0, None, "KP_Insert"))
 sequence.append(TypeAction ("f"))
-sequence.append(KeyReleaseAction(150, 106,"Insert"))   # Release Insert
+sequence.append(KeyReleaseAction(0, None, "KP_Insert"))
 sequence.append(utils.AssertPresentationAction(
     "Enter Insert-f to get text information on the underlined word",
     ["SPEECH OUTPUT: 'size 12'",
@@ -76,9 +76,9 @@
 # 7. Enter Insert-f to get text information on the bold word. 
 #
 sequence.append(utils.StartRecordingAction())
-sequence.append(KeyPressAction (0, 106,"Insert"))      # Press Insert
+sequence.append(KeyPressAction(0, None, "KP_Insert"))
 sequence.append(TypeAction ("f"))
-sequence.append(KeyReleaseAction(150, 106,"Insert"))   # Release Insert
+sequence.append(KeyReleaseAction(0, None, "KP_Insert"))
 sequence.append(utils.AssertPresentationAction(
     "Enter Insert-f to get text information on the bold word",
     ["SPEECH OUTPUT: 'size 12'",
Index: test/keystrokes/oowriter/bug_435201.py
===================================================================
--- test/keystrokes/oowriter/bug_435201.py	(revision 4130)
+++ test/keystrokes/oowriter/bug_435201.py	(working copy)
@@ -31,13 +31,13 @@
 sequence.append(utils.AssertPresentationAction(
     "Type Control-down to move to the next paragraph [1]",
     ["BUG: speaks the paragraph three times",
-     "BRAILLE LINE:  '" + utils.getOOoBrailleLine("Writer", "spanish", "NOBODY expects the Spanish Inquisition! Our chief weapon is surprise. Surprise and  \$l") + "'",
+     "BRAILLE LINE:  '" + utils.getOOoBrailleLine("Writer", "spanish(.odt|)", "NOBODY expects the Spanish Inquisition! Our chief weapon is surprise. Surprise and  \$l") + "'",
      "     VISIBLE:  'NOBODY expects the Spanish Inqui', cursor=2",
-     "BRAILLE LINE:  '" + utils.getOOoBrailleLine("Writer", "spanish", "NOBODY expects the Spanish Inquisition! Our chief weapon is surprise. Surprise and  \$l") + "'",
+     "BRAILLE LINE:  '" + utils.getOOoBrailleLine("Writer", "spanish(.odt|)", "NOBODY expects the Spanish Inquisition! Our chief weapon is surprise. Surprise and  \$l") + "'",
      "     VISIBLE:  'NOBODY expects the Spanish Inqui', cursor=1",
      "BRAILLE LINE:  'NOBODY expects the Spanish Inquisition! Our chief weapon is surprise. Surprise and  $l'",
      "     VISIBLE:  'NOBODY expects the Spanish Inqui', cursor=1",
-     "BRAILLE LINE:  '" + utils.getOOoBrailleLine("Writer", "spanish", "NOBODY expects the Spanish Inquisition! Amongst our weaponry are such diverse  \$l") + "'",
+     "BRAILLE LINE:  '" + utils.getOOoBrailleLine("Writer", "spanish(.odt|)", "NOBODY expects the Spanish Inquisition! Amongst our weaponry are such diverse  \$l") + "'",
      "     VISIBLE:  'NOBODY expects the Spanish Inqui', cursor=1",
      "SPEECH OUTPUT: 'NOBODY expects the Spanish Inquisition! Our chief weapon is surprise. Surprise and '",
      "SPEECH OUTPUT: 'NOBODY expects the Spanish Inquisition! Our chief weapon is surprise. Surprise and '",
@@ -52,13 +52,13 @@
 sequence.append(utils.AssertPresentationAction(
     "Type Control-down to move to the next paragraph [2]",
     ["BUG: speaks the paragraph two times",
-     "BRAILLE LINE:  '" + utils.getOOoBrailleLine("Writer", "spanish", "NOBODY expects the Spanish Inquisition! Amongst our weaponry are such diverse  \$l") + "'",
+     "BRAILLE LINE:  '" + utils.getOOoBrailleLine("Writer", "spanish(.odt|)", "NOBODY expects the Spanish Inquisition! Amongst our weaponry are such diverse  \$l") + "'",
      "     VISIBLE:  'NOBODY expects the Spanish Inqui', cursor=2",
-     "BRAILLE LINE:  '" + utils.getOOoBrailleLine("Writer", "spanish", "NOBODY expects the Spanish Inquisition! Amongst our weaponry are such diverse  \$l") + "'",
+     "BRAILLE LINE:  '" + utils.getOOoBrailleLine("Writer", "spanish(.odt|)", "NOBODY expects the Spanish Inquisition! Amongst our weaponry are such diverse  \$l") + "'",
      "     VISIBLE:  'NOBODY expects the Spanish Inqui', cursor=1",
      "BRAILLE LINE:  'NOBODY expects the Spanish Inquisition! Amongst our weaponry are such diverse  $l'",
      "     VISIBLE:  'NOBODY expects the Spanish Inqui', cursor=1",
-     "BRAILLE LINE:  '" + utils.getOOoBrailleLine("Writer", "spanish", " \$l") + "'",
+     "BRAILLE LINE:  '" + utils.getOOoBrailleLine("Writer", "spanish(.odt|)", " \$l") + "'",
      "     VISIBLE:  ' $l', cursor=1",
      "SPEECH OUTPUT: 'NOBODY expects the Spanish Inquisition! Amongst our weaponry are such diverse '",
      "SPEECH OUTPUT: 'NOBODY expects the Spanish Inquisition! Amongst our weaponry are such diverse '",
@@ -73,15 +73,15 @@
 sequence.append(utils.AssertPresentationAction(
     "Type Control-down to move to the next paragraph [3]",
     ["BUG: speaks the paragraph two times",
-     "BRAILLE LINE:  '" + utils.getOOoBrailleLine("Writer", "spanish", "Now old lady, you have one last chance.  Confess the heinous sin of heresy, reject  \$l") + "'",
+     "BRAILLE LINE:  '" + utils.getOOoBrailleLine("Writer", "spanish(.odt|)", "Now old lady, you have one last chance.  Confess the heinous sin of heresy, reject  \$l") + "'",
      "     VISIBLE:  'Now old lady, you have one last ', cursor=1",
      "BRAILLE LINE:  'Now old lady, you have one last chance. Confess the heinous sin of heresy, reject  $l'",
      "     VISIBLE:  'Now old lady, you have one last ', cursor=1",
-     "BRAILLE LINE:  '" + utils.getOOoBrailleLine("Writer", "spanish", " \$l") + "'",
+     "BRAILLE LINE:  '" + utils.getOOoBrailleLine("Writer", "spanish(.odt|)", " \$l") + "'",
      "     VISIBLE:  ' $l', cursor=1",
      "BRAILLE LINE:  ' $l'",
      "     VISIBLE:  ' $l', cursor=1",
-     "BRAILLE LINE:  '" + utils.getOOoBrailleLine("Writer", "spanish", "Now old lady, you have one last chance.  Confess the heinous sin of heresy, reject  \$l") + "'",
+     "BRAILLE LINE:  '" + utils.getOOoBrailleLine("Writer", "spanish(.odt|)", "Now old lady, you have one last chance.  Confess the heinous sin of heresy, reject  \$l") + "'",
      "     VISIBLE:  'Now old lady, you have one last ', cursor=1",
      "SPEECH OUTPUT: 'Now old lady, you have one last chance. Confess the heinous sin of heresy, reject '",
      "SPEECH OUTPUT: 'blank'",
@@ -96,13 +96,13 @@
 sequence.append(utils.AssertPresentationAction(
     "Type Control-down to move to the next paragraph [4]",
     ["BUG: speaks the paragraph two times",
-     "BRAILLE LINE:  '" + utils.getOOoBrailleLine("Writer", "spanish", "Now old lady, you have one last chance.  Confess the heinous sin of heresy, reject  \$l") + "'",
+     "BRAILLE LINE:  '" + utils.getOOoBrailleLine("Writer", "spanish(.odt|)", "Now old lady, you have one last chance.  Confess the heinous sin of heresy, reject  \$l") + "'",
      "     VISIBLE:  'Now old lady, you have one last ', cursor=2",
-     "BRAILLE LINE:  '" + utils.getOOoBrailleLine("Writer", "spanish", "Now old lady, you have one last chance.  Confess the heinous sin of heresy, reject  \$l") + "'",
+     "BRAILLE LINE:  '" + utils.getOOoBrailleLine("Writer", "spanish(.odt|)", "Now old lady, you have one last chance.  Confess the heinous sin of heresy, reject  \$l") + "'",
      "     VISIBLE:  'Now old lady, you have one last ', cursor=1",
      "BRAILLE LINE:  'Now old lady, you have one last chance. Confess the heinous sin of heresy, reject  $l'",
      "     VISIBLE:  'Now old lady, you have one last ', cursor=1",
-     "BRAILLE LINE:  '" + utils.getOOoBrailleLine("Writer", "spanish", " \$l") + "'",
+     "BRAILLE LINE:  '" + utils.getOOoBrailleLine("Writer", "spanish(.odt|)", " \$l") + "'",
      "     VISIBLE:  ' $l', cursor=1",
      "SPEECH OUTPUT: 'Now old lady, you have one last chance. Confess the heinous sin of heresy, reject '",
      "SPEECH OUTPUT: 'Now old lady, you have one last chance. Confess the heinous sin of heresy, reject '",
@@ -117,15 +117,15 @@
 sequence.append(utils.AssertPresentationAction(
     "Type Control-down to move to the next paragraph [5]",
     ["BUG: speaks the paragraph two times",
-     "BRAILLE LINE:  '" + utils.getOOoBrailleLine("Writer", "spanish", "Hm! She is made of harder stuff! Cardinal Fang! Fetch the COMFY CHAIR! \$l") + "'",
+     "BRAILLE LINE:  '" + utils.getOOoBrailleLine("Writer", "spanish(.odt|)", "Hm! She is made of harder stuff! Cardinal Fang! Fetch the COMFY CHAIR! \$l") + "'",
      "     VISIBLE:  'Hm! She is made of harder stuff!', cursor=1",
      "BRAILLE LINE:  'Hm! She is made of harder stuff! Cardinal Fang! Fetch the COMFY CHAIR! $l'",
      "     VISIBLE:  'Hm! She is made of harder stuff!', cursor=1",
-     "BRAILLE LINE:  '" + utils.getOOoBrailleLine("Writer", "spanish", " \$l") + "'",
+     "BRAILLE LINE:  '" + utils.getOOoBrailleLine("Writer", "spanish(.odt|)", " \$l") + "'",
      "     VISIBLE:  ' $l', cursor=1",
      "BRAILLE LINE:  ' $l'",
      "     VISIBLE:  ' $l', cursor=1",
-     "BRAILLE LINE:  '" + utils.getOOoBrailleLine("Writer", "spanish", "Hm! She is made of harder stuff! Cardinal Fang! Fetch the COMFY CHAIR! \$l") + "'",
+     "BRAILLE LINE:  '" + utils.getOOoBrailleLine("Writer", "spanish(.odt|)", "Hm! She is made of harder stuff! Cardinal Fang! Fetch the COMFY CHAIR! \$l") + "'",
      "     VISIBLE:  'Hm! She is made of harder stuff!', cursor=1",
      "SPEECH OUTPUT: 'Hm! She is made of harder stuff! Cardinal Fang! Fetch the COMFY CHAIR!'",
      "SPEECH OUTPUT: 'blank'",
Index: test/keystrokes/oowriter/bug_342602.py
===================================================================
--- test/keystrokes/oowriter/bug_342602.py	(revision 4130)
+++ test/keystrokes/oowriter/bug_342602.py	(working copy)
@@ -67,9 +67,7 @@
      "     VISIBLE:  'Paragraph', cursor=1",
      "SPEECH OUTPUT: 'A'",
      "SPEECH OUTPUT: ' not selected'",
-# [[[TODO: WDW - StarOffice 8 gives us this.  DEV300_m25 does not.]]]
-#
-#     "SPEECH OUTPUT: 'table with 2 rows and 2 columns.'",
+     "SPEECH OUTPUT: 'table with 2 rows and 2 columns.'",
      "SPEECH OUTPUT: ''",
      "SPEECH OUTPUT: ' not selected'",
      "SPEECH OUTPUT: 'Cell B1'",
@@ -89,9 +87,7 @@
      "     VISIBLE:  'A Paragraph', cursor=1",
      "SPEECH OUTPUT: ''",
      "SPEECH OUTPUT: ' not selected'",
-# [[[TODO: WDW - StarOffice 8 gives us this.  DEV300_m25 does not.]]]
-#
-#     "SPEECH OUTPUT: 'table with 2 rows and 2 columns.'",
+     "SPEECH OUTPUT: 'table with 2 rows and 2 columns.'",
      "SPEECH OUTPUT: 'A'",
      "SPEECH OUTPUT: ' not selected'",
      "SPEECH OUTPUT: 'Cell A1'"]))
Index: test/keystrokes/oowriter/bug_382408.py
===================================================================
--- test/keystrokes/oowriter/bug_382408.py	(revision 4130)
+++ test/keystrokes/oowriter/bug_382408.py	(working copy)
@@ -23,9 +23,9 @@
 ######################################################################
 # 3. Type Insert-F11 to switch to read table cells by row.
 #
-sequence.append(KeyPressAction (0, 106,"Insert"))      # Press Insert
+sequence.append(KeyPressAction(0, None, "KP_Insert"))
 sequence.append(KeyComboAction("F11"))
-sequence.append(KeyReleaseAction(150, 106,"Insert"))   # Release Insert
+sequence.append(KeyReleaseAction(0, None, "KP_Insert"))
 
 ######################################################################
 # 4. Type a down arrow to move to the next line.
Index: test/keystrokes/oowriter/bug_382418.py
===================================================================
--- test/keystrokes/oowriter/bug_382418.py	(revision 4130)
+++ test/keystrokes/oowriter/bug_382418.py	(working copy)
@@ -86,7 +86,7 @@
     "Type a down arrow to enter the table",
 # [[[TODO: WDW - StarOffice 8 gives us this.  DEV300_m25 does not.]]]
 #
-    [#"SPEECH OUTPUT: 'table with 2 rows and 2 columns.'",
+    ["SPEECH OUTPUT: 'table with 2 rows and 2 columns.'",
      "SPEECH OUTPUT: 'Cell A1'"]))
 
 ######################################################################
Index: test/keystrokes/oowriter/bug_361747.py
===================================================================
--- test/keystrokes/oowriter/bug_361747.py	(revision 4130)
+++ test/keystrokes/oowriter/bug_361747.py	(working copy)
@@ -52,9 +52,9 @@
 # 6. Type Insert-f to get the text information for the bold word.
 #
 sequence.append(utils.StartRecordingAction())
-sequence.append(KeyPressAction (0, 106,"Insert"))      # Press Insert
+sequence.append(KeyPressAction(0, None, "KP_Insert"))
 sequence.append(TypeAction ("f"))
-sequence.append(KeyReleaseAction(150, 106,"Insert"))   # Release Insert
+sequence.append(KeyReleaseAction(0, None, "KP_Insert"))
 sequence.append(utils.AssertPresentationAction(
     "Text information for bold word",
     ["SPEECH OUTPUT: 'size 12'",
@@ -67,9 +67,9 @@
 #
 sequence.append(utils.StartRecordingAction())
 sequence.append(KeyComboAction("<Control>Right"))
-sequence.append(KeyPressAction (0, 106,"Insert"))      # Press Insert
+sequence.append(KeyPressAction(0, None, "KP_Insert"))
 sequence.append(TypeAction ("f"))
-sequence.append(KeyReleaseAction(150, 106,"Insert"))   # Release Insert
+sequence.append(KeyReleaseAction(0, None, "KP_Insert"))
 sequence.append(utils.AssertPresentationAction(
     "Text information for italic word",
     ["BRAILLE LINE:  '" + utils.getOOoBrailleLine("Writer", "empty_document(.odt|)", "Bold Italic Normal \$l") + "'",
@@ -85,9 +85,9 @@
 #
 sequence.append(utils.StartRecordingAction())
 sequence.append(KeyComboAction("<Control>Right"))
-sequence.append(KeyPressAction (0, 106,"Insert"))      # Press Insert
+sequence.append(KeyPressAction(0, None, "KP_Insert"))
 sequence.append(TypeAction ("f"))
-sequence.append(KeyReleaseAction(150, 106,"Insert"))   # Release Insert
+sequence.append(KeyReleaseAction(0, None, "KP_Insert"))
 sequence.append(utils.AssertPresentationAction(
     "Text information for regular word",
     ["BRAILLE LINE:  '" + utils.getOOoBrailleLine("Writer", "empty_document(.odt|)", "Bold Italic Normal \$l") + "'",
Index: test/keystrokes/oowriter/bug_469367.py
===================================================================
--- test/keystrokes/oowriter/bug_469367.py	(revision 4130)
+++ test/keystrokes/oowriter/bug_469367.py	(working copy)
@@ -51,9 +51,9 @@
 # 5. Enter Insert-f to get text information.
 #
 sequence.append(utils.StartRecordingAction())
-sequence.append(KeyPressAction (0, 106,"Insert"))      # Press Insert
+sequence.append(KeyPressAction(0, None, "KP_Insert"))
 sequence.append(TypeAction ("f"))
-sequence.append(KeyReleaseAction(150, 106,"Insert"))   # Release Insert
+sequence.append(KeyReleaseAction(0, None, "KP_Insert"))
 sequence.append(utils.AssertPresentationAction(
     "Enter Insert-f to get text information",
     ["SPEECH OUTPUT: 'size 12'",
Index: src/orca/scripts/apps/soffice/braille_generator.py
===================================================================
--- src/orca/scripts/apps/soffice/braille_generator.py	(revision 4130)
+++ src/orca/scripts/apps/soffice/braille_generator.py	(working copy)
@@ -43,6 +43,14 @@
     def __init__(self, script):
         braillegenerator.BrailleGenerator.__init__(self, script)
 
+    def _getTextForRole(self, obj, role=None):
+        if obj.getRole() == pyatspi.ROLE_DOCUMENT_FRAME \
+           or role == pyatspi.ROLE_DOCUMENT_FRAME:
+            return None
+
+        return braillegenerator.BrailleGenerator.\
+            _getTextForRole(self, obj, role)
+
     def _getBrailleRegionsForTableCellRow(self, obj):
         """Get the braille for a table cell row or a single table cell
         if settings.readTableCellRow is False.
Index: src/orca/scripts/apps/soffice/script.py
===================================================================
--- src/orca/scripts/apps/soffice/script.py	(revision 4130)
+++ src/orca/scripts/apps/soffice/script.py	(working copy)
@@ -516,13 +516,13 @@
         """
 
         found = False
-        rolesList = [pyatspi.ROLE_TABLE_CELL, \
-                     pyatspi.ROLE_TABLE, \
-                     pyatspi.ROLE_UNKNOWN, \
-                     pyatspi.ROLE_SCROLL_PANE, \
-                     pyatspi.ROLE_PANEL, \
-                     pyatspi.ROLE_ROOT_PANE, \
-                     pyatspi.ROLE_FRAME, \
+        rolesList = [pyatspi.ROLE_TABLE_CELL,
+                     pyatspi.ROLE_TABLE,
+                     [pyatspi.ROLE_UNKNOWN, pyatspi.ROLE_DOCUMENT_FRAME],
+                     pyatspi.ROLE_SCROLL_PANE,
+                     pyatspi.ROLE_PANEL,
+                     pyatspi.ROLE_ROOT_PANE,
+                     pyatspi.ROLE_FRAME,
                      pyatspi.ROLE_APPLICATION]
         if startFromTable:
             rolesList = rolesList[1:]
@@ -566,12 +566,15 @@
             if current is None:
                 return False
 
-            if isinstance(role, str):
+            if not isinstance(role, list):
+                role = [role]
+
+            if isinstance(role[0], str):
                 current_role = current.getRoleName()
             else:
                 current_role = current.getRole()
 
-            if current_role != role:
+            if not current_role in role:
                 return False
 
             current = self._getParent(current)
@@ -1089,11 +1092,11 @@
 
         isPanel = False
         if event.type == "object:state-changed:focused":
-            rolesList = [pyatspi.ROLE_PANEL, \
-                         pyatspi.ROLE_SCROLL_PANE, \
-                         pyatspi.ROLE_PANEL, \
-                         pyatspi.ROLE_OPTION_PANE, \
-                         pyatspi.ROLE_DIALOG, \
+            rolesList = [pyatspi.ROLE_PANEL,
+                         pyatspi.ROLE_SCROLL_PANE,
+                         pyatspi.ROLE_PANEL,
+                         pyatspi.ROLE_OPTION_PANE,
+                         pyatspi.ROLE_DIALOG,
                          pyatspi.ROLE_APPLICATION]
             if self.isDesiredFocusedItem(event.source, rolesList):
                 tmp = event.source.parent.parent
@@ -1101,19 +1104,19 @@
                     isPanel = True
 
             if not isPanel:
-                rolesList = [pyatspi.ROLE_SCROLL_PANE, \
-                             pyatspi.ROLE_PANEL, \
-                             pyatspi.ROLE_OPTION_PANE, \
-                             pyatspi.ROLE_DIALOG, \
+                rolesList = [pyatspi.ROLE_SCROLL_PANE,
+                             pyatspi.ROLE_PANEL,
+                             pyatspi.ROLE_OPTION_PANE,
+                             pyatspi.ROLE_DIALOG,
                              pyatspi.ROLE_APPLICATION]
                 if self.isDesiredFocusedItem(event.source, rolesList):
                     if event.source.parent.name.startswith(panelName):
                         isPanel = True
 
             if not isPanel:
-                rolesList = [pyatspi.ROLE_PANEL, \
-                             pyatspi.ROLE_OPTION_PANE, \
-                             pyatspi.ROLE_DIALOG, \
+                rolesList = [pyatspi.ROLE_PANEL,
+                             pyatspi.ROLE_OPTION_PANE,
+                             pyatspi.ROLE_DIALOG,
                              pyatspi.ROLE_APPLICATION]
                 if self.isDesiredFocusedItem(event.source, rolesList):
                     if event.source.name.startswith(panelName):
@@ -1220,11 +1223,11 @@
         # the Writer, then just speak/braille the current line (rather than
         # speaking a bogus initial "paragraph" utterance as well).
 
-        rolesList = [pyatspi.ROLE_PARAGRAPH, \
-                     pyatspi.ROLE_UNKNOWN, \
-                     pyatspi.ROLE_SCROLL_PANE, \
-                     pyatspi.ROLE_PANEL, \
-                     pyatspi.ROLE_ROOT_PANE, \
+        rolesList = [pyatspi.ROLE_PARAGRAPH,
+                     [pyatspi.ROLE_UNKNOWN, pyatspi.ROLE_DOCUMENT_FRAME],
+                     pyatspi.ROLE_SCROLL_PANE,
+                     pyatspi.ROLE_PANEL,
+                     pyatspi.ROLE_ROOT_PANE,
                      pyatspi.ROLE_FRAME]
         if self.isDesiredFocusedItem(event.source, rolesList):
             debug.println(self.debugLevel,
@@ -1262,9 +1265,9 @@
         # their translation of this string matches what StarOffice uses in
         # that locale.
 
-        rolesList = [pyatspi.ROLE_PUSH_BUTTON, \
-                     pyatspi.ROLE_OPTION_PANE, \
-                     pyatspi.ROLE_DIALOG, \
+        rolesList = [pyatspi.ROLE_PUSH_BUTTON,
+                     pyatspi.ROLE_OPTION_PANE,
+                     pyatspi.ROLE_DIALOG,
                      pyatspi.ROLE_APPLICATION]
         if self.isDesiredFocusedItem(event.source, rolesList):
             pane = event.source.parent
@@ -1292,10 +1295,10 @@
 
             # Check for 2. License Agreement: Scroll Down button.
             #
-            rolesList = [pyatspi.ROLE_PUSH_BUTTON, \
-                         pyatspi.ROLE_PANEL, \
-                         pyatspi.ROLE_OPTION_PANE, \
-                         pyatspi.ROLE_DIALOG, \
+            rolesList = [pyatspi.ROLE_PUSH_BUTTON,
+                         pyatspi.ROLE_PANEL,
+                         pyatspi.ROLE_OPTION_PANE,
+                         pyatspi.ROLE_DIALOG,
                          pyatspi.ROLE_APPLICATION]
             if self.isDesiredFocusedItem(event.source, rolesList):
                 debug.println(self.debugLevel,
@@ -1307,11 +1310,11 @@
 
             # Check for 2. License Agreement: Accept button.
             #
-            rolesList = [pyatspi.ROLE_UNKNOWN, \
-                         pyatspi.ROLE_SCROLL_PANE, \
-                         pyatspi.ROLE_PANEL, \
-                         pyatspi.ROLE_OPTION_PANE, \
-                         pyatspi.ROLE_DIALOG, \
+            rolesList = [pyatspi.ROLE_UNKNOWN,
+                         pyatspi.ROLE_SCROLL_PANE,
+                         pyatspi.ROLE_PANEL,
+                         pyatspi.ROLE_OPTION_PANE,
+                         pyatspi.ROLE_DIALOG,
                          pyatspi.ROLE_APPLICATION]
             if self.isDesiredFocusedItem(event.source, rolesList):
                 debug.println(self.debugLevel,
@@ -1322,10 +1325,10 @@
 
             # Check for 3. Personal Data: Transfer Personal Data check box.
             #
-            rolesList = [pyatspi.ROLE_CHECK_BOX, \
-                         pyatspi.ROLE_PANEL, \
-                         pyatspi.ROLE_OPTION_PANE, \
-                         pyatspi.ROLE_DIALOG, \
+            rolesList = [pyatspi.ROLE_CHECK_BOX,
+                         pyatspi.ROLE_PANEL,
+                         pyatspi.ROLE_OPTION_PANE,
+                         pyatspi.ROLE_DIALOG,
                          pyatspi.ROLE_APPLICATION]
             if self.isDesiredFocusedItem(event.source, rolesList):
                 debug.println(self.debugLevel,
@@ -1335,11 +1338,11 @@
 
             # Check for 4. User name: First Name text field.
             #
-            rolesList = [pyatspi.ROLE_TEXT, \
-                        pyatspi.ROLE_PANEL, \
-                        pyatspi.ROLE_OPTION_PANE, \
-                        pyatspi.ROLE_DIALOG, \
-                        pyatspi.ROLE_APPLICATION]
+            rolesList = [pyatspi.ROLE_TEXT,
+                         pyatspi.ROLE_PANEL,
+                         pyatspi.ROLE_OPTION_PANE,
+                         pyatspi.ROLE_DIALOG,
+                         pyatspi.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
@@ -1369,11 +1372,11 @@
 
             # Check for 5. Registration: Register Now radio button.
             #
-            rolesList = [pyatspi.ROLE_RADIO_BUTTON, \
-                        pyatspi.ROLE_PANEL, \
-                        pyatspi.ROLE_OPTION_PANE, \
-                        pyatspi.ROLE_DIALOG, \
-                        pyatspi.ROLE_APPLICATION]
+            rolesList = [pyatspi.ROLE_RADIO_BUTTON,
+                         pyatspi.ROLE_PANEL,
+                         pyatspi.ROLE_OPTION_PANE,
+                         pyatspi.ROLE_DIALOG,
+                         pyatspi.ROLE_APPLICATION]
             if self.isDesiredFocusedItem(event.source, rolesList):
                 debug.println(self.debugLevel,
                     "StarOffice.locusOfFocusChanged - Setup dialog: " \
@@ -1385,13 +1388,13 @@
         # Check to see if we are editing a spread sheet cell. If so, just
         # return to avoid uttering something like "Paragraph 0 paragraph".
         #
-        rolesList = [pyatspi.ROLE_PARAGRAPH, \
-                     pyatspi.ROLE_PANEL, \
-                     pyatspi.ROLE_UNKNOWN, \
-                     pyatspi.ROLE_SCROLL_PANE, \
-                     pyatspi.ROLE_PANEL, \
-                     pyatspi.ROLE_ROOT_PANE, \
-                     pyatspi.ROLE_FRAME, \
+        rolesList = [pyatspi.ROLE_PARAGRAPH,
+                     [pyatspi.ROLE_PANEL, pyatspi.ROLE_EXTENDED],
+                     [pyatspi.ROLE_UNKNOWN, pyatspi.ROLE_DOCUMENT_FRAME],
+                     pyatspi.ROLE_SCROLL_PANE,
+                     pyatspi.ROLE_PANEL,
+                     pyatspi.ROLE_ROOT_PANE,
+                     pyatspi.ROLE_FRAME,
                      pyatspi.ROLE_APPLICATION]
         if self.isDesiredFocusedItem(event.source, rolesList):
             debug.println(self.debugLevel, "StarOffice.locusOfFocusChanged - " \
@@ -1406,12 +1409,12 @@
         # locusOfFocusChanged method, which in turn will result in our
         # _getSpeechForComboBox() method being called.
         #
-        rolesList = [pyatspi.ROLE_LIST, \
-                     pyatspi.ROLE_COMBO_BOX, \
-                     pyatspi.ROLE_TOOL_BAR, \
-                     pyatspi.ROLE_PANEL, \
-                     pyatspi.ROLE_ROOT_PANE, \
-                     pyatspi.ROLE_FRAME, \
+        rolesList = [pyatspi.ROLE_LIST,
+                     pyatspi.ROLE_COMBO_BOX,
+                     pyatspi.ROLE_TOOL_BAR,
+                     pyatspi.ROLE_PANEL,
+                     pyatspi.ROLE_ROOT_PANE,
+                     pyatspi.ROLE_FRAME,
                      pyatspi.ROLE_APPLICATION]
 
         if self.isDesiredFocusedItem(event.source, rolesList) \
@@ -1462,11 +1465,11 @@
         # If we are in the slide presentation scroll pane, also announce
         # the current page tab. See bug #538056 for more details.
         #
-        rolesList = [pyatspi.ROLE_SCROLL_PANE, \
-                     pyatspi.ROLE_PANEL, \
-                     pyatspi.ROLE_PANEL, \
-                     pyatspi.ROLE_ROOT_PANE, \
-                     pyatspi.ROLE_FRAME, \
+        rolesList = [pyatspi.ROLE_SCROLL_PANE,
+                     pyatspi.ROLE_PANEL,
+                     pyatspi.ROLE_PANEL,
+                     pyatspi.ROLE_ROOT_PANE,
+                     pyatspi.ROLE_FRAME,
                      pyatspi.ROLE_APPLICATION]
 
         if self.isDesiredFocusedItem(event.source, rolesList):
@@ -1490,13 +1493,13 @@
         # try to present each of its children. See bug #538064 for
         # more details.
         #
-        rolesList = [pyatspi.ROLE_UNKNOWN,
-                     pyatspi.ROLE_UNKNOWN,
-                     pyatspi.ROLE_SCROLL_PANE, \
-                     pyatspi.ROLE_PANEL, \
-                     pyatspi.ROLE_PANEL, \
-                     pyatspi.ROLE_ROOT_PANE, \
-                     pyatspi.ROLE_FRAME, \
+        rolesList = [[pyatspi.ROLE_UNKNOWN, pyatspi.ROLE_LIST_ITEM],
+                     [pyatspi.ROLE_UNKNOWN, pyatspi.ROLE_DOCUMENT_FRAME],
+                     pyatspi.ROLE_SCROLL_PANE,
+                     pyatspi.ROLE_PANEL,
+                     pyatspi.ROLE_PANEL,
+                     pyatspi.ROLE_ROOT_PANE,
+                     pyatspi.ROLE_FRAME,
                      pyatspi.ROLE_APPLICATION]
         if self.isDesiredFocusedItem(event.source, rolesList):
             default.Script.locusOfFocusChanged(self, event,
@@ -1612,12 +1615,12 @@
         # If this is a "focus:" event for the Calc Name combo box, catch
         # it here to reduce verbosity (see bug #364407).
         #
-        rolesList = [pyatspi.ROLE_LIST, \
-                     pyatspi.ROLE_COMBO_BOX, \
-                     pyatspi.ROLE_TOOL_BAR, \
-                     pyatspi.ROLE_PANEL, \
-                     pyatspi.ROLE_ROOT_PANE, \
-                     pyatspi.ROLE_FRAME, \
+        rolesList = [pyatspi.ROLE_LIST,
+                     pyatspi.ROLE_COMBO_BOX,
+                     pyatspi.ROLE_TOOL_BAR,
+                     pyatspi.ROLE_PANEL,
+                     pyatspi.ROLE_ROOT_PANE,
+                     pyatspi.ROLE_FRAME,
                      pyatspi.ROLE_APPLICATION]
         if self.isDesiredFocusedItem(event.source, rolesList):
             debug.println(self.debugLevel, "StarOffice.onFocus - " \
@@ -1769,11 +1772,11 @@
         # so we'll do an updateBraille() just in case.
         #
         if event.type.startswith("object:state-changed:focused"):
-            rolesList = [pyatspi.ROLE_PARAGRAPH, \
-                         pyatspi.ROLE_UNKNOWN, \
-                         pyatspi.ROLE_SCROLL_PANE, \
-                         pyatspi.ROLE_PANEL, \
-                         pyatspi.ROLE_ROOT_PANE, \
+            rolesList = [pyatspi.ROLE_PARAGRAPH,
+                         [pyatspi.ROLE_UNKNOWN, pyatspi.ROLE_DOCUMENT_FRAME],
+                         pyatspi.ROLE_SCROLL_PANE,
+                         pyatspi.ROLE_PANEL,
+                         pyatspi.ROLE_ROOT_PANE,
                          pyatspi.ROLE_FRAME]
             if self.isDesiredFocusedItem(event.source, rolesList) \
                and event.source != self.currentParagraph \
@@ -1826,13 +1829,13 @@
         # different from what is displayed in that cell, then speak "has
         # formula" and append it to the braille line.
         #
-        rolesList = [pyatspi.ROLE_LIST, \
-                     pyatspi.ROLE_COMBO_BOX, \
-                     pyatspi.ROLE_PANEL, \
-                     pyatspi.ROLE_TOOL_BAR, \
-                     pyatspi.ROLE_PANEL, \
-                     pyatspi.ROLE_ROOT_PANE, \
-                     pyatspi.ROLE_FRAME, \
+        rolesList = [pyatspi.ROLE_LIST,
+                     pyatspi.ROLE_COMBO_BOX,
+                     pyatspi.ROLE_PANEL,
+                     pyatspi.ROLE_TOOL_BAR,
+                     pyatspi.ROLE_PANEL,
+                     pyatspi.ROLE_ROOT_PANE,
+                     pyatspi.ROLE_FRAME,
                      pyatspi.ROLE_APPLICATION]
         if self.isDesiredFocusedItem(event.source, rolesList):
             if orca_state.locusOfFocus.getRole() == pyatspi.ROLE_TABLE_CELL:
@@ -1936,22 +1939,22 @@
         if event.detail1 == -1:
             # ooimpress paragraph in a slide presentation.
             rolesList = [pyatspi.ROLE_PARAGRAPH,
-                         pyatspi.ROLE_UNKNOWN,
-                         pyatspi.ROLE_UNKNOWN,
-                         pyatspi.ROLE_SCROLL_PANE, \
-                         pyatspi.ROLE_PANEL, \
-                         pyatspi.ROLE_PANEL, \
-                         pyatspi.ROLE_ROOT_PANE, \
-                         pyatspi.ROLE_FRAME, \
+                         [pyatspi.ROLE_UNKNOWN, pyatspi.ROLE_LIST_ITEM],
+                         [pyatspi.ROLE_UNKNOWN, pyatspi.ROLE_DOCUMENT_FRAME],
+                         pyatspi.ROLE_SCROLL_PANE,
+                         pyatspi.ROLE_PANEL,
+                         pyatspi.ROLE_PANEL,
+                         pyatspi.ROLE_ROOT_PANE,
+                         pyatspi.ROLE_FRAME,
                          pyatspi.ROLE_APPLICATION]
 
             # oowriter paragraph in a text document.
             rolesList1 = [pyatspi.ROLE_PARAGRAPH,
-                          pyatspi.ROLE_UNKNOWN,
-                          pyatspi.ROLE_SCROLL_PANE, \
-                          pyatspi.ROLE_PANEL, \
-                          pyatspi.ROLE_ROOT_PANE, \
-                          pyatspi.ROLE_FRAME, \
+                          [pyatspi.ROLE_UNKNOWN, pyatspi.ROLE_DOCUMENT_FRAME],
+                          pyatspi.ROLE_SCROLL_PANE,
+                          pyatspi.ROLE_PANEL,
+                          pyatspi.ROLE_ROOT_PANE,
+                          pyatspi.ROLE_FRAME,
                           pyatspi.ROLE_APPLICATION]
             if settings.enableEchoByWord and \
                (self.isDesiredFocusedItem(event.source, rolesList) or
Index: src/orca/default.py
===================================================================
--- src/orca/default.py	(revision 4130)
+++ src/orca/default.py	(working copy)
@@ -6103,12 +6103,15 @@
             if current is None:
                 return False
 
-            if isinstance(role, str):
+            if not isinstance(role, list):
+                role = [role]
+
+            if isinstance(role[0], str):
                 current_role = current.getRoleName()
             else:
                 current_role = current.getRole()
 
-            if current_role != role:
+            if not current_role in role:
                 return False
             current = current.parent
 
