Index: atspi.py
===================================================================
--- atspi.py	(revision 1989)
+++ atspi.py	(working copy)
@@ -1276,6 +1276,23 @@
 
         return value
 
+    def attributeSet(self): 
+        try:
+            attributes = self.accessible.getAttributes()
+        except:
+            attributes = None
+        return attributes
+
+    def getAttributeSetDictionary(self):
+        """Orbit returns an AttributeSet in "name:value" string form.
+           This converts that syntax into Python dictionary pairs.
+        """
+        attributeDictionary = {}
+        for item in self.attributeSet():
+            (key,value) = item.split(":",1)
+            attributeDictionary[key] = value
+        return attributeDictionary
+
     def __get_attributes(self):
         """Returns an Accessibility_AttributeSet of the object.
         """
Index: Gecko.py
===================================================================
--- Gecko.py	(revision 1989)
+++ Gecko.py	(working copy)
@@ -87,6 +87,7 @@
                 rolenames.ROLE_PASSWORD_TEXT,
                 rolenames.ROLE_PROGRESS_BAR,
                 rolenames.ROLE_PUSH_BUTTON,
+                rolenames.ROLE_QUOTATION,
                 rolenames.ROLE_RADIO_BUTTON,
                 rolenames.ROLE_RADIO_MENU_ITEM,
                 rolenames.ROLE_RADIO_MENU,
@@ -400,11 +401,24 @@
              self._getSpeechForLink
 
     def _getSpeechForObjectRole(self, obj):
-        """Prevents some roles from being spoken."""
-        if obj.role in [rolenames.ROLE_PARAGRAPH,
-                        rolenames.ROLE_SECTION,
-                        rolenames.ROLE_LABEL,
-                        rolenames.ROLE_UNKNOWN]:
+        """Customize speech for certain roles. Prevent some roles from being
+           spoken.
+        """ 
+        attributes = obj.getAttributeSetDictionary()
+        """Announce quotations"""
+        if settings.announceQuotations and \
+           obj.role == rolenames.ROLE_SECTION and \
+           attributes["tag"] in ["html:blockquote", "BLOCKQUOTE"]:
+            return [rolenames.rolenames[rolenames.ROLE_QUOTATION].speech]
+        elif settings.announceQuotations and \
+             obj.role == rolenames.ROLE_TEXT and \
+             attributes["tag"] in ["html:q", "Q"]:
+            return [rolenames.rolenames[rolenames.ROLE_QUOTATION].speech]
+        elif obj.role in [rolenames.ROLE_SECTION,
+                          rolenames.ROLE_TEXT,
+                          rolenames.ROLE_PARAGRAPH,
+                          rolenames.ROLE_LABEL,
+                          rolenames.ROLE_UNKNOWN]:
             return []
         else:
             return [rolenames.getSpeechForRoleName(obj)]
@@ -2661,11 +2675,16 @@
     # Methods to speak current objects.                                #
     #                                                                  #
     ####################################################################
-
+    
     def getACSS(self, obj, string):
         """Returns the ACSS to speak anything for the given obj."""
+        attributes = obj.getAttributeSetDictionary()
+
         if obj.role == rolenames.ROLE_LINK:
             acss = self.voices[settings.HYPERLINK_VOICE]
+        elif obj.role in [rolenames.ROLE_SECTION, rolenames.ROLE_TEXT] and \
+                attributes["tag"] in ["html:blockquote","BLOCKQUOTE","html:q","Q"]:
+             acss = self.voices[settings.QUOTATION_VOICE]
         elif string and string.isupper():
             acss = self.voices[settings.UPPERCASE_VOICE]
         else:
Index: orca_gui_prefs.py
===================================================================
--- orca_gui_prefs.py	(revision 1989)
+++ orca_gui_prefs.py	(working copy)
@@ -274,6 +274,8 @@
             voiceACSS = self.uppercaseVoice
         elif voiceType == _("Hyperlink"):
             voiceACSS = self.hyperlinkVoice
+        elif voiceType == _("Quotation"):
+            voiceACSS = self.quotationVoice
         else:
             voiceACSS = self.defaultVoice
 
@@ -307,6 +309,12 @@
                 if not useDefault:
                     return None
                 voice = self.defaultVoice
