Index: src/orca/scripts/apps/soffice/speech_generator.py
===================================================================
--- src/orca/scripts/apps/soffice/speech_generator.py	(revision 4148)
+++ src/orca/scripts/apps/soffice/speech_generator.py	(working copy)
@@ -52,6 +52,17 @@
     def __init__(self, script):
         speechgenerator.SpeechGenerator.__init__(self, script)
 
+    def getSpeechForObjectRole(self, obj, role=None):
+        if obj.getRoleName() == "text frame" \
+           or (obj.getRole() == pyatspi.ROLE_PARAGRAPH \
+               and self._script.getAncestor(obj,
+                                            [pyatspi.ROLE_DIALOG],
+                                            [pyatspi.ROLE_APPLICATION])):
+            role = pyatspi.ROLE_TEXT
+            
+        return speechgenerator.SpeechGenerator.\
+            getSpeechForObjectRole(self, obj, role)
+
     def _getSpeechForComboBox(self, obj, already_focused):
         """Get the speech for a combo box. If the combo box already has focus,
         then only the selection is spoken.
@@ -289,6 +300,49 @@
 
         return utterances
 
+    def _getSpeechForText(self, obj, already_focused):
+        """Get the speech for a paragraph which is serving as a text object
+        in a dialog.
+
+        Arguments:
+        - obj: the text component
+        - already_focused: False if object just received focus
+
+        Returns a list of utterances to be spoken for the object.
+        """
+
+        utterances = []
+        if obj.getRole() == pyatspi.ROLE_PARAGRAPH \
+           and self._script.getAncestor(obj,
+                                        [pyatspi.ROLE_DIALOG],
+                                        [pyatspi.ROLE_APPLICATION]):
+            utterances.extend(self._getSpeechForObjectLabel(obj))
+            if len(utterances) == 0 and obj.parent:
+                parentLabel = self._getSpeechForObjectLabel(obj.parent)
+                # If we aren't already focused, we will have spoken the
+                # parent as part of the speech context and do not want
+                # to repeat it.
+                #
+                if already_focused:
+                    utterances.extend(parentLabel)
+                # If we still don't have a label, look to the name.
+                #
+                if not parentLabel and obj.name and len(obj.name):
+                    utterances.append(obj.name)
+
+            utterances.append(self._script.getTextLineAtCaret(obj)[0])
+            utterances.extend(self._getSpeechForAllTextSelection(obj))
+
+            self._debugGenerator("soffice _getSpeechForText",
+                                 obj,
+                                 already_focused,
+                                 utterances)
+        else:
+            utterances.extend(speechgenerator.SpeechGenerator.\
+                _getSpeechForText(self, obj, already_focused))
+
+        return utterances
+
     def _getSpeechForToggleButton(self, obj, already_focused):
         """Get the speech for a toggle button.  We always want to speak the
         state if it's on a toolbar.
Index: src/orca/scripts/apps/soffice/where_am_i.py
===================================================================
--- src/orca/scripts/apps/soffice/where_am_i.py	(revision 4148)
+++ src/orca/scripts/apps/soffice/where_am_i.py	(working copy)
@@ -136,6 +136,8 @@
             self._speakCalc(obj, basicOnly)
         elif top and top.name.endswith(" Writer"):
             self._speakText(obj, basicOnly)
