Web   ·   Wiki   ·   Activities   ·   Blog   ·   Lists   ·   Chat   ·   Meeting   ·   Bugs   ·   Git   ·   Translate   ·   Archive   ·   People   ·   Donate
summaryrefslogtreecommitdiffstats
path: root/sugar-toolkit/src/sugar/activity
diff options
context:
space:
mode:
Diffstat (limited to 'sugar-toolkit/src/sugar/activity')
-rw-r--r--sugar-toolkit/src/sugar/activity/Makefile.am10
-rw-r--r--sugar-toolkit/src/sugar/activity/Makefile.in437
-rw-r--r--sugar-toolkit/src/sugar/activity/__init__.py55
-rw-r--r--sugar-toolkit/src/sugar/activity/__init__py0
-rw-r--r--sugar-toolkit/src/sugar/activity/activity.py1102
-rw-r--r--sugar-toolkit/src/sugar/activity/activityfactory.py343
-rw-r--r--sugar-toolkit/src/sugar/activity/activityhandle.py70
-rw-r--r--sugar-toolkit/src/sugar/activity/activityservice.py82
-rw-r--r--sugar-toolkit/src/sugar/activity/bundlebuilder.py398
-rw-r--r--sugar-toolkit/src/sugar/activity/main.py140
-rw-r--r--sugar-toolkit/src/sugar/activity/namingalert.py320
11 files changed, 0 insertions, 2957 deletions
diff --git a/sugar-toolkit/src/sugar/activity/Makefile.am b/sugar-toolkit/src/sugar/activity/Makefile.am
deleted file mode 100644
index 91f6ea8..0000000
--- a/sugar-toolkit/src/sugar/activity/Makefile.am
+++ /dev/null
@@ -1,10 +0,0 @@
-sugardir = $(pythondir)/sugar/activity
-sugar_PYTHON = \
- __init__.py \
- activity.py \
- activityfactory.py \
- activityhandle.py \
- activityservice.py \
- bundlebuilder.py \
- main.py \
- namingalert.py \ No newline at end of file
diff --git a/sugar-toolkit/src/sugar/activity/Makefile.in b/sugar-toolkit/src/sugar/activity/Makefile.in
deleted file mode 100644
index 24c3dd0..0000000
--- a/sugar-toolkit/src/sugar/activity/Makefile.in
+++ /dev/null
@@ -1,437 +0,0 @@
-# Makefile.in generated by automake 1.10.1 from Makefile.am.
-# @configure_input@
-
-# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002,
-# 2003, 2004, 2005, 2006, 2007, 2008 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@
-pkglibdir = $(libdir)/@PACKAGE@
-pkgincludedir = $(includedir)/@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 = :
-build_triplet = @build@
-host_triplet = @host@
-subdir = src/sugar/activity
-DIST_COMMON = $(srcdir)/Makefile.am $(srcdir)/Makefile.in \
- $(sugar_PYTHON)
-ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
-am__aclocal_m4_deps = $(top_srcdir)/m4/gnome-compiler-flags.m4 \
- $(top_srcdir)/m4/intltool.m4 $(top_srcdir)/m4/libtool.m4 \
- $(top_srcdir)/m4/ltoptions.m4 $(top_srcdir)/m4/ltsugar.m4 \
- $(top_srcdir)/m4/ltversion.m4 $(top_srcdir)/m4/lt~obsolete.m4 \
- $(top_srcdir)/m4/python.m4 $(top_srcdir)/configure.ac
-am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
- $(ACLOCAL_M4)
-mkinstalldirs = $(install_sh) -d
-CONFIG_CLEAN_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 = `echo $$p | sed -e 's|^.*/||'`;
-am__installdirs = "$(DESTDIR)$(sugardir)"
-sugarPYTHON_INSTALL = $(INSTALL_DATA)
-py_compile = $(top_srcdir)/py-compile
-DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
-ACLOCAL = @ACLOCAL@
-ALL_LINGUAS = @ALL_LINGUAS@
-AMTAR = @AMTAR@
-AR = @AR@
-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@
-DSYMUTIL = @DSYMUTIL@
-DUMPBIN = @DUMPBIN@
-ECHO_C = @ECHO_C@
-ECHO_N = @ECHO_N@
-ECHO_T = @ECHO_T@
-EGREP = @EGREP@
-EXEEXT = @EXEEXT@
-EXT_CFLAGS = @EXT_CFLAGS@
-EXT_LIBS = @EXT_LIBS@
-FGREP = @FGREP@
-GETTEXT_PACKAGE = @GETTEXT_PACKAGE@
-GLIB_GENMARSHAL = @GLIB_GENMARSHAL@
-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_CAVES_RULE = @INTLTOOL_CAVES_RULE@
-INTLTOOL_DESKTOP_RULE = @INTLTOOL_DESKTOP_RULE@
-INTLTOOL_DIRECTORY_RULE = @INTLTOOL_DIRECTORY_RULE@
-INTLTOOL_EXTRACT = @INTLTOOL_EXTRACT@
-INTLTOOL_KBD_RULE = @INTLTOOL_KBD_RULE@
-INTLTOOL_KEYS_RULE = @INTLTOOL_KEYS_RULE@
-INTLTOOL_MERGE = @INTLTOOL_MERGE@
-INTLTOOL_OAF_RULE = @INTLTOOL_OAF_RULE@
-INTLTOOL_PERL = @INTLTOOL_PERL@
-INTLTOOL_POLICY_RULE = @INTLTOOL_POLICY_RULE@
-INTLTOOL_PONG_RULE = @INTLTOOL_PONG_RULE@
-INTLTOOL_PROP_RULE = @INTLTOOL_PROP_RULE@
-INTLTOOL_SCHEMAS_RULE = @INTLTOOL_SCHEMAS_RULE@
-INTLTOOL_SERVER_RULE = @INTLTOOL_SERVER_RULE@
-INTLTOOL_SERVICE_RULE = @INTLTOOL_SERVICE_RULE@
-INTLTOOL_SHEET_RULE = @INTLTOOL_SHEET_RULE@
-INTLTOOL_SOUNDLIST_RULE = @INTLTOOL_SOUNDLIST_RULE@
-INTLTOOL_THEME_RULE = @INTLTOOL_THEME_RULE@
-INTLTOOL_UI_RULE = @INTLTOOL_UI_RULE@
-INTLTOOL_UPDATE = @INTLTOOL_UPDATE@
-INTLTOOL_XAM_RULE = @INTLTOOL_XAM_RULE@
-INTLTOOL_XML_NOMERGE_RULE = @INTLTOOL_XML_NOMERGE_RULE@
-INTLTOOL_XML_RULE = @INTLTOOL_XML_RULE@
-LD = @LD@
-LDFLAGS = @LDFLAGS@
-LIBOBJS = @LIBOBJS@
-LIBS = @LIBS@
-LIBTOOL = @LIBTOOL@
-LIPO = @LIPO@
-LN_S = @LN_S@
-LTLIBOBJS = @LTLIBOBJS@
-MAKEINFO = @MAKEINFO@
-MKDIR_P = @MKDIR_P@
-MKINSTALLDIRS = @MKINSTALLDIRS@
-MSGFMT = @MSGFMT@
-MSGFMT_OPTS = @MSGFMT_OPTS@
-MSGMERGE = @MSGMERGE@
-NM = @NM@
-NMEDIT = @NMEDIT@
-OBJEXT = @OBJEXT@
-OTOOL = @OTOOL@
-OTOOL64 = @OTOOL64@
-PACKAGE = @PACKAGE@
-PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@
-PACKAGE_NAME = @PACKAGE_NAME@
-PACKAGE_STRING = @PACKAGE_STRING@
-PACKAGE_TARNAME = @PACKAGE_TARNAME@
-PACKAGE_VERSION = @PACKAGE_VERSION@
-PATH_SEPARATOR = @PATH_SEPARATOR@
-PKG_CONFIG = @PKG_CONFIG@
-POFILES = @POFILES@
-POSUB = @POSUB@
-PO_IN_DATADIR_FALSE = @PO_IN_DATADIR_FALSE@
-PO_IN_DATADIR_TRUE = @PO_IN_DATADIR_TRUE@
-PYGTK_CODEGEN = @PYGTK_CODEGEN@
-PYGTK_DEFSDIR = @PYGTK_DEFSDIR@
-PYTHON = @PYTHON@
-PYTHON_EXEC_PREFIX = @PYTHON_EXEC_PREFIX@
-PYTHON_INCLUDES = @PYTHON_INCLUDES@
-PYTHON_PLATFORM = @PYTHON_PLATFORM@
-PYTHON_PREFIX = @PYTHON_PREFIX@
-PYTHON_VERSION = @PYTHON_VERSION@
-RANLIB = @RANLIB@
-SED = @SED@
-SET_MAKE = @SET_MAKE@
-SHELL = @SHELL@
-STRIP = @STRIP@
-USE_NLS = @USE_NLS@
-VERSION = @VERSION@
-WARN_CFLAGS = @WARN_CFLAGS@
-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@
-ac_ct_DUMPBIN = @ac_ct_DUMPBIN@
-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 = @build@
-build_alias = @build_alias@
-build_cpu = @build_cpu@
-build_os = @build_os@
-build_vendor = @build_vendor@
-builddir = @builddir@
-datadir = @datadir@
-datarootdir = @datarootdir@
-docdir = @docdir@
-dvidir = @dvidir@
-exec_prefix = @exec_prefix@
-host = @host@
-host_alias = @host_alias@
-host_cpu = @host_cpu@
-host_os = @host_os@
-host_vendor = @host_vendor@
-htmldir = @htmldir@
-includedir = @includedir@
-infodir = @infodir@
-install_sh = @install_sh@
-libdir = @libdir@
-libexecdir = @libexecdir@
-localedir = @localedir@
-localstatedir = @localstatedir@
-lt_ECHO = @lt_ECHO@
-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_builddir = @top_builddir@
-top_srcdir = @top_srcdir@
-sugardir = $(pythondir)/sugar/activity
-sugar_PYTHON = \
- __init__.py \
- activity.py \
- activityfactory.py \
- activityhandle.py \
- activityservice.py \
- bundlebuilder.py \
- main.py \
- namingalert.py
-
-all: all-am
-
-.SUFFIXES:
-$(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps)
- @for dep in $?; do \
- case '$(am__configure_deps)' in \
- *$$dep*) \
- cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh \
- && exit 0; \
- exit 1;; \
- esac; \
- done; \
- echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign src/sugar/activity/Makefile'; \
- cd $(top_srcdir) && \
- $(AUTOMAKE) --foreign src/sugar/activity/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: $(am__configure_deps)
- cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
-$(ACLOCAL_M4): $(am__aclocal_m4_deps)
- cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
-
-mostlyclean-libtool:
- -rm -f *.lo
-
-clean-libtool:
- -rm -rf .libs _libs
-install-sugarPYTHON: $(sugar_PYTHON)
- @$(NORMAL_INSTALL)
- test -z "$(sugardir)" || $(MKDIR_P) "$(DESTDIR)$(sugardir)"
- @list='$(sugar_PYTHON)'; dlist=''; for p in $$list; do\
- if test -f "$$p"; then b=; else b="$(srcdir)/"; fi; \
- if test -f $$b$$p; then \
- f=$(am__strip_dir) \
- dlist="$$dlist $$f"; \
- echo " $(sugarPYTHON_INSTALL) '$$b$$p' '$(DESTDIR)$(sugardir)/$$f'"; \
- $(sugarPYTHON_INSTALL) "$$b$$p" "$(DESTDIR)$(sugardir)/$$f"; \
- else :; fi; \
- done; \
- if test -n "$$dlist"; then \
- if test -z "$(DESTDIR)"; then \
- PYTHON=$(PYTHON) $(py_compile) --basedir "$(sugardir)" $$dlist; \
- else \
- PYTHON=$(PYTHON) $(py_compile) --destdir "$(DESTDIR)" --basedir "$(sugardir)" $$dlist; \
- fi; \
- else :; fi
-
-uninstall-sugarPYTHON:
- @$(NORMAL_UNINSTALL)
- @list='$(sugar_PYTHON)'; dlist=''; for p in $$list; do\
- f=$(am__strip_dir) \
- rm -f "$(DESTDIR)$(sugardir)/$$f"; \
- rm -f "$(DESTDIR)$(sugardir)/$${f}c"; \
- rm -f "$(DESTDIR)$(sugardir)/$${f}o"; \
- done
-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 $(srcdir)/$$file && test $$d != $(srcdir); then \
- cp -pR $(srcdir)/$$file $(distdir)$$dir || exit 1; \
- fi; \
- cp -pR $$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:
- $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
- install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
- `test -z '$(STRIP)' || \
- echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install
-mostlyclean-generic:
-
-clean-generic:
-
-distclean-generic:
- -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_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 clean-libtool mostlyclean-am
-
-distclean: distclean-am
- -rm -f Makefile
-distclean-am: clean-am distclean-generic
-
-dvi: dvi-am
-
-dvi-am:
-
-html: html-am
-
-info: info-am
-
-info-am:
-
-install-data-am: install-sugarPYTHON
-
-install-dvi: install-dvi-am
-
-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
-
-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 mostlyclean-libtool
-
-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 clean-libtool \
- distclean distclean-generic distclean-libtool 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 mostlyclean-libtool 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/sugar-toolkit/src/sugar/activity/__init__.py b/sugar-toolkit/src/sugar/activity/__init__.py
deleted file mode 100644
index 8d3ef2b..0000000
--- a/sugar-toolkit/src/sugar/activity/__init__.py
+++ /dev/null
@@ -1,55 +0,0 @@
-# Copyright (C) 2006-2007, Red Hat, Inc.
-#
-# This library is free software; you can redistribute it and/or
-# modify it under the terms of the GNU Lesser General Public
-# License as published by the Free Software Foundation; either
-# version 2 of the License, or (at your option) any later version.
-#
-# This library is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-# Lesser General Public License for more details.
-#
-# You should have received a copy of the GNU Lesser General Public
-# License along with this library; if not, write to the
-# Free Software Foundation, Inc., 59 Temple Place - Suite 330,
-# Boston, MA 02111-1307, USA.
-
-"""Activity implementation code for Sugar-based activities
-
-Each activity within the OLPC environment must provide two
-dbus services. The first, patterned after the
-
- sugar.activity.activityfactory.ActivityFactory
-
-class is responsible for providing a "create" method which
-takes a small dictionary with values corresponding to a
-
- sugar.activity.activityhandle.ActivityHandle
-
-describing an individual instance of the activity.
-
-Each activity so registered is described by a
-
- sugar.activity.bundle.Bundle
-
-instance, which parses a specially formatted activity.info
-file (stored in the activity directory's ./activity
-subdirectory). The
-
- sugar.activity.bundlebuilder
-
-module provides facilities for the standard setup.py module
-which produces and registers bundles from activity source
-directories.
-
-Once instantiated by the ActivityFactory's create method,
-each activity must provide an introspection API patterned
-after the
-
- sugar.activity.activityservice.ActivityService
-
-class. This class allows for querying the ID of the root
-window, requesting sharing across the network, and basic
-"what type of application are you" queries.
-"""
diff --git a/sugar-toolkit/src/sugar/activity/__init__py b/sugar-toolkit/src/sugar/activity/__init__py
deleted file mode 100644
index e69de29..0000000
--- a/sugar-toolkit/src/sugar/activity/__init__py
+++ /dev/null
diff --git a/sugar-toolkit/src/sugar/activity/activity.py b/sugar-toolkit/src/sugar/activity/activity.py
deleted file mode 100644
index 0ad1d91..0000000
--- a/sugar-toolkit/src/sugar/activity/activity.py
+++ /dev/null
@@ -1,1102 +0,0 @@
-"""Base class for activities written in Python
-
-This is currently the only definitive reference for what an
-activity must do to participate in the Sugar desktop.
-
- A Basic Activity
-
-All activities must implement a class derived from 'Activity' in this class.
-The convention is to call it ActivitynameActivity, but this is not required as
-the activity.info file associated with your activity will tell the sugar-shell
-which class to start.
-
-For example the most minimal Activity:
-
-
- from sugar.activity import activity
-
- class ReadActivity(activity.Activity):
- pass
-
-To get a real, working activity, you will at least have to implement:
- __init__(), read_file() and write_file()
-
-Aditionally, you will probably need a at least a Toolbar so you can have some
-interesting buttons for the user, like for example 'exit activity'
-
-See the methods of the Activity class below for more information on what you
-will need for a real activity.
-
-STABLE.
-"""
-# Copyright (C) 2006-2007 Red Hat, Inc.
-# Copyright (C) 2007-2009 One Laptop Per Child
-#
-# This library is free software; you can redistribute it and/or
-# modify it under the terms of the GNU Lesser General Public
-# License as published by the Free Software Foundation; either
-# version 2 of the License, or (at your option) any later version.
-#
-# This library is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-# Lesser General Public License for more details.
-#
-# You should have received a copy of the GNU Lesser General Public
-# License along with this library; if not, write to the
-# Free Software Foundation, Inc., 59 Temple Place - Suite 330,
-# Boston, MA 02111-1307, USA.
-
-import gettext
-import logging
-import os
-import time
-from hashlib import sha1
-import traceback
-import gconf
-
-import gtk
-import gobject
-import dbus
-import dbus.service
-import cjson
-
-from sugar import util
-from sugar.presence import presenceservice
-from sugar.activity.activityservice import ActivityService
-from sugar.activity.namingalert import NamingAlert
-from sugar.graphics import style
-from sugar.graphics.window import Window
-from sugar.graphics.toolbox import Toolbox
-from sugar.graphics.toolbutton import ToolButton
-from sugar.graphics.toolcombobox import ToolComboBox
-from sugar.graphics.alert import Alert
-from sugar.graphics.icon import Icon
-from sugar.graphics.xocolor import XoColor
-from sugar.datastore import datastore
-from sugar.session import XSMPClient
-from sugar import wm
-from sugar.tutorius.services import ObjectStore
-
-_ = lambda msg: gettext.dgettext('sugar-toolkit', msg)
-
-SCOPE_PRIVATE = "private"
-SCOPE_INVITE_ONLY = "invite" # shouldn't be shown in UI, it's implicit
-SCOPE_NEIGHBORHOOD = "public"
-
-J_DBUS_SERVICE = 'org.laptop.Journal'
-J_DBUS_PATH = '/org/laptop/Journal'
-J_DBUS_INTERFACE = 'org.laptop.Journal'
-
-class ActivityToolbar(gtk.Toolbar):
- """The Activity toolbar with the Journal entry title, sharing,
- Keep and Stop buttons
-
- All activities should have this toolbar. It is easiest to add it to your
- Activity by using the ActivityToolbox.
- """
- def __init__(self, activity):
- gtk.Toolbar.__init__(self)
- self.set_name("ActivityToolbar")
-
- self._activity = activity
- self._updating_share = False
-
- activity.connect('shared', self.__activity_shared_cb)
- activity.connect('joined', self.__activity_shared_cb)
- activity.connect('notify::max_participants',
- self.__max_participants_changed_cb)
-
- if activity.metadata:
- self.title = gtk.Entry()
- self.title.set_name("Title")
- self.title.set_size_request(int(gtk.gdk.screen_width() / 3), -1)
- self.title.set_text(activity.metadata['title'])
- self.title.connect('changed', self.__title_changed_cb)
- self._add_widget(self.title)
-
- activity.metadata.connect('updated', self.__jobject_updated_cb)
-
- separator = gtk.SeparatorToolItem()
- separator.props.draw = False
- separator.set_expand(True)
- self.insert(separator, -1)
- separator.show()
-
- if hasattr(self._activity,"get_tutorials") and hasattr(self._activity.get_tutorials,"__call__"):
- self.tutorials = ToolComboBox(label_text=_('Tutorials:'))
- self.tutorials.combo.connect('changed', self.__tutorial_changed_cb)
- tutorials = self._activity.get_tutorials()
- self._current_tutorial = None
- if tutorials:
- for key, tutorial in tutorials.items():
- self.tutorials.combo.append_item(key, tutorial.name)
- self.insert(self.tutorials, -1)
- self.tutorials.show()
-
- self.share = ToolComboBox(label_text=_('Share with:'))
- self.share.set_name("Share")
- self.share.combo.connect('changed', self.__share_changed_cb)
- self.share.combo.append_item(SCOPE_PRIVATE, _('Private'), 'zoom-home')
- self.share.combo.append_item(SCOPE_NEIGHBORHOOD, _('My Neighborhood'),
- 'zoom-neighborhood')
- self.insert(self.share, -1)
- self.share.show()
-
- self._update_share()
-
- self.keep = ToolButton(tooltip=_('Keep'))
- self.keep.set_name("Keep")
- client = gconf.client_get_default()
- color = XoColor(client.get_string('/desktop/sugar/user/color'))
- keep_icon = Icon(icon_name='document-save', xo_color=color)
- self.keep.set_icon_widget(keep_icon)
- keep_icon.show()
- self.keep.props.accelerator = '<Ctrl>S'
- self.keep.connect('clicked', self.__keep_clicked_cb)
- self.insert(self.keep, -1)
- self.keep.show()
-
- self.stop = ToolButton('activity-stop', tooltip=_('Stop'))
- self.stop.set_name("Stop")
- self.stop.props.accelerator = '<Ctrl>Q'
- self.stop.connect('clicked', self.__stop_clicked_cb)
- self.insert(self.stop, -1)
- self.stop.show()
-
- self._update_title_sid = None
-
-
- def _update_share(self):
- self._updating_share = True
-
- if self._activity.props.max_participants == 1:
- self.share.hide()
-
- if self._activity.get_shared():
- self.share.set_sensitive(False)
- self.share.combo.set_active(1)
- else:
- self.share.set_sensitive(True)
- self.share.combo.set_active(0)
-
- self._updating_share = False
-
- def __tutorial_changed_cb(self, combo):
- if self._current_tutorial:
- self._current_tutorial.detach()
-
- model = self.tutorials.combo.get_model()
- it = self.tutorials.combo.get_active_iter()
- (key, ) = model.get(it, 0)
- t = self._activity.get_tutorials.get(key,None)
- if t:
- self._current_tutorial = t
- self._current_tutorial.attach(self._activity)
-
- def __share_changed_cb(self, combo):
- if self._updating_share:
- return
-
- model = self.share.combo.get_model()
- it = self.share.combo.get_active_iter()
- (scope, ) = model.get(it, 0)
- if scope == SCOPE_NEIGHBORHOOD:
- self._activity.share()
-
- def __tutorial_changed_cb(self, combo):
- """
- Callback for tutorial combobox item change
- """
- model = combo.get_model()
- it = combo.get_active_iter()
- (key, ) = model.get(it, 0)
- tutorial = self._activity.get_tutorials().get(key,None)
- if not tutorial is None:
- if not self._current_tutorial is None:
- self._current_tutorial.detach()
- self._current_tutorial = tutorial
- self._current_tutorial.attach(self._activity)
-
- def __keep_clicked_cb(self, button):
- self._activity.copy()
-
- def __stop_clicked_cb(self, button):
- self._activity.close()
-
- def __jobject_updated_cb(self, jobject):
- self.title.set_text(jobject['title'])
-
- def __title_changed_cb(self, entry):
- if not self._update_title_sid:
- self._update_title_sid = gobject.timeout_add_seconds(
- 1, self.__update_title_cb)
-
- def __update_title_cb(self):
- title = self.title.get_text()
-
- self._activity.metadata['title'] = title
- self._activity.metadata['title_set_by_user'] = '1'
- self._activity.save()
-
- shared_activity = self._activity.get_shared_activity()
- if shared_activity:
- shared_activity.props.name = title
-
- self._update_title_sid = None
- return False
-
- def _add_widget(self, widget, expand=False):
- tool_item = gtk.ToolItem()
- tool_item.set_expand(expand)
-
- tool_item.add(widget)
- widget.show()
-
- self.insert(tool_item, -1)
- tool_item.show()
-
- def __activity_shared_cb(self, activity):
- self._update_share()
-
- def __max_participants_changed_cb(self, activity, pspec):
- self._update_share()
-
-class EditToolbar(gtk.Toolbar):
- """Provides the standard edit toolbar for Activities.
-
- Members:
- undo -- the undo button
- redo -- the redo button
- copy -- the copy button
- paste -- the paste button
- separator -- A separator between undo/redo and copy/paste
-
- This class only provides the 'edit' buttons in a standard layout,
- your activity will need to either hide buttons which make no sense for your
- Activity, or you need to connect the button events to your own callbacks:
-
- ## Example from Read.activity:
- # Create the edit toolbar:
- self._edit_toolbar = EditToolbar(self._view)
- # Hide undo and redo, they're not needed
- self._edit_toolbar.undo.props.visible = False
- self._edit_toolbar.redo.props.visible = False
- # Hide the separator too:
- self._edit_toolbar.separator.props.visible = False
-
- # As long as nothing is selected, copy needs to be insensitive:
- self._edit_toolbar.copy.set_sensitive(False)
- # When the user clicks the button, call _edit_toolbar_copy_cb()
- self._edit_toolbar.copy.connect('clicked', self._edit_toolbar_copy_cb)
-
- # Add the edit toolbar:
- toolbox.add_toolbar(_('Edit'), self._edit_toolbar)
- # And make it visible:
- self._edit_toolbar.show()
- """
- def __init__(self):
- gtk.Toolbar.__init__(self)
- self.set_name("EditToolbar")
-
- self.undo = ToolButton('edit-undo')
- self.undo.set_name("Undo")
- self.undo.set_tooltip(_('Undo'))
- self.insert(self.undo, -1)
- self.undo.show()
-
- self.redo = ToolButton('edit-redo')
- self.redo.set_name("Redo")
- self.redo.set_tooltip(_('Redo'))
- self.insert(self.redo, -1)
- self.redo.show()
-
- self.separator = gtk.SeparatorToolItem()
- self.separator.set_draw(True)
- self.insert(self.separator, -1)
- self.separator.show()
-
- self.copy = ToolButton('edit-copy')
- self.copy.set_name("Copy")
- self.copy.set_tooltip(_('Copy'))
- self.insert(self.copy, -1)
- self.copy.show()
-
- self.paste = ToolButton('edit-paste')
- self.paste.set_name("Paste")
- self.paste.set_tooltip(_('Paste'))
- self.insert(self.paste, -1)
- self.paste.show()
-
-class ActivityToolbox(Toolbox):
- """Creates the Toolbox for the Activity
-
- By default, the toolbox contains only the ActivityToolbar. After creating
- the toolbox, you can add your activity specific toolbars, for example the
- EditToolbar.
-
- To add the ActivityToolbox to your Activity in MyActivity.__init__() do:
-
- # Create the Toolbar with the ActivityToolbar:
- toolbox = activity.ActivityToolbox(self)
- ... your code, inserting all other toolbars you need, like EditToolbar
-
- # Add the toolbox to the activity frame:
- self.set_toolbox(toolbox)
- # And make it visible:
- toolbox.show()
- """
- def __init__(self, activity):
- Toolbox.__init__(self)
-
- self._activity_toolbar = ActivityToolbar(activity)
- self.add_toolbar(_('Activity'), self._activity_toolbar)
- self._activity_toolbar.show()
-
- def get_activity_toolbar(self):
- return self._activity_toolbar
-
-class _ActivitySession(gobject.GObject):
- __gsignals__ = {
- 'quit-requested': (gobject.SIGNAL_RUN_FIRST, gobject.TYPE_NONE, ([])),
- 'quit': (gobject.SIGNAL_RUN_FIRST, gobject.TYPE_NONE, ([]))
- }
-
- def __init__(self):
- gobject.GObject.__init__(self)
-
- self._xsmp_client = XSMPClient()
- self._xsmp_client.connect('quit-requested', self.__sm_quit_requested_cb)
- self._xsmp_client.connect('quit', self.__sm_quit_cb)
- self._xsmp_client.startup()
-
- self._activities = []
- self._will_quit = []
-
- def register(self, activity):
- self._activities.append(activity)
-
- def unregister(self, activity):
- self._activities.remove(activity)
-
- if len(self._activities) == 0:
- logging.debug('Quitting the activity process.')
- gtk.main_quit()
-
- def will_quit(self, activity, will_quit):
- if will_quit:
- self._will_quit.append(activity)
-
- # We can quit only when all the instances agreed to
- for activity in self._activities:
- if activity not in self._will_quit:
- return
-
- self._xsmp_client.will_quit(True)
- else:
- self._will_quit = []
- self._xsmp_client.will_quit(False)
-
- def __sm_quit_requested_cb(self, client):
- self.emit('quit-requested')
-
- def __sm_quit_cb(self, client):
- self.emit('quit')
-
-class Activity(Window, gtk.Container):
- """This is the base Activity class that all other Activities derive from.
- This is where your activity starts.
-
- To get a working Activity:
- 0. Derive your Activity from this class:
- class MyActivity(activity.Activity):
- ...
-
- 1. implement an __init__() method for your Activity class.
-
- Use your init method to create your own ActivityToolbar which will
- contain some standard buttons:
- toolbox = activity.ActivityToolbox(self)
-
- Add extra Toolbars to your toolbox.
-
- You should setup Activity sharing here too.
-
- Finaly, your Activity may need some resources which you can claim
- here too.
-
- The __init__() method is also used to make the distinction between
- being resumed from the Journal, or starting with a blank document.
-
- 2. Implement read_file() and write_file()
- Most activities revolve around creating and storing Journal entries.
- For example, Write: You create a document, it is saved to the Journal
- and then later you resume working on the document.
-
- read_file() and write_file() will be called by sugar to tell your
- Activity that it should load or save the document the user is working
- on.
-
- 3. Implement our Activity Toolbars.
- The Toolbars are added to your Activity in step 1 (the toolbox), but
- you need to implement them somewhere. Now is a good time.
-
- There are a number of standard Toolbars. The most basic one, the one
- your almost absolutely MUST have is the ActivityToolbar. Without
- this, you're not really making a proper Sugar Activity (which may be
- okay, but you should really stop and think about why not!) You do
- this with the ActivityToolbox(self) call in step 1.
-
- Usually, you will also need the standard EditToolbar. This is the one
- which has the standard copy and paste buttons. You need to derive
- your own EditToolbar class from sugar.EditToolbar:
- class EditToolbar(activity.EditToolbar):
- ...
-
- See EditToolbar for the methods you should implement in your class.
-
- Finaly, your Activity will very likely need some activity specific
- buttons and options you can create your own toolbars by deriving a
- class from gtk.Toolbar:
- class MySpecialToolbar(gtk.Toolbar):
- ...
-
- 4. Use your creativity. Make your Activity something special and share
- it with your friends!
-
- Read through the methods of the Activity class below, to learn more about
- how to make an Activity work.
-
- Hint: A good and simple Activity to learn from is the Read activity. To
- create your own activity, you may want to copy it and use it as a template.
- """
- __gtype_name__ = 'SugarActivity'
-
- __gsignals__ = {
- 'shared': (gobject.SIGNAL_RUN_FIRST, gobject.TYPE_NONE, ([])),
- 'joined': (gobject.SIGNAL_RUN_FIRST, gobject.TYPE_NONE, ([]))
- }
-
- def __init__(self, handle, create_jobject=True):
- """Initialise the Activity
-
- handle -- sugar.activity.activityhandle.ActivityHandle
- instance providing the activity id and access to the
- presence service which *may* provide sharing for this
- application
-
- create_jobject -- boolean
- define if it should create a journal object if we are
- not resuming
-
- Side effects:
-
- Sets the gdk screen DPI setting (resolution) to the
- Sugar screen resolution.
-
- Connects our "destroy" message to our _destroy_cb
- method.
-
- Creates a base gtk.Window within this window.
-
- Creates an ActivityService (self._bus) servicing
- this application.
-
- Usage:
- If your Activity implements __init__(), it should call
- the base class __init()__ before doing Activity specific things.
-
- """
- Window.__init__(self)
-
- ObjectStore().activity = self
-
- # process titles will only show 15 characters
- # but they get truncated anyway so if more characters
- # are supported in the future we will get a better view
- # of the processes
- proc_title = "%s <%s>" % (get_bundle_name(), handle.activity_id)
- util.set_proc_title(proc_title)
-
- self.connect('realize', self.__realize_cb)
- self.connect('delete-event', self.__delete_event_cb)
-
- self._active = False
- self._activity_id = handle.activity_id
- self._pservice = presenceservice.get_instance()
- self.shared_activity = None
- self._share_id = None
- self._join_id = None
- self._updating_jobject = False
- self._closing = False
- self._quit_requested = False
- self._deleting = False
- self._max_participants = 0
- self._invites_queue = []
- self._jobject = None
-
- self._session = _get_session()
- self._session.register(self)
- self._session.connect('quit-requested',
- self.__session_quit_requested_cb)
- self._session.connect('quit', self.__session_quit_cb)
-
- accel_group = gtk.AccelGroup()
- self.set_data('sugar-accel-group', accel_group)
- self.add_accel_group(accel_group)
-
- self._bus = ActivityService(self)
- self._owns_file = False
-
- share_scope = SCOPE_PRIVATE
-
- if handle.object_id:
- self._jobject = datastore.get(handle.object_id)
- self.set_title(self._jobject.metadata['title'])
-
- if self._jobject.metadata.has_key('share-scope'):
- share_scope = self._jobject.metadata['share-scope']
-
- # handle activity share/join
- mesh_instance = self._pservice.get_activity(self._activity_id,
- warn_if_none=False)
- logging.debug("*** Act %s, mesh instance %r, scope %s",
- self._activity_id, mesh_instance, share_scope)
- if mesh_instance is not None:
- # There's already an instance on the mesh, join it
- logging.debug("*** Act %s joining existing mesh instance %r",
- self._activity_id, mesh_instance)
- self.shared_activity = mesh_instance
- self.shared_activity.connect('notify::private',
- self.__privacy_changed_cb)
- self._join_id = self.shared_activity.connect("joined",
- self.__joined_cb)
- if not self.shared_activity.props.joined:
- self.shared_activity.join()
- else:
- self.__joined_cb(self.shared_activity, True, None)
- elif share_scope != SCOPE_PRIVATE:
- logging.debug("*** Act %s no existing mesh instance, but used to " \
- "be shared, will share" % self._activity_id)
- # no existing mesh instance, but activity used to be shared, so
- # restart the share
- if share_scope == SCOPE_INVITE_ONLY:
- self.share(private=True)
- elif share_scope == SCOPE_NEIGHBORHOOD:
- self.share(private=False)
- else:
- logging.debug("Unknown share scope %r" % share_scope)
-
- if handle.object_id is None and create_jobject:
- logging.debug('Creating a jobject.')
- self._jobject = datastore.create()
- title = _('%s Activity') % get_bundle_name()
- self._jobject.metadata['title'] = title
- self.set_title(self._jobject.metadata['title'])
- self._jobject.metadata['title_set_by_user'] = '0'
- self._jobject.metadata['activity'] = self.get_bundle_id()
- self._jobject.metadata['activity_id'] = self.get_id()
- self._jobject.metadata['keep'] = '0'
- self._jobject.metadata['preview'] = ''
- self._jobject.metadata['share-scope'] = SCOPE_PRIVATE
- if self.shared_activity is not None:
- icon_color = self.shared_activity.props.color
- else:
- client = gconf.client_get_default()
- icon_color = client.get_string('/desktop/sugar/user/color')
- self._jobject.metadata['icon-color'] = icon_color
-
- self._jobject.file_path = ''
- # Cannot call datastore.write async for creates:
- # https://dev.laptop.org/ticket/3071
- datastore.write(self._jobject)
-
- def get_active(self):
- return self._active
-
- def set_active(self, active):
- if self._active != active:
- self._active = active
- if not self._active and self._jobject:
- self.save()
-
- active = gobject.property(
- type=bool, default=False, getter=get_active, setter=set_active)
-
- def get_max_participants(self):
- return self._max_participants
-
- def set_max_participants(self, participants):
- self._max_participants = participants
-
- max_participants = gobject.property(
- type=int, default=0, getter=get_max_participants,
- setter=set_max_participants)
-
- def get_id(self):
- """Returns the activity id of the current instance of your activity.
-
- The activity id is sort-of-like the unix process id (PID). However,
- unlike PIDs it is only different for each new instance (with
- create_jobject = True set) and stays the same everytime a user
- resumes an activity. This is also the identity of your Activity to other
- XOs for use when sharing.
- """
- return self._activity_id
-
- def get_bundle_id(self):
- """Returns the bundle_id from the activity.info file"""
- return os.environ['SUGAR_BUNDLE_ID']
-
- def set_canvas(self, canvas):
- """Sets the 'work area' of your activity with the canvas of your choice.
-
- One commonly used canvas is gtk.ScrolledWindow
- """
- Window.set_canvas(self, canvas)
- canvas.connect('map', self.__canvas_map_cb)
-
- def __session_quit_requested_cb(self, session):
- self._quit_requested = True
-
- if not self._prepare_close():
- session.will_quit(self, False)
- elif not self._updating_jobject:
- session.will_quit(self, True)
-
- def __session_quit_cb(self, client):
- self._complete_close()
-
- def __canvas_map_cb(self, canvas):
- if self._jobject and self._jobject.file_path:
- self.read_file(self._jobject.file_path)
-
- def __jobject_create_cb(self):
- pass
-
- def __jobject_error_cb(self, err):
- logging.debug("Error creating activity datastore object: %s" % err)
-
- def get_activity_root(self):
- """ FIXME: Deprecated. This part of the API has been moved
- out of this class to the module itself
-
- Returns a path for saving Activity specific preferences, etc.
-
- Returns a path to the location in the filesystem where the activity can
- store activity related data that doesn't pertain to the current
- execution of the activity and thus cannot go into the DataStore.
-
- Currently, this will return something like
- ~/.sugar/default/MyActivityName/
-
- Activities should ONLY save settings, user preferences and other data
- which isn't specific to a journal item here. If (meta-)data is in anyway
- specific to a journal entry, it MUST be stored in the DataStore.
- """
- if os.environ.has_key('SUGAR_ACTIVITY_ROOT') and \
- os.environ['SUGAR_ACTIVITY_ROOT']:
- return os.environ['SUGAR_ACTIVITY_ROOT']
- else:
- return '/'
-
- def read_file(self, file_path):
- """
- Subclasses implement this method if they support resuming objects from
- the journal. 'file_path' is the file to read from.
-
- You should immediately open the file from the file_path, because the
- file_name will be deleted immediately after returning from read_file().
- Once the file has been opened, you do not have to read it immediately:
- After you have opened it, the file will only be really gone when you
- close it.
-
- Although not required, this is also a good time to read all meta-data:
- the file itself cannot be changed externally, but the title, description
- and other metadata['tags'] may change. So if it is important for you to
- notice changes, this is the time to record the originals.
- """
- raise NotImplementedError
-
- def write_file(self, file_path):
- """
- Subclasses implement this method if they support saving data to objects
- in the journal. 'file_path' is the file to write to.
-
- If the user did make changes, you should create the file_path and save
- all document data to it.
-
- Additionally, you should also write any metadata needed to resume your
- activity. For example, the Read activity saves the current page and zoom
- level, so it can display the page.
-
- Note: Currently, the file_path *WILL* be different from the one you
- received in file_read(). Even if you kept the file_path from file_read()
- open until now, you must still write the entire file to this file_path.
- """
- raise NotImplementedError
-
- def __save_cb(self):
- logging.debug('Activity.__save_cb')
- self._updating_jobject = False
- if self._quit_requested:
- self._session.will_quit(self, True)
- elif self._closing:
- self._complete_close()
-
- def __save_error_cb(self, err):
- logging.debug('Activity.__save_error_cb')
- self._updating_jobject = False
- if self._quit_requested:
- self._session.will_quit(self, False)
- if self._closing:
- self._show_keep_failed_dialog()
- self._closing = False
- logging.debug("Error saving activity object to datastore: %s" % err)
-
- def _cleanup_jobject(self):
- if self._jobject:
- if self._owns_file and os.path.isfile(self._jobject.file_path):
- logging.debug('_cleanup_jobject: removing %r' %
- self._jobject.file_path)
- os.remove(self._jobject.file_path)
- self._owns_file = False
- self._jobject.destroy()
- self._jobject = None
-
- def _get_preview(self):
-
- if self.canvas is None or not hasattr(self.canvas, 'get_snapshot'):
- return None
- pixmap = self.canvas.get_snapshot((-1, -1, 0, 0))
-
- width, height = pixmap.get_size()
- pixbuf = gtk.gdk.Pixbuf(gtk.gdk.COLORSPACE_RGB, 0, 8, width, height)
- pixbuf = pixbuf.get_from_drawable(pixmap, pixmap.get_colormap(),
- 0, 0, 0, 0, width, height)
- pixbuf = pixbuf.scale_simple(style.zoom(300), style.zoom(225),
- gtk.gdk.INTERP_BILINEAR)
-
- preview_data = []
- def save_func(buf, data):
- data.append(buf)
-
- pixbuf.save_to_callback(save_func, 'png', user_data=preview_data)
- preview_data = ''.join(preview_data)
-
- return preview_data
-
- def _get_buddies(self):
- if self.shared_activity is not None:
- buddies = {}
- for buddy in self.shared_activity.get_joined_buddies():
- if not buddy.props.owner:
- buddy_id = sha1(buddy.props.key).hexdigest()
- buddies[buddy_id] = [buddy.props.nick, buddy.props.color]
- return buddies
- else:
- return {}
-
- def save(self):
- """Request that the activity is saved to the Journal.
-
- This method is called by the close() method below. In general,
- activities should not override this method. This method is part of the
- public API of an Acivity, and should behave in standard ways. Use your
- own implementation of write_file() to save your Activity specific data.
- """
-
- if self._jobject is None:
- logging.debug('Cannot save, no journal object.')
- return
-
- logging.debug('Activity.save: %r' % self._jobject.object_id)
-
- if self._updating_jobject:
- logging.info('Activity.save: still processing a previous request.')
- return
-
- buddies_dict = self._get_buddies()
- if buddies_dict:
- self.metadata['buddies_id'] = cjson.encode(buddies_dict.keys())
- self.metadata['buddies'] = cjson.encode(self._get_buddies())
-
- preview = self._get_preview()
- if preview is not None:
- self.metadata['preview'] = dbus.ByteArray(preview)
-
- try:
- file_path = os.path.join(self.get_activity_root(), 'instance',
- '%i' % time.time())
- self.write_file(file_path)
- self._owns_file = True
- self._jobject.file_path = file_path
- except NotImplementedError:
- logging.debug('Activity.write_file is not implemented.')
-
- # Cannot call datastore.write async for creates:
- # https://dev.laptop.org/ticket/3071
- if self._jobject.object_id is None:
- datastore.write(self._jobject, transfer_ownership=True)
- else:
- self._updating_jobject = True
- datastore.write(self._jobject,
- transfer_ownership=True,
- reply_handler=self.__save_cb,
- error_handler=self.__save_error_cb)
-
- def copy(self):
- """Request that the activity 'Keep in Journal' the current state
- of the activity.
-
- Activities should not override this method. Instead, like save() do any
- copy work that needs to be done in write_file()
- """
- logging.debug('Activity.copy: %r' % self._jobject.object_id)
- self.save()
- self._jobject.object_id = None
-
- def __privacy_changed_cb(self, shared_activity, param_spec):
- if shared_activity.props.private:
- self._jobject.metadata['share-scope'] = SCOPE_INVITE_ONLY
- else:
- self._jobject.metadata['share-scope'] = SCOPE_NEIGHBORHOOD
-
- def __joined_cb(self, activity, success, err):
- """Callback when join has finished"""
- self.shared_activity.disconnect(self._join_id)
- self._join_id = None
- if not success:
- logging.debug("Failed to join activity: %s" % err)
- return
-
- self.present()
- self.emit('joined')
- self.__privacy_changed_cb(self.shared_activity, None)
-
- def get_shared_activity(self):
- """Returns an instance of the shared Activity or None
-
- The shared activity is of type sugar.presence.activity.Activity
- """
- return self._shared_activity
-
- def get_shared(self):
- """Returns TRUE if the activity is shared on the mesh."""
- if not self.shared_activity:
- return False
- return self.shared_activity.props.joined
-
- def __share_cb(self, ps, success, activity, err):
- self._pservice.disconnect(self._share_id)
- self._share_id = None
- if not success:
- logging.debug('Share of activity %s failed: %s.' %
- (self._activity_id, err))
- return
-
- logging.debug('Share of activity %s successful, PS activity is %r.',
- self._activity_id, activity)
-
- activity.props.name = self._jobject.metadata['title']
-
- self.shared_activity = activity
- self.shared_activity.connect('notify::private',
- self.__privacy_changed_cb)
- self.emit('shared')
- self.__privacy_changed_cb(self.shared_activity, None)
-
- self._send_invites()
-
- def _invite_response_cb(self, error):
- if error:
- logging.error('Invite failed: %s' % error)
-
- def _send_invites(self):
- while self._invites_queue:
- buddy_key = self._invites_queue.pop()
- buddy = self._pservice.get_buddy(buddy_key)
- if buddy:
- self.shared_activity.invite(
- buddy, '', self._invite_response_cb)
- else:
- logging.error('Cannot invite %s, no such buddy.' % buddy_key)
-
- def invite(self, buddy_key):
- """Invite a buddy to join this Activity.
-
- Side Effects:
- Calls self.share(True) to privately share the activity if it wasn't
- shared before.
- """
- self._invites_queue.append(buddy_key)
-
- if (self.shared_activity is None
- or not self.shared_activity.props.joined):
- self.share(True)
- else:
- self._send_invites()
-
- def share(self, private=False):
- """Request that the activity be shared on the network.
-
- private -- bool: True to share by invitation only,
- False to advertise as shared to everyone.
-
- Once the activity is shared, its privacy can be changed by setting
- its 'private' property.
- """
- if self.shared_activity and self.shared_activity.props.joined:
- raise RuntimeError("Activity %s already shared." %
- self._activity_id)
- verb = private and 'private' or 'public'
- logging.debug('Requesting %s share of activity %s.' %
- (verb, self._activity_id))
- self._share_id = self._pservice.connect("activity-shared",
- self.__share_cb)
- self._pservice.share_activity(self, private=private)
-
- def _show_keep_failed_dialog(self):
- alert = Alert()
- alert.props.title = _('Keep error')
- alert.props.msg = _('Keep error: all changes will be lost')
-
- cancel_icon = Icon(icon_name='dialog-cancel')
- alert.add_button(gtk.RESPONSE_CANCEL, _('Don\'t stop'), cancel_icon)
-
- stop_icon = Icon(icon_name='dialog-ok')
- alert.add_button(gtk.RESPONSE_OK, _('Stop anyway'), stop_icon)
-
- self.add_alert(alert)
- alert.connect('response', self._keep_failed_dialog_response_cb)
-
- self.present()
-
- def _keep_failed_dialog_response_cb(self, alert, response_id):
- self.remove_alert(alert)
- if response_id == gtk.RESPONSE_OK:
- self.close(skip_save=True)
-
- def can_close(self):
- """Activities should override this function if they want to perform
- extra checks before actually closing."""
-
- return True
-
- def _prepare_close(self, skip_save=False):
- if not skip_save:
- try:
- self.save()
- except Exception:
- logging.info(traceback.format_exc())
- self._show_keep_failed_dialog()
- return False
-
- if self.shared_activity:
- self.shared_activity.leave()
-
- self._closing = True
-
- return True
-
- def _complete_close(self):
- self._cleanup_jobject()
- self.destroy()
-
- # Make the exported object inaccessible
- dbus.service.Object.remove_from_connection(self._bus)
-
- self._session.unregister(self)
-
- def close(self, skip_save=False):
- """Request that the activity be stopped and saved to the Journal
-
- Activities should not override this method, but should implement
- write_file() to do any state saving instead. If the application wants
- to control wether it can close, it should override can_close().
- """
- if not self.can_close():
- return
-
- if skip_save or self.metadata.get('title_set_by_user', '0') == '1':
- if not self._closing:
- if not self._prepare_close(skip_save):
- return
-
- if not self._updating_jobject:
- self._complete_close()
- else:
- title_alert = NamingAlert(self, get_bundle_path())
- title_alert.set_transient_for(self.get_toplevel())
- title_alert.show()
-
- def __realize_cb(self, window):
- wm.set_bundle_id(window.window, self.get_bundle_id())
- wm.set_activity_id(window.window, str(self._activity_id))
-
- def __delete_event_cb(self, widget, event):
- self.close()
- return True
-
- def get_metadata(self):
- """Returns the jobject metadata or None if there is no jobject.
-
- Activities can set metadata in write_file() using:
- self.metadata['MyKey'] = "Something"
-
- and retrieve metadata in read_file() using:
- self.metadata.get('MyKey', 'aDefaultValue')
-
- Note: Make sure your activity works properly if one or more of the
- metadata items is missing. Never assume they will all be present.
- """
- if self._jobject:
- return self._jobject.metadata
- else:
- return None
-
- metadata = property(get_metadata, None)
-
- def handle_view_source(self):
- raise NotImplementedError
-
- def get_document_path(self, async_cb, async_err_cb):
- async_err_cb(NotImplementedError())
-
- def get_tutorials(self):
- return {}
-
- # DEPRECATED
- _shared_activity = property(lambda self: self.shared_activity, None)
-
-_session = None
-
-def _get_session():
- global _session
-
- if _session is None:
- _session = _ActivitySession()
-
- return _session
-
-def get_bundle_name():
- """Return the bundle name for the current process' bundle"""
- return os.environ['SUGAR_BUNDLE_NAME']
-
-def get_bundle_path():
- """Return the bundle path for the current process' bundle"""
- return os.environ['SUGAR_BUNDLE_PATH']
-
-def get_activity_root():
- """Returns a path for saving Activity specific preferences, etc."""
- if os.environ.has_key('SUGAR_ACTIVITY_ROOT') and \
- os.environ['SUGAR_ACTIVITY_ROOT']:
- return os.environ['SUGAR_ACTIVITY_ROOT']
- else:
- raise RuntimeError("No SUGAR_ACTIVITY_ROOT set.")
-
-def show_object_in_journal(object_id):
- bus = dbus.SessionBus()
- obj = bus.get_object(J_DBUS_SERVICE, J_DBUS_PATH)
- journal = dbus.Interface(obj, J_DBUS_INTERFACE)
- journal.ShowObject(object_id)
diff --git a/sugar-toolkit/src/sugar/activity/activityfactory.py b/sugar-toolkit/src/sugar/activity/activityfactory.py
deleted file mode 100644
index e92314d..0000000
--- a/sugar-toolkit/src/sugar/activity/activityfactory.py
+++ /dev/null
@@ -1,343 +0,0 @@
-# Copyright (C) 2006-2007 Red Hat, Inc.
-#
-# This library is free software; you can redistribute it and/or
-# modify it under the terms of the GNU Lesser General Public
-# License as published by the Free Software Foundation; either
-# version 2 of the License, or (at your option) any later version.
-#
-# This library is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-# Lesser General Public License for more details.
-#
-# You should have received a copy of the GNU Lesser General Public
-# License along with this library; if not, write to the
-# Free Software Foundation, Inc., 59 Temple Place - Suite 330,
-# Boston, MA 02111-1307, USA.
-
-"""Shell side object which manages request to start activity
-
-UNSTABLE. Activities are currently not allowed to run other activities so at
-the moment there is no reason to stabilize this API.
-"""
-
-import logging
-
-import dbus
-import gobject
-
-from sugar.presence import presenceservice
-from sugar.activity.activityhandle import ActivityHandle
-from sugar import util
-from sugar import env
-
-from errno import EEXIST, ENOSPC
-
-import os
-
-_SHELL_SERVICE = "org.laptop.Shell"
-_SHELL_PATH = "/org/laptop/Shell"
-_SHELL_IFACE = "org.laptop.Shell"
-
-_DS_SERVICE = "org.laptop.sugar.DataStore"
-_DS_INTERFACE = "org.laptop.sugar.DataStore"
-_DS_PATH = "/org/laptop/sugar/DataStore"
-
-_ACTIVITY_FACTORY_INTERFACE = "org.laptop.ActivityFactory"
-
-_RAINBOW_SERVICE_NAME = "org.laptop.security.Rainbow"
-_RAINBOW_ACTIVITY_FACTORY_PATH = "/"
-_RAINBOW_ACTIVITY_FACTORY_INTERFACE = "org.laptop.security.Rainbow"
-
-# helper method to close all filedescriptors
-# borrowed from subprocess.py
-try:
- MAXFD = os.sysconf("SC_OPEN_MAX")
-except ValueError:
- MAXFD = 256
-def _close_fds():
- for i in xrange(3, MAXFD):
- try:
- os.close(i)
- # pylint: disable-msg=W0704
- except Exception:
- pass
-
-def create_activity_id():
- """Generate a new, unique ID for this activity"""
- pservice = presenceservice.get_instance()
-
- # create a new unique activity ID
- i = 0
- act_id = None
- while i < 10:
- act_id = util.unique_id()
- i += 1
-
- # check through network activities
- found = False
- activities = pservice.get_activities()
- for act in activities:
- if act_id == act.props.id:
- found = True
- break
- if not found:
- return act_id
- raise RuntimeError("Cannot generate unique activity id.")
-
-def get_environment(activity):
- environ = os.environ.copy()
-
- bin_path = os.path.join(activity.get_path(), 'bin')
-
- activity_root = env.get_profile_path(activity.get_bundle_id())
- if not os.path.exists(activity_root):
- os.mkdir(activity_root)
-
- data_dir = os.path.join(activity_root, 'instance')
- if not os.path.exists(data_dir):
- os.mkdir(data_dir)
-
- data_dir = os.path.join(activity_root, 'data')
- if not os.path.exists(data_dir):
- os.mkdir(data_dir)
-
- tmp_dir = os.path.join(activity_root, 'tmp')
- if not os.path.exists(tmp_dir):
- os.mkdir(tmp_dir)
-
- environ['SUGAR_BUNDLE_PATH'] = activity.get_path()
- environ['SUGAR_BUNDLE_ID'] = activity.get_bundle_id()
- environ['SUGAR_ACTIVITY_ROOT'] = activity_root
- environ['PATH'] = bin_path + ':' + environ['PATH']
- #environ['RAINBOW_STRACE_LOG'] = '1'
-
- if activity.get_path().startswith(env.get_user_activities_path()):
- environ['SUGAR_LOCALEDIR'] = os.path.join(activity.get_path(), 'locale')
-
- if activity.get_bundle_id() in [ 'org.laptop.WebActivity',
- 'org.laptop.GmailActivity',
- 'org.laptop.WikiBrowseActivity'
- ]:
- environ['RAINBOW_CONSTANT_UID'] = 'yes'
-
- return environ
-
-def get_command(activity, activity_id=None, object_id=None, uri=None):
- if not activity_id:
- activity_id = create_activity_id()
-
- command = activity.get_command().split(' ')
- command.extend(['-b', activity.get_bundle_id()])
- command.extend(['-a', activity_id])
-
- if object_id is not None:
- command.extend(['-o', object_id])
- if uri is not None:
- command.extend(['-u', uri])
-
- # if the command is in $BUNDLE_ROOT/bin, execute the absolute path so there
- # is no need to mangle with the shell's PATH
- if '/' not in command[0]:
- bin_path = os.path.join(activity.get_path(), 'bin')
- absolute_path = os.path.join(bin_path, command[0])
- if os.path.exists(absolute_path):
- command[0] = absolute_path
-
- logging.debug('launching: %r' % command)
-
- return command
-
-def open_log_file(activity):
- i = 1
- while True:
- path = env.get_logs_path('%s-%s.log' % (activity.get_bundle_id(), i))
- try:
- fd = os.open(path, os.O_EXCL | os.O_CREAT \
- | os.O_SYNC | os.O_WRONLY, 0644)
- f = os.fdopen(fd, 'w', 0)
- return (path, f)
- except OSError, e:
- if e.errno == EEXIST:
- i += 1
- elif e.errno == ENOSPC:
- # not the end of the world; let's try to keep going.
- return ('/dev/null', open('/dev/null','w'))
- else:
- raise e
-
-class ActivityCreationHandler(gobject.GObject):
- """Sugar-side activity creation interface
-
- This object uses a dbus method on the ActivityFactory
- service to create the new activity. It generates
- GObject events in response to the success/failure of
- activity startup using callbacks to the service's
- create call.
- """
-
- def __init__(self, bundle, handle):
- """Initialise the handler
-
- bundle -- the ActivityBundle to launch
- activity_handle -- stores the values which are to
- be passed to the service to uniquely identify
- the activity to be created and the sharing
- service that may or may not be connected with it
-
- sugar.activity.activityhandle.ActivityHandle instance
-
- calls the "create" method on the service for this
- particular activity type and registers the
- _reply_handler and _error_handler methods on that
- call's results.
-
- The specific service which creates new instances of this
- particular type of activity is created during the activity
- registration process in shell bundle registry which creates
- service definition files for each registered bundle type.
-
- If the file '/etc/olpc-security' exists, then activity launching
- will be delegated to the prototype 'Rainbow' security service.
- """
- gobject.GObject.__init__(self)
-
- self._bundle = bundle
- self._service_name = bundle.get_bundle_id()
- self._handle = handle
-
- self._use_rainbow = os.path.exists('/etc/olpc-security')
- if self._service_name in [ 'org.laptop.JournalActivity',
- 'org.laptop.Terminal',
- 'org.laptop.Log',
- 'org.laptop.Analyze'
- ]:
- self._use_rainbow = False
-
- bus = dbus.SessionBus()
-
- bus_object = bus.get_object(_SHELL_SERVICE, _SHELL_PATH)
- self._shell = dbus.Interface(bus_object, _SHELL_IFACE)
-
- if handle.activity_id is not None and \
- handle.object_id is None:
- datastore = dbus.Interface(
- bus.get_object(_DS_SERVICE, _DS_PATH), _DS_INTERFACE)
- datastore.find({ 'activity_id': self._handle.activity_id }, [],
- reply_handler=self._find_object_reply_handler,
- error_handler=self._find_object_error_handler,
- byte_arrays=True)
- else:
- self._launch_activity()
-
- def _launch_activity(self):
- if self._handle.activity_id != None:
- self._shell.ActivateActivity(self._handle.activity_id,
- reply_handler=self._activate_reply_handler,
- error_handler=self._activate_error_handler)
- else:
- self._create_activity()
-
- def _create_activity(self):
- if self._handle.activity_id is None:
- self._handle.activity_id = create_activity_id()
-
- self._shell.NotifyLaunch(
- self._service_name, self._handle.activity_id,
- reply_handler=self._no_reply_handler,
- error_handler=self._notify_launch_error_handler)
-
- environ = get_environment(self._bundle)
- (log_path, log_file) = open_log_file(self._bundle)
- command = get_command(self._bundle, self._handle.activity_id,
- self._handle.object_id,
- self._handle.uri)
-
- if not self._use_rainbow:
- # use gobject spawn functionality, so that zombies are
- # automatically reaped by the gobject event loop.
- def child_setup():
- # clone logfile.fileno() onto stdout/stderr
- os.dup2(log_file.fileno(), 1)
- os.dup2(log_file.fileno(), 2)
- # close all other fds
- _close_fds()
- # we need to sanitize and str-ize the various bits which
- # dbus gives us.
- gobject.spawn_async([str(s) for s in command],
- envp=['%s=%s' % (k, str(v))
- for k, v in environ.items()],
- working_directory=str(self._bundle.get_path()),
- child_setup=child_setup,
- flags=(gobject.SPAWN_SEARCH_PATH |
- gobject.SPAWN_LEAVE_DESCRIPTORS_OPEN))
- log_file.close()
- else:
- log_file.close()
- system_bus = dbus.SystemBus()
- factory = system_bus.get_object(_RAINBOW_SERVICE_NAME,
- _RAINBOW_ACTIVITY_FACTORY_PATH)
- factory.CreateActivity(
- log_path,
- environ,
- command,
- environ['SUGAR_BUNDLE_PATH'],
- environ['SUGAR_BUNDLE_ID'],
- timeout=30,
- reply_handler=self._create_reply_handler,
- error_handler=self._create_error_handler,
- dbus_interface=_RAINBOW_ACTIVITY_FACTORY_INTERFACE)
-
- def _no_reply_handler(self, *args):
- pass
-
- def _notify_launch_failure_error_handler(self, err):
- logging.error('Notify launch failure failed %s' % err)
-
- def _notify_launch_error_handler(self, err):
- logging.debug('Notify launch failed %s' % err)
-
- def _activate_reply_handler(self, activated):
- if not activated:
- self._create_activity()
-
- def _activate_error_handler(self, err):
- logging.error("Activity activation request failed %s" % err)
-
- def _create_reply_handler(self):
- logging.debug("Activity created %s (%s)." %
- (self._handle.activity_id, self._service_name))
-
- def _create_error_handler(self, err):
- logging.error("Couldn't create activity %s (%s): %s" %
- (self._handle.activity_id, self._service_name, err))
- self._shell.NotifyLaunchFailure(
- self._handle.activity_id, reply_handler=self._no_reply_handler,
- error_handler=self._notify_launch_failure_error_handler)
-
- def _find_object_reply_handler(self, jobjects, count):
- if count > 0:
- if count > 1:
- logging.debug("Multiple objects has the same activity_id.")
- self._handle.object_id = jobjects[0]['uid']
- self._create_activity()
-
- def _find_object_error_handler(self, err):
- logging.error("Datastore find failed %s" % err)
- self._create_activity()
-
-def create(bundle, activity_handle=None):
- """Create a new activity from its name."""
- if not activity_handle:
- activity_handle = ActivityHandle()
- return ActivityCreationHandler(bundle, activity_handle)
-
-def create_with_uri(bundle, uri):
- """Create a new activity and pass the uri as handle."""
- activity_handle = ActivityHandle(uri=uri)
- return ActivityCreationHandler(bundle, activity_handle)
-
-def create_with_object_id(bundle, object_id):
- """Create a new activity and pass the object id as handle."""
- activity_handle = ActivityHandle(object_id=object_id)
- return ActivityCreationHandler(bundle, activity_handle)
diff --git a/sugar-toolkit/src/sugar/activity/activityhandle.py b/sugar-toolkit/src/sugar/activity/activityhandle.py
deleted file mode 100644
index f255fd5..0000000
--- a/sugar-toolkit/src/sugar/activity/activityhandle.py
+++ /dev/null
@@ -1,70 +0,0 @@
-# Copyright (C) 2006-2007 Red Hat, Inc.
-#
-# This library is free software; you can redistribute it and/or
-# modify it under the terms of the GNU Lesser General Public
-# License as published by the Free Software Foundation; either
-# version 2 of the License, or (at your option) any later version.
-#
-# This library is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-# Lesser General Public License for more details.
-#
-# You should have received a copy of the GNU Lesser General Public
-# License along with this library; if not, write to the
-# Free Software Foundation, Inc., 59 Temple Place - Suite 330,
-# Boston, MA 02111-1307, USA.
-
-"""
-STABLE.
-"""
-
-class ActivityHandle(object):
- """Data structure storing simple activity metadata"""
- def __init__(
- self, activity_id=None, object_id=None, uri=None
- ):
- """Initialise the handle from activity_id
-
- activity_id -- unique id for the activity to be
- created
- object_id -- identity of the journal object
- associated with the activity. It was used by
- the journal prototype implementation, might
- change when we do the real one.
-
- When you resume an activity from the journal
- the object_id will be passed in. It's optional
- since new activities does not have an
- associated object (yet).
-
- XXX Not clear how this relates to the activity
- id yet, i.e. not sure we really need both. TBF
- uri -- URI associated with the activity. Used when
- opening an external file or resource in the
- activity, rather than a journal object
- (downloads stored on the file system for
- example or web pages)
- """
- self.activity_id = activity_id
- self.object_id = object_id
- self.uri = uri
-
- def get_dict(self):
- """Retrieve our settings as a dictionary"""
- result = { 'activity_id' : self.activity_id }
- if self.object_id:
- result['object_id'] = self.object_id
- if self.uri:
- result['uri'] = self.uri
-
- return result
-
-def create_from_dict(handle_dict):
- """Create a handle from a dictionary of parameters"""
- result = ActivityHandle(
- handle_dict['activity_id'],
- object_id = handle_dict.get('object_id'),
- uri = handle_dict.get('uri'),
- )
- return result
diff --git a/sugar-toolkit/src/sugar/activity/activityservice.py b/sugar-toolkit/src/sugar/activity/activityservice.py
deleted file mode 100644
index ff806f3..0000000
--- a/sugar-toolkit/src/sugar/activity/activityservice.py
+++ /dev/null
@@ -1,82 +0,0 @@
-# Copyright (C) 2006-2007 Red Hat, Inc.
-#
-# This library is free software; you can redistribute it and/or
-# modify it under the terms of the GNU Lesser General Public
-# License as published by the Free Software Foundation; either
-# version 2 of the License, or (at your option) any later version.
-#
-# This library is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-# Lesser General Public License for more details.
-#
-# You should have received a copy of the GNU Lesser General Public
-# License along with this library; if not, write to the
-# Free Software Foundation, Inc., 59 Temple Place - Suite 330,
-# Boston, MA 02111-1307, USA.
-
-"""
-UNSTABLE. It should really be internal to the Activity class.
-"""
-
-import logging
-
-import dbus
-import dbus.service
-
-_ACTIVITY_SERVICE_NAME = "org.laptop.Activity"
-_ACTIVITY_SERVICE_PATH = "/org/laptop/Activity"
-_ACTIVITY_INTERFACE = "org.laptop.Activity"
-
-class ActivityService(dbus.service.Object):
- """Base dbus service object that each Activity uses to export dbus methods.
-
- The dbus service is separate from the actual Activity object so that we can
- tightly control what stuff passes through the dbus python bindings."""
-
- def __init__(self, activity):
- """Initialise the service for the given activity
-
- activity -- sugar.activity.activity.Activity instance
-
- Creates dbus services that use the instance's activity_id
- as discriminants among all active services
- of this type. That is, the services are all available
- as names/paths derived from the instance's activity_id.
-
- The various methods exposed on dbus are just forwarded
- to the client Activity object's equally-named methods.
- """
- activity.realize()
-
- activity_id = activity.get_id()
- service_name = _ACTIVITY_SERVICE_NAME + activity_id
- object_path = _ACTIVITY_SERVICE_PATH + "/" + activity_id
-
- bus = dbus.SessionBus()
- bus_name = dbus.service.BusName(service_name, bus=bus)
- dbus.service.Object.__init__(self, bus_name, object_path)
-
- self._activity = activity
-
- @dbus.service.method(_ACTIVITY_INTERFACE)
- def SetActive(self, active):
- logging.debug('ActivityService.set_active: %s.' % active)
- self._activity.props.active = active
-
- @dbus.service.method(_ACTIVITY_INTERFACE)
- def Invite(self, buddy_key):
- self._activity.invite(buddy_key)
-
- @dbus.service.method(_ACTIVITY_INTERFACE)
- def HandleViewSource(self):
- self._activity.handle_view_source()
-
- @dbus.service.method(_ACTIVITY_INTERFACE,
- async_callbacks=('async_cb', 'async_err_cb'))
- def GetDocumentPath(self, async_cb, async_err_cb):
- try:
- self._activity.get_document_path(async_cb, async_err_cb)
- except Exception, e:
- async_err_cb(e)
-
diff --git a/sugar-toolkit/src/sugar/activity/bundlebuilder.py b/sugar-toolkit/src/sugar/activity/bundlebuilder.py
deleted file mode 100644
index ab3679b..0000000
--- a/sugar-toolkit/src/sugar/activity/bundlebuilder.py
+++ /dev/null
@@ -1,398 +0,0 @@
-# Copyright (C) 2008 Red Hat, Inc.
-#
-# This library is free software; you can redistribute it and/or
-# modify it under the terms of the GNU Lesser General Public
-# License as published by the Free Software Foundation; either
-# version 2 of the License, or (at your option) any later version.
-#
-# This library is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-# Lesser General Public License for more details.
-#
-# You should have received a copy of the GNU Lesser General Public
-# License along with this library; if not, write to the
-# Free Software Foundation, Inc., 59 Temple Place - Suite 330,
-# Boston, MA 02111-1307, USA.
-
-"""
-STABLE.
-"""
-
-import os
-import sys
-import zipfile
-import tarfile
-import shutil
-import subprocess
-import re
-import gettext
-from optparse import OptionParser
-import logging
-from fnmatch import fnmatch
-
-from sugar import env
-from sugar.bundle.activitybundle import ActivityBundle
-
-IGNORE_DIRS = ['dist', '.git']
-IGNORE_FILES = ['.gitignore', 'MANIFEST', '*.pyc', '*~', '*.bak', 'pseudo.po']
-
-def list_files(base_dir, ignore_dirs=None, ignore_files=None):
- result = []
-
- for root, dirs, files in os.walk(base_dir):
- if ignore_files:
- for pattern in ignore_files:
- files = [f for f in files if not fnmatch(f, pattern)]
-
- rel_path = root[len(base_dir) + 1:]
- for f in files:
- result.append(os.path.join(rel_path, f))
-
- if ignore_dirs and root == base_dir:
- for ignore in ignore_dirs:
- if ignore in dirs:
- dirs.remove(ignore)
-
- return result
-
-class Config(object):
- def __init__(self, source_dir=None, dist_dir = None, dist_name = None):
- self.source_dir = source_dir or os.getcwd()
- self.dist_dir = dist_dir or os.path.join(self.source_dir, 'dist')
- self.dist_name = dist_name
- self.bundle = None
- self.version = None
- self.activity_name = None
- self.bundle_id = None
- self.bundle_name = None
- self.bundle_root_dir = None
- self.tar_root_dir = None
- self.xo_name = None
- self.tar_name = None
-
- self.update()
-
- def update(self):
- self.bundle = bundle = ActivityBundle(self.source_dir)
- self.version = bundle.get_activity_version()
- self.activity_name = bundle.get_name()
- self.bundle_id = bundle.get_bundle_id()
- self.bundle_name = reduce(lambda x, y:x+y, self.activity_name.split())
- self.bundle_root_dir = self.bundle_name + '.activity'
- self.tar_root_dir = '%s-%d' % (self.bundle_name, self.version)
-
- if self.dist_name:
- self.xo_name = self.tar_name = self.dist_name
- else:
- self.xo_name = '%s-%d.xo' % (self.bundle_name, self.version)
- self.tar_name = '%s-%d.tar.bz2' % (self.bundle_name, self.version)
-
-class Builder(object):
- def __init__(self, config):
- self.config = config
-
- def build(self):
- self.build_locale()
-
- def build_locale(self):
- po_dir = os.path.join(self.config.source_dir, 'po')
-
- if not self.config.bundle.is_dir(po_dir):
- logging.warn("Missing po/ dir, cannot build_locale")
- return
-
- locale_dir = os.path.join(self.config.source_dir, 'locale')
-
- if os.path.exists(locale_dir):
- shutil.rmtree(locale_dir)
-
- for f in os.listdir(po_dir):
- if not f.endswith('.po') or f == 'pseudo.po':
- continue
-
- file_name = os.path.join(po_dir, f)
- lang = f[:-3]
-
- localedir = os.path.join(self.config.source_dir, 'locale', lang)
- mo_path = os.path.join(localedir, 'LC_MESSAGES')
- if not os.path.isdir(mo_path):
- os.makedirs(mo_path)
-
- mo_file = os.path.join(mo_path, "%s.mo" % self.config.bundle_id)
- args = ["msgfmt", "--output-file=%s" % mo_file, file_name]
- retcode = subprocess.call(args)
- if retcode:
- print 'ERROR - msgfmt failed with return code %i.' % retcode
-
- cat = gettext.GNUTranslations(open(mo_file, 'r'))
- translated_name = cat.gettext(self.config.activity_name)
- linfo_file = os.path.join(localedir, 'activity.linfo')
- f = open(linfo_file, 'w')
- f.write('[Activity]\nname = %s\n' % translated_name)
- f.close()
-
- def get_files(self):
- files = self.config.bundle.get_files()
-
- if not files:
- logging.error('No files found, fixing the MANIFEST.')
- self.fix_manifest()
- files = self.config.bundle.get_files()
-
- return files
-
- def check_manifest(self):
- missing_files = []
-
- allfiles = list_files(self.config.source_dir,
- IGNORE_DIRS, IGNORE_FILES)
- for path in allfiles:
- if path not in self.config.bundle.manifest:
- missing_files.append(path)
-
- return missing_files
-
- def fix_manifest(self):
- self.build()
-
- manifest = self.config.bundle.manifest
-
- for path in self.check_manifest():
- manifest.append(path)
-
- f = open(os.path.join(self.config.source_dir, "MANIFEST"), "wb")
- for line in manifest:
- f.write(line + "\n")
-
-class Packager(object):
- def __init__(self, config):
- self.config = config
- self.package_path = None
-
- if not os.path.exists(self.config.dist_dir):
- os.mkdir(self.config.dist_dir)
-
-class XOPackager(Packager):
- def __init__(self, builder):
- Packager.__init__(self, builder.config)
-
- self.builder = builder
- self.package_path = os.path.join(self.config.dist_dir,
- self.config.xo_name)
-
- def package(self):
- bundle_zip = zipfile.ZipFile(self.package_path, 'w',
- zipfile.ZIP_DEFLATED)
-
- missing_files = self.builder.check_manifest()
- if missing_files:
- logging.warn('These files are not included in the manifest ' \
- 'and will not be present in the bundle:\n\n' +
- '\n'.join(missing_files) +
- '\n\nUse fix_manifest if you want to add them.')
-
- for f in self.builder.get_files():
- bundle_zip.write(os.path.join(self.config.source_dir, f),
- os.path.join(self.config.bundle_root_dir, f))
-
- bundle_zip.close()
-
-class SourcePackager(Packager):
- def __init__(self, config):
- Packager.__init__(self, config)
- self.package_path = os.path.join(self.config.dist_dir,
- self.config.tar_name)
-
- def get_files(self):
- git_ls = subprocess.Popen('git-ls-files', stdout=subprocess.PIPE,
- cwd=self.config.source_dir)
- if git_ls.wait():
- # Fall back to filtered list
- return list_files(self.config.source_dir,
- IGNORE_DIRS, IGNORE_FILES)
-
- return [path.strip() for path in git_ls.stdout.readlines()]
-
- def package(self):
- tar = tarfile.open(self.package_path, 'w:bz2')
- for f in self.get_files():
- tar.add(os.path.join(self.config.source_dir, f),
- os.path.join(self.config.tar_root_dir, f))
- tar.close()
-
-class Installer(object):
- IGNORES = [ 'po/*', 'MANIFEST', 'AUTHORS' ]
-
- def __init__(self, builder):
- self.config = builder.config
- self.builder = builder
-
- def should_ignore(self, f):
- for pattern in self.IGNORES:
- if fnmatch(f, pattern):
- return True
- return False
-
- def install(self, prefix):
- self.builder.build()
-
- activity_path = os.path.join(prefix, 'share', 'sugar', 'activities',
- self.config.bundle_root_dir)
-
- source_to_dest = {}
- for f in self.builder.get_files():
- if self.should_ignore(f):
- pass
- elif f.startswith('locale/') and f.endswith('.mo'):
- source_to_dest[f] = os.path.join(prefix, 'share', f)
- else:
- source_to_dest[f] = os.path.join(activity_path, f)
-
- for source, dest in source_to_dest.items():
- print 'Install %s to %s.' % (source, dest)
-
- path = os.path.dirname(dest)
- if not os.path.exists(path):
- os.makedirs(path)
-
- shutil.copy(source, dest)
-
-def cmd_dev(config, args):
- '''Setup for development'''
-
- if args:
- print 'Usage: %prog dev'
- return
-
- bundle_path = env.get_user_activities_path()
- if not os.path.isdir(bundle_path):
- os.mkdir(bundle_path)
- bundle_path = os.path.join(bundle_path, config.bundle_root_dir)
- try:
- os.symlink(config.source_dir, bundle_path)
- except OSError:
- if os.path.islink(bundle_path):
- print 'ERROR - The bundle has been already setup for development.'
- else:
- print 'ERROR - A bundle with the same name is already installed.'
-
-def cmd_dist_xo(config, args):
- '''Create a xo bundle package'''
-
- if args:
- print 'Usage: %prog dist_xo'
- return
-
- packager = XOPackager(Builder(config))
- packager.package()
-
-def cmd_fix_manifest(config, args):
- '''Add missing files to the manifest'''
-
- if args:
- print 'Usage: %prog fix_manifest'
- return
-
- builder = Builder(config)
- builder.fix_manifest()
-
-def cmd_dist_source(config, args):
- '''Create a tar source package'''
-
- if args:
- print 'Usage: %prog dist_source'
- return
-
- packager = SourcePackager(config)
- packager.package()
-
-def cmd_install(config, args):
- '''Install the activity in the system'''
-
- parser = OptionParser(usage='usage: %prog install [options]')
- parser.add_option('--prefix', dest='prefix', default=sys.prefix,
- help='Prefix to install files to')
- (suboptions, subargs) = parser.parse_args(args)
- if subargs:
- parser.print_help()
- return
-
- installer = Installer(Builder(config))
- installer.install(suboptions.prefix)
-
-def cmd_genpot(config, args):
- '''Generate the gettext pot file'''
-
- if args:
- print 'Usage: %prog genpot'
- return
-
- po_path = os.path.join(config.source_dir, 'po')
- if not os.path.isdir(po_path):
- os.mkdir(po_path)
-
- python_files = []
- for root_dummy, dirs_dummy, files in os.walk(config.source_dir):
- for file_name in files:
- if file_name.endswith('.py'):
- python_files.append(file_name)
-
- # First write out a stub .pot file containing just the translated
- # activity name, then have xgettext merge the rest of the
- # translations into that. (We can't just append the activity name
- # to the end of the .pot file afterwards, because that might
- # create a duplicate msgid.)
- pot_file = os.path.join('po', '%s.pot' % config.bundle_name)
- escaped_name = re.sub('([\\\\"])', '\\\\\\1', config.activity_name)
- f = open(pot_file, 'w')
- f.write('#: activity/activity.info:2\n')
- f.write('msgid "%s"\n' % escaped_name)
- f.write('msgstr ""\n')
- f.close()
-
- args = [ 'xgettext', '--join-existing', '--language=Python',
- '--keyword=_', '--add-comments=TRANS:', '--output=%s' % pot_file ]
-
- args += python_files
- retcode = subprocess.call(args)
- if retcode:
- print 'ERROR - xgettext failed with return code %i.' % retcode
-
-def cmd_build(config, args):
- '''Build generated files'''
-
- if args:
- print 'Usage: %prog build'
- return
-
- builder = Builder(config)
- builder.build()
-
-def print_commands():
- print 'Available commands:\n'
-
- for name, func in globals().items():
- if name.startswith('cmd_'):
- print "%-20s %s" % (name.replace('cmd_', ''), func.__doc__)
-
- print '\n(Type "./setup.py <command> --help" for help about a ' \
- 'particular command\'s options.'
-
-def start(bundle_name=None):
- if bundle_name:
- logging.warn("bundle_name deprecated, now comes from activity.info")
-
- parser = OptionParser(usage='[action] [options]')
- parser.disable_interspersed_args()
- (options_, args) = parser.parse_args()
-
- config = Config()
-
- try:
- globals()['cmd_' + args[0]](config, args[1:])
- except (KeyError, IndexError):
- print_commands()
-
-if __name__ == '__main__':
- start()
diff --git a/sugar-toolkit/src/sugar/activity/main.py b/sugar-toolkit/src/sugar/activity/main.py
deleted file mode 100644
index 0295bf9..0000000
--- a/sugar-toolkit/src/sugar/activity/main.py
+++ /dev/null
@@ -1,140 +0,0 @@
-# Copyright (C) 2008 Red Hat, Inc.
-#
-# This library is free software; you can redistribute it and/or
-# modify it under the terms of the GNU Lesser General Public
-# License as published by the Free Software Foundation; either
-# version 2 of the License, or (at your option) any later version.
-#
-# This library is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-# Lesser General Public License for more details.
-#
-# You should have received a copy of the GNU Lesser General Public
-# License along with this library; if not, write to the
-# Free Software Foundation, Inc., 59 Temple Place - Suite 330,
-# Boston, MA 02111-1307, USA.
-
-import os
-import sys
-import gettext
-from optparse import OptionParser
-
-import gtk
-import dbus
-import dbus.service
-import dbus.glib
-
-from sugar.activity import activityhandle
-from sugar.bundle.activitybundle import ActivityBundle
-from sugar import logger
-
-def create_activity_instance(constructor, handle):
- activity = constructor(handle)
- activity.show()
-
-def get_single_process_name(bundle_id):
- return bundle_id
-
-def get_single_process_path(bundle_id):
- return '/' + bundle_id.replace('.', '/')
-
-class SingleProcess(dbus.service.Object):
- def __init__(self, name_service, constructor):
- self.constructor = constructor
-
- bus = dbus.SessionBus()
- bus_name = dbus.service.BusName(name_service, bus=bus)
- object_path = get_single_process_path(name_service)
- dbus.service.Object.__init__(self, bus_name, object_path)
-
- @dbus.service.method("org.laptop.SingleProcess", in_signature="a{ss}")
- def create(self, handle_dict):
- handle = activityhandle.create_from_dict(handle_dict)
- create_activity_instance(self.constructor, handle)
-
-def main():
- parser = OptionParser()
- parser.add_option("-b", "--bundle-id", dest="bundle_id",
- help="identifier of the activity bundle")
- parser.add_option("-a", "--activity-id", dest="activity_id",
- help="identifier of the activity instance")
- parser.add_option("-o", "--object-id", dest="object_id",
- help="identifier of the associated datastore object")
- parser.add_option("-u", "--uri", dest="uri",
- help="URI to load")
- parser.add_option('-s', '--single-process', dest='single_process',
- action='store_true',
- help='start all the instances in the same process')
- (options, args) = parser.parse_args()
-
- logger.start()
-
- if 'SUGAR_BUNDLE_PATH' not in os.environ:
- print 'SUGAR_BUNDLE_PATH is not defined in the environment.'
- sys.exit(1)
-
- if len(args) == 0:
- print 'A python class must be specified as first argument.'
- sys.exit(1)
-
- bundle_path = os.environ['SUGAR_BUNDLE_PATH']
- sys.path.append(bundle_path)
-
- bundle = ActivityBundle(bundle_path)
-
- os.environ['SUGAR_BUNDLE_ID'] = bundle.get_bundle_id()
- os.environ['SUGAR_BUNDLE_NAME'] = bundle.get_name()
- os.environ['SUGAR_BUNDLE_VERSION'] = str(bundle.get_activity_version())
-
- gtk.icon_theme_get_default().append_search_path(bundle.get_icons_path())
-
- locale_path = None
- if 'SUGAR_LOCALEDIR' in os.environ:
- locale_path = os.environ['SUGAR_LOCALEDIR']
-
- gettext.bindtextdomain(bundle.get_bundle_id(), locale_path)
- gettext.textdomain(bundle.get_bundle_id())
-
- splitted_module = args[0].rsplit('.', 1)
- module_name = splitted_module[0]
- class_name = splitted_module[1]
-
- module = __import__(module_name)
- for comp in module_name.split('.')[1:]:
- module = getattr(module, comp)
-
- activity_constructor = getattr(module, class_name)
- activity_handle = activityhandle.ActivityHandle(
- activity_id=options.activity_id,
- object_id=options.object_id, uri=options.uri)
-
- if options.single_process is True:
- sessionbus = dbus.SessionBus()
-
- service_name = get_single_process_name(options.bundle_id)
- service_path = get_single_process_path(options.bundle_id)
-
- bus_object = sessionbus.get_object(
- 'org.freedesktop.DBus', '/org/freedesktop/DBus')
- try:
- name = bus_object.GetNameOwner(
- service_name, dbus_interface='org.freedesktop.DBus')
- except dbus.DBusException:
- name = None
-
- if not name:
- SingleProcess(service_name, activity_constructor)
- else:
- single_process = sessionbus.get_object(service_name, service_path)
- single_process.create(activity_handle.get_dict())
-
- print 'Created %s in a single process.' % service_name
- sys.exit(0)
-
- if hasattr(module, 'start'):
- module.start()
-
- create_activity_instance(activity_constructor, activity_handle)
-
- gtk.main()
diff --git a/sugar-toolkit/src/sugar/activity/namingalert.py b/sugar-toolkit/src/sugar/activity/namingalert.py
deleted file mode 100644
index 724d76a..0000000
--- a/sugar-toolkit/src/sugar/activity/namingalert.py
+++ /dev/null
@@ -1,320 +0,0 @@
-# Copyright (C) 2009 One Laptop Per Child
-#
-# This library is free software; you can redistribute it and/or
-# modify it under the terms of the GNU Lesser General Public
-# License as published by the Free Software Foundation; either
-# version 2 of the License, or (at your option) any later version.
-#
-# This library is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-# Lesser General Public License for more details.
-#
-# You should have received a copy of the GNU Lesser General Public
-# License along with this library; if not, write to the
-# Free Software Foundation, Inc., 59 Temple Place - Suite 330,
-# Boston, MA 02111-1307, USA.
-
-import gettext
-
-import gtk
-import gobject
-import hippo
-import gconf
-
-from sugar.graphics import style
-from sugar.graphics.icon import Icon
-from sugar.graphics.xocolor import XoColor
-from sugar.graphics.icon import CanvasIcon
-from sugar.graphics.entry import CanvasEntry
-from sugar.graphics.toolbutton import ToolButton
-from sugar.graphics.canvastextview import CanvasTextView
-
-from sugar.bundle.activitybundle import ActivityBundle
-
-_ = lambda msg: gettext.dgettext('sugar-toolkit', msg)
-
-class NamingToolbar(gtk.Toolbar):
- """ Toolbar of the naming alert
- """
- __gtype_name__ = 'SugarNamingToolbar'
-
- __gsignals__ = {
- 'keep-clicked': (gobject.SIGNAL_RUN_FIRST,
- gobject.TYPE_NONE,
- ([]))
- }
- def __init__(self):
- gtk.Toolbar.__init__(self)
-
- client = gconf.client_get_default()
- color = XoColor(client.get_string('/desktop/sugar/user/color'))
- icon = Icon()
- icon.set_from_icon_name('activity-journal',
- gtk.ICON_SIZE_LARGE_TOOLBAR)
- icon.props.xo_color = color
- self._add_widget(icon)
-
- self._add_separator()
-
- self._title = gtk.Label(_('Name this entry'))
- self._add_widget(self._title)
-
- self._add_separator(True)
-
- self._keep_button = ToolButton('dialog-ok', tooltip=_('Keep'))
- self._keep_button.props.accelerator = 'Return'
- self._keep_button.connect('clicked', self.__keep_button_clicked_cb)
- self.insert(self._keep_button, -1)
- self._keep_button.show()
-
- def _add_separator(self, expand=False):
- separator = gtk.SeparatorToolItem()
- separator.props.draw = False
- if expand:
- separator.set_expand(True)
- else:
- separator.set_size_request(style.DEFAULT_SPACING, -1)
- self.insert(separator, -1)
- separator.show()
-
- def _add_widget(self, widget, expand=False):
- tool_item = gtk.ToolItem()
- tool_item.set_expand(expand)
-
- tool_item.add(widget)
- widget.show()
-
- self.insert(tool_item, -1)
- tool_item.show()
-
- def __keep_button_clicked_cb(self, widget, data=None):
- self.emit('keep-clicked')
-
-class FavoriteIcon(CanvasIcon):
- def __init__(self, favorite):
- CanvasIcon.__init__(self, icon_name='emblem-favorite',
- box_width=style.GRID_CELL_SIZE * 3 / 5,
- size=style.SMALL_ICON_SIZE)
- self._favorite = None
- self.set_favorite(favorite)
- self.connect('button-release-event', self.__release_event_cb)
- self.connect('motion-notify-event', self.__motion_notify_event_cb)
-
- def set_favorite(self, favorite):
- if favorite == self._favorite:
- return
-
- self._favorite = favorite
- if favorite:
- client = gconf.client_get_default()
- color = XoColor(client.get_string('/desktop/sugar/user/color'))
- self.props.xo_color = color
- else:
- self.props.stroke_color = style.COLOR_BUTTON_GREY.get_svg()
- self.props.fill_color = style.COLOR_WHITE.get_svg()
-
- def get_favorite(self):
- return self._favorite
-
- favorite = gobject.property(
- type=bool, default=False, getter=get_favorite, setter=set_favorite)
-
- def __release_event_cb(self, icon, event):
- self.props.favorite = not self.props.favorite
-
- def __motion_notify_event_cb(self, icon, event):
- if not self._favorite:
- if event.detail == hippo.MOTION_DETAIL_ENTER:
- icon.props.fill_color = style.COLOR_BUTTON_GREY.get_svg()
- elif event.detail == hippo.MOTION_DETAIL_LEAVE:
- icon.props.fill_color = style.COLOR_TRANSPARENT.get_svg()
-
-class NamingAlert(gtk.Window):
- __gtype_name__ = 'SugarNamingAlert'
-
- def __init__(self, activity, bundle_path):
- gtk.Window.__init__(self)
-
- self._bundle_path = bundle_path
- self._favorite_icon = None
- self._title = None
- self._description = None
- self._tags = None
-
- accel_group = gtk.AccelGroup()
- self.set_data('sugar-accel-group', accel_group)
- self.add_accel_group(accel_group)
-
- self.set_border_width(style.LINE_WIDTH)
- offset = style.GRID_CELL_SIZE
- width = gtk.gdk.screen_width() - offset * 2
- height = gtk.gdk.screen_height() - offset * 2
- self.set_size_request(width, height)
- self.set_position(gtk.WIN_POS_CENTER_ALWAYS)
- self.set_decorated(False)
- self.set_resizable(False)
- self.set_modal(True)
- self.connect('realize', self.__realize_cb)
-
- self._activity = activity
-
- vbox = gtk.VBox()
- self.add(vbox)
- vbox.show()
-
- toolbar = NamingToolbar()
- toolbar.connect('keep-clicked', self.__keep_cb)
- vbox.pack_start(toolbar, False)
- toolbar.show()
-
- canvas = hippo.Canvas()
- self._root = hippo.CanvasBox()
- self._root.props.background_color = style.COLOR_WHITE.get_int()
- canvas.set_root(self._root)
- vbox.pack_start(canvas)
- canvas.show()
-
- body = self._create_body()
- self._root.append(body, hippo.PACK_EXPAND)
-
- widget = self._title.get_property('widget')
- widget.grab_focus()
-
- def _create_body(self):
- body = hippo.CanvasBox()
- body.props.orientation = hippo.ORIENTATION_VERTICAL
- body.props.background_color = style.COLOR_WHITE.get_int()
- body.props.padding_top = style.DEFAULT_SPACING * 3
-
- header = hippo.CanvasBox(orientation=hippo.ORIENTATION_HORIZONTAL,
- padding=style.DEFAULT_PADDING,
- padding_right=style.GRID_CELL_SIZE,
- spacing=style.DEFAULT_SPACING)
- body.append(header)
-
- descriptions = hippo.CanvasBox(orientation=hippo.ORIENTATION_HORIZONTAL,
- spacing=style.DEFAULT_SPACING * 3,
- padding_left=style.GRID_CELL_SIZE,
- padding_right=style.GRID_CELL_SIZE,
- padding_top=style.DEFAULT_SPACING * 3)
-
- body.append(descriptions, hippo.PACK_EXPAND)
-
- first_column = hippo.CanvasBox(orientation=hippo.ORIENTATION_VERTICAL,
- spacing=style.DEFAULT_SPACING)
- descriptions.append(first_column)
-
- second_column = hippo.CanvasBox(orientation=hippo.ORIENTATION_VERTICAL,
- spacing=style.DEFAULT_SPACING)
- descriptions.append(second_column, hippo.PACK_EXPAND)
-
- self._favorite_icon = self._create_favorite_icon()
- header.append(self._favorite_icon)
-
- activity_icon = self._create_activity_icon()
- header.append(activity_icon)
-
- self._title = self._create_title()
- header.append(self._title, hippo.PACK_EXPAND)
-
- if gtk.widget_get_default_direction() == gtk.TEXT_DIR_RTL:
- header.reverse()
-
- description_box, self._description = self._create_description()
- second_column.append(description_box)
-
- tags_box, self._tags = self._create_tags()
- second_column.append(tags_box)
-
- return body
-
- def _create_favorite_icon(self):
- favorite_icon = FavoriteIcon(False)
- return favorite_icon
-
- def _create_activity_icon(self):
- activity_bundle = ActivityBundle(self._bundle_path)
- activity_icon = CanvasIcon(file_name=activity_bundle.get_icon())
- if self._activity.metadata.has_key('icon-color') and \
- self._activity.metadata['icon-color']:
- activity_icon.props.xo_color = XoColor( \
- self._activity.metadata['icon-color'])
- return activity_icon
-
- def _create_title(self):
- title = CanvasEntry()
- title.set_background(style.COLOR_WHITE.get_html())
- title.props.text = self._activity.metadata.get('title', _('Untitled'))
- return title
-
- def _create_description(self):
- vbox = hippo.CanvasBox()
- vbox.props.spacing = style.DEFAULT_SPACING
-
- text = hippo.CanvasText(text=_('Description:'),
- font_desc=style.FONT_NORMAL.get_pango_desc())
- text.props.color = style.COLOR_BUTTON_GREY.get_int()
-
- if gtk.widget_get_default_direction() == gtk.TEXT_DIR_RTL:
- text.props.xalign = hippo.ALIGNMENT_END
- else:
- text.props.xalign = hippo.ALIGNMENT_START
-
- vbox.append(text)
-
- description = self._activity.metadata.get('description', '')
- text_view = CanvasTextView(description,
- box_height=style.GRID_CELL_SIZE * 2)
- vbox.append(text_view, hippo.PACK_EXPAND)
-
- text_view.text_view_widget.props.accepts_tab = False
-
- return vbox, text_view
-
- def _create_tags(self):
- vbox = hippo.CanvasBox()
- vbox.props.spacing = style.DEFAULT_SPACING
-
- text = hippo.CanvasText(text=_('Tags:'),
- font_desc=style.FONT_NORMAL.get_pango_desc())
- text.props.color = style.COLOR_BUTTON_GREY.get_int()
-
- if gtk.widget_get_default_direction() == gtk.TEXT_DIR_RTL:
- text.props.xalign = hippo.ALIGNMENT_END
- else:
- text.props.xalign = hippo.ALIGNMENT_START
-
- vbox.append(text)
-
- tags = self._activity.metadata.get('tags', '')
- text_view = CanvasTextView(tags, box_height=style.GRID_CELL_SIZE * 2)
- vbox.append(text_view, hippo.PACK_EXPAND)
-
- text_view.text_view_widget.props.accepts_tab = False
-
- return vbox, text_view
-
- def __realize_cb(self, widget):
- self.window.set_type_hint(gtk.gdk.WINDOW_TYPE_HINT_DIALOG)
- self.window.set_accept_focus(True)
-
- def __keep_cb(self, widget):
- is_favorite = self._favorite_icon.get_favorite()
- if is_favorite:
- self._activity.metadata['keep'] = 1
- else:
- self._activity.metadata['keep'] = 0
-
- self._activity.metadata['title'] = self._title.props.text
-
- new_tags = self._tags.text_view_widget.props.buffer.props.text
- self._activity.metadata['tags'] = new_tags
-
- new_description = \
- self._description.text_view_widget.props.buffer.props.text
- self._activity.metadata['description'] = new_description
-
- self._activity.metadata['title_set_by_user'] = '1'
- self._activity.close()
- self.destroy()