GNOME Bugzilla – Bug 363815
Implement the ability to have application-specific settings
Last modified: 2006-11-09 18:46:41 UTC
Sometimes different applications (tasks) call for different settings. For instance, when writing a document in OOo Writer, one might always want keyboard echo set to words or none, but when creating a spreadsheet in Calc, the preferred keyboard echo might be characters. Similarly, when navigating in Evolution, one might prefer to have Orca always speak the current row in tables, but when navigating in Calc, speak cell might be preferred. It would be helpful to be able to set application-specific settings, so that one's preferences in such instances are used automatically. (Suggested at Boston Orca users group)
One can do part of this now using scripting, but it's not exactly trivial. User's can have their own versions of scripts in their ~/.orca/orca-scripts directory. These can sub-class the "standard" application scripts under the Python site-packages directory. You can set what settings you want in the __init__() method of your scripts, but there is no way to unset them (i.e. put them back to the default values) when the script is no longer active. We probably need to rework this a bit to allow this to be properly done (and to be easily done).
This would be a very useful feature. I think it would be nice to allow for a separate settings file elated to an application that if existed would simply override the setting in the application script without copying the whole script.
Created attachment 75950 [details] [review] Patch to implement this feature. Explanation to follow.
Created attachment 75951 [details] Sample application specific settings for StarOffice Explanation to follow.
Note that I have NOT checked these patches in yet. Although they do appear to work, we might be able to do better. Here's how to test them. 1/ Apply the patches to Orca CVS HEAD. 2/ Run: % cd orca % ./autogen.sh --prefix=/usr % make % sudo make install 3/ Do the following: % mkdir ~/.orca/app-settings % cd ~/.orca/app-settings % cp ~/.orca/orca-scripts/__init__.py . % cp ~/.orca/orca-scripts/__init__.pyc . (Note that you could also just run the new Orca, bought up the Preferences dialog and hit Apply, and these four steps would have been done automatically for you.) 4/ Save a copy of the StarOffice.py attachment to this bug in your ~/.orca/app-settings directory. 5/ Make sure that in your ~/.orca/user-settings.py file, you have: orca.settings.readTableCellRow = True 6/ Start up Orca. 7/ Start up OpenOffice calc and the gtk-demo Tree View List Store demo. 8/ When you are navigating table cells in OOo calc, it will read single table cells. When you navigate table cells in the List Store demo it will automatically read each row. The StarOffice.py file shows that there are two methods doing this: def loadNewSettings(self): """Load the application specific settings. Note that it is upto the individual application settings scripts, to save away the previous value of each setting that it overrides, so that it can later be restored correctly. """ self.readTableCellRow = settings.readTableCellRow settings.readTableCellRow = False def restoreOldSettings(self): """Restore the previous settings.""" settings.readTableCellRow = self.readTableCellRow They get called before and after each object event is processed. There are default versions of those methods in appsettings.py that do nothing. Feel free to experiment with new scripts that adjust other settings. Points for discussion: Is this solution enough? It certainly works and isn't that hard for users to work with as it stands. Just like the pronunciation dictionary, we could add a GUI front-end to it at a future date to make it even easier. While I was thinking about this, I thought that wouldn't it be nice if settings.py was a subclass of the appsettings.py Settings class, then all the application specific settings files under ~/.orca/app-settings would be a subclass of that. Thinking about it some more though, and I couldn't see an easy way to do the equivalent of def loadNewSettings(self): def restoreOldSettings(self): in settings.py. It would also mean that there would need to be a major re-factor. Every occurance of settings.<whatever> throughout the code would have to be changed to settings.Settings.<whatever>. Still, it's worth thinking about. Comments?
Just spoke with Will on this one. There is a much simpler approach: * We'd add two new routines to util.py: - saveOldAppSettings() - this would automatically save a copy of all the settings (as specified by the settings.userCustomizableSettings dictionary). - restoreOldAppSettings() - this would automatically restore a copy of all the settings from those that we'd previously saved via saveOldAppSettings() * The above two routines would sandwich the s.processObjectEvent() call in _processObjectEvent() in focus_tracking_presenter.py. * We would no longer need the appsettings.py file in the .../src/orca directory. * __import__()'ing of the app-settings/<appname>.py would then be simpler. Along the lines of the way that we import user-settings.py in loadUserSettings in orca.py. * The app-settings/<appname>.py files then become trivial. The StarOffice.py example would now be something like: import orca.settings settings.readTableCellRow = False I'll generate up a rework of the patch (probably next week).
Ack! It looks like readPreferences() and writePreferences(prefsDict) already do exactly what I want. No need to write new routines in util.py.
Created attachment 75972 [details] [review] Reworked patch to implement this feature. The new patch needs a little work. It happily imports the ~/.orca/app-settings/StarOffice.py file the first time then ignores it from then on. How to you get it to automatically import it for new each time?
Created attachment 75973 [details] New version of the sample application specific settings for StarOffice
Created attachment 76174 [details] [review] Reworked version of the patch that uses the reload() function to attempt to reload the application specific settings. And still doesn't work. I added a print statement to ~/.orca/app-settings/StarOffice.py that says "Hello World" but this is not getting displayed. Here's a sample of the output. You'll see it prints the "Hello World" the first time, but not when reloadeding (yet no import error is thrown). ... Got an import error for app-settings.orca Importing app-settings.orca Got an import error for app-settings.orca Importing app-settings.orca Got an import error for app-settings.orca Importing app-settings.orca Got an import error for app-settings.orca Importing app-settings.gnome-panel Got an import error for app-settings.gnome-panel Importing app-settings.gnome-panel Got an import error for app-settings.gnome-panel Importing app-settings.orca Got an import error for app-settings.orca Importing app-settings.StarOffice Hello world from StarOffice app settings. After importing. Reloading: app-settings.StarOffice After reloading. Importing app-settings.orca Got an import error for app-settings.orca Importing app-settings.orca Got an import error for app-settings.orca Importing app-settings.orca Got an import error for app-settings.orca Reloading: app-settings.StarOffice After reloading. Reloading: app-settings.StarOffice After reloading. Reloading: app-settings.StarOffice After reloading. Reloading: app-settings.StarOffice After reloading. Reloading: app-settings.StarOffice After reloading. Reloading: app-settings.StarOffice After reloading. Reloading: app-settings.StarOffice After reloading. Reloading: app-settings.StarOffice After reloading. ...
As a data point, I put print statements either side of the reload for the user-settings.py file in orca.py: Index: orca.py =================================================================== RCS file: /cvs/gnome/orca/src/orca/orca.py,v retrieving revision 1.164 diff -u -r1.164 orca.py --- orca.py 2 Nov 2006 16:07:42 -0000 1.164 +++ orca.py 7 Nov 2006 21:06:10 -0000 @@ -803,7 +803,9 @@ reloaded = False if _userSettings: try: + print "orca: loadUserSetting: BEFORE reload." reload(_userSettings) + print "orca: loadUserSetting: AFTER reload." reloaded = True except ImportError: debug.printException(debug.LEVEL_FINEST) and added a print line to my ~/.orca/orca-customizations.py file to print out "Hello world". I then started up Orca, and then bought up Preferences and hit Apply. You'll see it prints the "Hello World" the first time, but not when reloading (yet no import error is thrown). I don't think reload() is working the way we think it is... 1 % orca GTK Accessibility Module initialized Hello World from orca-customizations.py Importing app-settings.-c Got an import error for app-settings.-c Importing app-settings.-c Got an import error for app-settings.-c Importing app-settings.-c Got an import error for app-settings.-c Importing app-settings.-c Got an import error for app-settings.-c ... Importing app-settings.-c Got an import error for app-settings.-c Importing app-settings.-c Got an import error for app-settings.-c Importing app-settings.-c Got an import error for app-settings.-c orca: loadUserSetting: BEFORE reload. orca: loadUserSetting: AFTER reload. Importing app-settings.-c Got an import error for app-settings.-c Importing app-settings.-c Got an import error for app-settings.-c
Okay, the magic is to use: __import__(name, globals(), locals(), ['']) not: __import__(name) Fixing up the patch now.
Created attachment 76183 [details] [review] Working version of the reworked patch.
Changes checked into CVS HEAD. Please test this and let me know if it works for you. If so, I'll close out the bug as FIXED. Thanks.
Rich, this is *extremely* cool! So far I've tried it with readTableCellRow and enableEchoByWord. Works very nicely, and I'm already coming up with more uses for this feature. Thanks!! I do have a couple of questions. I suspect the first one you'll have me file as an RFE, but I'll put them both here to start with. 1. Is the only way to modify one's app-specific settings through manually editing the appropriate file(s) in ~/.orca/app-settings? 2. For the sake of argument, what if I want to temporarily change readTableCellRow so that "just this one time" I can read the entire row in calc? I press Insert F11, but my app-specific setting seems to override the toggle. Thanks again VERY much!
Hi Joanie. Yes, please file an RFE on wrapping a GUI around this. I'm going to target it as FUTURE, because it's not going to be easy to do, and will require a bit of thinking about. The Insert-F11 "speak cell/row" won't work because the application settings file ~/.orca/app-settings/StarOffice.py is getting reloaded for *every* event that happens in that application and in it's simplistic form, is going to immediately set it back to reading a single cell. I suspect you could come up with some more complicated Python code to put in that file that would allow you to still be able to toggle this, but it's getting late in the day and I missed my nap today, and it's not coming to me at the moment.
w.r.t. the former: http://bugzilla.gnome.org/show_bug.cgi?id=372273 w.r.t. the latter: I haven't had a nap AND I'm not a developer. :-) BUT would it be possible for Orca to simply load the settings in ~/.orca/app-settings/*.py when the script for that app becomes active, rather than load it for *every* event that happens in that application? Just a thought. Feel free to dismiss it. ;-) At the risk of repeating myself: This really is a cool feature *as it is*. Just because I say "yeah, but...." doesn't mean I don't appreciate what you have done -- here and elsewhere. Thanks again!!
That's certainly possible, but how would it work for say gaim, where typically things (like new IM's) are happening when the application isn't the active script?
Hmmmm. Excellent question! :-) Based on your question, it occurred to me that it might not be such a great idea if it loads those settings for *every* event that happens in an application *if that application isn't the active script*. For instance, if I I set readTableCellRow to False in my ~/.orca/app-settings/gaim.py, entered a chatroom, and then started reading my mail in Evolution, it would be a drag if readTableCellRow got switched to false each time someone in the chatroom said something. I wasn't sure if that's what you meant by "every event that happens in that application" or not, so I did a test, setting readTableCellRow to false in my gaim.py, verifying that it really was false, joining a channel with nearly 1000 people in it, and then navigating in my message list in Evolution. Orca did read the new messages while Gaim was in the background, but it did NOT have any impact on readTableCellRow in Evolution. (Which is a good thing) From this, it *seems* that the app-specific settings are getting loaded only if the application is the active script. And if this is indeed the case, what would be impacted by having Orca load the settings only when the script for that app becomes active?
Just talked with Will on this. I'm going to revamp the patch. It'll be adjusted so that the specific application settings will only be loaded when the orca_state.activeScript changes (not for every event). This changes when we get "window:activate" events or a "focus:" event for an object that has a FRAME role. In other words, we will only be doing this for the active app and not for applications that get events "in the background". New patch to follow (hopefully later this afternoon). One other issue to consider (and for you to comment back on Joanie after you've tested the new patch): Here's a scenerio that reflects the issue: You're working in OpenOffice calc (where the app specific setting is to (say) read single cells and not the whole row). You hit Insert-F11 to toggle that to read by row. (With the new patch this should hopefully do the right thing again.) You now change focus to another app and work on that for a bit. Then you bring focus back to OpenOffice calc. The new patch will load those app specific setting again and you will be back to reading single cells rather than by row. You will have lost your previous Insert-F11 setting and have to toggle it again "by hand". Can you live with this? ;-)
While I haven't yet tested the patch (obviously), I can tell you right now that I can happily live with the scenario you describe. If I make an app-specific setting, it's because 9 times out of 10 the default behavior is not what I want. Therefore, I don't consider it to be problematic if Orca reverts back to the behavior I normally want. :-) Besides this behavior would be consistent with how Windows screen readers work, so I doubt many users would get confused or bothered by it.
Created attachment 76230 [details] [review] Revised diffs. App specific settings only loaded now when orca_state.activeScript changes. New changes checked into CVS HEAD. Joanie, could you try them out please and let me know if they need any further tweaking. Thanks!
In the spirit of putting it through its paces, I'm afraid I did find something that might need tweaking. My default voices setting is: orca.settings.voices = { 'default' : orca.acss.ACSS({'average-pitch': 5.0, 'family': {'locale': 'en_US', 'gender': None, 'name': 'Paul'}, 'gain': 9, 'rate': 65.0}), 'uppercase' : orca.acss.ACSS({'average-pitch': 6}), 'hyperlink' : orca.acss.ACSS({'average-pitch': 2}), } I decided to make Betty my default voice for gaim: orca.settings.voices = { 'default' : orca.acss.ACSS({'average-pitch': 5.0, 'family': {'locale': 'en_US', 'gender': None, 'name': 'Betty'}, 'gain': 9, 'rate': 65.0}), 'uppercase' : orca.acss.ACSS({'average-pitch': 6}), 'hyperlink' : orca.acss.ACSS({'average-pitch': 2}), } Sometimes Betty kicks in; sometimes she doesn't: 1. Launch Gaim, arrow around in the buddy list, navigate in the menus: Paul 2. Alt Tab to get to some other window, but don't release Alt (i.e. just cycle through them): Betty 3. Type something in a channel with key echo enabled (or review your text with the arrows prior to pressing enter): Paul 4. Press Enter to send the text to the room, causing Orca to speak that text: Betty
I'll have a look at this tomorrow. Thanks for trying it.
There doesn't seem to be an easy way to do this. It's going to involve including a large chunk of the speech handling code in the app settings file. We need to provide a convenience routine to make this easier. I'll file a separate bug on this, so we can close this one off.
I've filed bug #373078 on the speech reload problem. I'm closing this one out as fixed. If we find other problems related to this new feature, let's open up new individual bugs for them.