+        else:
+            where_am_I.WhereAmI._speakParagraph(self, obj, basicOnly)
 
     def _speakCalc(self, obj, basicOnly):
         """Speak a OpenOffice Calc cell.
@@ -251,3 +253,36 @@
         debug.println(self._debugLevel,
                       "Calc status bar utterances=%s" % utterances)
         speech.speakUtterances(utterances)
+
+    def _getObjLabel(self, obj):
+        """Returns the label to speak for an object.
+        """
+
+        label = self._script.getDisplayedLabel(obj) or ""
+        if not label and obj.getRole() == pyatspi.ROLE_PARAGRAPH \
+           and self._script.getAncestor(obj,
+                                        [pyatspi.ROLE_DIALOG],
+                                        [pyatspi.ROLE_APPLICATION]):
+            label = self._script.getDisplayedLabel(obj.parent) or ""
+
+        return label.strip()
+
+    def _speakObjDescription(self, obj):
+        """Speaks the object's description if it is not the same as
+        the object's name and displayed contents.
+        """
+
+        if not obj.description:
+            return
+
+        # The descriptions of some OOo paragraphs consists of the name and
+        # the displayed text, with punctuation added. Try to spot this and,
+        # if found, ignore the description.
+        #
+        text = self._script.getDisplayedText(obj) or ""
+        desc = obj.description.replace(text, "")
+        for item in obj.name.split():
+            desc = desc.replace(item, "")
+        for char in desc.decode("UTF-8").strip():
+            if char.isalnum():
+                return where_am_I.WhereAmI._speakObjDescription(self, obj)
Index: src/orca/speechgenerator.py
===================================================================
--- src/orca/speechgenerator.py	(revision 4148)
+++ src/orca/speechgenerator.py	(working copy)
@@ -1867,12 +1867,11 @@
                     #
                     if parent.getRole() not in [pyatspi.ROLE_TABLE_CELL,
                                                 pyatspi.ROLE_FILLER]:
-                        utterances.append(\
-                            rolenames.getSpeechForRoleName(parent))
+                        utterances.extend(self.getSpeechForObjectRole(parent))
                     utterances.append(text)
                     if parent.getRole() == pyatspi.ROLE_TABLE_CELL:
-                        utterances.append(\
-                            rolenames.getSpeechForRoleName(parent))
+                        utterances.extend(self.getSpeechForObjectRole(parent))
+
             parent = parent.parent
 
         utterances.reverse()
Index: src/orca/where_am_I.py
===================================================================
--- src/orca/where_am_I.py	(revision 4148)
+++ src/orca/where_am_I.py	(working copy)
@@ -28,7 +28,6 @@
 import pyatspi
 import debug
 import orca_state
-import rolenames
 import settings
 import speech
 import text_attribute_names
@@ -172,8 +171,7 @@
         """
 
         utterances = []
-        text = self.getObjLabelAndName(obj) + " " + \
-               rolenames.getSpeechForRoleName(obj)
+        text = self.getObjLabelAndName(obj) + " " + self._getObjRole(obj)
         text = text + " " + self._getCheckBoxState(obj)
         utterances.append(text)
 
@@ -212,8 +210,7 @@
         if text:
             utterances.append(text)
 
-        text = self.getObjLabelAndName(obj) + " " + \
-               rolenames.getSpeechForRoleName(obj)
+        text = self.getObjLabelAndName(obj) + " " + self._getObjRole(obj)
         utterances.append(text)
 
         state = obj.getState()
@@ -263,7 +260,7 @@
         text = self._getObjLabel(obj)
         utterances.append(text)
 
-        text = rolenames.getSpeechForRoleName(obj)
+        text = self._getObjRole(obj)
         utterances.append(text)
 
         name = self._getObjName(obj)
@@ -299,7 +296,7 @@
         label = self._getObjLabel(obj)
         utterances.append(label)
 
-        text = rolenames.getSpeechForRoleName(obj)
+        text = self._getObjRole(obj)
         utterances.append(text)
 
         name = self._getObjName(obj)
@@ -336,7 +333,7 @@
         text = self.getObjLabelAndName(obj)
         utterances.append(text)
 
-        text = rolenames.getSpeechForRoleName(obj)
+        text = self._getObjRole(obj)
         utterances.append(text)
 
         text = self._getObjAccelerator(obj)
@@ -365,7 +362,7 @@
         text = self._getObjLabel(obj)
         utterances.append(text)
 
-        text = rolenames.getSpeechForRoleName(obj)
+        text = self._getObjRole(obj)
         utterances.append(text)
 
         values = self._getSliderValues(obj)
@@ -403,7 +400,7 @@
 
         utterances = []
         text = self.getObjLabelAndName(obj.parent) + " " + \
-               rolenames.getSpeechForRoleName(obj.parent)
+               self._getObjRole(obj.parent)
         utterances.append(text.strip())
 
         text = self.getObjLabelAndName(obj)
@@ -412,7 +409,7 @@
         state = obj.getState()
 
         if obj.getRole() != pyatspi.ROLE_MENU_ITEM:
-            text = rolenames.getSpeechForRoleName(obj)
+            text = self._getObjRole(obj)
             utterances.append(text)
 
         if obj.getRole() == pyatspi.ROLE_CHECK_MENU_ITEM:
