[orca/new-settings] Finished implementation of settings manager and gconf backend.



commit 54473cecf1844dc77ec301d8bbd54a720539c1dc
Author: Alejandro Leiva <aleiva src gnome org>
Date:   Wed Jul 21 10:23:26 2010 +0200

    Finished implementation of settings manager and gconf backend.

 src/orca/Makefile.am                |    4 +-
 src/orca/backends/Makefile.am       |    1 +
 src/orca/backends/gconf_backend.py  |   98 +++++++++--------
 src/orca/backends/gconf_defaults.py |    2 +-
 src/orca/orca-profile.ui            |  202 +++++++++++++++++++++++++++++++++
 src/orca/orca-setup.ui              |  189 +++++++++++++++++++++++++++----
 src/orca/orca_gui_prefs.py          |  143 ++++++++++++++++++++++++-
 src/orca/orca_gui_profile.py        |  209 +++++++++++++++++++++++++++++++++++
 src/orca/settings_manager.py        |    8 ++
 9 files changed, 782 insertions(+), 74 deletions(-)
---
diff --git a/src/orca/Makefile.am b/src/orca/Makefile.am
index 6d67d14..165fa54 100644
--- a/src/orca/Makefile.am
+++ b/src/orca/Makefile.am
@@ -47,6 +47,7 @@ orca_python_PYTHON = \
 	orca_gui_find.py \
 	orca_gui_main.py \
 	orca_gui_prefs.py \
+        orca_gui_profile.py \
 	orca_i18n.py \
 	orca_prefs.py \
 	orca_quit.py \
@@ -85,7 +86,8 @@ ui_DATA = \
 	orca-mainwin.ui \
 	orca-preferences-warning.ui \
 	orca-quit.ui \
-	orca-setup.ui
+	orca-setup.ui \
+        orca-profile.ui
 
 EXTRA_DIST = \
 	$(ui_DATA)
diff --git a/src/orca/backends/Makefile.am b/src/orca/backends/Makefile.am
index a137dd4..a762e10 100644
--- a/src/orca/backends/Makefile.am
+++ b/src/orca/backends/Makefile.am
@@ -7,3 +7,4 @@ orca_python_PYTHON = \
         gconf_defaults.py
 
 orca_pythondir=$(pyexecdir)/orca/backends
+
diff --git a/src/orca/backends/gconf_backend.py b/src/orca/backends/gconf_backend.py
index ce3cfc5..63fa9d8 100644
--- a/src/orca/backends/gconf_backend.py
+++ b/src/orca/backends/gconf_backend.py
@@ -57,7 +57,7 @@ class GConfKeysDict(dict):
 
 class OrcaPrefs():
     # set gconf configuration properties
-    GCONF_DIR = '/apps/gnome-orca'
+    GCONF_BASE_DIR = '/apps/gnome-orca'
     VALID_KEY_TYPES = (bool, str, int, list, tuple)
     import gconf_defaults
 
@@ -68,30 +68,6 @@ class OrcaPrefs():
                 'magCursorColor', 'magCrossHairColor', 'magTargetDisplay', 'magSourceDisplay',
                 'speechRequiredStateString', 'speechServerFactory', 'presentDateFormat', 'presentTimeFormat']
 
-#    need2repr = ['speechServerFactory', 'brailleEOLIndicator', 'magCursorColor', 'magCrossHairColor', 
-#                'magZoomerBorderColor', 'magTargetDisplay', 'magSourceDisplay', 'enabledSpokenTextAttributes',
-#                'enabledBrailledTextAttributes', 'brailleContractionTable']
-
-#    DEFAULTS = {
-#        'speakCellHeaders': True,
-#        'magEdgeMargin': 0,
-#        'brailleContractionTable': '',
-#        'magPointerFollowsFocus': False,
-#        'magTextTrackingMode': 2
-#    }
-
-#    DEFAULTS = {'key-1' : 1,
-#                'key-2' : 'dos',
-#                'key-3' : ['uno', 2],
-#                'key-4' : {'key-4.1': 1, 'clave-4.2' : 'key 4.2 string value',
-#                            'key-4.3' : {'key-4.3.1' : 'key 4.3.1 string value'},
-#                            'key-4.4': ['4.4 List #1', '4.4 List #2', 4.403]
-#                            },
-#                'key-5' : 'key 5 string value',
-#                'key-6' : {'key-6.1' : 'key 6.1 string value'},
-#                'key-7' : 7
-#               }
-
 
     def __init__(self, prefsDict=None, keyBindingsTreeModel=None,
                  pronunciationTreeModel=None):