+        elif voiceType == _("Quotation"):
+            voice = self.quotationVoice
+            if not voice.has_key(key):
+                if not useDefault:
+                    return None
+                voice = self.defaultVoice
         else:
             voice = self.defaultVoice
 
@@ -672,6 +680,7 @@
         self.defaultVoice   = acss.ACSS(voices[settings.DEFAULT_VOICE])
         self.uppercaseVoice = acss.ACSS(voices[settings.UPPERCASE_VOICE])
         self.hyperlinkVoice = acss.ACSS(voices[settings.HYPERLINK_VOICE])
+        self.quotationVoice = acss.ACSS(voices[settings.QUOTATION_VOICE])
 
         # Just a note on general naming pattern:
         #
@@ -732,6 +741,9 @@
 
         self.speechIndentationCheckbutton.set_active(\
             prefs["enableSpeechIndentation"])
+        
+        self.announceQuotationsCheckbutton.set_active(\
+            prefs["announceQuotations"])
 
         self.speakBlankLinesCheckButton.set_active(\
             prefs["speakBlankLines"])
@@ -1255,6 +1267,7 @@
             del self.defaultVoice[acss.ACSS.FAMILY]
             del self.uppercaseVoice[acss.ACSS.FAMILY]
             del self.hyperlinkVoice[acss.ACSS.FAMILY]
+            del self.quotationVoice[acss.ACSS.FAMILY]
         except:
             pass
 
@@ -1354,6 +1367,19 @@
         enable = widget.get_active()
         self.prefsDict["enableSpeechIndentation"] = enable
 
