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)
@@ -906,19 +906,50 @@
         Arguments:
         - event: the event.
         - pane: the option pane in the spell check dialog.
+
+        Returns True if this is the spell speck dialog (whether we actually
+        wind up reading the word or not).
         """
 
+        print "Entering readMisspeltWord", event.type, pane
         paragraph = self.findByRole(pane, pyatspi.ROLE_PARAGRAPH)
 
+        # If there is not exactly one paragraph, this isn't the spellcheck
+        # dialog.
+        #
+        if len(paragraph) != 1:
+            print "    failed: paragraph count is", len(paragraph)
+            return False
+
+        # If there's not any text displayed in the paragraph, this isn't
+        # the spellcheck dialog.
+        #
+        try:
+            text = paragraph[0].queryText()
+        except:
+            print "    failed due to no accessible text"
+            return False
+        else:
+            textLength = text.characterCount
+            if not textLength:
+                print "    failed due to empty text"
+                return False
+
+        # If the text here is not editable, this isn't the spellcheck
+        # dialog.
+        #
+        if not paragraph[0].getState().contains(pyatspi.STATE_EDITABLE):
+            print "    failed due to non-editable text"
+            return False
+
         # Determine which word is the misspelt word. This word will have
         # non-default text attributes associated with it.
-
-        textLength = paragraph[0].queryText().characterCount
+        #
         startFound = False
         startOff = 0
         endOff = textLength
         for i in range(0, textLength):
-            attributes = paragraph[0].queryText().getAttributes(i)
+            attributes = text.getAttributes(i)
             if len(attributes[0]) != 0:
                 if not startFound:
                     startOff = i
@@ -928,6 +959,13 @@
                     endOff = i
                     break
 
+        if not startFound:
+            # If there are no text attributes in this paragraph, this isn't
+            # the spellcheck dialog.
+            #
+            print "    failed due to lack of attributes"
+            return False
+
         badWord = self.getText(paragraph[0], startOff, endOff - 1)
 
         # Note that we often get two or more of these focus or property-change
@@ -936,7 +974,7 @@
         # offsets for that word and compare them against the values saved
         # from the last time this routine was called. If they are the same
         # then we ignore it.
-
+        #
         debug.println(self.debugLevel, \
             "StarOffice.readMisspeltWord: type=%s  word=%s(%d,%d)  len=%d" % \
             (event.type, badWord, startOff, endOff, textLength))
@@ -945,13 +983,13 @@
            (badWord == self.lastBadWord) and \
            (startOff == self.lastStartOff) and \
            (endOff == self.lastEndOff):
-            return
+            print "    success, but it's the same word so we're ignoring it"
+            return True
 
         # Create a list of all the words found in the misspelt paragraph.
         #
         text = self.getText(paragraph[0], 0, -1)
         allTokens = text.split()
-
         self.speakMisspeltWord(allTokens, badWord)
 
         # Save misspelt word information for comparison purposes next
@@ -962,6 +1000,9 @@
         self.lastStartOff = startOff
         self.lastEndOff = endOff
 
+        print "    success."
+        return True
+
     def endOfLink(self, obj, word, startOffset, endOffset):
         """Return an indication of whether the given word contains the
            end of a hypertext link.
@@ -1171,13 +1212,12 @@
     # This method tries to detect and handle the following cases:
     # 0) Writer: find command.
     # 1) Writer: text paragraph.