@@ -109,9 +85,9 @@ class OrcaPrefs():
         """
 
         # init gconf
-        self.__app_key = self.GCONF_DIR
+        self.__app_key = self.GCONF_BASE_DIR
         self._client = gconf.client_get_default()
-        self._client.add_dir(self.GCONF_DIR[:-1], gconf.CLIENT_PRELOAD_RECURSIVE)
+        self._client.add_dir(self.GCONF_BASE_DIR[:-1], gconf.CLIENT_PRELOAD_RECURSIVE)
         self._notifications = []
 
         self.options = GConfKeysDict()
@@ -172,7 +148,7 @@ class OrcaPrefs():
     def __format_gconf_dir(self, dir, entry):
         formatDir = dir.split('/')
 
-        for item in range(3):
+        for item in range(4):
             formatDir.pop(0)
         dictString = 'self.options'
 
@@ -199,10 +175,8 @@ class OrcaPrefs():
                 keyDict = self.options = self.DEFAULTS
             else:
                 keyDict = self.options = self.prefsDict
-
  
         for name, value in keyDict.items():
-            print '### Guardando %s = %s' % (name, value)
             if isinstance(value, dict) and len(value) != 0:
                 self.gconf_save(name, value)
                 self.__app_key = \
@@ -957,7 +931,12 @@ class OrcaPrefs():
         # as a result of this call.
         #
 
+        if not 'activeProfile' in self.prefsDict: self.prefsDict['activeProfile']='default'
+
         if self.prefsDict:
+                self._client.set_string('/apps/gnome-orca/activeProfile',self.prefsDict['activeProfile'])
+                self.__app_key += '/%s' % self.prefsDict['activeProfile']
+                
                 for key in settings.userCustomizableSettings:
                     if key != 'voices':
                         self.prefsDict[key] = self._getValueForKey(self.prefsDict, key) 
@@ -984,7 +963,7 @@ class OrcaPrefs():
 
                 thisIter = self.keyBindingsTreeModel.iter_next(thisIter)
             # Clear overridenkeybindings gconf's dir for a safe store/load 
-            self._client.recursive_unset(self.GCONF_DIR + '/overridenKeyBindings', 
+            self._client.recursive_unset(self.GCONF_BASE_DIR + '/overridenKeyBindings', 
                 gconf.UNSET_INCLUDING_SCHEMA_NAMES)           
             self._client.suggest_sync()
 
@@ -1003,7 +982,7 @@ class OrcaPrefs():
                 thisIter = self.pronunciationTreeModel.iter_next(thisIter)
 
             # Clear pronunciations gconf's dir for a safe store/load 
-            self._client.recursive_unset(self.GCONF_DIR + '/pronunciations',
+            self._client.recursive_unset(self.GCONF_BASE_DIR + '/pronunciations',
                 gconf.UNSET_INCLUDING_SCHEMA_NAMES)
             self._client.suggest_sync()
             
@@ -1017,6 +996,26 @@ class OrcaPrefs():
     def loadSettings(self):
         """Load settings"""
         
+        # if not settings to load, save defaults
+        #
+
+        ## Now, if this the first orca exec, orca should
+        #  show preferences dialog
+        if not self._client.all_entries(self.__app_key):
+            return False
+        else:
+            self.__app_key += '/%s' % self._client.get_string('/apps/gnome-orca/activeProfile')
+        #    self.options = self.DEFAULTS
+        #    self.gconf_save()
+ 
+        # Load gconf settings
+        #
+        self.gconf_load()
+
+        self.settingsDict = self.prefsDict = self.options
+
+        # some imports
+        #
         import orca.debug
         import orca.settings
         from orca import acss
@@ -1028,14 +1027,8 @@ class OrcaPrefs():
             sys.settrace(orca.debug.traceit)
             orca.debug.debugLevel = orca.debug.LEVEL_ALL
 
-        if not self._client.all_entries(self.__app_key):
-            self.options = self.DEFAULTS
-            self.gconf_save()
- 
-        self.gconf_load()
-
-        self.settingsDict = self.prefsDict = self.options
-
+        # Load settings in userCustomizableSettings
+        #
         for key in settings.userCustomizableSettings:
             if key != 'voices' and key != 'speechServerFactory':
                 #value = self._getValueForKey(self.settingsDict, key)
@@ -1048,18 +1041,19 @@ class OrcaPrefs():
                     setting = 'orca.settings.%s = %s' % (key, value)
                     exec setting
 
-        # Load orca.settings.voices
+        # Load orca.settings.speechServerFactory and orca.settings.voices
+        #
         ssfLoad = "orca.settings.speechServerFactory = %s" % self.settingsDict['speechServerFactory']
+        print 'speechServerFactory = ', ssfLoad
         exec(ssfLoad)
 
-
         orca.settings.voices = {
                 'default' : acss.ACSS(self.settingsDict['voices']['default']),
                 'uppercase' : acss.ACSS(self.settingsDict['voices']['uppercase']),
                 'hyperlink' : acss.ACSS(self.settingsDict['voices']['hyperlink'])}
 
-
-        #return UserSettings
+        # Load orca.pronunciation_dict
+        #
         import orca.pronunciation_dict
 
         orca.pronunciation_dict.pronunciation_dict={}
@@ -1068,8 +1062,8 @@ class OrcaPrefs():
 
         import orca.orca_state
 
-        ## Load keybindings
-        
+        # Load keybindings
+        #
         orca.settings.overrideKeyBindings = self.__loadOverridenKeyBindings
 
         try:
@@ -1128,6 +1122,10 @@ def readPreferences():
         except:
             pass 
 
+    # must be in userCustomizableSettings
+    # profile support
+    prefsDict['activeProfile'] = gconf.client_get_default().get_string('/apps/gnome-orca/activeProfile')
+
     return prefsDict
 
 def writePreferences(prefsDict, keyBindingsTreeModel=None,
@@ -1162,3 +1160,11 @@ def loadSettings():
     print '\n## loaded from gconf_backend!!'
     
     return orcaPrefs.loadSettings()
+
+def availableProfiles():
+    """Returns available profiles"""
+    
+    client = gconf.client_get_default()
+    profiles = client.all_dirs('/apps/gnome-orca')
+    profiles = [profiles[profiles.index(profile)].split('/apps/gnome-orca/')[1] for profile in profiles] 
+    return profiles 
diff --git a/src/orca/backends/gconf_defaults.py b/src/orca/backends/gconf_defaults.py
index 5cd0191..45a709e 100644
--- a/src/orca/backends/gconf_defaults.py
+++ b/src/orca/backends/gconf_defaults.py
@@ -111,7 +111,7 @@ defaults = {'speakCellHeaders': True,
  'voices': {'default' : orca.acss.ACSS({'average-pitch': 5.0,
                                         'gain': 10.0,
                                         'rate': 50.0,
-                                        'family' : {}}),
+                                        'family' : {'locale': 'english', 'name' : 'kal_diphone'}}),
             'uppercase' : orca.acss.ACSS({'average-pitch': 5.5999999999999996}),
             'hyperlink' : orca.acss.ACSS({'average-pitch': 5.5999999999999996})},
  'enabledBrailledTextAttributes': "size:; family-name:; weight:400; indent:0; underline:none; strikethrough:false; justification:left; style:normal; text-spelling:none;",
diff --git a/src/orca/orca-profile.ui b/src/orca/orca-profile.ui
new file mode 100644
index 0000000..8a28f5f
--- /dev/null
+++ b/src/orca/orca-profile.ui
@@ -0,0 +1,202 @@
+<?xml version="1.0"?>
+<interface>
+  <!-- interface-requires gtk+ 2.12 -->
+  <!-- interface-naming-policy toplevel-contextual -->
+  <object class="GtkDialog" id="profileDialog">
+    <property name="title" translatable="yes">Save profile as</property>
+    <property name="resizable">False</property>
+    <property name="modal">True</property>
+    <property name="type_hint">dialog</property>
+    <property name="has_separator">False</property>
+    <child internal-child="accessible">
+      <object class="AtkObject" id="profileDialog-atkobject">
+        <property name="AtkObject::accessible-name" translatable="yes">Orca Profile Dialog</property>
+      </object>
+    </child>
+    <signal name="destroy" handler="profileDialogDestroyed"/>
+    <child internal-child="vbox">
+      <object class="GtkVBox" id="dialog-vbox1">
+        <property name="visible">True</property>
+        <child>
+          <object class="GtkVBox" id="vbox1">
+            <property name="visible">True</property>
+            <property name="border_width">6</property>
+            <property name="spacing">12</property>
+            <child>
+              <object class="GtkHBox" id="hbox2">
+                <property name="visible">True</property>
+                <property name="border_width">6</property>
+                <child>
+                  <object class="GtkLabel" id="ProfilesLabel">
+                    <property name="visible">True</property>
+                    <property name="label" translatable="yes">_Profiles:</property>
+                    <property name="use_markup">True</property>
+                    <property name="use_underline">True</property>
+                    <property name="mnemonic_widget">availableProfilesCombo</property>
+                    <property name="width_chars">12</property>
+                    <child internal-child="accessible">
+                      <object class="AtkObject" id="ProfilesLabel-atkobject">
+                        <property name="AtkObject::accessible-name" translatable="yes">New Profile:</property>
+                      </object>
+                    </child>
+                  </object>
+                  <packing>
+                    <property name="expand">False</property>
+                    <property name="fill">False</property>
+                    <property name="position">0</property>
+                  </packing>
+                </child>
+                <child>
+                  <object class="GtkComboBox" id="availableProfilesCombo">
+                    <property name="visible">True</property>
+                    <property name="model">liststore1</property>
+                    <child>
+                      <object class="GtkCellRendererText" id="cellrenderertext1"/>
+                      <attributes>
+                        <attribute name="text">0</attribute>
+                      </attributes>
+                    </child>
+                  </object>
+                  <packing>
+                    <property name="expand">False</property>
+                    <property name="fill">False</property>
+                    <property name="position">1</property>
+                  </packing>
+                </child>
+              </object>
+              <packing>
+                <property name="position">0</property>
+              </packing>
+            </child>
+            <child>
+              <object class="GtkHBox" id="hbox1">
+                <property name="visible">True</property>
+                <property name="border_width">6</property>
+                <child>
+                  <object class="GtkLabel" id="profileLabel">
+                    <property name="visible">True</property>
+                    <property name="label" translatable="yes">_New Profile:</property>
+                    <property name="use_markup">True</property>
+                    <property name="use_underline">True</property>
+                    <property name="mnemonic_widget">profileEntry</property>
+                    <property name="width_chars">12</property>
+                    <child internal-child="accessible">
+                      <object class="AtkObject" id="profileLabel-atkobject">
+                        <property name="AtkObject::accessible-name" translatable="yes">New Profile:</property>
+                      </object>
+                    </child>
+                  </object>
+                  <packing>
+                    <property name="expand">False</property>
+                    <property name="fill">False</property>
+                    <property name="position">0</property>
+                  </packing>
+                </child>
+                <child>
+                  <object class="GtkEntry" id="profileEntry">
+                    <property name="visible">True</property>
+                    <property name="can_focus">True</property>
+                    <property name="invisible_char">&#x25CF;</property>
+                    <property name="activates_default">True</property>
+                    <child internal-child="accessible">
+                      <object class="AtkObject" id="profileEntry-atkobject">
+                        <property name="AtkObject::accessible-name" translatable="yes">New Profile:</property>
+                      </object>
+                    </child>
+                    <signal name="changed" handler="onProfileEntryChanged"/>
+                  </object>
+                  <packing>
+                    <property name="position">1</property>
+                  </packing>
+                </child>
+              </object>
+              <packing>
+                <property name="position">1</property>
+              </packing>
+            </child>
+            <child>
+              <object class="GtkLabel" id="profileInfoLabel">
+                <property name="visible">True</property>
+                <property name="label" translatable="yes">New settings will be saved
+automatically and preferences
+dialog will be closed.</property>
+              </object>
+              <packing>
+                <property name="position">2</property>
+              </packing>
+            </child>
+          </object>
+          <packing>
+            <property name="padding">5</property>
+            <property name="position">1</property>
+          </packing>
+        </child>
+        <child internal-child="action_area">
+          <object class="GtkHButtonBox" id="dialog-action_area1">
+            <property name="visible">True</property>
+            <property name="layout_style">end</property>
+            <child>
+              <object class="GtkButton" id="closeButton">
+                <property name="label">gtk-close</property>
+                <property name="visible">True</property>
+                <property name="can_focus">True</property>
+                <property name="can_default">True</property>
+                <property name="receives_default">False</property>
+                <property name="use_stock">True</property>
+                <accelerator key="c" signal="activate" modifiers="GDK_MOD1_MASK"/>
+                <child internal-child="accessible">
+                  <object class="AtkObject" id="closeButton-atkobject">
+                    <property name="AtkObject::accessible-name" translatable="yes">Close</property>
+                  </object>
+                </child>
+                <signal name="clicked" handler="closeButtonClicked"/>
+              </object>
+              <packing>
+                <property name="expand">False</property>
+                <property name="fill">False</property>
+                <property name="position">0</property>
+              </packing>
+            </child>
+            <child>
+              <object class="GtkButton" id="saveProfileButton">
+                <property name="label">gtk-ok</property>
+                <property name="visible">True</property>
+                <property name="can_focus">True</property>
+                <property name="can_default">True</property>
+                <property name="has_default">True</property>
+                <property name="receives_default">False</property>
+                <property name="use_stock">True</property>
+                <child internal-child="accessible">
+                  <object class="AtkObject" id="saveProfileButton-atkobject">
+                    <property name="AtkObject::accessible-name" translatable="yes">Add Profile</property>
+                  </object>
+                </child>
+                <signal name="clicked" handler="on_saveProfileButton_clicked"/>
+              </object>
+              <packing>
+                <property name="expand">False</property>
+                <property name="fill">False</property>
+                <property name="position">1</property>
+              </packing>
+            </child>
+          </object>
+          <packing>
+            <property name="expand">False</property>
+            <property name="pack_type">end</property>
+            <property name="position">0</property>
+          </packing>
+        </child>
+      </object>
+    </child>
+    <action-widgets>
+      <action-widget response="-7">closeButton</action-widget>
+      <action-widget response="0">saveProfileButton</action-widget>
+    </action-widgets>
+  </object>
+  <object class="GtkListStore" id="liststore1">
+    <columns>
+      <!-- column-name profiles -->
+      <column type="gchararray"/>
+    </columns>
+  </object>
+</interface>
diff --git a/src/orca/orca-setup.ui b/src/orca/orca-setup.ui
index 46ea8a6..92d9e09 100644
--- a/src/orca/orca-setup.ui
+++ b/src/orca/orca-setup.ui
@@ -238,6 +238,12 @@
       <column type="gchararray"/>
     </columns>
   </object>
+  <object class="GtkListStore" id="model9">
+    <columns>
+      <!-- column-name profiles -->
+      <column type="gchararray"/>
+    </columns>
+  </object>
   <object class="GtkDialog" id="orcaSetupWindow">
     <property name="title" translatable="yes">Orca Preferences</property>
     <property name="type_hint">normal</property>
@@ -247,13 +253,11 @@
     <child internal-child="vbox">
       <object class="GtkVBox" id="dialog-vbox1">
         <property name="visible">True</property>
-        <property name="orientation">vertical</property>
         <property name="spacing">3</property>
         <child>
           <object class="GtkVBox" id="mainvbox">
             <property name="visible">True</property>
             <property name="border_width">6</property>
-            <property name="orientation">vertical</property>
             <property name="spacing">12</property>
             <child>
               <object class="GtkNotebook" id="notebook">
@@ -263,7 +267,6 @@
                   <object class="GtkVBox" id="generalVBox">
                     <property name="visible">True</property>
                     <property name="border_width">12</property>
-                    <property name="orientation">vertical</property>
                     <child>
                       <object class="GtkFrame" id="frame9">
                         <property name="visible">True</property>
@@ -277,7 +280,6 @@
                               <object class="GtkVBox" id="vbox22">
                                 <property name="visible">True</property>
                                 <property name="border_width">3</property>
-                                <property name="orientation">vertical</property>
                                 <child>
                                   <object class="GtkRadioButton" id="generalDesktopButton">
                                     <property name="label" translatable="yes">_Desktop</property>
@@ -529,7 +531,6 @@
                   <object class="GtkVBox" id="vbox20">
                     <property name="visible">True</property>
                     <property name="border_width">12</property>
-                    <property name="orientation">vertical</property>
                     <child>
                       <object class="GtkCheckButton" id="speechSupportCheckButton">
                         <property name="label" translatable="yes">_Enable speech</property>
@@ -551,7 +552,6 @@
                       <object class="GtkVBox" id="speechVbox">
                         <property name="visible">True</property>
                         <property name="border_width">12</property>
-                        <property name="orientation">vertical</property>
                         <property name="spacing">6</property>
                         <child>
                           <object class="GtkTable" id="speechTable">
@@ -951,7 +951,6 @@
                                               <object class="GtkVBox" id="vbox17">
                                                 <property name="visible">True</property>
                                                 <property name="border_width">3</property>
-                                                <property name="orientation">vertical</property>
                                                 <child>
                                                   <object class="GtkRadioButton" id="speechBriefButton">
                                                     <property name="label" translatable="yes">Brie_f</property>
@@ -1021,7 +1020,6 @@
                                               <object class="GtkVBox" id="vbox21">
                                                 <property name="visible">True</property>
                                                 <property name="border_width">3</property>
-                                                <property name="orientation">vertical</property>
                                                 <child>
                                                   <object class="GtkRadioButton" id="cellSpeechButton">
                                                     <property name="label" translatable="yes" comments="Translators: This is one of two options available in the Preferences dialog for the Table Rows setting. If chosen, Orca will speak just the new cell when the user arrows Up or Down in a table.">Speak _cell</property>
@@ -1119,7 +1117,6 @@
                                                 <child>
                                                   <object class="GtkVBox" id="progressBarVBox">
                                                     <property name="visible">True</property>
-                                                    <property name="orientation">vertical</property>
                                                     <child>
                                                       <object class="GtkHBox" id="speakUpdateIntervalHBox">
                                                         <property name="visible">True</property>
@@ -1448,7 +1445,6 @@
                   <object class="GtkVBox" id="brailleVbox">
                     <property name="visible">True</property>
                     <property name="border_width">12</property>
-                    <property name="orientation">vertical</property>
                     <property name="spacing">12</property>
                     <child>
                       <object class="GtkTable" id="table2">
@@ -1459,7 +1455,6 @@
                         <child>
                           <object class="GtkVBox" id="vbox23">
                             <property name="visible">True</property>
-                            <property name="orientation">vertical</property>
                             <child>
                               <object class="GtkCheckButton" id="enableBrailleCheckButton">
                                 <property name="label" translatable="yes">Enable Braille _support</property>
@@ -1603,7 +1598,6 @@
                                   <object class="GtkVBox" id="vbox18">
                                     <property name="visible">True</property>
                                     <property name="border_width">3</property>
-                                    <property name="orientation">vertical</property>
                                     <child>
                                       <object class="GtkRadioButton" id="brailleBriefButton">
                                         <property name="label" translatable="yes">Brie_f</property>
@@ -1668,7 +1662,6 @@
                                   <object class="GtkVBox" id="vbox28">
                                     <property name="visible">True</property>
                                     <property name="border_width">3</property>
-                                    <property name="orientation">vertical</property>
                                     <child>
                                       <object class="GtkRadioButton" id="brailleSelectionNoneButton">
                                         <property name="label" translatable="yes">_None</property>
@@ -1766,7 +1759,6 @@
                                 <child>
                                   <object class="GtkVBox" id="vbox35">
                                     <property name="visible">True</property>
-                                    <property name="orientation">vertical</property>
                                     <child>
                                       <object class="GtkRadioButton" id="brailleLinkNoneButton">
                                         <property name="label" translatable="yes">_None</property>
@@ -1881,7 +1873,6 @@
                   <object class="GtkVBox" id="keyechoVbox">
                     <property name="visible">True</property>
                     <property name="border_width">12</property>
-                    <property name="orientation">vertical</property>
                     <child>
                       <object class="GtkCheckButton" id="keyEchoCheckButton">
                         <property name="label" translatable="yes">Enable _key echo</property>
@@ -2131,7 +2122,6 @@
                   <object class="GtkVBox" id="vbox19">
                     <property name="visible">True</property>
                     <property name="border_width">12</property>
-                    <property name="orientation">vertical</property>
                     <child>
                       <object class="GtkCheckButton" id="magnifierSupportCheckButton">
                         <property name="label" translatable="yes">Enable _magnifier</property>
@@ -2555,7 +2545,6 @@
                                     <child>
                                       <object class="GtkVBox" id="vbox33">
                                         <property name="visible">True</property>
-                                        <property name="orientation">vertical</property>
                                         <child>
                                           <object class="GtkAlignment" id="alignment83">
                                             <property name="visible">True</property>
@@ -2761,7 +2750,6 @@
                                     <child>
                                       <object class="GtkVBox" id="vbox32">
                                         <property name="visible">True</property>
-                                        <property name="orientation">vertical</property>
                                         <child>
                                           <object class="GtkAlignment" id="alignment81">
                                             <property name="visible">True</property>
@@ -3112,7 +3100,6 @@
                                     <child>
                                       <object class="GtkVBox" id="vbox31">
                                         <property name="visible">True</property>
-                                        <property name="orientation">vertical</property>
                                         <child>
                                           <object class="GtkAlignment" id="alignment78">
                                             <property name="visible">True</property>
@@ -3577,7 +3564,6 @@
                   <object class="GtkVBox" id="keyBindingsVBox">
                     <property name="visible">True</property>
                     <property name="border_width">12</property>
-                    <property name="orientation">vertical</property>
                     <property name="spacing">6</property>
                     <child>
                       <object class="GtkHBox" id="hbox36">
@@ -3656,7 +3642,6 @@
                 <child>
                   <object class="GtkVBox" id="vbox29">
                     <property name="visible">True</property>
-                    <property name="orientation">vertical</property>
                     <child>
                       <object class="GtkFrame" id="pronunciationFrame">
                         <property name="visible">True</property>
@@ -3770,7 +3755,6 @@
                             <child>
                               <object class="GtkVBox" id="vbox24">
                                 <property name="visible">True</property>
-                                <property name="orientation">vertical</property>
                                 <child>
                                   <object class="GtkScrolledWindow" id="scrolledwindow2">
                                     <property name="visible">True</property>
@@ -3864,7 +3848,6 @@
                     <child>
                       <object class="GtkVBox" id="vbox26">
                         <property name="visible">True</property>
-                        <property name="orientation">vertical</property>
                         <property name="homogeneous">True</property>
                         <child>
                           <object class="GtkFrame" id="adjustAttributesFrame">
@@ -3880,7 +3863,6 @@
                                   <object class="GtkVBox" id="vbox25">
                                     <property name="visible">True</property>
                                     <property name="border_width">5</property>
-                                    <property name="orientation">vertical</property>
                                     <child>
                                       <object class="GtkButton" id="textMoveToTopButton">
                                         <property name="label" translatable="yes" comments="Translators:  This label is on a button on the Text Attributes pane of the Orca Preferences dialog. On that pane there is a long list of possible text attributes. The user can select one and then, by using the Move to _top button, move that attribute to the top of the list. The ordering in the list is important as Orca will speak the selected text attributes in the given order.">Move to _top</property>
@@ -3978,7 +3960,6 @@ attributes&lt;/b&gt;</property>
                                   <object class="GtkVBox" id="vbox27">
                                     <property name="visible">True</property>
                                     <property name="border_width">3</property>
-                                    <property name="orientation">vertical</property>
                                     <child>
                                       <object class="GtkRadioButton" id="textBrailleNoneButton">
                                         <property name="label" translatable="yes">_None</property>
@@ -4085,6 +4066,164 @@ attributes&lt;/b&gt;</property>
                     <property name="tab_fill">False</property>
                   </packing>
                 </child>
+                <child>
+                  <object class="GtkVBox" id="profilesVbox">
+                    <property name="visible">True</property>
+                    <child>
+                      <object class="GtkFrame" id="userProfilesFrame">
+                        <property name="visible">True</property>
+                        <property name="label_xalign">0</property>
+                        <property name="label_yalign">1</property>
+                        <property name="shadow_type">none</property>
+                        <child>
+                          <object class="GtkAlignment" id="alignment5">
+                            <property name="visible">True</property>
+                            <property name="top_padding">5</property>
+                            <property name="left_padding">12</property>
+                            <child>
+                              <object class="GtkTable" id="userProfilesTable1">
+                                <property name="visible">True</property>
+                                <property name="n_rows">3</property>
+                                <property name="n_columns">2</property>
+                                <property name="column_spacing">10</property>
+                                <child>
+                                  <object class="GtkComboBox" id="availableProfilesComboBox">
+                                    <property name="visible">True</property>
+                                    <property name="model">model9</property>
+                                    <child>
+                                      <object class="GtkCellRendererText" id="cellrenderertext3"/>
+                                      <attributes>
+                                        <attribute name="text">0</attribute>
+                                      </attributes>
+                                    </child>
+                                  </object>
+                                  <packing>
+                                    <property name="left_attach">1</property>
+                                    <property name="right_attach">2</property>
+                                    <property name="x_options">GTK_FILL</property>
+                                  </packing>
+                                </child>
+                                <child>
+                                  <object class="GtkLabel" id="availableProfilesLabel">
+                                    <property name="visible">True</property>
+                                    <property name="xalign">1</property>
+                                    <property name="label" translatable="yes">Available Profiles:</property>
+                                    <property name="use_underline">True</property>
+                                    <property name="justify">right</property>
+                                    <property name="mnemonic_widget">availableProfilesComboBox</property>
+                                    <accessibility>
+                                      <relation type="label-for" target="speechServers"/>
+                                    </accessibility>
+                                  </object>
+                                  <packing>
+                                    <property name="x_options">GTK_FILL</property>
+                                    <property name="y_options"></property>
+                                  </packing>
+                                </child>
+                                <child>
+                                  <object class="GtkLabel" id="saveProfileLabel">
+                                    <property name="visible">True</property>
+                                    <property name="xalign">1</property>
+                                    <property name="label" translatable="yes">Save profile as:</property>
+                                    <property name="use_underline">True</property>
+                                    <property name="justify">right</property>
+                                    <property name="mnemonic_widget">saveProfileButton</property>
+                                    <accessibility>
+                                      <relation type="label-for" target="speechSystems"/>
+                                    </accessibility>
+                                  </object>
+                                  <packing>
+                                    <property name="top_attach">2</property>
+                                    <property name="bottom_attach">3</property>
+                                    <property name="x_options">GTK_FILL</property>
+                                    <property name="y_options"></property>
+                                  </packing>
+                                </child>
+                                <child>
+                                  <object class="GtkButton" id="saveProfileButton">
+                                    <property name="label">gtk-save</property>
+                                    <property name="visible">True</property>
+                                    <property name="can_focus">True</property>
+                                    <property name="receives_default">True</property>
+                                    <property name="use_stock">True</property>
+                                    <signal name="clicked" handler="showProfileGUI"/>
+                                  </object>
+                                  <packing>
+                                    <property name="left_attach">1</property>
+                                    <property name="right_attach">2</property>
+                                    <property name="top_attach">2</property>
+                                    <property name="bottom_attach">3</property>
+                                    <property name="x_options">GTK_FILL</property>
+                                  </packing>
+                                </child>
+                                <child>
+                                  <object class="GtkLabel" id="loadProfileLabel">
+                                    <property name="visible">True</property>
+                                    <property name="xalign">1</property>
+                                    <property name="label" translatable="yes">Load selected profile:</property>
+                                    <property name="use_underline">True</property>
+                                    <property name="justify">right</property>
+                                    <property name="mnemonic_widget">loadProfileButton</property>
+                                    <accessibility>
+                                      <relation type="label-for" target="speechSystems"/>
+                                    </accessibility>
+                                  </object>
+                                  <packing>
+                                    <property name="top_attach">1</property>
+                                    <property name="bottom_attach">2</property>
+                                    <property name="x_options">GTK_FILL</property>
+                                    <property name="y_options"></property>
+                                  </packing>
+                                </child>
+                                <child>
+                                  <object class="GtkButton" id="loadProfileButton">
+                                    <property name="label" translatable="yes">Load</property>
+                                    <property name="visible">True</property>
+                                    <property name="can_focus">True</property>
+                                    <property name="receives_default">True</property>
+                                    <signal name="clicked" handler="loadProfileButtonClicked"/>
+                                  </object>
+                                  <packing>
+                                    <property name="left_attach">1</property>
+                                    <property name="right_attach">2</property>
+                                    <property name="top_attach">1</property>
+                                    <property name="bottom_attach">2</property>
+                                    <property name="x_options">GTK_FILL</property>
+                                  </packing>
+                                </child>
+                              </object>
+                            </child>
+                          </object>
+                        </child>
+                        <child type="label">
+                          <object class="GtkLabel" id="userProfilesLabel">
+                            <property name="visible">True</property>
+                            <property name="label" translatable="yes">&lt;b&gt;Orca User Profiles&lt;/b&gt;</property>
+                            <property name="use_markup">True</property>
+                          </object>
+                        </child>
+                      </object>
+                      <packing>
+                        <property name="expand">False</property>
+                        <property name="padding">5</property>
+                        <property name="position">0</property>
+                      </packing>
+                    </child>
+                  </object>
+                  <packing>
+                    <property name="position">8</property>
+                  </packing>
+                </child>
+                <child type="tab">
+                  <object class="GtkLabel" id="profilesTabLabel">
+                    <property name="visible">True</property>
+                    <property name="label" translatable="yes">Profiles</property>
+                  </object>
+                  <packing>
+                    <property name="position">8</property>
+                    <property name="tab_fill">False</property>
+                  </packing>
+                </child>
               </object>
               <packing>
                 <property name="padding">3</property>
diff --git a/src/orca/orca_gui_prefs.py b/src/orca/orca_gui_prefs.py
index 96bdca6..de5ebbf 100644
--- a/src/orca/orca_gui_prefs.py
+++ b/src/orca/orca_gui_prefs.py
@@ -54,6 +54,8 @@ import speech
 import speechserver
 import text_attribute_names
 
+import orca_gui_profile
+
 from settings_manager import SettingsManager
 
 try:
@@ -207,7 +209,13 @@ class OrcaSetupGUI(orca_gtkbuilder.GtkBuilderWrapper):
             self.savedRate = 50.0
 
         # ***** Key Bindings treeview initialization *****
+
         self.keyBindView = self.get_widget("keyBindingsTreeview")
+        
+        if self.keyBindView.get_columns():
+            for column in self.keyBindView.get_columns():
+                self.keyBindView.remove_column(column)
+
         self.keyBindingsModel = gtk.TreeStore(
             gobject.TYPE_STRING,  # Handler name
             gobject.TYPE_STRING,  # Human Readable Description
@@ -1158,6 +1166,11 @@ class OrcaSetupGUI(orca_gtkbuilder.GtkBuilderWrapper):
         """
 
         self.getTextAttributesView = self.get_widget("textAttributesTreeView")