+    def announceQuotationsChecked(self, widget):
+        """Signal handler for the "toggled" signal for the
+           announceQuotationsCheckbutton GtkCheckButton widget. The user has
+           [un]checked the 'Announce quotations' checkbox.
+           Set the 'announceQuotations' preference to the new value.
+
+        Arguments:
+        - widget: the component that generated the signal.
+        """
+
+        enable = widget.get_active()
+        self.prefsDict["announceQuotations"] = enable
+
     def speakBlankLinesChecked(self, widget):
         """Signal handler for the "toggled" signal for the
            speakBlankLinesCheckButton GtkCheckButton widget. The user has
@@ -1962,7 +1988,8 @@
         self.prefsDict["voices"] = {
             settings.DEFAULT_VOICE   : acss.ACSS(self.defaultVoice),
             settings.UPPERCASE_VOICE : acss.ACSS(self.uppercaseVoice),
-            settings.HYPERLINK_VOICE : acss.ACSS(self.hyperlinkVoice)
+            settings.HYPERLINK_VOICE : acss.ACSS(self.hyperlinkVoice),
+            settings.QUOTATION_VOICE : acss.ACSS(self.quotationVoice)
         }
 
         if self.disableKeyGrabPref:
Index: orca-setup.glade
===================================================================
--- orca-setup.glade	(revision 1989)
+++ orca-setup.glade	(working copy)
@@ -747,7 +747,8 @@
 			      <property name="visible">True</property>
 			      <property name="items" translatable="yes">Default
 Uppercase
-Hyperlink</property>
+Hyperlink
+Quotation</property>
 			      <property name="add_tearoffs">False</property>
 			      <property name="focus_on_click">True</property>
 			      <accessibility>
@@ -1212,15 +1213,50 @@
 			  <property name="draw_indicator">True</property>
 			  <signal name="toggled" handler="speechIndentationChecked" last_modification_time="Mon, 19 Jun 2006 15:46:40 GMT"/>
 			</widget>
-		      </child>
+		</child>
 		    </widget>
 		    <packing>
 		      <property name="padding">0</property>
 		      <property name="expand">True</property>
 		      <property name="fill">True</property>
 		    </packing>
+		</child>
+
+		  <child>
+		    <widget class="GtkAlignment" id="alignment44">
+		      <property name="visible">True</property>
+		      <property name="xalign">0.5</property>
+		      <property name="yalign">0.5</property>
+		      <property name="xscale">1</property>
+		      <property name="yscale">1</property>
+		      <property name="top_padding">0</property>
+		      <property name="bottom_padding">12</property>
+		      <property name="left_padding">12</property>
+		      <property name="right_padding">12</property>
+
+		      <child>
+			<widget class="GtkCheckButton" id="announceQuotationsCheckbutton">
+			  <property name="visible">True</property>
+			  <property name="can_focus">True</property>
+			  <property name="label" translatable="yes">Announce _quotations</property>
+			  <property name="use_underline">True</property>
+			  <property name="relief">GTK_RELIEF_NORMAL</property>
+			  <property name="focus_on_click">True</property>
+			  <property name="active">False</property>
+			  <property name="inconsistent">False</property>
+			  <property name="draw_indicator">True</property>
+			  <signal name="toggled" handler="announceQuotationsChecked" last_modification_time="Thu, 08 Feb 2007 11:40:00 GMT"/>
+			</widget>
+		</child>
+		    </widget>
+		    <packing>
+		      <property name="padding">0</property>
+		      <property name="expand">True</property>
+		      <property name="fill">True</property>
+		    </packing>
 		  </child>
 
+
 		  <child>
 		    <widget class="GtkAlignment" id="alignment47">
 		      <property name="visible">True</property>
Index: rolenames.py
===================================================================
--- rolenames.py	(revision 1989)
+++ rolenames.py	(working copy)
@@ -109,6 +109,7 @@
 ROLE_TEAR_OFF_MENU_ITEM  = "tear off menu item"
 ROLE_TERMINAL            = "terminal"
 ROLE_TEXT                = "text"
+ROLE_QUOTATION           = "quotation" # invented for items that are quotations
 ROLE_TOGGLE_BUTTON       = "toggle button"
 ROLE_TOOL_BAR            = "tool bar"
 ROLE_TOOL_TIP            = "tool tip"
@@ -396,6 +397,11 @@
                                        _("Button"),
                                        _("button"))
 
+rolenames[ROLE_QUOTATION] = Rolename(ROLE_QUOTATION,
+                                       _("quotation"),
+                                       _("Quotation"),
+                                       _("quotation"))
+
 rolenames[ROLE_RADIO_BUTTON] = Rolename(ROLE_RADIO_BUTTON,
                                         _("radio"),
                                         _("RadioButton"),
@@ -496,6 +502,11 @@
                                 _("Text"),
                                 _("text"))
 
+rolenames[ROLE_QUOTATION] = Rolename(ROLE_QUOTATION,
+                                _("quote"),
+                                _("quotation"),
+                                _("quotation"))
+
 rolenames[ROLE_ENTRY] = rolenames[ROLE_TEXT]
 
 rolenames[ROLE_TOGGLE_BUTTON] = Rolename(ROLE_TOGGLE_BUTTON,
Index: settings.py
===================================================================
--- settings.py	(revision 1989)
+++ settings.py	(working copy)
@@ -66,6 +66,7 @@
 # These are the settings that Orca supports the user customizing.
 #
 userCustomizableSettings = [
+    "announceQuotations",
     "orcaModifierKeys",
     "enableSpeech",
     "speechServerFactory",
@@ -111,6 +112,7 @@
 ]
 
 # The name of the module that hold the user interface for the main window
+
 # for Orca. This module is expected to have two methods, showMainUI and
 # hideMainUI, which will show and hide the main window GUI.
 #
@@ -210,17 +212,26 @@
 DEFAULT_VOICE           = "default"
 UPPERCASE_VOICE         = "uppercase"
 HYPERLINK_VOICE         = "hyperlink"
+QUOTATION_VOICE         = "quotation"
 
 voices = {
     DEFAULT_VOICE   : ACSS({}),
     UPPERCASE_VOICE : ACSS({ACSS.AVERAGE_PITCH : 6}),
-    HYPERLINK_VOICE : ACSS({})
+    HYPERLINK_VOICE : ACSS({}),
+    QUOTATION_VOICE : ACSS({ACSS.AVERAGE_PITCH : 4, 
+                            ACSS.RATE : 40,
+                            ACSS.STRESS : 6})
 }
 
+
 # If True, enable speaking of speech indentation and justification.
 #
 enableSpeechIndentation = False
 
+# If true, enable announcing of quotations.
+#
+announceQuotations = True
+
 # If True, enable braille.
 #
 enableBraille           = True
