Web   ·   Wiki   ·   Activities   ·   Blog   ·   Lists   ·   Chat   ·   Meeting   ·   Bugs   ·   Git   ·   Translate   ·   Archive   ·   People   ·   Donate
summaryrefslogtreecommitdiffstats
path: root/extensions/cpsection
diff options
context:
space:
mode:
Diffstat (limited to 'extensions/cpsection')
-rw-r--r--extensions/cpsection/Makefile.am5
-rw-r--r--extensions/cpsection/Makefile.in643
-rw-r--r--extensions/cpsection/__init__.py0
-rw-r--r--extensions/cpsection/aboutcomputer/Makefile.am6
-rw-r--r--extensions/cpsection/aboutcomputer/Makefile.in442
-rw-r--r--extensions/cpsection/aboutcomputer/__init__.py21
-rw-r--r--extensions/cpsection/aboutcomputer/model.py228
-rw-r--r--extensions/cpsection/aboutcomputer/view.py215
-rw-r--r--extensions/cpsection/aboutme/Makefile.am6
-rw-r--r--extensions/cpsection/aboutme/Makefile.in442
-rw-r--r--extensions/cpsection/aboutme/__init__.py26
-rw-r--r--extensions/cpsection/aboutme/model.py125
-rw-r--r--extensions/cpsection/aboutme/view.py340
-rw-r--r--extensions/cpsection/datetime/Makefile.am6
-rw-r--r--extensions/cpsection/datetime/Makefile.in442
-rw-r--r--extensions/cpsection/datetime/__init__.py21
-rw-r--r--extensions/cpsection/datetime/model.py96
-rw-r--r--extensions/cpsection/datetime/view.py140
-rw-r--r--extensions/cpsection/frame/Makefile.am6
-rw-r--r--extensions/cpsection/frame/Makefile.in442
-rw-r--r--extensions/cpsection/frame/__init__.py21
-rw-r--r--extensions/cpsection/frame/model.py69
-rw-r--r--extensions/cpsection/frame/view.py234
-rw-r--r--extensions/cpsection/keyboard/Makefile.am6
-rw-r--r--extensions/cpsection/keyboard/Makefile.in442
-rw-r--r--extensions/cpsection/keyboard/__init__.py21
-rw-r--r--extensions/cpsection/keyboard/model.py169
-rw-r--r--extensions/cpsection/keyboard/view.py425
-rw-r--r--extensions/cpsection/language/Makefile.am6
-rw-r--r--extensions/cpsection/language/Makefile.in442
-rw-r--r--extensions/cpsection/language/__init__.py21
-rw-r--r--extensions/cpsection/language/model.py164
-rw-r--r--extensions/cpsection/language/view.py281
-rw-r--r--extensions/cpsection/modemconfiguration/Makefile.am6
-rw-r--r--extensions/cpsection/modemconfiguration/Makefile.in442
-rw-r--r--extensions/cpsection/modemconfiguration/__init__.py21
-rwxr-xr-xextensions/cpsection/modemconfiguration/model.py100
-rw-r--r--extensions/cpsection/modemconfiguration/view.py144
-rw-r--r--extensions/cpsection/network/Makefile.am6
-rw-r--r--extensions/cpsection/network/Makefile.in442
-rw-r--r--extensions/cpsection/network/__init__.py22
-rw-r--r--extensions/cpsection/network/model.py156
-rw-r--r--extensions/cpsection/network/view.py261
-rw-r--r--extensions/cpsection/power/Makefile.am6
-rw-r--r--extensions/cpsection/power/Makefile.in442
-rw-r--r--extensions/cpsection/power/__init__.py22
-rw-r--r--extensions/cpsection/power/model.py94
-rw-r--r--extensions/cpsection/power/view.py122
-rw-r--r--extensions/cpsection/updater/Makefile.am8
-rw-r--r--extensions/cpsection/updater/Makefile.in645
-rw-r--r--extensions/cpsection/updater/__init__.py22
-rw-r--r--extensions/cpsection/updater/backends/Makefile.am5
-rw-r--r--extensions/cpsection/updater/backends/Makefile.in441
-rw-r--r--extensions/cpsection/updater/backends/__init__.py16
-rw-r--r--extensions/cpsection/updater/backends/aslo.py164
-rwxr-xr-xextensions/cpsection/updater/model.py354
-rw-r--r--extensions/cpsection/updater/view.py391
57 files changed, 10285 insertions, 0 deletions
diff --git a/extensions/cpsection/Makefile.am b/extensions/cpsection/Makefile.am
new file mode 100644
index 0000000..a92b5dd
--- /dev/null
+++ b/extensions/cpsection/Makefile.am
@@ -0,0 +1,5 @@
+SUBDIRS = aboutme aboutcomputer datetime frame keyboard language \
+ modemconfiguration network power updater
+
+sugardir = $(pkgdatadir)/extensions/cpsection
+sugar_PYTHON = __init__.py
diff --git a/extensions/cpsection/Makefile.in b/extensions/cpsection/Makefile.in
new file mode 100644
index 0000000..45b11e2
--- /dev/null
+++ b/extensions/cpsection/Makefile.in
@@ -0,0 +1,643 @@
+# Makefile.in generated by automake 1.11.3 from Makefile.am.
+# @configure_input@
+
+# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002,
+# 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011 Free Software
+# Foundation, Inc.
+# This Makefile.in is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
+# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
+# PARTICULAR PURPOSE.
+
+@SET_MAKE@
+VPATH = @srcdir@
+pkgdatadir = $(datadir)/@PACKAGE@
+pkgincludedir = $(includedir)/@PACKAGE@
+pkglibdir = $(libdir)/@PACKAGE@
+pkglibexecdir = $(libexecdir)/@PACKAGE@
+am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd
+install_sh_DATA = $(install_sh) -c -m 644
+install_sh_PROGRAM = $(install_sh) -c
+install_sh_SCRIPT = $(install_sh) -c
+INSTALL_HEADER = $(INSTALL_DATA)
+transform = $(program_transform_name)
+NORMAL_INSTALL = :
+PRE_INSTALL = :
+POST_INSTALL = :
+NORMAL_UNINSTALL = :
+PRE_UNINSTALL = :
+POST_UNINSTALL = :
+subdir = extensions/cpsection
+DIST_COMMON = $(srcdir)/Makefile.am $(srcdir)/Makefile.in \
+ $(sugar_PYTHON)
+ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
+am__aclocal_m4_deps = $(top_srcdir)/configure.ac
+am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
+ $(ACLOCAL_M4)
+mkinstalldirs = $(install_sh) -d
+CONFIG_CLEAN_FILES =
+CONFIG_CLEAN_VPATH_FILES =
+SOURCES =
+DIST_SOURCES =
+RECURSIVE_TARGETS = all-recursive check-recursive dvi-recursive \
+ html-recursive info-recursive install-data-recursive \
+ install-dvi-recursive install-exec-recursive \
+ install-html-recursive install-info-recursive \
+ install-pdf-recursive install-ps-recursive install-recursive \
+ installcheck-recursive installdirs-recursive pdf-recursive \
+ ps-recursive uninstall-recursive
+am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`;
+am__vpath_adj = case $$p in \
+ $(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \
+ *) f=$$p;; \
+ esac;
+am__strip_dir = f=`echo $$p | sed -e 's|^.*/||'`;
+am__install_max = 40
+am__nobase_strip_setup = \
+ srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*|]/\\\\&/g'`
+am__nobase_strip = \
+ for p in $$list; do echo "$$p"; done | sed -e "s|$$srcdirstrip/||"
+am__nobase_list = $(am__nobase_strip_setup); \
+ for p in $$list; do echo "$$p $$p"; done | \
+ sed "s| $$srcdirstrip/| |;"' / .*\//!s/ .*/ ./; s,\( .*\)/[^/]*$$,\1,' | \
+ $(AWK) 'BEGIN { files["."] = "" } { files[$$2] = files[$$2] " " $$1; \
+ if (++n[$$2] == $(am__install_max)) \
+ { print $$2, files[$$2]; n[$$2] = 0; files[$$2] = "" } } \
+ END { for (dir in files) print dir, files[dir] }'
+am__base_list = \
+ sed '$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;s/\n/ /g' | \
+ sed '$$!N;$$!N;$$!N;$$!N;s/\n/ /g'
+am__uninstall_files_from_dir = { \
+ test -z "$$files" \
+ || { test ! -d "$$dir" && test ! -f "$$dir" && test ! -r "$$dir"; } \
+ || { echo " ( cd '$$dir' && rm -f" $$files ")"; \
+ $(am__cd) "$$dir" && rm -f $$files; }; \
+ }
+am__py_compile = PYTHON=$(PYTHON) $(SHELL) $(py_compile)
+am__installdirs = "$(DESTDIR)$(sugardir)"
+py_compile = $(top_srcdir)/py-compile
+RECURSIVE_CLEAN_TARGETS = mostlyclean-recursive clean-recursive \
+ distclean-recursive maintainer-clean-recursive
+AM_RECURSIVE_TARGETS = $(RECURSIVE_TARGETS:-recursive=) \
+ $(RECURSIVE_CLEAN_TARGETS:-recursive=) tags TAGS ctags CTAGS \
+ distdir
+ETAGS = etags
+CTAGS = ctags
+DIST_SUBDIRS = $(SUBDIRS)
+DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
+am__relativize = \
+ dir0=`pwd`; \
+ sed_first='s,^\([^/]*\)/.*$$,\1,'; \
+ sed_rest='s,^[^/]*/*,,'; \
+ sed_last='s,^.*/\([^/]*\)$$,\1,'; \
+ sed_butlast='s,/*[^/]*$$,,'; \
+ while test -n "$$dir1"; do \
+ first=`echo "$$dir1" | sed -e "$$sed_first"`; \
+ if test "$$first" != "."; then \
+ if test "$$first" = ".."; then \
+ dir2=`echo "$$dir0" | sed -e "$$sed_last"`/"$$dir2"; \
+ dir0=`echo "$$dir0" | sed -e "$$sed_butlast"`; \
+ else \
+ first2=`echo "$$dir2" | sed -e "$$sed_first"`; \
+ if test "$$first2" = "$$first"; then \
+ dir2=`echo "$$dir2" | sed -e "$$sed_rest"`; \
+ else \
+ dir2="../$$dir2"; \
+ fi; \
+ dir0="$$dir0"/"$$first"; \
+ fi; \
+ fi; \
+ dir1=`echo "$$dir1" | sed -e "$$sed_rest"`; \
+ done; \
+ reldir="$$dir2"
+ACLOCAL = @ACLOCAL@
+ALL_LINGUAS = @ALL_LINGUAS@
+AMTAR = @AMTAR@
+AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@
+AUTOCONF = @AUTOCONF@
+AUTOHEADER = @AUTOHEADER@
+AUTOMAKE = @AUTOMAKE@
+AWK = @AWK@
+CATALOGS = @CATALOGS@
+CATOBJEXT = @CATOBJEXT@
+CC = @CC@
+CCDEPMODE = @CCDEPMODE@
+CFLAGS = @CFLAGS@
+CPP = @CPP@
+CPPFLAGS = @CPPFLAGS@
+CYGPATH_W = @CYGPATH_W@
+DATADIRNAME = @DATADIRNAME@
+DEFS = @DEFS@
+DEPDIR = @DEPDIR@
+ECHO_C = @ECHO_C@
+ECHO_N = @ECHO_N@
+ECHO_T = @ECHO_T@
+EGREP = @EGREP@
+EXEEXT = @EXEEXT@
+GCONFTOOL = @GCONFTOOL@
+GCONF_SCHEMA_CONFIG_SOURCE = @GCONF_SCHEMA_CONFIG_SOURCE@
+GCONF_SCHEMA_FILE_DIR = @GCONF_SCHEMA_FILE_DIR@
+GETTEXT_PACKAGE = @GETTEXT_PACKAGE@
+GMOFILES = @GMOFILES@
+GMSGFMT = @GMSGFMT@
+GREP = @GREP@
+INSTALL = @INSTALL@
+INSTALL_DATA = @INSTALL_DATA@
+INSTALL_PROGRAM = @INSTALL_PROGRAM@
+INSTALL_SCRIPT = @INSTALL_SCRIPT@
+INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@
+INSTOBJEXT = @INSTOBJEXT@
+INTLLIBS = @INTLLIBS@
+INTLTOOL_EXTRACT = @INTLTOOL_EXTRACT@
+INTLTOOL_MERGE = @INTLTOOL_MERGE@
+INTLTOOL_PERL = @INTLTOOL_PERL@
+INTLTOOL_UPDATE = @INTLTOOL_UPDATE@
+INTLTOOL_V_MERGE = @INTLTOOL_V_MERGE@
+INTLTOOL_V_MERGE_OPTIONS = @INTLTOOL_V_MERGE_OPTIONS@
+INTLTOOL__v_MERGE_ = @INTLTOOL__v_MERGE_@
+INTLTOOL__v_MERGE_0 = @INTLTOOL__v_MERGE_0@
+LDFLAGS = @LDFLAGS@
+LIBOBJS = @LIBOBJS@
+LIBS = @LIBS@
+LTLIBOBJS = @LTLIBOBJS@
+MAINT = @MAINT@
+MAKEINFO = @MAKEINFO@
+MKDIR_P = @MKDIR_P@
+MKINSTALLDIRS = @MKINSTALLDIRS@
+MSGFMT = @MSGFMT@
+MSGFMT_OPTS = @MSGFMT_OPTS@
+MSGMERGE = @MSGMERGE@
+OBJEXT = @OBJEXT@
+PACKAGE = @PACKAGE@
+PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@
+PACKAGE_NAME = @PACKAGE_NAME@
+PACKAGE_STRING = @PACKAGE_STRING@
+PACKAGE_TARNAME = @PACKAGE_TARNAME@
+PACKAGE_URL = @PACKAGE_URL@
+PACKAGE_VERSION = @PACKAGE_VERSION@
+PATH_SEPARATOR = @PATH_SEPARATOR@
+PKG_CONFIG = @PKG_CONFIG@
+PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@
+PKG_CONFIG_PATH = @PKG_CONFIG_PATH@
+POFILES = @POFILES@
+POSUB = @POSUB@
+PO_IN_DATADIR_FALSE = @PO_IN_DATADIR_FALSE@
+PO_IN_DATADIR_TRUE = @PO_IN_DATADIR_TRUE@
+PYTHON = @PYTHON@
+PYTHON_EXEC_PREFIX = @PYTHON_EXEC_PREFIX@
+PYTHON_PLATFORM = @PYTHON_PLATFORM@
+PYTHON_PREFIX = @PYTHON_PREFIX@
+PYTHON_VERSION = @PYTHON_VERSION@
+SET_MAKE = @SET_MAKE@
+SHELL = @SHELL@
+SHELL_CFLAGS = @SHELL_CFLAGS@
+SHELL_LIBS = @SHELL_LIBS@
+STRIP = @STRIP@
+SUCROSE_VERSION = @SUCROSE_VERSION@
+USE_NLS = @USE_NLS@
+VERSION = @VERSION@
+XGETTEXT = @XGETTEXT@
+abs_builddir = @abs_builddir@
+abs_srcdir = @abs_srcdir@
+abs_top_builddir = @abs_top_builddir@
+abs_top_srcdir = @abs_top_srcdir@
+ac_ct_CC = @ac_ct_CC@
+am__include = @am__include@
+am__leading_dot = @am__leading_dot@
+am__quote = @am__quote@
+am__tar = @am__tar@
+am__untar = @am__untar@
+bindir = @bindir@
+build_alias = @build_alias@
+builddir = @builddir@
+datadir = @datadir@
+datarootdir = @datarootdir@
+docdir = @docdir@
+dvidir = @dvidir@
+exec_prefix = @exec_prefix@
+host_alias = @host_alias@
+htmldir = @htmldir@
+includedir = @includedir@
+infodir = @infodir@
+install_sh = @install_sh@
+intltool__v_merge_options_ = @intltool__v_merge_options_@
+intltool__v_merge_options_0 = @intltool__v_merge_options_0@
+libdir = @libdir@
+libexecdir = @libexecdir@
+localedir = @localedir@
+localstatedir = @localstatedir@
+mandir = @mandir@
+mkdir_p = @mkdir_p@
+oldincludedir = @oldincludedir@
+pdfdir = @pdfdir@
+pkgpyexecdir = @pkgpyexecdir@
+pkgpythondir = @pkgpythondir@
+prefix = @prefix@
+program_transform_name = @program_transform_name@
+psdir = @psdir@
+pyexecdir = @pyexecdir@
+pythondir = @pythondir@
+sbindir = @sbindir@
+sharedstatedir = @sharedstatedir@
+srcdir = @srcdir@
+sysconfdir = @sysconfdir@
+target_alias = @target_alias@
+top_build_prefix = @top_build_prefix@
+top_builddir = @top_builddir@
+top_srcdir = @top_srcdir@
+SUBDIRS = aboutme aboutcomputer datetime frame keyboard language \
+ modemconfiguration network power updater
+
+sugardir = $(pkgdatadir)/extensions/cpsection
+sugar_PYTHON = __init__.py
+all: all-recursive
+
+.SUFFIXES:
+$(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ $(srcdir)/Makefile.am $(am__configure_deps)
+ @for dep in $?; do \
+ case '$(am__configure_deps)' in \
+ *$$dep*) \
+ ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \
+ && { if test -f $@; then exit 0; else break; fi; }; \
+ exit 1;; \
+ esac; \
+ done; \
+ echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign extensions/cpsection/Makefile'; \
+ $(am__cd) $(top_srcdir) && \
+ $(AUTOMAKE) --foreign extensions/cpsection/Makefile
+.PRECIOUS: Makefile
+Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
+ @case '$?' in \
+ *config.status*) \
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \
+ *) \
+ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \
+ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \
+ esac;
+
+$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES)
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+
+$(top_srcdir)/configure: @MAINTAINER_MODE_TRUE@ $(am__configure_deps)
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+$(ACLOCAL_M4): @MAINTAINER_MODE_TRUE@ $(am__aclocal_m4_deps)
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+$(am__aclocal_m4_deps):
+install-sugarPYTHON: $(sugar_PYTHON)
+ @$(NORMAL_INSTALL)
+ test -z "$(sugardir)" || $(MKDIR_P) "$(DESTDIR)$(sugardir)"
+ @list='$(sugar_PYTHON)'; dlist=; list2=; test -n "$(sugardir)" || list=; \
+ for p in $$list; do \
+ if test -f "$$p"; then b=; else b="$(srcdir)/"; fi; \
+ if test -f $$b$$p; then \
+ $(am__strip_dir) \
+ dlist="$$dlist $$f"; \
+ list2="$$list2 $$b$$p"; \
+ else :; fi; \
+ done; \
+ for file in $$list2; do echo $$file; done | $(am__base_list) | \
+ while read files; do \
+ echo " $(INSTALL_DATA) $$files '$(DESTDIR)$(sugardir)'"; \
+ $(INSTALL_DATA) $$files "$(DESTDIR)$(sugardir)" || exit $$?; \
+ done || exit $$?; \
+ if test -n "$$dlist"; then \
+ $(am__py_compile) --destdir "$(DESTDIR)" \
+ --basedir "$(sugardir)" $$dlist; \
+ else :; fi
+
+uninstall-sugarPYTHON:
+ @$(NORMAL_UNINSTALL)
+ @list='$(sugar_PYTHON)'; test -n "$(sugardir)" || list=; \
+ files=`for p in $$list; do echo $$p; done | sed -e 's|^.*/||'`; \
+ test -n "$$files" || exit 0; \
+ dir='$(DESTDIR)$(sugardir)'; \
+ filesc=`echo "$$files" | sed 's|$$|c|'`; \
+ fileso=`echo "$$files" | sed 's|$$|o|'`; \
+ st=0; \
+ for files in "$$files" "$$filesc" "$$fileso"; do \
+ $(am__uninstall_files_from_dir) || st=$$?; \
+ done; \
+ exit $$st
+
+# This directory's subdirectories are mostly independent; you can cd
+# into them and run `make' without going through this Makefile.
+# To change the values of `make' variables: instead of editing Makefiles,
+# (1) if the variable is set in `config.status', edit `config.status'
+# (which will cause the Makefiles to be regenerated when you run `make');
+# (2) otherwise, pass the desired values on the `make' command line.
+$(RECURSIVE_TARGETS):
+ @fail= failcom='exit 1'; \
+ for f in x $$MAKEFLAGS; do \
+ case $$f in \
+ *=* | --[!k]*);; \
+ *k*) failcom='fail=yes';; \
+ esac; \
+ done; \
+ dot_seen=no; \
+ target=`echo $@ | sed s/-recursive//`; \
+ list='$(SUBDIRS)'; for subdir in $$list; do \
+ echo "Making $$target in $$subdir"; \
+ if test "$$subdir" = "."; then \
+ dot_seen=yes; \
+ local_target="$$target-am"; \
+ else \
+ local_target="$$target"; \
+ fi; \
+ ($(am__cd) $$subdir && $(MAKE) $(AM_MAKEFLAGS) $$local_target) \
+ || eval $$failcom; \
+ done; \
+ if test "$$dot_seen" = "no"; then \
+ $(MAKE) $(AM_MAKEFLAGS) "$$target-am" || exit 1; \
+ fi; test -z "$$fail"
+
+$(RECURSIVE_CLEAN_TARGETS):
+ @fail= failcom='exit 1'; \
+ for f in x $$MAKEFLAGS; do \
+ case $$f in \
+ *=* | --[!k]*);; \
+ *k*) failcom='fail=yes';; \
+ esac; \
+ done; \
+ dot_seen=no; \
+ case "$@" in \
+ distclean-* | maintainer-clean-*) list='$(DIST_SUBDIRS)' ;; \
+ *) list='$(SUBDIRS)' ;; \
+ esac; \
+ rev=''; for subdir in $$list; do \
+ if test "$$subdir" = "."; then :; else \
+ rev="$$subdir $$rev"; \
+ fi; \
+ done; \
+ rev="$$rev ."; \
+ target=`echo $@ | sed s/-recursive//`; \
+ for subdir in $$rev; do \
+ echo "Making $$target in $$subdir"; \
+ if test "$$subdir" = "."; then \
+ local_target="$$target-am"; \
+ else \
+ local_target="$$target"; \
+ fi; \
+ ($(am__cd) $$subdir && $(MAKE) $(AM_MAKEFLAGS) $$local_target) \
+ || eval $$failcom; \
+ done && test -z "$$fail"
+tags-recursive:
+ list='$(SUBDIRS)'; for subdir in $$list; do \
+ test "$$subdir" = . || ($(am__cd) $$subdir && $(MAKE) $(AM_MAKEFLAGS) tags); \
+ done
+ctags-recursive:
+ list='$(SUBDIRS)'; for subdir in $$list; do \
+ test "$$subdir" = . || ($(am__cd) $$subdir && $(MAKE) $(AM_MAKEFLAGS) ctags); \
+ done
+
+ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES)
+ list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \
+ unique=`for i in $$list; do \
+ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
+ done | \
+ $(AWK) '{ files[$$0] = 1; nonempty = 1; } \
+ END { if (nonempty) { for (i in files) print i; }; }'`; \
+ mkid -fID $$unique
+tags: TAGS
+
+TAGS: tags-recursive $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \
+ $(TAGS_FILES) $(LISP)
+ set x; \
+ here=`pwd`; \
+ if ($(ETAGS) --etags-include --version) >/dev/null 2>&1; then \
+ include_option=--etags-include; \
+ empty_fix=.; \
+ else \
+ include_option=--include; \
+ empty_fix=; \
+ fi; \
+ list='$(SUBDIRS)'; for subdir in $$list; do \
+ if test "$$subdir" = .; then :; else \
+ test ! -f $$subdir/TAGS || \
+ set "$$@" "$$include_option=$$here/$$subdir/TAGS"; \
+ fi; \
+ done; \
+ list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \
+ unique=`for i in $$list; do \
+ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
+ done | \
+ $(AWK) '{ files[$$0] = 1; nonempty = 1; } \
+ END { if (nonempty) { for (i in files) print i; }; }'`; \
+ shift; \
+ if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \
+ test -n "$$unique" || unique=$$empty_fix; \
+ if test $$# -gt 0; then \
+ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
+ "$$@" $$unique; \
+ else \
+ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
+ $$unique; \
+ fi; \
+ fi
+ctags: CTAGS
+CTAGS: ctags-recursive $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \
+ $(TAGS_FILES) $(LISP)
+ list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \
+ unique=`for i in $$list; do \
+ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
+ done | \
+ $(AWK) '{ files[$$0] = 1; nonempty = 1; } \
+ END { if (nonempty) { for (i in files) print i; }; }'`; \
+ test -z "$(CTAGS_ARGS)$$unique" \
+ || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \
+ $$unique
+
+GTAGS:
+ here=`$(am__cd) $(top_builddir) && pwd` \
+ && $(am__cd) $(top_srcdir) \
+ && gtags -i $(GTAGS_ARGS) "$$here"
+
+distclean-tags:
+ -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags
+
+distdir: $(DISTFILES)
+ @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
+ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
+ list='$(DISTFILES)'; \
+ dist_files=`for file in $$list; do echo $$file; done | \
+ sed -e "s|^$$srcdirstrip/||;t" \
+ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \
+ case $$dist_files in \
+ */*) $(MKDIR_P) `echo "$$dist_files" | \
+ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \
+ sort -u` ;; \
+ esac; \
+ for file in $$dist_files; do \
+ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \
+ if test -d $$d/$$file; then \
+ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \
+ if test -d "$(distdir)/$$file"; then \
+ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \
+ fi; \
+ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \
+ cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \
+ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \
+ fi; \
+ cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \
+ else \
+ test -f "$(distdir)/$$file" \
+ || cp -p $$d/$$file "$(distdir)/$$file" \
+ || exit 1; \
+ fi; \
+ done
+ @list='$(DIST_SUBDIRS)'; for subdir in $$list; do \
+ if test "$$subdir" = .; then :; else \
+ test -d "$(distdir)/$$subdir" \
+ || $(MKDIR_P) "$(distdir)/$$subdir" \
+ || exit 1; \
+ fi; \
+ done
+ @list='$(DIST_SUBDIRS)'; for subdir in $$list; do \
+ if test "$$subdir" = .; then :; else \
+ dir1=$$subdir; dir2="$(distdir)/$$subdir"; \
+ $(am__relativize); \
+ new_distdir=$$reldir; \
+ dir1=$$subdir; dir2="$(top_distdir)"; \
+ $(am__relativize); \
+ new_top_distdir=$$reldir; \
+ echo " (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) top_distdir="$$new_top_distdir" distdir="$$new_distdir" \\"; \
+ echo " am__remove_distdir=: am__skip_length_check=: am__skip_mode_fix=: distdir)"; \
+ ($(am__cd) $$subdir && \
+ $(MAKE) $(AM_MAKEFLAGS) \
+ top_distdir="$$new_top_distdir" \
+ distdir="$$new_distdir" \
+ am__remove_distdir=: \
+ am__skip_length_check=: \
+ am__skip_mode_fix=: \
+ distdir) \
+ || exit 1; \
+ fi; \
+ done
+check-am: all-am
+check: check-recursive
+all-am: Makefile
+installdirs: installdirs-recursive
+installdirs-am:
+ for dir in "$(DESTDIR)$(sugardir)"; do \
+ test -z "$$dir" || $(MKDIR_P) "$$dir"; \
+ done
+install: install-recursive
+install-exec: install-exec-recursive
+install-data: install-data-recursive
+uninstall: uninstall-recursive
+
+install-am: all-am
+ @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am
+
+installcheck: installcheck-recursive
+install-strip:
+ if test -z '$(STRIP)'; then \
+ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
+ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
+ install; \
+ else \
+ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
+ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
+ "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \
+ fi
+mostlyclean-generic:
+
+clean-generic:
+
+distclean-generic:
+ -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES)
+ -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES)
+
+maintainer-clean-generic:
+ @echo "This command is intended for maintainers to use"
+ @echo "it deletes files that may require special tools to rebuild."
+clean: clean-recursive
+
+clean-am: clean-generic mostlyclean-am
+
+distclean: distclean-recursive
+ -rm -f Makefile
+distclean-am: clean-am distclean-generic distclean-tags
+
+dvi: dvi-recursive
+
+dvi-am:
+
+html: html-recursive
+
+html-am:
+
+info: info-recursive
+
+info-am:
+
+install-data-am: install-sugarPYTHON
+
+install-dvi: install-dvi-recursive
+
+install-dvi-am:
+
+install-exec-am:
+
+install-html: install-html-recursive
+
+install-html-am:
+
+install-info: install-info-recursive
+
+install-info-am:
+
+install-man:
+
+install-pdf: install-pdf-recursive
+
+install-pdf-am:
+
+install-ps: install-ps-recursive
+
+install-ps-am:
+
+installcheck-am:
+
+maintainer-clean: maintainer-clean-recursive
+ -rm -f Makefile
+maintainer-clean-am: distclean-am maintainer-clean-generic
+
+mostlyclean: mostlyclean-recursive
+
+mostlyclean-am: mostlyclean-generic
+
+pdf: pdf-recursive
+
+pdf-am:
+
+ps: ps-recursive
+
+ps-am:
+
+uninstall-am: uninstall-sugarPYTHON
+
+.MAKE: $(RECURSIVE_CLEAN_TARGETS) $(RECURSIVE_TARGETS) ctags-recursive \
+ install-am install-strip tags-recursive
+
+.PHONY: $(RECURSIVE_CLEAN_TARGETS) $(RECURSIVE_TARGETS) CTAGS GTAGS \
+ all all-am check check-am clean clean-generic ctags \
+ ctags-recursive distclean distclean-generic distclean-tags \
+ distdir dvi dvi-am html html-am info info-am install \
+ install-am install-data install-data-am install-dvi \
+ install-dvi-am install-exec install-exec-am install-html \
+ install-html-am install-info install-info-am install-man \
+ install-pdf install-pdf-am install-ps install-ps-am \
+ install-strip install-sugarPYTHON installcheck installcheck-am \
+ installdirs installdirs-am maintainer-clean \
+ maintainer-clean-generic mostlyclean mostlyclean-generic pdf \
+ pdf-am ps ps-am tags tags-recursive uninstall uninstall-am \
+ uninstall-sugarPYTHON
+
+
+# Tell versions [3.59,3.63) of GNU make to not export all variables.
+# Otherwise a system limit (for SysV at least) may be exceeded.
+.NOEXPORT:
diff --git a/extensions/cpsection/__init__.py b/extensions/cpsection/__init__.py
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/extensions/cpsection/__init__.py
diff --git a/extensions/cpsection/aboutcomputer/Makefile.am b/extensions/cpsection/aboutcomputer/Makefile.am
new file mode 100644
index 0000000..a3bdec8
--- /dev/null
+++ b/extensions/cpsection/aboutcomputer/Makefile.am
@@ -0,0 +1,6 @@
+sugardir = $(pkgdatadir)/extensions/cpsection/aboutcomputer
+
+sugar_PYTHON = \
+ __init__.py \
+ model.py \
+ view.py
diff --git a/extensions/cpsection/aboutcomputer/Makefile.in b/extensions/cpsection/aboutcomputer/Makefile.in
new file mode 100644
index 0000000..7d25501
--- /dev/null
+++ b/extensions/cpsection/aboutcomputer/Makefile.in
@@ -0,0 +1,442 @@
+# Makefile.in generated by automake 1.11.3 from Makefile.am.
+# @configure_input@
+
+# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002,
+# 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011 Free Software
+# Foundation, Inc.
+# This Makefile.in is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
+# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
+# PARTICULAR PURPOSE.
+
+@SET_MAKE@
+VPATH = @srcdir@
+pkgdatadir = $(datadir)/@PACKAGE@
+pkgincludedir = $(includedir)/@PACKAGE@
+pkglibdir = $(libdir)/@PACKAGE@
+pkglibexecdir = $(libexecdir)/@PACKAGE@
+am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd
+install_sh_DATA = $(install_sh) -c -m 644
+install_sh_PROGRAM = $(install_sh) -c
+install_sh_SCRIPT = $(install_sh) -c
+INSTALL_HEADER = $(INSTALL_DATA)
+transform = $(program_transform_name)
+NORMAL_INSTALL = :
+PRE_INSTALL = :
+POST_INSTALL = :
+NORMAL_UNINSTALL = :
+PRE_UNINSTALL = :
+POST_UNINSTALL = :
+subdir = extensions/cpsection/aboutcomputer
+DIST_COMMON = $(srcdir)/Makefile.am $(srcdir)/Makefile.in \
+ $(sugar_PYTHON)
+ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
+am__aclocal_m4_deps = $(top_srcdir)/configure.ac
+am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
+ $(ACLOCAL_M4)
+mkinstalldirs = $(install_sh) -d
+CONFIG_CLEAN_FILES =
+CONFIG_CLEAN_VPATH_FILES =
+SOURCES =
+DIST_SOURCES =
+am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`;
+am__vpath_adj = case $$p in \
+ $(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \
+ *) f=$$p;; \
+ esac;
+am__strip_dir = f=`echo $$p | sed -e 's|^.*/||'`;
+am__install_max = 40
+am__nobase_strip_setup = \
+ srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*|]/\\\\&/g'`
+am__nobase_strip = \
+ for p in $$list; do echo "$$p"; done | sed -e "s|$$srcdirstrip/||"
+am__nobase_list = $(am__nobase_strip_setup); \
+ for p in $$list; do echo "$$p $$p"; done | \
+ sed "s| $$srcdirstrip/| |;"' / .*\//!s/ .*/ ./; s,\( .*\)/[^/]*$$,\1,' | \
+ $(AWK) 'BEGIN { files["."] = "" } { files[$$2] = files[$$2] " " $$1; \
+ if (++n[$$2] == $(am__install_max)) \
+ { print $$2, files[$$2]; n[$$2] = 0; files[$$2] = "" } } \
+ END { for (dir in files) print dir, files[dir] }'
+am__base_list = \
+ sed '$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;s/\n/ /g' | \
+ sed '$$!N;$$!N;$$!N;$$!N;s/\n/ /g'
+am__uninstall_files_from_dir = { \
+ test -z "$$files" \
+ || { test ! -d "$$dir" && test ! -f "$$dir" && test ! -r "$$dir"; } \
+ || { echo " ( cd '$$dir' && rm -f" $$files ")"; \
+ $(am__cd) "$$dir" && rm -f $$files; }; \
+ }
+am__py_compile = PYTHON=$(PYTHON) $(SHELL) $(py_compile)
+am__installdirs = "$(DESTDIR)$(sugardir)"
+py_compile = $(top_srcdir)/py-compile
+DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
+ACLOCAL = @ACLOCAL@
+ALL_LINGUAS = @ALL_LINGUAS@
+AMTAR = @AMTAR@
+AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@
+AUTOCONF = @AUTOCONF@
+AUTOHEADER = @AUTOHEADER@
+AUTOMAKE = @AUTOMAKE@
+AWK = @AWK@
+CATALOGS = @CATALOGS@
+CATOBJEXT = @CATOBJEXT@
+CC = @CC@
+CCDEPMODE = @CCDEPMODE@
+CFLAGS = @CFLAGS@
+CPP = @CPP@
+CPPFLAGS = @CPPFLAGS@
+CYGPATH_W = @CYGPATH_W@
+DATADIRNAME = @DATADIRNAME@
+DEFS = @DEFS@
+DEPDIR = @DEPDIR@
+ECHO_C = @ECHO_C@
+ECHO_N = @ECHO_N@
+ECHO_T = @ECHO_T@
+EGREP = @EGREP@
+EXEEXT = @EXEEXT@
+GCONFTOOL = @GCONFTOOL@
+GCONF_SCHEMA_CONFIG_SOURCE = @GCONF_SCHEMA_CONFIG_SOURCE@
+GCONF_SCHEMA_FILE_DIR = @GCONF_SCHEMA_FILE_DIR@
+GETTEXT_PACKAGE = @GETTEXT_PACKAGE@
+GMOFILES = @GMOFILES@
+GMSGFMT = @GMSGFMT@
+GREP = @GREP@
+INSTALL = @INSTALL@
+INSTALL_DATA = @INSTALL_DATA@
+INSTALL_PROGRAM = @INSTALL_PROGRAM@
+INSTALL_SCRIPT = @INSTALL_SCRIPT@
+INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@
+INSTOBJEXT = @INSTOBJEXT@
+INTLLIBS = @INTLLIBS@
+INTLTOOL_EXTRACT = @INTLTOOL_EXTRACT@
+INTLTOOL_MERGE = @INTLTOOL_MERGE@
+INTLTOOL_PERL = @INTLTOOL_PERL@
+INTLTOOL_UPDATE = @INTLTOOL_UPDATE@
+INTLTOOL_V_MERGE = @INTLTOOL_V_MERGE@
+INTLTOOL_V_MERGE_OPTIONS = @INTLTOOL_V_MERGE_OPTIONS@
+INTLTOOL__v_MERGE_ = @INTLTOOL__v_MERGE_@
+INTLTOOL__v_MERGE_0 = @INTLTOOL__v_MERGE_0@
+LDFLAGS = @LDFLAGS@
+LIBOBJS = @LIBOBJS@
+LIBS = @LIBS@
+LTLIBOBJS = @LTLIBOBJS@
+MAINT = @MAINT@
+MAKEINFO = @MAKEINFO@
+MKDIR_P = @MKDIR_P@
+MKINSTALLDIRS = @MKINSTALLDIRS@
+MSGFMT = @MSGFMT@
+MSGFMT_OPTS = @MSGFMT_OPTS@
+MSGMERGE = @MSGMERGE@
+OBJEXT = @OBJEXT@
+PACKAGE = @PACKAGE@
+PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@
+PACKAGE_NAME = @PACKAGE_NAME@
+PACKAGE_STRING = @PACKAGE_STRING@
+PACKAGE_TARNAME = @PACKAGE_TARNAME@
+PACKAGE_URL = @PACKAGE_URL@
+PACKAGE_VERSION = @PACKAGE_VERSION@
+PATH_SEPARATOR = @PATH_SEPARATOR@
+PKG_CONFIG = @PKG_CONFIG@
+PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@
+PKG_CONFIG_PATH = @PKG_CONFIG_PATH@
+POFILES = @POFILES@
+POSUB = @POSUB@
+PO_IN_DATADIR_FALSE = @PO_IN_DATADIR_FALSE@
+PO_IN_DATADIR_TRUE = @PO_IN_DATADIR_TRUE@
+PYTHON = @PYTHON@
+PYTHON_EXEC_PREFIX = @PYTHON_EXEC_PREFIX@
+PYTHON_PLATFORM = @PYTHON_PLATFORM@
+PYTHON_PREFIX = @PYTHON_PREFIX@
+PYTHON_VERSION = @PYTHON_VERSION@
+SET_MAKE = @SET_MAKE@
+SHELL = @SHELL@
+SHELL_CFLAGS = @SHELL_CFLAGS@
+SHELL_LIBS = @SHELL_LIBS@
+STRIP = @STRIP@
+SUCROSE_VERSION = @SUCROSE_VERSION@
+USE_NLS = @USE_NLS@
+VERSION = @VERSION@
+XGETTEXT = @XGETTEXT@
+abs_builddir = @abs_builddir@
+abs_srcdir = @abs_srcdir@
+abs_top_builddir = @abs_top_builddir@
+abs_top_srcdir = @abs_top_srcdir@
+ac_ct_CC = @ac_ct_CC@
+am__include = @am__include@
+am__leading_dot = @am__leading_dot@
+am__quote = @am__quote@
+am__tar = @am__tar@
+am__untar = @am__untar@
+bindir = @bindir@
+build_alias = @build_alias@
+builddir = @builddir@
+datadir = @datadir@
+datarootdir = @datarootdir@
+docdir = @docdir@
+dvidir = @dvidir@
+exec_prefix = @exec_prefix@
+host_alias = @host_alias@
+htmldir = @htmldir@
+includedir = @includedir@
+infodir = @infodir@
+install_sh = @install_sh@
+intltool__v_merge_options_ = @intltool__v_merge_options_@
+intltool__v_merge_options_0 = @intltool__v_merge_options_0@
+libdir = @libdir@
+libexecdir = @libexecdir@
+localedir = @localedir@
+localstatedir = @localstatedir@
+mandir = @mandir@
+mkdir_p = @mkdir_p@
+oldincludedir = @oldincludedir@
+pdfdir = @pdfdir@
+pkgpyexecdir = @pkgpyexecdir@
+pkgpythondir = @pkgpythondir@
+prefix = @prefix@
+program_transform_name = @program_transform_name@
+psdir = @psdir@
+pyexecdir = @pyexecdir@
+pythondir = @pythondir@
+sbindir = @sbindir@
+sharedstatedir = @sharedstatedir@
+srcdir = @srcdir@
+sysconfdir = @sysconfdir@
+target_alias = @target_alias@
+top_build_prefix = @top_build_prefix@
+top_builddir = @top_builddir@
+top_srcdir = @top_srcdir@
+sugardir = $(pkgdatadir)/extensions/cpsection/aboutcomputer
+sugar_PYTHON = \
+ __init__.py \
+ model.py \
+ view.py
+
+all: all-am
+
+.SUFFIXES:
+$(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ $(srcdir)/Makefile.am $(am__configure_deps)
+ @for dep in $?; do \
+ case '$(am__configure_deps)' in \
+ *$$dep*) \
+ ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \
+ && { if test -f $@; then exit 0; else break; fi; }; \
+ exit 1;; \
+ esac; \
+ done; \
+ echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign extensions/cpsection/aboutcomputer/Makefile'; \
+ $(am__cd) $(top_srcdir) && \
+ $(AUTOMAKE) --foreign extensions/cpsection/aboutcomputer/Makefile
+.PRECIOUS: Makefile
+Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
+ @case '$?' in \
+ *config.status*) \
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \
+ *) \
+ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \
+ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \
+ esac;
+
+$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES)
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+
+$(top_srcdir)/configure: @MAINTAINER_MODE_TRUE@ $(am__configure_deps)
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+$(ACLOCAL_M4): @MAINTAINER_MODE_TRUE@ $(am__aclocal_m4_deps)
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+$(am__aclocal_m4_deps):
+install-sugarPYTHON: $(sugar_PYTHON)
+ @$(NORMAL_INSTALL)
+ test -z "$(sugardir)" || $(MKDIR_P) "$(DESTDIR)$(sugardir)"
+ @list='$(sugar_PYTHON)'; dlist=; list2=; test -n "$(sugardir)" || list=; \
+ for p in $$list; do \
+ if test -f "$$p"; then b=; else b="$(srcdir)/"; fi; \
+ if test -f $$b$$p; then \
+ $(am__strip_dir) \
+ dlist="$$dlist $$f"; \
+ list2="$$list2 $$b$$p"; \
+ else :; fi; \
+ done; \
+ for file in $$list2; do echo $$file; done | $(am__base_list) | \
+ while read files; do \
+ echo " $(INSTALL_DATA) $$files '$(DESTDIR)$(sugardir)'"; \
+ $(INSTALL_DATA) $$files "$(DESTDIR)$(sugardir)" || exit $$?; \
+ done || exit $$?; \
+ if test -n "$$dlist"; then \
+ $(am__py_compile) --destdir "$(DESTDIR)" \
+ --basedir "$(sugardir)" $$dlist; \
+ else :; fi
+
+uninstall-sugarPYTHON:
+ @$(NORMAL_UNINSTALL)
+ @list='$(sugar_PYTHON)'; test -n "$(sugardir)" || list=; \
+ files=`for p in $$list; do echo $$p; done | sed -e 's|^.*/||'`; \
+ test -n "$$files" || exit 0; \
+ dir='$(DESTDIR)$(sugardir)'; \
+ filesc=`echo "$$files" | sed 's|$$|c|'`; \
+ fileso=`echo "$$files" | sed 's|$$|o|'`; \
+ st=0; \
+ for files in "$$files" "$$filesc" "$$fileso"; do \
+ $(am__uninstall_files_from_dir) || st=$$?; \
+ done; \
+ exit $$st
+tags: TAGS
+TAGS:
+
+ctags: CTAGS
+CTAGS:
+
+
+distdir: $(DISTFILES)
+ @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
+ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
+ list='$(DISTFILES)'; \
+ dist_files=`for file in $$list; do echo $$file; done | \
+ sed -e "s|^$$srcdirstrip/||;t" \
+ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \
+ case $$dist_files in \
+ */*) $(MKDIR_P) `echo "$$dist_files" | \
+ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \
+ sort -u` ;; \
+ esac; \
+ for file in $$dist_files; do \
+ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \
+ if test -d $$d/$$file; then \
+ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \
+ if test -d "$(distdir)/$$file"; then \
+ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \
+ fi; \
+ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \
+ cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \
+ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \
+ fi; \
+ cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \
+ else \
+ test -f "$(distdir)/$$file" \
+ || cp -p $$d/$$file "$(distdir)/$$file" \
+ || exit 1; \
+ fi; \
+ done
+check-am: all-am
+check: check-am
+all-am: Makefile
+installdirs:
+ for dir in "$(DESTDIR)$(sugardir)"; do \
+ test -z "$$dir" || $(MKDIR_P) "$$dir"; \
+ done
+install: install-am
+install-exec: install-exec-am
+install-data: install-data-am
+uninstall: uninstall-am
+
+install-am: all-am
+ @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am
+
+installcheck: installcheck-am
+install-strip:
+ if test -z '$(STRIP)'; then \
+ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
+ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
+ install; \
+ else \
+ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
+ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
+ "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \
+ fi
+mostlyclean-generic:
+
+clean-generic:
+
+distclean-generic:
+ -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES)
+ -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES)
+
+maintainer-clean-generic:
+ @echo "This command is intended for maintainers to use"
+ @echo "it deletes files that may require special tools to rebuild."
+clean: clean-am
+
+clean-am: clean-generic mostlyclean-am
+
+distclean: distclean-am
+ -rm -f Makefile
+distclean-am: clean-am distclean-generic
+
+dvi: dvi-am
+
+dvi-am:
+
+html: html-am
+
+html-am:
+
+info: info-am
+
+info-am:
+
+install-data-am: install-sugarPYTHON
+
+install-dvi: install-dvi-am
+
+install-dvi-am:
+
+install-exec-am:
+
+install-html: install-html-am
+
+install-html-am:
+
+install-info: install-info-am
+
+install-info-am:
+
+install-man:
+
+install-pdf: install-pdf-am
+
+install-pdf-am:
+
+install-ps: install-ps-am
+
+install-ps-am:
+
+installcheck-am:
+
+maintainer-clean: maintainer-clean-am
+ -rm -f Makefile
+maintainer-clean-am: distclean-am maintainer-clean-generic
+
+mostlyclean: mostlyclean-am
+
+mostlyclean-am: mostlyclean-generic
+
+pdf: pdf-am
+
+pdf-am:
+
+ps: ps-am
+
+ps-am:
+
+uninstall-am: uninstall-sugarPYTHON
+
+.MAKE: install-am install-strip
+
+.PHONY: all all-am check check-am clean clean-generic distclean \
+ distclean-generic distdir dvi dvi-am html html-am info info-am \
+ install install-am install-data install-data-am install-dvi \
+ install-dvi-am install-exec install-exec-am install-html \
+ install-html-am install-info install-info-am install-man \
+ install-pdf install-pdf-am install-ps install-ps-am \
+ install-strip install-sugarPYTHON installcheck installcheck-am \
+ installdirs maintainer-clean maintainer-clean-generic \
+ mostlyclean mostlyclean-generic pdf pdf-am ps ps-am uninstall \
+ uninstall-am uninstall-sugarPYTHON
+
+
+# Tell versions [3.59,3.63) of GNU make to not export all variables.
+# Otherwise a system limit (for SysV at least) may be exceeded.
+.NOEXPORT:
diff --git a/extensions/cpsection/aboutcomputer/__init__.py b/extensions/cpsection/aboutcomputer/__init__.py
new file mode 100644
index 0000000..faf814d
--- /dev/null
+++ b/extensions/cpsection/aboutcomputer/__init__.py
@@ -0,0 +1,21 @@
+# Copyright (C) 2008, OLPC
+#
+# 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 2 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, write to the Free Software
+# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+
+from gettext import gettext as _
+
+CLASS = 'AboutComputer'
+ICON = 'module-about_my_computer'
+TITLE = _('About my Computer')
diff --git a/extensions/cpsection/aboutcomputer/model.py b/extensions/cpsection/aboutcomputer/model.py
new file mode 100644
index 0000000..86d2e3f
--- /dev/null
+++ b/extensions/cpsection/aboutcomputer/model.py
@@ -0,0 +1,228 @@
+# Copyright (C) 2008 One Laptop Per Child
+#
+# 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 2 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, write to the Free Software
+# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+#
+
+import os
+import logging
+import re
+import subprocess
+from gettext import gettext as _
+import errno
+
+import dbus
+
+from jarabe import config
+
+
+_NM_SERVICE = 'org.freedesktop.NetworkManager'
+_NM_PATH = '/org/freedesktop/NetworkManager'
+_NM_IFACE = 'org.freedesktop.NetworkManager'
+_NM_DEVICE_IFACE = 'org.freedesktop.NetworkManager.Device'
+_NM_DEVICE_TYPE_WIFI = 2
+
+_OFW_TREE = '/ofw'
+_PROC_TREE = '/proc/device-tree'
+_DMI_DIRECTORY = '/sys/class/dmi/id'
+_SN = 'serial-number'
+_MODEL = 'openprom/model'
+
+_logger = logging.getLogger('ControlPanel - AboutComputer')
+_not_available = _('Not available')
+
+
+def get_aboutcomputer():
+ msg = 'Serial Number: %s \nBuild Number: %s \nFirmware Number: %s \n' \
+ % (get_serial_number(), get_build_number(), get_firmware_number())
+ return msg
+
+
+def print_aboutcomputer():
+ print get_aboutcomputer()
+
+
+def get_serial_number():
+ serial_no = None
+ if os.path.exists(os.path.join(_OFW_TREE, _SN)):
+ serial_no = _read_file(os.path.join(_OFW_TREE, _SN))
+ elif os.path.exists(os.path.join(_PROC_TREE, _SN)):
+ serial_no = _read_file(os.path.join(_PROC_TREE, _SN))
+ if serial_no is None:
+ serial_no = _not_available
+ return serial_no
+
+
+def print_serial_number():
+ serial_no = get_serial_number()
+ if serial_no is None:
+ serial_no = _not_available
+ print serial_no
+
+
+def get_build_number():
+ build_no = _read_file('/boot/olpc_build')
+
+ if build_no is None:
+ build_no = _read_file('/etc/redhat-release')
+
+ if build_no is None:
+ try:
+ popen = subprocess.Popen(['lsb_release', '-ds'],
+ stdout=subprocess.PIPE)
+ except OSError, e:
+ if e.errno != errno.ENOENT:
+ raise
+ else:
+ build_no, stderr_ = popen.communicate()
+
+ if build_no is None or not build_no:
+ build_no = _not_available
+
+ return build_no
+
+
+def print_build_number():
+ print get_build_number()
+
+
+def _parse_firmware_number(firmware_no):
+ if firmware_no is None:
+ firmware_no = _not_available
+ else:
+ # try to extract Open Firmware version from OLPC style version
+ # string, e.g. "CL2 Q4B11 Q4B"
+ if firmware_no.startswith('CL'):
+ firmware_no = firmware_no[6:13]
+ return firmware_no
+
+
+def get_firmware_number():
+ firmware_no = None
+ if os.path.exists(os.path.join(_OFW_TREE, _MODEL)):
+ firmware_no = _read_file(os.path.join(_OFW_TREE, _MODEL))
+ firmware_no = _parse_firmware_number(firmware_no)
+ elif os.path.exists(os.path.join(_PROC_TREE, _MODEL)):
+ firmware_no = _read_file(os.path.join(_PROC_TREE, _MODEL))
+ firmware_no = _parse_firmware_number(firmware_no)
+ elif os.path.exists(os.path.join(_DMI_DIRECTORY, 'bios_version')):
+ firmware_no = _read_file(os.path.join(_DMI_DIRECTORY, 'bios_version'))
+ if firmware_no is None:
+ firmware_no = _not_available
+ return firmware_no
+
+
+def print_firmware_number():
+ print get_firmware_number()
+
+
+def _get_wireless_interfaces():
+ try:
+ bus = dbus.SystemBus()
+ manager_object = bus.get_object(_NM_SERVICE, _NM_PATH)
+ network_manager = dbus.Interface(manager_object, _NM_IFACE)
+ except dbus.DBusException:
+ _logger.warning('Cannot connect to NetworkManager, falling back to'
+ ' static list of devices')
+ return ['wlan0', 'eth0']
+
+ interfaces = []
+ for device_path in network_manager.GetDevices():
+ device_object = bus.get_object(_NM_SERVICE, device_path)
+ properties = dbus.Interface(device_object,
+ 'org.freedesktop.DBus.Properties')
+ device_type = properties.Get(_NM_DEVICE_IFACE, 'DeviceType')
+ if device_type != _NM_DEVICE_TYPE_WIFI:
+ continue
+
+ interfaces.append(properties.Get(_NM_DEVICE_IFACE, 'Interface'))
+
+ return interfaces
+
+
+def get_wireless_firmware():
+ environment = os.environ.copy()
+ environment['PATH'] = '%s:/usr/sbin' % (environment['PATH'], )
+ firmware_info = {}
+ for interface in _get_wireless_interfaces():
+ try:
+ output = subprocess.Popen(['ethtool', '-i', interface],
+ stdout=subprocess.PIPE,
+ env=environment).stdout.readlines()
+ except OSError:
+ _logger.exception('Error running ethtool for %r', interface)
+ continue
+
+ try:
+ version = ([line for line in output
+ if line.startswith('firmware')][0].split()[1])
+ except IndexError:
+ _logger.exception('Error parsing ethtool output for %r',
+ interface)
+ continue
+
+ firmware_info[interface] = version
+
+ if not firmware_info:
+ return _not_available
+
+ if len(firmware_info) == 1:
+ return firmware_info.values()[0]
+
+ return ', '.join(['%(interface)s: %(version)s' %
+ {'interface': interface, 'version': version}
+ for interface, version in firmware_info.items()])
+
+
+def print_wireless_firmware():
+ print get_wireless_firmware()
+
+
+def _read_file(path):
+ if os.access(path, os.R_OK) == 0:
+ return None
+
+ fd = open(path, 'r')
+ value = fd.read()
+ fd.close()
+ if value:
+ value = value.strip('\n')
+ return value
+ else:
+ _logger.debug('No information in file or directory: %s', path)
+ return None
+
+
+def get_license():
+ license_file = os.path.join(config.data_path, 'GPLv2')
+ lang = os.environ['LANG']
+ if lang.endswith('UTF-8'):
+ lang = lang[:-6]
+
+ try_file = license_file + '.' + lang
+ if os.path.isfile(try_file):
+ license_file = try_file
+ else:
+ try_file = license_file + '.' + lang.split('_')[0]
+ if os.path.isfile(try_file):
+ license_file = try_file
+
+ try:
+ fd = open(license_file)
+ # remove 0x0c page breaks which can't be rendered in text views
+ license_text = fd.read().replace('\x0c', '')
+ fd.close()
+ except IOError:
+ license_text = _not_available
+ return license_text
diff --git a/extensions/cpsection/aboutcomputer/view.py b/extensions/cpsection/aboutcomputer/view.py
new file mode 100644
index 0000000..6b16005
--- /dev/null
+++ b/extensions/cpsection/aboutcomputer/view.py
@@ -0,0 +1,215 @@
+# coding=utf-8
+# Copyright (C) 2008, OLPC
+# Copyright (C) 2009 Simon Schampijer
+#
+# 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 2 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, write to the Free Software
+# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+
+from gettext import gettext as _
+
+import gtk
+
+from sugar.graphics import style
+
+from jarabe import config
+from jarabe.controlpanel.sectionview import SectionView
+
+
+class AboutComputer(SectionView):
+ def __init__(self, model, alerts=None):
+ SectionView.__init__(self)
+
+ self._model = model
+
+ self.set_border_width(style.DEFAULT_SPACING * 2)
+ self.set_spacing(style.DEFAULT_SPACING)
+
+ self._group = gtk.SizeGroup(gtk.SIZE_GROUP_HORIZONTAL)
+
+ scrollwindow = gtk.ScrolledWindow()
+ scrollwindow.set_policy(gtk.POLICY_NEVER, gtk.POLICY_AUTOMATIC)
+ self.pack_start(scrollwindow, expand=True)
+ scrollwindow.show()
+
+ self._vbox = gtk.VBox()
+ scrollwindow.add_with_viewport(self._vbox)
+ self._vbox.show()
+
+ self._setup_identity()
+
+ self._setup_software()
+ self._setup_copyright()
+
+ def _setup_identity(self):
+ separator_identity = gtk.HSeparator()
+ self._vbox.pack_start(separator_identity, expand=False)
+ separator_identity.show()
+
+ label_identity = gtk.Label(_('Identity'))
+ label_identity.set_alignment(0, 0)
+ self._vbox.pack_start(label_identity, expand=False)
+ label_identity.show()
+ vbox_identity = gtk.VBox()
+ vbox_identity.set_border_width(style.DEFAULT_SPACING * 2)
+ vbox_identity.set_spacing(style.DEFAULT_SPACING)
+
+ box_identity = gtk.HBox(spacing=style.DEFAULT_SPACING)
+ label_serial = gtk.Label(_('Serial Number:'))
+ label_serial.set_alignment(1, 0)
+ label_serial.modify_fg(gtk.STATE_NORMAL,
+ style.COLOR_SELECTION_GREY.get_gdk_color())
+ box_identity.pack_start(label_serial, expand=False)
+ self._group.add_widget(label_serial)
+ label_serial.show()
+ label_serial_no = gtk.Label(self._model.get_serial_number())
+ label_serial_no.set_alignment(0, 0)
+ box_identity.pack_start(label_serial_no, expand=False)
+ label_serial_no.show()
+ vbox_identity.pack_start(box_identity, expand=False)
+ box_identity.show()
+
+ self._vbox.pack_start(vbox_identity, expand=False)
+ vbox_identity.show()
+
+ def _setup_software(self):
+ separator_software = gtk.HSeparator()
+ self._vbox.pack_start(separator_software, expand=False)
+ separator_software.show()
+
+ label_software = gtk.Label(_('Software'))
+ label_software.set_alignment(0, 0)
+ self._vbox.pack_start(label_software, expand=False)
+ label_software.show()
+ box_software = gtk.VBox()
+ box_software.set_border_width(style.DEFAULT_SPACING * 2)
+ box_software.set_spacing(style.DEFAULT_SPACING)
+
+ box_build = gtk.HBox(spacing=style.DEFAULT_SPACING)
+ label_build = gtk.Label(_('Build:'))
+ label_build.set_alignment(1, 0)
+ label_build.modify_fg(gtk.STATE_NORMAL,
+ style.COLOR_SELECTION_GREY.get_gdk_color())
+ box_build.pack_start(label_build, expand=False)
+ self._group.add_widget(label_build)
+ label_build.show()
+ label_build_no = gtk.Label(self._model.get_build_number())
+ label_build_no.set_alignment(0, 0)
+ box_build.pack_start(label_build_no, expand=False)
+ label_build_no.show()
+ box_software.pack_start(box_build, expand=False)
+ box_build.show()
+
+ box_sugar = gtk.HBox(spacing=style.DEFAULT_SPACING)
+ label_sugar = gtk.Label(_('Sugar:'))
+ label_sugar.set_alignment(1, 0)
+ label_sugar.modify_fg(gtk.STATE_NORMAL,
+ style.COLOR_SELECTION_GREY.get_gdk_color())
+ box_sugar.pack_start(label_sugar, expand=False)
+ self._group.add_widget(label_sugar)
+ label_sugar.show()
+ label_sugar_ver = gtk.Label(config.version)
+ label_sugar_ver.set_alignment(0, 0)
+ box_sugar.pack_start(label_sugar_ver, expand=False)
+ label_sugar_ver.show()
+ box_software.pack_start(box_sugar, expand=False)
+ box_sugar.show()
+
+ box_firmware = gtk.HBox(spacing=style.DEFAULT_SPACING)
+ label_firmware = gtk.Label(_('Firmware:'))
+ label_firmware.set_alignment(1, 0)
+ label_firmware.modify_fg(gtk.STATE_NORMAL,
+ style.COLOR_SELECTION_GREY.get_gdk_color())
+ box_firmware.pack_start(label_firmware, expand=False)
+ self._group.add_widget(label_firmware)
+ label_firmware.show()
+ label_firmware_no = gtk.Label(self._model.get_firmware_number())
+ label_firmware_no.set_alignment(0, 0)
+ box_firmware.pack_start(label_firmware_no, expand=False)
+ label_firmware_no.show()
+ box_software.pack_start(box_firmware, expand=False)
+ box_firmware.show()
+
+ box_wireless_fw = gtk.HBox(spacing=style.DEFAULT_SPACING)
+ label_wireless_fw = gtk.Label(_('Wireless Firmware:'))
+ label_wireless_fw.set_alignment(1, 0)
+ label_wireless_fw.modify_fg(gtk.STATE_NORMAL,
+ style.COLOR_SELECTION_GREY.get_gdk_color())
+ box_wireless_fw.pack_start(label_wireless_fw, expand=False)
+ self._group.add_widget(label_wireless_fw)
+ label_wireless_fw.show()
+ wireless_fw_no = self._model.get_wireless_firmware()
+ label_wireless_fw_no = gtk.Label(wireless_fw_no)
+ label_wireless_fw_no.set_alignment(0, 0)
+ box_wireless_fw.pack_start(label_wireless_fw_no, expand=False)
+ label_wireless_fw_no.show()
+ box_software.pack_start(box_wireless_fw, expand=False)
+ box_wireless_fw.show()
+
+ self._vbox.pack_start(box_software, expand=False)
+ box_software.show()
+
+ def _setup_copyright(self):
+ separator_copyright = gtk.HSeparator()
+ self._vbox.pack_start(separator_copyright, expand=False)
+ separator_copyright.show()
+
+ label_copyright = gtk.Label(_('Copyright and License'))
+ label_copyright.set_alignment(0, 0)
+ self._vbox.pack_start(label_copyright, expand=False)
+ label_copyright.show()
+ vbox_copyright = gtk.VBox()
+ vbox_copyright.set_border_width(style.DEFAULT_SPACING * 2)
+ vbox_copyright.set_spacing(style.DEFAULT_SPACING)
+
+ copyright_text = '© 2006-2012 One Laptop per Child Association Inc,' \
+ ' Sugar Labs Inc, Red Hat Inc, Collabora Ltd and' \
+ ' Contributors.'
+ label_copyright = gtk.Label(copyright_text)
+ label_copyright.set_alignment(0, 0)
+ label_copyright.set_size_request(gtk.gdk.screen_width() / 2, -1)
+ label_copyright.set_line_wrap(True)
+ label_copyright.show()
+ vbox_copyright.pack_start(label_copyright, expand=False)
+
+ info_text = _('Sugar is the graphical user interface that you are'
+ ' looking at. Sugar is free software, covered by the'
+ ' GNU General Public License, and you are welcome to'
+ ' change it and/or distribute copies of it under'
+ ' certain conditions described therein.')
+ label_info = gtk.Label(info_text)
+ label_info.set_alignment(0, 0)
+ label_info.set_line_wrap(True)
+ label_info.set_size_request(gtk.gdk.screen_width() / 2, -1)
+ label_info.show()
+ vbox_copyright.pack_start(label_info, expand=False)
+
+ expander = gtk.Expander(_('Full license:'))
+ expander.connect('notify::expanded', self.license_expander_cb)
+ expander.show()
+ vbox_copyright.pack_start(expander, expand=True)
+
+ self._vbox.pack_start(vbox_copyright, expand=True)
+ vbox_copyright.show()
+
+ def license_expander_cb(self, expander, param_spec):
+ # load/destroy the license viewer on-demand, to avoid storing the
+ # GPL in memory at all times
+ if expander.get_expanded():
+ view_license = gtk.TextView()
+ view_license.set_editable(False)
+ view_license.get_buffer().set_text(self._model.get_license())
+ view_license.show()
+ expander.add(view_license)
+ else:
+ expander.get_child().destroy()
diff --git a/extensions/cpsection/aboutme/Makefile.am b/extensions/cpsection/aboutme/Makefile.am
new file mode 100644
index 0000000..9ca91d2
--- /dev/null
+++ b/extensions/cpsection/aboutme/Makefile.am
@@ -0,0 +1,6 @@
+sugardir = $(pkgdatadir)/extensions/cpsection/aboutme
+
+sugar_PYTHON = \
+ __init__.py \
+ model.py \
+ view.py
diff --git a/extensions/cpsection/aboutme/Makefile.in b/extensions/cpsection/aboutme/Makefile.in
new file mode 100644
index 0000000..f8ea8cd
--- /dev/null
+++ b/extensions/cpsection/aboutme/Makefile.in
@@ -0,0 +1,442 @@
+# Makefile.in generated by automake 1.11.3 from Makefile.am.
+# @configure_input@
+
+# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002,
+# 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011 Free Software
+# Foundation, Inc.
+# This Makefile.in is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
+# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
+# PARTICULAR PURPOSE.
+
+@SET_MAKE@
+VPATH = @srcdir@
+pkgdatadir = $(datadir)/@PACKAGE@
+pkgincludedir = $(includedir)/@PACKAGE@
+pkglibdir = $(libdir)/@PACKAGE@
+pkglibexecdir = $(libexecdir)/@PACKAGE@
+am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd
+install_sh_DATA = $(install_sh) -c -m 644
+install_sh_PROGRAM = $(install_sh) -c
+install_sh_SCRIPT = $(install_sh) -c
+INSTALL_HEADER = $(INSTALL_DATA)
+transform = $(program_transform_name)
+NORMAL_INSTALL = :
+PRE_INSTALL = :
+POST_INSTALL = :
+NORMAL_UNINSTALL = :
+PRE_UNINSTALL = :
+POST_UNINSTALL = :
+subdir = extensions/cpsection/aboutme
+DIST_COMMON = $(srcdir)/Makefile.am $(srcdir)/Makefile.in \
+ $(sugar_PYTHON)
+ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
+am__aclocal_m4_deps = $(top_srcdir)/configure.ac
+am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
+ $(ACLOCAL_M4)
+mkinstalldirs = $(install_sh) -d
+CONFIG_CLEAN_FILES =
+CONFIG_CLEAN_VPATH_FILES =
+SOURCES =
+DIST_SOURCES =
+am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`;
+am__vpath_adj = case $$p in \
+ $(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \
+ *) f=$$p;; \
+ esac;
+am__strip_dir = f=`echo $$p | sed -e 's|^.*/||'`;
+am__install_max = 40
+am__nobase_strip_setup = \
+ srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*|]/\\\\&/g'`
+am__nobase_strip = \
+ for p in $$list; do echo "$$p"; done | sed -e "s|$$srcdirstrip/||"
+am__nobase_list = $(am__nobase_strip_setup); \
+ for p in $$list; do echo "$$p $$p"; done | \
+ sed "s| $$srcdirstrip/| |;"' / .*\//!s/ .*/ ./; s,\( .*\)/[^/]*$$,\1,' | \
+ $(AWK) 'BEGIN { files["."] = "" } { files[$$2] = files[$$2] " " $$1; \
+ if (++n[$$2] == $(am__install_max)) \
+ { print $$2, files[$$2]; n[$$2] = 0; files[$$2] = "" } } \
+ END { for (dir in files) print dir, files[dir] }'
+am__base_list = \
+ sed '$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;s/\n/ /g' | \
+ sed '$$!N;$$!N;$$!N;$$!N;s/\n/ /g'
+am__uninstall_files_from_dir = { \
+ test -z "$$files" \
+ || { test ! -d "$$dir" && test ! -f "$$dir" && test ! -r "$$dir"; } \
+ || { echo " ( cd '$$dir' && rm -f" $$files ")"; \
+ $(am__cd) "$$dir" && rm -f $$files; }; \
+ }
+am__py_compile = PYTHON=$(PYTHON) $(SHELL) $(py_compile)
+am__installdirs = "$(DESTDIR)$(sugardir)"
+py_compile = $(top_srcdir)/py-compile
+DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
+ACLOCAL = @ACLOCAL@
+ALL_LINGUAS = @ALL_LINGUAS@
+AMTAR = @AMTAR@
+AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@
+AUTOCONF = @AUTOCONF@
+AUTOHEADER = @AUTOHEADER@
+AUTOMAKE = @AUTOMAKE@
+AWK = @AWK@
+CATALOGS = @CATALOGS@
+CATOBJEXT = @CATOBJEXT@
+CC = @CC@
+CCDEPMODE = @CCDEPMODE@
+CFLAGS = @CFLAGS@
+CPP = @CPP@
+CPPFLAGS = @CPPFLAGS@
+CYGPATH_W = @CYGPATH_W@
+DATADIRNAME = @DATADIRNAME@
+DEFS = @DEFS@
+DEPDIR = @DEPDIR@
+ECHO_C = @ECHO_C@
+ECHO_N = @ECHO_N@
+ECHO_T = @ECHO_T@
+EGREP = @EGREP@
+EXEEXT = @EXEEXT@
+GCONFTOOL = @GCONFTOOL@
+GCONF_SCHEMA_CONFIG_SOURCE = @GCONF_SCHEMA_CONFIG_SOURCE@
+GCONF_SCHEMA_FILE_DIR = @GCONF_SCHEMA_FILE_DIR@
+GETTEXT_PACKAGE = @GETTEXT_PACKAGE@
+GMOFILES = @GMOFILES@
+GMSGFMT = @GMSGFMT@
+GREP = @GREP@
+INSTALL = @INSTALL@
+INSTALL_DATA = @INSTALL_DATA@
+INSTALL_PROGRAM = @INSTALL_PROGRAM@
+INSTALL_SCRIPT = @INSTALL_SCRIPT@
+INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@
+INSTOBJEXT = @INSTOBJEXT@
+INTLLIBS = @INTLLIBS@
+INTLTOOL_EXTRACT = @INTLTOOL_EXTRACT@
+INTLTOOL_MERGE = @INTLTOOL_MERGE@
+INTLTOOL_PERL = @INTLTOOL_PERL@
+INTLTOOL_UPDATE = @INTLTOOL_UPDATE@
+INTLTOOL_V_MERGE = @INTLTOOL_V_MERGE@
+INTLTOOL_V_MERGE_OPTIONS = @INTLTOOL_V_MERGE_OPTIONS@
+INTLTOOL__v_MERGE_ = @INTLTOOL__v_MERGE_@
+INTLTOOL__v_MERGE_0 = @INTLTOOL__v_MERGE_0@
+LDFLAGS = @LDFLAGS@
+LIBOBJS = @LIBOBJS@
+LIBS = @LIBS@
+LTLIBOBJS = @LTLIBOBJS@
+MAINT = @MAINT@
+MAKEINFO = @MAKEINFO@
+MKDIR_P = @MKDIR_P@
+MKINSTALLDIRS = @MKINSTALLDIRS@
+MSGFMT = @MSGFMT@
+MSGFMT_OPTS = @MSGFMT_OPTS@
+MSGMERGE = @MSGMERGE@
+OBJEXT = @OBJEXT@
+PACKAGE = @PACKAGE@
+PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@
+PACKAGE_NAME = @PACKAGE_NAME@
+PACKAGE_STRING = @PACKAGE_STRING@
+PACKAGE_TARNAME = @PACKAGE_TARNAME@
+PACKAGE_URL = @PACKAGE_URL@
+PACKAGE_VERSION = @PACKAGE_VERSION@
+PATH_SEPARATOR = @PATH_SEPARATOR@
+PKG_CONFIG = @PKG_CONFIG@
+PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@
+PKG_CONFIG_PATH = @PKG_CONFIG_PATH@
+POFILES = @POFILES@
+POSUB = @POSUB@
+PO_IN_DATADIR_FALSE = @PO_IN_DATADIR_FALSE@
+PO_IN_DATADIR_TRUE = @PO_IN_DATADIR_TRUE@
+PYTHON = @PYTHON@
+PYTHON_EXEC_PREFIX = @PYTHON_EXEC_PREFIX@
+PYTHON_PLATFORM = @PYTHON_PLATFORM@
+PYTHON_PREFIX = @PYTHON_PREFIX@
+PYTHON_VERSION = @PYTHON_VERSION@
+SET_MAKE = @SET_MAKE@
+SHELL = @SHELL@
+SHELL_CFLAGS = @SHELL_CFLAGS@
+SHELL_LIBS = @SHELL_LIBS@
+STRIP = @STRIP@
+SUCROSE_VERSION = @SUCROSE_VERSION@
+USE_NLS = @USE_NLS@
+VERSION = @VERSION@
+XGETTEXT = @XGETTEXT@
+abs_builddir = @abs_builddir@
+abs_srcdir = @abs_srcdir@
+abs_top_builddir = @abs_top_builddir@
+abs_top_srcdir = @abs_top_srcdir@
+ac_ct_CC = @ac_ct_CC@
+am__include = @am__include@
+am__leading_dot = @am__leading_dot@
+am__quote = @am__quote@
+am__tar = @am__tar@
+am__untar = @am__untar@
+bindir = @bindir@
+build_alias = @build_alias@
+builddir = @builddir@
+datadir = @datadir@
+datarootdir = @datarootdir@
+docdir = @docdir@
+dvidir = @dvidir@
+exec_prefix = @exec_prefix@
+host_alias = @host_alias@
+htmldir = @htmldir@
+includedir = @includedir@
+infodir = @infodir@
+install_sh = @install_sh@
+intltool__v_merge_options_ = @intltool__v_merge_options_@
+intltool__v_merge_options_0 = @intltool__v_merge_options_0@
+libdir = @libdir@
+libexecdir = @libexecdir@
+localedir = @localedir@
+localstatedir = @localstatedir@
+mandir = @mandir@
+mkdir_p = @mkdir_p@
+oldincludedir = @oldincludedir@
+pdfdir = @pdfdir@
+pkgpyexecdir = @pkgpyexecdir@
+pkgpythondir = @pkgpythondir@
+prefix = @prefix@
+program_transform_name = @program_transform_name@
+psdir = @psdir@
+pyexecdir = @pyexecdir@
+pythondir = @pythondir@
+sbindir = @sbindir@
+sharedstatedir = @sharedstatedir@
+srcdir = @srcdir@
+sysconfdir = @sysconfdir@
+target_alias = @target_alias@
+top_build_prefix = @top_build_prefix@
+top_builddir = @top_builddir@
+top_srcdir = @top_srcdir@
+sugardir = $(pkgdatadir)/extensions/cpsection/aboutme
+sugar_PYTHON = \
+ __init__.py \
+ model.py \
+ view.py
+
+all: all-am
+
+.SUFFIXES:
+$(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ $(srcdir)/Makefile.am $(am__configure_deps)
+ @for dep in $?; do \
+ case '$(am__configure_deps)' in \
+ *$$dep*) \
+ ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \
+ && { if test -f $@; then exit 0; else break; fi; }; \
+ exit 1;; \
+ esac; \
+ done; \
+ echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign extensions/cpsection/aboutme/Makefile'; \
+ $(am__cd) $(top_srcdir) && \
+ $(AUTOMAKE) --foreign extensions/cpsection/aboutme/Makefile
+.PRECIOUS: Makefile
+Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
+ @case '$?' in \
+ *config.status*) \
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \
+ *) \
+ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \
+ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \
+ esac;
+
+$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES)
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+
+$(top_srcdir)/configure: @MAINTAINER_MODE_TRUE@ $(am__configure_deps)
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+$(ACLOCAL_M4): @MAINTAINER_MODE_TRUE@ $(am__aclocal_m4_deps)
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+$(am__aclocal_m4_deps):
+install-sugarPYTHON: $(sugar_PYTHON)
+ @$(NORMAL_INSTALL)
+ test -z "$(sugardir)" || $(MKDIR_P) "$(DESTDIR)$(sugardir)"
+ @list='$(sugar_PYTHON)'; dlist=; list2=; test -n "$(sugardir)" || list=; \
+ for p in $$list; do \
+ if test -f "$$p"; then b=; else b="$(srcdir)/"; fi; \
+ if test -f $$b$$p; then \
+ $(am__strip_dir) \
+ dlist="$$dlist $$f"; \
+ list2="$$list2 $$b$$p"; \
+ else :; fi; \
+ done; \
+ for file in $$list2; do echo $$file; done | $(am__base_list) | \
+ while read files; do \
+ echo " $(INSTALL_DATA) $$files '$(DESTDIR)$(sugardir)'"; \
+ $(INSTALL_DATA) $$files "$(DESTDIR)$(sugardir)" || exit $$?; \
+ done || exit $$?; \
+ if test -n "$$dlist"; then \
+ $(am__py_compile) --destdir "$(DESTDIR)" \
+ --basedir "$(sugardir)" $$dlist; \
+ else :; fi
+
+uninstall-sugarPYTHON:
+ @$(NORMAL_UNINSTALL)
+ @list='$(sugar_PYTHON)'; test -n "$(sugardir)" || list=; \
+ files=`for p in $$list; do echo $$p; done | sed -e 's|^.*/||'`; \
+ test -n "$$files" || exit 0; \
+ dir='$(DESTDIR)$(sugardir)'; \
+ filesc=`echo "$$files" | sed 's|$$|c|'`; \
+ fileso=`echo "$$files" | sed 's|$$|o|'`; \
+ st=0; \
+ for files in "$$files" "$$filesc" "$$fileso"; do \
+ $(am__uninstall_files_from_dir) || st=$$?; \
+ done; \
+ exit $$st
+tags: TAGS
+TAGS:
+
+ctags: CTAGS
+CTAGS:
+
+
+distdir: $(DISTFILES)
+ @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
+ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
+ list='$(DISTFILES)'; \
+ dist_files=`for file in $$list; do echo $$file; done | \
+ sed -e "s|^$$srcdirstrip/||;t" \
+ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \
+ case $$dist_files in \
+ */*) $(MKDIR_P) `echo "$$dist_files" | \
+ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \
+ sort -u` ;; \
+ esac; \
+ for file in $$dist_files; do \
+ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \
+ if test -d $$d/$$file; then \
+ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \
+ if test -d "$(distdir)/$$file"; then \
+ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \
+ fi; \
+ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \
+ cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \
+ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \
+ fi; \
+ cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \
+ else \
+ test -f "$(distdir)/$$file" \
+ || cp -p $$d/$$file "$(distdir)/$$file" \
+ || exit 1; \
+ fi; \
+ done
+check-am: all-am
+check: check-am
+all-am: Makefile
+installdirs:
+ for dir in "$(DESTDIR)$(sugardir)"; do \
+ test -z "$$dir" || $(MKDIR_P) "$$dir"; \
+ done
+install: install-am
+install-exec: install-exec-am
+install-data: install-data-am
+uninstall: uninstall-am
+
+install-am: all-am
+ @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am
+
+installcheck: installcheck-am
+install-strip:
+ if test -z '$(STRIP)'; then \
+ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
+ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
+ install; \
+ else \
+ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
+ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
+ "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \
+ fi
+mostlyclean-generic:
+
+clean-generic:
+
+distclean-generic:
+ -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES)
+ -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES)
+
+maintainer-clean-generic:
+ @echo "This command is intended for maintainers to use"
+ @echo "it deletes files that may require special tools to rebuild."
+clean: clean-am
+
+clean-am: clean-generic mostlyclean-am
+
+distclean: distclean-am
+ -rm -f Makefile
+distclean-am: clean-am distclean-generic
+
+dvi: dvi-am
+
+dvi-am:
+
+html: html-am
+
+html-am:
+
+info: info-am
+
+info-am:
+
+install-data-am: install-sugarPYTHON
+
+install-dvi: install-dvi-am
+
+install-dvi-am:
+
+install-exec-am:
+
+install-html: install-html-am
+
+install-html-am:
+
+install-info: install-info-am
+
+install-info-am:
+
+install-man:
+
+install-pdf: install-pdf-am
+
+install-pdf-am:
+
+install-ps: install-ps-am
+
+install-ps-am:
+
+installcheck-am:
+
+maintainer-clean: maintainer-clean-am
+ -rm -f Makefile
+maintainer-clean-am: distclean-am maintainer-clean-generic
+
+mostlyclean: mostlyclean-am
+
+mostlyclean-am: mostlyclean-generic
+
+pdf: pdf-am
+
+pdf-am:
+
+ps: ps-am
+
+ps-am:
+
+uninstall-am: uninstall-sugarPYTHON
+
+.MAKE: install-am install-strip
+
+.PHONY: all all-am check check-am clean clean-generic distclean \
+ distclean-generic distdir dvi dvi-am html html-am info info-am \
+ install install-am install-data install-data-am install-dvi \
+ install-dvi-am install-exec install-exec-am install-html \
+ install-html-am install-info install-info-am install-man \
+ install-pdf install-pdf-am install-ps install-ps-am \
+ install-strip install-sugarPYTHON installcheck installcheck-am \
+ installdirs maintainer-clean maintainer-clean-generic \
+ mostlyclean mostlyclean-generic pdf pdf-am ps ps-am uninstall \
+ uninstall-am uninstall-sugarPYTHON
+
+
+# Tell versions [3.59,3.63) of GNU make to not export all variables.
+# Otherwise a system limit (for SysV at least) may be exceeded.
+.NOEXPORT:
diff --git a/extensions/cpsection/aboutme/__init__.py b/extensions/cpsection/aboutme/__init__.py
new file mode 100644
index 0000000..7ded428
--- /dev/null
+++ b/extensions/cpsection/aboutme/__init__.py
@@ -0,0 +1,26 @@
+# Copyright (C) 2008, OLPC
+#
+# 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 2 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, write to the Free Software
+# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+
+from gettext import gettext as _
+import gconf
+
+from sugar.graphics.xocolor import XoColor
+
+CLASS = 'AboutMe'
+ICON = 'module-about_me'
+TITLE = _('About Me')
+client = gconf.client_get_default()
+COLOR = XoColor(client.get_string('/desktop/sugar/user/color'))
diff --git a/extensions/cpsection/aboutme/model.py b/extensions/cpsection/aboutme/model.py
new file mode 100644
index 0000000..fb4c2f1
--- /dev/null
+++ b/extensions/cpsection/aboutme/model.py
@@ -0,0 +1,125 @@
+# Copyright (C) 2008 One Laptop Per Child
+#
+# 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 2 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, write to the Free Software
+# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+#
+
+from gettext import gettext as _
+import gconf
+
+
+_COLORS = {
+ 'red': {'dark': '#b20008', 'medium': '#e6000a', 'light': '#ffadce'},
+ 'orange': {'dark': '#9a5200', 'medium': '#c97e00', 'light': '#ffc169'},
+ 'yellow': {'dark': '#807500', 'medium': '#be9e00', 'light': '#fffa00'},
+ 'green': {'dark': '#008009', 'medium': '#00b20d', 'light': '#8bff7a'},
+ 'blue': {'dark': '#00588c', 'medium': '#005fe4', 'light': '#bccdff'},
+ 'purple': {'dark': '#5e008c', 'medium': '#7f00bf', 'light': '#d1a3ff'},
+}
+
+_MODIFIERS = ('dark', 'medium', 'light')
+
+
+def get_nick():
+ client = gconf.client_get_default()
+ return client.get_string('/desktop/sugar/user/nick')
+
+
+def print_nick():
+ print get_nick()
+
+
+def set_nick(nick):
+ """Set the nickname.
+ nick : e.g. 'walter'
+ """
+ if not nick:
+ raise ValueError(_('You must enter a name.'))
+ if not isinstance(nick, unicode):
+ nick = unicode(nick, 'utf-8')
+ client = gconf.client_get_default()
+ client.set_string('/desktop/sugar/user/nick', nick)
+ return 1
+
+
+def get_color():
+ client = gconf.client_get_default()
+ return client.get_string('/desktop/sugar/user/color')
+
+
+def print_color():
+ color_string = get_color()
+ tmp = color_string.split(',')
+
+ stroke_tuple = None
+ fill_tuple = None
+ for color in _COLORS:
+ for hue in _COLORS[color]:
+ if _COLORS[color][hue] == tmp[0]:
+ stroke_tuple = (color, hue)
+ if _COLORS[color][hue] == tmp[1]:
+ fill_tuple = (color, hue)
+
+ if stroke_tuple is not None:
+ print _('stroke: color=%s hue=%s') % (stroke_tuple[0],
+ stroke_tuple[1])
+ else:
+ print _('stroke: %s') % (tmp[0])
+ if fill_tuple is not None:
+ print _('fill: color=%s hue=%s') % (fill_tuple[0], fill_tuple[1])
+ else:
+ print _('fill: %s') % (tmp[1])
+
+
+def set_color(stroke, fill, stroke_modifier='medium', fill_modifier='medium'):
+ """Set the system color by setting a fill and stroke color.
+ fill : [red, orange, yellow, blue, green, purple]
+ stroke : [red, orange, yellow, blue, green, purple]
+ hue stroke : [dark, medium, light] (optional)
+ hue fill : [dark, medium, light] (optional)
+ """
+
+ if stroke_modifier not in _MODIFIERS or fill_modifier not in _MODIFIERS:
+ print (_('Error in specified color modifiers.'))
+ return
+ if stroke not in _COLORS or fill not in _COLORS:
+ print (_('Error in specified colors.'))
+ return
+
+ if stroke_modifier == fill_modifier:
+ if fill_modifier == 'medium':
+ fill_modifier = 'light'
+ else:
+ fill_modifier = 'medium'
+
+ color = _COLORS[stroke][stroke_modifier] + ',' \
+ + _COLORS[fill][fill_modifier]
+
+ client = gconf.client_get_default()
+ client.set_string('/desktop/sugar/user/color', color)
+ return 1
+
+
+def get_color_xo():
+ client = gconf.client_get_default()
+ return client.get_string('/desktop/sugar/user/color')
+
+
+def set_color_xo(color):
+ """Set a color with an XoColor
+ This method is used by the graphical user interface
+ """
+ client = gconf.client_get_default()
+ client.set_string('/desktop/sugar/user/color', color)
+ return 1
diff --git a/extensions/cpsection/aboutme/view.py b/extensions/cpsection/aboutme/view.py
new file mode 100644
index 0000000..84daec7
--- /dev/null
+++ b/extensions/cpsection/aboutme/view.py
@@ -0,0 +1,340 @@
+# Copyright (C) 2008, OLPC
+# Copyright (C) 2010, Sugar Labs
+#
+# 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 2 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, write to the Free Software
+# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+
+import gtk
+import gobject
+from gettext import gettext as _
+
+from sugar.graphics.icon import Icon
+from sugar.graphics import style
+from sugar.graphics.xocolor import XoColor, colors
+
+from jarabe.controlpanel.sectionview import SectionView
+from jarabe.controlpanel.inlinealert import InlineAlert
+
+_STROKE_COLOR = 0
+_FILL_COLOR = 1
+
+
+def _get_next_stroke_color(color):
+ """ Return the next color pair in the list that shares the same fill
+ as color. """
+ current_index = _get_current_index(color)
+ if current_index == -1:
+ return '%s,%s' % (color.stroke, color.fill)
+ next_index = _next_index(current_index)
+ while(colors[next_index][_FILL_COLOR] != \
+ colors[current_index][_FILL_COLOR]):
+ next_index = _next_index(next_index)
+ return '%s,%s' % (colors[next_index][_STROKE_COLOR],
+ colors[next_index][_FILL_COLOR])
+
+
+def _get_previous_stroke_color(color):
+ """ Return the previous color pair in the list that shares the same fill
+ as color. """
+ current_index = _get_current_index(color)
+ if current_index == -1:
+ return '%s,%s' % (color.stroke, color.fill)
+ previous_index = _previous_index(current_index)
+ while (colors[previous_index][_FILL_COLOR] != \
+ colors[current_index][_FILL_COLOR]):
+ previous_index = _previous_index(previous_index)
+ return '%s,%s' % (colors[previous_index][_STROKE_COLOR],
+ colors[previous_index][_FILL_COLOR])
+
+
+def _get_next_fill_color(color):
+ """ Return the next color pair in the list that shares the same stroke
+ as color. """
+ current_index = _get_current_index(color)
+ if current_index == -1:
+ return '%s,%s' % (color.stroke, color.fill)
+ next_index = _next_index(current_index)
+ while (colors[next_index][_STROKE_COLOR] != \
+ colors[current_index][_STROKE_COLOR]):
+ next_index = _next_index(next_index)
+ return '%s,%s' % (colors[next_index][_STROKE_COLOR],
+ colors[next_index][_FILL_COLOR])
+
+
+def _get_previous_fill_color(color):
+ """ Return the previous color pair in the list that shares the same stroke
+ as color. """
+ current_index = _get_current_index(color)
+ if current_index == -1:
+ return '%s,%s' % (color.stroke, color.fill)
+ previous_index = _previous_index(current_index)
+ while (colors[previous_index][_STROKE_COLOR] != \
+ colors[current_index][_STROKE_COLOR]):
+ previous_index = _previous_index(previous_index)
+ return '%s,%s' % (colors[previous_index][_STROKE_COLOR],
+ colors[previous_index][_FILL_COLOR])
+
+
+def _next_index(current_index):
+ next_index = current_index + 1
+ if next_index == len(colors):
+ next_index = 0
+ return next_index
+
+
+def _previous_index(current_index):
+ previous_index = current_index - 1
+ if previous_index < 0:
+ previous_index = len(colors) - 1
+ return previous_index
+
+
+def _get_current_index(color):
+ return colors.index([color.stroke, color.fill])
+
+
+_PREVIOUS_FILL_COLOR = 0
+_NEXT_FILL_COLOR = 1
+_CURRENT_COLOR = 2
+_NEXT_STROKE_COLOR = 3
+_PREVIOUS_STROKE_COLOR = 4
+
+
+class EventIcon(gtk.EventBox):
+ __gtype_name__ = 'SugarEventIcon'
+
+ def __init__(self, **kwargs):
+ gtk.EventBox.__init__(self)
+
+ self.icon = Icon(pixel_size=style.XLARGE_ICON_SIZE, **kwargs)
+
+ self.set_visible_window(False)
+ self.set_app_paintable(True)
+ self.set_events(gtk.gdk.BUTTON_PRESS_MASK)
+
+ self.add(self.icon)
+ self.icon.show()
+
+
+class ColorPicker(EventIcon):
+ __gsignals__ = {
+ 'color-changed': (gobject.SIGNAL_RUN_FIRST,
+ gobject.TYPE_NONE,
+ ([object])),
+ }
+
+ def __init__(self, picker):
+ EventIcon.__init__(self)
+
+ self.icon.props.icon_name = 'computer-xo'
+ self._picker = picker
+ self._color = None
+
+ self.icon.props.pixel_size = style.XLARGE_ICON_SIZE
+
+ self.connect('button_press_event', self.__pressed_cb, picker)
+
+ def update(self, color):
+ if self._picker == _PREVIOUS_FILL_COLOR:
+ self._color = XoColor(_get_previous_fill_color(color))
+ elif self._picker == _PREVIOUS_STROKE_COLOR:
+ self._color = XoColor(_get_previous_stroke_color(color))
+ elif self._picker == _NEXT_FILL_COLOR:
+ self._color = XoColor(_get_next_fill_color(color))
+ elif self._picker == _NEXT_STROKE_COLOR:
+ self._color = XoColor(_get_next_stroke_color(color))
+ else:
+ self._color = color
+ self.icon.props.xo_color = self._color
+
+ def __pressed_cb(self, button, event, picker):
+ if picker != _CURRENT_COLOR:
+ self.emit('color-changed', self._color)
+
+
+class AboutMe(SectionView):
+
+ def __init__(self, model, alerts):
+ SectionView.__init__(self)
+
+ self._model = model
+ self.restart_alerts = alerts
+ self._nick_sid = 0
+ self._color_valid = True
+ self._nick_valid = True
+
+ self.set_border_width(style.DEFAULT_SPACING * 2)
+ self.set_spacing(style.DEFAULT_SPACING)
+ self._group = gtk.SizeGroup(gtk.SIZE_GROUP_HORIZONTAL)
+
+ self._color_label = gtk.HBox(spacing=style.DEFAULT_SPACING)
+ self._color_box = gtk.HBox(spacing=style.DEFAULT_SPACING)
+ self._color_alert_box = gtk.HBox(spacing=style.DEFAULT_SPACING)
+ self._color_alert = None
+
+ self._pickers = {
+ _PREVIOUS_FILL_COLOR: ColorPicker(_PREVIOUS_FILL_COLOR),
+ _NEXT_FILL_COLOR: ColorPicker(_NEXT_FILL_COLOR),
+ _CURRENT_COLOR: ColorPicker(_CURRENT_COLOR),
+ _NEXT_STROKE_COLOR: ColorPicker(_NEXT_STROKE_COLOR),
+ _PREVIOUS_STROKE_COLOR: ColorPicker(_PREVIOUS_STROKE_COLOR),
+ }
+
+ self._setup_color()
+ initial_color = XoColor(self._model.get_color_xo())
+ self._update_pickers(initial_color)
+
+ self._nick_box = gtk.HBox(spacing=style.DEFAULT_SPACING)
+ self._nick_alert_box = gtk.HBox(spacing=style.DEFAULT_SPACING)
+ self._nick_entry = None
+ self._nick_alert = None
+ self._setup_nick()
+ self.setup()
+
+ def _setup_nick(self):
+ self._nick_entry = gtk.Entry()
+ self._nick_entry.modify_bg(gtk.STATE_INSENSITIVE,
+ style.COLOR_WHITE.get_gdk_color())
+ self._nick_entry.modify_base(gtk.STATE_INSENSITIVE,
+ style.COLOR_WHITE.get_gdk_color())
+ self._nick_entry.set_width_chars(25)
+ self._nick_box.pack_start(self._nick_entry, expand=False)
+ self._nick_entry.show()
+
+ label_entry_error = gtk.Label()
+ self._group.add_widget(label_entry_error)
+ self._nick_alert_box.pack_start(label_entry_error, expand=False)
+ label_entry_error.show()
+
+ self._nick_alert = InlineAlert()
+ self._nick_alert_box.pack_start(self._nick_alert)
+ if 'nick' in self.restart_alerts:
+ self._nick_alert.props.msg = self.restart_msg
+ self._nick_alert.show()
+
+ self._center_in_panel = gtk.Alignment(0.5)
+ self._center_in_panel.add(self._nick_box)
+ self.pack_start(self._center_in_panel, False)
+ self.pack_start(self._nick_alert_box, False)
+ self._nick_box.show()
+ self._nick_alert_box.show()
+ self._center_in_panel.show()
+
+ def _setup_color(self):
+ label_color = gtk.Label(_('Click to change your color:'))
+ label_color.modify_fg(gtk.STATE_NORMAL,
+ style.COLOR_SELECTION_GREY.get_gdk_color())
+ self._group.add_widget(label_color)
+ self._color_label.pack_start(label_color, expand=False)
+ label_color.show()
+
+ for picker_index in sorted(self._pickers.keys()):
+ if picker_index == _CURRENT_COLOR:
+ left_separator = gtk.SeparatorToolItem()
+ left_separator.show()
+ self._color_box.pack_start(left_separator, expand=False)
+
+ picker = self._pickers[picker_index]
+ picker.show()
+ self._color_box.pack_start(picker, expand=False)
+
+ if picker_index == _CURRENT_COLOR:
+ right_separator = gtk.SeparatorToolItem()
+ right_separator.show()
+ self._color_box.pack_start(right_separator, expand=False)
+
+ label_color_error = gtk.Label()
+ self._group.add_widget(label_color_error)
+ self._color_alert_box.pack_start(label_color_error, expand=False)
+ label_color_error.show()
+
+ self._color_alert = InlineAlert()
+ self._color_alert_box.pack_start(self._color_alert)
+ if 'color' in self.restart_alerts:
+ self._color_alert.props.msg = self.restart_msg
+ self._color_alert.show()
+
+ self._center_in_panel = gtk.Alignment(0.5)
+ self._center_in_panel.add(self._color_box)
+ self.pack_start(self._color_label, False)
+ self.pack_start(self._center_in_panel, False)
+ self.pack_start(self._color_alert_box, False)
+ self._color_label.show()
+ self._color_box.show()
+ self._color_alert_box.show()
+ self._center_in_panel.show()
+
+ def setup(self):
+ self._nick_entry.set_text(self._model.get_nick())
+ self._color_valid = True
+ self._nick_valid = True
+ self.needs_restart = False
+
+ self._nick_entry.connect('changed', self.__nick_changed_cb)
+ for picker in self._pickers.values():
+ picker.connect('color-changed', self.__color_changed_cb)
+
+ def undo(self):
+ self._model.undo()
+ self._nick_alert.hide()
+ self._color_alert.hide()
+
+ def _update_pickers(self, color):
+ for picker in self._pickers.values():
+ picker.update(color)
+
+ def _validate(self):
+ if self._nick_valid and self._color_valid:
+ self.props.is_valid = True
+ else:
+ self.props.is_valid = False
+
+ def __nick_changed_cb(self, widget, data=None):
+ if self._nick_sid:
+ gobject.source_remove(self._nick_sid)
+ self._nick_sid = gobject.timeout_add(self._APPLY_TIMEOUT,
+ self.__nick_timeout_cb, widget)
+
+ def __nick_timeout_cb(self, widget):
+ self._nick_sid = 0
+
+ if widget.get_text() == self._model.get_nick():
+ return False
+ try:
+ self._model.set_nick(widget.get_text())
+ except ValueError, detail:
+ self._nick_alert.props.msg = detail
+ self._nick_valid = False
+ else:
+ self._nick_alert.props.msg = self.restart_msg
+ self._nick_valid = True
+ self.needs_restart = True
+ self.restart_alerts.append('nick')
+ self._validate()
+ self._nick_alert.show()
+ return False
+
+ def __color_changed_cb(self, colorpicker, color):
+ self._model.set_color_xo(color.to_string())
+ self.needs_restart = True
+ self._color_alert.props.msg = self.restart_msg
+ self._color_valid = True
+ self.restart_alerts.append('color')
+
+ self._validate()
+ self._color_alert.show()
+
+ self._update_pickers(color)
+
+ return False
diff --git a/extensions/cpsection/datetime/Makefile.am b/extensions/cpsection/datetime/Makefile.am
new file mode 100644
index 0000000..b5b518e
--- /dev/null
+++ b/extensions/cpsection/datetime/Makefile.am
@@ -0,0 +1,6 @@
+sugardir = $(pkgdatadir)/extensions/cpsection/datetime
+
+sugar_PYTHON = \
+ __init__.py \
+ model.py \
+ view.py
diff --git a/extensions/cpsection/datetime/Makefile.in b/extensions/cpsection/datetime/Makefile.in
new file mode 100644
index 0000000..d8b2cc1
--- /dev/null
+++ b/extensions/cpsection/datetime/Makefile.in
@@ -0,0 +1,442 @@
+# Makefile.in generated by automake 1.11.3 from Makefile.am.
+# @configure_input@
+
+# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002,
+# 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011 Free Software
+# Foundation, Inc.
+# This Makefile.in is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
+# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
+# PARTICULAR PURPOSE.
+
+@SET_MAKE@
+VPATH = @srcdir@
+pkgdatadir = $(datadir)/@PACKAGE@
+pkgincludedir = $(includedir)/@PACKAGE@
+pkglibdir = $(libdir)/@PACKAGE@
+pkglibexecdir = $(libexecdir)/@PACKAGE@
+am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd
+install_sh_DATA = $(install_sh) -c -m 644
+install_sh_PROGRAM = $(install_sh) -c
+install_sh_SCRIPT = $(install_sh) -c
+INSTALL_HEADER = $(INSTALL_DATA)
+transform = $(program_transform_name)
+NORMAL_INSTALL = :
+PRE_INSTALL = :
+POST_INSTALL = :
+NORMAL_UNINSTALL = :
+PRE_UNINSTALL = :
+POST_UNINSTALL = :
+subdir = extensions/cpsection/datetime
+DIST_COMMON = $(srcdir)/Makefile.am $(srcdir)/Makefile.in \
+ $(sugar_PYTHON)
+ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
+am__aclocal_m4_deps = $(top_srcdir)/configure.ac
+am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
+ $(ACLOCAL_M4)
+mkinstalldirs = $(install_sh) -d
+CONFIG_CLEAN_FILES =
+CONFIG_CLEAN_VPATH_FILES =
+SOURCES =
+DIST_SOURCES =
+am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`;
+am__vpath_adj = case $$p in \
+ $(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \
+ *) f=$$p;; \
+ esac;
+am__strip_dir = f=`echo $$p | sed -e 's|^.*/||'`;
+am__install_max = 40
+am__nobase_strip_setup = \
+ srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*|]/\\\\&/g'`
+am__nobase_strip = \
+ for p in $$list; do echo "$$p"; done | sed -e "s|$$srcdirstrip/||"
+am__nobase_list = $(am__nobase_strip_setup); \
+ for p in $$list; do echo "$$p $$p"; done | \
+ sed "s| $$srcdirstrip/| |;"' / .*\//!s/ .*/ ./; s,\( .*\)/[^/]*$$,\1,' | \
+ $(AWK) 'BEGIN { files["."] = "" } { files[$$2] = files[$$2] " " $$1; \
+ if (++n[$$2] == $(am__install_max)) \
+ { print $$2, files[$$2]; n[$$2] = 0; files[$$2] = "" } } \
+ END { for (dir in files) print dir, files[dir] }'
+am__base_list = \
+ sed '$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;s/\n/ /g' | \
+ sed '$$!N;$$!N;$$!N;$$!N;s/\n/ /g'
+am__uninstall_files_from_dir = { \
+ test -z "$$files" \
+ || { test ! -d "$$dir" && test ! -f "$$dir" && test ! -r "$$dir"; } \
+ || { echo " ( cd '$$dir' && rm -f" $$files ")"; \
+ $(am__cd) "$$dir" && rm -f $$files; }; \
+ }
+am__py_compile = PYTHON=$(PYTHON) $(SHELL) $(py_compile)
+am__installdirs = "$(DESTDIR)$(sugardir)"
+py_compile = $(top_srcdir)/py-compile
+DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
+ACLOCAL = @ACLOCAL@
+ALL_LINGUAS = @ALL_LINGUAS@
+AMTAR = @AMTAR@
+AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@
+AUTOCONF = @AUTOCONF@
+AUTOHEADER = @AUTOHEADER@
+AUTOMAKE = @AUTOMAKE@
+AWK = @AWK@
+CATALOGS = @CATALOGS@
+CATOBJEXT = @CATOBJEXT@
+CC = @CC@
+CCDEPMODE = @CCDEPMODE@
+CFLAGS = @CFLAGS@
+CPP = @CPP@
+CPPFLAGS = @CPPFLAGS@
+CYGPATH_W = @CYGPATH_W@
+DATADIRNAME = @DATADIRNAME@
+DEFS = @DEFS@
+DEPDIR = @DEPDIR@
+ECHO_C = @ECHO_C@
+ECHO_N = @ECHO_N@
+ECHO_T = @ECHO_T@
+EGREP = @EGREP@
+EXEEXT = @EXEEXT@
+GCONFTOOL = @GCONFTOOL@
+GCONF_SCHEMA_CONFIG_SOURCE = @GCONF_SCHEMA_CONFIG_SOURCE@
+GCONF_SCHEMA_FILE_DIR = @GCONF_SCHEMA_FILE_DIR@
+GETTEXT_PACKAGE = @GETTEXT_PACKAGE@
+GMOFILES = @GMOFILES@
+GMSGFMT = @GMSGFMT@
+GREP = @GREP@
+INSTALL = @INSTALL@
+INSTALL_DATA = @INSTALL_DATA@
+INSTALL_PROGRAM = @INSTALL_PROGRAM@
+INSTALL_SCRIPT = @INSTALL_SCRIPT@
+INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@
+INSTOBJEXT = @INSTOBJEXT@
+INTLLIBS = @INTLLIBS@
+INTLTOOL_EXTRACT = @INTLTOOL_EXTRACT@
+INTLTOOL_MERGE = @INTLTOOL_MERGE@
+INTLTOOL_PERL = @INTLTOOL_PERL@
+INTLTOOL_UPDATE = @INTLTOOL_UPDATE@
+INTLTOOL_V_MERGE = @INTLTOOL_V_MERGE@
+INTLTOOL_V_MERGE_OPTIONS = @INTLTOOL_V_MERGE_OPTIONS@
+INTLTOOL__v_MERGE_ = @INTLTOOL__v_MERGE_@
+INTLTOOL__v_MERGE_0 = @INTLTOOL__v_MERGE_0@
+LDFLAGS = @LDFLAGS@
+LIBOBJS = @LIBOBJS@
+LIBS = @LIBS@
+LTLIBOBJS = @LTLIBOBJS@
+MAINT = @MAINT@
+MAKEINFO = @MAKEINFO@
+MKDIR_P = @MKDIR_P@
+MKINSTALLDIRS = @MKINSTALLDIRS@
+MSGFMT = @MSGFMT@
+MSGFMT_OPTS = @MSGFMT_OPTS@
+MSGMERGE = @MSGMERGE@
+OBJEXT = @OBJEXT@
+PACKAGE = @PACKAGE@
+PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@
+PACKAGE_NAME = @PACKAGE_NAME@
+PACKAGE_STRING = @PACKAGE_STRING@
+PACKAGE_TARNAME = @PACKAGE_TARNAME@
+PACKAGE_URL = @PACKAGE_URL@
+PACKAGE_VERSION = @PACKAGE_VERSION@
+PATH_SEPARATOR = @PATH_SEPARATOR@
+PKG_CONFIG = @PKG_CONFIG@
+PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@
+PKG_CONFIG_PATH = @PKG_CONFIG_PATH@
+POFILES = @POFILES@
+POSUB = @POSUB@
+PO_IN_DATADIR_FALSE = @PO_IN_DATADIR_FALSE@
+PO_IN_DATADIR_TRUE = @PO_IN_DATADIR_TRUE@
+PYTHON = @PYTHON@
+PYTHON_EXEC_PREFIX = @PYTHON_EXEC_PREFIX@
+PYTHON_PLATFORM = @PYTHON_PLATFORM@
+PYTHON_PREFIX = @PYTHON_PREFIX@
+PYTHON_VERSION = @PYTHON_VERSION@
+SET_MAKE = @SET_MAKE@
+SHELL = @SHELL@
+SHELL_CFLAGS = @SHELL_CFLAGS@
+SHELL_LIBS = @SHELL_LIBS@
+STRIP = @STRIP@
+SUCROSE_VERSION = @SUCROSE_VERSION@
+USE_NLS = @USE_NLS@
+VERSION = @VERSION@
+XGETTEXT = @XGETTEXT@
+abs_builddir = @abs_builddir@
+abs_srcdir = @abs_srcdir@
+abs_top_builddir = @abs_top_builddir@
+abs_top_srcdir = @abs_top_srcdir@
+ac_ct_CC = @ac_ct_CC@
+am__include = @am__include@
+am__leading_dot = @am__leading_dot@
+am__quote = @am__quote@
+am__tar = @am__tar@
+am__untar = @am__untar@
+bindir = @bindir@
+build_alias = @build_alias@
+builddir = @builddir@
+datadir = @datadir@
+datarootdir = @datarootdir@
+docdir = @docdir@
+dvidir = @dvidir@
+exec_prefix = @exec_prefix@
+host_alias = @host_alias@
+htmldir = @htmldir@
+includedir = @includedir@
+infodir = @infodir@
+install_sh = @install_sh@
+intltool__v_merge_options_ = @intltool__v_merge_options_@
+intltool__v_merge_options_0 = @intltool__v_merge_options_0@
+libdir = @libdir@
+libexecdir = @libexecdir@
+localedir = @localedir@
+localstatedir = @localstatedir@
+mandir = @mandir@
+mkdir_p = @mkdir_p@
+oldincludedir = @oldincludedir@
+pdfdir = @pdfdir@
+pkgpyexecdir = @pkgpyexecdir@
+pkgpythondir = @pkgpythondir@
+prefix = @prefix@
+program_transform_name = @program_transform_name@
+psdir = @psdir@
+pyexecdir = @pyexecdir@
+pythondir = @pythondir@
+sbindir = @sbindir@
+sharedstatedir = @sharedstatedir@
+srcdir = @srcdir@
+sysconfdir = @sysconfdir@
+target_alias = @target_alias@
+top_build_prefix = @top_build_prefix@
+top_builddir = @top_builddir@
+top_srcdir = @top_srcdir@
+sugardir = $(pkgdatadir)/extensions/cpsection/datetime
+sugar_PYTHON = \
+ __init__.py \
+ model.py \
+ view.py
+
+all: all-am
+
+.SUFFIXES:
+$(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ $(srcdir)/Makefile.am $(am__configure_deps)
+ @for dep in $?; do \
+ case '$(am__configure_deps)' in \
+ *$$dep*) \
+ ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \
+ && { if test -f $@; then exit 0; else break; fi; }; \
+ exit 1;; \
+ esac; \
+ done; \
+ echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign extensions/cpsection/datetime/Makefile'; \
+ $(am__cd) $(top_srcdir) && \
+ $(AUTOMAKE) --foreign extensions/cpsection/datetime/Makefile
+.PRECIOUS: Makefile
+Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
+ @case '$?' in \
+ *config.status*) \
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \
+ *) \
+ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \
+ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \
+ esac;
+
+$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES)
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+
+$(top_srcdir)/configure: @MAINTAINER_MODE_TRUE@ $(am__configure_deps)
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+$(ACLOCAL_M4): @MAINTAINER_MODE_TRUE@ $(am__aclocal_m4_deps)
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+$(am__aclocal_m4_deps):
+install-sugarPYTHON: $(sugar_PYTHON)
+ @$(NORMAL_INSTALL)
+ test -z "$(sugardir)" || $(MKDIR_P) "$(DESTDIR)$(sugardir)"
+ @list='$(sugar_PYTHON)'; dlist=; list2=; test -n "$(sugardir)" || list=; \
+ for p in $$list; do \
+ if test -f "$$p"; then b=; else b="$(srcdir)/"; fi; \
+ if test -f $$b$$p; then \
+ $(am__strip_dir) \
+ dlist="$$dlist $$f"; \
+ list2="$$list2 $$b$$p"; \
+ else :; fi; \
+ done; \
+ for file in $$list2; do echo $$file; done | $(am__base_list) | \
+ while read files; do \
+ echo " $(INSTALL_DATA) $$files '$(DESTDIR)$(sugardir)'"; \
+ $(INSTALL_DATA) $$files "$(DESTDIR)$(sugardir)" || exit $$?; \
+ done || exit $$?; \
+ if test -n "$$dlist"; then \
+ $(am__py_compile) --destdir "$(DESTDIR)" \
+ --basedir "$(sugardir)" $$dlist; \
+ else :; fi
+
+uninstall-sugarPYTHON:
+ @$(NORMAL_UNINSTALL)
+ @list='$(sugar_PYTHON)'; test -n "$(sugardir)" || list=; \
+ files=`for p in $$list; do echo $$p; done | sed -e 's|^.*/||'`; \
+ test -n "$$files" || exit 0; \
+ dir='$(DESTDIR)$(sugardir)'; \
+ filesc=`echo "$$files" | sed 's|$$|c|'`; \
+ fileso=`echo "$$files" | sed 's|$$|o|'`; \
+ st=0; \
+ for files in "$$files" "$$filesc" "$$fileso"; do \
+ $(am__uninstall_files_from_dir) || st=$$?; \
+ done; \
+ exit $$st
+tags: TAGS
+TAGS:
+
+ctags: CTAGS
+CTAGS:
+
+
+distdir: $(DISTFILES)
+ @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
+ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
+ list='$(DISTFILES)'; \
+ dist_files=`for file in $$list; do echo $$file; done | \
+ sed -e "s|^$$srcdirstrip/||;t" \
+ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \
+ case $$dist_files in \
+ */*) $(MKDIR_P) `echo "$$dist_files" | \
+ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \
+ sort -u` ;; \
+ esac; \
+ for file in $$dist_files; do \
+ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \
+ if test -d $$d/$$file; then \
+ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \
+ if test -d "$(distdir)/$$file"; then \
+ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \
+ fi; \
+ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \
+ cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \
+ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \
+ fi; \
+ cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \
+ else \
+ test -f "$(distdir)/$$file" \
+ || cp -p $$d/$$file "$(distdir)/$$file" \
+ || exit 1; \
+ fi; \
+ done
+check-am: all-am
+check: check-am
+all-am: Makefile
+installdirs:
+ for dir in "$(DESTDIR)$(sugardir)"; do \
+ test -z "$$dir" || $(MKDIR_P) "$$dir"; \
+ done
+install: install-am
+install-exec: install-exec-am
+install-data: install-data-am
+uninstall: uninstall-am
+
+install-am: all-am
+ @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am
+
+installcheck: installcheck-am
+install-strip:
+ if test -z '$(STRIP)'; then \
+ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
+ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
+ install; \
+ else \
+ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
+ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
+ "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \
+ fi
+mostlyclean-generic:
+
+clean-generic:
+
+distclean-generic:
+ -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES)
+ -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES)
+
+maintainer-clean-generic:
+ @echo "This command is intended for maintainers to use"
+ @echo "it deletes files that may require special tools to rebuild."
+clean: clean-am
+
+clean-am: clean-generic mostlyclean-am
+
+distclean: distclean-am
+ -rm -f Makefile
+distclean-am: clean-am distclean-generic
+
+dvi: dvi-am
+
+dvi-am:
+
+html: html-am
+
+html-am:
+
+info: info-am
+
+info-am:
+
+install-data-am: install-sugarPYTHON
+
+install-dvi: install-dvi-am
+
+install-dvi-am:
+
+install-exec-am:
+
+install-html: install-html-am
+
+install-html-am:
+
+install-info: install-info-am
+
+install-info-am:
+
+install-man:
+
+install-pdf: install-pdf-am
+
+install-pdf-am:
+
+install-ps: install-ps-am
+
+install-ps-am:
+
+installcheck-am:
+
+maintainer-clean: maintainer-clean-am
+ -rm -f Makefile
+maintainer-clean-am: distclean-am maintainer-clean-generic
+
+mostlyclean: mostlyclean-am
+
+mostlyclean-am: mostlyclean-generic
+
+pdf: pdf-am
+
+pdf-am:
+
+ps: ps-am
+
+ps-am:
+
+uninstall-am: uninstall-sugarPYTHON
+
+.MAKE: install-am install-strip
+
+.PHONY: all all-am check check-am clean clean-generic distclean \
+ distclean-generic distdir dvi dvi-am html html-am info info-am \
+ install install-am install-data install-data-am install-dvi \
+ install-dvi-am install-exec install-exec-am install-html \
+ install-html-am install-info install-info-am install-man \
+ install-pdf install-pdf-am install-ps install-ps-am \
+ install-strip install-sugarPYTHON installcheck installcheck-am \
+ installdirs maintainer-clean maintainer-clean-generic \
+ mostlyclean mostlyclean-generic pdf pdf-am ps ps-am uninstall \
+ uninstall-am uninstall-sugarPYTHON
+
+
+# Tell versions [3.59,3.63) of GNU make to not export all variables.
+# Otherwise a system limit (for SysV at least) may be exceeded.
+.NOEXPORT:
diff --git a/extensions/cpsection/datetime/__init__.py b/extensions/cpsection/datetime/__init__.py
new file mode 100644
index 0000000..fc9be45
--- /dev/null
+++ b/extensions/cpsection/datetime/__init__.py
@@ -0,0 +1,21 @@
+# Copyright (C) 2008, OLPC
+#
+# 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 2 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, write to the Free Software
+# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+
+from gettext import gettext as _
+
+CLASS = 'TimeZone'
+ICON = 'module-date_and_time'
+TITLE = _('Date & Time')
diff --git a/extensions/cpsection/datetime/model.py b/extensions/cpsection/datetime/model.py
new file mode 100644
index 0000000..84e1259
--- /dev/null
+++ b/extensions/cpsection/datetime/model.py
@@ -0,0 +1,96 @@
+# Copyright (C) 2007, 2008 One Laptop Per Child
+#
+# 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 2 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, write to the Free Software
+# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+#
+#
+# The timezone config is based on the system-config-date
+# (http://fedoraproject.org/wiki/SystemConfig/date) tool.
+# Parts of the code were reused.
+#
+
+import os
+from gettext import gettext as _
+import gconf
+
+_zone_tab = '/usr/share/zoneinfo/zone.tab'
+
+
+def _initialize():
+ """Initialize the docstring of the set function"""
+ if set_timezone.__doc__ is None:
+ # when running under 'python -OO', all __doc__ fields are None,
+ # so += would fail -- and this function would be unnecessary anyway.
+ return
+ timezones = read_all_timezones()
+ for timezone in timezones:
+ set_timezone.__doc__ += timezone + '\n'
+
+
+def read_all_timezones(fn=_zone_tab):
+ fd = open(fn, 'r')
+ lines = fd.readlines()
+ fd.close()
+ timezones = []
+ for line in lines:
+ if line.startswith('#'):
+ continue
+ line = line.split()
+ if len(line) > 1:
+ timezones.append(line[2])
+ timezones.sort()
+
+ for offset in xrange(-12, 13):
+ if offset < 0:
+ tz = 'GMT%d' % offset
+ elif offset > 0:
+ tz = 'GMT+%d' % offset
+ else:
+ tz = 'GMT'
+ timezones.append(tz)
+ for offset in xrange(-12, 13):
+ if offset < 0:
+ tz = 'UTC%d' % offset
+ elif offset > 0:
+ tz = 'UTC+%d' % offset
+ else:
+ tz = 'UTC'
+ timezones.append(tz)
+ return timezones
+
+
+def get_timezone():
+ client = gconf.client_get_default()
+ return client.get_string('/desktop/sugar/date/timezone')
+
+
+def print_timezone():
+ print get_timezone()
+
+
+def set_timezone(timezone):
+ """Set the system timezone
+ timezone : e.g. 'America/Los_Angeles'
+ """
+ timezones = read_all_timezones()
+ if timezone in timezones:
+ os.environ['TZ'] = timezone
+ client = gconf.client_get_default()
+ client.set_string('/desktop/sugar/date/timezone', timezone)
+ else:
+ raise ValueError(_('Error timezone does not exist.'))
+ return 1
+
+# inilialize the docstrings for the timezone
+_initialize()
diff --git a/extensions/cpsection/datetime/view.py b/extensions/cpsection/datetime/view.py
new file mode 100644
index 0000000..1cef78f
--- /dev/null
+++ b/extensions/cpsection/datetime/view.py
@@ -0,0 +1,140 @@
+# Copyright (C) 2008, OLPC
+#
+# 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 2 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, write to the Free Software
+# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+
+import gtk
+import gobject
+from gettext import gettext as _
+
+from sugar.graphics import style
+from sugar.graphics import iconentry
+
+from jarabe.controlpanel.sectionview import SectionView
+from jarabe.controlpanel.inlinealert import InlineAlert
+
+
+class TimeZone(SectionView):
+ def __init__(self, model, alerts):
+ SectionView.__init__(self)
+
+ self._model = model
+ self.restart_alerts = alerts
+ self._zone_sid = 0
+ self._cursor_change_handler = None
+
+ self.set_border_width(style.DEFAULT_SPACING * 2)
+ self.set_spacing(style.DEFAULT_SPACING)
+
+ self.connect('realize', self.__realize_cb)
+
+ self._entry = iconentry.IconEntry()
+ self._entry.set_icon_from_name(iconentry.ICON_ENTRY_PRIMARY,
+ 'system-search')
+ self._entry.add_clear_button()
+ self._entry.modify_bg(gtk.STATE_INSENSITIVE,
+ style.COLOR_WHITE.get_gdk_color())
+ self._entry.modify_base(gtk.STATE_INSENSITIVE,
+ style.COLOR_WHITE.get_gdk_color())
+ self.pack_start(self._entry, False)
+ self._entry.show()
+
+ self._scrolled_window = gtk.ScrolledWindow()
+ self._scrolled_window.set_policy(gtk.POLICY_NEVER,
+ gtk.POLICY_AUTOMATIC)
+ self._scrolled_window.set_shadow_type(gtk.SHADOW_IN)
+
+ self._store = gtk.ListStore(gobject.TYPE_STRING)
+ zones = model.read_all_timezones()
+ for zone in zones:
+ self._store.append([zone])
+
+ self._treeview = gtk.TreeView(self._store)
+ self._treeview.set_search_entry(self._entry)
+ self._treeview.set_search_equal_func(self._search)
+ self._treeview.set_search_column(0)
+ self._scrolled_window.add(self._treeview)
+ self._treeview.show()
+
+ self._timezone_column = gtk.TreeViewColumn(_('Timezone'))
+ self._cell = gtk.CellRendererText()
+ self._timezone_column.pack_start(self._cell, True)
+ self._timezone_column.add_attribute(self._cell, 'text', 0)
+ self._timezone_column.set_sort_column_id(0)
+ self._treeview.append_column(self._timezone_column)
+
+ self.pack_start(self._scrolled_window)
+ self._scrolled_window.show()
+
+ self._zone_alert_box = gtk.HBox(spacing=style.DEFAULT_SPACING)
+ self.pack_start(self._zone_alert_box, False)
+
+ self._zone_alert = InlineAlert()
+ self._zone_alert_box.pack_start(self._zone_alert)
+ if 'zone' in self.restart_alerts:
+ self._zone_alert.props.msg = self.restart_msg
+ self._zone_alert.show()
+ self._zone_alert_box.show()
+
+ self.setup()
+
+ def setup(self):
+ zone = self._model.get_timezone()
+ for row in self._store:
+ if zone == row[0]:
+ self._treeview.set_cursor(row.path, self._timezone_column,
+ False)
+ self._treeview.scroll_to_cell(row.path, self._timezone_column,
+ True, 0.5, 0.5)
+ break
+
+ self.needs_restart = False
+ self._cursor_change_handler = self._treeview.connect( \
+ 'cursor-changed', self.__zone_changed_cd)
+
+ def undo(self):
+ self._treeview.disconnect(self._cursor_change_handler)
+ self._model.undo()
+ self._zone_alert.hide()
+
+ def __realize_cb(self, widget):
+ self._entry.grab_focus()
+
+ def _search(self, model, column, key, iterator, data=None):
+ value = model.get_value(iterator, column)
+ if key.lower() in value.lower():
+ return False
+ return True
+
+ def __zone_changed_cd(self, treeview, data=None):
+ list_, row = treeview.get_selection().get_selected()
+ if not row:
+ return False
+ if self._model.get_timezone() == self._store.get_value(row, 0):
+ return False
+
+ if self._zone_sid:
+ gobject.source_remove(self._zone_sid)
+ self._zone_sid = gobject.timeout_add(self._APPLY_TIMEOUT,
+ self.__zone_timeout_cb, row)
+ return True
+
+ def __zone_timeout_cb(self, row):
+ self._zone_sid = 0
+ self._model.set_timezone(self._store.get_value(row, 0))
+ self.restart_alerts.append('zone')
+ self.needs_restart = True
+ self._zone_alert.props.msg = self.restart_msg
+ self._zone_alert.show()
+ return False
diff --git a/extensions/cpsection/frame/Makefile.am b/extensions/cpsection/frame/Makefile.am
new file mode 100644
index 0000000..1e09c04
--- /dev/null
+++ b/extensions/cpsection/frame/Makefile.am
@@ -0,0 +1,6 @@
+sugardir = $(pkgdatadir)/extensions/cpsection/frame
+
+sugar_PYTHON = \
+ __init__.py \
+ model.py \
+ view.py
diff --git a/extensions/cpsection/frame/Makefile.in b/extensions/cpsection/frame/Makefile.in
new file mode 100644
index 0000000..1a7d880
--- /dev/null
+++ b/extensions/cpsection/frame/Makefile.in
@@ -0,0 +1,442 @@
+# Makefile.in generated by automake 1.11.3 from Makefile.am.
+# @configure_input@
+
+# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002,
+# 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011 Free Software
+# Foundation, Inc.
+# This Makefile.in is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
+# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
+# PARTICULAR PURPOSE.
+
+@SET_MAKE@
+VPATH = @srcdir@
+pkgdatadir = $(datadir)/@PACKAGE@
+pkgincludedir = $(includedir)/@PACKAGE@
+pkglibdir = $(libdir)/@PACKAGE@
+pkglibexecdir = $(libexecdir)/@PACKAGE@
+am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd
+install_sh_DATA = $(install_sh) -c -m 644
+install_sh_PROGRAM = $(install_sh) -c
+install_sh_SCRIPT = $(install_sh) -c
+INSTALL_HEADER = $(INSTALL_DATA)
+transform = $(program_transform_name)
+NORMAL_INSTALL = :
+PRE_INSTALL = :
+POST_INSTALL = :
+NORMAL_UNINSTALL = :
+PRE_UNINSTALL = :
+POST_UNINSTALL = :
+subdir = extensions/cpsection/frame
+DIST_COMMON = $(srcdir)/Makefile.am $(srcdir)/Makefile.in \
+ $(sugar_PYTHON)
+ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
+am__aclocal_m4_deps = $(top_srcdir)/configure.ac
+am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
+ $(ACLOCAL_M4)
+mkinstalldirs = $(install_sh) -d
+CONFIG_CLEAN_FILES =
+CONFIG_CLEAN_VPATH_FILES =
+SOURCES =
+DIST_SOURCES =
+am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`;
+am__vpath_adj = case $$p in \
+ $(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \
+ *) f=$$p;; \
+ esac;
+am__strip_dir = f=`echo $$p | sed -e 's|^.*/||'`;
+am__install_max = 40
+am__nobase_strip_setup = \
+ srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*|]/\\\\&/g'`
+am__nobase_strip = \
+ for p in $$list; do echo "$$p"; done | sed -e "s|$$srcdirstrip/||"
+am__nobase_list = $(am__nobase_strip_setup); \
+ for p in $$list; do echo "$$p $$p"; done | \
+ sed "s| $$srcdirstrip/| |;"' / .*\//!s/ .*/ ./; s,\( .*\)/[^/]*$$,\1,' | \
+ $(AWK) 'BEGIN { files["."] = "" } { files[$$2] = files[$$2] " " $$1; \
+ if (++n[$$2] == $(am__install_max)) \
+ { print $$2, files[$$2]; n[$$2] = 0; files[$$2] = "" } } \
+ END { for (dir in files) print dir, files[dir] }'
+am__base_list = \
+ sed '$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;s/\n/ /g' | \
+ sed '$$!N;$$!N;$$!N;$$!N;s/\n/ /g'
+am__uninstall_files_from_dir = { \
+ test -z "$$files" \
+ || { test ! -d "$$dir" && test ! -f "$$dir" && test ! -r "$$dir"; } \
+ || { echo " ( cd '$$dir' && rm -f" $$files ")"; \
+ $(am__cd) "$$dir" && rm -f $$files; }; \
+ }
+am__py_compile = PYTHON=$(PYTHON) $(SHELL) $(py_compile)
+am__installdirs = "$(DESTDIR)$(sugardir)"
+py_compile = $(top_srcdir)/py-compile
+DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
+ACLOCAL = @ACLOCAL@
+ALL_LINGUAS = @ALL_LINGUAS@
+AMTAR = @AMTAR@
+AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@
+AUTOCONF = @AUTOCONF@
+AUTOHEADER = @AUTOHEADER@
+AUTOMAKE = @AUTOMAKE@
+AWK = @AWK@
+CATALOGS = @CATALOGS@
+CATOBJEXT = @CATOBJEXT@
+CC = @CC@
+CCDEPMODE = @CCDEPMODE@
+CFLAGS = @CFLAGS@
+CPP = @CPP@
+CPPFLAGS = @CPPFLAGS@
+CYGPATH_W = @CYGPATH_W@
+DATADIRNAME = @DATADIRNAME@
+DEFS = @DEFS@
+DEPDIR = @DEPDIR@
+ECHO_C = @ECHO_C@
+ECHO_N = @ECHO_N@
+ECHO_T = @ECHO_T@
+EGREP = @EGREP@
+EXEEXT = @EXEEXT@
+GCONFTOOL = @GCONFTOOL@
+GCONF_SCHEMA_CONFIG_SOURCE = @GCONF_SCHEMA_CONFIG_SOURCE@
+GCONF_SCHEMA_FILE_DIR = @GCONF_SCHEMA_FILE_DIR@
+GETTEXT_PACKAGE = @GETTEXT_PACKAGE@
+GMOFILES = @GMOFILES@
+GMSGFMT = @GMSGFMT@
+GREP = @GREP@
+INSTALL = @INSTALL@
+INSTALL_DATA = @INSTALL_DATA@
+INSTALL_PROGRAM = @INSTALL_PROGRAM@
+INSTALL_SCRIPT = @INSTALL_SCRIPT@
+INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@
+INSTOBJEXT = @INSTOBJEXT@
+INTLLIBS = @INTLLIBS@
+INTLTOOL_EXTRACT = @INTLTOOL_EXTRACT@
+INTLTOOL_MERGE = @INTLTOOL_MERGE@
+INTLTOOL_PERL = @INTLTOOL_PERL@
+INTLTOOL_UPDATE = @INTLTOOL_UPDATE@
+INTLTOOL_V_MERGE = @INTLTOOL_V_MERGE@
+INTLTOOL_V_MERGE_OPTIONS = @INTLTOOL_V_MERGE_OPTIONS@
+INTLTOOL__v_MERGE_ = @INTLTOOL__v_MERGE_@
+INTLTOOL__v_MERGE_0 = @INTLTOOL__v_MERGE_0@
+LDFLAGS = @LDFLAGS@
+LIBOBJS = @LIBOBJS@
+LIBS = @LIBS@
+LTLIBOBJS = @LTLIBOBJS@
+MAINT = @MAINT@
+MAKEINFO = @MAKEINFO@
+MKDIR_P = @MKDIR_P@
+MKINSTALLDIRS = @MKINSTALLDIRS@
+MSGFMT = @MSGFMT@
+MSGFMT_OPTS = @MSGFMT_OPTS@
+MSGMERGE = @MSGMERGE@
+OBJEXT = @OBJEXT@
+PACKAGE = @PACKAGE@
+PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@
+PACKAGE_NAME = @PACKAGE_NAME@
+PACKAGE_STRING = @PACKAGE_STRING@
+PACKAGE_TARNAME = @PACKAGE_TARNAME@
+PACKAGE_URL = @PACKAGE_URL@
+PACKAGE_VERSION = @PACKAGE_VERSION@
+PATH_SEPARATOR = @PATH_SEPARATOR@
+PKG_CONFIG = @PKG_CONFIG@
+PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@
+PKG_CONFIG_PATH = @PKG_CONFIG_PATH@
+POFILES = @POFILES@
+POSUB = @POSUB@
+PO_IN_DATADIR_FALSE = @PO_IN_DATADIR_FALSE@
+PO_IN_DATADIR_TRUE = @PO_IN_DATADIR_TRUE@
+PYTHON = @PYTHON@
+PYTHON_EXEC_PREFIX = @PYTHON_EXEC_PREFIX@
+PYTHON_PLATFORM = @PYTHON_PLATFORM@
+PYTHON_PREFIX = @PYTHON_PREFIX@
+PYTHON_VERSION = @PYTHON_VERSION@
+SET_MAKE = @SET_MAKE@
+SHELL = @SHELL@
+SHELL_CFLAGS = @SHELL_CFLAGS@
+SHELL_LIBS = @SHELL_LIBS@
+STRIP = @STRIP@
+SUCROSE_VERSION = @SUCROSE_VERSION@
+USE_NLS = @USE_NLS@
+VERSION = @VERSION@
+XGETTEXT = @XGETTEXT@
+abs_builddir = @abs_builddir@
+abs_srcdir = @abs_srcdir@
+abs_top_builddir = @abs_top_builddir@
+abs_top_srcdir = @abs_top_srcdir@
+ac_ct_CC = @ac_ct_CC@
+am__include = @am__include@
+am__leading_dot = @am__leading_dot@
+am__quote = @am__quote@
+am__tar = @am__tar@
+am__untar = @am__untar@
+bindir = @bindir@
+build_alias = @build_alias@
+builddir = @builddir@
+datadir = @datadir@
+datarootdir = @datarootdir@
+docdir = @docdir@
+dvidir = @dvidir@
+exec_prefix = @exec_prefix@
+host_alias = @host_alias@
+htmldir = @htmldir@
+includedir = @includedir@
+infodir = @infodir@
+install_sh = @install_sh@
+intltool__v_merge_options_ = @intltool__v_merge_options_@
+intltool__v_merge_options_0 = @intltool__v_merge_options_0@
+libdir = @libdir@
+libexecdir = @libexecdir@
+localedir = @localedir@
+localstatedir = @localstatedir@
+mandir = @mandir@
+mkdir_p = @mkdir_p@
+oldincludedir = @oldincludedir@
+pdfdir = @pdfdir@
+pkgpyexecdir = @pkgpyexecdir@
+pkgpythondir = @pkgpythondir@
+prefix = @prefix@
+program_transform_name = @program_transform_name@
+psdir = @psdir@
+pyexecdir = @pyexecdir@
+pythondir = @pythondir@
+sbindir = @sbindir@
+sharedstatedir = @sharedstatedir@
+srcdir = @srcdir@
+sysconfdir = @sysconfdir@
+target_alias = @target_alias@
+top_build_prefix = @top_build_prefix@
+top_builddir = @top_builddir@
+top_srcdir = @top_srcdir@
+sugardir = $(pkgdatadir)/extensions/cpsection/frame
+sugar_PYTHON = \
+ __init__.py \
+ model.py \
+ view.py
+
+all: all-am
+
+.SUFFIXES:
+$(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ $(srcdir)/Makefile.am $(am__configure_deps)
+ @for dep in $?; do \
+ case '$(am__configure_deps)' in \
+ *$$dep*) \
+ ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \
+ && { if test -f $@; then exit 0; else break; fi; }; \
+ exit 1;; \
+ esac; \
+ done; \
+ echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign extensions/cpsection/frame/Makefile'; \
+ $(am__cd) $(top_srcdir) && \
+ $(AUTOMAKE) --foreign extensions/cpsection/frame/Makefile
+.PRECIOUS: Makefile
+Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
+ @case '$?' in \
+ *config.status*) \
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \
+ *) \
+ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \
+ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \
+ esac;
+
+$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES)
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+
+$(top_srcdir)/configure: @MAINTAINER_MODE_TRUE@ $(am__configure_deps)
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+$(ACLOCAL_M4): @MAINTAINER_MODE_TRUE@ $(am__aclocal_m4_deps)
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+$(am__aclocal_m4_deps):
+install-sugarPYTHON: $(sugar_PYTHON)
+ @$(NORMAL_INSTALL)
+ test -z "$(sugardir)" || $(MKDIR_P) "$(DESTDIR)$(sugardir)"
+ @list='$(sugar_PYTHON)'; dlist=; list2=; test -n "$(sugardir)" || list=; \
+ for p in $$list; do \
+ if test -f "$$p"; then b=; else b="$(srcdir)/"; fi; \
+ if test -f $$b$$p; then \
+ $(am__strip_dir) \
+ dlist="$$dlist $$f"; \
+ list2="$$list2 $$b$$p"; \
+ else :; fi; \
+ done; \
+ for file in $$list2; do echo $$file; done | $(am__base_list) | \
+ while read files; do \
+ echo " $(INSTALL_DATA) $$files '$(DESTDIR)$(sugardir)'"; \
+ $(INSTALL_DATA) $$files "$(DESTDIR)$(sugardir)" || exit $$?; \
+ done || exit $$?; \
+ if test -n "$$dlist"; then \
+ $(am__py_compile) --destdir "$(DESTDIR)" \
+ --basedir "$(sugardir)" $$dlist; \
+ else :; fi
+
+uninstall-sugarPYTHON:
+ @$(NORMAL_UNINSTALL)
+ @list='$(sugar_PYTHON)'; test -n "$(sugardir)" || list=; \
+ files=`for p in $$list; do echo $$p; done | sed -e 's|^.*/||'`; \
+ test -n "$$files" || exit 0; \
+ dir='$(DESTDIR)$(sugardir)'; \
+ filesc=`echo "$$files" | sed 's|$$|c|'`; \
+ fileso=`echo "$$files" | sed 's|$$|o|'`; \
+ st=0; \
+ for files in "$$files" "$$filesc" "$$fileso"; do \
+ $(am__uninstall_files_from_dir) || st=$$?; \
+ done; \
+ exit $$st
+tags: TAGS
+TAGS:
+
+ctags: CTAGS
+CTAGS:
+
+
+distdir: $(DISTFILES)
+ @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
+ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
+ list='$(DISTFILES)'; \
+ dist_files=`for file in $$list; do echo $$file; done | \
+ sed -e "s|^$$srcdirstrip/||;t" \
+ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \
+ case $$dist_files in \
+ */*) $(MKDIR_P) `echo "$$dist_files" | \
+ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \
+ sort -u` ;; \
+ esac; \
+ for file in $$dist_files; do \
+ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \
+ if test -d $$d/$$file; then \
+ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \
+ if test -d "$(distdir)/$$file"; then \
+ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \
+ fi; \
+ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \
+ cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \
+ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \
+ fi; \
+ cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \
+ else \
+ test -f "$(distdir)/$$file" \
+ || cp -p $$d/$$file "$(distdir)/$$file" \
+ || exit 1; \
+ fi; \
+ done
+check-am: all-am
+check: check-am
+all-am: Makefile
+installdirs:
+ for dir in "$(DESTDIR)$(sugardir)"; do \
+ test -z "$$dir" || $(MKDIR_P) "$$dir"; \
+ done
+install: install-am
+install-exec: install-exec-am
+install-data: install-data-am
+uninstall: uninstall-am
+
+install-am: all-am
+ @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am
+
+installcheck: installcheck-am
+install-strip:
+ if test -z '$(STRIP)'; then \
+ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
+ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
+ install; \
+ else \
+ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
+ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
+ "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \
+ fi
+mostlyclean-generic:
+
+clean-generic:
+
+distclean-generic:
+ -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES)
+ -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES)
+
+maintainer-clean-generic:
+ @echo "This command is intended for maintainers to use"
+ @echo "it deletes files that may require special tools to rebuild."
+clean: clean-am
+
+clean-am: clean-generic mostlyclean-am
+
+distclean: distclean-am
+ -rm -f Makefile
+distclean-am: clean-am distclean-generic
+
+dvi: dvi-am
+
+dvi-am:
+
+html: html-am
+
+html-am:
+
+info: info-am
+
+info-am:
+
+install-data-am: install-sugarPYTHON
+
+install-dvi: install-dvi-am
+
+install-dvi-am:
+
+install-exec-am:
+
+install-html: install-html-am
+
+install-html-am:
+
+install-info: install-info-am
+
+install-info-am:
+
+install-man:
+
+install-pdf: install-pdf-am
+
+install-pdf-am:
+
+install-ps: install-ps-am
+
+install-ps-am:
+
+installcheck-am:
+
+maintainer-clean: maintainer-clean-am
+ -rm -f Makefile
+maintainer-clean-am: distclean-am maintainer-clean-generic
+
+mostlyclean: mostlyclean-am
+
+mostlyclean-am: mostlyclean-generic
+
+pdf: pdf-am
+
+pdf-am:
+
+ps: ps-am
+
+ps-am:
+
+uninstall-am: uninstall-sugarPYTHON
+
+.MAKE: install-am install-strip
+
+.PHONY: all all-am check check-am clean clean-generic distclean \
+ distclean-generic distdir dvi dvi-am html html-am info info-am \
+ install install-am install-data install-data-am install-dvi \
+ install-dvi-am install-exec install-exec-am install-html \
+ install-html-am install-info install-info-am install-man \
+ install-pdf install-pdf-am install-ps install-ps-am \
+ install-strip install-sugarPYTHON installcheck installcheck-am \
+ installdirs maintainer-clean maintainer-clean-generic \
+ mostlyclean mostlyclean-generic pdf pdf-am ps ps-am uninstall \
+ uninstall-am uninstall-sugarPYTHON
+
+
+# Tell versions [3.59,3.63) of GNU make to not export all variables.
+# Otherwise a system limit (for SysV at least) may be exceeded.
+.NOEXPORT:
diff --git a/extensions/cpsection/frame/__init__.py b/extensions/cpsection/frame/__init__.py
new file mode 100644
index 0000000..a93f9c7
--- /dev/null
+++ b/extensions/cpsection/frame/__init__.py
@@ -0,0 +1,21 @@
+# Copyright (C) 2008, OLPC
+#
+# 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 2 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, write to the Free Software
+# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+
+from gettext import gettext as _
+
+CLASS = 'Frame'
+ICON = 'module-frame'
+TITLE = _('Frame')
diff --git a/extensions/cpsection/frame/model.py b/extensions/cpsection/frame/model.py
new file mode 100644
index 0000000..4796062
--- /dev/null
+++ b/extensions/cpsection/frame/model.py
@@ -0,0 +1,69 @@
+# Copyright (C) 2008 One Laptop Per Child
+#
+# 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 2 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, write to the Free Software
+# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+#
+
+from gettext import gettext as _
+import gconf
+
+
+def get_corner_delay():
+ client = gconf.client_get_default()
+ corner_delay = client.get_int('/desktop/sugar/frame/corner_delay')
+ return corner_delay
+
+
+def print_corner_delay():
+ print get_corner_delay()
+
+
+def set_corner_delay(delay):
+ """Set a delay for the activation of the frame using hot corners.
+ instantaneous: 0 (0 milliseconds)
+ delay: 100 (100 milliseconds)
+ never: 1000 (disable activation)
+ """
+ try:
+ int(delay)
+ except ValueError:
+ raise ValueError(_('Value must be an integer.'))
+ client = gconf.client_get_default()
+ client.set_int('/desktop/sugar/frame/corner_delay', int(delay))
+ return 0
+
+
+def get_edge_delay():
+ client = gconf.client_get_default()
+ edge_delay = client.get_int('/desktop/sugar/frame/edge_delay')
+ return edge_delay
+
+
+def print_edge_delay():
+ print get_edge_delay()
+
+
+def set_edge_delay(delay):
+ """Set a delay for the activation of the frame using warm edges.
+ instantaneous: 0 (0 milliseconds)
+ delay: 100 (100 milliseconds)
+ never: 1000 (disable activation)
+ """
+ try:
+ int(delay)
+ except ValueError:
+ raise ValueError(_('Value must be an integer.'))
+ client = gconf.client_get_default()
+ client.set_int('/desktop/sugar/frame/edge_delay', int(delay))
+ return 0
diff --git a/extensions/cpsection/frame/view.py b/extensions/cpsection/frame/view.py
new file mode 100644
index 0000000..8b4ab83
--- /dev/null
+++ b/extensions/cpsection/frame/view.py
@@ -0,0 +1,234 @@
+# Copyright (C) 2008, OLPC
+#
+# 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 2 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, write to the Free Software
+# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+
+import gtk
+import gobject
+from gettext import gettext as _
+
+from sugar.graphics import style
+
+from jarabe.controlpanel.sectionview import SectionView
+from jarabe.controlpanel.inlinealert import InlineAlert
+
+
+_never = _('never')
+_instantaneous = _('instantaneous')
+_seconds_label = _('%s seconds')
+_MAX_DELAY = 1000
+
+
+class Frame(SectionView):
+ def __init__(self, model, alerts):
+ SectionView.__init__(self)
+
+ self._model = model
+ self._corner_delay_sid = 0
+ self._corner_delay_is_valid = True
+ self._corner_delay_change_handler = None
+ self._edge_delay_sid = 0
+ self._edge_delay_is_valid = True
+ self._edge_delay_change_handler = None
+ self.restart_alerts = alerts
+
+ self.set_border_width(style.DEFAULT_SPACING * 2)
+ self.set_spacing(style.DEFAULT_SPACING)
+ self._group = gtk.SizeGroup(gtk.SIZE_GROUP_HORIZONTAL)
+
+ separator = gtk.HSeparator()
+ self.pack_start(separator, expand=False)
+ separator.show()
+
+ label_activation = gtk.Label(_('Activation Delay'))
+ label_activation.set_alignment(0, 0)
+ self.pack_start(label_activation, expand=False)
+ label_activation.show()
+
+ self._box_sliders = gtk.VBox()
+ self._box_sliders.set_border_width(style.DEFAULT_SPACING * 2)
+ self._box_sliders.set_spacing(style.DEFAULT_SPACING)
+
+ self._corner_delay_slider = None
+ self._corner_delay_alert = None
+ self._setup_corner()
+
+ self._edge_delay_slider = None
+ self._edge_delay_alert = None
+ self._setup_edge()
+
+ self.pack_start(self._box_sliders, expand=False)
+ self._box_sliders.show()
+
+ self.setup()
+
+ def _setup_corner(self):
+ box_delay = gtk.HBox(spacing=style.DEFAULT_SPACING)
+ label_delay = gtk.Label(_('Corner'))
+ label_delay.set_alignment(1, 0.75)
+ label_delay.modify_fg(gtk.STATE_NORMAL,
+ style.COLOR_SELECTION_GREY.get_gdk_color())
+ box_delay.pack_start(label_delay, expand=False)
+ self._group.add_widget(label_delay)
+ label_delay.show()
+
+ adj = gtk.Adjustment(value=100, lower=0, upper=_MAX_DELAY,
+ step_incr=100, page_incr=100, page_size=0)
+ self._corner_delay_slider = gtk.HScale(adj)
+ self._corner_delay_slider.set_digits(0)
+ self._corner_delay_slider.connect('format-value',
+ self.__corner_delay_format_cb)
+ box_delay.pack_start(self._corner_delay_slider)
+ self._corner_delay_slider.show()
+ self._box_sliders.pack_start(box_delay, expand=False)
+ box_delay.show()
+
+ self._corner_delay_alert = InlineAlert()
+ label_delay_error = gtk.Label()
+ self._group.add_widget(label_delay_error)
+
+ delay_alert_box = gtk.HBox(spacing=style.DEFAULT_SPACING)
+ delay_alert_box.pack_start(label_delay_error, expand=False)
+ label_delay_error.show()
+ delay_alert_box.pack_start(self._corner_delay_alert, expand=False)
+ self._box_sliders.pack_start(delay_alert_box, expand=False)
+ delay_alert_box.show()
+ if 'corner_delay' in self.restart_alerts:
+ self._corner_delay_alert.props.msg = self.restart_msg
+ self._corner_delay_alert.show()
+
+ def _setup_edge(self):
+ box_delay = gtk.HBox(spacing=style.DEFAULT_SPACING)
+ label_delay = gtk.Label(_('Edge'))
+ label_delay.set_alignment(1, 0.75)
+ label_delay.modify_fg(gtk.STATE_NORMAL,
+ style.COLOR_SELECTION_GREY.get_gdk_color())
+ box_delay.pack_start(label_delay, expand=False)
+ self._group.add_widget(label_delay)
+ label_delay.show()
+
+ adj = gtk.Adjustment(value=100, lower=0, upper=_MAX_DELAY,
+ step_incr=100, page_incr=100, page_size=0)
+ self._edge_delay_slider = gtk.HScale(adj)
+ self._edge_delay_slider.set_digits(0)
+ self._edge_delay_slider.connect('format-value',
+ self.__edge_delay_format_cb)
+ box_delay.pack_start(self._edge_delay_slider)
+ self._edge_delay_slider.show()
+ self._box_sliders.pack_start(box_delay, expand=False)
+ box_delay.show()
+
+ self._edge_delay_alert = InlineAlert()
+ label_delay_error = gtk.Label()
+ self._group.add_widget(label_delay_error)
+
+ delay_alert_box = gtk.HBox(spacing=style.DEFAULT_SPACING)
+ delay_alert_box.pack_start(label_delay_error, expand=False)
+ label_delay_error.show()
+ delay_alert_box.pack_start(self._edge_delay_alert, expand=False)
+ self._box_sliders.pack_start(delay_alert_box, expand=False)
+ delay_alert_box.show()
+ if 'edge_delay' in self.restart_alerts:
+ self._edge_delay_alert.props.msg = self.restart_msg
+ self._edge_delay_alert.show()
+
+ def setup(self):
+ self._corner_delay_slider.set_value(self._model.get_corner_delay())
+ self._edge_delay_slider.set_value(self._model.get_edge_delay())
+ self._corner_delay_is_valid = True
+ self._edge_delay_is_valid = True
+ self.needs_restart = False
+ self._corner_delay_change_handler = self._corner_delay_slider.connect(
+ 'value-changed', self.__corner_delay_changed_cb)
+ self._edge_delay_change_handler = self._edge_delay_slider.connect(
+ 'value-changed', self.__edge_delay_changed_cb)
+
+ def undo(self):
+ self._corner_delay_slider.disconnect(self._corner_delay_change_handler)
+ self._edge_delay_slider.disconnect(self._edge_delay_change_handler)
+ self._model.undo()
+ self._corner_delay_alert.hide()
+ self._edge_delay_alert.hide()
+
+ def _validate(self):
+ if self._edge_delay_is_valid and self._corner_delay_is_valid:
+ self.props.is_valid = True
+ else:
+ self.props.is_valid = False
+
+ def __corner_delay_changed_cb(self, scale, data=None):
+ if self._corner_delay_sid:
+ gobject.source_remove(self._corner_delay_sid)
+ self._corner_delay_sid = gobject.timeout_add( \
+ self._APPLY_TIMEOUT, self.__corner_delay_timeout_cb, scale)
+
+ def __corner_delay_timeout_cb(self, scale):
+ self._corner_delay_sid = 0
+ if scale.get_value() == self._model.get_corner_delay():
+ return
+ try:
+ self._model.set_corner_delay(scale.get_value())
+ except ValueError, detail:
+ self._corner_delay_alert.props.msg = detail
+ self._corner_delay_is_valid = False
+ else:
+ self._corner_delay_alert.props.msg = self.restart_msg
+ self._corner_delay_is_valid = True
+ self.needs_restart = True
+ self.restart_alerts.append('corner_delay')
+
+ self._validate()
+ self._corner_delay_alert.show()
+ return False
+
+ def __corner_delay_format_cb(self, scale, value):
+ if value == _MAX_DELAY:
+ return _never
+ elif value == 0:
+ return _instantaneous
+ else:
+ return _seconds_label % (value / _MAX_DELAY)
+
+ def __edge_delay_changed_cb(self, scale, data=None):
+ if self._edge_delay_sid:
+ gobject.source_remove(self._edge_delay_sid)
+ self._edge_delay_sid = gobject.timeout_add( \
+ self._APPLY_TIMEOUT, self.__edge_delay_timeout_cb, scale)
+
+ def __edge_delay_timeout_cb(self, scale):
+ self._edge_delay_sid = 0
+ if scale.get_value() == self._model.get_edge_delay():
+ return
+ try:
+ self._model.set_edge_delay(scale.get_value())
+ except ValueError, detail:
+ self._edge_delay_alert.props.msg = detail
+ self._edge_delay_is_valid = False
+ else:
+ self._edge_delay_alert.props.msg = self.restart_msg
+ self._edge_delay_is_valid = True
+ self.needs_restart = True
+ self.restart_alerts.append('edge_delay')
+
+ self._validate()
+ self._edge_delay_alert.show()
+ return False
+
+ def __edge_delay_format_cb(self, scale, value):
+ if value == _MAX_DELAY:
+ return _never
+ elif value == 0:
+ return _instantaneous
+ else:
+ return _seconds_label % (value / _MAX_DELAY)
diff --git a/extensions/cpsection/keyboard/Makefile.am b/extensions/cpsection/keyboard/Makefile.am
new file mode 100644
index 0000000..7a95da5
--- /dev/null
+++ b/extensions/cpsection/keyboard/Makefile.am
@@ -0,0 +1,6 @@
+sugardir = $(pkgdatadir)/extensions/cpsection/keyboard
+
+sugar_PYTHON = \
+ __init__.py \
+ model.py \
+ view.py
diff --git a/extensions/cpsection/keyboard/Makefile.in b/extensions/cpsection/keyboard/Makefile.in
new file mode 100644
index 0000000..08f36cd
--- /dev/null
+++ b/extensions/cpsection/keyboard/Makefile.in
@@ -0,0 +1,442 @@
+# Makefile.in generated by automake 1.11.3 from Makefile.am.
+# @configure_input@
+
+# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002,
+# 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011 Free Software
+# Foundation, Inc.
+# This Makefile.in is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
+# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
+# PARTICULAR PURPOSE.
+
+@SET_MAKE@
+VPATH = @srcdir@
+pkgdatadir = $(datadir)/@PACKAGE@
+pkgincludedir = $(includedir)/@PACKAGE@
+pkglibdir = $(libdir)/@PACKAGE@
+pkglibexecdir = $(libexecdir)/@PACKAGE@
+am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd
+install_sh_DATA = $(install_sh) -c -m 644
+install_sh_PROGRAM = $(install_sh) -c
+install_sh_SCRIPT = $(install_sh) -c
+INSTALL_HEADER = $(INSTALL_DATA)
+transform = $(program_transform_name)
+NORMAL_INSTALL = :
+PRE_INSTALL = :
+POST_INSTALL = :
+NORMAL_UNINSTALL = :
+PRE_UNINSTALL = :
+POST_UNINSTALL = :
+subdir = extensions/cpsection/keyboard
+DIST_COMMON = $(srcdir)/Makefile.am $(srcdir)/Makefile.in \
+ $(sugar_PYTHON)
+ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
+am__aclocal_m4_deps = $(top_srcdir)/configure.ac
+am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
+ $(ACLOCAL_M4)
+mkinstalldirs = $(install_sh) -d
+CONFIG_CLEAN_FILES =
+CONFIG_CLEAN_VPATH_FILES =
+SOURCES =
+DIST_SOURCES =
+am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`;
+am__vpath_adj = case $$p in \
+ $(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \
+ *) f=$$p;; \
+ esac;
+am__strip_dir = f=`echo $$p | sed -e 's|^.*/||'`;
+am__install_max = 40
+am__nobase_strip_setup = \
+ srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*|]/\\\\&/g'`
+am__nobase_strip = \
+ for p in $$list; do echo "$$p"; done | sed -e "s|$$srcdirstrip/||"
+am__nobase_list = $(am__nobase_strip_setup); \
+ for p in $$list; do echo "$$p $$p"; done | \
+ sed "s| $$srcdirstrip/| |;"' / .*\//!s/ .*/ ./; s,\( .*\)/[^/]*$$,\1,' | \
+ $(AWK) 'BEGIN { files["."] = "" } { files[$$2] = files[$$2] " " $$1; \
+ if (++n[$$2] == $(am__install_max)) \
+ { print $$2, files[$$2]; n[$$2] = 0; files[$$2] = "" } } \
+ END { for (dir in files) print dir, files[dir] }'
+am__base_list = \
+ sed '$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;s/\n/ /g' | \
+ sed '$$!N;$$!N;$$!N;$$!N;s/\n/ /g'
+am__uninstall_files_from_dir = { \
+ test -z "$$files" \
+ || { test ! -d "$$dir" && test ! -f "$$dir" && test ! -r "$$dir"; } \
+ || { echo " ( cd '$$dir' && rm -f" $$files ")"; \
+ $(am__cd) "$$dir" && rm -f $$files; }; \
+ }
+am__py_compile = PYTHON=$(PYTHON) $(SHELL) $(py_compile)
+am__installdirs = "$(DESTDIR)$(sugardir)"
+py_compile = $(top_srcdir)/py-compile
+DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
+ACLOCAL = @ACLOCAL@
+ALL_LINGUAS = @ALL_LINGUAS@
+AMTAR = @AMTAR@
+AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@
+AUTOCONF = @AUTOCONF@
+AUTOHEADER = @AUTOHEADER@
+AUTOMAKE = @AUTOMAKE@
+AWK = @AWK@
+CATALOGS = @CATALOGS@
+CATOBJEXT = @CATOBJEXT@
+CC = @CC@
+CCDEPMODE = @CCDEPMODE@
+CFLAGS = @CFLAGS@
+CPP = @CPP@
+CPPFLAGS = @CPPFLAGS@
+CYGPATH_W = @CYGPATH_W@
+DATADIRNAME = @DATADIRNAME@
+DEFS = @DEFS@
+DEPDIR = @DEPDIR@
+ECHO_C = @ECHO_C@
+ECHO_N = @ECHO_N@
+ECHO_T = @ECHO_T@
+EGREP = @EGREP@
+EXEEXT = @EXEEXT@
+GCONFTOOL = @GCONFTOOL@
+GCONF_SCHEMA_CONFIG_SOURCE = @GCONF_SCHEMA_CONFIG_SOURCE@
+GCONF_SCHEMA_FILE_DIR = @GCONF_SCHEMA_FILE_DIR@
+GETTEXT_PACKAGE = @GETTEXT_PACKAGE@
+GMOFILES = @GMOFILES@
+GMSGFMT = @GMSGFMT@
+GREP = @GREP@
+INSTALL = @INSTALL@
+INSTALL_DATA = @INSTALL_DATA@
+INSTALL_PROGRAM = @INSTALL_PROGRAM@
+INSTALL_SCRIPT = @INSTALL_SCRIPT@
+INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@
+INSTOBJEXT = @INSTOBJEXT@
+INTLLIBS = @INTLLIBS@
+INTLTOOL_EXTRACT = @INTLTOOL_EXTRACT@
+INTLTOOL_MERGE = @INTLTOOL_MERGE@
+INTLTOOL_PERL = @INTLTOOL_PERL@
+INTLTOOL_UPDATE = @INTLTOOL_UPDATE@
+INTLTOOL_V_MERGE = @INTLTOOL_V_MERGE@
+INTLTOOL_V_MERGE_OPTIONS = @INTLTOOL_V_MERGE_OPTIONS@
+INTLTOOL__v_MERGE_ = @INTLTOOL__v_MERGE_@
+INTLTOOL__v_MERGE_0 = @INTLTOOL__v_MERGE_0@
+LDFLAGS = @LDFLAGS@
+LIBOBJS = @LIBOBJS@
+LIBS = @LIBS@
+LTLIBOBJS = @LTLIBOBJS@
+MAINT = @MAINT@
+MAKEINFO = @MAKEINFO@
+MKDIR_P = @MKDIR_P@
+MKINSTALLDIRS = @MKINSTALLDIRS@
+MSGFMT = @MSGFMT@
+MSGFMT_OPTS = @MSGFMT_OPTS@
+MSGMERGE = @MSGMERGE@
+OBJEXT = @OBJEXT@
+PACKAGE = @PACKAGE@
+PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@
+PACKAGE_NAME = @PACKAGE_NAME@
+PACKAGE_STRING = @PACKAGE_STRING@
+PACKAGE_TARNAME = @PACKAGE_TARNAME@
+PACKAGE_URL = @PACKAGE_URL@
+PACKAGE_VERSION = @PACKAGE_VERSION@
+PATH_SEPARATOR = @PATH_SEPARATOR@
+PKG_CONFIG = @PKG_CONFIG@
+PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@
+PKG_CONFIG_PATH = @PKG_CONFIG_PATH@
+POFILES = @POFILES@
+POSUB = @POSUB@
+PO_IN_DATADIR_FALSE = @PO_IN_DATADIR_FALSE@
+PO_IN_DATADIR_TRUE = @PO_IN_DATADIR_TRUE@
+PYTHON = @PYTHON@
+PYTHON_EXEC_PREFIX = @PYTHON_EXEC_PREFIX@
+PYTHON_PLATFORM = @PYTHON_PLATFORM@
+PYTHON_PREFIX = @PYTHON_PREFIX@
+PYTHON_VERSION = @PYTHON_VERSION@
+SET_MAKE = @SET_MAKE@
+SHELL = @SHELL@
+SHELL_CFLAGS = @SHELL_CFLAGS@
+SHELL_LIBS = @SHELL_LIBS@
+STRIP = @STRIP@
+SUCROSE_VERSION = @SUCROSE_VERSION@
+USE_NLS = @USE_NLS@
+VERSION = @VERSION@
+XGETTEXT = @XGETTEXT@
+abs_builddir = @abs_builddir@
+abs_srcdir = @abs_srcdir@
+abs_top_builddir = @abs_top_builddir@
+abs_top_srcdir = @abs_top_srcdir@
+ac_ct_CC = @ac_ct_CC@
+am__include = @am__include@
+am__leading_dot = @am__leading_dot@
+am__quote = @am__quote@
+am__tar = @am__tar@
+am__untar = @am__untar@
+bindir = @bindir@
+build_alias = @build_alias@
+builddir = @builddir@
+datadir = @datadir@
+datarootdir = @datarootdir@
+docdir = @docdir@
+dvidir = @dvidir@
+exec_prefix = @exec_prefix@
+host_alias = @host_alias@
+htmldir = @htmldir@
+includedir = @includedir@
+infodir = @infodir@
+install_sh = @install_sh@
+intltool__v_merge_options_ = @intltool__v_merge_options_@
+intltool__v_merge_options_0 = @intltool__v_merge_options_0@
+libdir = @libdir@
+libexecdir = @libexecdir@
+localedir = @localedir@
+localstatedir = @localstatedir@
+mandir = @mandir@
+mkdir_p = @mkdir_p@
+oldincludedir = @oldincludedir@
+pdfdir = @pdfdir@
+pkgpyexecdir = @pkgpyexecdir@
+pkgpythondir = @pkgpythondir@
+prefix = @prefix@
+program_transform_name = @program_transform_name@
+psdir = @psdir@
+pyexecdir = @pyexecdir@
+pythondir = @pythondir@
+sbindir = @sbindir@
+sharedstatedir = @sharedstatedir@
+srcdir = @srcdir@
+sysconfdir = @sysconfdir@
+target_alias = @target_alias@
+top_build_prefix = @top_build_prefix@
+top_builddir = @top_builddir@
+top_srcdir = @top_srcdir@
+sugardir = $(pkgdatadir)/extensions/cpsection/keyboard
+sugar_PYTHON = \
+ __init__.py \
+ model.py \
+ view.py
+
+all: all-am
+
+.SUFFIXES:
+$(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ $(srcdir)/Makefile.am $(am__configure_deps)
+ @for dep in $?; do \
+ case '$(am__configure_deps)' in \
+ *$$dep*) \
+ ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \
+ && { if test -f $@; then exit 0; else break; fi; }; \
+ exit 1;; \
+ esac; \
+ done; \
+ echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign extensions/cpsection/keyboard/Makefile'; \
+ $(am__cd) $(top_srcdir) && \
+ $(AUTOMAKE) --foreign extensions/cpsection/keyboard/Makefile
+.PRECIOUS: Makefile
+Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
+ @case '$?' in \
+ *config.status*) \
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \
+ *) \
+ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \
+ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \
+ esac;
+
+$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES)
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+
+$(top_srcdir)/configure: @MAINTAINER_MODE_TRUE@ $(am__configure_deps)
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+$(ACLOCAL_M4): @MAINTAINER_MODE_TRUE@ $(am__aclocal_m4_deps)
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+$(am__aclocal_m4_deps):
+install-sugarPYTHON: $(sugar_PYTHON)
+ @$(NORMAL_INSTALL)
+ test -z "$(sugardir)" || $(MKDIR_P) "$(DESTDIR)$(sugardir)"
+ @list='$(sugar_PYTHON)'; dlist=; list2=; test -n "$(sugardir)" || list=; \
+ for p in $$list; do \
+ if test -f "$$p"; then b=; else b="$(srcdir)/"; fi; \
+ if test -f $$b$$p; then \
+ $(am__strip_dir) \
+ dlist="$$dlist $$f"; \
+ list2="$$list2 $$b$$p"; \
+ else :; fi; \
+ done; \
+ for file in $$list2; do echo $$file; done | $(am__base_list) | \
+ while read files; do \
+ echo " $(INSTALL_DATA) $$files '$(DESTDIR)$(sugardir)'"; \
+ $(INSTALL_DATA) $$files "$(DESTDIR)$(sugardir)" || exit $$?; \
+ done || exit $$?; \
+ if test -n "$$dlist"; then \
+ $(am__py_compile) --destdir "$(DESTDIR)" \
+ --basedir "$(sugardir)" $$dlist; \
+ else :; fi
+
+uninstall-sugarPYTHON:
+ @$(NORMAL_UNINSTALL)
+ @list='$(sugar_PYTHON)'; test -n "$(sugardir)" || list=; \
+ files=`for p in $$list; do echo $$p; done | sed -e 's|^.*/||'`; \
+ test -n "$$files" || exit 0; \
+ dir='$(DESTDIR)$(sugardir)'; \
+ filesc=`echo "$$files" | sed 's|$$|c|'`; \
+ fileso=`echo "$$files" | sed 's|$$|o|'`; \
+ st=0; \
+ for files in "$$files" "$$filesc" "$$fileso"; do \
+ $(am__uninstall_files_from_dir) || st=$$?; \
+ done; \
+ exit $$st
+tags: TAGS
+TAGS:
+
+ctags: CTAGS
+CTAGS:
+
+
+distdir: $(DISTFILES)
+ @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
+ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
+ list='$(DISTFILES)'; \
+ dist_files=`for file in $$list; do echo $$file; done | \
+ sed -e "s|^$$srcdirstrip/||;t" \
+ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \
+ case $$dist_files in \
+ */*) $(MKDIR_P) `echo "$$dist_files" | \
+ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \
+ sort -u` ;; \
+ esac; \
+ for file in $$dist_files; do \
+ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \
+ if test -d $$d/$$file; then \
+ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \
+ if test -d "$(distdir)/$$file"; then \
+ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \
+ fi; \
+ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \
+ cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \
+ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \
+ fi; \
+ cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \
+ else \
+ test -f "$(distdir)/$$file" \
+ || cp -p $$d/$$file "$(distdir)/$$file" \
+ || exit 1; \
+ fi; \
+ done
+check-am: all-am
+check: check-am
+all-am: Makefile
+installdirs:
+ for dir in "$(DESTDIR)$(sugardir)"; do \
+ test -z "$$dir" || $(MKDIR_P) "$$dir"; \
+ done
+install: install-am
+install-exec: install-exec-am
+install-data: install-data-am
+uninstall: uninstall-am
+
+install-am: all-am
+ @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am
+
+installcheck: installcheck-am
+install-strip:
+ if test -z '$(STRIP)'; then \
+ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
+ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
+ install; \
+ else \
+ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
+ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
+ "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \
+ fi
+mostlyclean-generic:
+
+clean-generic:
+
+distclean-generic:
+ -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES)
+ -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES)
+
+maintainer-clean-generic:
+ @echo "This command is intended for maintainers to use"
+ @echo "it deletes files that may require special tools to rebuild."
+clean: clean-am
+
+clean-am: clean-generic mostlyclean-am
+
+distclean: distclean-am
+ -rm -f Makefile
+distclean-am: clean-am distclean-generic
+
+dvi: dvi-am
+
+dvi-am:
+
+html: html-am
+
+html-am:
+
+info: info-am
+
+info-am:
+
+install-data-am: install-sugarPYTHON
+
+install-dvi: install-dvi-am
+
+install-dvi-am:
+
+install-exec-am:
+
+install-html: install-html-am
+
+install-html-am:
+
+install-info: install-info-am
+
+install-info-am:
+
+install-man:
+
+install-pdf: install-pdf-am
+
+install-pdf-am:
+
+install-ps: install-ps-am
+
+install-ps-am:
+
+installcheck-am:
+
+maintainer-clean: maintainer-clean-am
+ -rm -f Makefile
+maintainer-clean-am: distclean-am maintainer-clean-generic
+
+mostlyclean: mostlyclean-am
+
+mostlyclean-am: mostlyclean-generic
+
+pdf: pdf-am
+
+pdf-am:
+
+ps: ps-am
+
+ps-am:
+
+uninstall-am: uninstall-sugarPYTHON
+
+.MAKE: install-am install-strip
+
+.PHONY: all all-am check check-am clean clean-generic distclean \
+ distclean-generic distdir dvi dvi-am html html-am info info-am \
+ install install-am install-data install-data-am install-dvi \
+ install-dvi-am install-exec install-exec-am install-html \
+ install-html-am install-info install-info-am install-man \
+ install-pdf install-pdf-am install-ps install-ps-am \
+ install-strip install-sugarPYTHON installcheck installcheck-am \
+ installdirs maintainer-clean maintainer-clean-generic \
+ mostlyclean mostlyclean-generic pdf pdf-am ps ps-am uninstall \
+ uninstall-am uninstall-sugarPYTHON
+
+
+# Tell versions [3.59,3.63) of GNU make to not export all variables.
+# Otherwise a system limit (for SysV at least) may be exceeded.
+.NOEXPORT:
diff --git a/extensions/cpsection/keyboard/__init__.py b/extensions/cpsection/keyboard/__init__.py
new file mode 100644
index 0000000..065086c
--- /dev/null
+++ b/extensions/cpsection/keyboard/__init__.py
@@ -0,0 +1,21 @@
+# Copyright (C) 2009, OLPC
+#
+# 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 2 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, write to the Free Software
+# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+
+from gettext import gettext as _
+
+CLASS = 'Keyboard'
+ICON = 'module-keyboard'
+TITLE = _('Keyboard')
diff --git a/extensions/cpsection/keyboard/model.py b/extensions/cpsection/keyboard/model.py
new file mode 100644
index 0000000..1f92973
--- /dev/null
+++ b/extensions/cpsection/keyboard/model.py
@@ -0,0 +1,169 @@
+# Copyright (C) 2009 OLPC
+# Author: Sayamindu Dasgupta <sayamindu@laptop.org>
+#
+# 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 2 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, write to the Free Software
+# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+#
+
+import xklavier
+import gconf
+
+
+_GROUP_NAME = 'grp' # The XKB name for group switch options
+
+_LAYOUTS_KEY = '/desktop/sugar/peripherals/keyboard/layouts'
+_OPTIONS_KEY = '/desktop/sugar/peripherals/keyboard/options'
+_MODEL_KEY = '/desktop/sugar/peripherals/keyboard/model'
+
+
+class KeyboardManager(object):
+ def __init__(self, display):
+ self._engine = xklavier.Engine(display)
+ self._configregistry = xklavier.ConfigRegistry(self._engine)
+ self._configregistry.load(False)
+ self._configrec = xklavier.ConfigRec()
+ self._configrec.get_from_server(self._engine)
+
+ self._gconf_client = gconf.client_get_default()
+
+ def _populate_one(self, config_registry, item, store):
+ store.append([item.get_description(), item.get_name()])
+
+ def _populate_two(self, config_registry, item, subitem, store):
+ layout = item.get_name()
+ if subitem:
+ description = '%s, %s' % (subitem.get_description(), \
+ item.get_description())
+ variant = subitem.get_name()
+ else:
+ description = 'Default layout, %s' % item.get_description()
+ variant = ''
+
+ store.append([description, ('%s(%s)' % (layout, variant))])
+
+ def get_models(self):
+ """Return list of supported keyboard models"""
+ models = []
+ self._configregistry.foreach_model(self._populate_one, models)
+ models.sort()
+ return models
+
+ def get_languages(self):
+ """Return list of supported keyboard languages"""
+ languages = []
+ self._configregistry.foreach_language(self._populate_one, languages)
+ languages.sort()
+ return languages
+
+ def get_layouts_for_language(self, language):
+ """Return list of supported keyboard layouts for a given language"""
+ layouts = []
+ self._configregistry.foreach_language_variant(language, \
+ self._populate_two, layouts)
+ layouts.sort()
+ return layouts
+
+ def get_options_group(self):
+ """Return list of supported options for switching keyboard group"""
+ options = []
+ self._configregistry.foreach_option(_GROUP_NAME, self._populate_one,
+ options)
+ options.sort()
+ return options
+
+ def get_current_model(self):
+ """Return the enabled keyboard model"""
+ model = self._gconf_client.get_string(_MODEL_KEY)
+ if model:
+ return model
+ else:
+ model = self._configrec.get_model()
+ self.set_model(model)
+ return model
+
+ def get_current_layouts(self):
+ """Return the enabled keyboard layouts with variants"""
+ layouts = self._gconf_client.get_list(_LAYOUTS_KEY, gconf.VALUE_STRING)
+ if layouts:
+ return layouts
+
+ layouts = self._configrec.get_layouts()
+ variants = self._configrec.get_variants()
+
+ layout_list = []
+ i = 0
+ for layout in layouts:
+ if len(variants) <= i or variants[i] == '':
+ layout_list.append('%s(%s)' % (layout, ''))
+ else:
+ layout_list.append('%s(%s)' % (layout, variants[i]))
+ i += 1
+
+ self.set_layouts(layout_list)
+
+ return layout_list
+
+ def get_current_option_group(self):
+ """Return the enabled option for switching keyboard group"""
+ options = self._gconf_client.get_list(_OPTIONS_KEY, gconf.VALUE_STRING)
+
+ if not options:
+ options = self._configrec.get_options()
+ self.set_option_group(options)
+
+ for option in options:
+ if option.startswith(_GROUP_NAME):
+ return option
+
+ return None
+
+ def get_max_layouts(self):
+ """Return the maximum number of layouts supported simultaneously"""
+ return self._engine.get_max_num_groups()
+
+ def set_model(self, model):
+ """Sets the supplied keyboard model"""
+ if model is None or not model:
+ return
+ self._gconf_client.set_string(_MODEL_KEY, model)
+ self._configrec.set_model(model)
+ self._configrec.activate(self._engine)
+
+ def set_option_group(self, option_group):
+ """Sets the supplied option for switching keyboard group"""
+ #XXX: Merge, not overwrite previous options
+ if not option_group:
+ options = ['']
+ elif isinstance(option_group, list):
+ options = option_group
+ else:
+ options = [option_group]
+ self._gconf_client.set_list(_OPTIONS_KEY, gconf.VALUE_STRING, options)
+ self._configrec.set_options(options)
+ self._configrec.activate(self._engine)
+
+ def set_layouts(self, layouts):
+ """Sets the supplied keyboard layouts (with variants)"""
+ if layouts is None or not layouts:
+ return
+ self._gconf_client.set_list(_LAYOUTS_KEY, gconf.VALUE_STRING, layouts)
+ layouts_list = []
+ variants_list = []
+ for layout in layouts:
+ layouts_list.append(layout.split('(')[0])
+ variants_list.append(layout.split('(')[1][:-1])
+
+ self._configrec.set_layouts(layouts_list)
+ self._configrec.set_variants(variants_list)
+ self._configrec.activate(self._engine)
diff --git a/extensions/cpsection/keyboard/view.py b/extensions/cpsection/keyboard/view.py
new file mode 100644
index 0000000..e349255
--- /dev/null
+++ b/extensions/cpsection/keyboard/view.py
@@ -0,0 +1,425 @@
+# Copyright (C) 2009, OLPC
+# Author: Sayamindu Dasgupta <sayamindu@laptop.org>
+#
+# 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 2 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, write to the Free Software
+# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+
+import gtk
+import gobject
+import pango
+import logging
+from gettext import gettext as _
+
+from sugar.graphics import style
+from sugar.graphics.icon import Icon
+
+from jarabe.controlpanel.sectionview import SectionView
+
+
+CLASS = 'Language'
+ICON = 'module-keyboard'
+TITLE = _('Keyboard')
+
+_APPLY_TIMEOUT = 500
+
+#TODO: This cpsection adds checks for xklavier in bin/sugar-session and
+# src/jarabe/controlpanel/gui.py. We should get rid of these checks
+# once python-xklavier has been packaged for all major distributions
+# For more information, see: http://dev.sugarlabs.org/ticket/407
+
+
+class LayoutCombo(gtk.HBox):
+
+ """
+ Custom GTK widget with two comboboxes side by side, one for layout, and
+ the other for variants for the selected layout.
+ """
+
+ __gsignals__ = {
+ 'selection-changed': (gobject.SIGNAL_RUN_LAST, gobject.TYPE_NONE,
+ (gobject.TYPE_STRING, gobject.TYPE_INT)),
+ }
+
+ def __init__(self, keyboard_manager, n):
+ gtk.HBox.__init__(self)
+ self._keyboard_manager = keyboard_manager
+ self._index = n
+
+ self.set_border_width(style.DEFAULT_SPACING)
+ self.set_spacing(style.DEFAULT_SPACING)
+
+ label = gtk.Label(' <b>%s</b> ' % str(n + 1))
+ label.set_use_markup(True)
+ label.modify_fg(gtk.STATE_NORMAL,
+ style.COLOR_SELECTION_GREY.get_gdk_color())
+ label.set_alignment(0.5, 0.5)
+ self.pack_start(label, expand=False)
+
+ self._klang_store = gtk.ListStore(gobject.TYPE_STRING, \
+ gobject.TYPE_STRING)
+ for description, name in self._keyboard_manager.get_languages():
+ self._klang_store.append([name, description])
+
+ self._klang_combo = gtk.ComboBox(model=self._klang_store)
+ self._klang_combo_changed_id = \
+ self._klang_combo.connect('changed', self._klang_combo_changed_cb)
+ cell = gtk.CellRendererText()
+ cell.props.ellipsize = pango.ELLIPSIZE_MIDDLE
+ cell.props.ellipsize_set = True
+ self._klang_combo.pack_start(cell)
+ self._klang_combo.add_attribute(cell, 'text', 1)
+ self.pack_start(self._klang_combo, expand=True, fill=True)
+
+ self._kvariant_store = None
+ self._kvariant_combo = gtk.ComboBox(model=None)
+ self._kvariant_combo_changed_id = \
+ self._kvariant_combo.connect('changed', \
+ self._kvariant_combo_changed_cb)
+ cell = gtk.CellRendererText()
+ cell.props.ellipsize = pango.ELLIPSIZE_MIDDLE
+ cell.props.ellipsize_set = True
+ self._kvariant_combo.pack_start(cell)
+ self._kvariant_combo.add_attribute(cell, 'text', 1)
+ self.pack_start(self._kvariant_combo, expand=True, fill=True)
+
+ self._klang_combo.set_active(self._index)
+
+ def select_layout(self, layout):
+ """Select a given keyboard layout and show appropriate variants"""
+ self._kvariant_combo.handler_block(self._kvariant_combo_changed_id)
+ for i in range(0, len(self._klang_store)):
+ self._klang_combo.set_active(i)
+ for j in range(0, len(self._kvariant_store)):
+ if self._kvariant_store[j][0] == layout:
+ self._kvariant_combo.set_active(j)
+ self._kvariant_combo.handler_unblock(\
+ self._kvariant_combo_changed_id)
+ return True
+
+ self._kvariant_combo.handler_unblock(self._kvariant_combo_changed_id)
+ self._klang_combo.set_active(0)
+ return False
+
+ def get_layout(self):
+ """Gets the selected layout (with variant)"""
+ it = self._kvariant_combo.get_active_iter()
+ model = self._kvariant_combo.get_model()
+ return model.get(it, 0)[0]
+
+ def _set_kvariant_store(self, lang):
+ self._kvariant_store = gtk.ListStore(gobject.TYPE_STRING, \
+ gobject.TYPE_STRING)
+ layouts = self._keyboard_manager.get_layouts_for_language(lang)
+ for description, name in layouts:
+ self._kvariant_store.append([name, description])
+ self._kvariant_combo.set_model(self._kvariant_store)
+ self._kvariant_combo.set_active(0)
+
+ def _klang_combo_changed_cb(self, combobox):
+ it = combobox.get_active_iter()
+ model = combobox.get_model()
+ lang = model.get(it, 0)[0]
+ self._set_kvariant_store(lang)
+
+ def _kvariant_combo_changed_cb(self, combobox):
+ it = combobox.get_active_iter()
+ model = combobox.get_model()
+ layout = model.get(it, 0)[0]
+ self.emit('selection-changed', layout, self._index)
+
+
+class Keyboard(SectionView):
+ def __init__(self, model, alerts):
+ SectionView.__init__(self)
+
+ self._model = model
+
+ self._kmodel = None
+ self._selected_kmodel = None
+
+ self._klayouts = []
+ self._selected_klayouts = []
+
+ self._group_switch_option = None
+ self._selected_group_switch_option = None
+
+ self.set_border_width(style.DEFAULT_SPACING * 2)
+ self.set_spacing(style.DEFAULT_SPACING)
+
+ self._layout_table = gtk.Table(rows=4, columns=2, homogeneous=False)
+
+ self._keyboard_manager = model.KeyboardManager(self.get_display())
+ self._layout_combo_list = []
+ self._layout_addremovebox_list = []
+
+ scrollwindow = gtk.ScrolledWindow()
+ scrollwindow.set_policy(gtk.POLICY_NEVER, gtk.POLICY_AUTOMATIC)
+ self.pack_start(scrollwindow, expand=True)
+ scrollwindow.show()
+
+ self._vbox = gtk.VBox()
+ scrollwindow.add_with_viewport(self._vbox)
+
+ self.__kmodel_sid = None
+ self.__layout_sid = None
+ self.__group_switch_sid = None
+
+ self._setup_kmodel()
+ self._setup_layouts()
+ self._setup_group_switch_option()
+
+ self._vbox.show()
+
+ def _setup_kmodel(self):
+ """Adds the controls for changing the keyboard model"""
+ separator_kmodel = gtk.HSeparator()
+ self._vbox.pack_start(separator_kmodel, expand=False)
+ separator_kmodel.show_all()
+
+ label_kmodel = gtk.Label(_('Keyboard Model'))
+ label_kmodel.set_alignment(0, 0)
+ self._vbox.pack_start(label_kmodel, expand=False)
+ label_kmodel.show_all()
+
+ box_kmodel = gtk.VBox()
+ box_kmodel.set_border_width(style.DEFAULT_SPACING * 2)
+ box_kmodel.set_spacing(style.DEFAULT_SPACING)
+
+ kmodel_store = gtk.ListStore(gobject.TYPE_STRING, \
+ gobject.TYPE_STRING)
+ for description, name in self._keyboard_manager.get_models():
+ kmodel_store.append([name, description])
+
+ kmodel_combo = gtk.ComboBox(model=kmodel_store)
+ cell = gtk.CellRendererText()
+ cell.props.ellipsize = pango.ELLIPSIZE_MIDDLE
+ cell.props.ellipsize_set = True
+ kmodel_combo.pack_start(cell)
+ kmodel_combo.add_attribute(cell, 'text', 1)
+
+ self._kmodel = self._keyboard_manager.get_current_model()
+ if self._kmodel is not None:
+ for row in kmodel_store:
+ if self._kmodel in row[0]:
+ kmodel_combo.set_active_iter(row.iter)
+ break
+
+ box_kmodel.pack_start(kmodel_combo, expand=False)
+ self._vbox.pack_start(box_kmodel, expand=False)
+ box_kmodel.show_all()
+
+ kmodel_combo.connect('changed', self.__kmodel_changed_cb)
+
+ def __kmodel_changed_cb(self, combobox):
+ if self.__kmodel_sid is not None:
+ gobject.source_remove(self.__kmodel_sid)
+ self.__kmodel_sid = gobject.timeout_add(_APPLY_TIMEOUT,
+ self.__kmodel_timeout_cb, combobox)
+
+ def __kmodel_timeout_cb(self, combobox):
+ it = combobox.get_active_iter()
+ model = combobox.get_model()
+ self._selected_kmodel = model.get(it, 0)[0]
+ if self._selected_kmodel == self._keyboard_manager.get_current_model():
+ return
+ try:
+ self._keyboard_manager.set_model(self._selected_kmodel)
+ except Exception:
+ logging.exception('Could not set new keyboard model')
+
+ return False
+
+ def _setup_group_switch_option(self):
+ """Adds the controls for changing the group switch option of keyboard
+ """
+ separator_group_option = gtk.HSeparator()
+ self._vbox.pack_start(separator_group_option, expand=False)
+ separator_group_option.show_all()
+
+ label_group_option = gtk.Label(_('Key(s) to change layout'))
+ label_group_option.set_alignment(0, 0)
+ self._vbox.pack_start(label_group_option, expand=False)
+ label_group_option.show_all()
+
+ box_group_option = gtk.VBox()
+ box_group_option.set_border_width(style.DEFAULT_SPACING * 2)
+ box_group_option.set_spacing(style.DEFAULT_SPACING)
+
+ group_option_store = gtk.ListStore(gobject.TYPE_STRING, \
+ gobject.TYPE_STRING)
+ for description, name in self._keyboard_manager.get_options_group():
+ group_option_store.append([name, description])
+
+ group_option_combo = gtk.ComboBox(model=group_option_store)
+ cell = gtk.CellRendererText()
+ cell.props.ellipsize = pango.ELLIPSIZE_MIDDLE
+ cell.props.ellipsize_set = True
+ group_option_combo.pack_start(cell)
+ group_option_combo.add_attribute(cell, 'text', 1)
+
+ self._group_switch_option = \
+ self._keyboard_manager.get_current_option_group()
+ if not self._group_switch_option:
+ group_option_combo.set_active(0)
+ else:
+ found = False
+ for row in group_option_store:
+ if self._group_switch_option in row[0]:
+ group_option_combo.set_active_iter(row.iter)
+ found = True
+ break
+ if not found:
+ group_option_combo.set_active(0)
+
+ box_group_option.pack_start(group_option_combo, expand=False)
+ self._vbox.pack_start(box_group_option, expand=False)
+ box_group_option.show_all()
+
+ group_option_combo.connect('changed', \
+ self.__group_switch_changed_cb)
+
+ def __group_switch_changed_cb(self, combobox):
+ if self.__group_switch_sid is not None:
+ gobject.source_remove(self.__group_switch_sid)
+ self.__group_switch_sid = gobject.timeout_add(_APPLY_TIMEOUT,
+ self.__group_switch_timeout_cb, combobox)
+
+ def __group_switch_timeout_cb(self, combobox):
+ it = combobox.get_active_iter()
+ model = combobox.get_model()
+ self._selected_group_switch_option = model.get(it, 0)[0]
+ if self._selected_group_switch_option == \
+ self._keyboard_manager.get_current_option_group():
+ return
+ try:
+ self._keyboard_manager.set_option_group(\
+ self._selected_group_switch_option)
+ except Exception:
+ logging.exception('Could not set new keyboard group switch option')
+
+ return False
+
+ def _setup_layouts(self):
+ """Adds the controls for changing the keyboard layouts"""
+ separator_klayout = gtk.HSeparator()
+ self._vbox.pack_start(separator_klayout, expand=False)
+ separator_klayout.show_all()
+
+ label_klayout = gtk.Label(_('Keyboard Layout(s)'))
+ label_klayout.set_alignment(0, 0)
+ label_klayout.show_all()
+ self._vbox.pack_start(label_klayout, expand=False)
+
+ self._klayouts = self._keyboard_manager.get_current_layouts()
+ for i in range(0, self._keyboard_manager.get_max_layouts()):
+ add_remove_box = self.__create_add_remove_box()
+ self._layout_addremovebox_list.append(add_remove_box)
+ self._layout_table.attach(add_remove_box, 1, 2, i, i + 1)
+
+ layout_combo = LayoutCombo(self._keyboard_manager, i)
+ layout_combo.connect('selection-changed', \
+ self.__layout_combo_selection_changed_cb)
+ self._layout_combo_list.append(layout_combo)
+ self._layout_table.attach(layout_combo, 0, 1, i, i + 1)
+
+ if i < len(self._klayouts):
+ layout_combo.show_all()
+ layout_combo.select_layout(self._klayouts[i])
+
+ self._vbox.pack_start(self._layout_table, expand=False)
+ self._layout_table.set_size_request(self._vbox.size_request()[0], -1)
+ self._layout_table.show()
+ self._update_klayouts()
+
+ def __determine_add_remove_box_visibility(self):
+ i = 1
+ for box in self._layout_addremovebox_list:
+ if not i == len(self._selected_klayouts):
+ box.props.visible = False
+ else:
+ box.show_all()
+ if i == 1:
+ # First row - no need for showing remove btn
+ add, remove = box.get_children()
+ remove.props.visible = False
+ if i == self._keyboard_manager.get_max_layouts():
+ # Last row - no need for showing add btn
+ add, remove = box.get_children()
+ add.props.visible = False
+ i += 1
+
+ def __create_add_remove_box(self):
+ """Creates gtk.Hbox with add/remove buttons"""
+ add_icon = Icon(icon_name='list-add')
+
+ add_button = gtk.Button()
+ add_button.set_image(add_icon)
+ add_button.connect('clicked',
+ self.__add_button_clicked_cb)
+
+ remove_icon = Icon(icon_name='list-remove')
+ remove_button = gtk.Button()
+ remove_button.set_image(remove_icon)
+ remove_button.connect('clicked',
+ self.__remove_button_clicked_cb)
+
+ add_remove_box = gtk.HButtonBox()
+ add_remove_box.set_layout(gtk.BUTTONBOX_START)
+ add_remove_box.set_spacing(10)
+ add_remove_box.pack_start(add_button)
+ add_remove_box.pack_start(remove_button)
+
+ return add_remove_box
+
+ def __layout_combo_selection_changed_cb(self, combo, layout, index):
+ self._update_klayouts()
+
+ def __add_button_clicked_cb(self, button):
+ self._layout_combo_list[len(self._selected_klayouts)].show_all()
+ self._update_klayouts()
+
+ def __remove_button_clicked_cb(self, button):
+ self._layout_combo_list[len(self._selected_klayouts) - 1].hide()
+ self._update_klayouts()
+
+ def _update_klayouts(self):
+ """Responds to any changes in the keyboard layout options"""
+ self._selected_klayouts = []
+ for combo in self._layout_combo_list:
+ if combo.props.visible:
+ self._selected_klayouts.append(combo.get_layout())
+
+ self.__determine_add_remove_box_visibility()
+
+ if self.__layout_sid is not None:
+ gobject.source_remove(self.__layout_sid)
+ self.__layout_sid = gobject.timeout_add(_APPLY_TIMEOUT,
+ self.__layout_timeout_cb)
+
+ def __layout_timeout_cb(self):
+ if self._selected_klayouts == \
+ self._keyboard_manager.get_current_layouts():
+ return
+ try:
+ self._keyboard_manager.set_layouts(self._selected_klayouts)
+ except Exception:
+ logging.exception('Could not set new keyboard layouts')
+
+ return False
+
+ def undo(self):
+ """Reverts back to the original keyboard configuration"""
+ self._keyboard_manager.set_model(self._kmodel)
+ self._keyboard_manager.set_layouts(self._klayouts)
+ self._keyboard_manager.set_option_group(self._group_switch_option)
diff --git a/extensions/cpsection/language/Makefile.am b/extensions/cpsection/language/Makefile.am
new file mode 100644
index 0000000..209fc32
--- /dev/null
+++ b/extensions/cpsection/language/Makefile.am
@@ -0,0 +1,6 @@
+sugardir = $(pkgdatadir)/extensions/cpsection/language
+
+sugar_PYTHON = \
+ __init__.py \
+ model.py \
+ view.py
diff --git a/extensions/cpsection/language/Makefile.in b/extensions/cpsection/language/Makefile.in
new file mode 100644
index 0000000..9028190
--- /dev/null
+++ b/extensions/cpsection/language/Makefile.in
@@ -0,0 +1,442 @@
+# Makefile.in generated by automake 1.11.3 from Makefile.am.
+# @configure_input@
+
+# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002,
+# 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011 Free Software
+# Foundation, Inc.
+# This Makefile.in is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
+# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
+# PARTICULAR PURPOSE.
+
+@SET_MAKE@
+VPATH = @srcdir@
+pkgdatadir = $(datadir)/@PACKAGE@
+pkgincludedir = $(includedir)/@PACKAGE@
+pkglibdir = $(libdir)/@PACKAGE@
+pkglibexecdir = $(libexecdir)/@PACKAGE@
+am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd
+install_sh_DATA = $(install_sh) -c -m 644
+install_sh_PROGRAM = $(install_sh) -c
+install_sh_SCRIPT = $(install_sh) -c
+INSTALL_HEADER = $(INSTALL_DATA)
+transform = $(program_transform_name)
+NORMAL_INSTALL = :
+PRE_INSTALL = :
+POST_INSTALL = :
+NORMAL_UNINSTALL = :
+PRE_UNINSTALL = :
+POST_UNINSTALL = :
+subdir = extensions/cpsection/language
+DIST_COMMON = $(srcdir)/Makefile.am $(srcdir)/Makefile.in \
+ $(sugar_PYTHON)
+ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
+am__aclocal_m4_deps = $(top_srcdir)/configure.ac
+am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
+ $(ACLOCAL_M4)
+mkinstalldirs = $(install_sh) -d
+CONFIG_CLEAN_FILES =
+CONFIG_CLEAN_VPATH_FILES =
+SOURCES =
+DIST_SOURCES =
+am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`;
+am__vpath_adj = case $$p in \
+ $(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \
+ *) f=$$p;; \
+ esac;
+am__strip_dir = f=`echo $$p | sed -e 's|^.*/||'`;
+am__install_max = 40
+am__nobase_strip_setup = \
+ srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*|]/\\\\&/g'`
+am__nobase_strip = \
+ for p in $$list; do echo "$$p"; done | sed -e "s|$$srcdirstrip/||"
+am__nobase_list = $(am__nobase_strip_setup); \
+ for p in $$list; do echo "$$p $$p"; done | \
+ sed "s| $$srcdirstrip/| |;"' / .*\//!s/ .*/ ./; s,\( .*\)/[^/]*$$,\1,' | \
+ $(AWK) 'BEGIN { files["."] = "" } { files[$$2] = files[$$2] " " $$1; \
+ if (++n[$$2] == $(am__install_max)) \
+ { print $$2, files[$$2]; n[$$2] = 0; files[$$2] = "" } } \
+ END { for (dir in files) print dir, files[dir] }'
+am__base_list = \
+ sed '$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;s/\n/ /g' | \
+ sed '$$!N;$$!N;$$!N;$$!N;s/\n/ /g'
+am__uninstall_files_from_dir = { \
+ test -z "$$files" \
+ || { test ! -d "$$dir" && test ! -f "$$dir" && test ! -r "$$dir"; } \
+ || { echo " ( cd '$$dir' && rm -f" $$files ")"; \
+ $(am__cd) "$$dir" && rm -f $$files; }; \
+ }
+am__py_compile = PYTHON=$(PYTHON) $(SHELL) $(py_compile)
+am__installdirs = "$(DESTDIR)$(sugardir)"
+py_compile = $(top_srcdir)/py-compile
+DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
+ACLOCAL = @ACLOCAL@
+ALL_LINGUAS = @ALL_LINGUAS@
+AMTAR = @AMTAR@
+AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@
+AUTOCONF = @AUTOCONF@
+AUTOHEADER = @AUTOHEADER@
+AUTOMAKE = @AUTOMAKE@
+AWK = @AWK@
+CATALOGS = @CATALOGS@
+CATOBJEXT = @CATOBJEXT@
+CC = @CC@
+CCDEPMODE = @CCDEPMODE@
+CFLAGS = @CFLAGS@
+CPP = @CPP@
+CPPFLAGS = @CPPFLAGS@
+CYGPATH_W = @CYGPATH_W@
+DATADIRNAME = @DATADIRNAME@
+DEFS = @DEFS@
+DEPDIR = @DEPDIR@
+ECHO_C = @ECHO_C@
+ECHO_N = @ECHO_N@
+ECHO_T = @ECHO_T@
+EGREP = @EGREP@
+EXEEXT = @EXEEXT@
+GCONFTOOL = @GCONFTOOL@
+GCONF_SCHEMA_CONFIG_SOURCE = @GCONF_SCHEMA_CONFIG_SOURCE@
+GCONF_SCHEMA_FILE_DIR = @GCONF_SCHEMA_FILE_DIR@
+GETTEXT_PACKAGE = @GETTEXT_PACKAGE@
+GMOFILES = @GMOFILES@
+GMSGFMT = @GMSGFMT@
+GREP = @GREP@
+INSTALL = @INSTALL@
+INSTALL_DATA = @INSTALL_DATA@
+INSTALL_PROGRAM = @INSTALL_PROGRAM@
+INSTALL_SCRIPT = @INSTALL_SCRIPT@
+INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@
+INSTOBJEXT = @INSTOBJEXT@
+INTLLIBS = @INTLLIBS@
+INTLTOOL_EXTRACT = @INTLTOOL_EXTRACT@
+INTLTOOL_MERGE = @INTLTOOL_MERGE@
+INTLTOOL_PERL = @INTLTOOL_PERL@
+INTLTOOL_UPDATE = @INTLTOOL_UPDATE@
+INTLTOOL_V_MERGE = @INTLTOOL_V_MERGE@
+INTLTOOL_V_MERGE_OPTIONS = @INTLTOOL_V_MERGE_OPTIONS@
+INTLTOOL__v_MERGE_ = @INTLTOOL__v_MERGE_@
+INTLTOOL__v_MERGE_0 = @INTLTOOL__v_MERGE_0@
+LDFLAGS = @LDFLAGS@
+LIBOBJS = @LIBOBJS@
+LIBS = @LIBS@
+LTLIBOBJS = @LTLIBOBJS@
+MAINT = @MAINT@
+MAKEINFO = @MAKEINFO@
+MKDIR_P = @MKDIR_P@
+MKINSTALLDIRS = @MKINSTALLDIRS@
+MSGFMT = @MSGFMT@
+MSGFMT_OPTS = @MSGFMT_OPTS@
+MSGMERGE = @MSGMERGE@
+OBJEXT = @OBJEXT@
+PACKAGE = @PACKAGE@
+PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@
+PACKAGE_NAME = @PACKAGE_NAME@
+PACKAGE_STRING = @PACKAGE_STRING@
+PACKAGE_TARNAME = @PACKAGE_TARNAME@
+PACKAGE_URL = @PACKAGE_URL@
+PACKAGE_VERSION = @PACKAGE_VERSION@
+PATH_SEPARATOR = @PATH_SEPARATOR@
+PKG_CONFIG = @PKG_CONFIG@
+PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@
+PKG_CONFIG_PATH = @PKG_CONFIG_PATH@
+POFILES = @POFILES@
+POSUB = @POSUB@
+PO_IN_DATADIR_FALSE = @PO_IN_DATADIR_FALSE@
+PO_IN_DATADIR_TRUE = @PO_IN_DATADIR_TRUE@
+PYTHON = @PYTHON@
+PYTHON_EXEC_PREFIX = @PYTHON_EXEC_PREFIX@
+PYTHON_PLATFORM = @PYTHON_PLATFORM@
+PYTHON_PREFIX = @PYTHON_PREFIX@
+PYTHON_VERSION = @PYTHON_VERSION@
+SET_MAKE = @SET_MAKE@
+SHELL = @SHELL@
+SHELL_CFLAGS = @SHELL_CFLAGS@
+SHELL_LIBS = @SHELL_LIBS@
+STRIP = @STRIP@
+SUCROSE_VERSION = @SUCROSE_VERSION@
+USE_NLS = @USE_NLS@
+VERSION = @VERSION@
+XGETTEXT = @XGETTEXT@
+abs_builddir = @abs_builddir@
+abs_srcdir = @abs_srcdir@
+abs_top_builddir = @abs_top_builddir@
+abs_top_srcdir = @abs_top_srcdir@
+ac_ct_CC = @ac_ct_CC@
+am__include = @am__include@
+am__leading_dot = @am__leading_dot@
+am__quote = @am__quote@
+am__tar = @am__tar@
+am__untar = @am__untar@
+bindir = @bindir@
+build_alias = @build_alias@
+builddir = @builddir@
+datadir = @datadir@
+datarootdir = @datarootdir@
+docdir = @docdir@
+dvidir = @dvidir@
+exec_prefix = @exec_prefix@
+host_alias = @host_alias@
+htmldir = @htmldir@
+includedir = @includedir@
+infodir = @infodir@
+install_sh = @install_sh@
+intltool__v_merge_options_ = @intltool__v_merge_options_@
+intltool__v_merge_options_0 = @intltool__v_merge_options_0@
+libdir = @libdir@
+libexecdir = @libexecdir@
+localedir = @localedir@
+localstatedir = @localstatedir@
+mandir = @mandir@
+mkdir_p = @mkdir_p@
+oldincludedir = @oldincludedir@
+pdfdir = @pdfdir@
+pkgpyexecdir = @pkgpyexecdir@
+pkgpythondir = @pkgpythondir@
+prefix = @prefix@
+program_transform_name = @program_transform_name@
+psdir = @psdir@
+pyexecdir = @pyexecdir@
+pythondir = @pythondir@
+sbindir = @sbindir@
+sharedstatedir = @sharedstatedir@
+srcdir = @srcdir@
+sysconfdir = @sysconfdir@
+target_alias = @target_alias@
+top_build_prefix = @top_build_prefix@
+top_builddir = @top_builddir@
+top_srcdir = @top_srcdir@
+sugardir = $(pkgdatadir)/extensions/cpsection/language
+sugar_PYTHON = \
+ __init__.py \
+ model.py \
+ view.py
+
+all: all-am
+
+.SUFFIXES:
+$(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ $(srcdir)/Makefile.am $(am__configure_deps)
+ @for dep in $?; do \
+ case '$(am__configure_deps)' in \
+ *$$dep*) \
+ ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \
+ && { if test -f $@; then exit 0; else break; fi; }; \
+ exit 1;; \
+ esac; \
+ done; \
+ echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign extensions/cpsection/language/Makefile'; \
+ $(am__cd) $(top_srcdir) && \
+ $(AUTOMAKE) --foreign extensions/cpsection/language/Makefile
+.PRECIOUS: Makefile
+Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
+ @case '$?' in \
+ *config.status*) \
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \
+ *) \
+ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \
+ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \
+ esac;
+
+$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES)
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+
+$(top_srcdir)/configure: @MAINTAINER_MODE_TRUE@ $(am__configure_deps)
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+$(ACLOCAL_M4): @MAINTAINER_MODE_TRUE@ $(am__aclocal_m4_deps)
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+$(am__aclocal_m4_deps):
+install-sugarPYTHON: $(sugar_PYTHON)
+ @$(NORMAL_INSTALL)
+ test -z "$(sugardir)" || $(MKDIR_P) "$(DESTDIR)$(sugardir)"
+ @list='$(sugar_PYTHON)'; dlist=; list2=; test -n "$(sugardir)" || list=; \
+ for p in $$list; do \
+ if test -f "$$p"; then b=; else b="$(srcdir)/"; fi; \
+ if test -f $$b$$p; then \
+ $(am__strip_dir) \
+ dlist="$$dlist $$f"; \
+ list2="$$list2 $$b$$p"; \
+ else :; fi; \
+ done; \
+ for file in $$list2; do echo $$file; done | $(am__base_list) | \
+ while read files; do \
+ echo " $(INSTALL_DATA) $$files '$(DESTDIR)$(sugardir)'"; \
+ $(INSTALL_DATA) $$files "$(DESTDIR)$(sugardir)" || exit $$?; \
+ done || exit $$?; \
+ if test -n "$$dlist"; then \
+ $(am__py_compile) --destdir "$(DESTDIR)" \
+ --basedir "$(sugardir)" $$dlist; \
+ else :; fi
+
+uninstall-sugarPYTHON:
+ @$(NORMAL_UNINSTALL)
+ @list='$(sugar_PYTHON)'; test -n "$(sugardir)" || list=; \
+ files=`for p in $$list; do echo $$p; done | sed -e 's|^.*/||'`; \
+ test -n "$$files" || exit 0; \
+ dir='$(DESTDIR)$(sugardir)'; \
+ filesc=`echo "$$files" | sed 's|$$|c|'`; \
+ fileso=`echo "$$files" | sed 's|$$|o|'`; \
+ st=0; \
+ for files in "$$files" "$$filesc" "$$fileso"; do \
+ $(am__uninstall_files_from_dir) || st=$$?; \
+ done; \
+ exit $$st
+tags: TAGS
+TAGS:
+
+ctags: CTAGS
+CTAGS:
+
+
+distdir: $(DISTFILES)
+ @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
+ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
+ list='$(DISTFILES)'; \
+ dist_files=`for file in $$list; do echo $$file; done | \
+ sed -e "s|^$$srcdirstrip/||;t" \
+ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \
+ case $$dist_files in \
+ */*) $(MKDIR_P) `echo "$$dist_files" | \
+ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \
+ sort -u` ;; \
+ esac; \
+ for file in $$dist_files; do \
+ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \
+ if test -d $$d/$$file; then \
+ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \
+ if test -d "$(distdir)/$$file"; then \
+ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \
+ fi; \
+ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \
+ cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \
+ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \
+ fi; \
+ cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \
+ else \
+ test -f "$(distdir)/$$file" \
+ || cp -p $$d/$$file "$(distdir)/$$file" \
+ || exit 1; \
+ fi; \
+ done
+check-am: all-am
+check: check-am
+all-am: Makefile
+installdirs:
+ for dir in "$(DESTDIR)$(sugardir)"; do \
+ test -z "$$dir" || $(MKDIR_P) "$$dir"; \
+ done
+install: install-am
+install-exec: install-exec-am
+install-data: install-data-am
+uninstall: uninstall-am
+
+install-am: all-am
+ @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am
+
+installcheck: installcheck-am
+install-strip:
+ if test -z '$(STRIP)'; then \
+ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
+ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
+ install; \
+ else \
+ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
+ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
+ "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \
+ fi
+mostlyclean-generic:
+
+clean-generic:
+
+distclean-generic:
+ -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES)
+ -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES)
+
+maintainer-clean-generic:
+ @echo "This command is intended for maintainers to use"
+ @echo "it deletes files that may require special tools to rebuild."
+clean: clean-am
+
+clean-am: clean-generic mostlyclean-am
+
+distclean: distclean-am
+ -rm -f Makefile
+distclean-am: clean-am distclean-generic
+
+dvi: dvi-am
+
+dvi-am:
+
+html: html-am
+
+html-am:
+
+info: info-am
+
+info-am:
+
+install-data-am: install-sugarPYTHON
+
+install-dvi: install-dvi-am
+
+install-dvi-am:
+
+install-exec-am:
+
+install-html: install-html-am
+
+install-html-am:
+
+install-info: install-info-am
+
+install-info-am:
+
+install-man:
+
+install-pdf: install-pdf-am
+
+install-pdf-am:
+
+install-ps: install-ps-am
+
+install-ps-am:
+
+installcheck-am:
+
+maintainer-clean: maintainer-clean-am
+ -rm -f Makefile
+maintainer-clean-am: distclean-am maintainer-clean-generic
+
+mostlyclean: mostlyclean-am
+
+mostlyclean-am: mostlyclean-generic
+
+pdf: pdf-am
+
+pdf-am:
+
+ps: ps-am
+
+ps-am:
+
+uninstall-am: uninstall-sugarPYTHON
+
+.MAKE: install-am install-strip
+
+.PHONY: all all-am check check-am clean clean-generic distclean \
+ distclean-generic distdir dvi dvi-am html html-am info info-am \
+ install install-am install-data install-data-am install-dvi \
+ install-dvi-am install-exec install-exec-am install-html \
+ install-html-am install-info install-info-am install-man \
+ install-pdf install-pdf-am install-ps install-ps-am \
+ install-strip install-sugarPYTHON installcheck installcheck-am \
+ installdirs maintainer-clean maintainer-clean-generic \
+ mostlyclean mostlyclean-generic pdf pdf-am ps ps-am uninstall \
+ uninstall-am uninstall-sugarPYTHON
+
+
+# Tell versions [3.59,3.63) of GNU make to not export all variables.
+# Otherwise a system limit (for SysV at least) may be exceeded.
+.NOEXPORT:
diff --git a/extensions/cpsection/language/__init__.py b/extensions/cpsection/language/__init__.py
new file mode 100644
index 0000000..c93b7d1
--- /dev/null
+++ b/extensions/cpsection/language/__init__.py
@@ -0,0 +1,21 @@
+# Copyright (C) 2008, OLPC
+#
+# 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 2 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, write to the Free Software
+# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+
+from gettext import gettext as _
+
+CLASS = 'Language'
+ICON = 'module-language'
+TITLE = _('Language')
diff --git a/extensions/cpsection/language/model.py b/extensions/cpsection/language/model.py
new file mode 100644
index 0000000..17de6bb
--- /dev/null
+++ b/extensions/cpsection/language/model.py
@@ -0,0 +1,164 @@
+# Copyright (C) 2007, 2008 One Laptop Per Child
+#
+# 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 2 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, write to the Free Software
+# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+#
+#
+# The language config is based on the system-config-language
+# (http://fedoraproject.org/wiki/SystemConfig/language) tool
+# Parts of the code were reused.
+#
+
+import os
+import locale
+from gettext import gettext as _
+import subprocess
+
+
+_default_lang = '%s.%s' % locale.getdefaultlocale()
+_standard_msg = _('Could not access ~/.i18n. Create standard settings.')
+
+
+def read_all_languages():
+ fdp = subprocess.Popen(['locale', '-av'], stdout=subprocess.PIPE)
+ lines = fdp.stdout.read().split('\n')
+ locales = []
+
+ for line in lines:
+ if line.find('locale:') != -1:
+ locale = line.split()[1]
+ elif line.find('language |') != -1:
+ lang = line.lstrip('language |')
+ elif line.find('territory |') != -1:
+ territory = line.lstrip('territory |')
+ if locale.endswith('utf8') and len(lang):
+ locales.append((lang, territory, locale))
+
+ #FIXME: This is a temporary workaround for locales that are essential to
+ # OLPC, but are not in Glibc yet.
+ locales.append(('Kreyol', 'Haiti', 'ht_HT.utf8'))
+ locales.append(('Dari', 'Afghanistan', 'fa_AF.utf8'))
+ locales.append(('Pashto', 'Afghanistan', 'ps_AF.utf8'))
+
+ locales.sort()
+ return locales
+
+
+def _initialize():
+ if set_languages.__doc__ is None:
+ # when running under 'python -OO', all __doc__ fields are None,
+ # so += would fail -- and this function would be unnecessary anyway.
+ return
+ languages = read_all_languages()
+ set_languages.__doc__ += '\n'
+ for lang in languages:
+ set_languages.__doc__ += '%s \n' % (lang[0].replace(' ', '_') + '/' +
+ lang[1].replace(' ', '_'))
+
+
+def _write_i18n(lang_env, language_env):
+ path = os.path.join(os.environ.get('HOME'), '.i18n')
+ if not os.access(path, os.W_OK):
+ print _standard_msg
+ fd = open(path, 'w')
+ fd.write('LANG="%s"\n' % _default_lang)
+ fd.write('LANGUAGE="%s"\n' % _default_lang)
+ fd.close()
+ else:
+ fd = open(path, 'w')
+ fd.write('LANG="%s"\n' % lang_env)
+ fd.write('LANGUAGE="%s"\n' % language_env)
+ fd.close()
+
+
+def get_languages():
+ path = os.path.join(os.environ.get('HOME', ''), '.i18n')
+ if not os.access(path, os.R_OK):
+ print _standard_msg
+ fd = open(path, 'w')
+ fd.write('LANG="%s"\n' % _default_lang)
+ fd.write('LANGUAGE="%s"\n' % _default_lang)
+ fd.close()
+ return [_default_lang]
+
+ fd = open(path, 'r')
+ lines = fd.readlines()
+ fd.close()
+
+ langlist = None
+
+ for line in lines:
+ if line.startswith('LANGUAGE='):
+ lang = line[9:].replace('"', '')
+ lang = lang.strip()
+ langlist = lang.split(':')
+ elif line.startswith('LANG='):
+ lang = line[5:].replace('"', '')
+
+ # There might be cases where .i18n may not contain a LANGUAGE field
+ if langlist == None:
+ return [lang]
+ else:
+ return langlist
+
+
+def print_languages():
+ codes = get_languages()
+
+ languages = read_all_languages()
+ for code in codes:
+ found_lang = False
+ for lang in languages:
+ if lang[2].split('.')[0] == code.split('.')[0]:
+ print lang[0].replace(' ', '_') + '/' + \
+ lang[1].replace(' ', '_')
+ found_lang = True
+ break
+ if not found_lang:
+ print (_('Language for code=%s could not be determined.') % code)
+
+
+def set_languages(languages):
+ """Set the system language.
+ languages :
+ """
+
+ if isinstance(languages, list):
+ set_languages_list(languages)
+ return
+
+ if languages.endswith('utf8'):
+ set_languages_list([languages])
+ return 1
+ else:
+ langs = read_all_languages()
+ for lang, territory, locale in langs:
+ code = lang.replace(' ', '_') + '/' \
+ + territory.replace(' ', '_')
+ if code == languages:
+ set_languages_list([locale])
+ return 1
+ print (_("Sorry I do not speak \'%s\'.") % languages)
+
+
+def set_languages_list(languages):
+ """Set the system language using a list of preferred languages"""
+ colon = ':'
+ language_env = colon.join(languages)
+ lang_env = languages[0].strip('\n')
+ _write_i18n(lang_env, language_env)
+
+
+# inilialize the docstrings for the language
+_initialize()
diff --git a/extensions/cpsection/language/view.py b/extensions/cpsection/language/view.py
new file mode 100644
index 0000000..1553959
--- /dev/null
+++ b/extensions/cpsection/language/view.py
@@ -0,0 +1,281 @@
+# Copyright (C) 2008, OLPC
+# Copyright (C) 2009, Simon Schampijer
+#
+# 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 2 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, write to the Free Software
+# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+
+import gtk
+import gobject
+import gettext
+
+from sugar.graphics import style
+from sugar.graphics.icon import Icon
+
+from jarabe.controlpanel.sectionview import SectionView
+from jarabe.controlpanel.inlinealert import InlineAlert
+
+_translate_language = lambda msg: gettext.dgettext('iso_639', msg)
+_translate_country = lambda msg: gettext.dgettext('iso_3166', msg)
+
+CLASS = 'Language'
+ICON = 'module-language'
+TITLE = gettext.gettext('Language')
+
+
+class Language(SectionView):
+ def __init__(self, model, alerts):
+ SectionView.__init__(self)
+
+ self._model = model
+ self.restart_alerts = alerts
+ self._lang_sid = 0
+ self._selected_lang_count = 0
+ self._labels = []
+ self._stores = []
+ self._comboboxes = []
+ self._add_remove_boxes = []
+ self._changed = False
+ self._cursor_change_handler = None
+
+ self._available_locales = self._model.read_all_languages()
+ self._selected_locales = self._model.get_languages()
+
+ self.set_border_width(style.DEFAULT_SPACING * 2)
+ self.set_spacing(style.DEFAULT_SPACING)
+
+ explanation = gettext.gettext('Add languages in the order you prefer.'
+ ' If a translation is not available,'
+ ' the next in the list will be used.')
+ self._text = gtk.Label(explanation)
+ self._text.set_width_chars(100)
+ self._text.set_line_wrap(True)
+ self._text.set_alignment(0, 0)
+ self.pack_start(self._text, False)
+ self._text.show()
+
+ scrolled = gtk.ScrolledWindow()
+ scrolled.set_policy(gtk.POLICY_NEVER, gtk.POLICY_AUTOMATIC)
+ scrolled.show()
+ self.pack_start(scrolled, expand=True)
+
+ self._table = gtk.Table(rows=1, columns=3, homogeneous=False)
+ self._table.set_border_width(style.DEFAULT_SPACING * 2)
+ self._table.show()
+ scrolled.add_with_viewport(self._table)
+
+ self._lang_alert_box = gtk.HBox(spacing=style.DEFAULT_SPACING)
+ self.pack_start(self._lang_alert_box, False)
+
+ self._lang_alert = InlineAlert()
+ self._lang_alert_box.pack_start(self._lang_alert)
+ if 'lang' in self.restart_alerts:
+ self._lang_alert.props.msg = self.restart_msg
+ self._lang_alert.show()
+ self._lang_alert_box.show()
+
+ self.setup()
+
+ def _add_row(self, locale_code=None):
+ """Adds a row to the table"""
+
+ self._selected_lang_count += 1
+
+ self._table.resize(self._selected_lang_count, 3)
+
+ label = gtk.Label(str=str(self._selected_lang_count))
+ label.modify_fg(gtk.STATE_NORMAL,
+ style.COLOR_SELECTION_GREY.get_gdk_color())
+ self._labels.append(label)
+ self._attach_to_table(label, 0, 1, padding=1)
+ label.show()
+
+ store = gtk.ListStore(gobject.TYPE_STRING, gobject.TYPE_STRING)
+ for language, country, code in self._available_locales:
+ description = '%s (%s)' % (_translate_language(language), \
+ _translate_country(country))
+ store.append([code, description])
+
+ combobox = gtk.ComboBox(model=store)
+ cell = gtk.CellRendererText()
+ combobox.pack_start(cell)
+ combobox.add_attribute(cell, 'text', 1)
+
+ if locale_code:
+ for row in store:
+ lang = locale_code.split('.')[0]
+ lang_column = row[0].split('.')[0]
+ if lang in lang_column:
+ combobox.set_active_iter(row.iter)
+ break
+ else:
+ combobox.set_active(1)
+
+ combobox.connect('changed', self.__combobox_changed_cb)
+
+ self._stores.append(store)
+ self._comboboxes.append(combobox)
+ self._attach_to_table(combobox, 1, 2, yoptions=gtk.SHRINK)
+
+ add_remove_box = self._create_add_remove_box()
+ self._add_remove_boxes.append(add_remove_box)
+ self._attach_to_table(add_remove_box, 2, 3)
+
+ add_remove_box.show_all()
+
+ if self._selected_lang_count > 1:
+ previous_add_removes = self._add_remove_boxes[-2]
+ previous_add_removes.hide_all()
+
+ self._determine_add_remove_visibility()
+
+ combobox.show()
+
+ def _attach_to_table(self, widget, row, column, padding=20, \
+ yoptions=gtk.FILL):
+ self._table.attach(widget, row, column, \
+ self._selected_lang_count - 1, self._selected_lang_count, \
+ xoptions=gtk.FILL, yoptions=yoptions, xpadding=padding, \
+ ypadding=padding)
+
+ def _delete_last_row(self):
+ """Deletes the last row of the table"""
+
+ self._selected_lang_count -= 1
+
+ label, add_remove_box, combobox, store_ = self._get_last_row()
+
+ label.destroy()
+ add_remove_box.destroy()
+ combobox.destroy()
+
+ self._table.resize(self._selected_lang_count, 3)
+
+ self._add_remove_boxes[-1].show_all()
+
+ def _get_last_row(self):
+ label = self._labels.pop()
+ add_remove_box = self._add_remove_boxes.pop()
+ combobox = self._comboboxes.pop()
+ store = self._stores.pop()
+
+ return label, add_remove_box, combobox, store
+
+ def setup(self):
+ for locale in self._selected_locales:
+ self._add_row(locale_code=locale)
+
+ def undo(self):
+ self._model.undo()
+ self._lang_alert.hide()
+
+ def _create_add_remove_box(self):
+ """Creates gtk.Hbox with add/remove buttons"""
+ add_icon = Icon(icon_name='list-add')
+
+ add_button = gtk.Button()
+ add_button.set_image(add_icon)
+ add_button.connect('clicked',
+ self.__add_button_clicked_cb)
+
+ remove_icon = Icon(icon_name='list-remove')
+ remove_button = gtk.Button()
+ remove_button.set_image(remove_icon)
+ remove_button.connect('clicked',
+ self.__remove_button_clicked_cb)
+
+ add_remove_box = gtk.HButtonBox()
+ add_remove_box.set_layout(gtk.BUTTONBOX_START)
+ add_remove_box.set_spacing(10)
+ add_remove_box.pack_start(add_button)
+ add_remove_box.pack_start(remove_button)
+
+ return add_remove_box
+
+ def __add_button_clicked_cb(self, button):
+ self._add_row()
+ self._check_change()
+
+ def __remove_button_clicked_cb(self, button):
+ self._delete_last_row()
+ self._check_change()
+
+ def __combobox_changed_cb(self, button):
+ self._check_change()
+
+ def _check_change(self):
+ selected_langs = self._get_selected_langs()
+ last_lang = selected_langs[-1]
+
+ self._determine_add_remove_visibility(last_lang=last_lang)
+
+ self._changed = (selected_langs != self._selected_locales)
+
+ if self._changed == False:
+ # The user reverted back to the original config
+ self.needs_restart = False
+ if 'lang' in self.restart_alerts:
+ self.restart_alerts.remove('lang')
+ self._lang_alert.hide()
+ if self._lang_sid:
+ gobject.source_remove(self._lang_sid)
+ self._model.undo()
+ return False
+
+ if self._lang_sid:
+ gobject.source_remove(self._lang_sid)
+ self._lang_sid = gobject.timeout_add(self._APPLY_TIMEOUT,
+ self.__lang_timeout_cb,
+ selected_langs)
+
+ def _get_selected_langs(self):
+ new_codes = []
+ for combobox in self._comboboxes:
+ it = combobox.get_active_iter()
+ model = combobox.get_model()
+ lang_code = model.get(it, 0)[0]
+ new_codes.append(lang_code)
+
+ return new_codes
+
+ def _determine_add_remove_visibility(self, last_lang=None):
+ # We should not let users add fallback languages for English (USA)
+ # This is because the software is not usually _translated_ into English
+ # which means that the fallback gets selected automatically
+
+ if last_lang is None:
+ selected_langs = self._get_selected_langs()
+ last_lang = selected_langs[-1]
+
+ add_remove_box = self._add_remove_boxes[-1]
+ buttons = add_remove_box.get_children()
+ add_button, remove_button = buttons
+
+ if last_lang.startswith('en_US'):
+ add_button.props.visible = False
+ else:
+ add_button.props.visible = True
+
+ if self._selected_lang_count == 1:
+ remove_button.props.visible = False
+ else:
+ remove_button.props.visible = True
+
+ def __lang_timeout_cb(self, codes):
+ self._lang_sid = 0
+ self._model.set_languages_list(codes)
+ self.restart_alerts.append('lang')
+ self.needs_restart = True
+ self._lang_alert.props.msg = self.restart_msg
+ self._lang_alert.show()
+ return False
diff --git a/extensions/cpsection/modemconfiguration/Makefile.am b/extensions/cpsection/modemconfiguration/Makefile.am
new file mode 100644
index 0000000..3e2613e
--- /dev/null
+++ b/extensions/cpsection/modemconfiguration/Makefile.am
@@ -0,0 +1,6 @@
+sugardir = $(pkgdatadir)/extensions/cpsection/modemconfiguration
+
+sugar_PYTHON = \
+ __init__.py \
+ model.py \
+ view.py
diff --git a/extensions/cpsection/modemconfiguration/Makefile.in b/extensions/cpsection/modemconfiguration/Makefile.in
new file mode 100644
index 0000000..921d5db
--- /dev/null
+++ b/extensions/cpsection/modemconfiguration/Makefile.in
@@ -0,0 +1,442 @@
+# Makefile.in generated by automake 1.11.3 from Makefile.am.
+# @configure_input@
+
+# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002,
+# 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011 Free Software
+# Foundation, Inc.
+# This Makefile.in is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
+# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
+# PARTICULAR PURPOSE.
+
+@SET_MAKE@
+VPATH = @srcdir@
+pkgdatadir = $(datadir)/@PACKAGE@
+pkgincludedir = $(includedir)/@PACKAGE@
+pkglibdir = $(libdir)/@PACKAGE@
+pkglibexecdir = $(libexecdir)/@PACKAGE@
+am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd
+install_sh_DATA = $(install_sh) -c -m 644
+install_sh_PROGRAM = $(install_sh) -c
+install_sh_SCRIPT = $(install_sh) -c
+INSTALL_HEADER = $(INSTALL_DATA)
+transform = $(program_transform_name)
+NORMAL_INSTALL = :
+PRE_INSTALL = :
+POST_INSTALL = :
+NORMAL_UNINSTALL = :
+PRE_UNINSTALL = :
+POST_UNINSTALL = :
+subdir = extensions/cpsection/modemconfiguration
+DIST_COMMON = $(srcdir)/Makefile.am $(srcdir)/Makefile.in \
+ $(sugar_PYTHON)
+ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
+am__aclocal_m4_deps = $(top_srcdir)/configure.ac
+am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
+ $(ACLOCAL_M4)
+mkinstalldirs = $(install_sh) -d
+CONFIG_CLEAN_FILES =
+CONFIG_CLEAN_VPATH_FILES =
+SOURCES =
+DIST_SOURCES =
+am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`;
+am__vpath_adj = case $$p in \
+ $(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \
+ *) f=$$p;; \
+ esac;
+am__strip_dir = f=`echo $$p | sed -e 's|^.*/||'`;
+am__install_max = 40
+am__nobase_strip_setup = \
+ srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*|]/\\\\&/g'`
+am__nobase_strip = \
+ for p in $$list; do echo "$$p"; done | sed -e "s|$$srcdirstrip/||"
+am__nobase_list = $(am__nobase_strip_setup); \
+ for p in $$list; do echo "$$p $$p"; done | \
+ sed "s| $$srcdirstrip/| |;"' / .*\//!s/ .*/ ./; s,\( .*\)/[^/]*$$,\1,' | \
+ $(AWK) 'BEGIN { files["."] = "" } { files[$$2] = files[$$2] " " $$1; \
+ if (++n[$$2] == $(am__install_max)) \
+ { print $$2, files[$$2]; n[$$2] = 0; files[$$2] = "" } } \
+ END { for (dir in files) print dir, files[dir] }'
+am__base_list = \
+ sed '$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;s/\n/ /g' | \
+ sed '$$!N;$$!N;$$!N;$$!N;s/\n/ /g'
+am__uninstall_files_from_dir = { \
+ test -z "$$files" \
+ || { test ! -d "$$dir" && test ! -f "$$dir" && test ! -r "$$dir"; } \
+ || { echo " ( cd '$$dir' && rm -f" $$files ")"; \
+ $(am__cd) "$$dir" && rm -f $$files; }; \
+ }
+am__py_compile = PYTHON=$(PYTHON) $(SHELL) $(py_compile)
+am__installdirs = "$(DESTDIR)$(sugardir)"
+py_compile = $(top_srcdir)/py-compile
+DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
+ACLOCAL = @ACLOCAL@
+ALL_LINGUAS = @ALL_LINGUAS@
+AMTAR = @AMTAR@
+AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@
+AUTOCONF = @AUTOCONF@
+AUTOHEADER = @AUTOHEADER@
+AUTOMAKE = @AUTOMAKE@
+AWK = @AWK@
+CATALOGS = @CATALOGS@
+CATOBJEXT = @CATOBJEXT@
+CC = @CC@
+CCDEPMODE = @CCDEPMODE@
+CFLAGS = @CFLAGS@
+CPP = @CPP@
+CPPFLAGS = @CPPFLAGS@
+CYGPATH_W = @CYGPATH_W@
+DATADIRNAME = @DATADIRNAME@
+DEFS = @DEFS@
+DEPDIR = @DEPDIR@
+ECHO_C = @ECHO_C@
+ECHO_N = @ECHO_N@
+ECHO_T = @ECHO_T@
+EGREP = @EGREP@
+EXEEXT = @EXEEXT@
+GCONFTOOL = @GCONFTOOL@
+GCONF_SCHEMA_CONFIG_SOURCE = @GCONF_SCHEMA_CONFIG_SOURCE@
+GCONF_SCHEMA_FILE_DIR = @GCONF_SCHEMA_FILE_DIR@
+GETTEXT_PACKAGE = @GETTEXT_PACKAGE@
+GMOFILES = @GMOFILES@
+GMSGFMT = @GMSGFMT@
+GREP = @GREP@
+INSTALL = @INSTALL@
+INSTALL_DATA = @INSTALL_DATA@
+INSTALL_PROGRAM = @INSTALL_PROGRAM@
+INSTALL_SCRIPT = @INSTALL_SCRIPT@
+INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@
+INSTOBJEXT = @INSTOBJEXT@
+INTLLIBS = @INTLLIBS@
+INTLTOOL_EXTRACT = @INTLTOOL_EXTRACT@
+INTLTOOL_MERGE = @INTLTOOL_MERGE@
+INTLTOOL_PERL = @INTLTOOL_PERL@
+INTLTOOL_UPDATE = @INTLTOOL_UPDATE@
+INTLTOOL_V_MERGE = @INTLTOOL_V_MERGE@
+INTLTOOL_V_MERGE_OPTIONS = @INTLTOOL_V_MERGE_OPTIONS@
+INTLTOOL__v_MERGE_ = @INTLTOOL__v_MERGE_@
+INTLTOOL__v_MERGE_0 = @INTLTOOL__v_MERGE_0@
+LDFLAGS = @LDFLAGS@
+LIBOBJS = @LIBOBJS@
+LIBS = @LIBS@
+LTLIBOBJS = @LTLIBOBJS@
+MAINT = @MAINT@
+MAKEINFO = @MAKEINFO@
+MKDIR_P = @MKDIR_P@
+MKINSTALLDIRS = @MKINSTALLDIRS@
+MSGFMT = @MSGFMT@
+MSGFMT_OPTS = @MSGFMT_OPTS@
+MSGMERGE = @MSGMERGE@
+OBJEXT = @OBJEXT@
+PACKAGE = @PACKAGE@
+PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@
+PACKAGE_NAME = @PACKAGE_NAME@
+PACKAGE_STRING = @PACKAGE_STRING@
+PACKAGE_TARNAME = @PACKAGE_TARNAME@
+PACKAGE_URL = @PACKAGE_URL@
+PACKAGE_VERSION = @PACKAGE_VERSION@
+PATH_SEPARATOR = @PATH_SEPARATOR@
+PKG_CONFIG = @PKG_CONFIG@
+PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@
+PKG_CONFIG_PATH = @PKG_CONFIG_PATH@
+POFILES = @POFILES@
+POSUB = @POSUB@
+PO_IN_DATADIR_FALSE = @PO_IN_DATADIR_FALSE@
+PO_IN_DATADIR_TRUE = @PO_IN_DATADIR_TRUE@
+PYTHON = @PYTHON@
+PYTHON_EXEC_PREFIX = @PYTHON_EXEC_PREFIX@
+PYTHON_PLATFORM = @PYTHON_PLATFORM@
+PYTHON_PREFIX = @PYTHON_PREFIX@
+PYTHON_VERSION = @PYTHON_VERSION@
+SET_MAKE = @SET_MAKE@
+SHELL = @SHELL@
+SHELL_CFLAGS = @SHELL_CFLAGS@
+SHELL_LIBS = @SHELL_LIBS@
+STRIP = @STRIP@
+SUCROSE_VERSION = @SUCROSE_VERSION@
+USE_NLS = @USE_NLS@
+VERSION = @VERSION@
+XGETTEXT = @XGETTEXT@
+abs_builddir = @abs_builddir@
+abs_srcdir = @abs_srcdir@
+abs_top_builddir = @abs_top_builddir@
+abs_top_srcdir = @abs_top_srcdir@
+ac_ct_CC = @ac_ct_CC@
+am__include = @am__include@
+am__leading_dot = @am__leading_dot@
+am__quote = @am__quote@
+am__tar = @am__tar@
+am__untar = @am__untar@
+bindir = @bindir@
+build_alias = @build_alias@
+builddir = @builddir@
+datadir = @datadir@
+datarootdir = @datarootdir@
+docdir = @docdir@
+dvidir = @dvidir@
+exec_prefix = @exec_prefix@
+host_alias = @host_alias@
+htmldir = @htmldir@
+includedir = @includedir@
+infodir = @infodir@
+install_sh = @install_sh@
+intltool__v_merge_options_ = @intltool__v_merge_options_@
+intltool__v_merge_options_0 = @intltool__v_merge_options_0@
+libdir = @libdir@
+libexecdir = @libexecdir@
+localedir = @localedir@
+localstatedir = @localstatedir@
+mandir = @mandir@
+mkdir_p = @mkdir_p@
+oldincludedir = @oldincludedir@
+pdfdir = @pdfdir@
+pkgpyexecdir = @pkgpyexecdir@
+pkgpythondir = @pkgpythondir@
+prefix = @prefix@
+program_transform_name = @program_transform_name@
+psdir = @psdir@
+pyexecdir = @pyexecdir@
+pythondir = @pythondir@
+sbindir = @sbindir@
+sharedstatedir = @sharedstatedir@
+srcdir = @srcdir@
+sysconfdir = @sysconfdir@
+target_alias = @target_alias@
+top_build_prefix = @top_build_prefix@
+top_builddir = @top_builddir@
+top_srcdir = @top_srcdir@
+sugardir = $(pkgdatadir)/extensions/cpsection/modemconfiguration
+sugar_PYTHON = \
+ __init__.py \
+ model.py \
+ view.py
+
+all: all-am
+
+.SUFFIXES:
+$(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ $(srcdir)/Makefile.am $(am__configure_deps)
+ @for dep in $?; do \
+ case '$(am__configure_deps)' in \
+ *$$dep*) \
+ ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \
+ && { if test -f $@; then exit 0; else break; fi; }; \
+ exit 1;; \
+ esac; \
+ done; \
+ echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign extensions/cpsection/modemconfiguration/Makefile'; \
+ $(am__cd) $(top_srcdir) && \
+ $(AUTOMAKE) --foreign extensions/cpsection/modemconfiguration/Makefile
+.PRECIOUS: Makefile
+Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
+ @case '$?' in \
+ *config.status*) \
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \
+ *) \
+ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \
+ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \
+ esac;
+
+$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES)
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+
+$(top_srcdir)/configure: @MAINTAINER_MODE_TRUE@ $(am__configure_deps)
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+$(ACLOCAL_M4): @MAINTAINER_MODE_TRUE@ $(am__aclocal_m4_deps)
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+$(am__aclocal_m4_deps):
+install-sugarPYTHON: $(sugar_PYTHON)
+ @$(NORMAL_INSTALL)
+ test -z "$(sugardir)" || $(MKDIR_P) "$(DESTDIR)$(sugardir)"
+ @list='$(sugar_PYTHON)'; dlist=; list2=; test -n "$(sugardir)" || list=; \
+ for p in $$list; do \
+ if test -f "$$p"; then b=; else b="$(srcdir)/"; fi; \
+ if test -f $$b$$p; then \
+ $(am__strip_dir) \
+ dlist="$$dlist $$f"; \
+ list2="$$list2 $$b$$p"; \
+ else :; fi; \
+ done; \
+ for file in $$list2; do echo $$file; done | $(am__base_list) | \
+ while read files; do \
+ echo " $(INSTALL_DATA) $$files '$(DESTDIR)$(sugardir)'"; \
+ $(INSTALL_DATA) $$files "$(DESTDIR)$(sugardir)" || exit $$?; \
+ done || exit $$?; \
+ if test -n "$$dlist"; then \
+ $(am__py_compile) --destdir "$(DESTDIR)" \
+ --basedir "$(sugardir)" $$dlist; \
+ else :; fi
+
+uninstall-sugarPYTHON:
+ @$(NORMAL_UNINSTALL)
+ @list='$(sugar_PYTHON)'; test -n "$(sugardir)" || list=; \
+ files=`for p in $$list; do echo $$p; done | sed -e 's|^.*/||'`; \
+ test -n "$$files" || exit 0; \
+ dir='$(DESTDIR)$(sugardir)'; \
+ filesc=`echo "$$files" | sed 's|$$|c|'`; \
+ fileso=`echo "$$files" | sed 's|$$|o|'`; \
+ st=0; \
+ for files in "$$files" "$$filesc" "$$fileso"; do \
+ $(am__uninstall_files_from_dir) || st=$$?; \
+ done; \
+ exit $$st
+tags: TAGS
+TAGS:
+
+ctags: CTAGS
+CTAGS:
+
+
+distdir: $(DISTFILES)
+ @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
+ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
+ list='$(DISTFILES)'; \
+ dist_files=`for file in $$list; do echo $$file; done | \
+ sed -e "s|^$$srcdirstrip/||;t" \
+ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \
+ case $$dist_files in \
+ */*) $(MKDIR_P) `echo "$$dist_files" | \
+ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \
+ sort -u` ;; \
+ esac; \
+ for file in $$dist_files; do \
+ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \
+ if test -d $$d/$$file; then \
+ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \
+ if test -d "$(distdir)/$$file"; then \
+ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \
+ fi; \
+ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \
+ cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \
+ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \
+ fi; \
+ cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \
+ else \
+ test -f "$(distdir)/$$file" \
+ || cp -p $$d/$$file "$(distdir)/$$file" \
+ || exit 1; \
+ fi; \
+ done
+check-am: all-am
+check: check-am
+all-am: Makefile
+installdirs:
+ for dir in "$(DESTDIR)$(sugardir)"; do \
+ test -z "$$dir" || $(MKDIR_P) "$$dir"; \
+ done
+install: install-am
+install-exec: install-exec-am
+install-data: install-data-am
+uninstall: uninstall-am
+
+install-am: all-am
+ @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am
+
+installcheck: installcheck-am
+install-strip:
+ if test -z '$(STRIP)'; then \
+ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
+ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
+ install; \
+ else \
+ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
+ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
+ "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \
+ fi
+mostlyclean-generic:
+
+clean-generic:
+
+distclean-generic:
+ -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES)
+ -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES)
+
+maintainer-clean-generic:
+ @echo "This command is intended for maintainers to use"
+ @echo "it deletes files that may require special tools to rebuild."
+clean: clean-am
+
+clean-am: clean-generic mostlyclean-am
+
+distclean: distclean-am
+ -rm -f Makefile
+distclean-am: clean-am distclean-generic
+
+dvi: dvi-am
+
+dvi-am:
+
+html: html-am
+
+html-am:
+
+info: info-am
+
+info-am:
+
+install-data-am: install-sugarPYTHON
+
+install-dvi: install-dvi-am
+
+install-dvi-am:
+
+install-exec-am:
+
+install-html: install-html-am
+
+install-html-am:
+
+install-info: install-info-am
+
+install-info-am:
+
+install-man:
+
+install-pdf: install-pdf-am
+
+install-pdf-am:
+
+install-ps: install-ps-am
+
+install-ps-am:
+
+installcheck-am:
+
+maintainer-clean: maintainer-clean-am
+ -rm -f Makefile
+maintainer-clean-am: distclean-am maintainer-clean-generic
+
+mostlyclean: mostlyclean-am
+
+mostlyclean-am: mostlyclean-generic
+
+pdf: pdf-am
+
+pdf-am:
+
+ps: ps-am
+
+ps-am:
+
+uninstall-am: uninstall-sugarPYTHON
+
+.MAKE: install-am install-strip
+
+.PHONY: all all-am check check-am clean clean-generic distclean \
+ distclean-generic distdir dvi dvi-am html html-am info info-am \
+ install install-am install-data install-data-am install-dvi \
+ install-dvi-am install-exec install-exec-am install-html \
+ install-html-am install-info install-info-am install-man \
+ install-pdf install-pdf-am install-ps install-ps-am \
+ install-strip install-sugarPYTHON installcheck installcheck-am \
+ installdirs maintainer-clean maintainer-clean-generic \
+ mostlyclean mostlyclean-generic pdf pdf-am ps ps-am uninstall \
+ uninstall-am uninstall-sugarPYTHON
+
+
+# Tell versions [3.59,3.63) of GNU make to not export all variables.
+# Otherwise a system limit (for SysV at least) may be exceeded.
+.NOEXPORT:
diff --git a/extensions/cpsection/modemconfiguration/__init__.py b/extensions/cpsection/modemconfiguration/__init__.py
new file mode 100644
index 0000000..61f5904
--- /dev/null
+++ b/extensions/cpsection/modemconfiguration/__init__.py
@@ -0,0 +1,21 @@
+# Copyright (C) 2009 Paraguay Educa, Martin Abente
+#
+# 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 2 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, write to the Free Software
+# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 US
+
+from gettext import gettext as _
+
+CLASS = 'ModemConfiguration'
+ICON = 'module-modemconfiguration'
+TITLE = _('Modem Configuration')
diff --git a/extensions/cpsection/modemconfiguration/model.py b/extensions/cpsection/modemconfiguration/model.py
new file mode 100755
index 0000000..969b5d9
--- /dev/null
+++ b/extensions/cpsection/modemconfiguration/model.py
@@ -0,0 +1,100 @@
+# Copyright (C) 2009 Paraguay Educa, Martin Abente
+#
+# 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 2 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, write to the Free Software
+# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 US
+
+import logging
+
+import dbus
+import gtk
+
+from jarabe.model import network
+
+
+def get_connection():
+ return network.find_gsm_connection()
+
+
+def get_modem_settings():
+ modem_settings = {}
+ connection = get_connection()
+ if not connection:
+ return modem_settings
+
+ settings = connection.get_settings('gsm')
+ for setting in ('username', 'number', 'apn'):
+ modem_settings[setting] = settings.get(setting, '')
+
+ # use mutable container for nested function control variable
+ secrets_call_done = [False]
+
+ def _secrets_cb(secrets):
+ secrets_call_done[0] = True
+ if not secrets or not 'gsm' in secrets:
+ return
+
+ gsm_secrets = secrets['gsm']
+ modem_settings['password'] = gsm_secrets.get('password', '')
+ modem_settings['pin'] = gsm_secrets.get('pin', '')
+
+ def _secrets_err_cb(err):
+ secrets_call_done[0] = True
+ if isinstance(err, dbus.exceptions.DBusException) and \
+ err.get_dbus_name() == network.NM_AGENT_MANAGER_ERR_NO_SECRETS:
+ logging.debug('No GSM secrets present')
+ else:
+ logging.error('Error retrieving GSM secrets: %s', err)
+
+ # must be called asynchronously as this re-enters the GTK main loop
+ connection.get_secrets('gsm', _secrets_cb, _secrets_err_cb)
+
+ # wait til asynchronous execution completes
+ while not secrets_call_done[0]:
+ gtk.main_iteration()
+
+ return modem_settings
+
+
+def _set_or_clear(_dict, key, value):
+ """Update a dictionary value for a specific key. If value is None or
+ zero-length, but the key is present in the dictionary, delete that
+ dictionary entry."""
+ if value:
+ _dict[key] = value
+ return
+
+ if key in _dict:
+ del _dict[key]
+
+
+def set_modem_settings(modem_settings):
+ username = modem_settings.get('username', '')
+ password = modem_settings.get('password', '')
+ number = modem_settings.get('number', '')
+ apn = modem_settings.get('apn', '')
+ pin = modem_settings.get('pin', '')
+
+ connection = get_connection()
+ if not connection:
+ network.create_gsm_connection(username, password, number, apn, pin)
+ return
+
+ settings = connection.get_settings()
+ gsm_settings = settings['gsm']
+ _set_or_clear(gsm_settings, 'username', username)
+ _set_or_clear(gsm_settings, 'password', password)
+ _set_or_clear(gsm_settings, 'number', number)
+ _set_or_clear(gsm_settings, 'apn', apn)
+ _set_or_clear(gsm_settings, 'pin', pin)
+ connection.update_settings(settings)
diff --git a/extensions/cpsection/modemconfiguration/view.py b/extensions/cpsection/modemconfiguration/view.py
new file mode 100644
index 0000000..4ce6c0d
--- /dev/null
+++ b/extensions/cpsection/modemconfiguration/view.py
@@ -0,0 +1,144 @@
+# Copyright (C) 2009 Paraguay Educa, Martin Abente
+#
+# 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 2 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, write to the Free Software
+# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 US
+
+from gettext import gettext as _
+import logging
+
+import gtk
+import gobject
+
+from sugar.graphics import style
+
+from jarabe.controlpanel.sectionview import SectionView
+
+
+APPLY_TIMEOUT = 1000
+
+
+class EntryWithLabel(gtk.HBox):
+ __gtype_name__ = 'SugarEntryWithLabel'
+
+ def __init__(self, label_text):
+ gtk.HBox.__init__(self, spacing=style.DEFAULT_SPACING)
+
+ self.label = gtk.Label(label_text)
+ self.label.modify_fg(gtk.STATE_NORMAL,
+ style.COLOR_SELECTION_GREY.get_gdk_color())
+ self.label.set_alignment(1, 0.5)
+ self.pack_start(self.label, expand=False)
+ self.label.show()
+
+ self._entry = gtk.Entry(25)
+ self._entry.set_width_chars(25)
+ self.pack_start(self._entry, expand=False)
+ self._entry.show()
+
+ def get_entry(self):
+ return self._entry
+
+ entry = gobject.property(type=object, getter=get_entry)
+
+
+class ModemConfiguration(SectionView):
+ def __init__(self, model, alerts=None):
+ SectionView.__init__(self)
+
+ self._model = model
+ self.restart_alerts = alerts
+ self._timeout_sid = 0
+
+ self.set_border_width(style.DEFAULT_SPACING)
+ self.set_spacing(style.DEFAULT_SPACING)
+ self._group = gtk.SizeGroup(gtk.SIZE_GROUP_HORIZONTAL)
+
+ explanation = _('You will need to provide the following information'
+ ' to set up a mobile broadband connection to a'
+ ' cellular (3G) network.')
+ self._text = gtk.Label(explanation)
+ self._text.set_width_chars(100)
+ self._text.set_line_wrap(True)
+ self._text.set_alignment(0, 0)
+ self.pack_start(self._text, False)
+ self._text.show()
+
+ self._username_entry = EntryWithLabel(_('Username:'))
+ self._username_entry.entry.connect('changed', self.__entry_changed_cb)
+ self._group.add_widget(self._username_entry.label)
+ self.pack_start(self._username_entry, expand=False)
+ self._username_entry.show()
+
+ self._password_entry = EntryWithLabel(_('Password:'))
+ self._password_entry.entry.connect('changed', self.__entry_changed_cb)
+ self._group.add_widget(self._password_entry.label)
+ self.pack_start(self._password_entry, expand=False)
+ self._password_entry.show()
+
+ self._number_entry = EntryWithLabel(_('Number:'))
+ self._number_entry.entry.connect('changed', self.__entry_changed_cb)
+ self._group.add_widget(self._number_entry.label)
+ self.pack_start(self._number_entry, expand=False)
+ self._number_entry.show()
+
+ self._apn_entry = EntryWithLabel(_('Access Point Name (APN):'))
+ self._apn_entry.entry.connect('changed', self.__entry_changed_cb)
+ self._group.add_widget(self._apn_entry.label)
+ self.pack_start(self._apn_entry, expand=False)
+ self._apn_entry.show()
+
+ self._pin_entry = EntryWithLabel(_('Personal Identity Number (PIN):'))
+ self._pin_entry.entry.connect('changed', self.__entry_changed_cb)
+ self._group.add_widget(self._pin_entry.label)
+ self.pack_start(self._pin_entry, expand=False)
+ self._pin_entry.show()
+
+ self.setup()
+
+ def undo(self):
+ self._model.undo()
+
+ def _populate_entry(self, entrywithlabel, text):
+ """Populate an entry with text, without triggering its 'changed'
+ handler."""
+ entry = entrywithlabel.entry
+ entry.handler_block_by_func(self.__entry_changed_cb)
+ entry.set_text(text)
+ entry.handler_unblock_by_func(self.__entry_changed_cb)
+
+ def setup(self):
+ settings = self._model.get_modem_settings()
+ self._populate_entry(self._username_entry,
+ settings.get('username', ''))
+ self._populate_entry(self._number_entry, settings.get('number', ''))
+ self._populate_entry(self._apn_entry, settings.get('apn', ''))
+ self._populate_entry(self._password_entry,
+ settings.get('password', ''))
+ self._populate_entry(self._pin_entry, settings.get('pin', ''))
+
+ def __entry_changed_cb(self, widget, data=None):
+ if self._timeout_sid:
+ gobject.source_remove(self._timeout_sid)
+ self._timeout_sid = gobject.timeout_add(APPLY_TIMEOUT,
+ self.__timeout_cb)
+
+ def __timeout_cb(self):
+ self._timeout_sid = 0
+ settings = {}
+ settings['username'] = self._username_entry.entry.get_text()
+ settings['password'] = self._password_entry.entry.get_text()
+ settings['number'] = self._number_entry.entry.get_text()
+ settings['apn'] = self._apn_entry.entry.get_text()
+ settings['pin'] = self._pin_entry.entry.get_text()
+ self._model.set_modem_settings(settings)
diff --git a/extensions/cpsection/network/Makefile.am b/extensions/cpsection/network/Makefile.am
new file mode 100644
index 0000000..35fd27c
--- /dev/null
+++ b/extensions/cpsection/network/Makefile.am
@@ -0,0 +1,6 @@
+sugardir = $(pkgdatadir)/extensions/cpsection/network
+
+sugar_PYTHON = \
+ __init__.py \
+ model.py \
+ view.py
diff --git a/extensions/cpsection/network/Makefile.in b/extensions/cpsection/network/Makefile.in
new file mode 100644
index 0000000..7194a98
--- /dev/null
+++ b/extensions/cpsection/network/Makefile.in
@@ -0,0 +1,442 @@
+# Makefile.in generated by automake 1.11.3 from Makefile.am.
+# @configure_input@
+
+# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002,
+# 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011 Free Software
+# Foundation, Inc.
+# This Makefile.in is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
+# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
+# PARTICULAR PURPOSE.
+
+@SET_MAKE@
+VPATH = @srcdir@
+pkgdatadir = $(datadir)/@PACKAGE@
+pkgincludedir = $(includedir)/@PACKAGE@
+pkglibdir = $(libdir)/@PACKAGE@
+pkglibexecdir = $(libexecdir)/@PACKAGE@
+am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd
+install_sh_DATA = $(install_sh) -c -m 644
+install_sh_PROGRAM = $(install_sh) -c
+install_sh_SCRIPT = $(install_sh) -c
+INSTALL_HEADER = $(INSTALL_DATA)
+transform = $(program_transform_name)
+NORMAL_INSTALL = :
+PRE_INSTALL = :
+POST_INSTALL = :
+NORMAL_UNINSTALL = :
+PRE_UNINSTALL = :
+POST_UNINSTALL = :
+subdir = extensions/cpsection/network
+DIST_COMMON = $(srcdir)/Makefile.am $(srcdir)/Makefile.in \
+ $(sugar_PYTHON)
+ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
+am__aclocal_m4_deps = $(top_srcdir)/configure.ac
+am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
+ $(ACLOCAL_M4)
+mkinstalldirs = $(install_sh) -d
+CONFIG_CLEAN_FILES =
+CONFIG_CLEAN_VPATH_FILES =
+SOURCES =
+DIST_SOURCES =
+am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`;
+am__vpath_adj = case $$p in \
+ $(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \
+ *) f=$$p;; \
+ esac;
+am__strip_dir = f=`echo $$p | sed -e 's|^.*/||'`;
+am__install_max = 40
+am__nobase_strip_setup = \
+ srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*|]/\\\\&/g'`
+am__nobase_strip = \
+ for p in $$list; do echo "$$p"; done | sed -e "s|$$srcdirstrip/||"
+am__nobase_list = $(am__nobase_strip_setup); \
+ for p in $$list; do echo "$$p $$p"; done | \
+ sed "s| $$srcdirstrip/| |;"' / .*\//!s/ .*/ ./; s,\( .*\)/[^/]*$$,\1,' | \
+ $(AWK) 'BEGIN { files["."] = "" } { files[$$2] = files[$$2] " " $$1; \
+ if (++n[$$2] == $(am__install_max)) \
+ { print $$2, files[$$2]; n[$$2] = 0; files[$$2] = "" } } \
+ END { for (dir in files) print dir, files[dir] }'
+am__base_list = \
+ sed '$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;s/\n/ /g' | \
+ sed '$$!N;$$!N;$$!N;$$!N;s/\n/ /g'
+am__uninstall_files_from_dir = { \
+ test -z "$$files" \
+ || { test ! -d "$$dir" && test ! -f "$$dir" && test ! -r "$$dir"; } \
+ || { echo " ( cd '$$dir' && rm -f" $$files ")"; \
+ $(am__cd) "$$dir" && rm -f $$files; }; \
+ }
+am__py_compile = PYTHON=$(PYTHON) $(SHELL) $(py_compile)
+am__installdirs = "$(DESTDIR)$(sugardir)"
+py_compile = $(top_srcdir)/py-compile
+DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
+ACLOCAL = @ACLOCAL@
+ALL_LINGUAS = @ALL_LINGUAS@
+AMTAR = @AMTAR@
+AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@
+AUTOCONF = @AUTOCONF@
+AUTOHEADER = @AUTOHEADER@
+AUTOMAKE = @AUTOMAKE@
+AWK = @AWK@
+CATALOGS = @CATALOGS@
+CATOBJEXT = @CATOBJEXT@
+CC = @CC@
+CCDEPMODE = @CCDEPMODE@
+CFLAGS = @CFLAGS@
+CPP = @CPP@
+CPPFLAGS = @CPPFLAGS@
+CYGPATH_W = @CYGPATH_W@
+DATADIRNAME = @DATADIRNAME@
+DEFS = @DEFS@
+DEPDIR = @DEPDIR@
+ECHO_C = @ECHO_C@
+ECHO_N = @ECHO_N@
+ECHO_T = @ECHO_T@
+EGREP = @EGREP@
+EXEEXT = @EXEEXT@
+GCONFTOOL = @GCONFTOOL@
+GCONF_SCHEMA_CONFIG_SOURCE = @GCONF_SCHEMA_CONFIG_SOURCE@
+GCONF_SCHEMA_FILE_DIR = @GCONF_SCHEMA_FILE_DIR@
+GETTEXT_PACKAGE = @GETTEXT_PACKAGE@
+GMOFILES = @GMOFILES@
+GMSGFMT = @GMSGFMT@
+GREP = @GREP@
+INSTALL = @INSTALL@
+INSTALL_DATA = @INSTALL_DATA@
+INSTALL_PROGRAM = @INSTALL_PROGRAM@
+INSTALL_SCRIPT = @INSTALL_SCRIPT@
+INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@
+INSTOBJEXT = @INSTOBJEXT@
+INTLLIBS = @INTLLIBS@
+INTLTOOL_EXTRACT = @INTLTOOL_EXTRACT@
+INTLTOOL_MERGE = @INTLTOOL_MERGE@
+INTLTOOL_PERL = @INTLTOOL_PERL@
+INTLTOOL_UPDATE = @INTLTOOL_UPDATE@
+INTLTOOL_V_MERGE = @INTLTOOL_V_MERGE@
+INTLTOOL_V_MERGE_OPTIONS = @INTLTOOL_V_MERGE_OPTIONS@
+INTLTOOL__v_MERGE_ = @INTLTOOL__v_MERGE_@
+INTLTOOL__v_MERGE_0 = @INTLTOOL__v_MERGE_0@
+LDFLAGS = @LDFLAGS@
+LIBOBJS = @LIBOBJS@
+LIBS = @LIBS@
+LTLIBOBJS = @LTLIBOBJS@
+MAINT = @MAINT@
+MAKEINFO = @MAKEINFO@
+MKDIR_P = @MKDIR_P@
+MKINSTALLDIRS = @MKINSTALLDIRS@
+MSGFMT = @MSGFMT@
+MSGFMT_OPTS = @MSGFMT_OPTS@
+MSGMERGE = @MSGMERGE@
+OBJEXT = @OBJEXT@
+PACKAGE = @PACKAGE@
+PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@
+PACKAGE_NAME = @PACKAGE_NAME@
+PACKAGE_STRING = @PACKAGE_STRING@
+PACKAGE_TARNAME = @PACKAGE_TARNAME@
+PACKAGE_URL = @PACKAGE_URL@
+PACKAGE_VERSION = @PACKAGE_VERSION@
+PATH_SEPARATOR = @PATH_SEPARATOR@
+PKG_CONFIG = @PKG_CONFIG@
+PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@
+PKG_CONFIG_PATH = @PKG_CONFIG_PATH@
+POFILES = @POFILES@
+POSUB = @POSUB@
+PO_IN_DATADIR_FALSE = @PO_IN_DATADIR_FALSE@
+PO_IN_DATADIR_TRUE = @PO_IN_DATADIR_TRUE@
+PYTHON = @PYTHON@
+PYTHON_EXEC_PREFIX = @PYTHON_EXEC_PREFIX@
+PYTHON_PLATFORM = @PYTHON_PLATFORM@
+PYTHON_PREFIX = @PYTHON_PREFIX@
+PYTHON_VERSION = @PYTHON_VERSION@
+SET_MAKE = @SET_MAKE@
+SHELL = @SHELL@
+SHELL_CFLAGS = @SHELL_CFLAGS@
+SHELL_LIBS = @SHELL_LIBS@
+STRIP = @STRIP@
+SUCROSE_VERSION = @SUCROSE_VERSION@
+USE_NLS = @USE_NLS@
+VERSION = @VERSION@
+XGETTEXT = @XGETTEXT@
+abs_builddir = @abs_builddir@
+abs_srcdir = @abs_srcdir@
+abs_top_builddir = @abs_top_builddir@
+abs_top_srcdir = @abs_top_srcdir@
+ac_ct_CC = @ac_ct_CC@
+am__include = @am__include@
+am__leading_dot = @am__leading_dot@
+am__quote = @am__quote@
+am__tar = @am__tar@
+am__untar = @am__untar@
+bindir = @bindir@
+build_alias = @build_alias@
+builddir = @builddir@
+datadir = @datadir@
+datarootdir = @datarootdir@
+docdir = @docdir@
+dvidir = @dvidir@
+exec_prefix = @exec_prefix@
+host_alias = @host_alias@
+htmldir = @htmldir@
+includedir = @includedir@
+infodir = @infodir@
+install_sh = @install_sh@
+intltool__v_merge_options_ = @intltool__v_merge_options_@
+intltool__v_merge_options_0 = @intltool__v_merge_options_0@
+libdir = @libdir@
+libexecdir = @libexecdir@
+localedir = @localedir@
+localstatedir = @localstatedir@
+mandir = @mandir@
+mkdir_p = @mkdir_p@
+oldincludedir = @oldincludedir@
+pdfdir = @pdfdir@
+pkgpyexecdir = @pkgpyexecdir@
+pkgpythondir = @pkgpythondir@
+prefix = @prefix@
+program_transform_name = @program_transform_name@
+psdir = @psdir@
+pyexecdir = @pyexecdir@
+pythondir = @pythondir@
+sbindir = @sbindir@
+sharedstatedir = @sharedstatedir@
+srcdir = @srcdir@
+sysconfdir = @sysconfdir@
+target_alias = @target_alias@
+top_build_prefix = @top_build_prefix@
+top_builddir = @top_builddir@
+top_srcdir = @top_srcdir@
+sugardir = $(pkgdatadir)/extensions/cpsection/network
+sugar_PYTHON = \
+ __init__.py \
+ model.py \
+ view.py
+
+all: all-am
+
+.SUFFIXES:
+$(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ $(srcdir)/Makefile.am $(am__configure_deps)
+ @for dep in $?; do \
+ case '$(am__configure_deps)' in \
+ *$$dep*) \
+ ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \
+ && { if test -f $@; then exit 0; else break; fi; }; \
+ exit 1;; \
+ esac; \
+ done; \
+ echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign extensions/cpsection/network/Makefile'; \
+ $(am__cd) $(top_srcdir) && \
+ $(AUTOMAKE) --foreign extensions/cpsection/network/Makefile
+.PRECIOUS: Makefile
+Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
+ @case '$?' in \
+ *config.status*) \
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \
+ *) \
+ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \
+ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \
+ esac;
+
+$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES)
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+
+$(top_srcdir)/configure: @MAINTAINER_MODE_TRUE@ $(am__configure_deps)
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+$(ACLOCAL_M4): @MAINTAINER_MODE_TRUE@ $(am__aclocal_m4_deps)
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+$(am__aclocal_m4_deps):
+install-sugarPYTHON: $(sugar_PYTHON)
+ @$(NORMAL_INSTALL)
+ test -z "$(sugardir)" || $(MKDIR_P) "$(DESTDIR)$(sugardir)"
+ @list='$(sugar_PYTHON)'; dlist=; list2=; test -n "$(sugardir)" || list=; \
+ for p in $$list; do \
+ if test -f "$$p"; then b=; else b="$(srcdir)/"; fi; \
+ if test -f $$b$$p; then \
+ $(am__strip_dir) \
+ dlist="$$dlist $$f"; \
+ list2="$$list2 $$b$$p"; \
+ else :; fi; \
+ done; \
+ for file in $$list2; do echo $$file; done | $(am__base_list) | \
+ while read files; do \
+ echo " $(INSTALL_DATA) $$files '$(DESTDIR)$(sugardir)'"; \
+ $(INSTALL_DATA) $$files "$(DESTDIR)$(sugardir)" || exit $$?; \
+ done || exit $$?; \
+ if test -n "$$dlist"; then \
+ $(am__py_compile) --destdir "$(DESTDIR)" \
+ --basedir "$(sugardir)" $$dlist; \
+ else :; fi
+
+uninstall-sugarPYTHON:
+ @$(NORMAL_UNINSTALL)
+ @list='$(sugar_PYTHON)'; test -n "$(sugardir)" || list=; \
+ files=`for p in $$list; do echo $$p; done | sed -e 's|^.*/||'`; \
+ test -n "$$files" || exit 0; \
+ dir='$(DESTDIR)$(sugardir)'; \
+ filesc=`echo "$$files" | sed 's|$$|c|'`; \
+ fileso=`echo "$$files" | sed 's|$$|o|'`; \
+ st=0; \
+ for files in "$$files" "$$filesc" "$$fileso"; do \
+ $(am__uninstall_files_from_dir) || st=$$?; \
+ done; \
+ exit $$st
+tags: TAGS
+TAGS:
+
+ctags: CTAGS
+CTAGS:
+
+
+distdir: $(DISTFILES)
+ @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
+ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
+ list='$(DISTFILES)'; \
+ dist_files=`for file in $$list; do echo $$file; done | \
+ sed -e "s|^$$srcdirstrip/||;t" \
+ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \
+ case $$dist_files in \
+ */*) $(MKDIR_P) `echo "$$dist_files" | \
+ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \
+ sort -u` ;; \
+ esac; \
+ for file in $$dist_files; do \
+ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \
+ if test -d $$d/$$file; then \
+ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \
+ if test -d "$(distdir)/$$file"; then \
+ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \
+ fi; \
+ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \
+ cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \
+ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \
+ fi; \
+ cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \
+ else \
+ test -f "$(distdir)/$$file" \
+ || cp -p $$d/$$file "$(distdir)/$$file" \
+ || exit 1; \
+ fi; \
+ done
+check-am: all-am
+check: check-am
+all-am: Makefile
+installdirs:
+ for dir in "$(DESTDIR)$(sugardir)"; do \
+ test -z "$$dir" || $(MKDIR_P) "$$dir"; \
+ done
+install: install-am
+install-exec: install-exec-am
+install-data: install-data-am
+uninstall: uninstall-am
+
+install-am: all-am
+ @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am
+
+installcheck: installcheck-am
+install-strip:
+ if test -z '$(STRIP)'; then \
+ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
+ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
+ install; \
+ else \
+ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
+ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
+ "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \
+ fi
+mostlyclean-generic:
+
+clean-generic:
+
+distclean-generic:
+ -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES)
+ -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES)
+
+maintainer-clean-generic:
+ @echo "This command is intended for maintainers to use"
+ @echo "it deletes files that may require special tools to rebuild."
+clean: clean-am
+
+clean-am: clean-generic mostlyclean-am
+
+distclean: distclean-am
+ -rm -f Makefile
+distclean-am: clean-am distclean-generic
+
+dvi: dvi-am
+
+dvi-am:
+
+html: html-am
+
+html-am:
+
+info: info-am
+
+info-am:
+
+install-data-am: install-sugarPYTHON
+
+install-dvi: install-dvi-am
+
+install-dvi-am:
+
+install-exec-am:
+
+install-html: install-html-am
+
+install-html-am:
+
+install-info: install-info-am
+
+install-info-am:
+
+install-man:
+
+install-pdf: install-pdf-am
+
+install-pdf-am:
+
+install-ps: install-ps-am
+
+install-ps-am:
+
+installcheck-am:
+
+maintainer-clean: maintainer-clean-am
+ -rm -f Makefile
+maintainer-clean-am: distclean-am maintainer-clean-generic
+
+mostlyclean: mostlyclean-am
+
+mostlyclean-am: mostlyclean-generic
+
+pdf: pdf-am
+
+pdf-am:
+
+ps: ps-am
+
+ps-am:
+
+uninstall-am: uninstall-sugarPYTHON
+
+.MAKE: install-am install-strip
+
+.PHONY: all all-am check check-am clean clean-generic distclean \
+ distclean-generic distdir dvi dvi-am html html-am info info-am \
+ install install-am install-data install-data-am install-dvi \
+ install-dvi-am install-exec install-exec-am install-html \
+ install-html-am install-info install-info-am install-man \
+ install-pdf install-pdf-am install-ps install-ps-am \
+ install-strip install-sugarPYTHON installcheck installcheck-am \
+ installdirs maintainer-clean maintainer-clean-generic \
+ mostlyclean mostlyclean-generic pdf pdf-am ps ps-am uninstall \
+ uninstall-am uninstall-sugarPYTHON
+
+
+# Tell versions [3.59,3.63) of GNU make to not export all variables.
+# Otherwise a system limit (for SysV at least) may be exceeded.
+.NOEXPORT:
diff --git a/extensions/cpsection/network/__init__.py b/extensions/cpsection/network/__init__.py
new file mode 100644
index 0000000..86546f7
--- /dev/null
+++ b/extensions/cpsection/network/__init__.py
@@ -0,0 +1,22 @@
+# Copyright (C) 2006-2007, Red Hat, Inc.
+#
+# 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 2 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, write to the Free Software
+# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+
+from gettext import gettext as _
+
+CLASS = 'Network'
+ICON = 'module-network'
+TITLE = _('Network')
+KEYWORDS = ['network', 'jabber', 'radio', 'server']
diff --git a/extensions/cpsection/network/model.py b/extensions/cpsection/network/model.py
new file mode 100644
index 0000000..4ddab35
--- /dev/null
+++ b/extensions/cpsection/network/model.py
@@ -0,0 +1,156 @@
+# Copyright (C) 2008 One Laptop Per Child
+#
+# 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 2 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, write to the Free Software
+# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+#
+
+import logging
+
+import dbus
+from gettext import gettext as _
+import gconf
+
+from jarabe.model import network
+
+
+_NM_SERVICE = 'org.freedesktop.NetworkManager'
+_NM_PATH = '/org/freedesktop/NetworkManager'
+_NM_IFACE = 'org.freedesktop.NetworkManager'
+
+KEYWORDS = ['network', 'jabber', 'radio', 'server']
+
+
+class ReadError(Exception):
+ def __init__(self, value):
+ self.value = value
+
+ def __str__(self):
+ return repr(self.value)
+
+
+def get_jabber():
+ client = gconf.client_get_default()
+ return client.get_string('/desktop/sugar/collaboration/jabber_server')
+
+
+def print_jabber():
+ print get_jabber()
+
+
+def set_jabber(server):
+ """Set the jabber server
+ server : e.g. 'olpc.collabora.co.uk'
+ """
+ client = gconf.client_get_default()
+ client.set_string('/desktop/sugar/collaboration/jabber_server', server)
+
+ return 0
+
+
+def get_radio():
+ try:
+ bus = dbus.SystemBus()
+ obj = bus.get_object(_NM_SERVICE, _NM_PATH)
+ nm_props = dbus.Interface(obj, dbus.PROPERTIES_IFACE)
+ except dbus.DBusException:
+ raise ReadError('%s service not available' % _NM_SERVICE)
+
+ state = nm_props.Get(_NM_IFACE, 'WirelessEnabled')
+ if state in (0, 1):
+ return state
+ else:
+ raise ReadError(_('State is unknown.'))
+
+
+def print_radio():
+ print ('off', 'on')[get_radio()]
+
+
+def set_radio(state):
+ """Turn Radio 'on' or 'off'
+ state : 'on/off'
+ """
+ if state == 'on' or state == 1:
+ try:
+ bus = dbus.SystemBus()
+ obj = bus.get_object(_NM_SERVICE, _NM_PATH)
+ nm_props = dbus.Interface(obj, dbus.PROPERTIES_IFACE)
+ except dbus.DBusException:
+ raise ReadError('%s service not available' % _NM_SERVICE)
+ nm_props.Set(_NM_IFACE, 'WirelessEnabled', True)
+ elif state == 'off' or state == 0:
+ try:
+ bus = dbus.SystemBus()
+ obj = bus.get_object(_NM_SERVICE, _NM_PATH)
+ nm_props = dbus.Interface(obj, dbus.PROPERTIES_IFACE)
+ except dbus.DBusException:
+ raise ReadError('%s service not available' % _NM_SERVICE)
+ nm_props.Set(_NM_IFACE, 'WirelessEnabled', False)
+ else:
+ raise ValueError(_('Error in specified radio argument use on/off.'))
+
+ return 0
+
+
+def clear_registration():
+ """Clear the registration with the schoolserver
+ """
+ client = gconf.client_get_default()
+ client.set_string('/desktop/sugar/backup_url', '')
+ return 1
+
+
+def clear_networks():
+ """Clear saved passwords and network configurations.
+ """
+ try:
+ connections = network.get_connections()
+ except dbus.DBusException:
+ logging.debug('NetworkManager not available')
+ return
+ connections.clear()
+
+
+def have_networks():
+ try:
+ connections = network.get_connections()
+ return len(connections.get_list()) > 0
+ except dbus.DBusException:
+ logging.debug('NetworkManager not available')
+ return False
+
+
+def get_publish_information():
+ client = gconf.client_get_default()
+ publish = client.get_bool('/desktop/sugar/collaboration/publish_gadget')
+ return publish
+
+
+def print_publish_information():
+ print get_publish_information()
+
+
+def set_publish_information(value):
+ """ If set to true, Sugar will make you searchable for
+ the other users of the Jabber server.
+ value: 0/1
+ """
+ try:
+ value = (False, True)[int(value)]
+ except:
+ raise ValueError(_('Error in specified argument use 0/1.'))
+
+ client = gconf.client_get_default()
+ client.set_bool('/desktop/sugar/collaboration/publish_gadget', value)
+ return 0
diff --git a/extensions/cpsection/network/view.py b/extensions/cpsection/network/view.py
new file mode 100644
index 0000000..381dcb6
--- /dev/null
+++ b/extensions/cpsection/network/view.py
@@ -0,0 +1,261 @@
+# Copyright (C) 2008, OLPC
+#
+# 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 2 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, write to the Free Software
+# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+
+import gtk
+import gobject
+from gettext import gettext as _
+
+from sugar.graphics import style
+
+from jarabe.controlpanel.sectionview import SectionView
+from jarabe.controlpanel.inlinealert import InlineAlert
+
+
+CLASS = 'Network'
+ICON = 'module-network'
+TITLE = _('Network')
+
+_APPLY_TIMEOUT = 3000
+
+
+class Network(SectionView):
+ def __init__(self, model, alerts):
+ SectionView.__init__(self)
+
+ self._model = model
+ self.restart_alerts = alerts
+ self._jabber_sid = 0
+ self._jabber_valid = True
+ self._radio_valid = True
+ self._jabber_change_handler = None
+ self._radio_change_handler = None
+ self._network_configuration_reset_handler = None
+
+ self.set_border_width(style.DEFAULT_SPACING * 2)
+ self.set_spacing(style.DEFAULT_SPACING)
+ group = gtk.SizeGroup(gtk.SIZE_GROUP_HORIZONTAL)
+
+ self._radio_alert_box = gtk.HBox(spacing=style.DEFAULT_SPACING)
+ self._jabber_alert_box = gtk.HBox(spacing=style.DEFAULT_SPACING)
+
+ workspace = gtk.VBox()
+ workspace.show()
+
+ separator_wireless = gtk.HSeparator()
+ workspace.pack_start(separator_wireless, expand=False)
+ separator_wireless.show()
+
+ label_wireless = gtk.Label(_('Wireless'))
+ label_wireless.set_alignment(0, 0)
+ workspace.pack_start(label_wireless, expand=False)
+ label_wireless.show()
+ box_wireless = gtk.VBox()
+ box_wireless.set_border_width(style.DEFAULT_SPACING * 2)
+ box_wireless.set_spacing(style.DEFAULT_SPACING)
+
+ radio_info = gtk.Label(_('Turn off the wireless radio to save battery'
+ ' life'))
+ radio_info.set_alignment(0, 0)
+ radio_info.set_line_wrap(True)
+ radio_info.show()
+ box_wireless.pack_start(radio_info, expand=False)
+
+ box_radio = gtk.HBox(spacing=style.DEFAULT_SPACING)
+ self._button = gtk.CheckButton()
+ self._button.set_alignment(0, 0)
+ box_radio.pack_start(self._button, expand=False)
+ self._button.show()
+
+ label_radio = gtk.Label(_('Radio'))
+ label_radio.set_alignment(0, 0.5)
+ box_radio.pack_start(label_radio, expand=False)
+ label_radio.show()
+
+ box_wireless.pack_start(box_radio, expand=False)
+ box_radio.show()
+
+ self._radio_alert = InlineAlert()
+ self._radio_alert_box.pack_start(self._radio_alert, expand=False)
+ box_radio.pack_end(self._radio_alert_box, expand=False)
+ self._radio_alert_box.show()
+ if 'radio' in self.restart_alerts:
+ self._radio_alert.props.msg = self.restart_msg
+ self._radio_alert.show()
+
+ history_info = gtk.Label(_('Discard network history if you have'
+ ' trouble connecting to the network'))
+ history_info.set_alignment(0, 0)
+ history_info.set_line_wrap(True)
+ history_info.show()
+ box_wireless.pack_start(history_info, expand=False)
+
+ box_clear_history = gtk.HBox(spacing=style.DEFAULT_SPACING)
+ self._clear_history_button = gtk.Button()
+ self._clear_history_button.set_label(_('Discard network history'))
+ box_clear_history.pack_start(self._clear_history_button, expand=False)
+ if not self._model.have_networks():
+ self._clear_history_button.set_sensitive(False)
+ self._clear_history_button.show()
+ box_wireless.pack_start(box_clear_history, expand=False)
+ box_clear_history.show()
+
+ workspace.pack_start(box_wireless, expand=False)
+ box_wireless.show()
+
+ separator_mesh = gtk.HSeparator()
+ workspace.pack_start(separator_mesh, False)
+ separator_mesh.show()
+
+ label_mesh = gtk.Label(_('Collaboration'))
+ label_mesh.set_alignment(0, 0)
+ workspace.pack_start(label_mesh, expand=False)
+ label_mesh.show()
+ box_mesh = gtk.VBox()
+ box_mesh.set_border_width(style.DEFAULT_SPACING * 2)
+ box_mesh.set_spacing(style.DEFAULT_SPACING)
+
+ server_info = gtk.Label(_("The server is the equivalent of what"
+ " room you are in; people on the same server"
+ " will be able to see each other, even when"
+ " they aren't on the same network."))
+ server_info.set_alignment(0, 0)
+ server_info.set_line_wrap(True)
+ box_mesh.pack_start(server_info, expand=False)
+ server_info.show()
+
+ box_server = gtk.HBox(spacing=style.DEFAULT_SPACING)
+ label_server = gtk.Label(_('Server:'))
+ label_server.set_alignment(1, 0.5)
+ label_server.modify_fg(gtk.STATE_NORMAL,
+ style.COLOR_SELECTION_GREY.get_gdk_color())
+ box_server.pack_start(label_server, expand=False)
+ group.add_widget(label_server)
+ label_server.show()
+ self._entry = gtk.Entry()
+ self._entry.set_alignment(0)
+ self._entry.modify_bg(gtk.STATE_INSENSITIVE,
+ style.COLOR_WHITE.get_gdk_color())
+ self._entry.modify_base(gtk.STATE_INSENSITIVE,
+ style.COLOR_WHITE.get_gdk_color())
+ self._entry.set_size_request(int(gtk.gdk.screen_width() / 3), -1)
+ box_server.pack_start(self._entry, expand=False)
+ self._entry.show()
+ box_mesh.pack_start(box_server, expand=False)
+ box_server.show()
+
+ self._jabber_alert = InlineAlert()
+ label_jabber_error = gtk.Label()
+ group.add_widget(label_jabber_error)
+ self._jabber_alert_box.pack_start(label_jabber_error, expand=False)
+ label_jabber_error.show()
+ self._jabber_alert_box.pack_start(self._jabber_alert, expand=False)
+ box_mesh.pack_end(self._jabber_alert_box, expand=False)
+ self._jabber_alert_box.show()
+ if 'jabber' in self.restart_alerts:
+ self._jabber_alert.props.msg = self.restart_msg
+ self._jabber_alert.show()
+
+ workspace.pack_start(box_mesh, expand=False)
+ box_mesh.show()
+
+ scrolled = gtk.ScrolledWindow()
+ scrolled.set_policy(gtk.POLICY_NEVER, gtk.POLICY_AUTOMATIC)
+ scrolled.add_with_viewport(workspace)
+ scrolled.show()
+ self.add(scrolled)
+
+ self.setup()
+
+ def setup(self):
+ self._entry.set_text(self._model.get_jabber())
+ try:
+ radio_state = self._model.get_radio()
+ except self._model.ReadError, detail:
+ self._radio_alert.props.msg = detail
+ self._radio_alert.show()
+ else:
+ self._button.set_active(radio_state)
+
+ self._jabber_valid = True
+ self._radio_valid = True
+ self.needs_restart = False
+ self._radio_change_handler = self._button.connect( \
+ 'toggled', self.__radio_toggled_cb)
+ self._jabber_change_handler = self._entry.connect( \
+ 'changed', self.__jabber_changed_cb)
+ self._network_configuration_reset_handler = \
+ self._clear_history_button.connect( \
+ 'clicked', self.__network_configuration_reset_cb)
+
+ def undo(self):
+ self._button.disconnect(self._radio_change_handler)
+ self._entry.disconnect(self._jabber_change_handler)
+ self._model.undo()
+ self._jabber_alert.hide()
+ self._radio_alert.hide()
+
+ def _validate(self):
+ if self._jabber_valid and self._radio_valid:
+ self.props.is_valid = True
+ else:
+ self.props.is_valid = False
+
+ def __radio_toggled_cb(self, widget, data=None):
+ radio_state = widget.get_active()
+ try:
+ self._model.set_radio(radio_state)
+ except self._model.ReadError, detail:
+ self._radio_alert.props.msg = detail
+ self._radio_valid = False
+ else:
+ self._radio_valid = True
+ if self._model.have_networks():
+ self._clear_history_button.set_sensitive(True)
+
+ self._validate()
+ return False
+
+ def __jabber_changed_cb(self, widget, data=None):
+ if self._jabber_sid:
+ gobject.source_remove(self._jabber_sid)
+ self._jabber_sid = gobject.timeout_add(_APPLY_TIMEOUT,
+ self.__jabber_timeout_cb,
+ widget)
+
+ def __jabber_timeout_cb(self, widget):
+ self._jabber_sid = 0
+ if widget.get_text() == self._model.get_jabber:
+ return
+ try:
+ self._model.set_jabber(widget.get_text())
+ except self._model.ReadError, detail:
+ self._jabber_alert.props.msg = detail
+ self._jabber_valid = False
+ self._jabber_alert.show()
+ self.restart_alerts.append('jabber')
+ else:
+ self._jabber_valid = True
+ self._jabber_alert.hide()
+
+ self._validate()
+ return False
+
+ def __network_configuration_reset_cb(self, widget):
+ # FIXME: takes effect immediately, not after CP is closed with
+ # confirmation button
+ self._model.clear_networks()
+ if not self._model.have_networks():
+ self._clear_history_button.set_sensitive(False)
diff --git a/extensions/cpsection/power/Makefile.am b/extensions/cpsection/power/Makefile.am
new file mode 100644
index 0000000..325260c
--- /dev/null
+++ b/extensions/cpsection/power/Makefile.am
@@ -0,0 +1,6 @@
+sugardir = $(pkgdatadir)/extensions/cpsection/power
+
+sugar_PYTHON = \
+ __init__.py \
+ model.py \
+ view.py
diff --git a/extensions/cpsection/power/Makefile.in b/extensions/cpsection/power/Makefile.in
new file mode 100644
index 0000000..52c52e5
--- /dev/null
+++ b/extensions/cpsection/power/Makefile.in
@@ -0,0 +1,442 @@
+# Makefile.in generated by automake 1.11.3 from Makefile.am.
+# @configure_input@
+
+# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002,
+# 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011 Free Software
+# Foundation, Inc.
+# This Makefile.in is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
+# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
+# PARTICULAR PURPOSE.
+
+@SET_MAKE@
+VPATH = @srcdir@
+pkgdatadir = $(datadir)/@PACKAGE@
+pkgincludedir = $(includedir)/@PACKAGE@
+pkglibdir = $(libdir)/@PACKAGE@
+pkglibexecdir = $(libexecdir)/@PACKAGE@
+am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd
+install_sh_DATA = $(install_sh) -c -m 644
+install_sh_PROGRAM = $(install_sh) -c
+install_sh_SCRIPT = $(install_sh) -c
+INSTALL_HEADER = $(INSTALL_DATA)
+transform = $(program_transform_name)
+NORMAL_INSTALL = :
+PRE_INSTALL = :
+POST_INSTALL = :
+NORMAL_UNINSTALL = :
+PRE_UNINSTALL = :
+POST_UNINSTALL = :
+subdir = extensions/cpsection/power
+DIST_COMMON = $(srcdir)/Makefile.am $(srcdir)/Makefile.in \
+ $(sugar_PYTHON)
+ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
+am__aclocal_m4_deps = $(top_srcdir)/configure.ac
+am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
+ $(ACLOCAL_M4)
+mkinstalldirs = $(install_sh) -d
+CONFIG_CLEAN_FILES =
+CONFIG_CLEAN_VPATH_FILES =
+SOURCES =
+DIST_SOURCES =
+am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`;
+am__vpath_adj = case $$p in \
+ $(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \
+ *) f=$$p;; \
+ esac;
+am__strip_dir = f=`echo $$p | sed -e 's|^.*/||'`;
+am__install_max = 40
+am__nobase_strip_setup = \
+ srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*|]/\\\\&/g'`
+am__nobase_strip = \
+ for p in $$list; do echo "$$p"; done | sed -e "s|$$srcdirstrip/||"
+am__nobase_list = $(am__nobase_strip_setup); \
+ for p in $$list; do echo "$$p $$p"; done | \
+ sed "s| $$srcdirstrip/| |;"' / .*\//!s/ .*/ ./; s,\( .*\)/[^/]*$$,\1,' | \
+ $(AWK) 'BEGIN { files["."] = "" } { files[$$2] = files[$$2] " " $$1; \
+ if (++n[$$2] == $(am__install_max)) \
+ { print $$2, files[$$2]; n[$$2] = 0; files[$$2] = "" } } \
+ END { for (dir in files) print dir, files[dir] }'
+am__base_list = \
+ sed '$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;s/\n/ /g' | \
+ sed '$$!N;$$!N;$$!N;$$!N;s/\n/ /g'
+am__uninstall_files_from_dir = { \
+ test -z "$$files" \
+ || { test ! -d "$$dir" && test ! -f "$$dir" && test ! -r "$$dir"; } \
+ || { echo " ( cd '$$dir' && rm -f" $$files ")"; \
+ $(am__cd) "$$dir" && rm -f $$files; }; \
+ }
+am__py_compile = PYTHON=$(PYTHON) $(SHELL) $(py_compile)
+am__installdirs = "$(DESTDIR)$(sugardir)"
+py_compile = $(top_srcdir)/py-compile
+DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
+ACLOCAL = @ACLOCAL@
+ALL_LINGUAS = @ALL_LINGUAS@
+AMTAR = @AMTAR@
+AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@
+AUTOCONF = @AUTOCONF@
+AUTOHEADER = @AUTOHEADER@
+AUTOMAKE = @AUTOMAKE@
+AWK = @AWK@
+CATALOGS = @CATALOGS@
+CATOBJEXT = @CATOBJEXT@
+CC = @CC@
+CCDEPMODE = @CCDEPMODE@
+CFLAGS = @CFLAGS@
+CPP = @CPP@
+CPPFLAGS = @CPPFLAGS@
+CYGPATH_W = @CYGPATH_W@
+DATADIRNAME = @DATADIRNAME@
+DEFS = @DEFS@
+DEPDIR = @DEPDIR@
+ECHO_C = @ECHO_C@
+ECHO_N = @ECHO_N@
+ECHO_T = @ECHO_T@
+EGREP = @EGREP@
+EXEEXT = @EXEEXT@
+GCONFTOOL = @GCONFTOOL@
+GCONF_SCHEMA_CONFIG_SOURCE = @GCONF_SCHEMA_CONFIG_SOURCE@
+GCONF_SCHEMA_FILE_DIR = @GCONF_SCHEMA_FILE_DIR@
+GETTEXT_PACKAGE = @GETTEXT_PACKAGE@
+GMOFILES = @GMOFILES@
+GMSGFMT = @GMSGFMT@
+GREP = @GREP@
+INSTALL = @INSTALL@
+INSTALL_DATA = @INSTALL_DATA@
+INSTALL_PROGRAM = @INSTALL_PROGRAM@
+INSTALL_SCRIPT = @INSTALL_SCRIPT@
+INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@
+INSTOBJEXT = @INSTOBJEXT@
+INTLLIBS = @INTLLIBS@
+INTLTOOL_EXTRACT = @INTLTOOL_EXTRACT@
+INTLTOOL_MERGE = @INTLTOOL_MERGE@
+INTLTOOL_PERL = @INTLTOOL_PERL@
+INTLTOOL_UPDATE = @INTLTOOL_UPDATE@
+INTLTOOL_V_MERGE = @INTLTOOL_V_MERGE@
+INTLTOOL_V_MERGE_OPTIONS = @INTLTOOL_V_MERGE_OPTIONS@
+INTLTOOL__v_MERGE_ = @INTLTOOL__v_MERGE_@
+INTLTOOL__v_MERGE_0 = @INTLTOOL__v_MERGE_0@
+LDFLAGS = @LDFLAGS@
+LIBOBJS = @LIBOBJS@
+LIBS = @LIBS@
+LTLIBOBJS = @LTLIBOBJS@
+MAINT = @MAINT@
+MAKEINFO = @MAKEINFO@
+MKDIR_P = @MKDIR_P@
+MKINSTALLDIRS = @MKINSTALLDIRS@
+MSGFMT = @MSGFMT@
+MSGFMT_OPTS = @MSGFMT_OPTS@
+MSGMERGE = @MSGMERGE@
+OBJEXT = @OBJEXT@
+PACKAGE = @PACKAGE@
+PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@
+PACKAGE_NAME = @PACKAGE_NAME@
+PACKAGE_STRING = @PACKAGE_STRING@
+PACKAGE_TARNAME = @PACKAGE_TARNAME@
+PACKAGE_URL = @PACKAGE_URL@
+PACKAGE_VERSION = @PACKAGE_VERSION@
+PATH_SEPARATOR = @PATH_SEPARATOR@
+PKG_CONFIG = @PKG_CONFIG@
+PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@
+PKG_CONFIG_PATH = @PKG_CONFIG_PATH@
+POFILES = @POFILES@
+POSUB = @POSUB@
+PO_IN_DATADIR_FALSE = @PO_IN_DATADIR_FALSE@
+PO_IN_DATADIR_TRUE = @PO_IN_DATADIR_TRUE@
+PYTHON = @PYTHON@
+PYTHON_EXEC_PREFIX = @PYTHON_EXEC_PREFIX@
+PYTHON_PLATFORM = @PYTHON_PLATFORM@
+PYTHON_PREFIX = @PYTHON_PREFIX@
+PYTHON_VERSION = @PYTHON_VERSION@
+SET_MAKE = @SET_MAKE@
+SHELL = @SHELL@
+SHELL_CFLAGS = @SHELL_CFLAGS@
+SHELL_LIBS = @SHELL_LIBS@
+STRIP = @STRIP@
+SUCROSE_VERSION = @SUCROSE_VERSION@
+USE_NLS = @USE_NLS@
+VERSION = @VERSION@
+XGETTEXT = @XGETTEXT@
+abs_builddir = @abs_builddir@
+abs_srcdir = @abs_srcdir@
+abs_top_builddir = @abs_top_builddir@
+abs_top_srcdir = @abs_top_srcdir@
+ac_ct_CC = @ac_ct_CC@
+am__include = @am__include@
+am__leading_dot = @am__leading_dot@
+am__quote = @am__quote@
+am__tar = @am__tar@
+am__untar = @am__untar@
+bindir = @bindir@
+build_alias = @build_alias@
+builddir = @builddir@
+datadir = @datadir@
+datarootdir = @datarootdir@
+docdir = @docdir@
+dvidir = @dvidir@
+exec_prefix = @exec_prefix@
+host_alias = @host_alias@
+htmldir = @htmldir@
+includedir = @includedir@
+infodir = @infodir@
+install_sh = @install_sh@
+intltool__v_merge_options_ = @intltool__v_merge_options_@
+intltool__v_merge_options_0 = @intltool__v_merge_options_0@
+libdir = @libdir@
+libexecdir = @libexecdir@
+localedir = @localedir@
+localstatedir = @localstatedir@
+mandir = @mandir@
+mkdir_p = @mkdir_p@
+oldincludedir = @oldincludedir@
+pdfdir = @pdfdir@
+pkgpyexecdir = @pkgpyexecdir@
+pkgpythondir = @pkgpythondir@
+prefix = @prefix@
+program_transform_name = @program_transform_name@
+psdir = @psdir@
+pyexecdir = @pyexecdir@
+pythondir = @pythondir@
+sbindir = @sbindir@
+sharedstatedir = @sharedstatedir@
+srcdir = @srcdir@
+sysconfdir = @sysconfdir@
+target_alias = @target_alias@
+top_build_prefix = @top_build_prefix@
+top_builddir = @top_builddir@
+top_srcdir = @top_srcdir@
+sugardir = $(pkgdatadir)/extensions/cpsection/power
+sugar_PYTHON = \
+ __init__.py \
+ model.py \
+ view.py
+
+all: all-am
+
+.SUFFIXES:
+$(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ $(srcdir)/Makefile.am $(am__configure_deps)
+ @for dep in $?; do \
+ case '$(am__configure_deps)' in \
+ *$$dep*) \
+ ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \
+ && { if test -f $@; then exit 0; else break; fi; }; \
+ exit 1;; \
+ esac; \
+ done; \
+ echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign extensions/cpsection/power/Makefile'; \
+ $(am__cd) $(top_srcdir) && \
+ $(AUTOMAKE) --foreign extensions/cpsection/power/Makefile
+.PRECIOUS: Makefile
+Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
+ @case '$?' in \
+ *config.status*) \
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \
+ *) \
+ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \
+ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \
+ esac;
+
+$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES)
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+
+$(top_srcdir)/configure: @MAINTAINER_MODE_TRUE@ $(am__configure_deps)
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+$(ACLOCAL_M4): @MAINTAINER_MODE_TRUE@ $(am__aclocal_m4_deps)
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+$(am__aclocal_m4_deps):
+install-sugarPYTHON: $(sugar_PYTHON)
+ @$(NORMAL_INSTALL)
+ test -z "$(sugardir)" || $(MKDIR_P) "$(DESTDIR)$(sugardir)"
+ @list='$(sugar_PYTHON)'; dlist=; list2=; test -n "$(sugardir)" || list=; \
+ for p in $$list; do \
+ if test -f "$$p"; then b=; else b="$(srcdir)/"; fi; \
+ if test -f $$b$$p; then \
+ $(am__strip_dir) \
+ dlist="$$dlist $$f"; \
+ list2="$$list2 $$b$$p"; \
+ else :; fi; \
+ done; \
+ for file in $$list2; do echo $$file; done | $(am__base_list) | \
+ while read files; do \
+ echo " $(INSTALL_DATA) $$files '$(DESTDIR)$(sugardir)'"; \
+ $(INSTALL_DATA) $$files "$(DESTDIR)$(sugardir)" || exit $$?; \
+ done || exit $$?; \
+ if test -n "$$dlist"; then \
+ $(am__py_compile) --destdir "$(DESTDIR)" \
+ --basedir "$(sugardir)" $$dlist; \
+ else :; fi
+
+uninstall-sugarPYTHON:
+ @$(NORMAL_UNINSTALL)
+ @list='$(sugar_PYTHON)'; test -n "$(sugardir)" || list=; \
+ files=`for p in $$list; do echo $$p; done | sed -e 's|^.*/||'`; \
+ test -n "$$files" || exit 0; \
+ dir='$(DESTDIR)$(sugardir)'; \
+ filesc=`echo "$$files" | sed 's|$$|c|'`; \
+ fileso=`echo "$$files" | sed 's|$$|o|'`; \
+ st=0; \
+ for files in "$$files" "$$filesc" "$$fileso"; do \
+ $(am__uninstall_files_from_dir) || st=$$?; \
+ done; \
+ exit $$st
+tags: TAGS
+TAGS:
+
+ctags: CTAGS
+CTAGS:
+
+
+distdir: $(DISTFILES)
+ @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
+ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
+ list='$(DISTFILES)'; \
+ dist_files=`for file in $$list; do echo $$file; done | \
+ sed -e "s|^$$srcdirstrip/||;t" \
+ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \
+ case $$dist_files in \
+ */*) $(MKDIR_P) `echo "$$dist_files" | \
+ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \
+ sort -u` ;; \
+ esac; \
+ for file in $$dist_files; do \
+ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \
+ if test -d $$d/$$file; then \
+ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \
+ if test -d "$(distdir)/$$file"; then \
+ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \
+ fi; \
+ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \
+ cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \
+ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \
+ fi; \
+ cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \
+ else \
+ test -f "$(distdir)/$$file" \
+ || cp -p $$d/$$file "$(distdir)/$$file" \
+ || exit 1; \
+ fi; \
+ done
+check-am: all-am
+check: check-am
+all-am: Makefile
+installdirs:
+ for dir in "$(DESTDIR)$(sugardir)"; do \
+ test -z "$$dir" || $(MKDIR_P) "$$dir"; \
+ done
+install: install-am
+install-exec: install-exec-am
+install-data: install-data-am
+uninstall: uninstall-am
+
+install-am: all-am
+ @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am
+
+installcheck: installcheck-am
+install-strip:
+ if test -z '$(STRIP)'; then \
+ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
+ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
+ install; \
+ else \
+ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
+ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
+ "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \
+ fi
+mostlyclean-generic:
+
+clean-generic:
+
+distclean-generic:
+ -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES)
+ -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES)
+
+maintainer-clean-generic:
+ @echo "This command is intended for maintainers to use"
+ @echo "it deletes files that may require special tools to rebuild."
+clean: clean-am
+
+clean-am: clean-generic mostlyclean-am
+
+distclean: distclean-am
+ -rm -f Makefile
+distclean-am: clean-am distclean-generic
+
+dvi: dvi-am
+
+dvi-am:
+
+html: html-am
+
+html-am:
+
+info: info-am
+
+info-am:
+
+install-data-am: install-sugarPYTHON
+
+install-dvi: install-dvi-am
+
+install-dvi-am:
+
+install-exec-am:
+
+install-html: install-html-am
+
+install-html-am:
+
+install-info: install-info-am
+
+install-info-am:
+
+install-man:
+
+install-pdf: install-pdf-am
+
+install-pdf-am:
+
+install-ps: install-ps-am
+
+install-ps-am:
+
+installcheck-am:
+
+maintainer-clean: maintainer-clean-am
+ -rm -f Makefile
+maintainer-clean-am: distclean-am maintainer-clean-generic
+
+mostlyclean: mostlyclean-am
+
+mostlyclean-am: mostlyclean-generic
+
+pdf: pdf-am
+
+pdf-am:
+
+ps: ps-am
+
+ps-am:
+
+uninstall-am: uninstall-sugarPYTHON
+
+.MAKE: install-am install-strip
+
+.PHONY: all all-am check check-am clean clean-generic distclean \
+ distclean-generic distdir dvi dvi-am html html-am info info-am \
+ install install-am install-data install-data-am install-dvi \
+ install-dvi-am install-exec install-exec-am install-html \
+ install-html-am install-info install-info-am install-man \
+ install-pdf install-pdf-am install-ps install-ps-am \
+ install-strip install-sugarPYTHON installcheck installcheck-am \
+ installdirs maintainer-clean maintainer-clean-generic \
+ mostlyclean mostlyclean-generic pdf pdf-am ps ps-am uninstall \
+ uninstall-am uninstall-sugarPYTHON
+
+
+# Tell versions [3.59,3.63) of GNU make to not export all variables.
+# Otherwise a system limit (for SysV at least) may be exceeded.
+.NOEXPORT:
diff --git a/extensions/cpsection/power/__init__.py b/extensions/cpsection/power/__init__.py
new file mode 100644
index 0000000..35f7efd
--- /dev/null
+++ b/extensions/cpsection/power/__init__.py
@@ -0,0 +1,22 @@
+# Copyright (C) 2008, OLPC
+#
+# 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 2 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, write to the Free Software
+# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+
+from gettext import gettext as _
+
+CLASS = 'Power'
+ICON = 'module-power'
+TITLE = _('Power')
+KEYWORDS = ['automatic', 'extreme', 'power', 'suspend', 'battery']
diff --git a/extensions/cpsection/power/model.py b/extensions/cpsection/power/model.py
new file mode 100644
index 0000000..8b6a1d3
--- /dev/null
+++ b/extensions/cpsection/power/model.py
@@ -0,0 +1,94 @@
+# Copyright (C) 2008 One Laptop Per Child
+#
+# 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 2 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, write to the Free Software
+# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+#
+
+import os
+from gettext import gettext as _
+import logging
+
+import gconf
+import dbus
+
+OHM_SERVICE_NAME = 'org.freedesktop.ohm'
+OHM_SERVICE_PATH = '/org/freedesktop/ohm/Keystore'
+OHM_SERVICE_IFACE = 'org.freedesktop.ohm.Keystore'
+
+POWERD_FLAG_DIR = '/etc/powerd/flags'
+POWERD_INHIBIT_FLAG = '/etc/powerd/flags/inhibit-suspend'
+
+_logger = logging.getLogger('ControlPanel - Power')
+
+
+class ReadError(Exception):
+ def __init__(self, value):
+ self.value = value
+
+ def __str__(self):
+ return repr(self.value)
+
+
+def using_powerd():
+ # directory exists if powerd running, and it's recent
+ # enough to be controllable.
+ return os.access(POWERD_FLAG_DIR, os.W_OK)
+
+
+def get_automatic_pm():
+ if using_powerd():
+ return not os.access(POWERD_INHIBIT_FLAG, os.R_OK)
+
+ # ohmd
+ client = gconf.client_get_default()
+ return client.get_bool('/desktop/sugar/power/automatic')
+
+
+def print_automatic_pm():
+ print ('off', 'on')[get_automatic_pm()]
+
+
+def set_automatic_pm(enabled):
+ """Automatic suspends on/off."""
+
+ if using_powerd():
+ # powerd
+ if enabled == 'off' or enabled == 0:
+ try:
+ fd = open(POWERD_INHIBIT_FLAG, 'w')
+ except IOError:
+ _logger.debug('File %s is not writeable' % POWERD_INHIBIT_FLAG)
+ else:
+ fd.close()
+ else:
+ os.unlink(POWERD_INHIBIT_FLAG)
+ return
+
+ # ohmd
+ bus = dbus.SystemBus()
+ proxy = bus.get_object(OHM_SERVICE_NAME, OHM_SERVICE_PATH)
+ keystore = dbus.Interface(proxy, OHM_SERVICE_IFACE)
+
+ if enabled == 'on' or enabled == 1:
+ keystore.SetKey('suspend.automatic_pm', 1)
+ enabled = True
+ elif enabled == 'off' or enabled == 0:
+ keystore.SetKey('suspend.automatic_pm', 0)
+ enabled = False
+ else:
+ raise ValueError(_('Error in automatic pm argument, use on/off.'))
+
+ client = gconf.client_get_default()
+ client.set_bool('/desktop/sugar/power/automatic', enabled)
+ return
diff --git a/extensions/cpsection/power/view.py b/extensions/cpsection/power/view.py
new file mode 100644
index 0000000..be0815d
--- /dev/null
+++ b/extensions/cpsection/power/view.py
@@ -0,0 +1,122 @@
+# Copyright (C) 2008, OLPC
+#
+# 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 2 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, write to the Free Software
+# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+
+import gtk
+from gettext import gettext as _
+
+from sugar.graphics import style
+
+from jarabe.controlpanel.sectionview import SectionView
+from jarabe.controlpanel.inlinealert import InlineAlert
+
+
+class Power(SectionView):
+ def __init__(self, model, alerts):
+ SectionView.__init__(self)
+
+ self._model = model
+ self.restart_alerts = alerts
+ self._automatic_pm_valid = True
+ self._automatic_pm_change_handler = None
+
+ self.set_border_width(style.DEFAULT_SPACING * 2)
+ self.set_spacing(style.DEFAULT_SPACING)
+ group = gtk.SizeGroup(gtk.SIZE_GROUP_HORIZONTAL)
+
+ self._automatic_pm_alert_box = gtk.HBox(spacing=style.DEFAULT_SPACING)
+
+ separator_pm = gtk.HSeparator()
+ self.pack_start(separator_pm, expand=False)
+ separator_pm.show()
+
+ label_pm = gtk.Label(_('Power management'))
+ label_pm.set_alignment(0, 0)
+ self.pack_start(label_pm, expand=False)
+ label_pm.show()
+ box_pm = gtk.VBox()
+ box_pm.set_border_width(style.DEFAULT_SPACING * 2)
+ box_pm.set_spacing(style.DEFAULT_SPACING)
+
+ box_automatic_pm = gtk.HBox(spacing=style.DEFAULT_SPACING)
+ label_automatic_pm = gtk.Label(
+ _('Automatic power management (increases battery life)'))
+ label_automatic_pm.set_alignment(0, 0.5)
+ self._automatic_button = gtk.CheckButton()
+ self._automatic_button.set_alignment(0, 0)
+ box_automatic_pm.pack_start(self._automatic_button, expand=False)
+ box_automatic_pm.pack_start(label_automatic_pm, expand=False)
+ self._automatic_button.show()
+ label_automatic_pm.show()
+ group.add_widget(label_automatic_pm)
+ box_pm.pack_start(box_automatic_pm, expand=False)
+ box_automatic_pm.show()
+
+ self._automatic_pm_alert = InlineAlert()
+ label_automatic_pm_error = gtk.Label()
+ group.add_widget(label_automatic_pm_error)
+ self._automatic_pm_alert_box.pack_start(label_automatic_pm_error,
+ expand=False)
+ label_automatic_pm_error.show()
+ self._automatic_pm_alert_box.pack_start(self._automatic_pm_alert,
+ expand=False)
+ box_pm.pack_end(self._automatic_pm_alert_box, expand=False)
+ self._automatic_pm_alert_box.show()
+ if 'automatic_pm' in self.restart_alerts:
+ self._automatic_pm_alert.props.msg = self.restart_msg
+ self._automatic_pm_alert.show()
+
+ self.pack_start(box_pm, expand=False)
+ box_pm.show()
+
+ self.setup()
+
+ def setup(self):
+ try:
+ automatic_state = self._model.get_automatic_pm()
+ except Exception, detail:
+ self._automatic_pm_alert.props.msg = detail
+ self._automatic_pm_alert.show()
+ else:
+ self._automatic_button.set_active(automatic_state)
+
+ self._automatic_pm_valid = True
+ self.needs_restart = False
+ self._automatic_pm_change_handler = self._automatic_button.connect( \
+ 'toggled', self.__automatic_pm_toggled_cb)
+
+ def undo(self):
+ self._automatic_button.disconnect(self._automatic_pm_change_handler)
+ self._model.undo()
+ self._automatic_pm_alert.hide()
+
+ def _validate(self):
+ if self._automatic_pm_valid:
+ self.props.is_valid = True
+ else:
+ self.props.is_valid = False
+
+ def __automatic_pm_toggled_cb(self, widget, data=None):
+ state = widget.get_active()
+ try:
+ self._model.set_automatic_pm(state)
+ except Exception, detail:
+ print detail
+ self._automatic_pm_alert.props.msg = detail
+ else:
+ self._automatic_pm_valid = True
+
+ self._validate()
+ return False
diff --git a/extensions/cpsection/updater/Makefile.am b/extensions/cpsection/updater/Makefile.am
new file mode 100644
index 0000000..897dbf3
--- /dev/null
+++ b/extensions/cpsection/updater/Makefile.am
@@ -0,0 +1,8 @@
+SUBDIRS = backends
+
+sugardir = $(pkgdatadir)/extensions/cpsection/updater
+
+sugar_PYTHON = \
+ __init__.py \
+ model.py \
+ view.py
diff --git a/extensions/cpsection/updater/Makefile.in b/extensions/cpsection/updater/Makefile.in
new file mode 100644
index 0000000..dd9b2ec
--- /dev/null
+++ b/extensions/cpsection/updater/Makefile.in
@@ -0,0 +1,645 @@
+# Makefile.in generated by automake 1.11.3 from Makefile.am.
+# @configure_input@
+
+# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002,
+# 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011 Free Software
+# Foundation, Inc.
+# This Makefile.in is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
+# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
+# PARTICULAR PURPOSE.
+
+@SET_MAKE@
+VPATH = @srcdir@
+pkgdatadir = $(datadir)/@PACKAGE@
+pkgincludedir = $(includedir)/@PACKAGE@
+pkglibdir = $(libdir)/@PACKAGE@
+pkglibexecdir = $(libexecdir)/@PACKAGE@
+am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd
+install_sh_DATA = $(install_sh) -c -m 644
+install_sh_PROGRAM = $(install_sh) -c
+install_sh_SCRIPT = $(install_sh) -c
+INSTALL_HEADER = $(INSTALL_DATA)
+transform = $(program_transform_name)
+NORMAL_INSTALL = :
+PRE_INSTALL = :
+POST_INSTALL = :
+NORMAL_UNINSTALL = :
+PRE_UNINSTALL = :
+POST_UNINSTALL = :
+subdir = extensions/cpsection/updater
+DIST_COMMON = $(srcdir)/Makefile.am $(srcdir)/Makefile.in \
+ $(sugar_PYTHON)
+ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
+am__aclocal_m4_deps = $(top_srcdir)/configure.ac
+am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
+ $(ACLOCAL_M4)
+mkinstalldirs = $(install_sh) -d
+CONFIG_CLEAN_FILES =
+CONFIG_CLEAN_VPATH_FILES =
+SOURCES =
+DIST_SOURCES =
+RECURSIVE_TARGETS = all-recursive check-recursive dvi-recursive \
+ html-recursive info-recursive install-data-recursive \
+ install-dvi-recursive install-exec-recursive \
+ install-html-recursive install-info-recursive \
+ install-pdf-recursive install-ps-recursive install-recursive \
+ installcheck-recursive installdirs-recursive pdf-recursive \
+ ps-recursive uninstall-recursive
+am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`;
+am__vpath_adj = case $$p in \
+ $(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \
+ *) f=$$p;; \
+ esac;
+am__strip_dir = f=`echo $$p | sed -e 's|^.*/||'`;
+am__install_max = 40
+am__nobase_strip_setup = \
+ srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*|]/\\\\&/g'`
+am__nobase_strip = \
+ for p in $$list; do echo "$$p"; done | sed -e "s|$$srcdirstrip/||"
+am__nobase_list = $(am__nobase_strip_setup); \
+ for p in $$list; do echo "$$p $$p"; done | \
+ sed "s| $$srcdirstrip/| |;"' / .*\//!s/ .*/ ./; s,\( .*\)/[^/]*$$,\1,' | \
+ $(AWK) 'BEGIN { files["."] = "" } { files[$$2] = files[$$2] " " $$1; \
+ if (++n[$$2] == $(am__install_max)) \
+ { print $$2, files[$$2]; n[$$2] = 0; files[$$2] = "" } } \
+ END { for (dir in files) print dir, files[dir] }'
+am__base_list = \
+ sed '$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;s/\n/ /g' | \
+ sed '$$!N;$$!N;$$!N;$$!N;s/\n/ /g'
+am__uninstall_files_from_dir = { \
+ test -z "$$files" \
+ || { test ! -d "$$dir" && test ! -f "$$dir" && test ! -r "$$dir"; } \
+ || { echo " ( cd '$$dir' && rm -f" $$files ")"; \
+ $(am__cd) "$$dir" && rm -f $$files; }; \
+ }
+am__py_compile = PYTHON=$(PYTHON) $(SHELL) $(py_compile)
+am__installdirs = "$(DESTDIR)$(sugardir)"
+py_compile = $(top_srcdir)/py-compile
+RECURSIVE_CLEAN_TARGETS = mostlyclean-recursive clean-recursive \
+ distclean-recursive maintainer-clean-recursive
+AM_RECURSIVE_TARGETS = $(RECURSIVE_TARGETS:-recursive=) \
+ $(RECURSIVE_CLEAN_TARGETS:-recursive=) tags TAGS ctags CTAGS \
+ distdir
+ETAGS = etags
+CTAGS = ctags
+DIST_SUBDIRS = $(SUBDIRS)
+DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
+am__relativize = \
+ dir0=`pwd`; \
+ sed_first='s,^\([^/]*\)/.*$$,\1,'; \
+ sed_rest='s,^[^/]*/*,,'; \
+ sed_last='s,^.*/\([^/]*\)$$,\1,'; \
+ sed_butlast='s,/*[^/]*$$,,'; \
+ while test -n "$$dir1"; do \
+ first=`echo "$$dir1" | sed -e "$$sed_first"`; \
+ if test "$$first" != "."; then \
+ if test "$$first" = ".."; then \
+ dir2=`echo "$$dir0" | sed -e "$$sed_last"`/"$$dir2"; \
+ dir0=`echo "$$dir0" | sed -e "$$sed_butlast"`; \
+ else \
+ first2=`echo "$$dir2" | sed -e "$$sed_first"`; \
+ if test "$$first2" = "$$first"; then \
+ dir2=`echo "$$dir2" | sed -e "$$sed_rest"`; \
+ else \
+ dir2="../$$dir2"; \
+ fi; \
+ dir0="$$dir0"/"$$first"; \
+ fi; \
+ fi; \
+ dir1=`echo "$$dir1" | sed -e "$$sed_rest"`; \
+ done; \
+ reldir="$$dir2"
+ACLOCAL = @ACLOCAL@
+ALL_LINGUAS = @ALL_LINGUAS@
+AMTAR = @AMTAR@
+AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@
+AUTOCONF = @AUTOCONF@
+AUTOHEADER = @AUTOHEADER@
+AUTOMAKE = @AUTOMAKE@
+AWK = @AWK@
+CATALOGS = @CATALOGS@
+CATOBJEXT = @CATOBJEXT@
+CC = @CC@
+CCDEPMODE = @CCDEPMODE@
+CFLAGS = @CFLAGS@
+CPP = @CPP@
+CPPFLAGS = @CPPFLAGS@
+CYGPATH_W = @CYGPATH_W@
+DATADIRNAME = @DATADIRNAME@
+DEFS = @DEFS@
+DEPDIR = @DEPDIR@
+ECHO_C = @ECHO_C@
+ECHO_N = @ECHO_N@
+ECHO_T = @ECHO_T@
+EGREP = @EGREP@
+EXEEXT = @EXEEXT@
+GCONFTOOL = @GCONFTOOL@
+GCONF_SCHEMA_CONFIG_SOURCE = @GCONF_SCHEMA_CONFIG_SOURCE@
+GCONF_SCHEMA_FILE_DIR = @GCONF_SCHEMA_FILE_DIR@
+GETTEXT_PACKAGE = @GETTEXT_PACKAGE@
+GMOFILES = @GMOFILES@
+GMSGFMT = @GMSGFMT@
+GREP = @GREP@
+INSTALL = @INSTALL@
+INSTALL_DATA = @INSTALL_DATA@
+INSTALL_PROGRAM = @INSTALL_PROGRAM@
+INSTALL_SCRIPT = @INSTALL_SCRIPT@
+INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@
+INSTOBJEXT = @INSTOBJEXT@
+INTLLIBS = @INTLLIBS@
+INTLTOOL_EXTRACT = @INTLTOOL_EXTRACT@
+INTLTOOL_MERGE = @INTLTOOL_MERGE@
+INTLTOOL_PERL = @INTLTOOL_PERL@
+INTLTOOL_UPDATE = @INTLTOOL_UPDATE@
+INTLTOOL_V_MERGE = @INTLTOOL_V_MERGE@
+INTLTOOL_V_MERGE_OPTIONS = @INTLTOOL_V_MERGE_OPTIONS@
+INTLTOOL__v_MERGE_ = @INTLTOOL__v_MERGE_@
+INTLTOOL__v_MERGE_0 = @INTLTOOL__v_MERGE_0@
+LDFLAGS = @LDFLAGS@
+LIBOBJS = @LIBOBJS@
+LIBS = @LIBS@
+LTLIBOBJS = @LTLIBOBJS@
+MAINT = @MAINT@
+MAKEINFO = @MAKEINFO@
+MKDIR_P = @MKDIR_P@
+MKINSTALLDIRS = @MKINSTALLDIRS@
+MSGFMT = @MSGFMT@
+MSGFMT_OPTS = @MSGFMT_OPTS@
+MSGMERGE = @MSGMERGE@
+OBJEXT = @OBJEXT@
+PACKAGE = @PACKAGE@
+PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@
+PACKAGE_NAME = @PACKAGE_NAME@
+PACKAGE_STRING = @PACKAGE_STRING@
+PACKAGE_TARNAME = @PACKAGE_TARNAME@
+PACKAGE_URL = @PACKAGE_URL@
+PACKAGE_VERSION = @PACKAGE_VERSION@
+PATH_SEPARATOR = @PATH_SEPARATOR@
+PKG_CONFIG = @PKG_CONFIG@
+PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@
+PKG_CONFIG_PATH = @PKG_CONFIG_PATH@
+POFILES = @POFILES@
+POSUB = @POSUB@
+PO_IN_DATADIR_FALSE = @PO_IN_DATADIR_FALSE@
+PO_IN_DATADIR_TRUE = @PO_IN_DATADIR_TRUE@
+PYTHON = @PYTHON@
+PYTHON_EXEC_PREFIX = @PYTHON_EXEC_PREFIX@
+PYTHON_PLATFORM = @PYTHON_PLATFORM@
+PYTHON_PREFIX = @PYTHON_PREFIX@
+PYTHON_VERSION = @PYTHON_VERSION@
+SET_MAKE = @SET_MAKE@
+SHELL = @SHELL@
+SHELL_CFLAGS = @SHELL_CFLAGS@
+SHELL_LIBS = @SHELL_LIBS@
+STRIP = @STRIP@
+SUCROSE_VERSION = @SUCROSE_VERSION@
+USE_NLS = @USE_NLS@
+VERSION = @VERSION@
+XGETTEXT = @XGETTEXT@
+abs_builddir = @abs_builddir@
+abs_srcdir = @abs_srcdir@
+abs_top_builddir = @abs_top_builddir@
+abs_top_srcdir = @abs_top_srcdir@
+ac_ct_CC = @ac_ct_CC@
+am__include = @am__include@
+am__leading_dot = @am__leading_dot@
+am__quote = @am__quote@
+am__tar = @am__tar@
+am__untar = @am__untar@
+bindir = @bindir@
+build_alias = @build_alias@
+builddir = @builddir@
+datadir = @datadir@
+datarootdir = @datarootdir@
+docdir = @docdir@
+dvidir = @dvidir@
+exec_prefix = @exec_prefix@
+host_alias = @host_alias@
+htmldir = @htmldir@
+includedir = @includedir@
+infodir = @infodir@
+install_sh = @install_sh@
+intltool__v_merge_options_ = @intltool__v_merge_options_@
+intltool__v_merge_options_0 = @intltool__v_merge_options_0@
+libdir = @libdir@
+libexecdir = @libexecdir@
+localedir = @localedir@
+localstatedir = @localstatedir@
+mandir = @mandir@
+mkdir_p = @mkdir_p@
+oldincludedir = @oldincludedir@
+pdfdir = @pdfdir@
+pkgpyexecdir = @pkgpyexecdir@
+pkgpythondir = @pkgpythondir@
+prefix = @prefix@
+program_transform_name = @program_transform_name@
+psdir = @psdir@
+pyexecdir = @pyexecdir@
+pythondir = @pythondir@
+sbindir = @sbindir@
+sharedstatedir = @sharedstatedir@
+srcdir = @srcdir@
+sysconfdir = @sysconfdir@
+target_alias = @target_alias@
+top_build_prefix = @top_build_prefix@
+top_builddir = @top_builddir@
+top_srcdir = @top_srcdir@
+SUBDIRS = backends
+sugardir = $(pkgdatadir)/extensions/cpsection/updater
+sugar_PYTHON = \
+ __init__.py \
+ model.py \
+ view.py
+
+all: all-recursive
+
+.SUFFIXES:
+$(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ $(srcdir)/Makefile.am $(am__configure_deps)
+ @for dep in $?; do \
+ case '$(am__configure_deps)' in \
+ *$$dep*) \
+ ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \
+ && { if test -f $@; then exit 0; else break; fi; }; \
+ exit 1;; \
+ esac; \
+ done; \
+ echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign extensions/cpsection/updater/Makefile'; \
+ $(am__cd) $(top_srcdir) && \
+ $(AUTOMAKE) --foreign extensions/cpsection/updater/Makefile
+.PRECIOUS: Makefile
+Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
+ @case '$?' in \
+ *config.status*) \
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \
+ *) \
+ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \
+ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \
+ esac;
+
+$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES)
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+
+$(top_srcdir)/configure: @MAINTAINER_MODE_TRUE@ $(am__configure_deps)
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+$(ACLOCAL_M4): @MAINTAINER_MODE_TRUE@ $(am__aclocal_m4_deps)
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+$(am__aclocal_m4_deps):
+install-sugarPYTHON: $(sugar_PYTHON)
+ @$(NORMAL_INSTALL)
+ test -z "$(sugardir)" || $(MKDIR_P) "$(DESTDIR)$(sugardir)"
+ @list='$(sugar_PYTHON)'; dlist=; list2=; test -n "$(sugardir)" || list=; \
+ for p in $$list; do \
+ if test -f "$$p"; then b=; else b="$(srcdir)/"; fi; \
+ if test -f $$b$$p; then \
+ $(am__strip_dir) \
+ dlist="$$dlist $$f"; \
+ list2="$$list2 $$b$$p"; \
+ else :; fi; \
+ done; \
+ for file in $$list2; do echo $$file; done | $(am__base_list) | \
+ while read files; do \
+ echo " $(INSTALL_DATA) $$files '$(DESTDIR)$(sugardir)'"; \
+ $(INSTALL_DATA) $$files "$(DESTDIR)$(sugardir)" || exit $$?; \
+ done || exit $$?; \
+ if test -n "$$dlist"; then \
+ $(am__py_compile) --destdir "$(DESTDIR)" \
+ --basedir "$(sugardir)" $$dlist; \
+ else :; fi
+
+uninstall-sugarPYTHON:
+ @$(NORMAL_UNINSTALL)
+ @list='$(sugar_PYTHON)'; test -n "$(sugardir)" || list=; \
+ files=`for p in $$list; do echo $$p; done | sed -e 's|^.*/||'`; \
+ test -n "$$files" || exit 0; \
+ dir='$(DESTDIR)$(sugardir)'; \
+ filesc=`echo "$$files" | sed 's|$$|c|'`; \
+ fileso=`echo "$$files" | sed 's|$$|o|'`; \
+ st=0; \
+ for files in "$$files" "$$filesc" "$$fileso"; do \
+ $(am__uninstall_files_from_dir) || st=$$?; \
+ done; \
+ exit $$st
+
+# This directory's subdirectories are mostly independent; you can cd
+# into them and run `make' without going through this Makefile.
+# To change the values of `make' variables: instead of editing Makefiles,
+# (1) if the variable is set in `config.status', edit `config.status'
+# (which will cause the Makefiles to be regenerated when you run `make');
+# (2) otherwise, pass the desired values on the `make' command line.
+$(RECURSIVE_TARGETS):
+ @fail= failcom='exit 1'; \
+ for f in x $$MAKEFLAGS; do \
+ case $$f in \
+ *=* | --[!k]*);; \
+ *k*) failcom='fail=yes';; \
+ esac; \
+ done; \
+ dot_seen=no; \
+ target=`echo $@ | sed s/-recursive//`; \
+ list='$(SUBDIRS)'; for subdir in $$list; do \
+ echo "Making $$target in $$subdir"; \
+ if test "$$subdir" = "."; then \
+ dot_seen=yes; \
+ local_target="$$target-am"; \
+ else \
+ local_target="$$target"; \
+ fi; \
+ ($(am__cd) $$subdir && $(MAKE) $(AM_MAKEFLAGS) $$local_target) \
+ || eval $$failcom; \
+ done; \
+ if test "$$dot_seen" = "no"; then \
+ $(MAKE) $(AM_MAKEFLAGS) "$$target-am" || exit 1; \
+ fi; test -z "$$fail"
+
+$(RECURSIVE_CLEAN_TARGETS):
+ @fail= failcom='exit 1'; \
+ for f in x $$MAKEFLAGS; do \
+ case $$f in \
+ *=* | --[!k]*);; \
+ *k*) failcom='fail=yes';; \
+ esac; \
+ done; \
+ dot_seen=no; \
+ case "$@" in \
+ distclean-* | maintainer-clean-*) list='$(DIST_SUBDIRS)' ;; \
+ *) list='$(SUBDIRS)' ;; \
+ esac; \
+ rev=''; for subdir in $$list; do \
+ if test "$$subdir" = "."; then :; else \
+ rev="$$subdir $$rev"; \
+ fi; \
+ done; \
+ rev="$$rev ."; \
+ target=`echo $@ | sed s/-recursive//`; \
+ for subdir in $$rev; do \
+ echo "Making $$target in $$subdir"; \
+ if test "$$subdir" = "."; then \
+ local_target="$$target-am"; \
+ else \
+ local_target="$$target"; \
+ fi; \
+ ($(am__cd) $$subdir && $(MAKE) $(AM_MAKEFLAGS) $$local_target) \
+ || eval $$failcom; \
+ done && test -z "$$fail"
+tags-recursive:
+ list='$(SUBDIRS)'; for subdir in $$list; do \
+ test "$$subdir" = . || ($(am__cd) $$subdir && $(MAKE) $(AM_MAKEFLAGS) tags); \
+ done
+ctags-recursive:
+ list='$(SUBDIRS)'; for subdir in $$list; do \
+ test "$$subdir" = . || ($(am__cd) $$subdir && $(MAKE) $(AM_MAKEFLAGS) ctags); \
+ done
+
+ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES)
+ list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \
+ unique=`for i in $$list; do \
+ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
+ done | \
+ $(AWK) '{ files[$$0] = 1; nonempty = 1; } \
+ END { if (nonempty) { for (i in files) print i; }; }'`; \
+ mkid -fID $$unique
+tags: TAGS
+
+TAGS: tags-recursive $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \
+ $(TAGS_FILES) $(LISP)
+ set x; \
+ here=`pwd`; \
+ if ($(ETAGS) --etags-include --version) >/dev/null 2>&1; then \
+ include_option=--etags-include; \
+ empty_fix=.; \
+ else \
+ include_option=--include; \
+ empty_fix=; \
+ fi; \
+ list='$(SUBDIRS)'; for subdir in $$list; do \
+ if test "$$subdir" = .; then :; else \
+ test ! -f $$subdir/TAGS || \
+ set "$$@" "$$include_option=$$here/$$subdir/TAGS"; \
+ fi; \
+ done; \
+ list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \
+ unique=`for i in $$list; do \
+ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
+ done | \
+ $(AWK) '{ files[$$0] = 1; nonempty = 1; } \
+ END { if (nonempty) { for (i in files) print i; }; }'`; \
+ shift; \
+ if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \
+ test -n "$$unique" || unique=$$empty_fix; \
+ if test $$# -gt 0; then \
+ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
+ "$$@" $$unique; \
+ else \
+ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
+ $$unique; \
+ fi; \
+ fi
+ctags: CTAGS
+CTAGS: ctags-recursive $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \
+ $(TAGS_FILES) $(LISP)
+ list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \
+ unique=`for i in $$list; do \
+ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
+ done | \
+ $(AWK) '{ files[$$0] = 1; nonempty = 1; } \
+ END { if (nonempty) { for (i in files) print i; }; }'`; \
+ test -z "$(CTAGS_ARGS)$$unique" \
+ || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \
+ $$unique
+
+GTAGS:
+ here=`$(am__cd) $(top_builddir) && pwd` \
+ && $(am__cd) $(top_srcdir) \
+ && gtags -i $(GTAGS_ARGS) "$$here"
+
+distclean-tags:
+ -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags
+
+distdir: $(DISTFILES)
+ @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
+ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
+ list='$(DISTFILES)'; \
+ dist_files=`for file in $$list; do echo $$file; done | \
+ sed -e "s|^$$srcdirstrip/||;t" \
+ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \
+ case $$dist_files in \
+ */*) $(MKDIR_P) `echo "$$dist_files" | \
+ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \
+ sort -u` ;; \
+ esac; \
+ for file in $$dist_files; do \
+ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \
+ if test -d $$d/$$file; then \
+ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \
+ if test -d "$(distdir)/$$file"; then \
+ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \
+ fi; \
+ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \
+ cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \
+ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \
+ fi; \
+ cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \
+ else \
+ test -f "$(distdir)/$$file" \
+ || cp -p $$d/$$file "$(distdir)/$$file" \
+ || exit 1; \
+ fi; \
+ done
+ @list='$(DIST_SUBDIRS)'; for subdir in $$list; do \
+ if test "$$subdir" = .; then :; else \
+ test -d "$(distdir)/$$subdir" \
+ || $(MKDIR_P) "$(distdir)/$$subdir" \
+ || exit 1; \
+ fi; \
+ done
+ @list='$(DIST_SUBDIRS)'; for subdir in $$list; do \
+ if test "$$subdir" = .; then :; else \
+ dir1=$$subdir; dir2="$(distdir)/$$subdir"; \
+ $(am__relativize); \
+ new_distdir=$$reldir; \
+ dir1=$$subdir; dir2="$(top_distdir)"; \
+ $(am__relativize); \
+ new_top_distdir=$$reldir; \
+ echo " (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) top_distdir="$$new_top_distdir" distdir="$$new_distdir" \\"; \
+ echo " am__remove_distdir=: am__skip_length_check=: am__skip_mode_fix=: distdir)"; \
+ ($(am__cd) $$subdir && \
+ $(MAKE) $(AM_MAKEFLAGS) \
+ top_distdir="$$new_top_distdir" \
+ distdir="$$new_distdir" \
+ am__remove_distdir=: \
+ am__skip_length_check=: \
+ am__skip_mode_fix=: \
+ distdir) \
+ || exit 1; \
+ fi; \
+ done
+check-am: all-am
+check: check-recursive
+all-am: Makefile
+installdirs: installdirs-recursive
+installdirs-am:
+ for dir in "$(DESTDIR)$(sugardir)"; do \
+ test -z "$$dir" || $(MKDIR_P) "$$dir"; \
+ done
+install: install-recursive
+install-exec: install-exec-recursive
+install-data: install-data-recursive
+uninstall: uninstall-recursive
+
+install-am: all-am
+ @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am
+
+installcheck: installcheck-recursive
+install-strip:
+ if test -z '$(STRIP)'; then \
+ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
+ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
+ install; \
+ else \
+ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
+ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
+ "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \
+ fi
+mostlyclean-generic:
+
+clean-generic:
+
+distclean-generic:
+ -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES)
+ -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES)
+
+maintainer-clean-generic:
+ @echo "This command is intended for maintainers to use"
+ @echo "it deletes files that may require special tools to rebuild."
+clean: clean-recursive
+
+clean-am: clean-generic mostlyclean-am
+
+distclean: distclean-recursive
+ -rm -f Makefile
+distclean-am: clean-am distclean-generic distclean-tags
+
+dvi: dvi-recursive
+
+dvi-am:
+
+html: html-recursive
+
+html-am:
+
+info: info-recursive
+
+info-am:
+
+install-data-am: install-sugarPYTHON
+
+install-dvi: install-dvi-recursive
+
+install-dvi-am:
+
+install-exec-am:
+
+install-html: install-html-recursive
+
+install-html-am:
+
+install-info: install-info-recursive
+
+install-info-am:
+
+install-man:
+
+install-pdf: install-pdf-recursive
+
+install-pdf-am:
+
+install-ps: install-ps-recursive
+
+install-ps-am:
+
+installcheck-am:
+
+maintainer-clean: maintainer-clean-recursive
+ -rm -f Makefile
+maintainer-clean-am: distclean-am maintainer-clean-generic
+
+mostlyclean: mostlyclean-recursive
+
+mostlyclean-am: mostlyclean-generic
+
+pdf: pdf-recursive
+
+pdf-am:
+
+ps: ps-recursive
+
+ps-am:
+
+uninstall-am: uninstall-sugarPYTHON
+
+.MAKE: $(RECURSIVE_CLEAN_TARGETS) $(RECURSIVE_TARGETS) ctags-recursive \
+ install-am install-strip tags-recursive
+
+.PHONY: $(RECURSIVE_CLEAN_TARGETS) $(RECURSIVE_TARGETS) CTAGS GTAGS \
+ all all-am check check-am clean clean-generic ctags \
+ ctags-recursive distclean distclean-generic distclean-tags \
+ distdir dvi dvi-am html html-am info info-am install \
+ install-am install-data install-data-am install-dvi \
+ install-dvi-am install-exec install-exec-am install-html \
+ install-html-am install-info install-info-am install-man \
+ install-pdf install-pdf-am install-ps install-ps-am \
+ install-strip install-sugarPYTHON installcheck installcheck-am \
+ installdirs installdirs-am maintainer-clean \
+ maintainer-clean-generic mostlyclean mostlyclean-generic pdf \
+ pdf-am ps ps-am tags tags-recursive uninstall uninstall-am \
+ uninstall-sugarPYTHON
+
+
+# Tell versions [3.59,3.63) of GNU make to not export all variables.
+# Otherwise a system limit (for SysV at least) may be exceeded.
+.NOEXPORT:
diff --git a/extensions/cpsection/updater/__init__.py b/extensions/cpsection/updater/__init__.py
new file mode 100644
index 0000000..6010615
--- /dev/null
+++ b/extensions/cpsection/updater/__init__.py
@@ -0,0 +1,22 @@
+# Copyright (C) 2008, OLPC
+#
+# 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 2 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, write to the Free Software
+# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+
+from gettext import gettext as _
+
+CLASS = 'ActivityUpdater'
+ICON = 'module-updater'
+TITLE = _('Software update')
+KEYWORDS = ['software', 'activity', 'update']
diff --git a/extensions/cpsection/updater/backends/Makefile.am b/extensions/cpsection/updater/backends/Makefile.am
new file mode 100644
index 0000000..e280a07
--- /dev/null
+++ b/extensions/cpsection/updater/backends/Makefile.am
@@ -0,0 +1,5 @@
+sugardir = $(pkgdatadir)/extensions/cpsection/updater/backends
+
+sugar_PYTHON = \
+ aslo.py \
+ __init__.py
diff --git a/extensions/cpsection/updater/backends/Makefile.in b/extensions/cpsection/updater/backends/Makefile.in
new file mode 100644
index 0000000..49e509c
--- /dev/null
+++ b/extensions/cpsection/updater/backends/Makefile.in
@@ -0,0 +1,441 @@
+# Makefile.in generated by automake 1.11.3 from Makefile.am.
+# @configure_input@
+
+# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002,
+# 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011 Free Software
+# Foundation, Inc.
+# This Makefile.in is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
+# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
+# PARTICULAR PURPOSE.
+
+@SET_MAKE@
+VPATH = @srcdir@
+pkgdatadir = $(datadir)/@PACKAGE@
+pkgincludedir = $(includedir)/@PACKAGE@
+pkglibdir = $(libdir)/@PACKAGE@
+pkglibexecdir = $(libexecdir)/@PACKAGE@
+am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd
+install_sh_DATA = $(install_sh) -c -m 644
+install_sh_PROGRAM = $(install_sh) -c
+install_sh_SCRIPT = $(install_sh) -c
+INSTALL_HEADER = $(INSTALL_DATA)
+transform = $(program_transform_name)
+NORMAL_INSTALL = :
+PRE_INSTALL = :
+POST_INSTALL = :
+NORMAL_UNINSTALL = :
+PRE_UNINSTALL = :
+POST_UNINSTALL = :
+subdir = extensions/cpsection/updater/backends
+DIST_COMMON = $(srcdir)/Makefile.am $(srcdir)/Makefile.in \
+ $(sugar_PYTHON)
+ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
+am__aclocal_m4_deps = $(top_srcdir)/configure.ac
+am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
+ $(ACLOCAL_M4)
+mkinstalldirs = $(install_sh) -d
+CONFIG_CLEAN_FILES =
+CONFIG_CLEAN_VPATH_FILES =
+SOURCES =
+DIST_SOURCES =
+am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`;
+am__vpath_adj = case $$p in \
+ $(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \
+ *) f=$$p;; \
+ esac;
+am__strip_dir = f=`echo $$p | sed -e 's|^.*/||'`;
+am__install_max = 40
+am__nobase_strip_setup = \
+ srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*|]/\\\\&/g'`
+am__nobase_strip = \
+ for p in $$list; do echo "$$p"; done | sed -e "s|$$srcdirstrip/||"
+am__nobase_list = $(am__nobase_strip_setup); \
+ for p in $$list; do echo "$$p $$p"; done | \
+ sed "s| $$srcdirstrip/| |;"' / .*\//!s/ .*/ ./; s,\( .*\)/[^/]*$$,\1,' | \
+ $(AWK) 'BEGIN { files["."] = "" } { files[$$2] = files[$$2] " " $$1; \
+ if (++n[$$2] == $(am__install_max)) \
+ { print $$2, files[$$2]; n[$$2] = 0; files[$$2] = "" } } \
+ END { for (dir in files) print dir, files[dir] }'
+am__base_list = \
+ sed '$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;s/\n/ /g' | \
+ sed '$$!N;$$!N;$$!N;$$!N;s/\n/ /g'
+am__uninstall_files_from_dir = { \
+ test -z "$$files" \
+ || { test ! -d "$$dir" && test ! -f "$$dir" && test ! -r "$$dir"; } \
+ || { echo " ( cd '$$dir' && rm -f" $$files ")"; \
+ $(am__cd) "$$dir" && rm -f $$files; }; \
+ }
+am__py_compile = PYTHON=$(PYTHON) $(SHELL) $(py_compile)
+am__installdirs = "$(DESTDIR)$(sugardir)"
+py_compile = $(top_srcdir)/py-compile
+DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
+ACLOCAL = @ACLOCAL@
+ALL_LINGUAS = @ALL_LINGUAS@
+AMTAR = @AMTAR@
+AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@
+AUTOCONF = @AUTOCONF@
+AUTOHEADER = @AUTOHEADER@
+AUTOMAKE = @AUTOMAKE@
+AWK = @AWK@
+CATALOGS = @CATALOGS@
+CATOBJEXT = @CATOBJEXT@
+CC = @CC@
+CCDEPMODE = @CCDEPMODE@
+CFLAGS = @CFLAGS@
+CPP = @CPP@
+CPPFLAGS = @CPPFLAGS@
+CYGPATH_W = @CYGPATH_W@
+DATADIRNAME = @DATADIRNAME@
+DEFS = @DEFS@
+DEPDIR = @DEPDIR@
+ECHO_C = @ECHO_C@
+ECHO_N = @ECHO_N@
+ECHO_T = @ECHO_T@
+EGREP = @EGREP@
+EXEEXT = @EXEEXT@
+GCONFTOOL = @GCONFTOOL@
+GCONF_SCHEMA_CONFIG_SOURCE = @GCONF_SCHEMA_CONFIG_SOURCE@
+GCONF_SCHEMA_FILE_DIR = @GCONF_SCHEMA_FILE_DIR@
+GETTEXT_PACKAGE = @GETTEXT_PACKAGE@
+GMOFILES = @GMOFILES@
+GMSGFMT = @GMSGFMT@
+GREP = @GREP@
+INSTALL = @INSTALL@
+INSTALL_DATA = @INSTALL_DATA@
+INSTALL_PROGRAM = @INSTALL_PROGRAM@
+INSTALL_SCRIPT = @INSTALL_SCRIPT@
+INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@
+INSTOBJEXT = @INSTOBJEXT@
+INTLLIBS = @INTLLIBS@
+INTLTOOL_EXTRACT = @INTLTOOL_EXTRACT@
+INTLTOOL_MERGE = @INTLTOOL_MERGE@
+INTLTOOL_PERL = @INTLTOOL_PERL@
+INTLTOOL_UPDATE = @INTLTOOL_UPDATE@
+INTLTOOL_V_MERGE = @INTLTOOL_V_MERGE@
+INTLTOOL_V_MERGE_OPTIONS = @INTLTOOL_V_MERGE_OPTIONS@
+INTLTOOL__v_MERGE_ = @INTLTOOL__v_MERGE_@
+INTLTOOL__v_MERGE_0 = @INTLTOOL__v_MERGE_0@
+LDFLAGS = @LDFLAGS@
+LIBOBJS = @LIBOBJS@
+LIBS = @LIBS@
+LTLIBOBJS = @LTLIBOBJS@
+MAINT = @MAINT@
+MAKEINFO = @MAKEINFO@
+MKDIR_P = @MKDIR_P@
+MKINSTALLDIRS = @MKINSTALLDIRS@
+MSGFMT = @MSGFMT@
+MSGFMT_OPTS = @MSGFMT_OPTS@
+MSGMERGE = @MSGMERGE@
+OBJEXT = @OBJEXT@
+PACKAGE = @PACKAGE@
+PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@
+PACKAGE_NAME = @PACKAGE_NAME@
+PACKAGE_STRING = @PACKAGE_STRING@
+PACKAGE_TARNAME = @PACKAGE_TARNAME@
+PACKAGE_URL = @PACKAGE_URL@
+PACKAGE_VERSION = @PACKAGE_VERSION@
+PATH_SEPARATOR = @PATH_SEPARATOR@
+PKG_CONFIG = @PKG_CONFIG@
+PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@
+PKG_CONFIG_PATH = @PKG_CONFIG_PATH@
+POFILES = @POFILES@
+POSUB = @POSUB@
+PO_IN_DATADIR_FALSE = @PO_IN_DATADIR_FALSE@
+PO_IN_DATADIR_TRUE = @PO_IN_DATADIR_TRUE@
+PYTHON = @PYTHON@
+PYTHON_EXEC_PREFIX = @PYTHON_EXEC_PREFIX@
+PYTHON_PLATFORM = @PYTHON_PLATFORM@
+PYTHON_PREFIX = @PYTHON_PREFIX@
+PYTHON_VERSION = @PYTHON_VERSION@
+SET_MAKE = @SET_MAKE@
+SHELL = @SHELL@
+SHELL_CFLAGS = @SHELL_CFLAGS@
+SHELL_LIBS = @SHELL_LIBS@
+STRIP = @STRIP@
+SUCROSE_VERSION = @SUCROSE_VERSION@
+USE_NLS = @USE_NLS@
+VERSION = @VERSION@
+XGETTEXT = @XGETTEXT@
+abs_builddir = @abs_builddir@
+abs_srcdir = @abs_srcdir@
+abs_top_builddir = @abs_top_builddir@
+abs_top_srcdir = @abs_top_srcdir@
+ac_ct_CC = @ac_ct_CC@
+am__include = @am__include@
+am__leading_dot = @am__leading_dot@
+am__quote = @am__quote@
+am__tar = @am__tar@
+am__untar = @am__untar@
+bindir = @bindir@
+build_alias = @build_alias@
+builddir = @builddir@
+datadir = @datadir@
+datarootdir = @datarootdir@
+docdir = @docdir@
+dvidir = @dvidir@
+exec_prefix = @exec_prefix@
+host_alias = @host_alias@
+htmldir = @htmldir@
+includedir = @includedir@
+infodir = @infodir@
+install_sh = @install_sh@
+intltool__v_merge_options_ = @intltool__v_merge_options_@
+intltool__v_merge_options_0 = @intltool__v_merge_options_0@
+libdir = @libdir@
+libexecdir = @libexecdir@
+localedir = @localedir@
+localstatedir = @localstatedir@
+mandir = @mandir@
+mkdir_p = @mkdir_p@
+oldincludedir = @oldincludedir@
+pdfdir = @pdfdir@
+pkgpyexecdir = @pkgpyexecdir@
+pkgpythondir = @pkgpythondir@
+prefix = @prefix@
+program_transform_name = @program_transform_name@
+psdir = @psdir@
+pyexecdir = @pyexecdir@
+pythondir = @pythondir@
+sbindir = @sbindir@
+sharedstatedir = @sharedstatedir@
+srcdir = @srcdir@
+sysconfdir = @sysconfdir@
+target_alias = @target_alias@
+top_build_prefix = @top_build_prefix@
+top_builddir = @top_builddir@
+top_srcdir = @top_srcdir@
+sugardir = $(pkgdatadir)/extensions/cpsection/updater/backends
+sugar_PYTHON = \
+ aslo.py \
+ __init__.py
+
+all: all-am
+
+.SUFFIXES:
+$(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ $(srcdir)/Makefile.am $(am__configure_deps)
+ @for dep in $?; do \
+ case '$(am__configure_deps)' in \
+ *$$dep*) \
+ ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \
+ && { if test -f $@; then exit 0; else break; fi; }; \
+ exit 1;; \
+ esac; \
+ done; \
+ echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign extensions/cpsection/updater/backends/Makefile'; \
+ $(am__cd) $(top_srcdir) && \
+ $(AUTOMAKE) --foreign extensions/cpsection/updater/backends/Makefile
+.PRECIOUS: Makefile
+Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
+ @case '$?' in \
+ *config.status*) \
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \
+ *) \
+ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \
+ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \
+ esac;
+
+$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES)
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+
+$(top_srcdir)/configure: @MAINTAINER_MODE_TRUE@ $(am__configure_deps)
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+$(ACLOCAL_M4): @MAINTAINER_MODE_TRUE@ $(am__aclocal_m4_deps)
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+$(am__aclocal_m4_deps):
+install-sugarPYTHON: $(sugar_PYTHON)
+ @$(NORMAL_INSTALL)
+ test -z "$(sugardir)" || $(MKDIR_P) "$(DESTDIR)$(sugardir)"
+ @list='$(sugar_PYTHON)'; dlist=; list2=; test -n "$(sugardir)" || list=; \
+ for p in $$list; do \
+ if test -f "$$p"; then b=; else b="$(srcdir)/"; fi; \
+ if test -f $$b$$p; then \
+ $(am__strip_dir) \
+ dlist="$$dlist $$f"; \
+ list2="$$list2 $$b$$p"; \
+ else :; fi; \
+ done; \
+ for file in $$list2; do echo $$file; done | $(am__base_list) | \
+ while read files; do \
+ echo " $(INSTALL_DATA) $$files '$(DESTDIR)$(sugardir)'"; \
+ $(INSTALL_DATA) $$files "$(DESTDIR)$(sugardir)" || exit $$?; \
+ done || exit $$?; \
+ if test -n "$$dlist"; then \
+ $(am__py_compile) --destdir "$(DESTDIR)" \
+ --basedir "$(sugardir)" $$dlist; \
+ else :; fi
+
+uninstall-sugarPYTHON:
+ @$(NORMAL_UNINSTALL)
+ @list='$(sugar_PYTHON)'; test -n "$(sugardir)" || list=; \
+ files=`for p in $$list; do echo $$p; done | sed -e 's|^.*/||'`; \
+ test -n "$$files" || exit 0; \
+ dir='$(DESTDIR)$(sugardir)'; \
+ filesc=`echo "$$files" | sed 's|$$|c|'`; \
+ fileso=`echo "$$files" | sed 's|$$|o|'`; \
+ st=0; \
+ for files in "$$files" "$$filesc" "$$fileso"; do \
+ $(am__uninstall_files_from_dir) || st=$$?; \
+ done; \
+ exit $$st
+tags: TAGS
+TAGS:
+
+ctags: CTAGS
+CTAGS:
+
+
+distdir: $(DISTFILES)
+ @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
+ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
+ list='$(DISTFILES)'; \
+ dist_files=`for file in $$list; do echo $$file; done | \
+ sed -e "s|^$$srcdirstrip/||;t" \
+ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \
+ case $$dist_files in \
+ */*) $(MKDIR_P) `echo "$$dist_files" | \
+ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \
+ sort -u` ;; \
+ esac; \
+ for file in $$dist_files; do \
+ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \
+ if test -d $$d/$$file; then \
+ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \
+ if test -d "$(distdir)/$$file"; then \
+ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \
+ fi; \
+ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \
+ cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \
+ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \
+ fi; \
+ cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \
+ else \
+ test -f "$(distdir)/$$file" \
+ || cp -p $$d/$$file "$(distdir)/$$file" \
+ || exit 1; \
+ fi; \
+ done
+check-am: all-am
+check: check-am
+all-am: Makefile
+installdirs:
+ for dir in "$(DESTDIR)$(sugardir)"; do \
+ test -z "$$dir" || $(MKDIR_P) "$$dir"; \
+ done
+install: install-am
+install-exec: install-exec-am
+install-data: install-data-am
+uninstall: uninstall-am
+
+install-am: all-am
+ @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am
+
+installcheck: installcheck-am
+install-strip:
+ if test -z '$(STRIP)'; then \
+ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
+ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
+ install; \
+ else \
+ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
+ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
+ "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \
+ fi
+mostlyclean-generic:
+
+clean-generic:
+
+distclean-generic:
+ -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES)
+ -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES)
+
+maintainer-clean-generic:
+ @echo "This command is intended for maintainers to use"
+ @echo "it deletes files that may require special tools to rebuild."
+clean: clean-am
+
+clean-am: clean-generic mostlyclean-am
+
+distclean: distclean-am
+ -rm -f Makefile
+distclean-am: clean-am distclean-generic
+
+dvi: dvi-am
+
+dvi-am:
+
+html: html-am
+
+html-am:
+
+info: info-am
+
+info-am:
+
+install-data-am: install-sugarPYTHON
+
+install-dvi: install-dvi-am
+
+install-dvi-am:
+
+install-exec-am:
+
+install-html: install-html-am
+
+install-html-am:
+
+install-info: install-info-am
+
+install-info-am:
+
+install-man:
+
+install-pdf: install-pdf-am
+
+install-pdf-am:
+
+install-ps: install-ps-am
+
+install-ps-am:
+
+installcheck-am:
+
+maintainer-clean: maintainer-clean-am
+ -rm -f Makefile
+maintainer-clean-am: distclean-am maintainer-clean-generic
+
+mostlyclean: mostlyclean-am
+
+mostlyclean-am: mostlyclean-generic
+
+pdf: pdf-am
+
+pdf-am:
+
+ps: ps-am
+
+ps-am:
+
+uninstall-am: uninstall-sugarPYTHON
+
+.MAKE: install-am install-strip
+
+.PHONY: all all-am check check-am clean clean-generic distclean \
+ distclean-generic distdir dvi dvi-am html html-am info info-am \
+ install install-am install-data install-data-am install-dvi \
+ install-dvi-am install-exec install-exec-am install-html \
+ install-html-am install-info install-info-am install-man \
+ install-pdf install-pdf-am install-ps install-ps-am \
+ install-strip install-sugarPYTHON installcheck installcheck-am \
+ installdirs maintainer-clean maintainer-clean-generic \
+ mostlyclean mostlyclean-generic pdf pdf-am ps ps-am uninstall \
+ uninstall-am uninstall-sugarPYTHON
+
+
+# Tell versions [3.59,3.63) of GNU make to not export all variables.
+# Otherwise a system limit (for SysV at least) may be exceeded.
+.NOEXPORT:
diff --git a/extensions/cpsection/updater/backends/__init__.py b/extensions/cpsection/updater/backends/__init__.py
new file mode 100644
index 0000000..0dd0174
--- /dev/null
+++ b/extensions/cpsection/updater/backends/__init__.py
@@ -0,0 +1,16 @@
+#!/usr/bin/python
+# Copyright (C) 2009, Sugar Labs
+#
+# 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 2 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, write to the Free Software
+# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
diff --git a/extensions/cpsection/updater/backends/aslo.py b/extensions/cpsection/updater/backends/aslo.py
new file mode 100644
index 0000000..6504e9e
--- /dev/null
+++ b/extensions/cpsection/updater/backends/aslo.py
@@ -0,0 +1,164 @@
+#!/usr/bin/python
+# Copyright (C) 2009, Sugar Labs
+#
+# 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 2 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, write to the Free Software
+# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+
+"""Activity information microformat parser.
+
+Activity information is embedded in HTML/XHTML/XML pages using a
+Resource Description Framework (RDF) http://www.w3.org/RDF/ .
+
+An example::
+
+<?xml version="1.0" encoding="UTF-8"?>
+<RDF:RDF xmlns:RDF="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
+ xmlns:em="http://www.mozilla.org/2004/em-rdf#">
+<RDF:Description about="urn:mozilla:extension:bounce">
+ <em:updates>
+ <RDF:Seq>
+ <RDF:li resource="urn:mozilla:extension:bounce:7"/>
+ </RDF:Seq>
+ </em:updates>
+</RDF:Description>
+
+<RDF:Description about="urn:mozilla:extension:bounce:7">
+ <em:version>7</em:version>
+ <em:targetApplication>
+ <RDF:Description>
+ <em:id>{3ca105e0-2280-4897-99a0-c277d1b733d2}</em:id>
+ <em:minVersion>0.82</em:minVersion>
+ <em:maxVersion>0.84</em:maxVersion>
+ <em:updateLink>http://foo.xo</em:updateLink>
+ <em:updateSize>7</em:updateSize>
+ <em:updateHash>sha256:816a7c43b4f1ea4769c61c03ea4..</em:updateHash>
+ </RDF:Description>
+ </em:targetApplication>
+</RDF:Description></RDF:RDF>
+"""
+
+import logging
+from xml.etree.ElementTree import XML
+import traceback
+
+import gio
+
+from sugar.bundle.bundleversion import NormalizedVersion
+from sugar.bundle.bundleversion import InvalidVersionError
+
+from jarabe import config
+
+_FIND_DESCRIPTION = \
+ './/{http://www.w3.org/1999/02/22-rdf-syntax-ns#}Description'
+_FIND_VERSION = './/{http://www.mozilla.org/2004/em-rdf#}version'
+_FIND_LINK = './/{http://www.mozilla.org/2004/em-rdf#}updateLink'
+_FIND_SIZE = './/{http://www.mozilla.org/2004/em-rdf#}updateSize'
+
+_UPDATE_PATH = 'http://activities.sugarlabs.org/services/update-aslo.php'
+
+_fetcher = None
+
+
+class _UpdateFetcher(object):
+
+ _CHUNK_SIZE = 10240
+
+ def __init__(self, bundle, completion_cb):
+ # ASLO knows only about stable SP releases
+ major, minor = config.version.split('.')[0:2]
+ sp_version = '%s.%s' % (major, int(minor) + int(minor) % 2)
+
+ url = '%s?id=%s&appVersion=%s' % \
+ (_UPDATE_PATH, bundle.get_bundle_id(), sp_version)
+
+ logging.debug('Fetch %s', url)
+
+ self._completion_cb = completion_cb
+ self._file = gio.File(url)
+ self._stream = None
+ self._xml_data = ''
+ self._bundle = bundle
+
+ self._file.read_async(self.__file_read_async_cb)
+
+ def __file_read_async_cb(self, gfile, result):
+ try:
+ self._stream = self._file.read_finish(result)
+ except:
+ global _fetcher
+ _fetcher = None
+ self._completion_cb(None, None, None, None, traceback.format_exc())
+ return
+
+ self._stream.read_async(self._CHUNK_SIZE, self.__stream_read_async_cb)
+
+ def __stream_read_async_cb(self, stream, result):
+ xml_data = self._stream.read_finish(result)
+ if xml_data is None:
+ global _fetcher
+ _fetcher = None
+ self._completion_cb(self._bundle, None, None, None,
+ 'Error reading update information for %s from '
+ 'server.' % self._bundle.get_bundle_id())
+ return
+ elif not xml_data:
+ self._process_result()
+ else:
+ self._xml_data += xml_data
+ self._stream.read_async(self._CHUNK_SIZE,
+ self.__stream_read_async_cb)
+
+ def _process_result(self):
+ document = XML(self._xml_data)
+
+ if document.find(_FIND_DESCRIPTION) is None:
+ logging.debug('Bundle %s not available in the server for the '
+ 'version %s', self._bundle.get_bundle_id(), config.version)
+ version = None
+ link = None
+ size = None
+ else:
+ try:
+ version = NormalizedVersion(document.find(_FIND_VERSION).text)
+ except InvalidVersionError:
+ logging.exception('Exception occured while parsing version')
+ version = '0'
+
+ link = document.find(_FIND_LINK).text
+
+ try:
+ size = long(document.find(_FIND_SIZE).text) * 1024
+ except ValueError:
+ logging.exception('Exception occured while parsing size')
+ size = 0
+
+ global _fetcher
+ _fetcher = None
+ self._completion_cb(self._bundle, version, link, size, None)
+
+
+def fetch_update_info(bundle, completion_cb):
+ """Queries the server for a newer version of the ActivityBundle.
+
+ completion_cb receives bundle, version, link, size and possibly an error
+ message:
+
+ def completion_cb(bundle, version, link, size, error_message):
+ """
+ global _fetcher
+
+ if _fetcher is not None:
+ raise RuntimeError('Multiple simultaneous requests are not supported')
+
+ _fetcher = _UpdateFetcher(bundle, completion_cb)
diff --git a/extensions/cpsection/updater/model.py b/extensions/cpsection/updater/model.py
new file mode 100755
index 0000000..7ea445f
--- /dev/null
+++ b/extensions/cpsection/updater/model.py
@@ -0,0 +1,354 @@
+# Copyright (C) 2009, Sugar Labs
+# Copyright (C) 2009, Tomeu Vizoso
+#
+# 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 2 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, write to the Free Software
+# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+"""Sugar bundle updater: model.
+
+This module implements the non-GUI portions of the bundle updater, including
+list of installed bundls, whether updates are needed, and the URL at which to
+find the bundle updated.
+"""
+
+import os
+import logging
+import tempfile
+from urlparse import urlparse
+import traceback
+
+import gobject
+import gio
+
+from sugar import env
+from sugar.datastore import datastore
+from sugar.bundle.activitybundle import ActivityBundle
+from sugar.bundle.bundleversion import NormalizedVersion
+
+from jarabe.model import bundleregistry
+
+from backends import aslo
+
+
+class UpdateModel(gobject.GObject):
+ __gtype_name__ = 'SugarUpdateModel'
+
+ __gsignals__ = {
+ 'progress': (gobject.SIGNAL_RUN_FIRST,
+ gobject.TYPE_NONE,
+ ([int, str, float, int])),
+ }
+
+ ACTION_CHECKING = 0
+ ACTION_UPDATING = 1
+ ACTION_DOWNLOADING = 2
+
+ def __init__(self):
+ gobject.GObject.__init__(self)
+
+ self.updates = None
+ self._bundles_to_check = None
+ self._bundles_to_update = None
+ self._total_bundles_to_update = 0
+ self._downloader = None
+ self._cancelling = False
+
+ def check_updates(self):
+ self.updates = []
+ self._bundles_to_check = list(bundleregistry.get_registry())
+ self._check_next_update()
+
+ def _check_next_update(self):
+ total = len(bundleregistry.get_registry())
+ current = total - len(self._bundles_to_check)
+
+ if not self._bundles_to_check:
+ return False
+
+ bundle = self._bundles_to_check.pop()
+ self.emit('progress', UpdateModel.ACTION_CHECKING, bundle.get_name(),
+ current, total)
+
+ aslo.fetch_update_info(bundle, self.__check_completed_cb)
+
+ def __check_completed_cb(self, bundle, version, link, size, error_message):
+ if error_message is not None:
+ logging.error('Error getting update information from server:\n'
+ '%s' % error_message)
+
+ if version is not None and \
+ version > NormalizedVersion(bundle.get_activity_version()):
+ self.updates.append(BundleUpdate(bundle, version, link, size))
+
+ if self._cancelling:
+ self._cancel_checking()
+ elif self._bundles_to_check:
+ gobject.idle_add(self._check_next_update)
+ else:
+ total = len(bundleregistry.get_registry())
+ if bundle is None:
+ name = ''
+ else:
+ name = bundle.get_name()
+ self.emit('progress', UpdateModel.ACTION_CHECKING, name, total,
+ total)
+
+ def update(self, bundle_ids):
+ self._bundles_to_update = []
+ for bundle_update in self.updates:
+ if bundle_update.bundle.get_bundle_id() in bundle_ids:
+ self._bundles_to_update.append(bundle_update)
+
+ self._total_bundles_to_update = len(self._bundles_to_update)
+ self._download_next_update()
+
+ def _download_next_update(self):
+ if self._cancelling:
+ self._cancel_updating()
+ return
+
+ bundle_update = self._bundles_to_update.pop()
+
+ total = self._total_bundles_to_update * 2
+ current = total - len(self._bundles_to_update) * 2 - 2
+
+ self.emit('progress', UpdateModel.ACTION_DOWNLOADING,
+ bundle_update.bundle.get_name(), current, total)
+
+ self._downloader = _Downloader(bundle_update)
+ self._downloader.connect('progress', self.__downloader_progress_cb)
+ self._downloader.connect('error', self.__downloader_error_cb)
+
+ def __downloader_progress_cb(self, downloader, progress):
+ logging.debug('__downloader_progress_cb %r', progress)
+
+ if self._cancelling:
+ self._cancel_updating()
+ return
+
+ total = self._total_bundles_to_update * 2
+ current = total - len(self._bundles_to_update) * 2 - 2 + progress
+
+ self.emit('progress', UpdateModel.ACTION_DOWNLOADING,
+ self._downloader.bundle_update.bundle.get_name(),
+ current, total)
+
+ if progress == 1:
+ self._install_update(self._downloader.bundle_update,
+ self._downloader.get_local_file_path())
+ self._downloader = None
+
+ def __downloader_error_cb(self, downloader, error_message):
+ logging.error('Error downloading update:\n%s', error_message)
+
+ if self._cancelling:
+ self._cancel_updating()
+ return
+
+ total = self._total_bundles_to_update
+ current = total - len(self._bundles_to_update)
+ self.emit('progress', UpdateModel.ACTION_UPDATING, '', current, total)
+
+ if self._bundles_to_update:
+ # do it in idle so the UI has a chance to refresh
+ gobject.idle_add(self._download_next_update)
+
+ def _install_update(self, bundle_update, local_file_path):
+
+ total = self._total_bundles_to_update
+ current = total - len(self._bundles_to_update) - 0.5
+
+ self.emit('progress', UpdateModel.ACTION_UPDATING,
+ bundle_update.bundle.get_name(),
+ current, total)
+
+ # TODO: Should we first expand the zip async so we can provide progress
+ # and only then copy to the journal?
+ jobject = datastore.create()
+ try:
+ title = '%s-%s' % (bundle_update.bundle.get_name(),
+ bundle_update.version)
+ jobject.metadata['title'] = title
+ jobject.metadata['mime_type'] = ActivityBundle.MIME_TYPE
+ jobject.file_path = local_file_path
+ datastore.write(jobject, transfer_ownership=True)
+ finally:
+ jobject.destroy()
+
+ self.emit('progress', UpdateModel.ACTION_UPDATING,
+ bundle_update.bundle.get_name(),
+ current + 0.5, total)
+
+ if self._bundles_to_update:
+ # do it in idle so the UI has a chance to refresh
+ gobject.idle_add(self._download_next_update)
+
+ def cancel(self):
+ self._cancelling = True
+
+ def _cancel_checking(self):
+ logging.debug('UpdateModel._cancel_checking')
+ total = len(bundleregistry.get_registry())
+ current = total - len(self._bundles_to_check)
+ self.emit('progress', UpdateModel.ACTION_CHECKING, '', current,
+ current)
+ self._bundles_to_check = None
+ self._cancelling = False
+
+ def _cancel_updating(self):
+ logging.debug('UpdateModel._cancel_updating')
+ current = (self._total_bundles_to_update -
+ len(self._bundles_to_update) - 1)
+ self.emit('progress', UpdateModel.ACTION_UPDATING, '', current,
+ current)
+
+ if self._downloader is not None:
+ self._downloader.cancel()
+ file_path = self._downloader.get_local_file_path()
+ if file_path is not None and os.path.exists(file_path):
+ os.unlink(file_path)
+ self._downloader = None
+
+ self._total_bundles_to_update = 0
+ self._bundles_to_update = None
+ self._cancelling = False
+
+
+class BundleUpdate(object):
+
+ def __init__(self, bundle, version, link, size):
+ self.bundle = bundle
+ self.version = version
+ self.link = link
+ self.size = size
+
+
+class _Downloader(gobject.GObject):
+ _CHUNK_SIZE = 10240 # 10K
+ __gsignals__ = {
+ 'progress': (gobject.SIGNAL_RUN_FIRST,
+ gobject.TYPE_NONE,
+ ([float])),
+ 'error': (gobject.SIGNAL_RUN_FIRST,
+ gobject.TYPE_NONE,
+ ([str])),
+ }
+
+ def __init__(self, bundle_update):
+ gobject.GObject.__init__(self)
+
+ self.bundle_update = bundle_update
+ self._input_stream = None
+ self._output_stream = None
+ self._pending_buffers = []
+ self._input_file = gio.File(bundle_update.link)
+ self._output_file = None
+ self._downloaded_size = 0
+ self._cancelling = False
+
+ self._input_file.read_async(self.__file_read_async_cb)
+
+ def cancel(self):
+ self._cancelling = True
+
+ def __file_read_async_cb(self, gfile, result):
+ if self._cancelling:
+ return
+
+ try:
+ self._input_stream = self._input_file.read_finish(result)
+ except:
+ self.emit('error', traceback.format_exc())
+ return
+
+ temp_file_path = self._get_temp_file_path(self.bundle_update.link)
+ self._output_file = gio.File(temp_file_path)
+ self._output_stream = self._output_file.create()
+
+ self._input_stream.read_async(self._CHUNK_SIZE, self.__read_async_cb,
+ gobject.PRIORITY_LOW)
+
+ def __read_async_cb(self, input_stream, result):
+ if self._cancelling:
+ return
+
+ data = input_stream.read_finish(result)
+
+ if data is None:
+ # TODO
+ pass
+ elif not data:
+ logging.debug('closing input stream')
+ self._input_stream.close()
+ self._check_if_finished_writing()
+ else:
+ self._pending_buffers.append(data)
+ self._input_stream.read_async(self._CHUNK_SIZE,
+ self.__read_async_cb,
+ gobject.PRIORITY_LOW)
+
+ self._write_next_buffer()
+
+ def __write_async_cb(self, output_stream, result, user_data):
+ if self._cancelling:
+ return
+
+ count = output_stream.write_finish(result)
+
+ self._downloaded_size += count
+ progress = self._downloaded_size / float(self.bundle_update.size)
+ self.emit('progress', progress)
+
+ self._check_if_finished_writing()
+
+ if self._pending_buffers:
+ self._write_next_buffer()
+
+ def _write_next_buffer(self):
+ if self._pending_buffers and not self._output_stream.has_pending():
+ data = self._pending_buffers.pop(0)
+ # TODO: we pass the buffer as user_data because of
+ # http://bugzilla.gnome.org/show_bug.cgi?id=564102
+ self._output_stream.write_async(data, self.__write_async_cb,
+ gobject.PRIORITY_LOW,
+ user_data=data)
+
+ def _get_temp_file_path(self, uri):
+ # TODO: Should we use the HTTP headers for the file name?
+ scheme_, netloc_, path, params_, query_, fragment_ = \
+ urlparse(uri)
+ path = os.path.basename(path)
+
+ if not os.path.exists(env.get_user_activities_path()):
+ os.makedirs(env.get_user_activities_path())
+
+ base_name, extension_ = os.path.splitext(path)
+ fd, file_path = tempfile.mkstemp(dir=env.get_user_activities_path(),
+ prefix=base_name, suffix='.xo')
+ os.close(fd)
+ os.unlink(file_path)
+
+ return file_path
+
+ def get_local_file_path(self):
+ return self._output_file.get_path()
+
+ def _check_if_finished_writing(self):
+ if not self._pending_buffers and \
+ not self._output_stream.has_pending() and \
+ self._input_stream.is_closed():
+
+ logging.debug('closing output stream')
+ self._output_stream.close()
+
+ self.emit('progress', 1.0)
diff --git a/extensions/cpsection/updater/view.py b/extensions/cpsection/updater/view.py
new file mode 100644
index 0000000..814658f
--- /dev/null
+++ b/extensions/cpsection/updater/view.py
@@ -0,0 +1,391 @@
+# Copyright (C) 2008, One Laptop Per Child
+# Copyright (C) 2009, Tomeu Vizoso
+#
+# 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 2 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, write to the Free Software
+# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+
+from gettext import gettext as _
+from gettext import ngettext
+import locale
+import logging
+
+import gobject
+import gtk
+
+from sugar.graphics import style
+from sugar.graphics.icon import Icon, CellRendererIcon
+
+from jarabe.controlpanel.sectionview import SectionView
+
+from model import UpdateModel
+
+_DEBUG_VIEW_ALL = True
+
+
+class ActivityUpdater(SectionView):
+
+ def __init__(self, model, alerts):
+ SectionView.__init__(self)
+
+ self._model = UpdateModel()
+ self._model.connect('progress', self.__progress_cb)
+
+ self.set_spacing(style.DEFAULT_SPACING)
+ self.set_border_width(style.DEFAULT_SPACING * 2)
+
+ self._top_label = gtk.Label()
+ self._top_label.set_line_wrap(True)
+ self._top_label.set_justify(gtk.JUSTIFY_LEFT)
+ self._top_label.props.xalign = 0
+ self.pack_start(self._top_label, expand=False)
+ self._top_label.show()
+
+ separator = gtk.HSeparator()
+ self.pack_start(separator, expand=False)
+ separator.show()
+
+ bottom_label = gtk.Label()
+ bottom_label.set_line_wrap(True)
+ bottom_label.set_justify(gtk.JUSTIFY_LEFT)
+ bottom_label.props.xalign = 0
+ bottom_label.set_markup(
+ _('Software updates correct errors, eliminate security ' \
+ 'vulnerabilities, and provide new features.'))
+ self.pack_start(bottom_label, expand=False)
+ bottom_label.show()
+
+ self._update_box = None
+ self._progress_pane = None
+
+ self._refresh()
+
+ def _switch_to_update_box(self):
+ if self._update_box in self.get_children():
+ return
+
+ if self._progress_pane in self.get_children():
+ self.remove(self._progress_pane)
+ self._progress_pane = None
+
+ if self._update_box is None:
+ self._update_box = UpdateBox(self._model)
+ self._update_box.refresh_button.connect('clicked',
+ self.__refresh_button_clicked_cb)
+ self._update_box.install_button.connect('clicked',
+ self.__install_button_clicked_cb)
+
+ self.pack_start(self._update_box, expand=True, fill=True)
+ self._update_box.show()
+
+ def _switch_to_progress_pane(self):
+ if self._progress_pane in self.get_children():
+ return
+
+ if self._update_box in self.get_children():
+ self.remove(self._update_box)
+ self._update_box = None
+
+ if self._progress_pane is None:
+ self._progress_pane = ProgressPane()
+ self._progress_pane.cancel_button.connect('clicked',
+ self.__cancel_button_clicked_cb)
+
+ self.pack_start(self._progress_pane, expand=True, fill=False)
+ self._progress_pane.show()
+
+ def _clear_center(self):
+ if self._progress_pane in self.get_children():
+ self.remove(self._progress_pane)
+ self._progress_pane = None
+
+ if self._update_box in self.get_children():
+ self.remove(self._update_box)
+ self._update_box = None
+
+ def __progress_cb(self, model, action, bundle_name, current, total):
+ if current == total and action == UpdateModel.ACTION_CHECKING:
+ self._finished_checking()
+ return
+ elif current == total:
+ self._finished_updating(int(current))
+ return
+
+ if action == UpdateModel.ACTION_CHECKING:
+ message = _('Checking %s...') % bundle_name
+ elif action == UpdateModel.ACTION_DOWNLOADING:
+ message = _('Downloading %s...') % bundle_name
+ elif action == UpdateModel.ACTION_UPDATING:
+ message = _('Updating %s...') % bundle_name
+
+ self._switch_to_progress_pane()
+ self._progress_pane.set_message(message)
+ self._progress_pane.set_progress(current / float(total))
+
+ def _finished_checking(self):
+ logging.debug('ActivityUpdater._finished_checking')
+ available_updates = len(self._model.updates)
+ if not available_updates:
+ top_message = _('Your software is up-to-date')
+ else:
+ top_message = ngettext('You can install %s update',
+ 'You can install %s updates',
+ available_updates)
+ top_message = top_message % available_updates
+ top_message = gobject.markup_escape_text(top_message)
+
+ self._top_label.set_markup('<big>%s</big>' % top_message)
+
+ if not available_updates:
+ self._clear_center()
+ else:
+ self._switch_to_update_box()
+ self._update_box.refresh()
+
+ def __refresh_button_clicked_cb(self, button):
+ self._refresh()
+
+ def _refresh(self):
+ top_message = _('Checking for updates...')
+ self._top_label.set_markup('<big>%s</big>' % top_message)
+ self._model.check_updates()
+
+ def __install_button_clicked_cb(self, button):
+ text = '<big>%s</big>' % _('Installing updates...')
+ self._top_label.set_markup(text)
+ self._model.update(self._update_box.get_bundles_to_update())
+
+ def __cancel_button_clicked_cb(self, button):
+ self._model.cancel()
+
+ def _finished_updating(self, installed_updates):
+ logging.debug('ActivityUpdater._finished_updating')
+ top_message = ngettext('%s update was installed',
+ '%s updates were installed', installed_updates)
+ top_message = top_message % installed_updates
+ top_message = gobject.markup_escape_text(top_message)
+ self._top_label.set_markup('<big>%s</big>' % top_message)
+ self._clear_center()
+
+ def undo(self):
+ self._model.cancel()
+
+
+class ProgressPane(gtk.VBox):
+ """Container which replaces the `ActivityPane` during refresh or
+ install."""
+
+ def __init__(self):
+ gtk.VBox.__init__(self)
+ self.set_spacing(style.DEFAULT_PADDING)
+ self.set_border_width(style.DEFAULT_SPACING * 2)
+
+ self._progress = gtk.ProgressBar()
+ self.pack_start(self._progress)
+ self._progress.show()
+
+ self._label = gtk.Label()
+ self._label.set_line_wrap(True)
+ self._label.set_property('xalign', 0.5)
+ self._label.modify_fg(gtk.STATE_NORMAL,
+ style.COLOR_BUTTON_GREY.get_gdk_color())
+ self.pack_start(self._label)
+ self._label.show()
+
+ alignment_box = gtk.Alignment(xalign=0.5, yalign=0.5)
+ self.pack_start(alignment_box)
+ alignment_box.show()
+
+ self.cancel_button = gtk.Button(stock=gtk.STOCK_CANCEL)
+ alignment_box.add(self.cancel_button)
+ self.cancel_button.show()
+
+ def set_message(self, message):
+ self._label.set_text(message)
+
+ def set_progress(self, fraction):
+ self._progress.props.fraction = fraction
+
+
+class UpdateBox(gtk.VBox):
+
+ def __init__(self, model):
+ gtk.VBox.__init__(self)
+
+ self._model = model
+
+ self.set_spacing(style.DEFAULT_PADDING)
+
+ scrolled_window = gtk.ScrolledWindow()
+ scrolled_window.set_policy(gtk.POLICY_AUTOMATIC, gtk.POLICY_AUTOMATIC)
+ self.pack_start(scrolled_window)
+ scrolled_window.show()
+
+ self._update_list = UpdateList(model)
+ self._update_list.props.model.connect('row-changed',
+ self.__row_changed_cb)
+ scrolled_window.add(self._update_list)
+ self._update_list.show()
+
+ bottom_box = gtk.HBox()
+ bottom_box.set_spacing(style.DEFAULT_SPACING)
+ self.pack_start(bottom_box, expand=False)
+ bottom_box.show()
+
+ self._size_label = gtk.Label()
+ self._size_label.props.xalign = 0
+ self._size_label.set_justify(gtk.JUSTIFY_LEFT)
+ bottom_box.pack_start(self._size_label, expand=True)
+ self._size_label.show()
+
+ self.refresh_button = gtk.Button(stock=gtk.STOCK_REFRESH)
+ bottom_box.pack_start(self.refresh_button, expand=False)
+ self.refresh_button.show()
+
+ self.install_button = gtk.Button(_('Install selected'))
+ self.install_button.props.image = Icon(icon_name='emblem-downloads',
+ icon_size=gtk.ICON_SIZE_BUTTON)
+ bottom_box.pack_start(self.install_button, expand=False)
+ self.install_button.show()
+
+ self._update_total_size_label()
+
+ def refresh(self):
+ self._update_list.refresh()
+
+ def __row_changed_cb(self, list_model, path, iterator):
+ self._update_total_size_label()
+ self._update_install_button()
+
+ def _update_total_size_label(self):
+ total_size = 0
+ for row in self._update_list.props.model:
+ if row[UpdateListModel.SELECTED]:
+ total_size += row[UpdateListModel.SIZE]
+
+ markup = _('Download size: %s') % _format_size(total_size)
+ self._size_label.set_markup(markup)
+
+ def _update_install_button(self):
+ for row in self._update_list.props.model:
+ if row[UpdateListModel.SELECTED]:
+ self.install_button.props.sensitive = True
+ return
+ self.install_button.props.sensitive = False
+
+ def get_bundles_to_update(self):
+ bundles_to_update = []
+ for row in self._update_list.props.model:
+ if row[UpdateListModel.SELECTED]:
+ bundles_to_update.append(row[UpdateListModel.BUNDLE_ID])
+ return bundles_to_update
+
+
+class UpdateList(gtk.TreeView):
+
+ def __init__(self, model):
+ list_model = UpdateListModel(model)
+ gtk.TreeView.__init__(self, list_model)
+
+ self.set_reorderable(False)
+ self.set_enable_search(False)
+ self.set_headers_visible(False)
+
+ toggle_renderer = gtk.CellRendererToggle()
+ toggle_renderer.props.activatable = True
+ toggle_renderer.props.xpad = style.DEFAULT_PADDING
+ toggle_renderer.props.indicator_size = style.zoom(26)
+ toggle_renderer.connect('toggled', self.__toggled_cb)
+
+ toggle_column = gtk.TreeViewColumn()
+ toggle_column.pack_start(toggle_renderer)
+ toggle_column.add_attribute(toggle_renderer, 'active',
+ UpdateListModel.SELECTED)
+ self.append_column(toggle_column)
+
+ icon_renderer = CellRendererIcon(self)
+ icon_renderer.props.width = style.STANDARD_ICON_SIZE
+ icon_renderer.props.height = style.STANDARD_ICON_SIZE
+ icon_renderer.props.size = style.STANDARD_ICON_SIZE
+ icon_renderer.props.xpad = style.DEFAULT_PADDING
+ icon_renderer.props.ypad = style.DEFAULT_PADDING
+ icon_renderer.props.stroke_color = style.COLOR_TOOLBAR_GREY.get_svg()
+ icon_renderer.props.fill_color = style.COLOR_TRANSPARENT.get_svg()
+
+ icon_column = gtk.TreeViewColumn()
+ icon_column.pack_start(icon_renderer)
+ icon_column.add_attribute(icon_renderer, 'file-name',
+ UpdateListModel.ICON_FILE_NAME)
+ self.append_column(icon_column)
+
+ text_renderer = gtk.CellRendererText()
+
+ description_column = gtk.TreeViewColumn()
+ description_column.pack_start(text_renderer)
+ description_column.add_attribute(text_renderer, 'markup',
+ UpdateListModel.DESCRIPTION)
+ self.append_column(description_column)
+
+ def __toggled_cb(self, cell_renderer, path):
+ row = self.props.model[path]
+ row[UpdateListModel.SELECTED] = not row[UpdateListModel.SELECTED]
+
+ def refresh(self):
+ pass
+
+
+class UpdateListModel(gtk.ListStore):
+
+ BUNDLE_ID = 0
+ SELECTED = 1
+ ICON_FILE_NAME = 2
+ DESCRIPTION = 3
+ SIZE = 4
+
+ def __init__(self, model):
+ gtk.ListStore.__init__(self, str, bool, str, str, int)
+
+ for bundle_update in model.updates:
+ row = [None] * 5
+ row[self.BUNDLE_ID] = bundle_update.bundle.get_bundle_id()
+ row[self.SELECTED] = True
+ row[self.ICON_FILE_NAME] = bundle_update.bundle.get_icon()
+
+ details = _('From version %(current)s to %(new)s (Size: %(size)s)')
+ details = details % \
+ {'current': bundle_update.bundle.get_activity_version(),
+ 'new': bundle_update.version,
+ 'size': _format_size(bundle_update.size)}
+
+ row[self.DESCRIPTION] = '<b>%s</b>\n%s' % \
+ (bundle_update.bundle.get_name(), details)
+
+ row[self.SIZE] = bundle_update.size
+
+ self.append(row)
+
+
+def _format_size(size):
+ """Convert a given size in bytes to a nicer better readable unit"""
+ if size == 0:
+ # TRANS: download size is 0
+ return _('None')
+ elif size < 1024:
+ # TRANS: download size of very small updates
+ return _('1 KB')
+ elif size < 1024 * 1024:
+ # TRANS: download size of small updates, e.g. '250 KB'
+ return locale.format_string(_('%.0f KB'), size / 1024.0)
+ else:
+ # TRANS: download size of updates, e.g. '2.3 MB'
+ return locale.format_string(_('%.1f MB'), size / 1024.0 / 1024)