+
+        if self.getTextAttributesView.get_columns():
+            for column in self.getTextAttributesView.get_columns():
+                self.getTextAttributesView.remove_column(column)
+
         model = gtk.ListStore(gobject.TYPE_STRING,
                               gobject.TYPE_BOOLEAN,
                               gobject.TYPE_BOOLEAN,
@@ -1328,6 +1341,11 @@ class OrcaSetupGUI(orca_gtkbuilder.GtkBuilderWrapper):
         """
 
         self.pronunciationView = self.get_widget("pronunciationTreeView")
+
+        if self.pronunciationView.get_columns():
+            for column in self.pronunciationView.get_columns():
+                self.pronunciationView.remove_column(column)
+
         model = gtk.ListStore(gobject.TYPE_STRING,
                               gobject.TYPE_STRING)
 
@@ -1734,6 +1752,7 @@ class OrcaSetupGUI(orca_gtkbuilder.GtkBuilderWrapper):
                             selectedTable:
                         selectedTableIter = it
                 cell = self.planeCellRendererText
+                tablesCombo.clear()
                 tablesCombo.pack_start(cell, True)
                 tablesCombo.add_attribute(cell, 'text', 0)
                 tablesCombo.set_model(tablesModel)
@@ -2131,6 +2150,52 @@ class OrcaSetupGUI(orca_gtkbuilder.GtkBuilderWrapper):
         self.get_widget("autostartOrcaCheckButton").set_active( \
                          self.enableAutostart)
 
+        
+        # Orca User Profiles
+        #
+        self.profilesCombo = self.get_widget('availableProfilesComboBox')
+        self.profilesComboModel = self.get_widget('model9')
+        
+        availableProfiles = self.__getAvailableProfiles()
+        iterChilds = {}
+        self.profilesComboModel.clear()
+
+        if not len(availableProfiles):
+            iterChilds.update({'default' : self.profilesComboModel.append(['default'])})
+        else:
+            for profile in availableProfiles:
+                iterChilds.update({profile: self.profilesComboModel.append([profile])})
+
+        if 'activeProfile' in prefs:
+            activeProfile = prefs['activeProfile']
+        else: 
+            activeProfile = 'default'
+
+        activeProfileItem = int(self.profilesComboModel.get_string_from_iter(iterChilds[activeProfile]))
+
+        # If not classic backend, show active profile
+        if not 'classic' in self.get_widget('userProfilesLabel').get_text():
+            self.get_widget('userProfilesLabel').set_markup('<b>Orca User Profiles:</b> <i>(Using <b>%s</b> profile)</i>' % activeProfile)
+        
+        self.profilesCombo.set_active(activeProfileItem)
+
+        
+    def __getAvailableProfiles(self):
+        """Get available user profiles"""
+
+        _settingsManager = SettingsManager()
+        _settingsManager.loadBackend()
+
+        if _settingsManager.DEFAULT_BACKEND == 'classic':
+            # If classic backend, disable profile features
+            self.get_widget('userProfilesFrame').set_sensitive(False)
+            self.get_widget('userProfilesLabel').set_markup('<b>Orca User Profiles</b> <i>(Not available in classic backend!)</i>')
+            return ['default']
+        else:
+            return _settingsManager.availableProfiles()
+
+
+
     def populateComboBox(self, combobox, items):
         """Populates the combobox with the items provided.
 
@@ -4193,6 +4258,8 @@ class OrcaSetupGUI(orca_gtkbuilder.GtkBuilderWrapper):
                 settings.HYPERLINK_VOICE : acss.ACSS(self.hyperlinkVoice)
             }
 