@@ -475,7 +472,7 @@
         """
 
         utterances = []
-        text = rolenames.getSpeechForRoleName(obj.parent)
+        text = self._getObjRole(obj.parent)
         utterances.append(text)
 
         # Translators: "page" is the word for a page tab in a tab list.
@@ -537,7 +534,7 @@
            and self._script.isReadOnlyTextArea(obj):
             utterances.append(settings.speechReadOnlyString)
 
-        text = rolenames.getSpeechForRoleName(obj)
+        text = self._getObjRole(obj)
         utterances.append(text)
 
         [textContents, startOffset, endOffset, selected] = \
@@ -554,6 +551,7 @@
         utterances.append(text)
         debug.println(self._debugLevel, "first text utterances=%s" % \
                       utterances)
+
         speech.speakUtterances(utterances)
 
         if not basicOnly:
@@ -603,7 +601,7 @@
             obj = obj.parent
         parent = obj.parent
 
-        text = rolenames.getSpeechForRoleName(parent)
+        text = self._getObjRole(parent)
         utterances.append(text)
 
         try:
@@ -626,7 +624,7 @@
                 text = self._getObjName(header)
                 utterances.append(text)
 
-        text = rolenames.getSpeechForRoleName(obj)
+        text = self._getObjRole(obj)
         utterances.append(text)
 
         if nColumns:
@@ -712,7 +710,7 @@
         if text:
             utterances.append(text)
 
-        text = rolenames.getSpeechForRoleName(obj)
+        text = self._getObjRole(obj)
         utterances.append(text)
 
         text = self._getObjName(obj)
@@ -762,6 +760,7 @@
     def _speakParagraph(self, obj, basicOnly):
         """Speak a paragraph object.
         """
+
         self._speakText(obj, basicOnly)
 
     def _speakIconPanel(self, obj, basicOnly):
@@ -876,7 +875,7 @@
         text = self.getObjLabelAndName(obj)
         utterances.append(text)
 
-        text = rolenames.getSpeechForRoleName(obj)
+        text = self._getObjRole(obj)
         utterances.append(text)
 
         if obj.getState().contains(pyatspi.STATE_CHECKED):
@@ -906,7 +905,7 @@
         text = self.getObjLabelAndName(obj)
         utterances.append(text)
 
-        text = rolenames.getSpeechForRoleName(obj)
+        text = self._getObjRole(obj)
         utterances.append(text)
 
         valueString = self._script.getTextForValue(obj)
@@ -931,7 +930,7 @@
 
         utterances.extend(self._getSpeechForAllTextSelection(obj))
 
-        text = rolenames.getSpeechForRoleName(obj)
+        text = self._getObjRole(obj)
         utterances.append(text)
 
         getTutorial = self._script.tutorialGenerator.getTutorial
@@ -952,7 +951,7 @@
         text = self.getObjLabelAndName(obj)
         utterances.append(text)
 
-        text = rolenames.getSpeechForRoleName(obj)
+        text = self._getObjRole(obj)
         utterances.append(text)
         utterances.extend(self._getSelectedItemCount(obj, basicOnly))
 
@@ -1079,7 +1078,7 @@
         text = self.getObjLabelAndName(obj)
         utterances.append(text)
 
-        text = rolenames.getSpeechForRoleName(obj)
+        text = self._getObjRole(obj)
         utterances.append(text)
 
         getTutorial = self._script.tutorialGenerator.getTutorial
@@ -1142,6 +1141,12 @@
 
         return text.strip()
 
+    def _getObjRole(self, obj):
+        """Returns the rolename to be spoken for the object.
+        """
+
+        return self._script.speechGenerator.getSpeechForObjectRole(obj)[0]
+
     def _getGroupLabel(self, obj):
         """Returns the label for a group of components.
         """
@@ -1340,7 +1345,7 @@
                     break
 
         if isToggle:
-            text = rolenames.getSpeechForRoleName(obj, pyatspi.ROLE_CHECK_BOX)
+            text = self._getObjRole(obj, pyatspi.ROLE_CHECK_BOX)
             text = text + " " + self._getCheckBoxState(obj)
         else:
             descendant = self._script.getRealActiveDescendant(obj)
@@ -1930,7 +1935,7 @@
 
         utterances = []
         text = self.getObjLabelAndName(obj) + " " + \
-               rolenames.getSpeechForRoleName(obj)
+               self._getObjRole(obj)
         utterances.append(text.strip())
 
         debug.println(self._debugLevel, "toolbar utterances=%s" \
