Index: src/Perks/DefaultDialogPerk.py
===================================================================
RCS file: /cvs/gnome/lsr/src/Perks/DefaultDialogPerk.py,v
retrieving revision 1.35
diff -u -r1.35 DefaultDialogPerk.py
--- src/Perks/DefaultDialogPerk.py	16 Nov 2006 16:13:34 -0000	1.35
+++ src/Perks/DefaultDialogPerk.py	29 Nov 2006 00:47:44 -0000
@@ -18,6 +18,16 @@
 
 __uie__ = dict(kind='perk', all_tiers=True)
 
+class DefaultDialogPerkState(Perk.PerkState):
+  '''
+  A state class used to store a singleton chooser across multiple perks.
+  '''
+  _chooser = None
+  def setChooser(self, chooser):
+    self._chooser = chooser
+  def getChooser(self):
+    return self._chooser
+
 class DefaultDialogPerk(Perk.Perk):
   '''
   Manages the built in LSR dialogs (e.g. settings).
@@ -27,6 +37,9 @@
   choosers are defined, but not mapped to any particular input device. Some
   other Perk must define the input mappings.
   '''
+  
+  STATE=DefaultDialogPerkState
+
   def init(self):
     '''
     Registers named tasks for the following choosers:
@@ -36,6 +49,7 @@
     '''
     self.registerTask(PerkChooserTask('show perk chooser'))
     self.registerTask(SettingsChooserTask('show settings chooser'))
+    self.registerTask(HandleSettingChange())
     
 class SettingsChooserTask(Task.ChooserTask):
   '''  
@@ -58,7 +72,6 @@
     '''
     self.installed = None
     self.associated = None
-    self.observer = None
     
   def executeStart(self, **kwargs):
     '''
@@ -95,12 +108,8 @@
                                installed=self.installed, 
                                profile=profile, devices=devices)    
     if chooser is not None:
-      # register a task to observe setting changes triggered by Perks so the
-      # chooser can update its view appropriately
-      self.observer = HandleSettingChange()
-      self.registerTask(self.observer)
-      self.observer.setChooser(chooser)
-    
+      self.perk.perk_state.setChooser(chooser)
+
   def _getProfileInfo(self):
     '''
     Populates the installed and associated profile metadata dictionary.
@@ -170,14 +179,12 @@
       self.doApply(chooser, **kwargs)
     elif kind == chooser.OK:
       self.doApply(None, **kwargs)
-      self.unregisterTask(self.observer)
-      self.observer = None
+      self.perk.perk_state.setChooser(None)
     elif kind == chooser.CANCEL:
       # undo any setting changes
       self.doCancel(**kwargs)
-      self.unregisterTask(self.observer)
-      self.observer = None
-      
+      self.perk.perk_state.setChooser(None)
+
     # stop speech and make a model-based announcement
     self.stopNow()
     # inhibit the next event from stopping us (possibly a selection)
@@ -277,14 +284,6 @@
       for name, value in group.restore().items():
         self.signalSetting(group.context, name, value)
         
-  def getChooser(self):
-    '''
-    @return: Reference to the current chooser instance or None if it is not
-      instantiated
-    @rtype: L{AEChooser}
-    '''
-    return self.chooser
-
 class PerkChooserTask(Task.ChooserTask):
   '''  
   Shows the Perk chooser which allows a user to pick Perks to load and unload
@@ -392,26 +391,7 @@
   '''
   Observes setting change notifications and informs an active instance of the
   settings chooser of an update.
-
-  @ivar chooser: Reference to the singleton settings dialog to inform about
-    setting changes in other L{Perk}s.
-  @type chooser: L{AEChooser}
   '''
-  def init(self):
-    self.chooser = None
-    
-  def close(self):
-    '''Throw away the chooser reference to allow garbage collection.'''
-    del self.chooser
-    
-  def setChooser(self, chooser):
-    '''
-    Stores a reference to the chooser to notify on a setting change.
-    
-    @param chooser: Chooser to notify
-    @type chooser: L{AEChooser}
-    '''
-    self.chooser = chooser
   
   def execute(self, source, state, name, value, **kwargs):
     '''