+        #self.prefsDict['activeProfile'] = self.profilesCombo.get_active_text()
+
         settings.setGKSUGrabDisabled(self.disableKeyGrabPref)
 
         try:
@@ -4227,7 +4294,7 @@ class OrcaSetupGUI(orca_gtkbuilder.GtkBuilderWrapper):
         self.windowClosed(widget)
         self.get_widget("orcaSetupWindow").destroy()
 
-    def okButtonClicked(self, widget):
+    def okButtonClicked(self, widget = None):
         """Signal handler for the "clicked" signal for the okButton
            GtkButton widget. The user has clicked the OK button.
            Write out the users preferences. If GNOME accessibility hadn't
@@ -4289,6 +4356,80 @@ class OrcaSetupGUI(orca_gtkbuilder.GtkBuilderWrapper):
 
         return self.orcaMagAdvancedDialog
 
+    def showProfileGUI(self, widget):
+        """Show profile Dialog to add a new one"""
+
+        profileToSave = orca_gui_profile.showProfileUI()
+
+        if isinstance(profileToSave, str) and profileToSave != '':
+            # If applyButtonClicked is needed, then this code will be uncommented,
+            # then new profile will be stored in profileCombo
+            #profile = {profileToSave: self.profilesComboModel.append([profileToSave])}
+            #activeProfile = int(self.profilesComboModel.get_string_from_iter(profile[profileToSave]))
+            #self.profilesCombo.set_active(activeProfile)
+
+            self.prefsDict['activeProfile'] = profileToSave.replace(' ','_')
+            self.okButtonClicked()
+
+    def loadProfileButtonClicked(self, widget):
+        """Load selected profile"""
+
+        print 'loading profile!'
+
+        if not self._isInitialSetup:
+            self.restoreSettings()
+
+        enable = self.get_widget("speechSupportCheckButton").get_active()
+        self.prefsDict["enableSpeech"] = enable
+
+        if self.speechSystemsChoice:
+            self.prefsDict["speechServerFactory"] = \
+                self.speechSystemsChoice.__name__
+
+        if self.speechServersChoice:
+            self.prefsDict["speechServerInfo"] = \
+                self.speechServersChoice.getInfo()
+
+        if self.defaultVoice != None:
+            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.setGKSUGrabDisabled(self.disableKeyGrabPref)
+
+        try:
+            status = settings.setOrcaAutostart(self.enableAutostart)
+            self.get_widget("autostartOrcaCheckButton").set_active(\
+                settings.isOrcaAutostarted())
+        except:
+            # If we are pressing Apply or OK from an application preferences
+            # dialog (rather than the general Orca preferences), then there
+            # won't be a general pane, so we won't be able to adjust this
+            # checkbox.
+            #
+            pass
+
+        #self.writeUserPreferences()
+        import gconf
+        gclient = gconf.client_get_default()
+        gclient.set_string('/apps/gnome-orca/activeProfile', self.profilesCombo.get_active_text())
+        
+        orca.loadUserSettings()
+        
+        _settingsManager = SettingsManager()
+        _settingsManager.loadBackend()
+
+        self.prefsDict = _settingsManager.readPreferences() 
+
+        self.init()
+
+        self._initSpeechState()
+
+        self._populateKeyBindings()
+
+
 class OrcaAdvancedMagGUI(OrcaSetupGUI):
 
     def __init__(self, fileName, windowName, prefsDict = None):
diff --git a/src/orca/orca_gui_profile.py b/src/orca/orca_gui_profile.py
new file mode 100644
index 0000000..04e949a
--- /dev/null
+++ b/src/orca/orca_gui_profile.py
@@ -0,0 +1,209 @@
+# Orca
+#
+# Copyright 2010 Consorcio Fernando de los Rios.
+# Author: Javier Hernandez Antunez <jhernandez emergya es>
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Library General Public
+# License as published by the Free Software Foundation; either
+# version 2 of the License, or (at your option) any later version.
+#
+# This library is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+# Library General Public License for more details.
+#
+# You should have received a copy of the GNU Library General Public
+# License along with this library; if not, write to the
+# Free Software Foundation, Inc., Franklin Street, Fifth Floor,
+# Boston MA  02110-1301 USA.
+
+"""Displays a GUI for the Orca Find window"""
+
+__id__        = "$Id$"
+__version__   = "$Revision$"
+__date__      = "$Date$"
+__copyright__ = "Copyright (c) 2005-2009 Sun Microsystems Inc."
+__license__   = "LGPL"
+
+import os
+import sys
+import debug
+import gtk
+import locale
+
+import find
+import orca_gtkbuilder
+import orca_state
+import platform
+
+from orca_i18n import _  # for gettext support
+
+from settings_manager import SettingsManager
+
+
+OS = None
+newProfile = None
+
+
+class OrcaProfileGUI(orca_gtkbuilder.GtkBuilderWrapper):
+
+    def __init__(self, fileName, windowName):
+        """Initialize the Orca configuration GUI.
+
+        Arguments:
+        - fileName: name of the GtkBuilder file.
+        - windowName: name of the component to get from the GtkBuilder file.
+        """
+
+        orca_gtkbuilder.GtkBuilderWrapper.__init__(self, fileName, windowName)
+
+        # Initialize variables to None to keep pylint happy.
+        #
+        self.searchString = None
+
+    def init(self):
+        # Initialize the dialog box controls.
+        self.profileString = ""
+
+    def showGUI(self):
+        """Show the Orca Find dialog. This assumes that the GUI has
+        already been created.
+        """
+
+        profileDialog = self.get_widget("profileDialog")
+
+        # Set the current time on the Find GUI dialog so that it'll
+        # get focus. set_user_time is a new call in pygtk 2.9.2 or later.
+        # It's surronded by a try/except block here so that if it's not found,
+        # then we can fail gracefully.
+        #
+        try:
+            profileDialog.realize()
+            ts = orca_state.lastInputEventTimestamp
+            if ts == 0:
+                ts = gtk.get_current_event_time()
+            profileDialog.window.set_user_time(ts)
+        except AttributeError:
+            debug.printException(debug.LEVEL_FINEST)
+
+
+        # Populate the dialog box from the previous searchQuery, should
+        # one exist.  Note:  This is necessary because we are destroying
+        # the dialog (rather than merely hiding it) before performing the
+        # search.
+
+        try:
+            profileEntry = self.get_widget("profileEntry")
+            profileEntry.set_text(self.profileString)
+        except:
+            pass
+
+        # Fill available profiles in combobox
+        profilesCombo = self.get_widget('availableProfilesCombo')
+        profilesComboModel = self.get_widget('liststore1')
+        availableProfiles = self.__getAvailableProfiles()
+        iterChilds = {}
+
+        if not len(availableProfiles):
+            iterChilds.update({'default' : profilesComboModel.append(['default'])})
+        else:
+            for profile in availableProfiles:
+                iterChilds.update({profile: profilesComboModel.append([profile])})
+
+
+        profileDialog.run()
+
+    def closeButtonClicked(self, widget):
+        """Signal handler for the "clicked" signal for the cancelButton
+           GtkButton widget. The user has clicked the Cancel button.
+           Hide the dialog.
+
+        Arguments:
+        - widget: the component that generated the signal.
+        """
+
+        self.get_widget("profileDialog").hide()
+
+    def on_saveProfileButton_clicked(self, widget):
+        """Signal handler for the "clicked" signal for the findButton
+           GtkButton widget. The user has clicked the Find button.
+           Call the method to begin the search.
+
+        Arguments:
+        - widget: the component that generated the signal.
+        """
+
+        # Merely hiding the dialog causes the find to take place before
+        # the original window has fully regained focus.
+        global newProfile
+
+        if self.get_widget("profileEntry").get_text() != '':
+            newProfile = self.get_widget("profileEntry").get_text()
+        else:
+            newProfile = self.get_widget("availableProfilesCombo").get_active_text()
+
+        self.get_widget("profileDialog").destroy()
+
+    def onProfileEntryChanged(self, widget, data=None):
+        """Signal handler for the "changed" signal for the ProfileEntry
+           GtkEntry widget."""
+        
+        if self.get_widget("profileEntry").get_text() != '':
+            self.get_widget('availableProfilesCombo').set_sensitive(False)
+        else:
+            self.get_widget('availableProfilesCombo').set_sensitive(True)
+
+
+    def profileDialogDestroyed(self, widget):
+        """Signal handler for the "destroyed" signal for the findDialog
+           GtkWindow widget. Reset OS to None.
+
+        Arguments:
+        - widget: the component that generated the signal.
+        """
+
+        global OS
+
+        OS = None
+
+    def __getAvailableProfiles(self):
+        """Get available user profiles"""
+
+        _settingsManager = SettingsManager()
+        _settingsManager.loadBackend()
+
+        return _settingsManager.availableProfiles()
+
+def showProfileUI():
+    global OS
+    global newProfile
+
+    newProfile = None
+
+    if not OS:
+        uiFile = os.path.join(platform.prefix,
+                              platform.datadirname,
+                              platform.package,
+                              "ui",
+                              "orca-profile.ui")
+        OS = OrcaProfileGUI(uiFile, "profileDialog")
+        OS.init()
+
+    OS.showGUI()
+   
+    print 'profile = ', newProfile
+
+    return newProfile
+ 
+
+def main():
+    locale.setlocale(locale.LC_ALL, '')
+
+    showProfileUI()
+
+    gtk.main()
+    sys.exit(0)
+
+if __name__ == "__main__":
+    main()
diff --git a/src/orca/settings_manager.py b/src/orca/settings_manager.py
index 76761c3..2c45466 100644
--- a/src/orca/settings_manager.py
+++ b/src/orca/settings_manager.py
@@ -85,6 +85,14 @@ class SettingsManager(Singleton):
         return SettingsBackend.writePreferences(prefsDict, keyBindingsTreeModel, pronunciationTreeModel)
 
     def readPreferences(self):
+        """Read current user preferences"""
 
         return SettingsBackend.readPreferences()
 
+
+    def availableProfiles(self):
+        """Get available profiles from active backend"""
+
+        return SettingsBackend.availableProfiles() 
+
+



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]