diff options
author | Ajay Garg <ajay@activitycentral.com> | 2012-10-18 08:28:20 (GMT) |
---|---|---|
committer | Ajay Garg <ajay@activitycentral.com> | 2012-10-18 08:29:28 (GMT) |
commit | 71928a533afbbf5334bccec8e9065f2d3a9d098a (patch) | |
tree | 342ab4770f03d5065025f13cf34107f4e4fa2ff0 | |
parent | 2cc6b91918aa8fabeb68b143f12c71cbf017b613 (diff) |
Accessibility
Signed-off-by: Ajay Garg <ajay@activitycentral.com>
-rwxr-xr-x | bin/sugar-session | 6 | ||||
-rw-r--r-- | bin/sugar.in | 23 | ||||
-rw-r--r-- | configure.ac | 1 | ||||
-rw-r--r-- | data/Makefile.am | 14 | ||||
-rw-r--r-- | data/gtkrc-contrast.em | 11 | ||||
-rw-r--r-- | data/gtkrc.em | 1 | ||||
-rw-r--r-- | data/icons/Makefile.am | 1 | ||||
-rw-r--r-- | data/icons/module-accessibility.svg | 92 | ||||
-rw-r--r-- | extensions/cpsection/Makefile.am | 2 | ||||
-rw-r--r-- | extensions/cpsection/accessibility/Makefile.am | 6 | ||||
-rw-r--r-- | extensions/cpsection/accessibility/__init__.py | 25 | ||||
-rw-r--r-- | extensions/cpsection/accessibility/model.py | 89 | ||||
-rw-r--r-- | extensions/cpsection/accessibility/view.py | 302 | ||||
-rw-r--r-- | extensions/globalkey/Makefile.am | 1 | ||||
-rw-r--r-- | extensions/globalkey/magnifier.py | 96 | ||||
-rw-r--r-- | src/jarabe/controlpanel/gui.py | 3 | ||||
-rw-r--r-- | src/jarabe/desktop/activitieslist.py | 3 | ||||
-rw-r--r-- | src/jarabe/desktop/favoritesview.py | 3 | ||||
-rw-r--r-- | src/jarabe/model/Makefile.am | 1 | ||||
-rw-r--r-- | src/jarabe/model/accessibility.py | 160 |
20 files changed, 831 insertions, 9 deletions
diff --git a/bin/sugar-session b/bin/sugar-session index 4f69f18..bfe4fb1 100755 --- a/bin/sugar-session +++ b/bin/sugar-session @@ -257,6 +257,7 @@ def bootstrap(): GObject.idle_add(setup_notification_service_cb) GObject.idle_add(setup_file_transfer_cb) GObject.idle_add(show_software_updates_cb) + GObject.idle_add(setup_accessibility_cb) if _USE_XKL: GObject.idle_add(setup_keyboard_cb) @@ -277,6 +278,11 @@ def set_theme(): settings.set_property('gtk-theme-name', sugar_theme) settings.set_property('gtk-icon-theme-name', 'sugar') +def setup_accessibility_cb(): + from jarabe.model import accessibility + accessibility_manager = accessibility.AccessibilityManager() + accessibility_manager.setup_accessibility() + def main(): try: diff --git a/bin/sugar.in b/bin/sugar.in index 428cbf2..d9a41ba 100644 --- a/bin/sugar.in +++ b/bin/sugar.in @@ -45,7 +45,18 @@ if test -z "$SUGAR_SCALING"; then export SUGAR_SCALING=100 fi -export GTK2_RC_FILES="@prefix@/share/sugar/data/sugar-$SUGAR_SCALING.gtkrc" +if gconftool-2 --dir-exists=/desktop/sugar/interface ; then + THEME="$(gconftool-2 --get /desktop/sugar/interface/gtk_theme)" + if [ "$THEME" = 'sugar-contrast' ]; then + GTK2_THEME="sugar-$SUGAR_SCALING-contrast" + else + GTK2_THEME="sugar-$SUGAR_SCALING" + fi +else + GTK2_THEME="sugar-$SUGAR_SCALING" +fi + +export GTK2_RC_FILES="@prefix@/share/sugar/data/$GTK2_THEME.gtkrc" # Needed for executing wpa_passphrase export PATH="$PATH":/sbin:/usr/sbin @@ -70,7 +81,15 @@ if [ -f ~/.sugar/debug ]; then . ~/.sugar/debug fi -echo Xcursor.theme: sugar | xrdb -merge + +if gconftool-2 --dir-exists=/desktop/sugar/peripherals/mouse ; then + CURSOR_THEME="$(gconftool-2 --get /desktop/sugar/peripherals/mouse/cursor_theme)" +else + CURSOR_THEME="sugar" +fi + + +echo Xcursor.theme: $CURSOR_THEME | xrdb -merge metacity --no-force-fullscreen -d $DISPLAY & exec sugar-session diff --git a/configure.ac b/configure.ac index 0878320..05c40b6 100644 --- a/configure.ac +++ b/configure.ac @@ -51,6 +51,7 @@ data/Makefile data/sugar-emulator.desktop extensions/cpsection/aboutcomputer/Makefile extensions/cpsection/aboutme/Makefile +extensions/cpsection/accessibility/Makefile extensions/cpsection/datetime/Makefile extensions/cpsection/frame/Makefile extensions/cpsection/keyboard/Makefile diff --git a/data/Makefile.am b/data/Makefile.am index 6a62d23..2a92ce1 100644 --- a/data/Makefile.am +++ b/data/Makefile.am @@ -8,6 +8,14 @@ sugar-100.gtkrc: gtkrc.em $(srcdir)/em.py -D scaling=\'100\' $(srcdir)/gtkrc.em > \ $(top_builddir)/data/sugar-100.gtkrc +sugar-100-contrast.gtkrc: gtkrc-contrast.em + $(srcdir)/em.py -D scaling=\'100\' $(srcdir)/gtkrc-contrast.em > \ + $(top_builddir)/data/sugar-100-contrast.gtkrc + +sugar-72-contrast.gtkrc: gtkrc-contrast.em + $(srcdir)/em.py -D scaling=\'100\' $(srcdir)/gtkrc-contrast.em > \ + $(top_builddir)/data/sugar-72-contrast.gtkrc + sugardir = $(pkgdatadir)/data sugar_DATA = \ activities.defaults \ @@ -18,7 +26,9 @@ sugar_DATA = \ GTKRC_FILES = \ sugar-72.gtkrc \ - sugar-100.gtkrc + sugar-100.gtkrc \ + sugar-100-contrast.gtkrc \ + sugar-72-contrast.gtkrc xsessionsdir = $(datadir)/xsessions xsessions_DATA = sugar.desktop @@ -64,5 +74,5 @@ endif icondir = $(datadir)/icons/hicolor/scalable/apps icon_DATA = sugar-xo.svg -EXTRA_DIST = $(sugar_DATA) $(xsessions_DATA) $(nmservice_DATA) $(mime_xml_in_files) em.py gtkrc.em $(schema_in_files) $(icon_DATA) +EXTRA_DIST = $(sugar_DATA) $(xsessions_DATA) $(nmservice_DATA) $(mime_xml_in_files) em.py gtkrc.em gtkrc-contrast.em $(schema_in_files) $(icon_DATA) CLEANFILES = $(GTKRC_FILES) $(mime_xml_files) $(schema_DATA) diff --git a/data/gtkrc-contrast.em b/data/gtkrc-contrast.em new file mode 100644 index 0000000..3ed4717 --- /dev/null +++ b/data/gtkrc-contrast.em @@ -0,0 +1,11 @@ +@{ +if scaling == '72': + icon_sizes = 'gtk-large-toolbar=40,40' +else: + icon_sizes = 'gtk-large-toolbar=55,55' +}@ +gtk-theme-name = "sugar-@scaling-contrast" +gtk-icon-theme-name = "sugar" +gtk-toolbar-style = GTK_TOOLBAR_ICONS +gtk-icon-sizes = "@icon_sizes" +gtk-cursor-blink-timeout = 3 diff --git a/data/gtkrc.em b/data/gtkrc.em index d4e1a7c..4459c42 100644 --- a/data/gtkrc.em +++ b/data/gtkrc.em @@ -6,7 +6,6 @@ else: }@ gtk-theme-name = "sugar-@scaling" gtk-icon-theme-name = "sugar" -gtk-cursor-theme-name = "sugar" gtk-toolbar-style = GTK_TOOLBAR_ICONS gtk-icon-sizes = "@icon_sizes" gtk-cursor-blink-timeout = 3 diff --git a/data/icons/Makefile.am b/data/icons/Makefile.am index a35643a..2497c4a 100644 --- a/data/icons/Makefile.am +++ b/data/icons/Makefile.am @@ -3,6 +3,7 @@ sugardir = $(pkgdatadir)/data/icons sugar_DATA = \ module-about_me.svg \ module-about_my_computer.svg \ + module-accessibility.svg \ module-date_and_time.svg \ module-frame.svg \ module-keyboard.svg \ diff --git a/data/icons/module-accessibility.svg b/data/icons/module-accessibility.svg new file mode 100644 index 0000000..245a47e --- /dev/null +++ b/data/icons/module-accessibility.svg @@ -0,0 +1,92 @@ +<?xml version="1.0" encoding="UTF-8" standalone="no"?> +<!-- Created with Inkscape (http://www.inkscape.org/) --> + +<svg + xmlns:svg="http://www.w3.org/2000/svg" + xmlns="http://www.w3.org/2000/svg" + version="1.0" + width="55" + height="55" + id="svg795"> + <defs + id="defs797" /> + <g + id="layer1"> + <path + d="m -23.738584,30.440666 a 8.901969,11.301082 0 1 1 -17.803937,0 8.901969,11.301082 0 1 1 17.803937,0 z" + transform="matrix(1.2765958,0,0,1.0558659,19.192898,-13.127946)" + id="path12" + style="fill:none;stroke:#ffffff" /> + <path + d="m 30.145644,37.823484 c -0.583589,6.659344 -6.7511,11.52268 -13.775517,10.862567 C 9.3457054,48.02594 4.1243814,42.092348 4.7079694,35.433004 5.2915594,28.773661 20.67887,20.597949 14.885997,24.011638 -12.777062,40.313232 24.43362,62.068174 30.145644,37.823484 z" + id="path1405-0" + style="fill:none;stroke:#ffffff;stroke-width:1.44962609;stroke-opacity:1" /> + <rect + width="2.916333" + height="21.188446" + ry="1.3939767" + x="18.332197" + y="13.76814" + id="rect1438-8" + style="fill:#ffffff;fill-opacity:1;stroke:#ffffff;stroke-width:1.50547338;stroke-opacity:1" /> + <rect + width="2.8716421" + height="19.140917" + ry="1.259271" + x="-35.091366" + y="-38.207035" + transform="matrix(0,-1,-1,0,0,0)" + id="rect1438-1-87" + style="fill:#ffffff;fill-opacity:1;stroke:#ffffff;stroke-width:1.41987956;stroke-opacity:1" /> + <rect + width="2.5733202" + height="15.766372" + ry="1.0372615" + x="-5.4068875" + y="-65.997124" + transform="matrix(-0.55477829,0.83199823,-0.68762037,-0.72607041,0,0)" + id="rect1438-0-4" + style="fill:#ffffff;fill-opacity:1;stroke:#ffffff;stroke-width:1.21988189;stroke-opacity:1" /> + <rect + width="2.0588" + height="12.916228" + ry="0.84975183" + x="6.7647386" + y="-38.278324" + transform="matrix(-0.21998034,0.97550431,-0.88967727,-0.45658992,0,0)" + id="rect1438-0-1-8" + style="fill:#ffffff;fill-opacity:1;stroke:#ffffff;stroke-width:0.98759735;stroke-opacity:1" /> + <rect + width="0.98179615" + height="13.275604" + ry="0.87339497" + x="-30.243309" + y="-41.495876" + transform="matrix(0,-1,-1,0,0,0)" + id="rect1438-1-8-5" + style="fill:#ffffff;fill-opacity:1;stroke:#ffffff;stroke-width:0.69142139;stroke-opacity:1" /> + <rect + width="0.97070193" + height="11.568416" + ry="0.76108003" + x="50.822704" + y="-8.6089849" + transform="matrix(0.89791652,0.44016579,0.56230073,-0.82693282,0,0)" + id="rect1438-1-8-0-0" + style="fill:#ffffff;fill-opacity:1;stroke:#ffffff;stroke-width:0.64177793;stroke-opacity:1" /> + <rect + width="1.6299056" + height="7.7739253" + ry="0.51144254" + x="72.759727" + y="35.364716" + transform="matrix(0.9888174,0.14913131,-0.60877492,0.79334299,0,0)" + id="rect1438-0-1-7-7" + style="fill:#ffffff;fill-opacity:1;stroke:#ffffff;stroke-width:0.68172067;stroke-opacity:1" /> + <path + d="m 79.67578,18.634508 a 3.2829957,3.0304577 0 1 1 -6.565992,0 3.2829957,3.0304577 0 1 1 6.565992,0 z" + transform="matrix(1.5397454,0,0,1.4719643,-97.932275,-17.750188)" + id="path1603-2" + style="fill:#ffffff;fill-opacity:1;fill-rule:evenodd;stroke:#ffffff;stroke-opacity:1" /> + </g> +</svg> diff --git a/extensions/cpsection/Makefile.am b/extensions/cpsection/Makefile.am index a92b5dd..ee5897f 100644 --- a/extensions/cpsection/Makefile.am +++ b/extensions/cpsection/Makefile.am @@ -1,4 +1,4 @@ -SUBDIRS = aboutme aboutcomputer datetime frame keyboard language \ +SUBDIRS = aboutme aboutcomputer accessibility datetime frame keyboard language \ modemconfiguration network power updater sugardir = $(pkgdatadir)/extensions/cpsection diff --git a/extensions/cpsection/accessibility/Makefile.am b/extensions/cpsection/accessibility/Makefile.am new file mode 100644 index 0000000..70d26f4 --- /dev/null +++ b/extensions/cpsection/accessibility/Makefile.am @@ -0,0 +1,6 @@ +sugardir = $(pkgdatadir)/extensions/cpsection/accessibility + +sugar_PYTHON = \ + __init__.py \ + model.py \ + view.py diff --git a/extensions/cpsection/accessibility/__init__.py b/extensions/cpsection/accessibility/__init__.py new file mode 100644 index 0000000..c69acfc --- /dev/null +++ b/extensions/cpsection/accessibility/__init__.py @@ -0,0 +1,25 @@ +# Copyright (C) 2010 Plan Ceibal +# +# Author: Esteban Arias <earias@plan.ceibal.edu.uy> +# Contact information: comunidad@plan.ceibal.edu.uy +# Plan Ceibal http://www.ceibal.edu.uy +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# This program 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 General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see <http://www.gnu.org/licenses/>. + +from gettext import gettext as _ + +CLASS = 'accessibility' +ICON = 'module-accessibility' +TITLE = _('Accessibility') + diff --git a/extensions/cpsection/accessibility/model.py b/extensions/cpsection/accessibility/model.py new file mode 100644 index 0000000..48b1636 --- /dev/null +++ b/extensions/cpsection/accessibility/model.py @@ -0,0 +1,89 @@ +# Copyright (C) 2010 Plan Ceibal +# +# Author: Esteban Arias <earias@plan.ceibal.edu.uy> +# Contact information: comunidad@plan.ceibal.edu.uy +# Plan Ceibal http://www.ceibal.edu.uy +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# This program 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 General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see <http://www.gnu.org/licenses/>. + +from jarabe.model import accessibility + +keyboard = accessibility.Keyboard() +screen = accessibility.Screen() +mouse = accessibility.Mouse() + +KEYWORDS = ['mouse_keys', 'sticky_keys', 'bounce_keys', 'contrast', 'white_mouse', 'accel_mouse', 'capital_letters'] + +def get_mouse_keys(): + return keyboard.get_mouse_keys() + +def set_mouse_keys(activar): + keyboard.set_mouse_keys(activar) + +def print_mouse_keys(): + print str(get_mouse_keys()) + +def get_sticky_keys(): + return keyboard.get_sticky_keys() + +def set_sticky_keys(activar): + keyboard.set_sticky_keys(activar) + +def print_sticky_keys(): + print str(get_sticky_keys()) + +def get_bounce_keys(): + return keyboard.get_bounce_keys() + +def set_bounce_keys(activar): + keyboard.set_bounce_keys(activar) + +def print_bounce_keys(): + print str(get_bounce_keys()) + +def get_contrast(): + return screen.get_contrast() + +def set_contrast(activar): + screen.set_contrast(activar) + +def print_contrast(): + print str(get_contrast()) + +def get_capital_letters(): + return screen.get_capital_letters() + +def set_capital_letters(activar): + screen.set_capital_letters(activar) + +def print_capital_letters(): + print str(get_capital_letters()) + +def get_white_mouse(): + return mouse.get_white_mouse() + +def set_white_mouse(activar): + mouse.set_white_mouse(activar) + +def print_white_mouse(): + print str(get_white_mouse()) + +def get_accel_mouse(): + return mouse.get_accel_mouse() + +def set_accel_mouse(valor): + mouse.set_accel_mouse(valor) + +def print_accel_mouse(): + print str(get_accel_mouse()) diff --git a/extensions/cpsection/accessibility/view.py b/extensions/cpsection/accessibility/view.py new file mode 100644 index 0000000..e443cb4 --- /dev/null +++ b/extensions/cpsection/accessibility/view.py @@ -0,0 +1,302 @@ +# Copyright (C) 2010 Plan Ceibal +# +# Author: Esteban Arias <earias@plan.ceibal.edu.uy> +# Contact information: comunidad@plan.ceibal.edu.uy +# Plan Ceibal http://www.ceibal.edu.uy +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# This program 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 General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see <http://www.gnu.org/licenses/>. + + +from gi.repository import Gtk +from gettext import gettext as _ + +from sugar3.graphics import style + +from jarabe.controlpanel.sectionview import SectionView +from jarabe.controlpanel.inlinealert import InlineAlert + +class accessibility(SectionView): + def __init__(self, model, alerts=None): + SectionView.__init__(self) + + self._model = model + self.restart_alerts = alerts + self.set_border_width(style.DEFAULT_SPACING * 2) + self.set_spacing(style.DEFAULT_SPACING) + scrollwindow = Gtk.ScrolledWindow() + scrollwindow.set_policy(Gtk.PolicyType.AUTOMATIC, Gtk.PolicyType.AUTOMATIC) + self.pack_start(scrollwindow, True, True, 0) + scrollwindow.show() + + self._vbox_section = Gtk.VBox() + scrollwindow.add_with_viewport(self._vbox_section) + self._vbox_section.show() + + self._zone_alert_box = Gtk.HBox(spacing=style.DEFAULT_SPACING) + self.pack_start(self._zone_alert_box, False, False, 0) + + self._zone_alert = InlineAlert() + self._zone_alert_box.pack_start(self._zone_alert, True, True, 0) + if 'zone' in self.restart_alerts: + self._zone_alert.props.msg = self.restart_msg + self._zone_alert.show() + self._zone_alert_box.show() + + self.needs_restart = False + + self._view_keyboard_options() + self._view_screen_options() + self._view_mouse_options() + + + def _view_keyboard_options(self): + separator_pm_keyboard = Gtk.HSeparator() + self._vbox_section.pack_start(separator_pm_keyboard, False, False, 0) + separator_pm_keyboard.show() + + label_pm_keyboard = Gtk.Label(_('Keyboard')) + label_pm_keyboard.set_alignment(0, 0) + self._vbox_section.pack_start(label_pm_keyboard, False, False, 0) + label_pm_keyboard.show() + + self.box_pm_keyboard = Gtk.VBox() + self.box_pm_keyboard.set_border_width(style.DEFAULT_SPACING * 2) + self.box_pm_keyboard.set_spacing(style.DEFAULT_SPACING) + + self._view_mouse_keys() + self._view_sticky_keys() + self._view_bounce_keys() + + self._vbox_section.pack_start(self.box_pm_keyboard, False, False, 0) + self.box_pm_keyboard.show() + + def _view_screen_options(self): + separator_pm_screen = Gtk.HSeparator() + self._vbox_section.pack_start(separator_pm_screen, False, False, 0) + separator_pm_screen.show() + + label_pm_screen = Gtk.Label(_('Screen')) + label_pm_screen.set_alignment(0, 0) + self._vbox_section.pack_start(label_pm_screen, False, False, 0) + label_pm_screen.show() + + self.box_pm_screen = Gtk.VBox() + self.box_pm_screen.set_border_width(style.DEFAULT_SPACING * 2) + self.box_pm_screen.set_spacing(style.DEFAULT_SPACING) + + self._view_contrast() + self._view_letters() + + self._vbox_section.pack_start(self.box_pm_screen, False, False, 0) + self.box_pm_screen.show() + + def _view_mouse_options(self): + separator_pm_mouse = Gtk.HSeparator() + self._vbox_section.pack_start(separator_pm_mouse, False, False, 0) + separator_pm_mouse.show() + + label_pm_mouse = Gtk.Label(_('Mouse')) + label_pm_mouse.set_alignment(0, 0) + self._vbox_section.pack_start(label_pm_mouse, False, False, 0) + label_pm_mouse.show() + + self.box_pm_mouse = Gtk.VBox() + self.box_pm_mouse.set_border_width(style.DEFAULT_SPACING * 2) + self.box_pm_mouse.set_spacing(style.DEFAULT_SPACING) + + self._view_white_mouse() + self._view_acceleration_mouse() + + self._vbox_section.pack_start(self.box_pm_mouse, False, False, 0) + self.box_pm_mouse.show() + + def _set_mouse_keys(self, widget): + state = widget.get_active() + self._model.set_mouse_keys(state) + + def _set_sticky_keys(self, widget): + state = widget.get_active() + self._model.set_sticky_keys(state) + + def _set_bounce_keys(self, widget): + state = widget.get_active() + self._model.set_bounce_keys(state) + + def _set_contrast(self, widget): + state = widget.get_active() + self._model.set_contrast(state) + self.restart_alerts.append('zone') + self.needs_restart = True + self._zone_alert.props.msg = self.restart_msg + self._zone_alert.show() + + def _set_capital_letters(self, widget): + state = widget.get_active() + self._model.set_capital_letters(state) + self.restart_alerts.append('zone') + self.needs_restart = True + self._zone_alert.props.msg = self.restart_msg + self._zone_alert.show() + + def _set_white_mouse(self, widget): + state = widget.get_active() + self._model.set_white_mouse(state) + self.restart_alerts.append('zone') + self.needs_restart = True + self._zone_alert.props.msg = self.restart_msg + self._zone_alert.show() + + def cb_digits_scale_accel_mouse(self, adj): + self._model.set_accel_mouse(adj.get_value()) + + def undo(self): + self._model.set_mouse_keys(self.init_state_mouse_keys) + self._model.set_sticky_keys(self.init_state_sticky_keys) + self._model.set_bounce_keys(self.init_state_bounce_keys) + + + self._model.set_contrast(self.init_state_contrast) + self.btn_contrast.set_active(self.init_state_contrast) + + self._model.set_capital_letters(self.init_state_capital_letters) + self.btn_capital_letters.set_active(self.init_state_capital_letters) + + self._model.set_white_mouse(self.init_state_white_mouse) + self.btn_white_mouse.set_active(self.init_state_white_mouse) + + self.adj_accel_mouse.set_value(self.init_state_accel_mouse) + + self.needs_restart = False + self._zone_alert.hide() + + def _view_mouse_keys(self): + self.btn_mouse_keys = Gtk.CheckButton(_('Mouse Keys')) + self._mouse_pm_change_handler = self.btn_mouse_keys.connect("toggled", self._set_mouse_keys) + self.init_state_mouse_keys = self._model.get_mouse_keys() + self.btn_mouse_keys.set_active(self.init_state_mouse_keys) + self.box_pm_keyboard.pack_start(self.btn_mouse_keys, True, True, 2) + self.btn_mouse_keys.show() + + lbl_mouse = Gtk.Label(_('Move the mouse pointer with keyboard number.')) + lbl_mouse.set_alignment(0, 0) + self.box_pm_keyboard.pack_start(lbl_mouse, True, True, 2) + lbl_mouse.show() + + def _view_sticky_keys(self): + self.btn_sticky_keys = Gtk.CheckButton(_('Sticky Keys')) + self._sticky_pm_change_handler = self.btn_sticky_keys.connect("toggled", self._set_sticky_keys) + self.init_state_sticky_keys = self._model.get_sticky_keys() + self.btn_sticky_keys.set_active(self.init_state_sticky_keys) + self.box_pm_keyboard.pack_start(self.btn_sticky_keys, True, True, 2) + self.btn_sticky_keys.show() + + lbl_sticky = Gtk.Label(_('Instead of having to press two keys at once (such as CTRL + Q), you can press one key at a time.')) + lbl_sticky.set_line_wrap(True) + lbl_sticky.set_alignment(0, 0) + self.box_pm_keyboard.pack_start(lbl_sticky, True, True, 2) + lbl_sticky.show() + + def _view_bounce_keys(self): + self.btn_bounce_keys = Gtk.CheckButton(_('Bounce Keys')) + self._bounce_pm_change_handler = self.btn_bounce_keys.connect("toggled", self._set_bounce_keys) + self.init_state_bounce_keys = self._model.get_bounce_keys() + self.btn_bounce_keys.set_active(self.init_state_bounce_keys) + self.box_pm_keyboard.pack_start(self.btn_bounce_keys, True, True, 2) + self.btn_bounce_keys.show() + + lbl_bounce = Gtk.Label(_('Ignore rapid, repeated keypresses of the same key.')) + lbl_bounce.set_alignment(0, 0) + self.box_pm_keyboard.pack_start(lbl_bounce, True, True, 2) + lbl_bounce.show() + + def _view_contrast(self): + self.btn_contrast = Gtk.CheckButton(_('Contrast')) + self._contrast_pm_change_handler = self.btn_contrast.connect("toggled", self._set_contrast) + self.init_state_contrast = self._model.get_contrast() + if self.init_state_contrast: + self.btn_contrast.handler_block(self._contrast_pm_change_handler) + self.btn_contrast.set_active(True) + self.btn_contrast.handler_unblock(self._contrast_pm_change_handler) + else: + self.btn_contrast.set_active(False) + self.box_pm_screen.pack_start(self.btn_contrast, True, True, 2) + self.btn_contrast.show() + + lbl_contrast = Gtk.Label(_('Enables the color contrast of the graphic interface.')) + lbl_contrast.set_alignment(0, 0) + self.box_pm_screen.pack_start(lbl_contrast, True, True, 2) + lbl_contrast.show() + + def _view_letters(self): + self.btn_capital_letters = Gtk.CheckButton(_('Capital letters')) + self._capital_letters_pm_change_handler = self.btn_capital_letters.connect("toggled", self._set_capital_letters) + self.init_state_capital_letters = self._model.get_capital_letters() + if self.init_state_capital_letters: + self.btn_capital_letters.handler_block(self._capital_letters_pm_change_handler) + self.btn_capital_letters.set_active(True) + self.btn_capital_letters.handler_unblock(self._capital_letters_pm_change_handler) + else: + self.btn_capital_letters.set_active(False) + self.box_pm_screen.pack_start(self.btn_capital_letters, True, True, 2) + self.btn_capital_letters.show() + + lbl_capital_letters = Gtk.Label(_('Shows capital letters in the user interface.')) + lbl_capital_letters.set_alignment(0, 0) + self.box_pm_screen.pack_start(lbl_capital_letters, True, True, 2) + lbl_capital_letters.show() + + def _view_white_mouse(self): + self.btn_white_mouse = Gtk.CheckButton(_('White Mouse')) + self._white_mouse_pm_change_handler = self.btn_white_mouse.connect("toggled", self._set_white_mouse) + self.init_state_white_mouse = self._model.get_white_mouse() + if self.init_state_white_mouse: + self.btn_white_mouse.handler_block(self._white_mouse_pm_change_handler) + self.btn_white_mouse.set_active(True) + self.btn_white_mouse.handler_unblock(self._white_mouse_pm_change_handler) + else: + self.btn_white_mouse.set_active(False) + self.box_pm_mouse.pack_start(self.btn_white_mouse, True, True, 2) + self.btn_white_mouse.show() + + lbl_white_mouse = Gtk.Label(_('Show the mouse cursor white.')) + lbl_white_mouse.set_alignment(0, 0) + self.box_pm_mouse.pack_start(lbl_white_mouse, True, True, 2) + lbl_white_mouse.show() + + def _view_acceleration_mouse(self): + box_accel_mouse = Gtk.HBox(False, 0) + box_accel_mouse.set_border_width(0) + lbl_accel_mouse = Gtk.Label(_('Acceleration: ')) + lbl_accel_mouse.show() + box_accel_mouse.pack_start(lbl_accel_mouse, False, False, 0) + + self.init_state_accel_mouse = self._model.get_accel_mouse(); + self.adj_accel_mouse = Gtk.Adjustment(self.init_state_accel_mouse, 0.0, 5.0, 1.0, 1.0, 0.0) + self.adj_accel_mouse.connect("value_changed", self.cb_digits_scale_accel_mouse) + self.scale_accel_mouse = Gtk.HScale(adjustment=self.adj_accel_mouse) + self.scale_accel_mouse.set_digits(0) + self.scale_accel_mouse.show() + + box_accel_mouse.pack_start(self.scale_accel_mouse, True, True, 0) + box_accel_mouse.show() + + self.box_pm_mouse.pack_start(box_accel_mouse, True, True, 2) + + desc_accel_mouse = Gtk.Label(_('Controller acceleration mouse.')) + desc_accel_mouse.set_alignment(0, 0) + self.box_pm_mouse.pack_start(desc_accel_mouse, True, True, 2) + desc_accel_mouse.show() + + def setup(self): + pass diff --git a/extensions/globalkey/Makefile.am b/extensions/globalkey/Makefile.am index b6cbbd6..cab05ba 100644 --- a/extensions/globalkey/Makefile.am +++ b/extensions/globalkey/Makefile.am @@ -3,5 +3,6 @@ sugardir = $(pkgdatadir)/extensions/globalkey sugar_PYTHON = \ __init__.py \ screenshot.py \ + magnifier.py \ speech.py \ viewsource.py diff --git a/extensions/globalkey/magnifier.py b/extensions/globalkey/magnifier.py new file mode 100644 index 0000000..3f17f34 --- /dev/null +++ b/extensions/globalkey/magnifier.py @@ -0,0 +1,96 @@ +# Copyright (C) 2010 Plan Ceibal <comunidad@plan.ceibal.edu.uy> + +import os + +import ConfigParser +import logging +import GObject + +from jarabe.view.viewsource import setup_view_source +from sugar import env + + +PATH_VMG_CONFIG = os.environ['HOME'] + '/.magnifier.ini' +BOUND_KEYS = ['<shift>F13', 'F13', '<control>F13'] + +def handle_key_press(key): + logger = logging.getLogger('magnifier') + logger.setLevel(logging.DEBUG) + logger.debug("Ejecutando magnifier......" + key) + if (key=='<shift>F13'): + set_ruta_archivo() + set_GraphicsTools() + if (key=='<control>F13'): + set_ruta_archivo() + set_InvertColors() + _run_cmd_async('launchVmg') + +def get_GraphicsTools(): + return leer_config('General', 'GraphicsTools') + +def set_GraphicsTools(): + grabar_config_GraphicsTools('General', 'GraphicsTools') + +def grabar_config_GraphicsTools(encabezado, etiqueta): + parser = ConfigParser.ConfigParser() + parser.read(PATH_VMG_CONFIG) + val_old = get_GraphicsTools() + if val_old == '1': + parser.set(encabezado, etiqueta, '0') + arch = open(PATH_VMG_CONFIG, 'w') + parser.write(arch) + arch.close() + else: + parser.set(encabezado, etiqueta, '1') + arch = open(PATH_VMG_CONFIG, 'w') + parser.write(arch) + arch.close() + +def get_InvertColors(): + return leer_config('General', 'InvertColors') + +def set_InvertColors(): + grabar_config_InvertColors('General', 'InvertColors') + +def grabar_config_InvertColors(encabezado, etiqueta): + parser = ConfigParser.ConfigParser() + parser.read(PATH_VMG_CONFIG) + val_old = get_InvertColors() + if val_old == '1': + parser.set(encabezado, etiqueta, '0') + arch = open(PATH_VMG_CONFIG, 'w') + parser.write(arch) + arch.close() + else: + parser.set(encabezado, etiqueta, '1') + arch = open(PATH_VMG_CONFIG, 'w') + parser.write(arch) + arch.close() + +def leer_config(encabezado, etiqueta): + parser = ConfigParser.ConfigParser() + parser.read(PATH_VMG_CONFIG) + return parser.get(encabezado, etiqueta) + +def set_ruta_archivo(): + try: + f = file(PATH_VMG_CONFIG) + except: + PATH_VMG_CONFIG = "/root/.magnifier.ini" + +def _run_cmd_async(cmd): + logger = logging.getLogger('magnifier') + logger.setLevel(logging.DEBUG) + try: + GObject.spawn_async([find_and_absolutize('launchVmg')]) + logger.debug("Ejecuto magnifier") + except Exception, e: + logger.debug("Error ejecutando magnifier" + str(e)) + +def find_and_absolutize(script_name): + paths = env.os.environ['PATH'].split(':') + for path in paths: + looking_path = path + '/' + script_name + if env.os.path.isfile(looking_path): + return looking_path + return None diff --git a/src/jarabe/controlpanel/gui.py b/src/jarabe/controlpanel/gui.py index daa58e4..0f7c5e2 100644 --- a/src/jarabe/controlpanel/gui.py +++ b/src/jarabe/controlpanel/gui.py @@ -1,4 +1,5 @@ # Copyright (C) 2008 One Laptop Per Child +# Copyright (C) 2010 Plan Ceibal <comunidad@plan.ceibal.edu.uy> # # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by @@ -247,7 +248,7 @@ class ControlPanel(Gtk.Window): self._section_view.connect('request-close', self.__close_request_cb) self._main_view.modify_bg(Gtk.StateType.NORMAL, - style.COLOR_WHITE.get_gdk_color()) + style.COLOR_BG_CP.get_gdk_color()) def set_section_view_auto_close(self): """Automatically close the control panel if there is "nothing to do" diff --git a/src/jarabe/desktop/activitieslist.py b/src/jarabe/desktop/activitieslist.py index 4adaf18..1b1dbdc 100644 --- a/src/jarabe/desktop/activitieslist.py +++ b/src/jarabe/desktop/activitieslist.py @@ -1,5 +1,6 @@ # Copyright (C) 2008 One Laptop Per Child # Copyright (C) 2009 Tomeu Vizoso +# Copyright (C) 2010 Plan Ceibal <comunidad@plan.ceibal.edu.uy> # # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by @@ -297,7 +298,7 @@ class CellRendererActivityIcon(CellRendererIcon): self.props.width = style.GRID_CELL_SIZE self.props.height = style.GRID_CELL_SIZE self.props.size = style.STANDARD_ICON_SIZE - self.props.stroke_color = style.COLOR_BUTTON_GREY.get_svg() + self.props.stroke_color = style.COLOR_DESKTOP_ICON.get_svg() self.props.fill_color = style.COLOR_TRANSPARENT.get_svg() self.props.mode = Gtk.CellRendererMode.ACTIVATABLE diff --git a/src/jarabe/desktop/favoritesview.py b/src/jarabe/desktop/favoritesview.py index 7f5b160..bcc4b9f 100644 --- a/src/jarabe/desktop/favoritesview.py +++ b/src/jarabe/desktop/favoritesview.py @@ -1,5 +1,6 @@ # Copyright (C) 2006-2007 Red Hat, Inc. # Copyright (C) 2008 One Laptop Per Child +# Copyright (C) 2010 Plan Ceibal <comunidad@plan.ceibal.edu.uy> # # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by @@ -555,7 +556,7 @@ class FavoritePalette(ActivityPalette): ActivityPalette.__init__(self, activity_info) if not journal_entries: - xo_color = XoColor('%s,%s' % (style.COLOR_BUTTON_GREY.get_svg(), + xo_color = XoColor('%s,%s' % (style.COLOR_WHITE.get_svg(), style.COLOR_TRANSPARENT.get_svg())) else: xo_color = misc.get_icon_color(journal_entries[0]) diff --git a/src/jarabe/model/Makefile.am b/src/jarabe/model/Makefile.am index d40fb8d..8b37ee7 100644 --- a/src/jarabe/model/Makefile.am +++ b/src/jarabe/model/Makefile.am @@ -1,6 +1,7 @@ sugardir = $(pythondir)/jarabe/model sugar_PYTHON = \ adhoc.py \ + accessibility.py \ __init__.py \ buddy.py \ bundleregistry.py \ diff --git a/src/jarabe/model/accessibility.py b/src/jarabe/model/accessibility.py new file mode 100644 index 0000000..81266b7 --- /dev/null +++ b/src/jarabe/model/accessibility.py @@ -0,0 +1,160 @@ +# Copyright (C) 2010 Plan Ceibal +# +# Author: Esteban Arias <earias@plan.ceibal.edu.uy> +# Contact information: comunidad@plan.ceibal.edu.uy +# Plan Ceibal http://www.ceibal.edu.uy +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# This program 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 General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see <http://www.gnu.org/licenses/>. + +from gi.repository import Gtk +from gi.repository import GConf +import subprocess + +class Keyboard: + + def get_mouse_keys(self): + client = GConf.Client.get_default() + return client.get_bool("/desktop/sugar/accessibility/keyboard/mousekeys_enable") + + def set_mouse_keys(self, activar): + client = GConf.Client.get_default() + client.set_bool("/desktop/sugar/accessibility/keyboard/mousekeys_enable", activar) + self.run_config_keyboard() + + def get_sticky_keys(self): + client = GConf.Client.get_default() + return client.get_bool("/desktop/sugar/accessibility/keyboard/stickykeys_enable") + + def set_sticky_keys(self, activar): + client = GConf.Client.get_default() + client.set_bool("/desktop/sugar/accessibility/keyboard/stickykeys_enable", activar) + self.run_config_keyboard() + + def get_bounce_keys(self): + client = GConf.Client.get_default() + return client.get_bool("/desktop/sugar/accessibility/keyboard/bouncekeys_enable") + + def set_bounce_keys(self, activar): + client = GConf.Client.get_default() + client.set_bool("/desktop/sugar/accessibility/keyboard/bouncekeys_enable", activar) + self.run_config_keyboard() + + def run_config_keyboard(self): + cmd = ['ax'] + if self.get_sticky_keys(): + cmd.append('+stickykeys') + else: + cmd.append('-stickykeys') + if self.get_bounce_keys(): + cmd.append('+bouncekeys') + else: + cmd.append('-bouncekeys') + if self.get_mouse_keys(): + cmd += ['+mousekeys', 'mousemaxspeed', '3000', 'mousetimetomax', '1000', '-timeout', '-repeatkeys'] + else: + cmd += ['-mousekeys', 'mousemaxspeed', '3000', 'mousetimetomax', '1000', '+timeout', '+repeatkeys'] + subprocess.call(cmd) + +class Screen: + + DEFAULT_THEME = "sugar" + DEFAULT_FONT_SIZE = 7 + DEFAULT_FONT_FACE = "Sans Serif" + CONTRAST_THEME = "sugar-contrast" + CONTRAST_FONT_SIZE = 9.5 + CAPITAL_LETTERS_FONT_FACE = "Oracle" + + def get_contrast(self): + client = GConf.Client.get_default() + value = client.get_string("/desktop/sugar/interface/Gtk_theme") + return value==self.CONTRAST_THEME + + def set_contrast(self, activar): + client = GConf.Client.get_default() + if (activar): + client.set_string("/desktop/sugar/interface/Gtk_theme", self.CONTRAST_THEME) + client.set_float('/desktop/sugar/font/default_size', self.CONTRAST_FONT_SIZE) + else: + client.set_string("/desktop/sugar/interface/Gtk_theme", self.DEFAULT_THEME) + client.set_float('/desktop/sugar/font/default_size', self.DEFAULT_FONT_SIZE) + + def get_capital_letters(self): + client = GConf.Client.get_default() + value = client.get_string("/desktop/sugar/font/default_face") + return value==self.CAPITAL_LETTERS_FONT_FACE + + def set_capital_letters(self, activar): + client = GConf.Client.get_default() + if (activar): + client.set_string('/desktop/sugar/font/default_face', self.CAPITAL_LETTERS_FONT_FACE) + else: + client.set_string('/desktop/sugar/font/default_face', self.DEFAULT_FONT_FACE) + + +class Mouse: + + WHITE_CURSOR_THEME="FlatbedCursors.White.Huge" + DEFAULT_CURSOR_THEME="sugar" + DEFAULT_ACCEL_MOUSE=3 + + def get_white_mouse(self): + client = GConf.Client.get_default() + value = client.get_string("/desktop/sugar/peripherals/mouse/cursor_theme") + return value==self.WHITE_CURSOR_THEME + + def set_white_mouse(self, activar): + client = GConf.Client.get_default() + if (activar): + client.set_string("/desktop/sugar/peripherals/mouse/cursor_theme", self.WHITE_CURSOR_THEME) + else: + client.set_string("/desktop/sugar/peripherals/mouse/cursor_theme", self.DEFAULT_CURSOR_THEME) + + def _set_white_mouse_setting(self): + cursor_theme = self.DEFAULT_CURSOR_THEME + if (self.get_white_mouse()): + cursor_theme = self.WHITE_CURSOR_THEME + settings = Gtk.settings_get_default() + settings.set_property("Gtk-cursor-theme-name", "%s" % (cursor_theme)) + + def get_accel_mouse(self): + client = GConf.Client.get_default() + value = client.get_float("/desktop/sugar/peripherals/mouse/motion_acceleration") + return value + + def set_accel_mouse(self, value): + client = GConf.Client.get_default() + client.set_float("/desktop/sugar/peripherals/mouse/motion_acceleration", value) + self.run_config_mouse() + + def _set_accel_mouse_setting(self): + cmd = ['xset', 'm' , str(self.get_accel_mouse())] + subprocess.call(cmd) + + def run_config_mouse(self): + self._set_accel_mouse_setting() + self._set_white_mouse_setting() + +class AccessibilityManager: + def setup_accessibility(self): + client = GConf.Client.get_default() + is_accessibility = client.dir_exists("/desktop/sugar/accessibility") + mouse = Mouse() + if is_accessibility: + keyboard = Keyboard() + keyboard.run_config_keyboard() + mouse.run_config_mouse() + else: + mouse.set_accel_mouse(mouse.DEFAULT_ACCEL_MOUSE) + mouse.set_white_mouse(False) + mouse._set_accel_mouse_setting() |