@@ -430,5 +410,8 @@
     @type value: object
     '''
     # if the setting change originated elsewhere, inform the chooser
-    if self.chooser is not source:
-      self.chooser.updateSetting(state, name, value)
+    chooser = self.perk.perk_state.getChooser()
+    if not chooser:
+      return
+    if chooser is not source:
+      chooser.updateSetting(state, name, value)
Index: src/Choosers/SettingsChooser.py
===================================================================
RCS file: /cvs/gnome/lsr/src/Choosers/SettingsChooser.py,v
retrieving revision 1.28
diff -u -r1.28 SettingsChooser.py
--- src/Choosers/SettingsChooser.py	27 Nov 2006 18:03:16 -0000	1.28
+++ src/Choosers/SettingsChooser.py	29 Nov 2006 00:47:44 -0000
@@ -127,13 +127,15 @@
       # enum
       widget = gtk.combo_box_new_text()
       map(widget.append_text, setting.labels)
-      widget.set_active(setting.values.index(setting.value))
+      widget.values_dict = setting.values
+      widget.set_active(widget.values_dict.index(setting.value))
       widget.connect('changed', self._updateChoice, setting)
     elif isinstance(setting, AEState.ChoiceSetting):
       # choice
       widget = gtk.combo_box_new_text()
       map(widget.append_text, setting.values)
-      widget.set_active(setting.values.index(setting.value))
+      widget.values_dict = setting.values
+      widget.set_active(widget.values_dict.index(setting.value))
       widget.connect('changed', self._updateChoice, setting)
     elif isinstance(setting, AEState.ColorSetting):
       # color
@@ -248,6 +250,9 @@
     '''
     # create a widget factory
     self.factory = WidgetFactory(self)
+
+    # Map each widget to a state and name
+    self.setting_contexts = weakref.WeakValueDictionary()
     
     # store group objects
     self.system = system
@@ -496,6 +501,7 @@
     @type group: L{AEState.Setting.Group}
     '''
     n = len(group)
+    state = group.context
     # use a n by 2 table to order widgets nicely
     table = gtk.Table(n, 2)
     table.set_row_spacings(5)
@@ -516,29 +522,26 @@
         # screws up the order in the acc. hierarchy
         table.attach(widget, 0, 2, n-row-1, n-row, yoptions=gtk.FILL, 
                      xpadding=5)
-      elif isinstance(widget, gtk.CheckButton):
-        if setting.description:
-          # set description as tooltip and accessible description
-          self.tips.set_tip(widget, setting.description)
-          Atk.setNameDesc(widget, description=setting.description)
+      else:
+        if isinstance(widget, gtk.CheckButton):
           # check buttons have a label already, so fill the row
           table.attach(widget, 0, 2, n-row-1, n-row, yoptions=gtk.FILL)
-          widget.connect('focus', self._onScrollToFocus, viewport)
-      else:
+        else:
+          # relate the label to the widget
+          Atk.setRelation(widget, atk.RELATION_LABELLED_BY, label)
+          Atk.setRelation(label, atk.RELATION_LABEL_FOR, widget)
+          # attach to the table
+          # note: add widget on the right first then label on the left,
+          # else gail screws up the order in the acc. hierarchy
+          table.attach(widget, 1, 2, n-row-1, n-row, yoptions=gtk.FILL)
+          table.attach(label, 0, 1, n-row-1, n-row, gtk.FILL, gtk.FILL, 5, 0)
+          # watch for focus on the widget so we can scroll
         if setting.description:
           # set description as tooltip and accessible description
           self.tips.set_tip(widget, setting.description)
           Atk.setNameDesc(widget, description=setting.description)
-        # relate the label to the widget
-        Atk.setRelation(widget, atk.RELATION_LABELLED_BY, label)
-        Atk.setRelation(label, atk.RELATION_LABEL_FOR, widget)
-        # attach to the table
-        # nit: add widget on the right first then label on the left, else gail
-        # screws up the order in the acc. hierarchy
-        table.attach(widget, 1, 2, n-row-1, n-row, yoptions=gtk.FILL)
-        table.attach(label, 0, 1, n-row-1, n-row, gtk.FILL, gtk.FILL, 5, 0)
-        # watch for focus on the widget so we can scroll
         widget.connect('focus', self._onScrollToFocus, viewport)
+        self.setting_contexts[(state,setting.variable)] = widget
     return table
   
   def _getAssociated(self):
@@ -623,4 +626,26 @@
     @todo: PP: need to get a reference to the panel showing the given state,
       and the widget representing the named setting
     '''
-    print 'chooser updating', state, name, value
+    try:
+      widget = self.setting_contexts[(state, name)]
+    except KeyError:
+      return
+    
+    if isinstance(widget, gtk.CheckButton):
+      widget.set_active(value)
+    elif isinstance(widget, gtk.FileChooserButton):
+      widget.set_filename(value)
+    elif isinstance(widget, gtk.Entry):
+      widget.set_text(value)
+    elif isinstance(widget, gtk.HScale):
+      widget.set_value(value)
+    elif isinstance(widget, gtk.SpinButton):
+      widget.set_value(value)
+    elif isinstance(widget, gtk.ComboBox):
+      widget.set_active(widget.values_dict.index(value))
+    elif isinstance(widget, gtk.ColorButton):
+      widget.set_color(gtk.gdk.Color(red=value[0],
+                                     green=value[1],
+                                     blue=value[2]))
+      if len(value) > 3:
+        widget.set_alpha(value[3])
