Web   ·   Wiki   ·   Activities   ·   Blog   ·   Lists   ·   Chat   ·   Meeting   ·   Bugs   ·   Git   ·   Translate   ·   Archive   ·   People   ·   Donate
summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJonas Smedegaard <dr@jones.dk>2008-10-18 23:39:20 (GMT)
committer Jonas Smedegaard <dr@jones.dk>2008-10-18 23:39:20 (GMT)
commitb93839e07925181d188b2061cb15ba71de7ff004 (patch)
tree690fafdeb9547316564c203ddeede60ee1c330d6
parentd7cb0f34bfbec887072b0465ade35752dee6cba4 (diff)
parentb3fde4a8e9a91425646bf9403dc27f00149a8980 (diff)
Merge commit 'v0.82.11'
-rw-r--r--configure.ac6
-rw-r--r--m4/gnome-compiler-flags.m4141
-rw-r--r--po/af.po1
-rw-r--r--po/am.po1
-rw-r--r--po/ar.po22
-rw-r--r--po/ay.po1
-rw-r--r--po/bg.po1
-rw-r--r--po/bn.po1
-rw-r--r--po/bn_IN.po1
-rw-r--r--po/ca.po1
-rw-r--r--po/de.po1
-rw-r--r--po/dz.po1
-rw-r--r--po/el.po76
-rw-r--r--po/en.po1
-rw-r--r--po/es.po58
-rw-r--r--po/fa.po1
-rw-r--r--po/fa_AF.po1
-rw-r--r--po/ff.po1
-rw-r--r--po/fr.po1
-rw-r--r--po/gu.po1
-rw-r--r--po/ha.po1
-rw-r--r--po/hi.po1
-rw-r--r--po/ht.po74
-rw-r--r--po/ig.po1
-rw-r--r--po/is.po1
-rw-r--r--po/it.po1
-rw-r--r--po/ja.po7
-rw-r--r--po/km.po1
-rw-r--r--po/ko.po1
-rw-r--r--po/mk.po1
-rw-r--r--po/ml.po1
-rw-r--r--po/mn.po1
-rw-r--r--po/mr.po1
-rw-r--r--po/mvo.po1
-rw-r--r--po/nb.po1
-rw-r--r--po/ne.po3
-rw-r--r--po/nl.po1
-rw-r--r--po/pa.po1
-rw-r--r--po/pap.po52
-rw-r--r--po/pis.po1
-rw-r--r--po/pl.po1
-rw-r--r--po/ps.po1
-rw-r--r--po/pt.po76
-rw-r--r--po/pt_BR.po81
-rw-r--r--po/qu.po1
-rw-r--r--po/ro.po1
-rw-r--r--po/ru.po1
-rw-r--r--po/rw.po7
-rw-r--r--po/sd.po1
-rw-r--r--po/si.po76
-rw-r--r--po/sl.po2
-rw-r--r--po/te.po7
-rw-r--r--po/th.po1
-rw-r--r--po/tpi.po1
-rw-r--r--po/tr.po77
-rw-r--r--po/ur.po1
-rw-r--r--po/vi.po71
-rw-r--r--po/yo.po1
-rw-r--r--po/zh_CN.po1
-rw-r--r--po/zh_TW.po1
-rw-r--r--src/sugar/Makefile.am9
-rw-r--r--src/sugar/_sugarext.defs116
-rw-r--r--src/sugar/_sugarext.override6
-rw-r--r--src/sugar/_sugarextmodule.c10
-rw-r--r--src/sugar/acme-volume-alsa.c317
-rw-r--r--src/sugar/acme-volume-alsa.h47
-rw-r--r--src/sugar/acme-volume.c127
-rw-r--r--src/sugar/acme-volume.h63
-rw-r--r--src/sugar/activity/Makefile.am1
-rw-r--r--src/sugar/activity/activity.py43
-rw-r--r--src/sugar/activity/activityfactory.py42
-rw-r--r--src/sugar/activity/bundlebuilder.py264
-rw-r--r--src/sugar/activity/main.py137
-rw-r--r--src/sugar/bundle/activitybundle.py19
-rw-r--r--src/sugar/bundle/bundle.py37
-rw-r--r--src/sugar/bundle/contentbundle.py4
-rw-r--r--src/sugar/eggsmclient-private.h2
-rw-r--r--src/sugar/graphics/alert.py3
-rw-r--r--src/sugar/graphics/palette.py46
-rw-r--r--src/sugar/graphics/radiotoolbutton.py6
-rw-r--r--src/sugar/graphics/style.py13
-rw-r--r--src/sugar/graphics/toggletoolbutton.py6
-rw-r--r--src/sugar/graphics/toolbutton.py12
-rw-r--r--src/sugar/graphics/tray.py6
-rw-r--r--src/sugar/gsm-session.c53
-rw-r--r--src/sugar/gsm-session.h2
-rw-r--r--src/sugar/profile.py4
-rw-r--r--src/sugar/sugar-grid.c120
-rw-r--r--src/sugar/sugar-grid.h63
-rw-r--r--src/sugar/sugar-menu.h1
-rw-r--r--src/sugar/sugar-preview.c29
-rw-r--r--src/sugar/sugar-preview.h2
-rw-r--r--src/sugar/util.py8
93 files changed, 1906 insertions, 591 deletions
diff --git a/configure.ac b/configure.ac
index 1c234d3..f0aaa85 100644
--- a/configure.ac
+++ b/configure.ac
@@ -1,4 +1,4 @@
-AC_INIT([sugar-toolkit],[0.82.0],[],[sugar-toolkit])
+AC_INIT([sugar-toolkit],[0.82.11],[],[sugar-toolkit])
AC_PREREQ([2.59])
@@ -10,6 +10,8 @@ AM_INIT_AUTOMAKE([1.9 foreign dist-bzip2 no-dist-gzip])
AC_DISABLE_STATIC
AC_PROG_LIBTOOL
+GNOME_COMPILE_WARNINGS(maximum)
+
AC_PATH_PROG([GLIB_GENMARSHAL], [glib-genmarshal])
AM_PATH_PYTHON
@@ -17,7 +19,7 @@ AM_CHECK_PYTHON_HEADERS(,[AC_MSG_ERROR(could not find Python headers)])
AC_PATH_PROG(PYGTK_CODEGEN, pygtk-codegen-2.0, no)
-PKG_CHECK_MODULES(EXT, pygtk-2.0 gtk+-2.0)
+PKG_CHECK_MODULES(EXT, pygtk-2.0 gtk+-2.0 sm ice alsa)
PYGTK_DEFSDIR=`$PKG_CONFIG --variable=defsdir pygtk-2.0`
AC_SUBST(PYGTK_DEFSDIR)
diff --git a/m4/gnome-compiler-flags.m4 b/m4/gnome-compiler-flags.m4
new file mode 100644
index 0000000..b9db2fd
--- /dev/null
+++ b/m4/gnome-compiler-flags.m4
@@ -0,0 +1,141 @@
+dnl GNOME_COMPILE_WARNINGS
+dnl Turn on many useful compiler warnings
+dnl For now, only works on GCC
+AC_DEFUN([GNOME_COMPILE_WARNINGS],[
+ dnl ******************************
+ dnl More compiler warnings
+ dnl ******************************
+
+ AC_ARG_ENABLE(compile-warnings,
+ AC_HELP_STRING([--enable-compile-warnings=@<:@no/minimum/yes/maximum/error@:>@],
+ [Turn on compiler warnings]),,
+ [enable_compile_warnings="m4_default([$1],[yes])"])
+
+ warnCFLAGS=
+ if test "x$GCC" != xyes; then
+ enable_compile_warnings=no
+ fi
+
+ warning_flags=
+ realsave_CFLAGS="$CFLAGS"
+
+ case "$enable_compile_warnings" in
+ no)
+ warning_flags=
+ ;;
+ minimum)
+ warning_flags="-Wall"
+ ;;
+ yes)
+ warning_flags="-Wall -Wmissing-prototypes"
+ ;;
+ maximum|error)
+ warning_flags="-Wall -Wmissing-prototypes -Wnested-externs -Wpointer-arith"
+ CFLAGS="$warning_flags $CFLAGS"
+ for option in -Wno-sign-compare; do
+ SAVE_CFLAGS="$CFLAGS"
+ CFLAGS="$CFLAGS $option"
+ AC_MSG_CHECKING([whether gcc understands $option])
+ AC_TRY_COMPILE([], [],
+ has_option=yes,
+ has_option=no,)
+ CFLAGS="$SAVE_CFLAGS"
+ AC_MSG_RESULT($has_option)
+ if test $has_option = yes; then
+ warning_flags="$warning_flags $option"
+ fi
+ unset has_option
+ unset SAVE_CFLAGS
+ done
+ unset option
+ if test "$enable_compile_warnings" = "error" ; then
+ warning_flags="$warning_flags -Werror"
+ fi
+ ;;
+ *)
+ AC_MSG_ERROR(Unknown argument '$enable_compile_warnings' to --enable-compile-warnings)
+ ;;
+ esac
+ CFLAGS="$realsave_CFLAGS"
+ AC_MSG_CHECKING(what warning flags to pass to the C compiler)
+ AC_MSG_RESULT($warning_flags)
+
+ AC_ARG_ENABLE(iso-c,
+ AC_HELP_STRING([--enable-iso-c],
+ [Try to warn if code is not ISO C ]),,
+ [enable_iso_c=no])
+
+ AC_MSG_CHECKING(what language compliance flags to pass to the C compiler)
+ complCFLAGS=
+ if test "x$enable_iso_c" != "xno"; then
+ if test "x$GCC" = "xyes"; then
+ case " $CFLAGS " in
+ *[\ \ ]-ansi[\ \ ]*) ;;
+ *) complCFLAGS="$complCFLAGS -ansi" ;;
+ esac
+ case " $CFLAGS " in
+ *[\ \ ]-pedantic[\ \ ]*) ;;
+ *) complCFLAGS="$complCFLAGS -pedantic" ;;
+ esac
+ fi
+ fi
+ AC_MSG_RESULT($complCFLAGS)
+
+ WARN_CFLAGS="$warning_flags $complCFLAGS"
+ AC_SUBST(WARN_CFLAGS)
+])
+
+dnl For C++, do basically the same thing.
+
+AC_DEFUN([GNOME_CXX_WARNINGS],[
+ AC_ARG_ENABLE(cxx-warnings,
+ AC_HELP_STRING([--enable-cxx-warnings=@<:@no/minimum/yes@:>@]
+ [Turn on compiler warnings.]),,
+ [enable_cxx_warnings="m4_default([$1],[minimum])"])
+
+ AC_MSG_CHECKING(what warning flags to pass to the C++ compiler)
+ warnCXXFLAGS=
+ if test "x$GXX" != xyes; then
+ enable_cxx_warnings=no
+ fi
+ if test "x$enable_cxx_warnings" != "xno"; then
+ if test "x$GXX" = "xyes"; then
+ case " $CXXFLAGS " in
+ *[\ \ ]-Wall[\ \ ]*) ;;
+ *) warnCXXFLAGS="-Wall -Wno-unused" ;;
+ esac
+
+ ## -W is not all that useful. And it cannot be controlled
+ ## with individual -Wno-xxx flags, unlike -Wall
+ if test "x$enable_cxx_warnings" = "xyes"; then
+ warnCXXFLAGS="$warnCXXFLAGS -Wshadow -Woverloaded-virtual"
+ fi
+ fi
+ fi
+ AC_MSG_RESULT($warnCXXFLAGS)
+
+ AC_ARG_ENABLE(iso-cxx,
+ AC_HELP_STRING([--enable-iso-cxx],
+ [Try to warn if code is not ISO C++ ]),,
+ [enable_iso_cxx=no])
+
+ AC_MSG_CHECKING(what language compliance flags to pass to the C++ compiler)
+ complCXXFLAGS=
+ if test "x$enable_iso_cxx" != "xno"; then
+ if test "x$GXX" = "xyes"; then
+ case " $CXXFLAGS " in
+ *[\ \ ]-ansi[\ \ ]*) ;;
+ *) complCXXFLAGS="$complCXXFLAGS -ansi" ;;
+ esac
+
+ case " $CXXFLAGS " in
+ *[\ \ ]-pedantic[\ \ ]*) ;;
+ *) complCXXFLAGS="$complCXXFLAGS -pedantic" ;;
+ esac
+ fi
+ fi
+ AC_MSG_RESULT($complCXXFLAGS)
+
+ WARN_CXXFLAGS="$CXXFLAGS $warnCXXFLAGS $complCXXFLAGS"
+ AC_SUBST(WARN_CXXFLAGS)
+])
diff --git a/po/af.po b/po/af.po
index 93a56e3..abbddbf 100644
--- a/po/af.po
+++ b/po/af.po
@@ -14,6 +14,7 @@ msgstr ""
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
+"Plural-Forms: nplurals=2; plural=(n!=1);\n"
"X-Generator: Translate Toolkit 1.1.1rc4\n"
#: ../src/sugar/activity/activity.py:120
diff --git a/po/am.po b/po/am.po
index 93a56e3..9951101 100644
--- a/po/am.po
+++ b/po/am.po
@@ -14,6 +14,7 @@ msgstr ""
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
+"Plural-Forms: nplurals = 2; plural=(n > 1);\n"
"X-Generator: Translate Toolkit 1.1.1rc4\n"
#: ../src/sugar/activity/activity.py:120
diff --git a/po/ar.po b/po/ar.po
index 25645f8..f4e9b3e 100644
--- a/po/ar.po
+++ b/po/ar.po
@@ -7,7 +7,7 @@ msgstr ""
"Project-Id-Version: sugar\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2008-06-24 00:07+0530\n"
-"PO-Revision-Date: 2008-08-07 09:05-0400\n"
+"PO-Revision-Date: 2008-08-07 17:03-0400\n"
"Last-Translator: Khaled Hosny <khaledhosny@eglug.org>\n"
"Language-Team: Arabic <doc@arabeyes.org>\n"
"MIME-Version: 1.0\n"
@@ -133,8 +133,8 @@ msgstr[5] "%d سنة"
msgid "%d month"
msgid_plural "%d months"
msgstr[0] "%d شهر"
-msgstr[1] "%.sشهر"
-msgstr[2] "%.sشهرين"
+msgstr[1] "%.0sشهر"
+msgstr[2] "%.0sشهرين"
msgstr[3] "%d شهور"
msgstr[4] "%d شهرا"
msgstr[5] "%d شهر"
@@ -144,8 +144,8 @@ msgstr[5] "%d شهر"
msgid "%d week"
msgid_plural "%d weeks"
msgstr[0] "%d أسبوع"
-msgstr[1] "%.sأسبوع"
-msgstr[2] "%.sأسبوعين"
+msgstr[1] "%.0sأسبوع"
+msgstr[2] "%.0sأسبوعين"
msgstr[3] "%d أسابيع"
msgstr[4] "%d أسبوعا"
msgstr[5] "%d أسبوع"
@@ -155,8 +155,8 @@ msgstr[5] "%d أسبوع"
msgid "%d day"
msgid_plural "%d days"
msgstr[0] "%d يوم"
-msgstr[1] "%.sيوم"
-msgstr[2] "%.sيومين"
+msgstr[1] "%.0sيوم"
+msgstr[2] "%.0sيومين"
msgstr[3] "%d أيام"
msgstr[4] "%d يوما"
msgstr[5] "%d يوم"
@@ -166,8 +166,8 @@ msgstr[5] "%d يوم"
msgid "%d hour"
msgid_plural "%d hours"
msgstr[0] "%d ساعة"
-msgstr[1] "%.sساعة"
-msgstr[2] "%.sساعتين"
+msgstr[1] "%.0sساعة"
+msgstr[2] "%.0sساعتين"
msgstr[3] "%d ساعات"
msgstr[4] "%d ساعة"
msgstr[5] "%d ساعة"
@@ -177,8 +177,8 @@ msgstr[5] "%d ساعة"
msgid "%d minute"
msgid_plural "%d minutes"
msgstr[0] "%d دقيقة"
-msgstr[1] "%.sدقيقة"
-msgstr[2] "%.sدقيقتين"
+msgstr[1] "%.0sدقيقة"
+msgstr[2] "%.0sدقيقتين"
msgstr[3] "%d دقائق"
msgstr[4] "%d دقيقة"
msgstr[5] "%d دقيقة"
diff --git a/po/ay.po b/po/ay.po
index 93a56e3..abbddbf 100644
--- a/po/ay.po
+++ b/po/ay.po
@@ -14,6 +14,7 @@ msgstr ""
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
+"Plural-Forms: nplurals=2; plural=(n!=1);\n"
"X-Generator: Translate Toolkit 1.1.1rc4\n"
#: ../src/sugar/activity/activity.py:120
diff --git a/po/bg.po b/po/bg.po
index 93a56e3..abbddbf 100644
--- a/po/bg.po
+++ b/po/bg.po
@@ -14,6 +14,7 @@ msgstr ""
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
+"Plural-Forms: nplurals=2; plural=(n!=1);\n"
"X-Generator: Translate Toolkit 1.1.1rc4\n"
#: ../src/sugar/activity/activity.py:120
diff --git a/po/bn.po b/po/bn.po
index 93a56e3..abbddbf 100644
--- a/po/bn.po
+++ b/po/bn.po
@@ -14,6 +14,7 @@ msgstr ""
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
+"Plural-Forms: nplurals=2; plural=(n!=1);\n"
"X-Generator: Translate Toolkit 1.1.1rc4\n"
#: ../src/sugar/activity/activity.py:120
diff --git a/po/bn_IN.po b/po/bn_IN.po
index 93a56e3..abbddbf 100644
--- a/po/bn_IN.po
+++ b/po/bn_IN.po
@@ -14,6 +14,7 @@ msgstr ""
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
+"Plural-Forms: nplurals=2; plural=(n!=1);\n"
"X-Generator: Translate Toolkit 1.1.1rc4\n"
#: ../src/sugar/activity/activity.py:120
diff --git a/po/ca.po b/po/ca.po
index 93a56e3..abbddbf 100644
--- a/po/ca.po
+++ b/po/ca.po
@@ -14,6 +14,7 @@ msgstr ""
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
+"Plural-Forms: nplurals=2; plural=(n!=1);\n"
"X-Generator: Translate Toolkit 1.1.1rc4\n"
#: ../src/sugar/activity/activity.py:120
diff --git a/po/de.po b/po/de.po
index b169738..25d85df 100644
--- a/po/de.po
+++ b/po/de.po
@@ -14,6 +14,7 @@ msgstr ""
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
+"Plural-Forms: nplurals=2; plural=(n!=1);\n"
"X-Generator: Translate Toolkit 1.1.1rc4\n"
#: ../src/sugar/activity/activity.py:120
diff --git a/po/dz.po b/po/dz.po
index 93a56e3..fc6dbcd 100644
--- a/po/dz.po
+++ b/po/dz.po
@@ -14,6 +14,7 @@ msgstr ""
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
+"Plural-Forms: nplurals=1; plural=0;\n"
"X-Generator: Translate Toolkit 1.1.1rc4\n"
#: ../src/sugar/activity/activity.py:120
diff --git a/po/el.po b/po/el.po
index 93a56e3..a629d0c 100644
--- a/po/el.po
+++ b/po/el.po
@@ -2,152 +2,152 @@
# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER
# This file is distributed under the same license as the PACKAGE package.
# FIRST AUTHOR <EMAIL@ADDRESS>, YEAR.
-#, fuzzy
msgid ""
msgstr ""
"Project-Id-Version: PACKAGE VERSION\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2008-06-24 00:07+0530\n"
-"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
-"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
+"PO-Revision-Date: 2008-07-05 05:02-0400\n"
+"Last-Translator: Γιάννης Κασκαμανίδης <ttnfy17@yahoo.gr>\n"
"Language-Team: LANGUAGE <LL@li.org>\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
-"X-Generator: Translate Toolkit 1.1.1rc4\n"
+"Plural-Forms: nplurals=2; plural=(n!=1);\n"
+"X-Generator: Pootle 1.1.0rc2\n"
#: ../src/sugar/activity/activity.py:120
msgid "Share with:"
-msgstr ""
+msgstr "Διαμοιρασμός με:"
#: ../src/sugar/activity/activity.py:122
msgid "Private"
-msgstr ""
+msgstr "Ιδιωτικό"
#: ../src/sugar/activity/activity.py:123
msgid "My Neighborhood"
-msgstr ""
+msgstr "Η γειτονιά μου"
#: ../src/sugar/activity/activity.py:130
msgid "Keep"
-msgstr ""
+msgstr "Διατήρηση"
#: ../src/sugar/activity/activity.py:136
msgid "Stop"
-msgstr ""
+msgstr "Διακοπή"
#: ../src/sugar/activity/activity.py:251
msgid "Undo"
-msgstr ""
+msgstr "Αναίρεση"
#: ../src/sugar/activity/activity.py:256
msgid "Redo"
-msgstr ""
+msgstr "Ακύρωση αναίρεσης"
#: ../src/sugar/activity/activity.py:266
msgid "Copy"
-msgstr ""
+msgstr "Αντιγραφή"
#: ../src/sugar/activity/activity.py:271
msgid "Paste"
-msgstr ""
+msgstr "Επικόλληση"
#: ../src/sugar/activity/activity.py:297
msgid "Activity"
-msgstr ""
+msgstr "Δραστηριότητα"
#: ../src/sugar/activity/activity.py:469
#, python-format
msgid "%s Activity"
-msgstr ""
+msgstr "%s Δραστηριότητα"
#: ../src/sugar/activity/activity.py:856
msgid "Keep error"
-msgstr ""
+msgstr "Το σφάλμα εξακολουθεί να υφίσταται"
#: ../src/sugar/activity/activity.py:857
msgid "Keep error: all changes will be lost"
-msgstr ""
+msgstr "Το σφάλμα εξακολουθεί να υφίσταται: όλες οι αλλαγές θα χαθούν"
#: ../src/sugar/activity/activity.py:860
msgid "Don't stop"
-msgstr ""
+msgstr "Αδυναμία διακοπής"
#: ../src/sugar/activity/activity.py:863
msgid "Stop anyway"
-msgstr ""
+msgstr "Διακοπή παρ' όλα αυτά"
#: ../src/sugar/graphics/alert.py:166 ../src/sugar/graphics/alert.py:209
msgid "Cancel"
-msgstr ""
+msgstr "Άκυρο"
#: ../src/sugar/graphics/alert.py:170 ../src/sugar/graphics/alert.py:247
msgid "Ok"
-msgstr ""
+msgstr "Εντάξει"
#: ../src/sugar/graphics/alert.py:219
msgid "Continue"
-msgstr ""
+msgstr "Συνέχεια"
#: ../src/sugar/util.py:181
msgid " and "
-msgstr ""
+msgstr " και "
#: ../src/sugar/util.py:182
msgid ", "
-msgstr ""
+msgstr ", "
#. TRANS: Indicating something that just happened, eg. "just now", "moments ago"
#: ../src/sugar/util.py:185
msgid "Seconds ago"
-msgstr ""
+msgstr "Δευτερόλεπτα πριν"
#. TRANS: Indicating time passed, eg. "[10 day, 5 hours] ago",
#. "[2 minutes] in the past", or "[3 years, 1 month] earlier"
#: ../src/sugar/util.py:189
#, python-format
msgid "%s ago"
-msgstr ""
+msgstr "%s πριν"
#. TRANS: Relative dates (eg. 1 month and 5 days).
#: ../src/sugar/util.py:202
#, python-format
msgid "%d year"
msgid_plural "%d years"
-msgstr[0] ""
-msgstr[1] ""
+msgstr[0] "%d έτος"
+msgstr[1] "%d έτη"
#: ../src/sugar/util.py:203
#, python-format
msgid "%d month"
msgid_plural "%d months"
-msgstr[0] ""
-msgstr[1] ""
+msgstr[0] "%d μήνας"
+msgstr[1] "%d μήνες"
#: ../src/sugar/util.py:204
#, python-format
msgid "%d week"
msgid_plural "%d weeks"
-msgstr[0] ""
-msgstr[1] ""
+msgstr[0] "%d εβδομάδα"
+msgstr[1] "%d εβδομάδες"
#: ../src/sugar/util.py:205
#, python-format
msgid "%d day"
msgid_plural "%d days"
-msgstr[0] ""
-msgstr[1] ""
+msgstr[0] "%d ημέρα"
+msgstr[1] "%d ημέρες"
#: ../src/sugar/util.py:206
#, python-format
msgid "%d hour"
msgid_plural "%d hours"
-msgstr[0] ""
-msgstr[1] ""
+msgstr[0] "%d ώρα"
+msgstr[1] "%d ώρες"
#: ../src/sugar/util.py:207
#, python-format
msgid "%d minute"
msgid_plural "%d minutes"
-msgstr[0] ""
-msgstr[1] ""
+msgstr[0] "%d λεπτό"
+msgstr[1] "%d λεπτά"
diff --git a/po/en.po b/po/en.po
index 93a56e3..abbddbf 100644
--- a/po/en.po
+++ b/po/en.po
@@ -14,6 +14,7 @@ msgstr ""
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
+"Plural-Forms: nplurals=2; plural=(n!=1);\n"
"X-Generator: Translate Toolkit 1.1.1rc4\n"
#: ../src/sugar/activity/activity.py:120
diff --git a/po/es.po b/po/es.po
index f7e27e3..0a9126f 100644
--- a/po/es.po
+++ b/po/es.po
@@ -7,12 +7,13 @@ msgstr ""
"Project-Id-Version: olpc-sugar\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2008-06-24 00:07+0530\n"
-"PO-Revision-Date: 2008-06-19 03:16-0400\n"
-"Last-Translator: Maria del Pilar Saenz Rodriguez <mapisaro@gmail.com>\n"
+"PO-Revision-Date: 2008-07-20 14:39-0400\n"
+"Last-Translator: Chema Q <jameson.quinn@gmail.com>\n"
"Language-Team: Fedora Spanish <fedora-trans-es@redhat.com>\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
+"Plural-Forms: nplurals=2; plural=(n!=1);\n"
"X-Generator: Pootle 1.1.0rc2\n"
"X-Poedit-Language: Spanish\n"
"X-Poedit-SourceCharset: utf-8\n"
@@ -69,11 +70,11 @@ msgstr "Actividad %s"
#: ../src/sugar/activity/activity.py:856
msgid "Keep error"
-msgstr "Error de guardado"
+msgstr "Error al guardar"
#: ../src/sugar/activity/activity.py:857
msgid "Keep error: all changes will be lost"
-msgstr "Error de guardado: todos los cambios se perderán"
+msgstr "Error al guardar: todos los cambios se perderán"
#: ../src/sugar/activity/activity.py:860
msgid "Don't stop"
@@ -106,57 +107,60 @@ msgstr ", "
#. TRANS: Indicating something that just happened, eg. "just now", "moments ago"
#: ../src/sugar/util.py:185
msgid "Seconds ago"
-msgstr ""
+msgstr "Segundos atrás"
+# I used an expression, not a literal translation, but I think it's OK.
#. TRANS: Indicating time passed, eg. "[10 day, 5 hours] ago",
#. "[2 minutes] in the past", or "[3 years, 1 month] earlier"
#: ../src/sugar/util.py:189
#, python-format
msgid "%s ago"
-msgstr ""
+msgstr "%s atrás"
+# No entiendo porque colocaron el plural igual que el singular.
+# Traduction: I don't know why somebody wrote the same for plural and singular traduction.
#. TRANS: Relative dates (eg. 1 month and 5 days).
#: ../src/sugar/util.py:202
-#, fuzzy, python-format
+#, python-format
msgid "%d year"
msgid_plural "%d years"
msgstr[0] "%d año"
-msgstr[1] "%d año"
+msgstr[1] "%d años"
#: ../src/sugar/util.py:203
-#, fuzzy, python-format
+#, python-format
msgid "%d month"
msgid_plural "%d months"
msgstr[0] "%d mes"
-msgstr[1] "%d mes"
+msgstr[1] "%d meses"
#: ../src/sugar/util.py:204
-#, fuzzy, python-format
+#, python-format
msgid "%d week"
msgid_plural "%d weeks"
msgstr[0] "%d semana"
-msgstr[1] "%d semana"
+msgstr[1] "%d semanas"
#: ../src/sugar/util.py:205
-#, fuzzy, python-format
+#, python-format
msgid "%d day"
msgid_plural "%d days"
msgstr[0] "%d día"
-msgstr[1] "%d día"
+msgstr[1] "%d días"
#: ../src/sugar/util.py:206
-#, fuzzy, python-format
+#, python-format
msgid "%d hour"
msgid_plural "%d hours"
msgstr[0] "%d hora"
-msgstr[1] "%d hora"
+msgstr[1] "%d horas"
#: ../src/sugar/util.py:207
-#, fuzzy, python-format
+#, python-format
msgid "%d minute"
msgid_plural "%d minutes"
msgstr[0] "%d minuto"
-msgstr[1] "%d minuto"
+msgstr[1] "%d minutos"
#~ msgid "Name:"
#~ msgstr "Nombre:"
@@ -622,23 +626,5 @@ msgstr[1] "%d minuto"
#~ msgid "OK"
#~ msgstr "OK"
-#~ msgid "%d years"
-#~ msgstr "%d años"
-
-#~ msgid "%d months"
-#~ msgstr "%d meses"
-
-#~ msgid "%d weeks"
-#~ msgstr "%d semanas"
-
-#~ msgid "%d days"
-#~ msgstr "%d días"
-
-#~ msgid "%d hours"
-#~ msgstr "%d horas"
-
-#~ msgid "%d minutes"
-#~ msgstr "%d minutos"
-
#~ msgid "%d second"
#~ msgstr "%d segundo"
diff --git a/po/fa.po b/po/fa.po
index 93a56e3..fc6dbcd 100644
--- a/po/fa.po
+++ b/po/fa.po
@@ -14,6 +14,7 @@ msgstr ""
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
+"Plural-Forms: nplurals=1; plural=0;\n"
"X-Generator: Translate Toolkit 1.1.1rc4\n"
#: ../src/sugar/activity/activity.py:120
diff --git a/po/fa_AF.po b/po/fa_AF.po
index 93a56e3..fc6dbcd 100644
--- a/po/fa_AF.po
+++ b/po/fa_AF.po
@@ -14,6 +14,7 @@ msgstr ""
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
+"Plural-Forms: nplurals=1; plural=0;\n"
"X-Generator: Translate Toolkit 1.1.1rc4\n"
#: ../src/sugar/activity/activity.py:120
diff --git a/po/ff.po b/po/ff.po
index 93a56e3..abbddbf 100644
--- a/po/ff.po
+++ b/po/ff.po
@@ -14,6 +14,7 @@ msgstr ""
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
+"Plural-Forms: nplurals=2; plural=(n!=1);\n"
"X-Generator: Translate Toolkit 1.1.1rc4\n"
#: ../src/sugar/activity/activity.py:120
diff --git a/po/fr.po b/po/fr.po
index e6845ad..5dfcc24 100644
--- a/po/fr.po
+++ b/po/fr.po
@@ -13,6 +13,7 @@ msgstr ""
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
+"Plural-Forms: nplurals=2; plural=(n!=1);\n"
"X-Generator: Pootle 1.1.0rc2\n"
#: ../src/sugar/activity/activity.py:120
diff --git a/po/gu.po b/po/gu.po
index 93a56e3..abbddbf 100644
--- a/po/gu.po
+++ b/po/gu.po
@@ -14,6 +14,7 @@ msgstr ""
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
+"Plural-Forms: nplurals=2; plural=(n!=1);\n"
"X-Generator: Translate Toolkit 1.1.1rc4\n"
#: ../src/sugar/activity/activity.py:120
diff --git a/po/ha.po b/po/ha.po
index 93a56e3..abbddbf 100644
--- a/po/ha.po
+++ b/po/ha.po
@@ -14,6 +14,7 @@ msgstr ""
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
+"Plural-Forms: nplurals=2; plural=(n!=1);\n"
"X-Generator: Translate Toolkit 1.1.1rc4\n"
#: ../src/sugar/activity/activity.py:120
diff --git a/po/hi.po b/po/hi.po
index 93a56e3..abbddbf 100644
--- a/po/hi.po
+++ b/po/hi.po
@@ -14,6 +14,7 @@ msgstr ""
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
+"Plural-Forms: nplurals=2; plural=(n!=1);\n"
"X-Generator: Translate Toolkit 1.1.1rc4\n"
#: ../src/sugar/activity/activity.py:120
diff --git a/po/ht.po b/po/ht.po
index 93a56e3..9784bdb 100644
--- a/po/ht.po
+++ b/po/ht.po
@@ -2,152 +2,152 @@
# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER
# This file is distributed under the same license as the PACKAGE package.
# FIRST AUTHOR <EMAIL@ADDRESS>, YEAR.
-#, fuzzy
msgid ""
msgstr ""
"Project-Id-Version: PACKAGE VERSION\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2008-06-24 00:07+0530\n"
-"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
-"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
+"PO-Revision-Date: 2008-07-02 08:41-0400\n"
+"Last-Translator: Jude Augusma <jayme2901@yahoo.com>\n"
"Language-Team: LANGUAGE <LL@li.org>\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
+"Plural-Forms: nplurals=2; plural=(n!=1);\n"
"X-Generator: Translate Toolkit 1.1.1rc4\n"
#: ../src/sugar/activity/activity.py:120
msgid "Share with:"
-msgstr ""
+msgstr "Pataje ak:"
#: ../src/sugar/activity/activity.py:122
msgid "Private"
-msgstr ""
+msgstr "Prive"
#: ../src/sugar/activity/activity.py:123
msgid "My Neighborhood"
-msgstr ""
+msgstr "Vwazinaj mwen"
#: ../src/sugar/activity/activity.py:130
msgid "Keep"
-msgstr ""
+msgstr "Kenbe"
#: ../src/sugar/activity/activity.py:136
msgid "Stop"
-msgstr ""
+msgstr "Kanpe"
#: ../src/sugar/activity/activity.py:251
msgid "Undo"
-msgstr ""
+msgstr "Defè"
#: ../src/sugar/activity/activity.py:256
msgid "Redo"
-msgstr ""
+msgstr "Refè"
#: ../src/sugar/activity/activity.py:266
msgid "Copy"
-msgstr ""
+msgstr "Kopye"
#: ../src/sugar/activity/activity.py:271
msgid "Paste"
-msgstr ""
+msgstr "Pase"
#: ../src/sugar/activity/activity.py:297
msgid "Activity"
-msgstr ""
+msgstr "Aktivite"
#: ../src/sugar/activity/activity.py:469
#, python-format
msgid "%s Activity"
-msgstr ""
+msgstr "%s Aktivite"
#: ../src/sugar/activity/activity.py:856
msgid "Keep error"
-msgstr ""
+msgstr "Erè anrejistreman"
#: ../src/sugar/activity/activity.py:857
msgid "Keep error: all changes will be lost"
-msgstr ""
+msgstr "Erè anrejistreman: Tout chanjman yo ap pèdi"
#: ../src/sugar/activity/activity.py:860
msgid "Don't stop"
-msgstr ""
+msgstr "Pa kanpe"
#: ../src/sugar/activity/activity.py:863
msgid "Stop anyway"
-msgstr ""
+msgstr "Kanpe kan menm"
#: ../src/sugar/graphics/alert.py:166 ../src/sugar/graphics/alert.py:209
msgid "Cancel"
-msgstr ""
+msgstr "Anile"
#: ../src/sugar/graphics/alert.py:170 ../src/sugar/graphics/alert.py:247
msgid "Ok"
-msgstr ""
+msgstr "Ok"
#: ../src/sugar/graphics/alert.py:219
msgid "Continue"
-msgstr ""
+msgstr "Kontinye"
#: ../src/sugar/util.py:181
msgid " and "
-msgstr ""
+msgstr "ak_"
#: ../src/sugar/util.py:182
msgid ", "
-msgstr ""
+msgstr ",_"
#. TRANS: Indicating something that just happened, eg. "just now", "moments ago"
#: ../src/sugar/util.py:185
msgid "Seconds ago"
-msgstr ""
+msgstr "yon segond pase"
#. TRANS: Indicating time passed, eg. "[10 day, 5 hours] ago",
#. "[2 minutes] in the past", or "[3 years, 1 month] earlier"
#: ../src/sugar/util.py:189
#, python-format
msgid "%s ago"
-msgstr ""
+msgstr "Li gen %s"
#. TRANS: Relative dates (eg. 1 month and 5 days).
#: ../src/sugar/util.py:202
#, python-format
msgid "%d year"
msgid_plural "%d years"
-msgstr[0] ""
-msgstr[1] ""
+msgstr[0] "%d ane"
+msgstr[1] "%d ane"
#: ../src/sugar/util.py:203
#, python-format
msgid "%d month"
msgid_plural "%d months"
-msgstr[0] ""
-msgstr[1] ""
+msgstr[0] "%d mwa"
+msgstr[1] "%d mwa"
#: ../src/sugar/util.py:204
#, python-format
msgid "%d week"
msgid_plural "%d weeks"
-msgstr[0] ""
-msgstr[1] ""
+msgstr[0] "%d semèn"
+msgstr[1] "%d semèn"
#: ../src/sugar/util.py:205
#, python-format
msgid "%d day"
msgid_plural "%d days"
-msgstr[0] ""
-msgstr[1] ""
+msgstr[0] "%d jou"
+msgstr[1] "%d jou"
#: ../src/sugar/util.py:206
#, python-format
msgid "%d hour"
msgid_plural "%d hours"
-msgstr[0] ""
-msgstr[1] ""
+msgstr[0] "%d è"
+msgstr[1] "%d è"
#: ../src/sugar/util.py:207
#, python-format
msgid "%d minute"
msgid_plural "%d minutes"
-msgstr[0] ""
-msgstr[1] ""
+msgstr[0] "%d minit"
+msgstr[1] "%d minit"
diff --git a/po/ig.po b/po/ig.po
index 93a56e3..abbddbf 100644
--- a/po/ig.po
+++ b/po/ig.po
@@ -14,6 +14,7 @@ msgstr ""
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
+"Plural-Forms: nplurals=2; plural=(n!=1);\n"
"X-Generator: Translate Toolkit 1.1.1rc4\n"
#: ../src/sugar/activity/activity.py:120
diff --git a/po/is.po b/po/is.po
index 93a56e3..abbddbf 100644
--- a/po/is.po
+++ b/po/is.po
@@ -14,6 +14,7 @@ msgstr ""
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
+"Plural-Forms: nplurals=2; plural=(n!=1);\n"
"X-Generator: Translate Toolkit 1.1.1rc4\n"
#: ../src/sugar/activity/activity.py:120
diff --git a/po/it.po b/po/it.po
index 638b957..82e0584 100644
--- a/po/it.po
+++ b/po/it.po
@@ -12,6 +12,7 @@ msgstr ""
"Language-Team: LANGUAGE <LL@li.org>\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
+"Plural-Forms: nplurals=2; plural=(n!=1);\n"
"Content-Transfer-Encoding: 8bit\n"
"X-Generator: Pootle 1.1.0rc2\n"
diff --git a/po/ja.po b/po/ja.po
index 3b902e9..2f4a198 100644
--- a/po/ja.po
+++ b/po/ja.po
@@ -7,12 +7,13 @@ msgstr ""
"Project-Id-Version: PACKAGE VERSION\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2008-06-24 00:07+0530\n"
-"PO-Revision-Date: 2008-07-27 09:55-0400\n"
+"PO-Revision-Date: 2008-08-21 10:55-0400\n"
"Last-Translator: korakurider <korakurider@gmail.com>\n"
"Language-Team: LANGUAGE <LL@li.org>\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
+"Plural-Forms: nplurals=1; plural=0;\n"
"X-Generator: Pootle 1.1.0rc2\n"
#: ../src/sugar/activity/activity.py:120
@@ -29,7 +30,7 @@ msgstr "私のお隣さん"
#: ../src/sugar/activity/activity.py:130
msgid "Keep"
-msgstr "残しておく"
+msgstr "ジャーナルに保存"
#: ../src/sugar/activity/activity.py:136
msgid "Stop"
@@ -106,7 +107,7 @@ msgstr "ちょっと前"
#: ../src/sugar/util.py:189
#, python-format
msgid "%s ago"
-msgstr "だけ前"
+msgstr "%s前"
#. TRANS: Relative dates (eg. 1 month and 5 days).
#: ../src/sugar/util.py:202
diff --git a/po/km.po b/po/km.po
index 93a56e3..50438a3 100644
--- a/po/km.po
+++ b/po/km.po
@@ -13,6 +13,7 @@ msgstr ""
"Language-Team: LANGUAGE <LL@li.org>\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
+"Plural-Forms: nplurals=1; plural=0;\n"
"Content-Transfer-Encoding: 8bit\n"
"X-Generator: Translate Toolkit 1.1.1rc4\n"
diff --git a/po/ko.po b/po/ko.po
index 93a56e3..f0dcf36 100644
--- a/po/ko.po
+++ b/po/ko.po
@@ -11,6 +11,7 @@ msgstr ""
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
"Language-Team: LANGUAGE <LL@li.org>\n"
+"Plural-Forms: nplurals=1; plural=0 ;\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
diff --git a/po/mk.po b/po/mk.po
index 93a56e3..b8b18b0 100644
--- a/po/mk.po
+++ b/po/mk.po
@@ -11,6 +11,7 @@ msgstr ""
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
"Language-Team: LANGUAGE <LL@li.org>\n"
+"Plural-Forms: nplurals=2; plural=((n % 10 == 1 && n % 100 != 11) ? 0 : 1)\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
diff --git a/po/ml.po b/po/ml.po
index 93a56e3..cdfd4b1 100644
--- a/po/ml.po
+++ b/po/ml.po
@@ -11,6 +11,7 @@ msgstr ""
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
"Language-Team: LANGUAGE <LL@li.org>\n"
+"Plural-Forms: nplurals=2; plural=(n!=1);\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
diff --git a/po/mn.po b/po/mn.po
index 3d98302..4aaf822 100644
--- a/po/mn.po
+++ b/po/mn.po
@@ -13,6 +13,7 @@ msgstr ""
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
+"Plural-Forms: nplurals=2; plural=(n!=1);\n"
"X-Generator: Pootle 1.1.0rc2\n"
#: ../src/sugar/activity/activity.py:120
diff --git a/po/mr.po b/po/mr.po
index aee6e3b..c670515 100644
--- a/po/mr.po
+++ b/po/mr.po
@@ -12,6 +12,7 @@ msgstr ""
"Language-Team: LANGUAGE <LL@li.org>\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
+"Plural-Forms: nplurals=2; plural=(n!=1);\n"
"Content-Transfer-Encoding: 8bit\n"
"X-Generator: Pootle 1.1.0rc2\n"
diff --git a/po/mvo.po b/po/mvo.po
index 93a56e3..e6ab5c0 100644
--- a/po/mvo.po
+++ b/po/mvo.po
@@ -13,6 +13,7 @@ msgstr ""
"Language-Team: LANGUAGE <LL@li.org>\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
+"Plural-Forms: nplurals=2; plural=(n!=1);\n"
"Content-Transfer-Encoding: 8bit\n"
"X-Generator: Translate Toolkit 1.1.1rc4\n"
diff --git a/po/nb.po b/po/nb.po
index 3e958e1..86e4240 100644
--- a/po/nb.po
+++ b/po/nb.po
@@ -11,6 +11,7 @@ msgstr ""
"Last-Translator: Kent Dahl <kentda@pvv.org>\n"
"Language-Team: LANGUAGE <LL@li.org>\n"
"MIME-Version: 1.0\n"
+"Plural-Forms: nplurals=2; plural=(n!=1);\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"X-Generator: Translate Toolkit 1.1.1rc4\n"
diff --git a/po/ne.po b/po/ne.po
index 42719d5..97ee6c6 100644
--- a/po/ne.po
+++ b/po/ne.po
@@ -11,6 +11,7 @@ msgstr ""
"Last-Translator: Bibek Kafle <oxese.eax@gmail.com>\n"
"Language-Team: LANGUAGE <LL@li.org>\n"
"MIME-Version: 1.0\n"
+"Plural-Forms: nplurals=2; plural=(n!=1);\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"X-Generator: Pootle 1.1.0rc2\n"
@@ -58,7 +59,7 @@ msgstr "क्रियाकलाप"
#: ../src/sugar/activity/activity.py:469
#, python-format
msgid "%s Activity"
-msgstr "%ऽ कृयाकलाप"
+msgstr "%s कृयाकलाप"
#: ../src/sugar/activity/activity.py:856
msgid "Keep error"
diff --git a/po/nl.po b/po/nl.po
index 0c2958b..e7736b2 100644
--- a/po/nl.po
+++ b/po/nl.po
@@ -10,6 +10,7 @@ msgstr ""
"PO-Revision-Date: 2008-06-25 15:47-0400\n"
"Last-Translator: Myckel Habets <myckel@sdf.lonestar.org>\n"
"Language-Team: LANGUAGE <LL@li.org>\n"
+"Plural-Forms: nplurals=2; plural=(n!=1);\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
diff --git a/po/pa.po b/po/pa.po
index 93a56e3..75d05a8 100644
--- a/po/pa.po
+++ b/po/pa.po
@@ -12,6 +12,7 @@ msgstr ""
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
"Language-Team: LANGUAGE <LL@li.org>\n"
"MIME-Version: 1.0\n"
+"Plural-Forms: nplurals=2; plural=(n!=1);\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"X-Generator: Translate Toolkit 1.1.1rc4\n"
diff --git a/po/pap.po b/po/pap.po
index 93a56e3..cf77586 100644
--- a/po/pap.po
+++ b/po/pap.po
@@ -2,112 +2,112 @@
# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER
# This file is distributed under the same license as the PACKAGE package.
# FIRST AUTHOR <EMAIL@ADDRESS>, YEAR.
-#, fuzzy
msgid ""
msgstr ""
"Project-Id-Version: PACKAGE VERSION\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2008-06-24 00:07+0530\n"
-"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
-"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
+"PO-Revision-Date: 2008-06-28 09:54-0400\n"
+"Last-Translator: Urso Wieske <uwieske@gmail.com>\n"
"Language-Team: LANGUAGE <LL@li.org>\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
-"X-Generator: Translate Toolkit 1.1.1rc4\n"
+"Plural-Forms: nplurals=2; plural=(n!=1);\n"
+"X-Generator: Pootle 1.1.0rc2\n"
#: ../src/sugar/activity/activity.py:120
msgid "Share with:"
-msgstr ""
+msgstr "Komparti ku:"
#: ../src/sugar/activity/activity.py:122
msgid "Private"
-msgstr ""
+msgstr "Privá"
#: ../src/sugar/activity/activity.py:123
msgid "My Neighborhood"
-msgstr ""
+msgstr "Mi Besindario"
#: ../src/sugar/activity/activity.py:130
msgid "Keep"
-msgstr ""
+msgstr "Warda"
#: ../src/sugar/activity/activity.py:136
msgid "Stop"
-msgstr ""
+msgstr "Para"
#: ../src/sugar/activity/activity.py:251
msgid "Undo"
-msgstr ""
+msgstr "Deshasí"
#: ../src/sugar/activity/activity.py:256
msgid "Redo"
-msgstr ""
+msgstr "Rehasí"
#: ../src/sugar/activity/activity.py:266
msgid "Copy"
-msgstr ""
+msgstr "Kopia"
#: ../src/sugar/activity/activity.py:271
msgid "Paste"
-msgstr ""
+msgstr "Pega"
#: ../src/sugar/activity/activity.py:297
msgid "Activity"
-msgstr ""
+msgstr "Aktividad"
#: ../src/sugar/activity/activity.py:469
#, python-format
msgid "%s Activity"
-msgstr ""
+msgstr "%s Aktividad"
#: ../src/sugar/activity/activity.py:856
msgid "Keep error"
-msgstr ""
+msgstr "Warda eror"
#: ../src/sugar/activity/activity.py:857
msgid "Keep error: all changes will be lost"
-msgstr ""
+msgstr "Warda eror: tur kambionan lo bai perdí"
#: ../src/sugar/activity/activity.py:860
msgid "Don't stop"
-msgstr ""
+msgstr "No para"
#: ../src/sugar/activity/activity.py:863
msgid "Stop anyway"
-msgstr ""
+msgstr "Stop kon ku para"
#: ../src/sugar/graphics/alert.py:166 ../src/sugar/graphics/alert.py:209
msgid "Cancel"
-msgstr ""
+msgstr "Kanselá"
#: ../src/sugar/graphics/alert.py:170 ../src/sugar/graphics/alert.py:247
msgid "Ok"
-msgstr ""
+msgstr "Ok"
#: ../src/sugar/graphics/alert.py:219
msgid "Continue"
-msgstr ""
+msgstr "Kontinua"
#: ../src/sugar/util.py:181
msgid " and "
-msgstr ""
+msgstr "i "
#: ../src/sugar/util.py:182
msgid ", "
-msgstr ""
+msgstr ", "
#. TRANS: Indicating something that just happened, eg. "just now", "moments ago"
#: ../src/sugar/util.py:185
msgid "Seconds ago"
-msgstr ""
+msgstr "Algun seconde pasá"
#. TRANS: Indicating time passed, eg. "[10 day, 5 hours] ago",
#. "[2 minutes] in the past", or "[3 years, 1 month] earlier"
#: ../src/sugar/util.py:189
#, python-format
msgid "%s ago"
-msgstr ""
+msgstr "%s pasá"
#. TRANS: Relative dates (eg. 1 month and 5 days).
#: ../src/sugar/util.py:202
diff --git a/po/pis.po b/po/pis.po
index 93a56e3..cdfd4b1 100644
--- a/po/pis.po
+++ b/po/pis.po
@@ -11,6 +11,7 @@ msgstr ""
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
"Language-Team: LANGUAGE <LL@li.org>\n"
+"Plural-Forms: nplurals=2; plural=(n!=1);\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
diff --git a/po/pl.po b/po/pl.po
index 93a56e3..d0c2a44 100644
--- a/po/pl.po
+++ b/po/pl.po
@@ -11,6 +11,7 @@ msgstr ""
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
"Language-Team: LANGUAGE <LL@li.org>\n"
+"Plural-Forms: nplurals=3; plural=(n==1 ? 0 : n%10>=2 && n%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2);\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
diff --git a/po/ps.po b/po/ps.po
index 93a56e3..55465ec 100644
--- a/po/ps.po
+++ b/po/ps.po
@@ -10,6 +10,7 @@ msgstr ""
"POT-Creation-Date: 2008-06-24 00:07+0530\n"
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
+"Plural-Forms: nplurals=2; plural=(n!=1);\n"
"Language-Team: LANGUAGE <LL@li.org>\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
diff --git a/po/pt.po b/po/pt.po
index 93a56e3..89e1fe8 100644
--- a/po/pt.po
+++ b/po/pt.po
@@ -2,152 +2,152 @@
# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER
# This file is distributed under the same license as the PACKAGE package.
# FIRST AUTHOR <EMAIL@ADDRESS>, YEAR.
-#, fuzzy
msgid ""
msgstr ""
"Project-Id-Version: PACKAGE VERSION\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2008-06-24 00:07+0530\n"
-"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
-"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
+"PO-Revision-Date: 2008-09-19 15:02-0400\n"
+"Last-Translator: Eduardo H. Silva <HoboPrimate@gmail.com>\n"
"Language-Team: LANGUAGE <LL@li.org>\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
-"X-Generator: Translate Toolkit 1.1.1rc4\n"
+"Plural-Forms: nplurals=2; plural=(n != 1);\n"
+"X-Generator: Pootle 1.1.0rc2\n"
#: ../src/sugar/activity/activity.py:120
msgid "Share with:"
-msgstr ""
+msgstr "Partilhar com:"
#: ../src/sugar/activity/activity.py:122
msgid "Private"
-msgstr ""
+msgstr "Privado"
#: ../src/sugar/activity/activity.py:123
msgid "My Neighborhood"
-msgstr ""
+msgstr "Minha Vizinhança"
#: ../src/sugar/activity/activity.py:130
msgid "Keep"
-msgstr ""
+msgstr "Guardar uma cópia"
#: ../src/sugar/activity/activity.py:136
msgid "Stop"
-msgstr ""
+msgstr "Parar"
#: ../src/sugar/activity/activity.py:251
msgid "Undo"
-msgstr ""
+msgstr "Desfazer"
#: ../src/sugar/activity/activity.py:256
msgid "Redo"
-msgstr ""
+msgstr "Refazer"
#: ../src/sugar/activity/activity.py:266
msgid "Copy"
-msgstr ""
+msgstr "Copiar"
#: ../src/sugar/activity/activity.py:271
msgid "Paste"
-msgstr ""
+msgstr "Colar"
#: ../src/sugar/activity/activity.py:297
msgid "Activity"
-msgstr ""
+msgstr "Actividade"
#: ../src/sugar/activity/activity.py:469
#, python-format
msgid "%s Activity"
-msgstr ""
+msgstr "Actividade %s"
#: ../src/sugar/activity/activity.py:856
msgid "Keep error"
-msgstr ""
+msgstr "Erro ao guardar"
#: ../src/sugar/activity/activity.py:857
msgid "Keep error: all changes will be lost"
-msgstr ""
+msgstr "Erro ao guardar: todas as alterações serão perdidas"
#: ../src/sugar/activity/activity.py:860
msgid "Don't stop"
-msgstr ""
+msgstr "Não parar"
#: ../src/sugar/activity/activity.py:863
msgid "Stop anyway"
-msgstr ""
+msgstr "Parar mesmo assim"
#: ../src/sugar/graphics/alert.py:166 ../src/sugar/graphics/alert.py:209
msgid "Cancel"
-msgstr ""
+msgstr "Cancelar"
#: ../src/sugar/graphics/alert.py:170 ../src/sugar/graphics/alert.py:247
msgid "Ok"
-msgstr ""
+msgstr "Ok"
#: ../src/sugar/graphics/alert.py:219
msgid "Continue"
-msgstr ""
+msgstr "Continuar"
#: ../src/sugar/util.py:181
msgid " and "
-msgstr ""
+msgstr " e "
#: ../src/sugar/util.py:182
msgid ", "
-msgstr ""
+msgstr ", "
#. TRANS: Indicating something that just happened, eg. "just now", "moments ago"
#: ../src/sugar/util.py:185
msgid "Seconds ago"
-msgstr ""
+msgstr "Segundos atrás"
#. TRANS: Indicating time passed, eg. "[10 day, 5 hours] ago",
#. "[2 minutes] in the past", or "[3 years, 1 month] earlier"
#: ../src/sugar/util.py:189
#, python-format
msgid "%s ago"
-msgstr ""
+msgstr "%s atrás"
#. TRANS: Relative dates (eg. 1 month and 5 days).
#: ../src/sugar/util.py:202
#, python-format
msgid "%d year"
msgid_plural "%d years"
-msgstr[0] ""
-msgstr[1] ""
+msgstr[0] "%d ano"
+msgstr[1] "%d anos"
#: ../src/sugar/util.py:203
#, python-format
msgid "%d month"
msgid_plural "%d months"
-msgstr[0] ""
-msgstr[1] ""
+msgstr[0] "%d mês"
+msgstr[1] "%d meses"
#: ../src/sugar/util.py:204
#, python-format
msgid "%d week"
msgid_plural "%d weeks"
-msgstr[0] ""
-msgstr[1] ""
+msgstr[0] "%d semana"
+msgstr[1] "%d semanas"
#: ../src/sugar/util.py:205
#, python-format
msgid "%d day"
msgid_plural "%d days"
-msgstr[0] ""
-msgstr[1] ""
+msgstr[0] "%d dia"
+msgstr[1] "%d dias"
#: ../src/sugar/util.py:206
#, python-format
msgid "%d hour"
msgid_plural "%d hours"
-msgstr[0] ""
-msgstr[1] ""
+msgstr[0] "%d hora"
+msgstr[1] "%d horas"
#: ../src/sugar/util.py:207
#, python-format
msgid "%d minute"
msgid_plural "%d minutes"
-msgstr[0] ""
-msgstr[1] ""
+msgstr[0] "%d minuto"
+msgstr[1] "%d minutos"
diff --git a/po/pt_BR.po b/po/pt_BR.po
index 93a56e3..bf97bd6 100644
--- a/po/pt_BR.po
+++ b/po/pt_BR.po
@@ -2,14 +2,14 @@
# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER
# This file is distributed under the same license as the PACKAGE package.
# FIRST AUTHOR <EMAIL@ADDRESS>, YEAR.
-#, fuzzy
msgid ""
msgstr ""
"Project-Id-Version: PACKAGE VERSION\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2008-06-24 00:07+0530\n"
-"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
-"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
+"PO-Revision-Date: 2008-08-30 13:18+0200\n"
+"Last-Translator: Juliano Bittencourt <juliano@lec.ufrgs.br>\n"
+"Plural-Forms: nplurals=2; plural=(n!=1);\n"
"Language-Team: LANGUAGE <LL@li.org>\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
@@ -18,136 +18,139 @@ msgstr ""
#: ../src/sugar/activity/activity.py:120
msgid "Share with:"
-msgstr ""
+msgstr "Compartilhar com:"
#: ../src/sugar/activity/activity.py:122
msgid "Private"
-msgstr ""
+msgstr "Privado"
#: ../src/sugar/activity/activity.py:123
msgid "My Neighborhood"
-msgstr ""
+msgstr "Minha Vizinhança"
#: ../src/sugar/activity/activity.py:130
msgid "Keep"
-msgstr ""
+msgstr "Guardar"
#: ../src/sugar/activity/activity.py:136
msgid "Stop"
-msgstr ""
+msgstr "Parar"
#: ../src/sugar/activity/activity.py:251
msgid "Undo"
-msgstr ""
+msgstr "Desfazer"
#: ../src/sugar/activity/activity.py:256
msgid "Redo"
-msgstr ""
+msgstr "Refazer"
#: ../src/sugar/activity/activity.py:266
msgid "Copy"
-msgstr ""
+msgstr "Copiar"
#: ../src/sugar/activity/activity.py:271
msgid "Paste"
-msgstr ""
+msgstr "Colar"
#: ../src/sugar/activity/activity.py:297
msgid "Activity"
-msgstr ""
+msgstr "Atividade"
#: ../src/sugar/activity/activity.py:469
#, python-format
msgid "%s Activity"
-msgstr ""
+msgstr "Atividade %s"
#: ../src/sugar/activity/activity.py:856
msgid "Keep error"
-msgstr ""
+msgstr "Erro ao guardar"
#: ../src/sugar/activity/activity.py:857
msgid "Keep error: all changes will be lost"
-msgstr ""
+msgstr "Erro ao guardar: todas as alterações serão perdidas"
#: ../src/sugar/activity/activity.py:860
msgid "Don't stop"
-msgstr ""
+msgstr "Não pare"
#: ../src/sugar/activity/activity.py:863
msgid "Stop anyway"
-msgstr ""
+msgstr "Parar de qualque forma"
-#: ../src/sugar/graphics/alert.py:166 ../src/sugar/graphics/alert.py:209
+#: ../src/sugar/graphics/alert.py:166
+#: ../src/sugar/graphics/alert.py:209
msgid "Cancel"
-msgstr ""
+msgstr "Cancelar"
-#: ../src/sugar/graphics/alert.py:170 ../src/sugar/graphics/alert.py:247
+#: ../src/sugar/graphics/alert.py:170
+#: ../src/sugar/graphics/alert.py:247
msgid "Ok"
-msgstr ""
+msgstr "Ok"
#: ../src/sugar/graphics/alert.py:219
msgid "Continue"
-msgstr ""
+msgstr "Continuar"
#: ../src/sugar/util.py:181
msgid " and "
-msgstr ""
+msgstr " e "
#: ../src/sugar/util.py:182
msgid ", "
-msgstr ""
+msgstr ", "
#. TRANS: Indicating something that just happened, eg. "just now", "moments ago"
#: ../src/sugar/util.py:185
msgid "Seconds ago"
-msgstr ""
+msgstr "Segundos atrás"
#. TRANS: Indicating time passed, eg. "[10 day, 5 hours] ago",
#. "[2 minutes] in the past", or "[3 years, 1 month] earlier"
#: ../src/sugar/util.py:189
#, python-format
msgid "%s ago"
-msgstr ""
+msgstr "%s atrás"
#. TRANS: Relative dates (eg. 1 month and 5 days).
#: ../src/sugar/util.py:202
#, python-format
msgid "%d year"
msgid_plural "%d years"
-msgstr[0] ""
-msgstr[1] ""
+msgstr[0] "%d ano"
+msgstr[1] "%d anos"
#: ../src/sugar/util.py:203
#, python-format
msgid "%d month"
msgid_plural "%d months"
-msgstr[0] ""
-msgstr[1] ""
+msgstr[0] "%d mês"
+msgstr[1] "%d meses"
#: ../src/sugar/util.py:204
#, python-format
msgid "%d week"
msgid_plural "%d weeks"
-msgstr[0] ""
-msgstr[1] ""
+msgstr[0] "%d semana"
+msgstr[1] "%d semanas"
#: ../src/sugar/util.py:205
#, python-format
msgid "%d day"
msgid_plural "%d days"
-msgstr[0] ""
-msgstr[1] ""
+msgstr[0] "%d dia"
+msgstr[1] "%d dias"
#: ../src/sugar/util.py:206
#, python-format
msgid "%d hour"
msgid_plural "%d hours"
-msgstr[0] ""
-msgstr[1] ""
+msgstr[0] "%d hora"
+msgstr[1] "%d horas"
#: ../src/sugar/util.py:207
#, python-format
msgid "%d minute"
msgid_plural "%d minutes"
-msgstr[0] ""
-msgstr[1] ""
+msgstr[0] "%d minuto"
+msgstr[1] "%d minutos"
+
diff --git a/po/qu.po b/po/qu.po
index 93a56e3..75d05a8 100644
--- a/po/qu.po
+++ b/po/qu.po
@@ -12,6 +12,7 @@ msgstr ""
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
"Language-Team: LANGUAGE <LL@li.org>\n"
"MIME-Version: 1.0\n"
+"Plural-Forms: nplurals=2; plural=(n!=1);\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"X-Generator: Translate Toolkit 1.1.1rc4\n"
diff --git a/po/ro.po b/po/ro.po
index 93a56e3..29e6bda 100644
--- a/po/ro.po
+++ b/po/ro.po
@@ -12,6 +12,7 @@ msgstr ""
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
"Language-Team: LANGUAGE <LL@li.org>\n"
"MIME-Version: 1.0\n"
+"Plural-Forms: nplurals=3; plural= (n == 1 ? 0: (((n % 100 > 19) || ((n % 100 == 0) && (n != 0))) ? 2: 1));\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"X-Generator: Translate Toolkit 1.1.1rc4\n"
diff --git a/po/ru.po b/po/ru.po
index 93a56e3..91c2300 100644
--- a/po/ru.po
+++ b/po/ru.po
@@ -12,6 +12,7 @@ msgstr ""
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
"Language-Team: LANGUAGE <LL@li.org>\n"
"MIME-Version: 1.0\n"
+"Plural-Forms: nplurals=3; plural=(n%10==1 && n%100!=11 ? 0 : n%10>=2 && n%10< =4 && (n%100<10 or n%100>=20) ? 1 : 2);\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"X-Generator: Translate Toolkit 1.1.1rc4\n"
diff --git a/po/rw.po b/po/rw.po
index 567ed5b..9dce79c 100644
--- a/po/rw.po
+++ b/po/rw.po
@@ -13,6 +13,7 @@ msgstr ""
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
+"Plural-Forms: nplurals=2; plural=(n!=1);\n"
"X-Generator: Pootle 1.1.0rc2\n"
#: ../src/sugar/activity/activity.py:120
@@ -76,13 +77,11 @@ msgstr "Ntuhagarare"
msgid "Stop anyway"
msgstr "Hagarara muburyo bwose"
-#: ../src/sugar/graphics/alert.py:166
-#: ../src/sugar/graphics/alert.py:209
+#: ../src/sugar/graphics/alert.py:166 ../src/sugar/graphics/alert.py:209
msgid "Cancel"
msgstr "Kuraho"
-#: ../src/sugar/graphics/alert.py:170
-#: ../src/sugar/graphics/alert.py:247
+#: ../src/sugar/graphics/alert.py:170 ../src/sugar/graphics/alert.py:247
msgid "Ok"
msgstr "Nibyo"
diff --git a/po/sd.po b/po/sd.po
index 93a56e3..75d05a8 100644
--- a/po/sd.po
+++ b/po/sd.po
@@ -12,6 +12,7 @@ msgstr ""
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
"Language-Team: LANGUAGE <LL@li.org>\n"
"MIME-Version: 1.0\n"
+"Plural-Forms: nplurals=2; plural=(n!=1);\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"X-Generator: Translate Toolkit 1.1.1rc4\n"
diff --git a/po/si.po b/po/si.po
index 93a56e3..f28b437 100644
--- a/po/si.po
+++ b/po/si.po
@@ -2,152 +2,152 @@
# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER
# This file is distributed under the same license as the PACKAGE package.
# FIRST AUTHOR <EMAIL@ADDRESS>, YEAR.
-#, fuzzy
msgid ""
msgstr ""
"Project-Id-Version: PACKAGE VERSION\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2008-06-24 00:07+0530\n"
-"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
-"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
+"PO-Revision-Date: 2008-07-18 06:59-0400\n"
+"Last-Translator: Rashan Anushka <rashan.uoc@gmail.com>\n"
"Language-Team: LANGUAGE <LL@li.org>\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
-"X-Generator: Translate Toolkit 1.1.1rc4\n"
+"Plural-Forms: nplurals=2; plural=(n!=1);\n"
+"X-Generator: Pootle 1.1.0rc2\n"
#: ../src/sugar/activity/activity.py:120
msgid "Share with:"
-msgstr ""
+msgstr "බෙදාගත යුත්තේ:"
#: ../src/sugar/activity/activity.py:122
msgid "Private"
-msgstr ""
+msgstr "පුද්ගලික"
#: ../src/sugar/activity/activity.py:123
msgid "My Neighborhood"
-msgstr ""
+msgstr "මගේ වටපිටාව"
#: ../src/sugar/activity/activity.py:130
msgid "Keep"
-msgstr ""
+msgstr "තබාගන්න"
#: ../src/sugar/activity/activity.py:136
msgid "Stop"
-msgstr ""
+msgstr "නවත්වන්න"
#: ../src/sugar/activity/activity.py:251
msgid "Undo"
-msgstr ""
+msgstr "නිශ්ප්‍රභ කරන්න"
#: ../src/sugar/activity/activity.py:256
msgid "Redo"
-msgstr ""
+msgstr "යළි කරන්න"
#: ../src/sugar/activity/activity.py:266
msgid "Copy"
-msgstr ""
+msgstr "පිටපත් කරන්න"
#: ../src/sugar/activity/activity.py:271
msgid "Paste"
-msgstr ""
+msgstr "අලවන්න"
#: ../src/sugar/activity/activity.py:297
msgid "Activity"
-msgstr ""
+msgstr "ක්‍රියාකාරකම"
#: ../src/sugar/activity/activity.py:469
#, python-format
msgid "%s Activity"
-msgstr ""
+msgstr "%s ක්‍රියාකාරකම"
#: ../src/sugar/activity/activity.py:856
msgid "Keep error"
-msgstr ""
+msgstr "දෝශය තබාගන්න"
#: ../src/sugar/activity/activity.py:857
msgid "Keep error: all changes will be lost"
-msgstr ""
+msgstr "දෝශය තබාගන්න: සියළු වෙනස්කිරීම් නැතිවනු ඇත"
#: ../src/sugar/activity/activity.py:860
msgid "Don't stop"
-msgstr ""
+msgstr "නවත්වන්න එපා"
#: ../src/sugar/activity/activity.py:863
msgid "Stop anyway"
-msgstr ""
+msgstr "කෙසේ හෝ නවත්වන්න"
#: ../src/sugar/graphics/alert.py:166 ../src/sugar/graphics/alert.py:209
msgid "Cancel"
-msgstr ""
+msgstr "අවලංගු කරන්න"
#: ../src/sugar/graphics/alert.py:170 ../src/sugar/graphics/alert.py:247
msgid "Ok"
-msgstr ""
+msgstr "හරි"
#: ../src/sugar/graphics/alert.py:219
msgid "Continue"
-msgstr ""
+msgstr "පවත්වාගෙන යන්න"
#: ../src/sugar/util.py:181
msgid " and "
-msgstr ""
+msgstr " හා "
#: ../src/sugar/util.py:182
msgid ", "
-msgstr ""
+msgstr ", "
#. TRANS: Indicating something that just happened, eg. "just now", "moments ago"
#: ../src/sugar/util.py:185
msgid "Seconds ago"
-msgstr ""
+msgstr "තත්පර කිහිපයකට පෙර"
#. TRANS: Indicating time passed, eg. "[10 day, 5 hours] ago",
#. "[2 minutes] in the past", or "[3 years, 1 month] earlier"
#: ../src/sugar/util.py:189
#, python-format
msgid "%s ago"
-msgstr ""
+msgstr "%s ට පෙර"
#. TRANS: Relative dates (eg. 1 month and 5 days).
#: ../src/sugar/util.py:202
#, python-format
msgid "%d year"
msgid_plural "%d years"
-msgstr[0] ""
-msgstr[1] ""
+msgstr[0] "අවුරුද්දයි"
+msgstr[1] "අවුරුදු %d "
#: ../src/sugar/util.py:203
#, python-format
msgid "%d month"
msgid_plural "%d months"
-msgstr[0] ""
-msgstr[1] ""
+msgstr[0] "මාසයයි"
+msgstr[1] "මාස %d"
#: ../src/sugar/util.py:204
#, python-format
msgid "%d week"
msgid_plural "%d weeks"
-msgstr[0] ""
-msgstr[1] ""
+msgstr[0] "සතියයි"
+msgstr[1] "සති %d"
#: ../src/sugar/util.py:205
#, python-format
msgid "%d day"
msgid_plural "%d days"
-msgstr[0] ""
-msgstr[1] ""
+msgstr[0] "දවසයි"
+msgstr[1] "දවස් %d"
#: ../src/sugar/util.py:206
#, python-format
msgid "%d hour"
msgid_plural "%d hours"
-msgstr[0] ""
-msgstr[1] ""
+msgstr[0] "පැයයි"
+msgstr[1] "පැය %d"
#: ../src/sugar/util.py:207
#, python-format
msgid "%d minute"
msgid_plural "%d minutes"
-msgstr[0] ""
-msgstr[1] ""
+msgstr[0] "මිනිත්තුවයි"
+msgstr[1] "මිනිත්තු %d"
diff --git a/po/sl.po b/po/sl.po
index 5035ab3..bfbbd43 100644
--- a/po/sl.po
+++ b/po/sl.po
@@ -13,6 +13,8 @@ msgstr ""
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
+"Plural-Forms: nplurals=4; plural=(n%100==1 ? 1 : n%100==2 ? 2 : n%100==3 || "
+"n%100==4 ? 3 : 0);\n"
"X-Generator: Pootle 1.1.0rc2\n"
#: ../src/sugar/activity/activity.py:120
diff --git a/po/te.po b/po/te.po
index bc632b1..5845fcd 100644
--- a/po/te.po
+++ b/po/te.po
@@ -13,6 +13,7 @@ msgstr ""
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
+"Plural-Forms: nplurals=2; plural=(n!=1);\n"
"X-Generator: Translate Toolkit 1.1.1rc4\n"
#: ../src/sugar/activity/activity.py:120
@@ -76,13 +77,11 @@ msgstr "ఆపవద్దు"
msgid "Stop anyway"
msgstr "ఏదేమైనా ఆపువేయి"
-#: ../src/sugar/graphics/alert.py:166
-#: ../src/sugar/graphics/alert.py:209
+#: ../src/sugar/graphics/alert.py:166 ../src/sugar/graphics/alert.py:209
msgid "Cancel"
msgstr "రద్దు చేయి"
-#: ../src/sugar/graphics/alert.py:170
-#: ../src/sugar/graphics/alert.py:247
+#: ../src/sugar/graphics/alert.py:170 ../src/sugar/graphics/alert.py:247
msgid "Ok"
msgstr "సరి"
diff --git a/po/th.po b/po/th.po
index 93a56e3..fa67c13 100644
--- a/po/th.po
+++ b/po/th.po
@@ -12,6 +12,7 @@ msgstr ""
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
"Language-Team: LANGUAGE <LL@li.org>\n"
"MIME-Version: 1.0\n"
+"Plural-Forms: nplurals=1; plural=0;\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"X-Generator: Translate Toolkit 1.1.1rc4\n"
diff --git a/po/tpi.po b/po/tpi.po
index 93a56e3..75d05a8 100644
--- a/po/tpi.po
+++ b/po/tpi.po
@@ -12,6 +12,7 @@ msgstr ""
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
"Language-Team: LANGUAGE <LL@li.org>\n"
"MIME-Version: 1.0\n"
+"Plural-Forms: nplurals=2; plural=(n!=1);\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"X-Generator: Translate Toolkit 1.1.1rc4\n"
diff --git a/po/tr.po b/po/tr.po
index 93a56e3..377a939 100644
--- a/po/tr.po
+++ b/po/tr.po
@@ -2,152 +2,153 @@
# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER
# This file is distributed under the same license as the PACKAGE package.
# FIRST AUTHOR <EMAIL@ADDRESS>, YEAR.
-#, fuzzy
msgid ""
msgstr ""
"Project-Id-Version: PACKAGE VERSION\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2008-06-24 00:07+0530\n"
-"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
-"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
+"PO-Revision-Date: 2008-08-28 07:53-0400\n"
+"Last-Translator: abdullah kocabas <abdullah.kocabas@abcdizustu.com>\n"
"Language-Team: LANGUAGE <LL@li.org>\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
-"X-Generator: Translate Toolkit 1.1.1rc4\n"
+"Plural-Forms: nplurals=2; plural=(n!=1);\n"
+"X-Generator: Pootle 1.1.0rc2\n"
#: ../src/sugar/activity/activity.py:120
msgid "Share with:"
-msgstr ""
+msgstr "paylaşınız."
#: ../src/sugar/activity/activity.py:122
msgid "Private"
-msgstr ""
+msgstr "özel"
#: ../src/sugar/activity/activity.py:123
msgid "My Neighborhood"
-msgstr ""
+msgstr "komşularım"
#: ../src/sugar/activity/activity.py:130
msgid "Keep"
-msgstr ""
+msgstr "kaydediniz."
#: ../src/sugar/activity/activity.py:136
msgid "Stop"
-msgstr ""
+msgstr "durdurunuz."
#: ../src/sugar/activity/activity.py:251
msgid "Undo"
-msgstr ""
+msgstr "geri alınız."
#: ../src/sugar/activity/activity.py:256
msgid "Redo"
-msgstr ""
+msgstr "yeniden yapınız."
#: ../src/sugar/activity/activity.py:266
msgid "Copy"
-msgstr ""
+msgstr "kopyalayınız."
#: ../src/sugar/activity/activity.py:271
msgid "Paste"
-msgstr ""
+msgstr "yapıştırınız."
#: ../src/sugar/activity/activity.py:297
msgid "Activity"
-msgstr ""
+msgstr "etkinlik"
#: ../src/sugar/activity/activity.py:469
#, python-format
msgid "%s Activity"
-msgstr ""
+msgstr "%s etkinlik"
#: ../src/sugar/activity/activity.py:856
msgid "Keep error"
-msgstr ""
+msgstr "hatayı saklayınız."
#: ../src/sugar/activity/activity.py:857
msgid "Keep error: all changes will be lost"
-msgstr ""
+msgstr "hata devam ediyor, tüm değişiklikleriniz silinecektir."
#: ../src/sugar/activity/activity.py:860
msgid "Don't stop"
-msgstr ""
+msgstr "durmayınız."
#: ../src/sugar/activity/activity.py:863
msgid "Stop anyway"
-msgstr ""
+msgstr "mutlaka durunuz."
#: ../src/sugar/graphics/alert.py:166 ../src/sugar/graphics/alert.py:209
msgid "Cancel"
-msgstr ""
+msgstr "iptal ediniz."
#: ../src/sugar/graphics/alert.py:170 ../src/sugar/graphics/alert.py:247
msgid "Ok"
-msgstr ""
+msgstr "tamam"
#: ../src/sugar/graphics/alert.py:219
msgid "Continue"
-msgstr ""
+msgstr "devam ediniz."
#: ../src/sugar/util.py:181
msgid " and "
-msgstr ""
+msgstr "ve"
#: ../src/sugar/util.py:182
msgid ", "
-msgstr ""
+msgstr ",_"
#. TRANS: Indicating something that just happened, eg. "just now", "moments ago"
#: ../src/sugar/util.py:185
msgid "Seconds ago"
-msgstr ""
+msgstr "saniye önce"
#. TRANS: Indicating time passed, eg. "[10 day, 5 hours] ago",
#. "[2 minutes] in the past", or "[3 years, 1 month] earlier"
#: ../src/sugar/util.py:189
#, python-format
msgid "%s ago"
-msgstr ""
+msgstr "%s önce"
#. TRANS: Relative dates (eg. 1 month and 5 days).
#: ../src/sugar/util.py:202
#, python-format
msgid "%d year"
msgid_plural "%d years"
-msgstr[0] ""
-msgstr[1] ""
+msgstr[0] "%d yıl"
+msgstr[1] "%d yıllar"
#: ../src/sugar/util.py:203
#, python-format
msgid "%d month"
msgid_plural "%d months"
-msgstr[0] ""
-msgstr[1] ""
+msgstr[0] "%d ay"
+msgstr[1] "%d aylar"
#: ../src/sugar/util.py:204
#, python-format
msgid "%d week"
msgid_plural "%d weeks"
-msgstr[0] ""
-msgstr[1] ""
+msgstr[0] "%d hafta"
+msgstr[1] "%d haftalar"
#: ../src/sugar/util.py:205
#, python-format
msgid "%d day"
msgid_plural "%d days"
-msgstr[0] ""
-msgstr[1] ""
+msgstr[0] "%d gün"
+msgstr[1] "%d günler"
#: ../src/sugar/util.py:206
#, python-format
msgid "%d hour"
msgid_plural "%d hours"
-msgstr[0] ""
-msgstr[1] ""
+msgstr[0] "%d saat"
+msgstr[1] "%d saatler"
#: ../src/sugar/util.py:207
#, python-format
msgid "%d minute"
msgid_plural "%d minutes"
-msgstr[0] ""
-msgstr[1] ""
+msgstr[0] "%d dakika"
+msgstr[1] "%d dakikalar"
+
diff --git a/po/ur.po b/po/ur.po
index 66ec1ce..12cb344 100644
--- a/po/ur.po
+++ b/po/ur.po
@@ -11,6 +11,7 @@ msgstr ""
"Last-Translator: salman minhas <sulmanminhas@gmail.com>\n"
"Language-Team: LANGUAGE <LL@li.org>\n"
"MIME-Version: 1.0\n"
+"Plural-Forms: nplurals=2; plural=(n!=1);\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"X-Generator: Pootle 1.1.0rc2\n"
diff --git a/po/vi.po b/po/vi.po
index 93a56e3..27bd52a 100644
--- a/po/vi.po
+++ b/po/vi.po
@@ -2,152 +2,147 @@
# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER
# This file is distributed under the same license as the PACKAGE package.
# FIRST AUTHOR <EMAIL@ADDRESS>, YEAR.
-#, fuzzy
msgid ""
msgstr ""
"Project-Id-Version: PACKAGE VERSION\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2008-06-24 00:07+0530\n"
-"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
-"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
+"PO-Revision-Date: 2008-07-02 08:40-0400\n"
+"Last-Translator: Clytie Siddall <clytie@riverland.net.au>\n"
"Language-Team: LANGUAGE <LL@li.org>\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
-"X-Generator: Translate Toolkit 1.1.1rc4\n"
+"Plural-Forms: nplurals=1; plural=0;\n"
+"X-Generator: Pootle 1.1.0rc2\n"
#: ../src/sugar/activity/activity.py:120
msgid "Share with:"
-msgstr ""
+msgstr "Chia sẻ với:"
#: ../src/sugar/activity/activity.py:122
msgid "Private"
-msgstr ""
+msgstr "Riêng"
#: ../src/sugar/activity/activity.py:123
msgid "My Neighborhood"
-msgstr ""
+msgstr "Hàng xóm mình"
#: ../src/sugar/activity/activity.py:130
msgid "Keep"
-msgstr ""
+msgstr "Giữ"
#: ../src/sugar/activity/activity.py:136
msgid "Stop"
-msgstr ""
+msgstr "Dừng"
#: ../src/sugar/activity/activity.py:251
msgid "Undo"
-msgstr ""
+msgstr "Hủy bước"
#: ../src/sugar/activity/activity.py:256
msgid "Redo"
-msgstr ""
+msgstr "Hoàn lại"
#: ../src/sugar/activity/activity.py:266
msgid "Copy"
-msgstr ""
+msgstr "Chép"
#: ../src/sugar/activity/activity.py:271
msgid "Paste"
-msgstr ""
+msgstr "Dán"
#: ../src/sugar/activity/activity.py:297
msgid "Activity"
-msgstr ""
+msgstr "Hoạt động"
#: ../src/sugar/activity/activity.py:469
#, python-format
msgid "%s Activity"
-msgstr ""
+msgstr "Hoạt động %s"
#: ../src/sugar/activity/activity.py:856
msgid "Keep error"
-msgstr ""
+msgstr "Giữ lỗi"
#: ../src/sugar/activity/activity.py:857
msgid "Keep error: all changes will be lost"
-msgstr ""
+msgstr "Giữ lỗi: tất cả các thay đổi sẽ bị mất"
#: ../src/sugar/activity/activity.py:860
msgid "Don't stop"
-msgstr ""
+msgstr "Không dừng"
#: ../src/sugar/activity/activity.py:863
msgid "Stop anyway"
-msgstr ""
+msgstr "Vẫn dừng"
#: ../src/sugar/graphics/alert.py:166 ../src/sugar/graphics/alert.py:209
msgid "Cancel"
-msgstr ""
+msgstr "Thôi"
#: ../src/sugar/graphics/alert.py:170 ../src/sugar/graphics/alert.py:247
msgid "Ok"
-msgstr ""
+msgstr "OK"
#: ../src/sugar/graphics/alert.py:219
msgid "Continue"
-msgstr ""
+msgstr "Tiếp"
+# Không cần từ. No word needed.
#: ../src/sugar/util.py:181
msgid " and "
-msgstr ""
+msgstr " "
#: ../src/sugar/util.py:182
msgid ", "
-msgstr ""
+msgstr ", "
#. TRANS: Indicating something that just happened, eg. "just now", "moments ago"
#: ../src/sugar/util.py:185
msgid "Seconds ago"
-msgstr ""
+msgstr "Giây trước"
#. TRANS: Indicating time passed, eg. "[10 day, 5 hours] ago",
#. "[2 minutes] in the past", or "[3 years, 1 month] earlier"
#: ../src/sugar/util.py:189
#, python-format
msgid "%s ago"
-msgstr ""
+msgstr "%s trước"
#. TRANS: Relative dates (eg. 1 month and 5 days).
#: ../src/sugar/util.py:202
#, python-format
msgid "%d year"
msgid_plural "%d years"
-msgstr[0] ""
-msgstr[1] ""
+msgstr[0] "%d năm"
#: ../src/sugar/util.py:203
#, python-format
msgid "%d month"
msgid_plural "%d months"
-msgstr[0] ""
-msgstr[1] ""
+msgstr[0] "%d tháng"
#: ../src/sugar/util.py:204
#, python-format
msgid "%d week"
msgid_plural "%d weeks"
-msgstr[0] ""
-msgstr[1] ""
+msgstr[0] "%d tuần"
#: ../src/sugar/util.py:205
#, python-format
msgid "%d day"
msgid_plural "%d days"
-msgstr[0] ""
-msgstr[1] ""
+msgstr[0] "%d ngày"
#: ../src/sugar/util.py:206
#, python-format
msgid "%d hour"
msgid_plural "%d hours"
-msgstr[0] ""
-msgstr[1] ""
+msgstr[0] "%d giờ"
#: ../src/sugar/util.py:207
#, python-format
msgid "%d minute"
msgid_plural "%d minutes"
-msgstr[0] ""
-msgstr[1] ""
+msgstr[0] "%d phút"
diff --git a/po/yo.po b/po/yo.po
index 93a56e3..75d05a8 100644
--- a/po/yo.po
+++ b/po/yo.po
@@ -12,6 +12,7 @@ msgstr ""
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
"Language-Team: LANGUAGE <LL@li.org>\n"
"MIME-Version: 1.0\n"
+"Plural-Forms: nplurals=2; plural=(n!=1);\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"X-Generator: Translate Toolkit 1.1.1rc4\n"
diff --git a/po/zh_CN.po b/po/zh_CN.po
index 93a56e3..fa67c13 100644
--- a/po/zh_CN.po
+++ b/po/zh_CN.po
@@ -12,6 +12,7 @@ msgstr ""
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
"Language-Team: LANGUAGE <LL@li.org>\n"
"MIME-Version: 1.0\n"
+"Plural-Forms: nplurals=1; plural=0;\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"X-Generator: Translate Toolkit 1.1.1rc4\n"
diff --git a/po/zh_TW.po b/po/zh_TW.po
index ab47f70..ac0c379 100644
--- a/po/zh_TW.po
+++ b/po/zh_TW.po
@@ -11,6 +11,7 @@ msgstr ""
"Last-Translator: Yuan Chao <yuanchao@gmail.com>\n"
"Language-Team: LANGUAGE <LL@li.org>\n"
"MIME-Version: 1.0\n"
+"Plural-Forms: nplurals=1; plural=0;\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"X-Generator: Pootle 1.1.0rc2\n"
diff --git a/src/sugar/Makefile.am b/src/sugar/Makefile.am
index ef91efe..ef7e634 100644
--- a/src/sugar/Makefile.am
+++ b/src/sugar/Makefile.am
@@ -14,6 +14,8 @@ pkgpyexecdir = $(pythondir)/sugar
pkgpyexec_LTLIBRARIES = _sugarext.la
_sugarext_la_CFLAGS = \
+ -DHAVE_ALSA \
+ $(WARN_CFLAGS) \
$(EXT_CFLAGS) \
$(PYTHON_INCLUDES)
@@ -23,6 +25,10 @@ _sugarext_la_LIBADD = $(EXT_LIBS) -lSM -lICE
_sugarext_la_SOURCES = \
$(BUILT_SOURCES) \
_sugarextmodule.c \
+ acme-volume.h \
+ acme-volume.c \
+ acme-volume-alsa.h \
+ acme-volume-alsa.c \
gsm-app.h \
gsm-app.c \
gsm-client.h \
@@ -45,6 +51,8 @@ _sugarext_la_SOURCES = \
sexy-icon-entry.c \
sugar-address-entry.c \
sugar-address-entry.h \
+ sugar-grid.c \
+ sugar-grid.h \
sugar-key-grabber.c \
sugar-key-grabber.h \
sugar-menu.h \
@@ -63,7 +71,6 @@ _sugarext.c: _sugarext.defs _sugarext.override
(cd $(srcdir)\
&& $(PYGTK_CODEGEN) \
--register $(PYGTK_DEFSDIR)/gdk-types.defs \
- --register $(PYGTK_DEFSDIR)/gdk-types.defs \
--register $(PYGTK_DEFSDIR)/gtk-types.defs \
--override $*.override \
--prefix py$* $*.defs) > gen-$*.c \
diff --git a/src/sugar/_sugarext.defs b/src/sugar/_sugarext.defs
index 6e741dc..32ea18a 100644
--- a/src/sugar/_sugarext.defs
+++ b/src/sugar/_sugarext.defs
@@ -22,6 +22,13 @@
(gtype-id "SUGAR_TYPE_MENU")
)
+(define-object Grid
+ (in-module "Sugar")
+ (parent "GObject")
+ (c-name "SugarGrid")
+ (gtype-id "SUGAR_TYPE_GRID")
+)
+
(define-object Preview
(in-module "Sugar")
(parent "GObject")
@@ -57,6 +64,20 @@
(gtype-id "GSM_TYPE_SESSION")
)
+(define-object Volume
+ (in-module "Acme")
+ (parent "GObject")
+ (c-name "AcmeVolume")
+ (gtype-id "ACME_TYPE_VOLUME")
+)
+
+(define-object VolumeAlsa
+ (in-module "Acme")
+ (parent "AcmeVolume")
+ (c-name "AcmeVolumeAlsa")
+ (gtype-id "ACME_TYPE_VOLUME_ALSA")
+)
+
;; Enumerations and flags ...
(define-enum IconEntryPosition
@@ -95,6 +116,45 @@
(return-type "none")
)
+;; From sugar-grid.h
+
+(define-method setup
+ (of-object "SugarGrid")
+ (c-name "sugar_grid_setup")
+ (return-type "none")
+ (parameters
+ '("gint" "width")
+ '("gint" "height")
+ )
+)
+
+(define-method add_weight
+ (of-object "SugarGrid")
+ (c-name "sugar_grid_add_weight")
+ (return-type "none")
+ (parameters
+ '("GdkRectangle*" "rect")
+ )
+)
+
+(define-method remove_weight
+ (of-object "SugarGrid")
+ (c-name "sugar_grid_remove_weight")
+ (return-type "none")
+ (parameters
+ '("GdkRectangle*" "rect")
+ )
+)
+
+(define-method compute_weight
+ (of-object "SugarGrid")
+ (c-name "sugar_grid_compute_weight")
+ (return-type "guint")
+ (parameters
+ '("GdkRectangle*" "rect")
+ )
+)
+
;; From sugar-key-grabber.h
(define-function sugar_key_grabber_get_type
@@ -200,7 +260,7 @@
(c-name "sugar_preview_take_screenshot")
(return-type "none")
(parameters
- '("GdkDrawable" "drawable")
+ '("GtkWidget" "widget")
)
)
@@ -345,3 +405,57 @@
(return-type "GsmSession*")
)
+;; From acme-volume.h
+
+(define-function acme_volume_get_type
+ (c-name "acme_volume_get_type")
+ (return-type "GType")
+)
+
+(define-method get_volume
+ (of-object "AcmeVolume")
+ (c-name "acme_volume_get_volume")
+ (return-type "int")
+)
+
+(define-method set_volume
+ (of-object "AcmeVolume")
+ (c-name "acme_volume_set_volume")
+ (return-type "none")
+ (parameters
+ '("int" "val")
+ )
+)
+
+(define-method get_mute
+ (of-object "AcmeVolume")
+ (c-name "acme_volume_get_mute")
+ (return-type "gboolean")
+)
+
+(define-method set_mute
+ (of-object "AcmeVolume")
+ (c-name "acme_volume_set_mute")
+ (return-type "none")
+ (parameters
+ '("gboolean" "val")
+ )
+)
+
+(define-method mute_toggle
+ (of-object "AcmeVolume")
+ (c-name "acme_volume_mute_toggle")
+ (return-type "none")
+)
+
+(define-method get_threshold
+ (of-object "AcmeVolume")
+ (c-name "acme_volume_get_threshold")
+ (return-type "int")
+)
+
+(define-function acme_volume_new
+ (c-name "acme_volume_new")
+ (is-constructor-of "AcmeVolume")
+ (return-type "AcmeVolume*")
+)
diff --git a/src/sugar/_sugarext.override b/src/sugar/_sugarext.override
index db49e27..5a0608d 100644
--- a/src/sugar/_sugarext.override
+++ b/src/sugar/_sugarext.override
@@ -5,13 +5,15 @@ headers
#include "pygobject.h"
#include "sugar-address-entry.h"
+#include "sugar-grid.h"
#include "sugar-key-grabber.h"
#include "sugar-menu.h"
#include "sugar-preview.h"
#include "sexy-icon-entry.h"
#include "gsm-session.h"
+#include "gsm-xsmp.h"
+#include "acme-volume-alsa.h"
-#define EGG_SM_CLIENT_BACKEND_XSMP
#include "eggsmclient.h"
#include "eggsmclient-private.h"
@@ -22,11 +24,11 @@ headers
modulename sugar._sugarext
%%
import gobject.GObject as PyGObject_Type
+import gtk.Widget as PyGtkWidget_Type
import gtk.Entry as PyGtkEntry_Type
import gtk.Menu as PyGtkMenu_Type
import gtk.Container as PyGtkContainer_Type
import gtk.gdk.Window as PyGdkWindow_Type
-import gtk.gdk.Drawable as PyGdkDrawable_Type
import gtk.Image as PyGtkImage_Type
%%
ignore-glob
diff --git a/src/sugar/_sugarextmodule.c b/src/sugar/_sugarextmodule.c
index 6f6af6d..1bb8545 100644
--- a/src/sugar/_sugarextmodule.c
+++ b/src/sugar/_sugarextmodule.c
@@ -23,6 +23,7 @@
/* include this first, before NO_IMPORT_PYGOBJECT is defined */
#include <pygobject.h>
+#include <pygtk/pygtk.h>
extern PyMethodDef py_sugarext_functions[];
@@ -34,12 +35,13 @@ init_sugarext(void)
{
PyObject *m, *d;
- init_pygobject ();
+ init_pygobject();
+ init_pygtk();
- m = Py_InitModule ("_sugarext", py_sugarext_functions);
- d = PyModule_GetDict (m);
+ m = Py_InitModule("_sugarext", py_sugarext_functions);
+ d = PyModule_GetDict(m);
- py_sugarext_register_classes (d);
+ py_sugarext_register_classes(d);
py_sugarext_add_constants(m, "SEXY_");
if (PyErr_Occurred ()) {
diff --git a/src/sugar/acme-volume-alsa.c b/src/sugar/acme-volume-alsa.c
new file mode 100644
index 0000000..c1ea5cc
--- /dev/null
+++ b/src/sugar/acme-volume-alsa.c
@@ -0,0 +1,317 @@
+/* acme-volume-alsa.c
+
+ Copyright (C) 2002, 2003 Bastien Nocera
+
+ The Gnome Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public License as
+ published by the Free Software Foundation; either version 2 of the
+ License, or (at your option) any later version.
+
+ The Gnome Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public
+ License along with the Gnome Library; see the file COPYING.LIB. If not,
+ write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ Boston, MA 02111-1307, USA.
+
+ Author: Bastien Nocera <hadess@hadess.net>
+ */
+
+#ifdef HAVE_CONFIG
+#include "config.h"
+#endif
+
+#include "acme-volume-alsa.h"
+
+#include <alsa/asoundlib.h>
+
+#ifndef DEFAULT_CARD
+#define DEFAULT_CARD "default"
+#endif
+
+#undef LOG
+#ifdef LOG
+#define D(x...) g_message (x)
+#else
+#define D(x...)
+#endif
+
+#define ROUND(x) ((x - (int)x > 0.5) ? x+1 : x)
+
+struct AcmeVolumeAlsaPrivate
+{
+ long pmin, pmax;
+ gboolean has_mute, has_master;
+ snd_mixer_t *handle;
+ snd_mixer_elem_t *elem;
+ int saved_volume;
+ guint timer_id;
+};
+
+static int acme_volume_alsa_get_volume (AcmeVolume *self);
+static void acme_volume_alsa_set_volume (AcmeVolume *self, int val);
+static gboolean acme_volume_alsa_open (AcmeVolumeAlsa *self);
+static void acme_volume_alsa_close (AcmeVolumeAlsa *self);
+static gboolean acme_volume_alsa_close_real (AcmeVolumeAlsa *self);
+
+G_DEFINE_TYPE (AcmeVolumeAlsa, acme_volume_alsa, ACME_TYPE_VOLUME)
+
+static void
+acme_volume_alsa_finalize (GObject *object)
+{
+ AcmeVolumeAlsa *self;
+
+ self = ACME_VOLUME_ALSA (object);
+
+ if (self->_priv)
+ {
+ if (self->_priv->timer_id != 0)
+ {
+ g_source_remove (self->_priv->timer_id);
+ self->_priv->timer_id = 0;
+ }
+
+ acme_volume_alsa_close_real (self);
+ g_free (self->_priv);
+ self->_priv = NULL;
+ }
+
+ G_OBJECT_CLASS (acme_volume_alsa_parent_class)->finalize (object);
+}
+
+static void
+acme_volume_alsa_set_mute (AcmeVolume *vol, gboolean val)
+{
+ AcmeVolumeAlsa *self = (AcmeVolumeAlsa *) vol;
+
+ if (acme_volume_alsa_open (self) == FALSE)
+ return;
+
+ /* If we have a hardware mute */
+ if (self->_priv->has_mute)
+ {
+ snd_mixer_selem_set_playback_switch_all
+ (self->_priv->elem, !val);
+ acme_volume_alsa_close (self);
+ return;
+ }
+
+ acme_volume_alsa_close (self);
+
+ /* If we don't */
+ if (val == TRUE)
+ {
+ self->_priv->saved_volume = acme_volume_alsa_get_volume (vol);
+ acme_volume_alsa_set_volume (vol, 0);
+ } else {
+ if (self->_priv->saved_volume != -1)
+ acme_volume_alsa_set_volume (vol,
+ self->_priv->saved_volume);
+ }
+}
+
+static gboolean
+acme_volume_alsa_get_mute (AcmeVolume *vol)
+{
+ AcmeVolumeAlsa *self = (AcmeVolumeAlsa *) vol;
+ int ival;
+
+ if (acme_volume_alsa_open (self) == FALSE)
+ return FALSE;
+
+ if (self->_priv->has_mute)
+ {
+ snd_mixer_selem_get_playback_switch(self->_priv->elem,
+ SND_MIXER_SCHN_FRONT_LEFT, &ival);
+
+ acme_volume_alsa_close (self);
+
+ return !ival;
+ } else {
+ acme_volume_alsa_close (self);
+
+ return (acme_volume_alsa_get_volume (vol) == 0);
+ }
+}
+
+static int
+acme_volume_alsa_get_volume (AcmeVolume *vol)
+{
+ AcmeVolumeAlsa *self = (AcmeVolumeAlsa *) vol;
+ long lval, rval;
+ int tmp;
+ float alsa_vol;
+
+ if (acme_volume_alsa_open (self) == FALSE)
+ return 0;
+
+ snd_mixer_selem_get_playback_volume(self->_priv->elem,
+ SND_MIXER_SCHN_FRONT_LEFT, &lval);
+ snd_mixer_selem_get_playback_volume(self->_priv->elem,
+ SND_MIXER_SCHN_FRONT_RIGHT, &rval);
+
+ acme_volume_alsa_close (self);
+
+ alsa_vol = (lval + rval) / 2;
+ alsa_vol = alsa_vol * 100 / (self->_priv->pmax - self->_priv->pmin);
+ tmp = ROUND (alsa_vol);
+
+ return tmp;
+}
+
+static void
+acme_volume_alsa_set_volume (AcmeVolume *vol, int val)
+{
+ AcmeVolumeAlsa *self = (AcmeVolumeAlsa *) vol;
+ float volume;
+ int tmp;
+
+ if (acme_volume_alsa_open (self) == FALSE)
+ return;
+
+ volume = (float) val / 100 * (self->_priv->pmax - self->_priv->pmin);
+ volume = CLAMP (volume, self->_priv->pmin, self->_priv->pmax);
+ tmp = ROUND (volume);
+
+ snd_mixer_selem_set_playback_volume_all (self->_priv->elem, tmp);
+
+ acme_volume_alsa_close (self);
+}
+
+static int
+acme_volume_alsa_get_threshold (AcmeVolume *vol)
+{
+ AcmeVolumeAlsa *self = (AcmeVolumeAlsa *) vol;
+ int steps;
+
+ if (acme_volume_alsa_open (self) == FALSE)
+ return 1;
+
+ acme_volume_alsa_close (self);
+
+ steps = self->_priv->pmax - self->_priv->pmin;
+ return (steps > 0) ? 100 / steps + 1 : 1;
+}
+
+static gboolean
+acme_volume_alsa_close_real (AcmeVolumeAlsa *self)
+{
+ if (self->_priv == NULL)
+ return FALSE;
+
+ if (self->_priv->handle != NULL)
+ {
+ snd_mixer_detach (self->_priv->handle, DEFAULT_CARD);
+ snd_mixer_free (self->_priv->handle);
+ self->_priv->handle = NULL;
+ self->_priv->elem = NULL;
+ }
+
+ self->_priv->timer_id = 0;
+
+ return FALSE;
+}
+
+static gboolean
+acme_volume_alsa_open (AcmeVolumeAlsa *self)
+{
+ snd_mixer_selem_id_t *sid;
+ snd_mixer_t *handle;
+ snd_mixer_elem_t *elem;
+
+ if (self->_priv->timer_id != 0)
+ {
+ g_source_remove (self->_priv->timer_id);
+ self->_priv->timer_id = 0;
+ return TRUE;
+ }
+
+ /* open the mixer */
+ if (snd_mixer_open (&handle, 0) < 0)
+ {
+ D("snd_mixer_open");
+ return FALSE;
+ }
+ /* attach the handle to the default card */
+ if (snd_mixer_attach (handle, DEFAULT_CARD) <0)
+ {
+ D("snd_mixer_attach");
+ goto bail;
+ }
+ /* ? */
+ if (snd_mixer_selem_register (handle, NULL, NULL) < 0)
+ {
+ D("snd_mixer_selem_register");
+ goto bail;
+ }
+ if (snd_mixer_load (handle) < 0)
+ {
+ D("snd_mixer_load");
+ goto bail;
+ }
+
+ snd_mixer_selem_id_alloca (&sid);
+ snd_mixer_selem_id_set_name (sid, "Master");
+ elem = snd_mixer_find_selem (handle, sid);
+ if (!elem)
+ {
+ snd_mixer_selem_id_alloca (&sid);
+ snd_mixer_selem_id_set_name (sid, "PCM");
+ elem = snd_mixer_find_selem (handle, sid);
+ if (!elem)
+ {
+ D("snd_mixer_find_selem");
+ goto bail;
+ }
+ }
+
+ if (!snd_mixer_selem_has_playback_volume (elem))
+ {
+ D("snd_mixer_selem_has_playback_volume");
+ goto bail;
+ }
+
+ snd_mixer_selem_get_playback_volume_range (elem,
+ &(self->_priv->pmin),
+ &(self->_priv->pmax));
+
+ self->_priv->has_mute = snd_mixer_selem_has_playback_switch (elem);
+ self->_priv->handle = handle;
+ self->_priv->elem = elem;
+
+ return TRUE;
+
+bail:
+ acme_volume_alsa_close_real (self);
+ return FALSE;
+}
+
+static void
+acme_volume_alsa_close (AcmeVolumeAlsa *self)
+{
+ self->_priv->timer_id = g_timeout_add (4000,
+ (GSourceFunc) acme_volume_alsa_close_real, self);
+}
+
+static void
+acme_volume_alsa_init (AcmeVolumeAlsa *self)
+{
+ self->_priv = g_new0 (AcmeVolumeAlsaPrivate, 1);
+}
+
+static void
+acme_volume_alsa_class_init (AcmeVolumeAlsaClass *klass)
+{
+ AcmeVolumeClass *volume_class = ACME_VOLUME_CLASS (klass);
+ G_OBJECT_CLASS (klass)->finalize = acme_volume_alsa_finalize;
+
+ volume_class->set_volume = acme_volume_alsa_set_volume;
+ volume_class->get_volume = acme_volume_alsa_get_volume;
+ volume_class->set_mute = acme_volume_alsa_set_mute;
+ volume_class->get_mute = acme_volume_alsa_get_mute;
+ volume_class->get_threshold = acme_volume_alsa_get_threshold;
+}
+
diff --git a/src/sugar/acme-volume-alsa.h b/src/sugar/acme-volume-alsa.h
new file mode 100644
index 0000000..b179a24
--- /dev/null
+++ b/src/sugar/acme-volume-alsa.h
@@ -0,0 +1,47 @@
+/* acme-volume-alsa.h
+
+ Copyright (C) 2002, 2003 Bastien Nocera
+
+ The Gnome Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public License as
+ published by the Free Software Foundation; either version 2 of the
+ License, or (at your option) any later version.
+
+ The Gnome Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public
+ License along with the Gnome Library; see the file COPYING.LIB. If not,
+ write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ Boston, MA 02111-1307, USA.
+
+ Author: Bastien Nocera <hadess@hadess.net>
+ */
+
+#include <glib.h>
+#include <glib-object.h>
+#include "acme-volume.h"
+
+#define ACME_TYPE_VOLUME_ALSA (acme_volume_alsa_get_type ())
+#define ACME_VOLUME_ALSA(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), ACME_TYPE_VOLUME_ALSA, AcmeVolumeAlsa))
+#define ACME_VOLUME_ALSA_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), ACME_TYPE_VOLUME_ALSA, AcmeVolumeAlsaClass))
+#define ACME_IS_VOLUME_ALSA(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), ACME_TYPE_VOLUME_ALSA))
+#define ACME_VOLUME_ALSA_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), ACME_TYPE_VOLUME_ALSA, AcmeVolumeAlsaClass))
+
+typedef struct AcmeVolumeAlsa AcmeVolumeAlsa;
+typedef struct AcmeVolumeAlsaClass AcmeVolumeAlsaClass;
+typedef struct AcmeVolumeAlsaPrivate AcmeVolumeAlsaPrivate;
+
+struct AcmeVolumeAlsa {
+ AcmeVolume parent;
+ AcmeVolumeAlsaPrivate *_priv;
+};
+
+struct AcmeVolumeAlsaClass {
+ AcmeVolumeClass parent;
+};
+
+GType acme_volume_alsa_get_type (void);
+
diff --git a/src/sugar/acme-volume.c b/src/sugar/acme-volume.c
new file mode 100644
index 0000000..09ae1d2
--- /dev/null
+++ b/src/sugar/acme-volume.c
@@ -0,0 +1,127 @@
+/* acme-volume.c
+
+ Copyright (C) 2002, 2003 Bastien Nocera
+
+ The Gnome Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public License as
+ published by the Free Software Foundation; either version 2 of the
+ License, or (at your option) any later version.
+
+ The Gnome Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public
+ License along with the Gnome Library; see the file COPYING.LIB. If not,
+ write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ Boston, MA 02111-1307, USA.
+
+ Author: Bastien Nocera <hadess@hadess.net>
+ */
+
+#ifdef HAVE_CONFIG
+#include "config.h"
+#endif
+#include "acme-volume.h"
+#ifdef HAVE_OSS
+#include "acme-volume-oss.h"
+#endif
+#ifdef HAVE_ALSA
+#include "acme-volume-alsa.h"
+#endif
+#ifdef HAVE_GSTREAMER
+#include "acme-volume-gstreamer.h"
+#endif
+
+G_DEFINE_TYPE (AcmeVolume, acme_volume, G_TYPE_OBJECT)
+
+static void
+acme_volume_class_init (AcmeVolumeClass *klass)
+{
+}
+
+static void
+acme_volume_init (AcmeVolume *vol)
+{
+}
+
+int
+acme_volume_get_volume (AcmeVolume *self)
+{
+ g_return_val_if_fail (self != NULL, 0);
+ g_return_val_if_fail (ACME_IS_VOLUME (self), 0);
+
+ return ACME_VOLUME_GET_CLASS (self)->get_volume (self);
+}
+
+void
+acme_volume_set_volume (AcmeVolume *self, int val)
+{
+ g_return_if_fail (self != NULL);
+ g_return_if_fail (ACME_IS_VOLUME (self));
+
+ ACME_VOLUME_GET_CLASS (self)->set_volume (self, val);
+}
+
+gboolean
+acme_volume_get_mute (AcmeVolume *self)
+{
+ g_return_val_if_fail (self != NULL, FALSE);
+ g_return_val_if_fail (ACME_IS_VOLUME (self), FALSE);
+
+ return ACME_VOLUME_GET_CLASS (self)->get_mute (self);
+}
+
+void
+acme_volume_set_mute (AcmeVolume *self, gboolean val)
+{
+ g_return_if_fail (self != NULL);
+ g_return_if_fail (ACME_IS_VOLUME (self));
+
+ ACME_VOLUME_GET_CLASS (self)->set_mute (self, val);
+}
+
+void
+acme_volume_mute_toggle (AcmeVolume *self)
+{
+ gboolean muted;
+
+ g_return_if_fail (self != NULL);
+ g_return_if_fail (ACME_IS_VOLUME (self));
+
+ muted = ACME_VOLUME_GET_CLASS (self)->get_mute (self);
+ ACME_VOLUME_GET_CLASS (self)->set_mute (self, !muted);
+}
+
+int
+acme_volume_get_threshold (AcmeVolume *self)
+{
+ g_return_val_if_fail (self != NULL, 0);
+ g_return_val_if_fail (ACME_IS_VOLUME (self), 0);
+
+ return ACME_VOLUME_GET_CLASS (self)->get_threshold (self);
+}
+
+AcmeVolume *acme_volume_new (void)
+{
+ AcmeVolume *vol;
+
+#ifdef HAVE_GSTREAMER
+ vol = ACME_VOLUME (g_object_new (acme_volume_gstreamer_get_type (), NULL));
+ return vol;
+#endif
+#ifdef HAVE_ALSA
+ vol = ACME_VOLUME (g_object_new (acme_volume_alsa_get_type (), NULL));
+ if (vol != NULL && ACME_VOLUME_ALSA (vol)->_priv != NULL)
+ return vol;
+ if (ACME_VOLUME_ALSA (vol)->_priv == NULL)
+ g_object_unref (vol);
+#endif
+#ifdef HAVE_OSS
+ vol = ACME_VOLUME (g_object_new (acme_volume_oss_get_type (), NULL));
+ return vol;
+#endif
+ return NULL;
+}
+
diff --git a/src/sugar/acme-volume.h b/src/sugar/acme-volume.h
new file mode 100644
index 0000000..ec5ee3d
--- /dev/null
+++ b/src/sugar/acme-volume.h
@@ -0,0 +1,63 @@
+/* acme-volume.h
+
+ Copyright (C) 2002, 2003 Bastien Nocera
+
+ The Gnome Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public License as
+ published by the Free Software Foundation; either version 2 of the
+ License, or (at your option) any later version.
+
+ The Gnome Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public
+ License along with the Gnome Library; see the file COPYING.LIB. If not,
+ write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ Boston, MA 02111-1307, USA.
+
+ Author: Bastien Nocera <hadess@hadess.net>
+ */
+
+#ifndef _ACME_VOLUME_H
+#define _ACME_VOLUME_H
+
+#include <glib.h>
+#include <glib-object.h>
+
+G_BEGIN_DECLS
+
+#define ACME_TYPE_VOLUME (acme_volume_get_type ())
+#define ACME_VOLUME(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), ACME_TYPE_VOLUME, AcmeVolume))
+#define ACME_VOLUME_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), ACME_TYPE_VOLUME, AcmeVolumeClass))
+#define ACME_IS_VOLUME(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), ACME_TYPE_VOLUME))
+#define ACME_VOLUME_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), ACME_TYPE_VOLUME, AcmeVolumeClass))
+
+typedef struct {
+ GObject parent;
+} AcmeVolume;
+
+typedef struct {
+ GObjectClass parent;
+
+ void (* set_volume) (AcmeVolume *self, int val);
+ int (* get_volume) (AcmeVolume *self);
+ void (* set_mute) (AcmeVolume *self, gboolean val);
+ int (* get_mute) (AcmeVolume *self);
+ int (* get_threshold) (AcmeVolume *self);
+} AcmeVolumeClass;
+
+GType acme_volume_get_type (void);
+int acme_volume_get_volume (AcmeVolume *self);
+void acme_volume_set_volume (AcmeVolume *self, int val);
+gboolean acme_volume_get_mute (AcmeVolume *self);
+void acme_volume_set_mute (AcmeVolume *self,
+ gboolean val);
+void acme_volume_mute_toggle (AcmeVolume *self);
+int acme_volume_get_threshold (AcmeVolume *self);
+AcmeVolume *acme_volume_new (void);
+
+G_END_DECLS
+
+#endif /* _ACME_VOLUME_H */
diff --git a/src/sugar/activity/Makefile.am b/src/sugar/activity/Makefile.am
index 9dfc8de..26a6782 100644
--- a/src/sugar/activity/Makefile.am
+++ b/src/sugar/activity/Makefile.am
@@ -6,4 +6,5 @@ sugar_PYTHON = \
activityhandle.py \
activityservice.py \
bundlebuilder.py \
+ main.py \
registry.py
diff --git a/src/sugar/activity/activity.py b/src/sugar/activity/activity.py
index 9784b28..6571994 100644
--- a/src/sugar/activity/activity.py
+++ b/src/sugar/activity/activity.py
@@ -104,7 +104,7 @@ class ActivityToolbar(gtk.Toolbar):
if activity.metadata:
self.title = gtk.Entry()
- self.title.set_size_request(int(gtk.gdk.screen_width() / 6), -1)
+ 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)
@@ -174,7 +174,6 @@ class ActivityToolbar(gtk.Toolbar):
self._activity.copy()
def __stop_clicked_cb(self, button):
- self._activity.take_screenshot()
self._activity.close()
def __jobject_updated_cb(self, jobject):
@@ -474,6 +473,12 @@ class Activity(Window, gtk.Container):
self.connect('realize', self.__realize_cb)
self.connect('delete-event', self.__delete_event_cb)
+ # watch visibility-notify-events to know when we can safely
+ # take a screenshot of the activity
+ self.add_events(gtk.gdk.VISIBILITY_NOTIFY_MASK)
+ self.connect('visibility-notify-event', self.__visibility_notify_event_cb)
+ self._fully_obscured = True
+
self._active = False
self._activity_id = handle.activity_id
self._pservice = presenceservice.get_instance()
@@ -728,19 +733,12 @@ class Activity(Window, gtk.Container):
pixbuf = pixbuf.scale_simple(style.zoom(300), style.zoom(225),
gtk.gdk.INTERP_BILINEAR)
- # TODO: Find a way of taking a png out of the pixbuf without saving
- # to a temp file. Impementing gtk.gdk.Pixbuf.save_to_buffer in pygtk
- # would solve this.
- fd, file_path = tempfile.mkstemp('.png')
- os.close(fd)
+ preview_data = []
+ def save_func(buf, data):
+ data.append(buf)
- pixbuf.save(file_path, 'png')
- f = open(file_path)
- try:
- preview_data = f.read()
- finally:
- f.close()
- os.remove(file_path)
+ pixbuf.save_to_callback(save_func, 'png', user_data=preview_data)
+ preview_data = ''.join(preview_data)
self._preview.clear()
@@ -758,8 +756,8 @@ class Activity(Window, gtk.Container):
return {}
def take_screenshot(self):
- if self.canvas and self.canvas.window:
- self._preview.take_screenshot(self.canvas.window)
+ if self.canvas:
+ self._preview.take_screenshot(self.canvas)
def save(self):
"""Request that the activity is saved to the Journal.
@@ -817,6 +815,8 @@ class Activity(Window, gtk.Container):
copy work that needs to be done in write_file()
"""
logging.debug('Activity.copy: %r' % self._jobject.object_id)
+ if not self._fully_obscured:
+ self.take_screenshot()
self.save()
self._jobject.object_id = None
@@ -972,6 +972,8 @@ class Activity(Window, gtk.Container):
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._fully_obscured:
+ self.take_screenshot()
if not self.can_close():
return
@@ -991,6 +993,15 @@ class Activity(Window, gtk.Container):
self.close()
return True
+ def __visibility_notify_event_cb(self, widget, event):
+ """Visibility state is used when deciding if we can take screenshots.
+ Currently we allow screenshots whenever the activity window is fully
+ visible or partially obscured."""
+ if event.state is gtk.gdk.VISIBILITY_FULLY_OBSCURED:
+ self._fully_obscured = True
+ else:
+ self._fully_obscured = False
+
def get_metadata(self):
"""Returns the jobject metadata or None if there is no jobject.
diff --git a/src/sugar/activity/activityfactory.py b/src/sugar/activity/activityfactory.py
index c9729d4..90f55cd 100644
--- a/src/sugar/activity/activityfactory.py
+++ b/src/sugar/activity/activityfactory.py
@@ -54,15 +54,18 @@ _RAINBOW_SERVICE_NAME = "org.laptop.security.Rainbow"
_RAINBOW_ACTIVITY_FACTORY_PATH = "/"
_RAINBOW_ACTIVITY_FACTORY_INTERFACE = "org.laptop.security.Rainbow"
-_children_pid = []
-
-def _sigchild_handler(signum, frame):
- for child_pid in _children_pid:
- pid, status_ = os.waitpid(child_pid, os.WNOHANG)
- if pid > 0:
- _children_pid.remove(pid)
-
-signal.signal(signal.SIGCHLD, _sigchild_handler)
+# helper method to close all filedescriptors
+# borrowed from subprocess.py
+try:
+ MAXFD = os.sysconf("SC_OPEN_MAX")
+except:
+ MAXFD = 256
+def _close_fds():
+ for i in xrange(3, MAXFD):
+ try:
+ os.close(i)
+ except:
+ pass
def create_activity_id():
"""Generate a new, unique ID for this activity"""
@@ -245,9 +248,24 @@ class ActivityCreationHandler(gobject.GObject):
self._handle.uri)
if not self._use_rainbow:
- p = subprocess.Popen(command, env=environ, cwd=activity.path,
- stdout=log_file, stderr=log_file)
- _children_pid.append(p.pid)
+ # 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(activity.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()
diff --git a/src/sugar/activity/bundlebuilder.py b/src/sugar/activity/bundlebuilder.py
index b8f87a7..baeb8b6 100644
--- a/src/sugar/activity/bundlebuilder.py
+++ b/src/sugar/activity/bundlebuilder.py
@@ -16,6 +16,7 @@
# Boston, MA 02111-1307, USA.
import os
+import sys
import zipfile
import tarfile
import shutil
@@ -29,6 +30,9 @@ 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 = []
@@ -51,7 +55,21 @@ def list_files(base_dir, ignore_dirs=None, ignore_files=None):
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()
@@ -59,14 +77,9 @@ class Config(object):
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 dist_dir:
- self.dist_dir = dist_dir
- else:
- self.dist_dir = os.path.join(self.source_dir, 'dist')
- if dist_name:
- self.xo_name = self.tar_name = dist_name
+ 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)
@@ -85,8 +98,13 @@ class Builder(object):
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'):
+ if not f.endswith('.po') or f == 'pseudo.po':
continue
file_name = os.path.join(po_dir, f)
@@ -110,15 +128,6 @@ class Builder(object):
f.write('[Activity]\nname = %s\n' % translated_name)
f.close()
-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 BuildPackager(Packager):
def get_files(self):
files = self.config.bundle.get_files()
@@ -128,28 +137,43 @@ class BuildPackager(Packager):
files = self.config.bundle.get_files()
return files
-
- def _list_useful_files(self):
- ignore_dirs = ['dist', '.git']
- ignore_files = ['.gitignore', 'MANIFEST', '*.pyc', '*~', '*.bak']
-
- return list_files(self.config.source_dir, ignore_dirs, ignore_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
- allfiles = self._list_useful_files()
- for path in allfiles:
- if path not in manifest:
- manifest.append(path)
+ 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 XOPackager(BuildPackager):
+class Packager(object):
def __init__(self, config):
- BuildPackager.__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)
@@ -157,15 +181,22 @@ class XOPackager(BuildPackager):
bundle_zip = zipfile.ZipFile(self.package_path, 'w',
zipfile.ZIP_DEFLATED)
- for f in self.get_files():
+ 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(BuildPackager):
+class SourcePackager(Packager):
def __init__(self, config):
- BuildPackager.__init__(self, config)
+ Packager.__init__(self, config)
self.package_path = os.path.join(self.config.dist_dir,
self.config.tar_name)
@@ -174,7 +205,8 @@ class SourcePackager(BuildPackager):
cwd=self.config.source_dir)
if git_ls.wait():
# Fall back to filtered list
- return self._list_useful_files()
+ return list_files(self.config.source_dir,
+ IGNORE_DIRS, IGNORE_FILES)
return [path.strip() for path in git_ls.stdout.readlines()]
@@ -185,20 +217,50 @@ class SourcePackager(BuildPackager):
os.path.join(self.config.tar_root_dir, f))
tar.close()
-def cmd_help(config, options, args):
- print 'Usage: \n\
-setup.py build - build generated files \n\
-setup.py dev - setup for development \n\
-setup.py dist_xo - create a xo bundle package \n\
-setup.py dist_source - create a tar source package \n\
-setup.py install [dirname] - install the bundle \n\
-setup.py uninstall [dirname] - uninstall the bundle \n\
-setup.py genpot - generate the gettext pot file \n\
-setup.py release - do a new release of the bundle \n\
-setup.py help - print this message \n\
-'
-
-def cmd_dev(config, options, args):
+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)
@@ -211,47 +273,57 @@ def cmd_dev(config, options, args):
else:
print 'ERROR - A bundle with the same name is already installed.'
-def cmd_dist_xo(config, options, args):
- builder = Builder(config)
- builder.build()
+def cmd_dist_xo(config, args):
+ '''Create a xo bundle package'''
- packager = XOPackager(config)
+ if args:
+ print 'Usage: %prog dist_xo'
+ return
+
+ packager = XOPackager(Builder(config))
packager.package()
-def cmd_dist(config, options, args):
- logging.warn("dist deprecated, use dist_xo.")
- cmd_dist_xo(config, options, args)
+def cmd_fix_manifest(config, args):
+ '''Add missing files to the manifest'''
-def cmd_dist_source(config, options, args):
- packager = SourcePackager(config)
- packager.package()
+ 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'''
-def cmd_install(config, options, args):
- path = args[0]
+ if args:
+ print 'Usage: %prog dist_source'
+ return
- packager = XOPackager(config)
+ packager = SourcePackager(config)
packager.package()
- root_path = os.path.join(args[0], config.bundle_root_dir)
- if os.path.isdir(root_path):
- shutil.rmtree(root_path)
+def cmd_install(config, args):
+ '''Install the activity in the system'''
- if not os.path.exists(path):
- os.mkdir(path)
+ 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
- zf = zipfile.ZipFile(packager.package_path)
+ installer = Installer(Builder(config))
+ installer.install(suboptions.prefix)
- for name in zf.namelist():
- full_path = os.path.join(path, name)
- if not os.path.exists(os.path.dirname(full_path)):
- os.makedirs(os.path.dirname(full_path))
+def cmd_genpot(config, args):
+ '''Generate the gettext pot file'''
- outfile = open(full_path, 'wb')
- outfile.write(zf.read(name))
- outfile.flush()
- outfile.close()
+ if args:
+ print 'Usage: %prog genpot'
+ return
-def cmd_genpot(config, options, args):
po_path = os.path.join(config.source_dir, 'po')
if not os.path.isdir(po_path):
os.mkdir(po_path)
@@ -283,7 +355,13 @@ def cmd_genpot(config, options, args):
if retcode:
print 'ERROR - xgettext failed with return code %i.' % retcode
-def cmd_release(config, options, args):
+def cmd_release(config, args):
+ '''Do a new release of the bundle'''
+
+ if args:
+ print 'Usage: %prog release'
+ return
+
if not os.path.isdir('.git'):
print 'ERROR - this command works only for git repositories'
return
@@ -309,6 +387,8 @@ def cmd_release(config, options, args):
f.write(info)
f.close()
+ config.update()
+
news_path = os.path.join(config.source_dir, 'NEWS')
if os.environ.has_key('SUGAR_NEWS'):
@@ -351,7 +431,7 @@ def cmd_release(config, options, args):
f.close()
print 'Creating the bundle...'
- packager = XOPackager(config)
+ packager = XOPackager(Builder(config))
packager.package()
print 'Committing to git...'
@@ -379,22 +459,40 @@ def cmd_release(config, options, args):
print 'Done.'
-def cmd_build(config, options, args):
+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()
- (options, args) = parser.parse_args()
+
+ parser = OptionParser(usage='[action] [options]')
+ parser.disable_interspersed_args()
+ (options_, args) = parser.parse_args()
config = Config()
try:
- globals()['cmd_' + args[0]](config, options, args[1:])
+ globals()['cmd_' + args[0]](config, args[1:])
except (KeyError, IndexError):
- cmd_help(config, options, args)
+ print_commands()
if __name__ == '__main__':
start()
diff --git a/src/sugar/activity/main.py b/src/sugar/activity/main.py
new file mode 100644
index 0000000..2175ff3
--- /dev/null
+++ b/src/sugar/activity/main.py
@@ -0,0 +1,137 @@
+# 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())
+
+ gettext.bindtextdomain(bundle.get_bundle_id(),
+ bundle.get_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:
+ service = 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/src/sugar/bundle/activitybundle.py b/src/sugar/bundle/activitybundle.py
index 2c235d8..2cc4da7 100644
--- a/src/sugar/bundle/activitybundle.py
+++ b/src/sugar/bundle/activitybundle.py
@@ -205,13 +205,13 @@ class ActivityBundle(Bundle):
def get_locale_path(self):
"""Get the locale path inside the (installed) activity bundle."""
- if not self._unpacked:
+ if self._zip_file is not None:
raise NotInstalledException
return os.path.join(self._path, 'locale')
def get_icons_path(self):
"""Get the icons path inside the (installed) activity bundle."""
- if not self._unpacked:
+ if self._zip_file is not None:
raise NotInstalledException
return os.path.join(self._path, 'icons')
@@ -237,7 +237,7 @@ class ActivityBundle(Bundle):
def get_icon(self):
"""Get the activity icon name"""
icon_path = os.path.join('activity', self._icon + '.svg')
- if self._unpacked:
+ if self._zip_file is None:
return os.path.join(self._path, icon_path)
else:
icon_data = self.get_file(icon_path).read()
@@ -365,7 +365,7 @@ class ActivityBundle(Bundle):
raise RegistrationException
def uninstall(self, force=False):
- if self._unpacked:
+ if self._zip_file is None:
install_path = self._path
else:
if not self.is_installed():
@@ -396,11 +396,12 @@ class ActivityBundle(Bundle):
if mime_types is not None:
installed_icons_dir = os.path.join(xdg_data_home,
'icons/sugar/scalable/mimetypes')
- for f in os.listdir(installed_icons_dir):
- path = os.path.join(installed_icons_dir, f)
- if os.path.islink(path) and \
- os.readlink(path).startswith(install_path):
- os.remove(path)
+ if os.path.isdir(installed_icons_dir):
+ for f in os.listdir(installed_icons_dir):
+ path = os.path.join(installed_icons_dir, f)
+ if os.path.islink(path) and \
+ os.readlink(path).startswith(install_path):
+ os.remove(path)
self._uninstall(install_path)
diff --git a/src/sugar/bundle/bundle.py b/src/sugar/bundle/bundle.py
index 3b12932..0319b9e 100644
--- a/src/sugar/bundle/bundle.py
+++ b/src/sugar/bundle/bundle.py
@@ -19,6 +19,7 @@
import os
import logging
+import shutil
import StringIO
import zipfile
@@ -59,9 +60,9 @@ class Bundle:
self._zip_root_dir = None
if os.path.isdir(self._path):
- self._unpacked = True
+ self._zip_file = None
else:
- self._unpacked = False
+ self._zip_file = zipfile.ZipFile(self._path)
self._check_zip_bundle()
# manifest = self._get_file(self._infodir + '/contents')
@@ -72,9 +73,12 @@ class Bundle:
# if signature is None:
# raise MalformedBundleException('No signature file')
+ def __del__(self):
+ if self._zip_file is not None:
+ self._zip_file.close()
+
def _check_zip_bundle(self):
- zip_file = zipfile.ZipFile(self._path)
- file_names = zip_file.namelist()
+ file_names = self._zip_file.namelist()
if len(file_names) == 0:
raise MalformedBundleException('Empty zip file')
@@ -99,48 +103,42 @@ class Bundle:
def get_file(self, filename):
f = None
- if self._unpacked:
+ if self._zip_file is None:
path = os.path.join(self._path, filename)
try:
f = open(path,"rb")
except IOError:
return None
else:
- zip_file = zipfile.ZipFile(self._path)
path = os.path.join(self._zip_root_dir, filename)
try:
- data = zip_file.read(path)
+ data = self._zip_file.read(path)
f = StringIO.StringIO(data)
except KeyError:
logging.debug('%s not found.' % filename)
- zip_file.close()
return f
def is_file(self, filename):
- if self._unpacked:
+ if self._zip_file is None:
path = os.path.join(self._path, filename)
return os.path.isfile(path)
else:
- zip_file = zipfile.ZipFile(self._path)
path = os.path.join(self._zip_root_dir, filename)
try:
- zip_file.getinfo(path)
+ self._zip_file.getinfo(path)
except KeyError:
return False
- finally:
- zip_file.close()
return True
def is_dir(self, filename):
- if self._unpacked:
+ if self._zip_file is None:
path = os.path.join(self._path, filename)
return os.path.isdir(path)
else:
- zip_file = zipfile.ZipFile(self._path)
path = os.path.join(self._zip_root_dir, filename, "")
- for f in zip_file.namelist():
+ for f in self._zip_file.namelist():
if f.startswith(path):
return True
return False
@@ -150,7 +148,7 @@ class Bundle:
return self._path
def _unzip(self, install_dir):
- if self._unpacked:
+ if self._zip_file is None:
raise AlreadyInstalledException
if not os.path.isdir(install_dir):
@@ -163,10 +161,13 @@ class Bundle:
# FIXME: use manifest
if os.spawnlp(os.P_WAIT, 'unzip', 'unzip', '-o', self._path,
'-x', 'mimetype', '-d', install_dir):
+ # clean up install dir after failure
+ shutil.rmtree(install_dir, ignore_errors=True)
+ # indicate failure.
raise ZipExtractException
def _zip(self, bundle_path):
- if not self._unpacked:
+ if self._zip_file is not None:
raise NotInstalledException
raise NotImplementedError
diff --git a/src/sugar/bundle/contentbundle.py b/src/sugar/bundle/contentbundle.py
index 32f38e3..09521be 100644
--- a/src/sugar/bundle/contentbundle.py
+++ b/src/sugar/bundle/contentbundle.py
@@ -194,7 +194,7 @@ class ContentBundle(Bundle):
return "file://" + urllib.pathname2url(self.get_start_path())
def is_installed(self):
- if self._unpacked:
+ if self._zip_file is None:
return True
elif os.path.isdir(self.get_root_dir()):
return True
@@ -206,7 +206,7 @@ class ContentBundle(Bundle):
self._run_indexer()
def uninstall(self):
- if self._unpacked:
+ if self._zip_file is None:
if not self.is_installed():
raise NotInstalledException
install_dir = self._path
diff --git a/src/sugar/eggsmclient-private.h b/src/sugar/eggsmclient-private.h
index 0b4ec40..d2958c9 100644
--- a/src/sugar/eggsmclient-private.h
+++ b/src/sugar/eggsmclient-private.h
@@ -25,6 +25,8 @@
G_BEGIN_DECLS
+#define EGG_SM_CLIENT_BACKEND_XSMP
+
GKeyFile *egg_sm_client_save_state (EggSMClient *client);
void egg_sm_client_quit_requested (EggSMClient *client);
void egg_sm_client_quit_cancelled (EggSMClient *client);
diff --git a/src/sugar/graphics/alert.py b/src/sugar/graphics/alert.py
index fad90bb..39c373c 100644
--- a/src/sugar/graphics/alert.py
+++ b/src/sugar/graphics/alert.py
@@ -85,7 +85,7 @@ class Alert(gtk.EventBox):
self._buttons_box.set_spacing(style.DEFAULT_SPACING)
self._hbox.pack_start(self._buttons_box)
- gtk.EventBox.__init__(self, **kwargs)
+ gobject.GObject.__init__(self, **kwargs)
self.set_visible_window(True)
self.add(self._hbox)
@@ -105,6 +105,7 @@ class Alert(gtk.EventBox):
if self._msg != value:
self._msg = value
self._msg_label.set_markup(self._msg)
+ self._msg_label.set_line_wrap(True)
elif pspec.name == 'icon':
if self._icon != value:
self._icon = value
diff --git a/src/sugar/graphics/palette.py b/src/sugar/graphics/palette.py
index 2c07389..c0a56fc 100644
--- a/src/sugar/graphics/palette.py
+++ b/src/sugar/graphics/palette.py
@@ -244,9 +244,7 @@ class Palette(gtk.Window):
self._menu_box = None
self._content = None
self._palette_popup_sid = None
- self._enter_invoker_hid = None
- self._leave_invoker_hid = None
- self._right_click_invoker_hid = None
+ self._invoker_hids = []
self.set_group_id("default")
@@ -274,8 +272,12 @@ class Palette(gtk.Window):
self._mouse_detector = MouseSpeedDetector(self, 200, 5)
self._mouse_detector.connect('motion-slow', self._mouse_slow_cb)
- def __destroy_cb(self, palette):
+ def __destroy_cb(self, palette):
self.set_group_id(None)
+
+ # Break the reference cycle. It looks like the gc is not able to free
+ # it, possibly because gtk.Menu memory handling is very special.
+ self.menu = None
if self._palette_popup_sid is not None:
_palette_observer.disconnect(self._palette_popup_sid)
@@ -312,21 +314,27 @@ class Palette(gtk.Window):
return gtk.gdk.Rectangle(x, y, width, height)
def _set_invoker(self, invoker):
- if self._invoker is not None:
- self._invoker.disconnect(self._enter_invoker_hid)
- self._invoker.disconnect(self._leave_invoker_hid)
- self._invoker.disconnect(self._right_click_invoker_hid)
+ for hid in self._invoker_hids[:]:
+ self._invoker.disconnect(hid)
+ self._invoker_hids.remove(hid)
self._invoker = invoker
if invoker is not None:
- self._enter_invoker_hid = self._invoker.connect(
- 'mouse-enter', self._invoker_mouse_enter_cb)
- self._leave_invoker_hid = self._invoker.connect(
- 'mouse-leave', self._invoker_mouse_leave_cb)
- self._right_click_invoker_hid = self._invoker.connect(
- 'right-click', self._invoker_right_click_cb)
+ self._invoker_hids.append(self._invoker.connect(
+ 'mouse-enter', self._invoker_mouse_enter_cb))
+ self._invoker_hids.append(self._invoker.connect(
+ 'mouse-leave', self._invoker_mouse_leave_cb))
+ self._invoker_hids.append(self._invoker.connect(
+ 'right-click', self._invoker_right_click_cb))
if hasattr(invoker.props, 'widget'):
- self._label.props.accel_widget = invoker.props.widget
+ self._update_accel_widget()
+ logging.debug(('Setup widget', invoker.props.widget))
+ self._invoker_hids.append(self._invoker.connect(
+ 'notify::widget', self._invoker_widget_changed_cb))
+
+ def _update_accel_widget(self):
+ assert self.props.invoker is not None
+ self._label.props.accel_widget = self.props.invoker.props.widget
def set_primary_text(self, label, accel_path=None):
self._primary_text = label
@@ -611,6 +619,9 @@ class Palette(gtk.Window):
self.popup(immediate=immediate)
+ def _invoker_widget_changed_cb(self, invoker, spec):
+ self._update_accel_widget()
+
def _invoker_mouse_enter_cb(self, invoker):
self._mouse_detector.start()
@@ -750,6 +761,9 @@ class Invoker(gobject.GObject):
def detach(self):
self.parent = None
+ if self._palette is not None:
+ self._palette.destroy()
+ self._palette = None
def _get_position_for_alignment(self, alignment, palette_dim):
palette_halign = alignment[0]
@@ -939,6 +953,8 @@ class WidgetInvoker(Invoker):
else:
self._widget = parent
+ self.notify('widget')
+
self._enter_hid = self._widget.connect('enter-notify-event',
self.__enter_notify_event_cb)
self._leave_hid = self._widget.connect('leave-notify-event',
diff --git a/src/sugar/graphics/radiotoolbutton.py b/src/sugar/graphics/radiotoolbutton.py
index abdf54c..e2636dc 100644
--- a/src/sugar/graphics/radiotoolbutton.py
+++ b/src/sugar/graphics/radiotoolbutton.py
@@ -36,6 +36,12 @@ class RadioToolButton(gtk.RadioToolButton):
self._palette_invoker.attach_tool(self)
+ self.connect('destroy', self.__destroy_cb)
+
+ def __destroy_cb(self, icon):
+ if self._palette_invoker is not None:
+ self._palette_invoker.detach()
+
def set_tooltip(self, tooltip):
""" Set a simple palette with just a single label.
"""
diff --git a/src/sugar/graphics/style.py b/src/sugar/graphics/style.py
index 1b510d1..ce2abe8 100644
--- a/src/sugar/graphics/style.py
+++ b/src/sugar/graphics/style.py
@@ -46,15 +46,6 @@ def _compute_zoom_factor():
return 1.0
-def _compute_font_height(font):
- widget = gtk.Label('')
-
- context = widget.get_pango_context()
- pango_font = context.load_font(font.get_pango_desc())
- metrics = pango_font.get_metrics()
-
- return pango.PIXELS(metrics.get_ascent() + metrics.get_descent())
-
class Font(object):
def __init__(self, desc):
self._desc = desc
@@ -124,8 +115,8 @@ XLARGE_ICON_SIZE = zoom(55 * 2.75)
FONT_SIZE = zoom(7 * _XO_DPI / _get_screen_dpi())
FONT_NORMAL = Font('Bitstream Vera Sans %d' % FONT_SIZE)
FONT_BOLD = Font('Bitstream Vera Sans bold %d' % FONT_SIZE)
-FONT_NORMAL_H = _compute_font_height(FONT_NORMAL)
-FONT_BOLD_H = _compute_font_height(FONT_BOLD)
+FONT_NORMAL_H = zoom(24)
+FONT_BOLD_H = zoom(24)
TOOLBOX_SEPARATOR_HEIGHT = zoom(9)
TOOLBOX_HORIZONTAL_PADDING = zoom(75)
diff --git a/src/sugar/graphics/toggletoolbutton.py b/src/sugar/graphics/toggletoolbutton.py
index ec622b4..35c4bf1 100644
--- a/src/sugar/graphics/toggletoolbutton.py
+++ b/src/sugar/graphics/toggletoolbutton.py
@@ -30,6 +30,12 @@ class ToggleToolButton(gtk.ToggleToolButton):
self._palette_invoker = ToolInvoker(self)
self.set_named_icon(named_icon)
+ self.connect('destroy', self.__destroy_cb)
+
+ def __destroy_cb(self, icon):
+ if self._palette_invoker is not None:
+ self._palette_invoker.detach()
+
def set_named_icon(self, named_icon):
icon = Icon(icon_name=named_icon)
self.set_icon_widget(icon)
diff --git a/src/sugar/graphics/toolbutton.py b/src/sugar/graphics/toolbutton.py
index bf392c8..a80c67a 100644
--- a/src/sugar/graphics/toolbutton.py
+++ b/src/sugar/graphics/toolbutton.py
@@ -65,6 +65,18 @@ class ToolButton(gtk.ToolButton):
self.set_icon(icon_name)
self.connect('clicked', self.__button_clicked_cb)
+ self.get_child().connect('can-activate-accel',
+ self.__button_can_activate_accel_cb)
+
+ self.connect('destroy', self.__destroy_cb)
+
+ def __destroy_cb(self, icon):
+ if self._palette_invoker is not None:
+ self._palette_invoker.detach()
+
+ def __button_can_activate_accel_cb(self, button, signal_id):
+ # Accept activation via accelerators regardless of this widget's state
+ return True
def set_tooltip(self, tooltip):
""" Set a simple palette with just a single label.
diff --git a/src/sugar/graphics/tray.py b/src/sugar/graphics/tray.py
index 8296a53..d5e9b39 100644
--- a/src/sugar/graphics/tray.py
+++ b/src/sugar/graphics/tray.py
@@ -358,6 +358,12 @@ class TrayIcon(gtk.ToolItem):
self.set_size_request(style.GRID_CELL_SIZE, style.GRID_CELL_SIZE)
+ self.connect('destroy', self.__destroy_cb)
+
+ def __destroy_cb(self, icon):
+ if self._palette_invoker is not None:
+ self._palette_invoker.detach()
+
def create_palette(self):
return None
diff --git a/src/sugar/gsm-session.c b/src/sugar/gsm-session.c
index 95dd7cb..3f0714c 100644
--- a/src/sugar/gsm-session.c
+++ b/src/sugar/gsm-session.c
@@ -151,53 +151,6 @@ end_phase (GsmSession *session)
}
static void
-app_condition_changed (GsmApp *app, gboolean condition, gpointer data)
-{
- GsmSession *session;
- GsmClient *client = NULL;
- GSList *cl = NULL;
-
- g_return_if_fail (data != NULL);
-
- session = (GsmSession *) data;
-
- /* Check for an existing session client for this app */
- for (cl = session->clients; cl; cl = cl->next)
- {
- GsmClient *c = GSM_CLIENT (cl->data);
-
- if (!strcmp (app->client_id, gsm_client_get_client_id (c)))
- client = c;
- }
-
- if (condition)
- {
- GError *error = NULL;
-
- if (app->pid <= 0 && client == NULL)
- gsm_app_launch (app, &error);
-
- if (error != NULL)
- {
- g_warning ("Not able to launch autostart app from its condition: %s",
- error->message);
-
- g_error_free (error);
- }
- }
- else
- {
- /* Kill client in case condition if false and make sure it won't
- * be automatically restarted by adding the client to
- * condition_clients */
- session->condition_clients =
- g_slist_prepend (session->condition_clients, client);
- gsm_client_die (client);
- app->pid = -1;
- }
-}
-
-static void
app_registered (GsmApp *app, gpointer data)
{
GsmSession *session = data;
@@ -241,10 +194,6 @@ phase_timeout (gpointer data)
static void
start_phase (GsmSession *session)
{
- GsmApp *app;
- GSList *a;
- GError *err = NULL;
-
g_debug ("starting phase %d\n", session->phase);
g_slist_free (session->pending_apps);
@@ -359,8 +308,6 @@ client_saved_state (GsmClient *client, gpointer data)
void
gsm_session_initiate_shutdown (GsmSession *session)
{
- gboolean logout_prompt;
-
if (session->phase == GSM_SESSION_PHASE_SHUTDOWN)
{
/* Already shutting down, nothing more to do */
diff --git a/src/sugar/gsm-session.h b/src/sugar/gsm-session.h
index 94577c9..d4880a9 100644
--- a/src/sugar/gsm-session.h
+++ b/src/sugar/gsm-session.h
@@ -73,6 +73,8 @@ typedef enum {
GSM_SESSION_LOGOUT_MODE_FORCE
} GsmSessionLogoutMode;
+GType gsm_session_get_type (void) G_GNUC_CONST;
+
void gsm_session_set_name (GsmSession *session,
const char *name);
diff --git a/src/sugar/profile.py b/src/sugar/profile.py
index 25b957e..1b08202 100644
--- a/src/sugar/profile.py
+++ b/src/sugar/profile.py
@@ -24,7 +24,7 @@ from sugar import env
from sugar import util
from sugar.graphics.xocolor import XoColor
-DEFAULT_JABBER_SERVER = 'olpc.collabora.co.uk'
+DEFAULT_JABBER_SERVER = ''
DEFAULT_VOLUME = 81
DEFAULT_TIMEZONE = 'UTC'
DEFAULT_HOT_CORNERS_DELAY = 0.0
@@ -104,7 +104,7 @@ class Profile(object):
_set_key(cp, 'Buddy', 'Color', self.color.to_string())
if self.backup1:
_set_key(cp, 'Server', 'Backup1', self.backup1)
- if self.jabber_server:
+ if self.jabber_server is not None:
_set_key(cp, 'Jabber', 'Server', self.jabber_server)
_set_key(cp, 'Date', 'Timezone', self.timezone)
diff --git a/src/sugar/sugar-grid.c b/src/sugar/sugar-grid.c
new file mode 100644
index 0000000..3fa7de5
--- /dev/null
+++ b/src/sugar/sugar-grid.c
@@ -0,0 +1,120 @@
+/*
+ * 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.
+ */
+
+#include "sugar-grid.h"
+
+static void sugar_grid_class_init (SugarGridClass *grid_class);
+static void sugar_grid_init (SugarGrid *grid);
+
+
+G_DEFINE_TYPE(SugarGrid, sugar_grid, G_TYPE_OBJECT)
+
+void
+sugar_grid_setup(SugarGrid *grid, gint width, gint height)
+{
+ g_free(grid->weights);
+
+ grid->weights = g_new0(guchar, width * height);
+ grid->width = width;
+ grid->height = height;
+}
+
+static gboolean
+check_bounds(SugarGrid *grid, GdkRectangle *rect)
+{
+ return (grid->weights != NULL &&
+ grid->width >= rect->x + rect->width &&
+ grid->height >= rect->y + rect->height);
+}
+
+void
+sugar_grid_add_weight(SugarGrid *grid, GdkRectangle *rect)
+{
+ int i, k;
+
+ if (!check_bounds(grid, rect)) {
+ g_warning("Trying to add weight outside the grid bounds.");
+ return;
+ }
+
+ for (k = rect->y; k < rect->y + rect->height; k++) {
+ for (i = rect->x; i < rect->x + rect->width; i++) {
+ grid->weights[i + k * grid->width] += 1;
+ }
+ }
+}
+
+void
+sugar_grid_remove_weight(SugarGrid *grid, GdkRectangle *rect)
+{
+ int i, k;
+
+ if (!check_bounds(grid, rect)) {
+ g_warning("Trying to remove weight outside the grid bounds.");
+ return;
+ }
+
+ for (k = rect->y; k < rect->y + rect->height; k++) {
+ for (i = rect->x; i < rect->x + rect->width; i++) {
+ grid->weights[i + k * grid->width] -= 1;
+ }
+ }
+}
+
+guint
+sugar_grid_compute_weight(SugarGrid *grid, GdkRectangle *rect)
+{
+ int i, k, sum = 0;
+
+ if (!check_bounds(grid, rect)) {
+ g_warning("Trying to compute weight outside the grid bounds.");
+ return 0;
+ }
+
+ for (k = rect->y; k < rect->y + rect->height; k++) {
+ for (i = rect->x; i < rect->x + rect->width; i++) {
+ sum += grid->weights[i + k * grid->width];
+ }
+ }
+
+ return sum;
+}
+
+static void
+sugar_grid_finalize(GObject *object)
+{
+ SugarGrid *grid = SUGAR_GRID(object);
+
+ g_free(grid->weights);
+}
+
+static void
+sugar_grid_class_init(SugarGridClass *grid_class)
+{
+ GObjectClass *gobject_class;
+
+ gobject_class = G_OBJECT_CLASS(grid_class);
+ gobject_class->finalize = sugar_grid_finalize;
+}
+
+static void
+sugar_grid_init(SugarGrid *grid)
+{
+ grid->weights = NULL;
+}
diff --git a/src/sugar/sugar-grid.h b/src/sugar/sugar-grid.h
new file mode 100644
index 0000000..d493a60
--- /dev/null
+++ b/src/sugar/sugar-grid.h
@@ -0,0 +1,63 @@
+/*
+ * 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.
+ */
+
+#ifndef __SUGAR_GRID_H__
+#define __SUGAR_GRID_H__
+
+#include <glib-object.h>
+#include <gdk/gdk.h>
+
+G_BEGIN_DECLS
+
+typedef struct _SugarGrid SugarGrid;
+typedef struct _SugarGridClass SugarGridClass;
+
+#define SUGAR_TYPE_GRID (sugar_grid_get_type())
+#define SUGAR_GRID(object) (G_TYPE_CHECK_INSTANCE_CAST((object), SUGAR_TYPE_GRID, SugarGrid))
+#define SUGAR_GRID_CLASS(klass) (G_TYPE_CHACK_CLASS_CAST((klass), SUGAR_TYPE_GRID, SugarGridClass))
+#define SUGAR_IS_GRID(object) (G_TYPE_CHECK_INSTANCE_TYPE((object), SUGAR_TYPE_GRID))
+#define SUGAR_IS_GRID_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass), SUGAR_TYPE_GRID))
+#define SUGAR_GRID_GET_CLASS(object) (G_TYPE_INSTANCE_GET_CLASS((object), SUGAR_TYPE_GRID, SugarGridClass))
+
+struct _SugarGrid {
+ GObject base_instance;
+
+ gint width;
+ gint height;
+ guchar *weights;
+};
+
+struct _SugarGridClass {
+ GObjectClass base_class;
+};
+
+GType sugar_grid_get_type (void);
+void sugar_grid_setup (SugarGrid *grid,
+ gint width,
+ gint height);
+void sugar_grid_add_weight (SugarGrid *grid,
+ GdkRectangle *rect);
+void sugar_grid_remove_weight (SugarGrid *grid,
+ GdkRectangle *rect);
+guint sugar_grid_compute_weight (SugarGrid *grid,
+ GdkRectangle *rect);
+
+G_END_DECLS
+
+#endif /* __SUGAR_GRID_H__ */
diff --git a/src/sugar/sugar-menu.h b/src/sugar/sugar-menu.h
index 8773a31..74ce891 100644
--- a/src/sugar/sugar-menu.h
+++ b/src/sugar/sugar-menu.h
@@ -50,6 +50,7 @@ void sugar_menu_set_active (SugarMenu *menu,
gboolean active);
void sugar_menu_embed (SugarMenu *menu,
GtkContainer *parent);
+void sugar_menu_unembed (SugarMenu *menu);
G_END_DECLS
diff --git a/src/sugar/sugar-preview.c b/src/sugar/sugar-preview.c
index f54045b..44b83e4 100644
--- a/src/sugar/sugar-preview.c
+++ b/src/sugar/sugar-preview.c
@@ -19,6 +19,7 @@
#include <gdk/gdkx.h>
#include <gtk/gtkwindow.h>
+#include <X11/extensions/XShm.h>
#include "sugar-preview.h"
@@ -37,8 +38,6 @@ sugar_preview_set_size(SugarPreview *preview, int width, int height)
GdkPixbuf *
sugar_preview_get_pixbuf(SugarPreview *preview)
{
- GdkPixbuf *pixbuf;
-
if (preview->pixbuf != NULL) {
return preview->pixbuf;
}
@@ -70,16 +69,38 @@ sugar_preview_clear(SugarPreview *preview)
}
}
+static gboolean
+widget_is_off_screen(GtkWidget *widget)
+{
+ GdkScreen *screen;
+ gint x, y, width, height;
+
+ screen = gtk_widget_get_screen(widget);
+
+ gdk_window_get_geometry(widget->window, &x, &y, &width, &height, NULL);
+
+ return (x < 0 || y < 0 ||
+ x + width > gdk_screen_get_width(screen) ||
+ y + height > gdk_screen_get_height(screen));
+}
+
void
-sugar_preview_take_screenshot(SugarPreview *preview, GdkDrawable *drawable)
+sugar_preview_take_screenshot(SugarPreview *preview, GtkWidget *widget)
{
+ GdkDrawable *drawable;
GdkScreen *screen;
GdkVisual *visual;
GdkColormap *colormap;
gint width, height;
+ if (widget->window == NULL || widget_is_off_screen(widget)) {
+ return;
+ }
+
sugar_preview_clear(preview);
+ drawable = GDK_DRAWABLE(widget->window);
+
gdk_drawable_get_size(drawable, &width, &height);
screen = gdk_drawable_get_screen(drawable);
@@ -92,7 +113,7 @@ sugar_preview_take_screenshot(SugarPreview *preview, GdkDrawable *drawable)
XShmGetImage(GDK_SCREEN_XDISPLAY(screen),
GDK_DRAWABLE_XID(drawable),
gdk_x11_image_get_ximage(preview->image),
- 0, 0, AllPlanes, ZPixmap);
+ 0, 0, AllPlanes);
}
static void
diff --git a/src/sugar/sugar-preview.h b/src/sugar/sugar-preview.h
index 6029cc1..70ea156 100644
--- a/src/sugar/sugar-preview.h
+++ b/src/sugar/sugar-preview.h
@@ -50,7 +50,7 @@ struct _SugarPreviewClass {
GType sugar_preview_get_type (void);
void sugar_preview_take_screenshot (SugarPreview *preview,
- GdkDrawable *drawable);
+ GtkWidget *widget);
void sugar_preview_set_size (SugarPreview *preview,
int width,
int height);
diff --git a/src/sugar/util.py b/src/sugar/util.py
index 8f81210..ad02d86 100644
--- a/src/sugar/util.py
+++ b/src/sugar/util.py
@@ -21,9 +21,11 @@ import sha
import random
import binascii
import string
-from gettext import gettext as _
import gettext
+_ = lambda msg: gettext.dgettext('sugar-toolkit', msg)
+_ngettext = lambda msg1, msg2, n: gettext.dngettext('sugar-toolkit', msg1, msg2, n)
+
def printable_hash(in_hash):
"""Convert binary hash data into printable characters."""
printable = ""
@@ -222,8 +224,8 @@ def timestamp_to_elapsed_string(timestamp, max_levels=2):
if levels > 0:
time_period += COMMA
- time_period += gettext.ngettext(name_singular, name_plural,
- elapsed_units) % elapsed_units
+ time_period += _ngettext(name_singular, name_plural,
+ elapsed_units) % elapsed_units
elapsed_seconds -= elapsed_units * factor