-    # 2) Writer: spell checking dialog.
-    # 3) Welcome to StarOffice dialog.
-    # 4) Calc: cell editor.
-    # 5) Calc: name box.
-    # 6) Calc: spreadsheet cell.
-    # 7) Impress: scroll pane.
-    # 8) Presentation: scroll pane: place holder
+    # 2) Welcome to StarOffice dialog.
+    # 3) Calc: cell editor.
+    # 4) Calc: name box.
+    # 5) Calc: spreadsheet cell.
+    # 6) Impress: scroll pane.
+    # 7) Presentation: scroll pane: place holder
 
     def locusOfFocusChanged(self, event, oldLocusOfFocus, newLocusOfFocus):
         """Called when the visual object with focus changes.
@@ -1250,41 +1290,8 @@
             braille.displayRegions(brailleGen.getBrailleRegions(event.source))
             return
 
-        # 2) Writer: spell checking dialog.
+        # 2) Welcome to StarOffice dialog.
         #
-        # Check to see if the Spell Check dialog has just appeared and got
-        # focus. If it has, then speak/braille the current misspelt word
-        # plus its context.
-        #
-        # Note that in order to make sure that this focus event is for the
-        # spell check dialog, a check is made of the localized name of the
-        # option pane. Translators for other locales will need to ensure that
-        # their translation of this string matches what StarOffice uses in
-        # that locale.
-
-        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
-            # 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 - " \
-                    + "Writer: spell check dialog.")
-
-                self.readMisspeltWord(event, pane)
-
-                # Fall-thru to process the event with the default handler.
-
-        # 3) Welcome to StarOffice dialog.
-        #
         # Check to see if the object that just got focus is in the Setup
         # dialog. If it is, then check for a variety of scenerios.
 
@@ -1380,7 +1387,7 @@
                     + "Registration: Register Now radio button.")
                 self.handleSetupPanel(event.source.parent)
 
-        # 4) Calc: cell editor.
+        # 3) Calc: cell editor.
         #
         # Check to see if we are editing a spread sheet cell. If so, just
         # return to avoid uttering something like "Paragraph 0 paragraph".
@@ -1398,7 +1405,7 @@
                           + "Calc: cell editor.")
             return
 
-        # 5) Calc: name box
+        # 4) Calc: name box
         #
         # 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
@@ -1428,7 +1435,7 @@
             speech.speak(_("Move to cell"))
             return
 
-        # 6) Calc: spreadsheet cell.
+        # 5) Calc: spreadsheet cell.
         #
         # Check to see if this is a Calc: spread sheet cell. If it is then
         # we don't want to speak "not selected" after giving the cell
@@ -1457,7 +1464,7 @@
                     self.pointOfReference['lastRow'] = row
                 return
 
-        # 7) Impress: scroll pane.
+        # 6) Impress: scroll pane.
         #
         # If we are in the slide presentation scroll pane, also announce
         # the current page tab. See bug #538056 for more details.
@@ -1483,7 +1490,7 @@
                             speech.speakUtterances(utterances)
             # Fall-thru to process the event with the default handler.
 
-        # 8) Presentation: scroll pane: place holder
+        # 7) Presentation: scroll pane: place holder
         #
         # If we are focused on a place holder element in the slide
         # presentation scroll pane, first present the object, then
@@ -1544,11 +1551,27 @@
                     for label in allLabels:
                         self.speakSetupLabel(label)
         else:
-            # Pass the event onto the parent class to be handled in the
-            # default way.
+            # Clear our stored misspelled word history.
             #
+            self.lastTextLength = -1
+            self.lastBadWord = ''
+            self.lastStartOff = -1
+            self.lastEndOff = -1
+
+            # Let the default script do its thing.
+            #
             default.Script.onWindowActivated(self, event)
 
+            # Maybe it's the spellcheck dialog. Might as well try and see.
+            # If it is, we want to speak the misspelled word and context
+            # after we've spoken the window name.
+            #
+            if event.source.getRole() == pyatspi.ROLE_DIALOG \
+               and event.source.childCount \
+               and event.source[0].getRole() == pyatspi.ROLE_OPTION_PANE:
+                success = self.readMisspeltWord(event, event.source)
+                print "onWindowActivated, trying readMisspeltWord", success
+
     # This method tries to detect and handle the following cases:
     # 1) Writer: spell checking dialog.
 
@@ -1573,33 +1596,14 @@
         # spelling mistake, in which case, speak/braille the current
         # misspelt word plus its context.
         #
-        # Note that in order to make sure that this focus event is for the
-        # spell check dialog, a check is made of the localized name of the
-        # option pane. Translators for other locales will need to ensure that
-        # their translation of this string matches what StarOffice uses in
-        # that locale.
-
         rolesList = [pyatspi.ROLE_OPTION_PANE, \
                      pyatspi.ROLE_DIALOG, \
                      pyatspi.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.")
+        if self.isDesiredFocusedItem(event.source, rolesList) \
+           and self.isSameObject(event.source.parent, orca_state.activeWindow):
+            success = self.readMisspeltWord(event, event.source)
+            print "onNameChanged: is spellcheck dialog?", success
 
-                self.readMisspeltWord(event, pane)
-
-                # Fall-thru to process the event with the default handler.
-
-        # Pass the event onto the parent class to be handled in the default way.
-
         default.Script.onNameChanged(self, event)
 
     def onFocus(self, event):
