Web   ·   Wiki   ·   Activities   ·   Blog   ·   Lists   ·   Chat   ·   Meeting   ·   Bugs   ·   Git   ·   Translate   ·   Archive   ·   People   ·   Donate
summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSascha Silbe <silbe@activitycentral.com>2011-03-12 17:41:59 (GMT)
committer Sascha Silbe <silbe@activitycentral.com>2011-03-12 17:41:59 (GMT)
commitdce4a6b62df0fee0d221e087006395e23b7aa6d7 (patch)
treee99284fb4c9fb1ecfe5ac758cdda9a4c557674e7
parent12a8a47002d1b3f4f67c06c12a286822731fe9e3 (diff)
parentc63cc7235205633917f3b69a76cc660b2b63dddb (diff)
Merge commit 'refs/top-bases/t/bug-1608' into t/bug-1608t/bug-1608
* commit 'refs/top-bases/t/bug-1608': (103 commits) fix merge left-overs Fix up style issues introduced by commit 3f8a1e1 Don't set default timezone Restore setting a language with the command line OLPC #10681 battery frame device: replace HAL with UPower use ConsoleKit instead of HAL for shutdown/reboot fix recognition of JEBs outside of data store Adjust the year in the licence visible in the control panel Handle activities that cycle through windows dlo#10695 Speaker frame device: pop up palette on left-click instead of toggling mute recognise translations using pgettext Remove last few pieces of buddy-icon.jpg handling fix whitespace error introduced by 4b6a534 (revert of 4a3416b) Commit from Sugar Labs: Translation System by user RafaelOrtiz.: 374 of 374 messages translated (0 fuzzy). Intro: Fall back to user name if GECOS real name field is empty Sugar Ad-hoc icons show in search results when connect/disconnect to AP OLPC #10412 Show busy cursor during session shutdown Show free space for the Journal in the Journal volumes toolbar (SL#2318) Fix incorrect logging level for warning about missing GSM configuration simplify extension loading exception error ...
-rw-r--r--configure.ac4
-rw-r--r--data/sugar.schemas.in20
-rw-r--r--data/sugar.xml.in6
-rw-r--r--docs/controls.txt6
-rw-r--r--docs/release_howto.txt22
-rw-r--r--extensions/cpsection/aboutcomputer/__init__.py1
-rw-r--r--extensions/cpsection/aboutcomputer/model.py101
-rw-r--r--extensions/cpsection/aboutcomputer/view.py33
-rw-r--r--extensions/cpsection/aboutme/__init__.py2
-rw-r--r--extensions/cpsection/aboutme/model.py64
-rw-r--r--extensions/cpsection/aboutme/view.py34
-rw-r--r--extensions/cpsection/datetime/model.py26
-rw-r--r--extensions/cpsection/datetime/view.py42
-rw-r--r--extensions/cpsection/frame/model.py28
-rw-r--r--extensions/cpsection/frame/view.py76
-rw-r--r--extensions/cpsection/keyboard/__init__.py1
-rw-r--r--extensions/cpsection/keyboard/model.py20
-rw-r--r--extensions/cpsection/keyboard/view.py65
-rw-r--r--extensions/cpsection/language/__init__.py1
-rw-r--r--extensions/cpsection/language/model.py83
-rw-r--r--extensions/cpsection/language/view.py49
-rw-r--r--extensions/cpsection/modemconfiguration/__init__.py1
-rwxr-xr-xextensions/cpsection/modemconfiguration/model.py13
-rw-r--r--extensions/cpsection/modemconfiguration/view.py30
-rw-r--r--extensions/cpsection/network/__init__.py3
-rw-r--r--extensions/cpsection/network/model.py41
-rw-r--r--extensions/cpsection/network/view.py69
-rw-r--r--extensions/cpsection/power/__init__.py1
-rw-r--r--extensions/cpsection/power/model.py26
-rw-r--r--extensions/cpsection/power/view.py1
-rw-r--r--extensions/cpsection/updater/backends/aslo.py23
-rwxr-xr-xextensions/cpsection/updater/model.py28
-rw-r--r--extensions/cpsection/updater/view.py22
-rw-r--r--extensions/deviceicon/Makefile.am2
-rw-r--r--extensions/deviceicon/battery.py224
-rw-r--r--extensions/deviceicon/network.py111
-rw-r--r--extensions/deviceicon/speaker.py29
-rw-r--r--extensions/deviceicon/touchpad.py12
-rw-r--r--extensions/deviceicon/volume.py11
-rw-r--r--extensions/globalkey/screenshot.py7
-rw-r--r--extensions/globalkey/viewsource.py2
-rw-r--r--po/Makevars1
-rw-r--r--po/ar.po22
-rw-r--r--po/de.po1053
-rw-r--r--po/es.po1213
-rw-r--r--po/fr.po1074
-rw-r--r--po/it.po1053
-rw-r--r--src/jarabe/__init__.py1
-rw-r--r--src/jarabe/config.py.in2
-rw-r--r--src/jarabe/controlpanel/__init__.py1
-rw-r--r--src/jarabe/controlpanel/cmd.py39
-rw-r--r--src/jarabe/controlpanel/gui.py69
-rw-r--r--src/jarabe/controlpanel/inlinealert.py10
-rw-r--r--src/jarabe/controlpanel/sectionview.py13
-rw-r--r--src/jarabe/controlpanel/toolbar.py9
-rw-r--r--src/jarabe/desktop/__init__.py1
-rw-r--r--src/jarabe/desktop/activitieslist.py30
-rw-r--r--src/jarabe/desktop/favoriteslayout.py57
-rw-r--r--src/jarabe/desktop/favoritesview.py57
-rw-r--r--src/jarabe/desktop/friendview.py2
-rw-r--r--src/jarabe/desktop/grid.py11
-rw-r--r--src/jarabe/desktop/groupbox.py6
-rw-r--r--src/jarabe/desktop/homebox.py21
-rw-r--r--src/jarabe/desktop/homewindow.py28
-rw-r--r--src/jarabe/desktop/keydialog.py61
-rw-r--r--src/jarabe/desktop/meshbox.py77
-rw-r--r--src/jarabe/desktop/networkviews.py82
-rw-r--r--src/jarabe/desktop/schoolserver.py65
-rw-r--r--src/jarabe/desktop/snowflakelayout.py3
-rw-r--r--src/jarabe/desktop/spreadlayout.py4
-rw-r--r--src/jarabe/desktop/transitionbox.py7
-rw-r--r--src/jarabe/frame/__init__.py2
-rw-r--r--src/jarabe/frame/activitiestray.py22
-rw-r--r--src/jarabe/frame/clipboard.py20
-rw-r--r--src/jarabe/frame/clipboardicon.py8
-rw-r--r--src/jarabe/frame/clipboardmenu.py7
-rw-r--r--src/jarabe/frame/clipboardobject.py17
-rw-r--r--src/jarabe/frame/clipboardpanelwindow.py14
-rw-r--r--src/jarabe/frame/clipboardtray.py18
-rw-r--r--src/jarabe/frame/devicestray.py11
-rw-r--r--src/jarabe/frame/eventarea.py14
-rw-r--r--src/jarabe/frame/frame.py19
-rw-r--r--src/jarabe/frame/frameinvoker.py2
-rw-r--r--src/jarabe/frame/framewindow.py1
-rw-r--r--src/jarabe/frame/friendstray.py6
-rw-r--r--src/jarabe/frame/notification.py12
-rw-r--r--src/jarabe/frame/zoomtoolbar.py2
-rw-r--r--src/jarabe/intro/Makefile.am4
-rw-r--r--src/jarabe/intro/__init__.py1
-rw-r--r--src/jarabe/intro/colorpicker.py1
-rw-r--r--src/jarabe/intro/default-picture.pngbin10442 -> 0 bytes
-rw-r--r--src/jarabe/intro/window.py50
-rw-r--r--src/jarabe/journal/Makefile.am1
-rw-r--r--src/jarabe/journal/detailview.py4
-rw-r--r--src/jarabe/journal/expandedentry.py23
-rw-r--r--src/jarabe/journal/journalactivity.py34
-rw-r--r--src/jarabe/journal/journalentrybundle.py4
-rw-r--r--src/jarabe/journal/journaltoolbox.py30
-rw-r--r--src/jarabe/journal/journalwindow.py33
-rw-r--r--src/jarabe/journal/keepicon.py1
-rw-r--r--src/jarabe/journal/listmodel.py88
-rw-r--r--src/jarabe/journal/listview.py54
-rw-r--r--src/jarabe/journal/misc.py97
-rw-r--r--src/jarabe/journal/modalalert.py7
-rw-r--r--src/jarabe/journal/model.py189
-rw-r--r--src/jarabe/journal/objectchooser.py10
-rw-r--r--src/jarabe/journal/palettes.py49
-rw-r--r--src/jarabe/journal/volumestoolbar.py65
-rw-r--r--src/jarabe/model/__init__.py1
-rw-r--r--src/jarabe/model/adhoc.py12
-rw-r--r--src/jarabe/model/buddy.py10
-rw-r--r--src/jarabe/model/bundleregistry.py86
-rw-r--r--src/jarabe/model/filetransfer.py26
-rw-r--r--src/jarabe/model/friends.py22
-rw-r--r--src/jarabe/model/invites.py22
-rw-r--r--src/jarabe/model/mimeregistry.py1
-rw-r--r--src/jarabe/model/neighborhood.py154
-rw-r--r--src/jarabe/model/network.py368
-rw-r--r--src/jarabe/model/notifications.py21
-rw-r--r--src/jarabe/model/olpcmesh.py20
-rw-r--r--src/jarabe/model/screen.py6
-rw-r--r--src/jarabe/model/session.py19
-rw-r--r--src/jarabe/model/shell.py165
-rw-r--r--src/jarabe/model/sound.py11
-rw-r--r--src/jarabe/model/telepathyclient.py5
-rw-r--r--src/jarabe/util/__init__.py1
-rw-r--r--src/jarabe/util/emulator.py28
-rw-r--r--src/jarabe/util/telepathy/__init__.py1
-rw-r--r--src/jarabe/util/telepathy/connection_watcher.py12
-rw-r--r--src/jarabe/view/__init__.py1
-rw-r--r--src/jarabe/view/buddyicon.py4
-rw-r--r--src/jarabe/view/buddymenu.py21
-rw-r--r--src/jarabe/view/keyhandler.py65
-rw-r--r--src/jarabe/view/palettes.py12
-rw-r--r--src/jarabe/view/pulsingicon.py4
-rw-r--r--src/jarabe/view/service.py23
-rw-r--r--src/jarabe/view/tabbinghandler.py3
-rw-r--r--src/jarabe/view/viewsource.py30
138 files changed, 5517 insertions, 2969 deletions
diff --git a/configure.ac b/configure.ac
index 3ec6359..151eaa5 100644
--- a/configure.ac
+++ b/configure.ac
@@ -1,11 +1,11 @@
-AC_INIT([Sugar],[0.89.9],[],[sugar])
+AC_INIT([Sugar],[0.90.3],[],[sugar])
AC_PREREQ([2.59])
AC_CONFIG_MACRO_DIR([m4])
AC_CONFIG_SRCDIR([configure.ac])
-SUCROSE_VERSION="0.89.6"
+SUCROSE_VERSION="0.90.1"
AC_SUBST(SUCROSE_VERSION)
AM_INIT_AUTOMAKE([1.9 foreign dist-bzip2 no-dist-gzip])
diff --git a/data/sugar.schemas.in b/data/sugar.schemas.in
index cfa7edf..b13f746 100644
--- a/data/sugar.schemas.in
+++ b/data/sugar.schemas.in
@@ -31,9 +31,9 @@
<default></default>
<locale name="C">
<short>User Color</short>
- <long>Color for the XO icon that is used throughout the
- desktop. The string is composed of the stroke color and fill
- color, format is that of rbg colors. Example: #AC32FF,#9A5200
+ <long>Color for the XO icon that is used throughout the
+ desktop. The string is composed of the stroke color and fill
+ color, format is that of rgb colors. Example: #AC32FF,#9A5200
</long>
</locale>
</schema>
@@ -78,7 +78,7 @@
<applyto>/desktop/sugar/date/timezone</applyto>
<owner>sugar</owner>
<type>string</type>
- <default>UTC</default>
+ <default></default>
<locale name="C">
<short>Timezone</short>
<long>Timezone setting for the system.</long>
@@ -192,6 +192,18 @@
</schema>
<schema>
+ <key>/schemas/desktop/sugar/show_restart</key>
+ <applyto>/desktop/sugar/show_restart</applyto>
+ <owner>sugar</owner>
+ <type>bool</type>
+ <default>true</default>
+ <locale name="C">
+ <short>Show Restart</short>
+ <long>If TRUE, Sugar will show a "Restart" option.</long>
+ </locale>
+ </schema>
+
+ <schema>
<key>/schemas/desktop/sugar/peripherals/keyboard/layouts</key>
<applyto>/desktop/sugar/peripherals/keyboard/layouts</applyto>
<owner>sugar</owner>
diff --git a/data/sugar.xml.in b/data/sugar.xml.in
index 6a7f253..9300a45 100644
--- a/data/sugar.xml.in
+++ b/data/sugar.xml.in
@@ -8,4 +8,8 @@
<_comment>Sugar content bundle</_comment>
<glob pattern="*.xol"/>
</mime-type>
-</mime-info> \ No newline at end of file
+ <mime-type type="application/vnd.olpc-journal-entry">
+ <_comment>Sugar Journal entry bundle</_comment>
+ <glob pattern="*.xoj"/>
+ </mime-type>
+</mime-info>
diff --git a/docs/controls.txt b/docs/controls.txt
index 52591ea..fa977ef 100644
--- a/docs/controls.txt
+++ b/docs/controls.txt
@@ -52,7 +52,7 @@ sugar.ToolButton (support for rollovers)
* There is no palette but a tooltip.
* Normal: Button grey rounded filled rectangle
* Inactive: Button grey rounded stroked rectangle
-
+
sugar.ToggleIconButton
* Toggled should be like Pressed
@@ -184,10 +184,10 @@ Palettes in ToolIconButton, IconButton
* The popup will have a setPrimaryState(label, accelerator) method. For action buttons would be a MenuItem, for the others would only be a Label.
* The primary state should already have the same width as the secondary state and the expandable areas.
* Primary states appear and disappear automatically (with a short delay). A click outside makes it disappear instantly.
-* Secondary states appear after a delay, or with a single click on the icon.
+* Secondary states appear after a delay, or with a single click on the icon.
* Secondary disappears with the esc key, clicking outside the popup or clicking on a button inside.
-Toolbox
+Toolbox
* When an activity opens, the activity tab should be opened and the focus on the activity title.
* We must provide an activity tab in the toolbox and would be good to also provide an standard Edit tab.
diff --git a/docs/release_howto.txt b/docs/release_howto.txt
index db877e0..841809a 100644
--- a/docs/release_howto.txt
+++ b/docs/release_howto.txt
@@ -1,7 +1,7 @@
-''' This is the release process of the sugar tarballs sugar(shell),
+""" This is the release process of the sugar tarballs sugar(shell),
sugar-toolkit and sugar-base described in a pytish way and
instructions for sugar packagers
-'''
+"""
# Release sugar tarballs
@@ -10,9 +10,9 @@ for package in [sugar, sugar-toolkit, sugar-base, sugar-artwork]:
Pull the latest sources.
Increase the version number in configure.ac
# this will create you a tarball and does a check if it builds fine
- # e.g. it will check if all the files containing translations are
+ # e.g. it will check if all the files containing translations are
# in po/POTFILES.in
- make distcheck
+ make distcheck
if that succeed:
# commit the change, log it as "Release [version_number]" (e.g. 0.79.1)
@@ -26,7 +26,7 @@ for package in [sugar, sugar-toolkit, sugar-base, sugar-artwork]:
break
# Upload the package
- Upload the tarball to
+ Upload the tarball to
shell.sugarlabs.org:/pub/sugarlabs/sources/sucrose/glucose/$name/$name-$version
# Verify the upload of the package
@@ -34,16 +34,16 @@ for package in [sugar, sugar-toolkit, sugar-base, sugar-artwork]:
http://download.sugarlabs.org/sources/sucrose/glucose/$name/$name-$version
# Package sugar for Fedora
-# - For announcements of the Sucrose release subscribe at the sugar-devel
+# - For announcements of the Sucrose release subscribe at the sugar-devel
# mailing list; you can filter for the [ANNOUNCE] tag
-# - Uploaded tarballs can be found at:
+# - Uploaded tarballs can be found at:
# glucose: http://download.sugarlabs.org/sources/sucrose/glucose/$name/$name-$version
# fructose: http://download.sugarlabs.org/sources/sucrose/fructose/$name/$name-$version
# more about the taxonomy: http://sugarlabs.org/go/Taxonomy
-
-# more info on fedora packaging:
+
+# more info on fedora packaging:
# http://fedoraproject.org/wiki/PackageMaintainers/UpdatingPackageHowTo
-# request permissions to contribute to the fedora package:
+# request permissions to contribute to the fedora package:
# https://admin.fedoraproject.org/pkgdb/packages/name/[package]
if not cvs_package:
@@ -70,4 +70,4 @@ cvs commit -F clog
make tag
make build
-# Do the same for the other branches e.g. devel
+# Do the same for the other branches e.g. devel
diff --git a/extensions/cpsection/aboutcomputer/__init__.py b/extensions/cpsection/aboutcomputer/__init__.py
index ceb515a..faf814d 100644
--- a/extensions/cpsection/aboutcomputer/__init__.py
+++ b/extensions/cpsection/aboutcomputer/__init__.py
@@ -19,4 +19,3 @@ from gettext import gettext as _
CLASS = 'AboutComputer'
ICON = 'module-about_my_computer'
TITLE = _('About my Computer')
-
diff --git a/extensions/cpsection/aboutcomputer/model.py b/extensions/cpsection/aboutcomputer/model.py
index 898d79c..3219dd1 100644
--- a/extensions/cpsection/aboutcomputer/model.py
+++ b/extensions/cpsection/aboutcomputer/model.py
@@ -22,31 +22,45 @@ import subprocess
from gettext import gettext as _
import errno
+import dbus
+
from jarabe import config
+
+_NM_SERVICE = 'org.freedesktop.NetworkManager'
+_NM_PATH = '/org/freedesktop/NetworkManager'
+_NM_IFACE = 'org.freedesktop.NetworkManager'
+_NM_DEVICE_IFACE = 'org.freedesktop.NetworkManager.Device'
+_NM_DEVICE_TYPE_WIFI = 2
+
_logger = logging.getLogger('ControlPanel - AboutComputer')
_not_available = _('Not available')
+
def get_aboutcomputer():
msg = 'Serial Number: %s \nBuild Number: %s \nFirmware Number: %s \n' \
% (get_serial_number(), get_build_number(), get_firmware_number())
return msg
+
def print_aboutcomputer():
print get_aboutcomputer()
+
def get_serial_number():
serial_no = _read_file('/ofw/serial-number')
if serial_no is None:
serial_no = _not_available
return serial_no
-
+
+
def print_serial_number():
serial_no = get_serial_number()
if serial_no is None:
serial_no = _not_available
print serial_no
+
def get_build_number():
build_no = _read_file('/boot/olpc_build')
@@ -68,38 +82,88 @@ def get_build_number():
return build_no
+
def print_build_number():
print get_build_number()
-def get_firmware_number():
+
+def get_firmware_number():
firmware_no = _read_file('/ofw/openprom/model')
if firmware_no is None:
firmware_no = _not_available
else:
- firmware_no = re.split(" +", firmware_no)
+ firmware_no = re.split(' +', firmware_no)
if len(firmware_no) == 3:
firmware_no = firmware_no[1]
- return firmware_no
+ return firmware_no
+
-def print_firmware_number():
+def print_firmware_number():
print get_firmware_number()
-def get_wireless_firmware():
+
+def _get_wireless_interfaces():
try:
- info = subprocess.Popen(["/usr/sbin/ethtool", "-i", "eth0"],
- stdout=subprocess.PIPE).stdout.readlines()
- except OSError:
+ bus = dbus.SystemBus()
+ manager_object = bus.get_object(_NM_SERVICE, _NM_PATH)
+ network_manager = dbus.Interface(manager_object, _NM_IFACE)
+ except dbus.DBusException:
+ _logger.warning('Cannot connect to NetworkManager, falling back to'
+ ' static list of devices')
+ return ['wlan0', 'eth0']
+
+ interfaces = []
+ for device_path in network_manager.GetDevices():
+ device_object = bus.get_object(_NM_SERVICE, device_path)
+ properties = dbus.Interface(device_object,
+ 'org.freedesktop.DBus.Properties')
+ device_type = properties.Get(_NM_DEVICE_IFACE, 'DeviceType')
+ if device_type != _NM_DEVICE_TYPE_WIFI:
+ continue
+
+ interfaces.append(properties.Get(_NM_DEVICE_IFACE, 'Interface'))
+
+ return interfaces
+
+
+def get_wireless_firmware():
+ environment = os.environ.copy()
+ environment['PATH'] = '%s:/usr/sbin' % (environment['PATH'], )
+ firmware_info = {}
+ for interface in _get_wireless_interfaces():
+ try:
+ output = subprocess.Popen(['ethtool', '-i', interface],
+ stdout=subprocess.PIPE,
+ env=environment).stdout.readlines()
+ except OSError:
+ _logger.exception('Error running ethtool for %r', interface)
+ continue
+
+ try:
+ version = ([line for line in output
+ if line.startswith('firmware')][0].split()[1])
+ except IndexError:
+ _logger.exception('Error parsing ethtool output for %r',
+ interface)
+ continue
+
+ firmware_info[interface] = version
+
+ if not firmware_info:
return _not_available
- try:
- wireless_firmware = [line for line in info
- if line.startswith('firmware')][0].split()[1]
- except IndexError:
- wireless_firmware = _not_available
- return wireless_firmware
+
+ if len(firmware_info) == 1:
+ return firmware_info.values()[0]
+
+ return ', '.join([_('%(interface)s: %(version)s') %
+ {'interface': interface, 'version': version}
+ for interface, version in firmware_info.items()])
+
def print_wireless_firmware():
print get_wireless_firmware()
+
def _read_file(path):
if os.access(path, os.R_OK) == 0:
return None
@@ -114,17 +178,18 @@ def _read_file(path):
_logger.debug('No information in file or directory: %s', path)
return None
+
def get_license():
license_file = os.path.join(config.data_path, 'GPLv2')
lang = os.environ['LANG']
- if lang.endswith("UTF-8"):
+ if lang.endswith('UTF-8'):
lang = lang[:-6]
- try_file = license_file + "." + lang
+ try_file = license_file + '.' + lang
if os.path.isfile(try_file):
license_file = try_file
else:
- try_file = license_file + "." + lang.split("_")[0]
+ try_file = license_file + '.' + lang.split('_')[0]
if os.path.isfile(try_file):
license_file = try_file
diff --git a/extensions/cpsection/aboutcomputer/view.py b/extensions/cpsection/aboutcomputer/view.py
index b6ff43f..e5f2f32 100644
--- a/extensions/cpsection/aboutcomputer/view.py
+++ b/extensions/cpsection/aboutcomputer/view.py
@@ -26,6 +26,7 @@ from sugar.graphics import style
from jarabe import config
from jarabe.controlpanel.sectionview import SectionView
+
class AboutComputer(SectionView):
def __init__(self, model, alerts=None):
SectionView.__init__(self)
@@ -68,7 +69,7 @@ class AboutComputer(SectionView):
box_identity = gtk.HBox(spacing=style.DEFAULT_SPACING)
label_serial = gtk.Label(_('Serial Number:'))
label_serial.set_alignment(1, 0)
- label_serial.modify_fg(gtk.STATE_NORMAL,
+ label_serial.modify_fg(gtk.STATE_NORMAL,
style.COLOR_SELECTION_GREY.get_gdk_color())
box_identity.pack_start(label_serial, expand=False)
self._group.add_widget(label_serial)
@@ -83,7 +84,7 @@ class AboutComputer(SectionView):
self._vbox.pack_start(vbox_identity, expand=False)
vbox_identity.show()
- def _setup_software(self):
+ def _setup_software(self):
separator_software = gtk.HSeparator()
self._vbox.pack_start(separator_software, expand=False)
separator_software.show()
@@ -99,7 +100,7 @@ class AboutComputer(SectionView):
box_build = gtk.HBox(spacing=style.DEFAULT_SPACING)
label_build = gtk.Label(_('Build:'))
label_build.set_alignment(1, 0)
- label_build.modify_fg(gtk.STATE_NORMAL,
+ label_build.modify_fg(gtk.STATE_NORMAL,
style.COLOR_SELECTION_GREY.get_gdk_color())
box_build.pack_start(label_build, expand=False)
self._group.add_widget(label_build)
@@ -130,7 +131,7 @@ class AboutComputer(SectionView):
box_firmware = gtk.HBox(spacing=style.DEFAULT_SPACING)
label_firmware = gtk.Label(_('Firmware:'))
label_firmware.set_alignment(1, 0)
- label_firmware.modify_fg(gtk.STATE_NORMAL,
+ label_firmware.modify_fg(gtk.STATE_NORMAL,
style.COLOR_SELECTION_GREY.get_gdk_color())
box_firmware.pack_start(label_firmware, expand=False)
self._group.add_widget(label_firmware)
@@ -174,30 +175,30 @@ class AboutComputer(SectionView):
vbox_copyright.set_border_width(style.DEFAULT_SPACING * 2)
vbox_copyright.set_spacing(style.DEFAULT_SPACING)
- label_copyright = gtk.Label("© 2006-2010 One Laptop per Child "
- "Association Inc, Sugar Labs Inc, "
- "Red Hat Inc, Collabora Ltd "
- "and Contributors.")
+ copyright_text = '© 2006-2011 One Laptop per Child Association Inc,' \
+ ' Sugar Labs Inc, Red Hat Inc, Collabora Ltd and' \
+ ' Contributors.'
+ label_copyright = gtk.Label(copyright_text)
label_copyright.set_alignment(0, 0)
label_copyright.set_size_request(gtk.gdk.screen_width() / 2, -1)
label_copyright.set_line_wrap(True)
label_copyright.show()
vbox_copyright.pack_start(label_copyright, expand=False)
- label_info = gtk.Label(_("Sugar is the graphical user interface that "
- "you are looking at. Sugar is free software, "
- "covered by the GNU General Public License, "
- "and you are welcome to change it and/or "
- "distribute copies of it under certain "
- "conditions described therein."))
+ info_text = _('Sugar is the graphical user interface that you are'
+ ' looking at. Sugar is free software, covered by the'
+ ' GNU General Public License, and you are welcome to'
+ ' change it and/or distribute copies of it under'
+ ' certain conditions described therein.')
+ label_info = gtk.Label(info_text)
label_info.set_alignment(0, 0)
label_info.set_line_wrap(True)
label_info.set_size_request(gtk.gdk.screen_width() / 2, -1)
label_info.show()
vbox_copyright.pack_start(label_info, expand=False)
- expander = gtk.Expander(_("Full license:"))
- expander.connect("notify::expanded", self.license_expander_cb)
+ expander = gtk.Expander(_('Full license:'))
+ expander.connect('notify::expanded', self.license_expander_cb)
expander.show()
vbox_copyright.pack_start(expander, expand=True)
diff --git a/extensions/cpsection/aboutme/__init__.py b/extensions/cpsection/aboutme/__init__.py
index 98843e1..7ded428 100644
--- a/extensions/cpsection/aboutme/__init__.py
+++ b/extensions/cpsection/aboutme/__init__.py
@@ -24,5 +24,3 @@ ICON = 'module-about_me'
TITLE = _('About Me')
client = gconf.client_get_default()
COLOR = XoColor(client.get_string('/desktop/sugar/user/color'))
-
-
diff --git a/extensions/cpsection/aboutme/model.py b/extensions/cpsection/aboutme/model.py
index 8500799..fb4c2f1 100644
--- a/extensions/cpsection/aboutme/model.py
+++ b/extensions/cpsection/aboutme/model.py
@@ -18,38 +18,45 @@
from gettext import gettext as _
import gconf
-_COLORS = {'red': {'dark':'#b20008', 'medium':'#e6000a', 'light':'#ffadce'},
- 'orange': {'dark':'#9a5200', 'medium':'#c97e00', 'light':'#ffc169'},
- 'yellow': {'dark':'#807500', 'medium':'#be9e00', 'light':'#fffa00'},
- 'green': {'dark':'#008009', 'medium':'#00b20d', 'light':'#8bff7a'},
- 'blue': {'dark':'#00588c', 'medium':'#005fe4', 'light':'#bccdff'},
- 'purple': {'dark':'#5e008c', 'medium':'#7f00bf', 'light':'#d1a3ff'}
- }
+
+_COLORS = {
+ 'red': {'dark': '#b20008', 'medium': '#e6000a', 'light': '#ffadce'},
+ 'orange': {'dark': '#9a5200', 'medium': '#c97e00', 'light': '#ffc169'},
+ 'yellow': {'dark': '#807500', 'medium': '#be9e00', 'light': '#fffa00'},
+ 'green': {'dark': '#008009', 'medium': '#00b20d', 'light': '#8bff7a'},
+ 'blue': {'dark': '#00588c', 'medium': '#005fe4', 'light': '#bccdff'},
+ 'purple': {'dark': '#5e008c', 'medium': '#7f00bf', 'light': '#d1a3ff'},
+}
_MODIFIERS = ('dark', 'medium', 'light')
-
+
+
def get_nick():
client = gconf.client_get_default()
- return client.get_string("/desktop/sugar/user/nick")
+ return client.get_string('/desktop/sugar/user/nick')
+
def print_nick():
print get_nick()
-
+
+
def set_nick(nick):
"""Set the nickname.
nick : e.g. 'walter'
"""
if not nick:
- raise ValueError(_("You must enter a name."))
+ raise ValueError(_('You must enter a name.'))
if not isinstance(nick, unicode):
nick = unicode(nick, 'utf-8')
client = gconf.client_get_default()
- client.set_string("/desktop/sugar/user/nick", nick)
+ client.set_string('/desktop/sugar/user/nick', nick)
return 1
+
def get_color():
client = gconf.client_get_default()
- return client.get_string("/desktop/sugar/user/color")
+ return client.get_string('/desktop/sugar/user/color')
+
def print_color():
color_string = get_color()
@@ -64,16 +71,17 @@ def print_color():
if _COLORS[color][hue] == tmp[1]:
fill_tuple = (color, hue)
- if stroke_tuple is not None:
- print _('stroke: color=%s hue=%s') % (stroke_tuple[0],
+ if stroke_tuple is not None:
+ print _('stroke: color=%s hue=%s') % (stroke_tuple[0],
stroke_tuple[1])
else:
- print _('stroke: %s') % (tmp[0])
- if fill_tuple is not None:
+ print _('stroke: %s') % (tmp[0])
+ if fill_tuple is not None:
print _('fill: color=%s hue=%s') % (fill_tuple[0], fill_tuple[1])
else:
print _('fill: %s') % (tmp[1])
-
+
+
def set_color(stroke, fill, stroke_modifier='medium', fill_modifier='medium'):
"""Set the system color by setting a fill and stroke color.
fill : [red, orange, yellow, blue, green, purple]
@@ -81,35 +89,37 @@ def set_color(stroke, fill, stroke_modifier='medium', fill_modifier='medium'):
hue stroke : [dark, medium, light] (optional)
hue fill : [dark, medium, light] (optional)
"""
-
+
if stroke_modifier not in _MODIFIERS or fill_modifier not in _MODIFIERS:
- print (_("Error in specified color modifiers."))
+ print (_('Error in specified color modifiers.'))
return
if stroke not in _COLORS or fill not in _COLORS:
- print (_("Error in specified colors."))
+ print (_('Error in specified colors.'))
return
-
+
if stroke_modifier == fill_modifier:
if fill_modifier == 'medium':
fill_modifier = 'light'
else:
fill_modifier = 'medium'
-
+
color = _COLORS[stroke][stroke_modifier] + ',' \
+ _COLORS[fill][fill_modifier]
client = gconf.client_get_default()
- client.set_string("/desktop/sugar/user/color", color)
+ client.set_string('/desktop/sugar/user/color', color)
return 1
+
def get_color_xo():
client = gconf.client_get_default()
- return client.get_string("/desktop/sugar/user/color")
+ return client.get_string('/desktop/sugar/user/color')
+
def set_color_xo(color):
- """Set a color with an XoColor
+ """Set a color with an XoColor
This method is used by the graphical user interface
"""
client = gconf.client_get_default()
- client.set_string("/desktop/sugar/user/color", color)
+ client.set_string('/desktop/sugar/user/color', color)
return 1
diff --git a/extensions/cpsection/aboutme/view.py b/extensions/cpsection/aboutme/view.py
index 95314a1..84daec7 100644
--- a/extensions/cpsection/aboutme/view.py
+++ b/extensions/cpsection/aboutme/view.py
@@ -35,12 +35,12 @@ def _get_next_stroke_color(color):
as color. """
current_index = _get_current_index(color)
if current_index == -1:
- return "%s,%s" % (color.stroke, color.fill)
+ return '%s,%s' % (color.stroke, color.fill)
next_index = _next_index(current_index)
while(colors[next_index][_FILL_COLOR] != \
colors[current_index][_FILL_COLOR]):
next_index = _next_index(next_index)
- return "%s,%s" % (colors[next_index][_STROKE_COLOR],
+ return '%s,%s' % (colors[next_index][_STROKE_COLOR],
colors[next_index][_FILL_COLOR])
@@ -49,12 +49,12 @@ def _get_previous_stroke_color(color):
as color. """
current_index = _get_current_index(color)
if current_index == -1:
- return "%s,%s" % (color.stroke, color.fill)
+ return '%s,%s' % (color.stroke, color.fill)
previous_index = _previous_index(current_index)
while (colors[previous_index][_FILL_COLOR] != \
colors[current_index][_FILL_COLOR]):
previous_index = _previous_index(previous_index)
- return "%s,%s" % (colors[previous_index][_STROKE_COLOR],
+ return '%s,%s' % (colors[previous_index][_STROKE_COLOR],
colors[previous_index][_FILL_COLOR])
@@ -63,12 +63,12 @@ def _get_next_fill_color(color):
as color. """
current_index = _get_current_index(color)
if current_index == -1:
- return "%s,%s" % (color.stroke, color.fill)
+ return '%s,%s' % (color.stroke, color.fill)
next_index = _next_index(current_index)
while (colors[next_index][_STROKE_COLOR] != \
colors[current_index][_STROKE_COLOR]):
next_index = _next_index(next_index)
- return "%s,%s" % (colors[next_index][_STROKE_COLOR],
+ return '%s,%s' % (colors[next_index][_STROKE_COLOR],
colors[next_index][_FILL_COLOR])
@@ -77,12 +77,12 @@ def _get_previous_fill_color(color):
as color. """
current_index = _get_current_index(color)
if current_index == -1:
- return "%s,%s" % (color.stroke, color.fill)
+ return '%s,%s' % (color.stroke, color.fill)
previous_index = _previous_index(current_index)
while (colors[previous_index][_STROKE_COLOR] != \
colors[current_index][_STROKE_COLOR]):
previous_index = _previous_index(previous_index)
- return "%s,%s" % (colors[previous_index][_STROKE_COLOR],
+ return '%s,%s' % (colors[previous_index][_STROKE_COLOR],
colors[previous_index][_FILL_COLOR])
@@ -96,7 +96,7 @@ def _next_index(current_index):
def _previous_index(current_index):
previous_index = current_index - 1
if previous_index < 0:
- previous_index = len(colors)-1
+ previous_index = len(colors) - 1
return previous_index
@@ -112,7 +112,7 @@ _PREVIOUS_STROKE_COLOR = 4
class EventIcon(gtk.EventBox):
- __gtype_name__ = "SugarEventIcon"
+ __gtype_name__ = 'SugarEventIcon'
def __init__(self, **kwargs):
gtk.EventBox.__init__(self)
@@ -131,7 +131,7 @@ class ColorPicker(EventIcon):
__gsignals__ = {
'color-changed': (gobject.SIGNAL_RUN_FIRST,
gobject.TYPE_NONE,
- ([object]))
+ ([object])),
}
def __init__(self, picker):
@@ -184,12 +184,12 @@ class AboutMe(SectionView):
self._color_alert = None
self._pickers = {
- _PREVIOUS_FILL_COLOR: ColorPicker(_PREVIOUS_FILL_COLOR),
- _NEXT_FILL_COLOR: ColorPicker(_NEXT_FILL_COLOR),
- _CURRENT_COLOR: ColorPicker(_CURRENT_COLOR),
- _NEXT_STROKE_COLOR: ColorPicker(_NEXT_STROKE_COLOR),
- _PREVIOUS_STROKE_COLOR: ColorPicker(_PREVIOUS_STROKE_COLOR)
- }
+ _PREVIOUS_FILL_COLOR: ColorPicker(_PREVIOUS_FILL_COLOR),
+ _NEXT_FILL_COLOR: ColorPicker(_NEXT_FILL_COLOR),
+ _CURRENT_COLOR: ColorPicker(_CURRENT_COLOR),
+ _NEXT_STROKE_COLOR: ColorPicker(_NEXT_STROKE_COLOR),
+ _PREVIOUS_STROKE_COLOR: ColorPicker(_PREVIOUS_STROKE_COLOR),
+ }
self._setup_color()
initial_color = XoColor(self._model.get_color_xo())
diff --git a/extensions/cpsection/datetime/model.py b/extensions/cpsection/datetime/model.py
index 76064e4..84e1259 100644
--- a/extensions/cpsection/datetime/model.py
+++ b/extensions/cpsection/datetime/model.py
@@ -26,18 +26,20 @@ import gconf
_zone_tab = '/usr/share/zoneinfo/zone.tab'
+
def _initialize():
- '''Initialize the docstring of the set function'''
+ """Initialize the docstring of the set function"""
if set_timezone.__doc__ is None:
# when running under 'python -OO', all __doc__ fields are None,
# so += would fail -- and this function would be unnecessary anyway.
return
- timezones = read_all_timezones()
+ timezones = read_all_timezones()
for timezone in timezones:
- set_timezone.__doc__ += timezone + '\n'
-
+ set_timezone.__doc__ += timezone + '\n'
+
+
def read_all_timezones(fn=_zone_tab):
- fd = open (fn, 'r')
+ fd = open(fn, 'r')
lines = fd.readlines()
fd.close()
timezones = []
@@ -48,7 +50,7 @@ def read_all_timezones(fn=_zone_tab):
if len(line) > 1:
timezones.append(line[2])
timezones.sort()
-
+
for offset in xrange(-12, 13):
if offset < 0:
tz = 'GMT%d' % offset
@@ -56,7 +58,7 @@ def read_all_timezones(fn=_zone_tab):
tz = 'GMT+%d' % offset
else:
tz = 'GMT'
- timezones.append(tz)
+ timezones.append(tz)
for offset in xrange(-12, 13):
if offset < 0:
tz = 'UTC%d' % offset
@@ -64,16 +66,19 @@ def read_all_timezones(fn=_zone_tab):
tz = 'UTC+%d' % offset
else:
tz = 'UTC'
- timezones.append(tz)
+ timezones.append(tz)
return timezones
+
def get_timezone():
client = gconf.client_get_default()
return client.get_string('/desktop/sugar/date/timezone')
+
def print_timezone():
print get_timezone()
+
def set_timezone(timezone):
"""Set the system timezone
timezone : e.g. 'America/Los_Angeles'
@@ -84,9 +89,8 @@ def set_timezone(timezone):
client = gconf.client_get_default()
client.set_string('/desktop/sugar/date/timezone', timezone)
else:
- raise ValueError(_("Error timezone does not exist."))
+ raise ValueError(_('Error timezone does not exist.'))
return 1
-# inilialize the docstrings for the timezone
+# inilialize the docstrings for the timezone
_initialize()
-
diff --git a/extensions/cpsection/datetime/view.py b/extensions/cpsection/datetime/view.py
index 58719b4..1cef78f 100644
--- a/extensions/cpsection/datetime/view.py
+++ b/extensions/cpsection/datetime/view.py
@@ -24,36 +24,38 @@ from sugar.graphics import iconentry
from jarabe.controlpanel.sectionview import SectionView
from jarabe.controlpanel.inlinealert import InlineAlert
+
class TimeZone(SectionView):
def __init__(self, model, alerts):
SectionView.__init__(self)
self._model = model
self.restart_alerts = alerts
- self._zone_sid = 0
+ self._zone_sid = 0
self._cursor_change_handler = None
self.set_border_width(style.DEFAULT_SPACING * 2)
self.set_spacing(style.DEFAULT_SPACING)
- self.connect("realize", self.__realize_cb)
+ self.connect('realize', self.__realize_cb)
self._entry = iconentry.IconEntry()
self._entry.set_icon_from_name(iconentry.ICON_ENTRY_PRIMARY,
'system-search')
self._entry.add_clear_button()
- self._entry.modify_bg(gtk.STATE_INSENSITIVE,
+ self._entry.modify_bg(gtk.STATE_INSENSITIVE,
style.COLOR_WHITE.get_gdk_color())
- self._entry.modify_base(gtk.STATE_INSENSITIVE,
- style.COLOR_WHITE.get_gdk_color())
+ self._entry.modify_base(gtk.STATE_INSENSITIVE,
+ style.COLOR_WHITE.get_gdk_color())
self.pack_start(self._entry, False)
- self._entry.show()
+ self._entry.show()
self._scrolled_window = gtk.ScrolledWindow()
- self._scrolled_window.set_policy(gtk.POLICY_NEVER, gtk.POLICY_AUTOMATIC)
+ self._scrolled_window.set_policy(gtk.POLICY_NEVER,
+ gtk.POLICY_AUTOMATIC)
self._scrolled_window.set_shadow_type(gtk.SHADOW_IN)
- self._store = gtk.ListStore(gobject.TYPE_STRING)
+ self._store = gtk.ListStore(gobject.TYPE_STRING)
zones = model.read_all_timezones()
for zone in zones:
self._store.append([zone])
@@ -91,16 +93,16 @@ class TimeZone(SectionView):
zone = self._model.get_timezone()
for row in self._store:
if zone == row[0]:
- self._treeview.set_cursor(row.path, self._timezone_column,
+ self._treeview.set_cursor(row.path, self._timezone_column,
False)
- self._treeview.scroll_to_cell(row.path, self._timezone_column,
- True, 0.5, 0.5)
+ self._treeview.scroll_to_cell(row.path, self._timezone_column,
+ True, 0.5, 0.5)
break
-
- self.needs_restart = False
+
+ self.needs_restart = False
self._cursor_change_handler = self._treeview.connect( \
- "cursor-changed", self.__zone_changed_cd)
-
+ 'cursor-changed', self.__zone_changed_cd)
+
def undo(self):
self._treeview.disconnect(self._cursor_change_handler)
self._model.undo()
@@ -121,18 +123,18 @@ class TimeZone(SectionView):
return False
if self._model.get_timezone() == self._store.get_value(row, 0):
return False
-
+
if self._zone_sid:
gobject.source_remove(self._zone_sid)
- self._zone_sid = gobject.timeout_add(self._APPLY_TIMEOUT,
+ self._zone_sid = gobject.timeout_add(self._APPLY_TIMEOUT,
self.__zone_timeout_cb, row)
return True
- def __zone_timeout_cb(self, row):
- self._zone_sid = 0
+ def __zone_timeout_cb(self, row):
+ self._zone_sid = 0
self._model.set_timezone(self._store.get_value(row, 0))
self.restart_alerts.append('zone')
- self.needs_restart = True
+ self.needs_restart = True
self._zone_alert.props.msg = self.restart_msg
self._zone_alert.show()
return False
diff --git a/extensions/cpsection/frame/model.py b/extensions/cpsection/frame/model.py
index 9eea9ad..4796062 100644
--- a/extensions/cpsection/frame/model.py
+++ b/extensions/cpsection/frame/model.py
@@ -17,47 +17,53 @@
from gettext import gettext as _
import gconf
-
+
+
def get_corner_delay():
client = gconf.client_get_default()
corner_delay = client.get_int('/desktop/sugar/frame/corner_delay')
return corner_delay
+
def print_corner_delay():
print get_corner_delay()
-
+
+
def set_corner_delay(delay):
"""Set a delay for the activation of the frame using hot corners.
instantaneous: 0 (0 milliseconds)
- delay: 100 (100 milliseconds)
+ delay: 100 (100 milliseconds)
never: 1000 (disable activation)
"""
try:
int(delay)
- except ValueError:
- raise ValueError(_("Value must be an integer."))
+ except ValueError:
+ raise ValueError(_('Value must be an integer.'))
client = gconf.client_get_default()
client.set_int('/desktop/sugar/frame/corner_delay', int(delay))
return 0
-
+
+
def get_edge_delay():
client = gconf.client_get_default()
edge_delay = client.get_int('/desktop/sugar/frame/edge_delay')
return edge_delay
+
def print_edge_delay():
print get_edge_delay()
-
+
+
def set_edge_delay(delay):
- """Set a delay for the activation of the frame using warm edges.
+ """Set a delay for the activation of the frame using warm edges.
instantaneous: 0 (0 milliseconds)
- delay: 100 (100 milliseconds)
+ delay: 100 (100 milliseconds)
never: 1000 (disable activation)
"""
try:
int(delay)
- except ValueError:
- raise ValueError(_("Value must be an integer."))
+ except ValueError:
+ raise ValueError(_('Value must be an integer.'))
client = gconf.client_get_default()
client.set_int('/desktop/sugar/frame/edge_delay', int(delay))
return 0
diff --git a/extensions/cpsection/frame/view.py b/extensions/cpsection/frame/view.py
index cbe43bb..8b4ab83 100644
--- a/extensions/cpsection/frame/view.py
+++ b/extensions/cpsection/frame/view.py
@@ -23,11 +23,13 @@ from sugar.graphics import style
from jarabe.controlpanel.sectionview import SectionView
from jarabe.controlpanel.inlinealert import InlineAlert
-_never = _('never')
+
+_never = _('never')
_instantaneous = _('instantaneous')
_seconds_label = _('%s seconds')
_MAX_DELAY = 1000
+
class Frame(SectionView):
def __init__(self, model, alerts):
SectionView.__init__(self)
@@ -43,7 +45,7 @@ class Frame(SectionView):
self.set_border_width(style.DEFAULT_SPACING * 2)
self.set_spacing(style.DEFAULT_SPACING)
- self._group = gtk.SizeGroup(gtk.SIZE_GROUP_HORIZONTAL)
+ self._group = gtk.SizeGroup(gtk.SIZE_GROUP_HORIZONTAL)
separator = gtk.HSeparator()
self.pack_start(separator, expand=False)
@@ -67,25 +69,25 @@ class Frame(SectionView):
self._setup_edge()
self.pack_start(self._box_sliders, expand=False)
- self._box_sliders.show()
+ self._box_sliders.show()
self.setup()
- def _setup_corner(self):
+ def _setup_corner(self):
box_delay = gtk.HBox(spacing=style.DEFAULT_SPACING)
label_delay = gtk.Label(_('Corner'))
label_delay.set_alignment(1, 0.75)
- label_delay.modify_fg(gtk.STATE_NORMAL,
+ label_delay.modify_fg(gtk.STATE_NORMAL,
style.COLOR_SELECTION_GREY.get_gdk_color())
box_delay.pack_start(label_delay, expand=False)
self._group.add_widget(label_delay)
- label_delay.show()
-
- adj = gtk.Adjustment(value=100, lower=0, upper=_MAX_DELAY,
+ label_delay.show()
+
+ adj = gtk.Adjustment(value=100, lower=0, upper=_MAX_DELAY,
step_incr=100, page_incr=100, page_size=0)
self._corner_delay_slider = gtk.HScale(adj)
self._corner_delay_slider.set_digits(0)
- self._corner_delay_slider.connect('format-value',
+ self._corner_delay_slider.connect('format-value',
self.__corner_delay_format_cb)
box_delay.pack_start(self._corner_delay_slider)
self._corner_delay_slider.show()
@@ -105,22 +107,22 @@ class Frame(SectionView):
if 'corner_delay' in self.restart_alerts:
self._corner_delay_alert.props.msg = self.restart_msg
self._corner_delay_alert.show()
-
- def _setup_edge(self):
+
+ def _setup_edge(self):
box_delay = gtk.HBox(spacing=style.DEFAULT_SPACING)
label_delay = gtk.Label(_('Edge'))
label_delay.set_alignment(1, 0.75)
- label_delay.modify_fg(gtk.STATE_NORMAL,
+ label_delay.modify_fg(gtk.STATE_NORMAL,
style.COLOR_SELECTION_GREY.get_gdk_color())
box_delay.pack_start(label_delay, expand=False)
self._group.add_widget(label_delay)
- label_delay.show()
-
- adj = gtk.Adjustment(value=100, lower=0, upper=_MAX_DELAY,
+ label_delay.show()
+
+ adj = gtk.Adjustment(value=100, lower=0, upper=_MAX_DELAY,
step_incr=100, page_incr=100, page_size=0)
self._edge_delay_slider = gtk.HScale(adj)
self._edge_delay_slider.set_digits(0)
- self._edge_delay_slider.connect('format-value',
+ self._edge_delay_slider.connect('format-value',
self.__edge_delay_format_cb)
box_delay.pack_start(self._edge_delay_slider)
self._edge_delay_slider.show()
@@ -140,24 +142,24 @@ class Frame(SectionView):
if 'edge_delay' in self.restart_alerts:
self._edge_delay_alert.props.msg = self.restart_msg
self._edge_delay_alert.show()
-
+
def setup(self):
self._corner_delay_slider.set_value(self._model.get_corner_delay())
self._edge_delay_slider.set_value(self._model.get_edge_delay())
self._corner_delay_is_valid = True
self._edge_delay_is_valid = True
self.needs_restart = False
- self._corner_delay_change_handler = self._corner_delay_slider.connect( \
+ self._corner_delay_change_handler = self._corner_delay_slider.connect(
'value-changed', self.__corner_delay_changed_cb)
- self._edge_delay_change_handler = self._edge_delay_slider.connect( \
+ self._edge_delay_change_handler = self._edge_delay_slider.connect(
'value-changed', self.__edge_delay_changed_cb)
-
- def undo(self):
+
+ def undo(self):
self._corner_delay_slider.disconnect(self._corner_delay_change_handler)
self._edge_delay_slider.disconnect(self._edge_delay_change_handler)
self._model.undo()
- self._corner_delay_alert.hide()
- self._edge_delay_alert.hide()
+ self._corner_delay_alert.hide()
+ self._edge_delay_alert.hide()
def _validate(self):
if self._edge_delay_is_valid and self._corner_delay_is_valid:
@@ -165,15 +167,15 @@ class Frame(SectionView):
else:
self.props.is_valid = False
- def __corner_delay_changed_cb(self, scale, data=None):
+ def __corner_delay_changed_cb(self, scale, data=None):
if self._corner_delay_sid:
gobject.source_remove(self._corner_delay_sid)
self._corner_delay_sid = gobject.timeout_add( \
self._APPLY_TIMEOUT, self.__corner_delay_timeout_cb, scale)
-
- def __corner_delay_timeout_cb(self, scale):
+
+ def __corner_delay_timeout_cb(self, scale):
self._corner_delay_sid = 0
- if scale.get_value() == self._model.get_corner_delay():
+ if scale.get_value() == self._model.get_corner_delay():
return
try:
self._model.set_corner_delay(scale.get_value())
@@ -182,12 +184,12 @@ class Frame(SectionView):
self._corner_delay_is_valid = False
else:
self._corner_delay_alert.props.msg = self.restart_msg
- self._corner_delay_is_valid = True
+ self._corner_delay_is_valid = True
self.needs_restart = True
self.restart_alerts.append('corner_delay')
-
+
self._validate()
- self._corner_delay_alert.show()
+ self._corner_delay_alert.show()
return False
def __corner_delay_format_cb(self, scale, value):
@@ -198,15 +200,15 @@ class Frame(SectionView):
else:
return _seconds_label % (value / _MAX_DELAY)
- def __edge_delay_changed_cb(self, scale, data=None):
+ def __edge_delay_changed_cb(self, scale, data=None):
if self._edge_delay_sid:
gobject.source_remove(self._edge_delay_sid)
self._edge_delay_sid = gobject.timeout_add( \
self._APPLY_TIMEOUT, self.__edge_delay_timeout_cb, scale)
-
- def __edge_delay_timeout_cb(self, scale):
+
+ def __edge_delay_timeout_cb(self, scale):
self._edge_delay_sid = 0
- if scale.get_value() == self._model.get_edge_delay():
+ if scale.get_value() == self._model.get_edge_delay():
return
try:
self._model.set_edge_delay(scale.get_value())
@@ -215,12 +217,12 @@ class Frame(SectionView):
self._edge_delay_is_valid = False
else:
self._edge_delay_alert.props.msg = self.restart_msg
- self._edge_delay_is_valid = True
+ self._edge_delay_is_valid = True
self.needs_restart = True
self.restart_alerts.append('edge_delay')
-
+
self._validate()
- self._edge_delay_alert.show()
+ self._edge_delay_alert.show()
return False
def __edge_delay_format_cb(self, scale, value):
diff --git a/extensions/cpsection/keyboard/__init__.py b/extensions/cpsection/keyboard/__init__.py
index 568e7a5..065086c 100644
--- a/extensions/cpsection/keyboard/__init__.py
+++ b/extensions/cpsection/keyboard/__init__.py
@@ -19,4 +19,3 @@ from gettext import gettext as _
CLASS = 'Keyboard'
ICON = 'module-keyboard'
TITLE = _('Keyboard')
-
diff --git a/extensions/cpsection/keyboard/model.py b/extensions/cpsection/keyboard/model.py
index 089c2ea..1f92973 100644
--- a/extensions/cpsection/keyboard/model.py
+++ b/extensions/cpsection/keyboard/model.py
@@ -20,12 +20,13 @@ import xklavier
import gconf
-_GROUP_NAME = 'grp' # The XKB name for group switch options
+_GROUP_NAME = 'grp' # The XKB name for group switch options
_LAYOUTS_KEY = '/desktop/sugar/peripherals/keyboard/layouts'
_OPTIONS_KEY = '/desktop/sugar/peripherals/keyboard/options'
_MODEL_KEY = '/desktop/sugar/peripherals/keyboard/model'
+
class KeyboardManager(object):
def __init__(self, display):
self._engine = xklavier.Engine(display)
@@ -33,7 +34,7 @@ class KeyboardManager(object):
self._configregistry.load(False)
self._configrec = xklavier.ConfigRec()
self._configrec.get_from_server(self._engine)
-
+
self._gconf_client = gconf.client_get_default()
def _populate_one(self, config_registry, item, store):
@@ -48,7 +49,7 @@ class KeyboardManager(object):
else:
description = 'Default layout, %s' % item.get_description()
variant = ''
-
+
store.append([description, ('%s(%s)' % (layout, variant))])
def get_models(self):
@@ -76,8 +77,8 @@ class KeyboardManager(object):
def get_options_group(self):
"""Return list of supported options for switching keyboard group"""
options = []
- self._configregistry.foreach_option(_GROUP_NAME, self._populate_one, \
- options)
+ self._configregistry.foreach_option(_GROUP_NAME, self._populate_one,
+ options)
options.sort()
return options
@@ -96,7 +97,7 @@ class KeyboardManager(object):
layouts = self._gconf_client.get_list(_LAYOUTS_KEY, gconf.VALUE_STRING)
if layouts:
return layouts
-
+
layouts = self._configrec.get_layouts()
variants = self._configrec.get_variants()
@@ -126,7 +127,7 @@ class KeyboardManager(object):
return option
return None
-
+
def get_max_layouts(self):
"""Return the maximum number of layouts supported simultaneously"""
return self._engine.get_max_num_groups()
@@ -162,8 +163,7 @@ class KeyboardManager(object):
for layout in layouts:
layouts_list.append(layout.split('(')[0])
variants_list.append(layout.split('(')[1][:-1])
-
+
self._configrec.set_layouts(layouts_list)
self._configrec.set_variants(variants_list)
- self._configrec.activate(self._engine)
-
+ self._configrec.activate(self._engine)
diff --git a/extensions/cpsection/keyboard/view.py b/extensions/cpsection/keyboard/view.py
index dd62a85..e349255 100644
--- a/extensions/cpsection/keyboard/view.py
+++ b/extensions/cpsection/keyboard/view.py
@@ -26,6 +26,7 @@ from sugar.graphics.icon import Icon
from jarabe.controlpanel.sectionview import SectionView
+
CLASS = 'Language'
ICON = 'module-keyboard'
TITLE = _('Keyboard')
@@ -37,6 +38,7 @@ _APPLY_TIMEOUT = 500
# once python-xklavier has been packaged for all major distributions
# For more information, see: http://dev.sugarlabs.org/ticket/407
+
class LayoutCombo(gtk.HBox):
"""
@@ -45,8 +47,8 @@ class LayoutCombo(gtk.HBox):
"""
__gsignals__ = {
- 'selection-changed' : (gobject.SIGNAL_RUN_LAST, gobject.TYPE_NONE,
- (gobject.TYPE_STRING, gobject.TYPE_INT))
+ 'selection-changed': (gobject.SIGNAL_RUN_LAST, gobject.TYPE_NONE,
+ (gobject.TYPE_STRING, gobject.TYPE_INT)),
}
def __init__(self, keyboard_manager, n):
@@ -57,7 +59,7 @@ class LayoutCombo(gtk.HBox):
self.set_border_width(style.DEFAULT_SPACING)
self.set_spacing(style.DEFAULT_SPACING)
- label = gtk.Label(' <b>%s</b> ' % str(n+1))
+ label = gtk.Label(' <b>%s</b> ' % str(n + 1))
label.set_use_markup(True)
label.modify_fg(gtk.STATE_NORMAL,
style.COLOR_SELECTION_GREY.get_gdk_color())
@@ -69,7 +71,7 @@ class LayoutCombo(gtk.HBox):
for description, name in self._keyboard_manager.get_languages():
self._klang_store.append([name, description])
- self._klang_combo = gtk.ComboBox(model = self._klang_store)
+ self._klang_combo = gtk.ComboBox(model=self._klang_store)
self._klang_combo_changed_id = \
self._klang_combo.connect('changed', self._klang_combo_changed_cb)
cell = gtk.CellRendererText()
@@ -77,10 +79,10 @@ class LayoutCombo(gtk.HBox):
cell.props.ellipsize_set = True
self._klang_combo.pack_start(cell)
self._klang_combo.add_attribute(cell, 'text', 1)
- self.pack_start(self._klang_combo, expand=True, fill = True)
+ self.pack_start(self._klang_combo, expand=True, fill=True)
self._kvariant_store = None
- self._kvariant_combo = gtk.ComboBox(model = None)
+ self._kvariant_combo = gtk.ComboBox(model=None)
self._kvariant_combo_changed_id = \
self._kvariant_combo.connect('changed', \
self._kvariant_combo_changed_cb)
@@ -89,7 +91,7 @@ class LayoutCombo(gtk.HBox):
cell.props.ellipsize_set = True
self._kvariant_combo.pack_start(cell)
self._kvariant_combo.add_attribute(cell, 'text', 1)
- self.pack_start(self._kvariant_combo, expand=True, fill = True)
+ self.pack_start(self._kvariant_combo, expand=True, fill=True)
self._klang_combo.set_active(self._index)
@@ -129,7 +131,7 @@ class LayoutCombo(gtk.HBox):
model = combobox.get_model()
lang = model.get(it, 0)[0]
self._set_kvariant_store(lang)
-
+
def _kvariant_combo_changed_cb(self, combobox):
it = combobox.get_active_iter()
model = combobox.get_model()
@@ -145,18 +147,17 @@ class Keyboard(SectionView):
self._kmodel = None
self._selected_kmodel = None
-
+
self._klayouts = []
self._selected_klayouts = []
-
+
self._group_switch_option = None
self._selected_group_switch_option = None
self.set_border_width(style.DEFAULT_SPACING * 2)
self.set_spacing(style.DEFAULT_SPACING)
-
- self._layout_table = gtk.Table(rows = 4, columns = 2, \
- homogeneous = False)
+
+ self._layout_table = gtk.Table(rows=4, columns=2, homogeneous=False)
self._keyboard_manager = model.KeyboardManager(self.get_display())
self._layout_combo_list = []
@@ -169,7 +170,7 @@ class Keyboard(SectionView):
self._vbox = gtk.VBox()
scrollwindow.add_with_viewport(self._vbox)
-
+
self.__kmodel_sid = None
self.__layout_sid = None
self.__group_switch_sid = None
@@ -177,7 +178,7 @@ class Keyboard(SectionView):
self._setup_kmodel()
self._setup_layouts()
self._setup_group_switch_option()
-
+
self._vbox.show()
def _setup_kmodel(self):
@@ -200,7 +201,7 @@ class Keyboard(SectionView):
for description, name in self._keyboard_manager.get_models():
kmodel_store.append([name, description])
- kmodel_combo = gtk.ComboBox(model = kmodel_store)
+ kmodel_combo = gtk.ComboBox(model=kmodel_store)
cell = gtk.CellRendererText()
cell.props.ellipsize = pango.ELLIPSIZE_MIDDLE
cell.props.ellipsize_set = True
@@ -214,7 +215,7 @@ class Keyboard(SectionView):
kmodel_combo.set_active_iter(row.iter)
break
- box_kmodel.pack_start(kmodel_combo, expand = False)
+ box_kmodel.pack_start(kmodel_combo, expand=False)
self._vbox.pack_start(box_kmodel, expand=False)
box_kmodel.show_all()
@@ -223,7 +224,7 @@ class Keyboard(SectionView):
def __kmodel_changed_cb(self, combobox):
if self.__kmodel_sid is not None:
gobject.source_remove(self.__kmodel_sid)
- self.__kmodel_sid = gobject.timeout_add(_APPLY_TIMEOUT,
+ self.__kmodel_sid = gobject.timeout_add(_APPLY_TIMEOUT,
self.__kmodel_timeout_cb, combobox)
def __kmodel_timeout_cb(self, combobox):
@@ -240,7 +241,8 @@ class Keyboard(SectionView):
return False
def _setup_group_switch_option(self):
- """Adds the controls for changing the group switch option of keyboard"""
+ """Adds the controls for changing the group switch option of keyboard
+ """
separator_group_option = gtk.HSeparator()
self._vbox.pack_start(separator_group_option, expand=False)
separator_group_option.show_all()
@@ -259,7 +261,7 @@ class Keyboard(SectionView):
for description, name in self._keyboard_manager.get_options_group():
group_option_store.append([name, description])
- group_option_combo = gtk.ComboBox(model = group_option_store)
+ group_option_combo = gtk.ComboBox(model=group_option_store)
cell = gtk.CellRendererText()
cell.props.ellipsize = pango.ELLIPSIZE_MIDDLE
cell.props.ellipsize_set = True
@@ -280,7 +282,7 @@ class Keyboard(SectionView):
if not found:
group_option_combo.set_active(0)
- box_group_option.pack_start(group_option_combo, expand = False)
+ box_group_option.pack_start(group_option_combo, expand=False)
self._vbox.pack_start(box_group_option, expand=False)
box_group_option.show_all()
@@ -290,7 +292,7 @@ class Keyboard(SectionView):
def __group_switch_changed_cb(self, combobox):
if self.__group_switch_sid is not None:
gobject.source_remove(self.__group_switch_sid)
- self.__group_switch_sid = gobject.timeout_add(_APPLY_TIMEOUT,
+ self.__group_switch_sid = gobject.timeout_add(_APPLY_TIMEOUT,
self.__group_switch_timeout_cb, combobox)
def __group_switch_timeout_cb(self, combobox):
@@ -306,7 +308,6 @@ class Keyboard(SectionView):
except Exception:
logging.exception('Could not set new keyboard group switch option')
-
return False
def _setup_layouts(self):
@@ -324,18 +325,18 @@ class Keyboard(SectionView):
for i in range(0, self._keyboard_manager.get_max_layouts()):
add_remove_box = self.__create_add_remove_box()
self._layout_addremovebox_list.append(add_remove_box)
- self._layout_table.attach(add_remove_box, 1, 2, i, i+1)
+ self._layout_table.attach(add_remove_box, 1, 2, i, i + 1)
layout_combo = LayoutCombo(self._keyboard_manager, i)
layout_combo.connect('selection-changed', \
self.__layout_combo_selection_changed_cb)
self._layout_combo_list.append(layout_combo)
- self._layout_table.attach(layout_combo, 0, 1, i, i+1)
+ self._layout_table.attach(layout_combo, 0, 1, i, i + 1)
if i < len(self._klayouts):
layout_combo.show_all()
layout_combo.select_layout(self._klayouts[i])
-
+
self._vbox.pack_start(self._layout_table, expand=False)
self._layout_table.set_size_request(self._vbox.size_request()[0], -1)
self._layout_table.show()
@@ -359,15 +360,15 @@ class Keyboard(SectionView):
i += 1
def __create_add_remove_box(self):
- '''Creates gtk.Hbox with add/remove buttons'''
- add_icon = Icon(icon_name='list-add')
+ """Creates gtk.Hbox with add/remove buttons"""
+ add_icon = Icon(icon_name='list-add')
add_button = gtk.Button()
add_button.set_image(add_icon)
add_button.connect('clicked',
self.__add_button_clicked_cb)
- remove_icon = Icon(icon_name='list-remove')
+ remove_icon = Icon(icon_name='list-remove')
remove_button = gtk.Button()
remove_button.set_image(remove_icon)
remove_button.connect('clicked',
@@ -387,7 +388,7 @@ class Keyboard(SectionView):
def __add_button_clicked_cb(self, button):
self._layout_combo_list[len(self._selected_klayouts)].show_all()
self._update_klayouts()
-
+
def __remove_button_clicked_cb(self, button):
self._layout_combo_list[len(self._selected_klayouts) - 1].hide()
self._update_klayouts()
@@ -403,7 +404,7 @@ class Keyboard(SectionView):
if self.__layout_sid is not None:
gobject.source_remove(self.__layout_sid)
- self.__layout_sid = gobject.timeout_add(_APPLY_TIMEOUT,
+ self.__layout_sid = gobject.timeout_add(_APPLY_TIMEOUT,
self.__layout_timeout_cb)
def __layout_timeout_cb(self):
@@ -417,10 +418,8 @@ class Keyboard(SectionView):
return False
-
def undo(self):
"""Reverts back to the original keyboard configuration"""
self._keyboard_manager.set_model(self._kmodel)
self._keyboard_manager.set_layouts(self._klayouts)
self._keyboard_manager.set_option_group(self._group_switch_option)
-
diff --git a/extensions/cpsection/language/__init__.py b/extensions/cpsection/language/__init__.py
index a8f9f08..c93b7d1 100644
--- a/extensions/cpsection/language/__init__.py
+++ b/extensions/cpsection/language/__init__.py
@@ -19,4 +19,3 @@ from gettext import gettext as _
CLASS = 'Language'
ICON = 'module-language'
TITLE = _('Language')
-
diff --git a/extensions/cpsection/language/model.py b/extensions/cpsection/language/model.py
index 4f3686f..240e562 100644
--- a/extensions/cpsection/language/model.py
+++ b/extensions/cpsection/language/model.py
@@ -25,8 +25,10 @@ import locale
from gettext import gettext as _
import subprocess
+
_default_lang = '%s.%s' % locale.getdefaultlocale()
-_standard_msg = _("Could not access ~/.i18n. Create standard settings.")
+_standard_msg = _('Could not access ~/.i18n. Create standard settings.')
+
def read_all_languages():
fdp = subprocess.Popen(['locale', '-av'], stdout=subprocess.PIPE)
@@ -43,7 +45,7 @@ def read_all_languages():
if locale.endswith('utf8') and len(lang):
locales.append((lang, territory, locale))
- #FIXME: This is a temporary workaround for locales that are essential to
+ #FIXME: This is a temporary workaround for locales that are essential to
# OLPC, but are not in Glibc yet.
locales.append(('Kreyol', 'Haiti', 'ht_HT.utf8'))
locales.append(('Dari', 'Afghanistan', 'fa_AF.utf8'))
@@ -52,7 +54,8 @@ def read_all_languages():
locales.sort()
return locales
-def _initialize():
+
+def _initialize():
if set_languages.__doc__ is None:
# when running under 'python -OO', all __doc__ fields are None,
# so += would fail -- and this function would be unnecessary anyway.
@@ -60,13 +63,12 @@ def _initialize():
languages = read_all_languages()
set_languages.__doc__ += '\n'
for lang in languages:
- set_languages.__doc__ += '%s \n' % (lang[0].replace(' ', '_') + '/' +
+ set_languages.__doc__ += '%s \n' % (lang[0].replace(' ', '_') + '/' +
lang[1].replace(' ', '_'))
-
-def _write_i18n(langs):
- colon = ':'
- langstr = colon.join(langs)
- path = os.path.join(os.environ.get("HOME"), '.i18n')
+
+
+def _write_i18n(lang_env, language_env):
+ path = os.path.join(os.environ.get('HOME'), '.i18n')
if not os.access(path, os.W_OK):
print _standard_msg
fd = open(path, 'w')
@@ -75,32 +77,33 @@ def _write_i18n(langs):
fd.close()
else:
fd = open(path, 'w')
- fd.write('LANG="%s"\n' % langs[0].strip("\n"))
- fd.write('LANGUAGE="%s"\n' % langstr)
+ fd.write('LANG="%s"\n' % lang_env)
+ fd.write('LANGUAGE="%s"\n' % language_env)
fd.close()
+
def get_languages():
- path = os.path.join(os.environ.get("HOME"), '.i18n')
+ path = os.path.join(os.environ.get('HOME', ''), '.i18n')
if not os.access(path, os.R_OK):
- print _standard_msg
+ print _standard_msg
fd = open(path, 'w')
fd.write('LANG="%s"\n' % _default_lang)
fd.write('LANGUAGE="%s"\n' % _default_lang)
fd.close()
return [_default_lang]
-
- fd = open(path, "r")
+
+ fd = open(path, 'r')
lines = fd.readlines()
fd.close()
langlist = None
for line in lines:
- if line.startswith("LANGUAGE="):
+ if line.startswith('LANGUAGE='):
lang = line[9:].replace('"', '')
lang = lang.strip()
langlist = lang.split(':')
- elif line.startswith("LANG="):
+ elif line.startswith('LANG='):
lang = line[5:].replace('"', '')
# There might be cases where .i18n may not contain a LANGUAGE field
@@ -109,6 +112,7 @@ def get_languages():
else:
return langlist
+
def print_languages():
codes = get_languages()
@@ -122,30 +126,35 @@ def print_languages():
found_lang = True
break
if not found_lang:
- print (_("Language for code=%s could not be determined.") % code)
-
+ print (_('Language for code=%s could not be determined.') % code)
+
+
def set_languages(languages):
"""Set the system language.
- languages :
+ languages :
"""
- if isinstance(languages, str):
- # This came from the commandline
- #TODO: Support multiple languages from the command line
- if languages.endswith('utf8'):
- _write_i18n(languages)
- return 1
- else:
- langs = read_all_languages()
- for lang, territory, locale in langs:
- code = lang.replace(' ', '_') + '/' \
- + territory.replace(' ', '_')
- if code == languages:
- _write_i18n(locale)
- return 1
- print (_("Sorry I do not speak \'%s\'.") % languages)
+
+ if languages.endswith('utf8'):
+ set_languages_list([languages])
+ return 1
else:
- _write_i18n(languages)
+ langs = read_all_languages()
+ for lang, territory, locale in langs:
+ code = lang.replace(' ', '_') + '/' \
+ + territory.replace(' ', '_')
+ if code == languages:
+ set_languages_list([locale])
+ return 1
+ print (_("Sorry I do not speak \'%s\'.") % languages)
+
+
+def set_languages_list(languages):
+ """Set the system language using a list of preferred languages"""
+ colon = ':'
+ language_env = colon.join(languages)
+ lang_env = languages[0].strip('\n')
+ _write_i18n(lang_env, language_env)
+
# inilialize the docstrings for the language
_initialize()
-
diff --git a/extensions/cpsection/language/view.py b/extensions/cpsection/language/view.py
index d1a49cf..1553959 100644
--- a/extensions/cpsection/language/view.py
+++ b/extensions/cpsection/language/view.py
@@ -25,13 +25,14 @@ from sugar.graphics.icon import Icon
from jarabe.controlpanel.sectionview import SectionView
from jarabe.controlpanel.inlinealert import InlineAlert
-_translate_language = lambda msg: gettext.dgettext('iso_639', msg)
+_translate_language = lambda msg: gettext.dgettext('iso_639', msg)
_translate_country = lambda msg: gettext.dgettext('iso_3166', msg)
CLASS = 'Language'
ICON = 'module-language'
TITLE = gettext.gettext('Language')
+
class Language(SectionView):
def __init__(self, model, alerts):
SectionView.__init__(self)
@@ -53,9 +54,9 @@ class Language(SectionView):
self.set_border_width(style.DEFAULT_SPACING * 2)
self.set_spacing(style.DEFAULT_SPACING)
- explanation = gettext.gettext("Add languages in the order you prefer." \
- " If a translation is not available,"\
- " the next in the list will be used.")
+ explanation = gettext.gettext('Add languages in the order you prefer.'
+ ' If a translation is not available,'
+ ' the next in the list will be used.')
self._text = gtk.Label(explanation)
self._text.set_width_chars(100)
self._text.set_line_wrap(True)
@@ -69,14 +70,14 @@ class Language(SectionView):
self.pack_start(scrolled, expand=True)
self._table = gtk.Table(rows=1, columns=3, homogeneous=False)
- self._table.set_border_width(style.DEFAULT_SPACING * 2)
+ self._table.set_border_width(style.DEFAULT_SPACING * 2)
self._table.show()
scrolled.add_with_viewport(self._table)
self._lang_alert_box = gtk.HBox(spacing=style.DEFAULT_SPACING)
self.pack_start(self._lang_alert_box, False)
- self._lang_alert = InlineAlert()
+ self._lang_alert = InlineAlert()
self._lang_alert_box.pack_start(self._lang_alert)
if 'lang' in self.restart_alerts:
self._lang_alert.props.msg = self.restart_msg
@@ -86,10 +87,10 @@ class Language(SectionView):
self.setup()
def _add_row(self, locale_code=None):
- '''Adds a row to the table'''
+ """Adds a row to the table"""
self._selected_lang_count += 1
-
+
self._table.resize(self._selected_lang_count, 3)
label = gtk.Label(str=str(self._selected_lang_count))
@@ -98,8 +99,7 @@ class Language(SectionView):
self._labels.append(label)
self._attach_to_table(label, 0, 1, padding=1)
label.show()
-
-
+
store = gtk.ListStore(gobject.TYPE_STRING, gobject.TYPE_STRING)
for language, country, code in self._available_locales:
description = '%s (%s)' % (_translate_language(language), \
@@ -115,7 +115,7 @@ class Language(SectionView):
for row in store:
lang = locale_code.split('.')[0]
lang_column = row[0].split('.')[0]
- if lang in lang_column:
+ if lang in lang_column:
combobox.set_active_iter(row.iter)
break
else:
@@ -132,7 +132,7 @@ class Language(SectionView):
self._attach_to_table(add_remove_box, 2, 3)
add_remove_box.show_all()
-
+
if self._selected_lang_count > 1:
previous_add_removes = self._add_remove_boxes[-2]
previous_add_removes.hide_all()
@@ -149,12 +149,12 @@ class Language(SectionView):
ypadding=padding)
def _delete_last_row(self):
- '''Deletes the last row of the table'''
+ """Deletes the last row of the table"""
self._selected_lang_count -= 1
label, add_remove_box, combobox, store_ = self._get_last_row()
-
+
label.destroy()
add_remove_box.destroy()
combobox.destroy()
@@ -180,15 +180,15 @@ class Language(SectionView):
self._lang_alert.hide()
def _create_add_remove_box(self):
- '''Creates gtk.Hbox with add/remove buttons'''
- add_icon = Icon(icon_name='list-add')
+ """Creates gtk.Hbox with add/remove buttons"""
+ add_icon = Icon(icon_name='list-add')
add_button = gtk.Button()
add_button.set_image(add_icon)
add_button.connect('clicked',
self.__add_button_clicked_cb)
- remove_icon = Icon(icon_name='list-remove')
+ remove_icon = Icon(icon_name='list-remove')
remove_button = gtk.Button()
remove_button.set_image(remove_icon)
remove_button.connect('clicked',
@@ -217,8 +217,8 @@ class Language(SectionView):
selected_langs = self._get_selected_langs()
last_lang = selected_langs[-1]
- self._determine_add_remove_visibility(last_lang = last_lang)
-
+ self._determine_add_remove_visibility(last_lang=last_lang)
+
self._changed = (selected_langs != self._selected_locales)
if self._changed == False:
@@ -245,10 +245,10 @@ class Language(SectionView):
model = combobox.get_model()
lang_code = model.get(it, 0)[0]
new_codes.append(lang_code)
-
+
return new_codes
- def _determine_add_remove_visibility(self, last_lang = None):
+ def _determine_add_remove_visibility(self, last_lang=None):
# We should not let users add fallback languages for English (USA)
# This is because the software is not usually _translated_ into English
# which means that the fallback gets selected automatically
@@ -256,11 +256,11 @@ class Language(SectionView):
if last_lang is None:
selected_langs = self._get_selected_langs()
last_lang = selected_langs[-1]
-
+
add_remove_box = self._add_remove_boxes[-1]
buttons = add_remove_box.get_children()
add_button, remove_button = buttons
-
+
if last_lang.startswith('en_US'):
add_button.props.visible = False
else:
@@ -271,10 +271,9 @@ class Language(SectionView):
else:
remove_button.props.visible = True
-
def __lang_timeout_cb(self, codes):
self._lang_sid = 0
- self._model.set_languages(codes)
+ self._model.set_languages_list(codes)
self.restart_alerts.append('lang')
self.needs_restart = True
self._lang_alert.props.msg = self.restart_msg
diff --git a/extensions/cpsection/modemconfiguration/__init__.py b/extensions/cpsection/modemconfiguration/__init__.py
index 8a219dc..61f5904 100644
--- a/extensions/cpsection/modemconfiguration/__init__.py
+++ b/extensions/cpsection/modemconfiguration/__init__.py
@@ -19,4 +19,3 @@ from gettext import gettext as _
CLASS = 'ModemConfiguration'
ICON = 'module-modemconfiguration'
TITLE = _('Modem Configuration')
-
diff --git a/extensions/cpsection/modemconfiguration/model.py b/extensions/cpsection/modemconfiguration/model.py
index 2545ce1..1e83c44 100755
--- a/extensions/cpsection/modemconfiguration/model.py
+++ b/extensions/cpsection/modemconfiguration/model.py
@@ -20,51 +20,62 @@ from jarabe.model.network import GSM_USERNAME_PATH, GSM_PASSWORD_PATH, \
GSM_NUMBER_PATH, GSM_APN_PATH, GSM_PIN_PATH, \
GSM_PUK_PATH
+
def get_username():
client = gconf.client_get_default()
return client.get_string(GSM_USERNAME_PATH) or ''
+
def get_password():
client = gconf.client_get_default()
return client.get_string(GSM_PASSWORD_PATH) or ''
+
def get_number():
client = gconf.client_get_default()
return client.get_string(GSM_NUMBER_PATH) or ''
+
def get_apn():
client = gconf.client_get_default()
return client.get_string(GSM_APN_PATH) or ''
+
def get_pin():
client = gconf.client_get_default()
return client.get_string(GSM_PIN_PATH) or ''
+
def get_puk():
client = gconf.client_get_default()
return client.get_string(GSM_PUK_PATH) or ''
+
def set_username(username):
client = gconf.client_get_default()
client.set_string(GSM_USERNAME_PATH, username)
+
def set_password(password):
client = gconf.client_get_default()
client.set_string(GSM_PASSWORD_PATH, password)
+
def set_number(number):
client = gconf.client_get_default()
client.set_string(GSM_NUMBER_PATH, number)
+
def set_apn(apn):
client = gconf.client_get_default()
client.set_string(GSM_APN_PATH, apn)
+
def set_pin(pin):
client = gconf.client_get_default()
client.set_string(GSM_PIN_PATH, pin)
+
def set_puk(puk):
client = gconf.client_get_default()
client.set_string(GSM_PUK_PATH, puk)
-
diff --git a/extensions/cpsection/modemconfiguration/view.py b/extensions/cpsection/modemconfiguration/view.py
index b236f3f..c31edba 100644
--- a/extensions/cpsection/modemconfiguration/view.py
+++ b/extensions/cpsection/modemconfiguration/view.py
@@ -25,10 +25,12 @@ from sugar.graphics import style
from jarabe.controlpanel.sectionview import SectionView
+
APPLY_TIMEOUT = 1000
+
class EntryWithLabel(gtk.HBox):
- __gtype_name__ = "SugarEntryWithLabel"
+ __gtype_name__ = 'SugarEntryWithLabel'
def __init__(self, label_text):
gtk.HBox.__init__(self, spacing=style.DEFAULT_SPACING)
@@ -53,7 +55,7 @@ class EntryWithLabel(gtk.HBox):
def __entry_changed_cb(self, widget, data=None):
if self._timeout_sid:
gobject.source_remove(self._timeout_sid)
- self._timeout_sid = gobject.timeout_add(APPLY_TIMEOUT,
+ self._timeout_sid = gobject.timeout_add(APPLY_TIMEOUT,
self.__timeout_cb)
def __timeout_cb(self):
@@ -63,7 +65,7 @@ class EntryWithLabel(gtk.HBox):
return False
try:
- self.set_value(self._entry.get_text())
+ self.set_value(self._entry.get_text())
except ValueError:
self._is_valid = False
else:
@@ -74,18 +76,19 @@ class EntryWithLabel(gtk.HBox):
return False
def set_text_from_model(self):
- self._entry.set_text(self.get_value())
+ self._entry.set_text(self.get_value())
def get_value(self):
raise NotImplementedError
def set_value(self):
- raise NotImplementedError
+ raise NotImplementedError
def _get_is_valid(self):
return self._is_valid
is_valid = gobject.property(type=bool, getter=_get_is_valid, default=True)
+
class UsernameEntry(EntryWithLabel):
def __init__(self, model):
EntryWithLabel.__init__(self, _('Username:'))
@@ -97,6 +100,7 @@ class UsernameEntry(EntryWithLabel):
def set_value(self, username):
self._model.set_username(username)
+
class PasswordEntry(EntryWithLabel):
def __init__(self, model):
EntryWithLabel.__init__(self, _('Password:'))
@@ -108,6 +112,7 @@ class PasswordEntry(EntryWithLabel):
def set_value(self, password):
self._model.set_password(password)
+
class NumberEntry(EntryWithLabel):
def __init__(self, model):
EntryWithLabel.__init__(self, _('Number:'))
@@ -119,6 +124,7 @@ class NumberEntry(EntryWithLabel):
def set_value(self, number):
self._model.set_number(number)
+
class ApnEntry(EntryWithLabel):
def __init__(self, model):
EntryWithLabel.__init__(self, _('Access Point Name (APN):'))
@@ -130,6 +136,7 @@ class ApnEntry(EntryWithLabel):
def set_value(self, apn):
self._model.set_apn(apn)
+
class PinEntry(EntryWithLabel):
def __init__(self, model):
EntryWithLabel.__init__(self, _('Personal Identity Number (PIN):'))
@@ -141,6 +148,7 @@ class PinEntry(EntryWithLabel):
def set_value(self, pin):
self._model.set_pin(pin)
+
class PukEntry(EntryWithLabel):
def __init__(self, model):
EntryWithLabel.__init__(self, _('Personal Unblocking Key (PUK):'))
@@ -164,10 +172,9 @@ class ModemConfiguration(SectionView):
self.set_spacing(style.DEFAULT_SPACING)
self._group = gtk.SizeGroup(gtk.SIZE_GROUP_HORIZONTAL)
- explanation = _("You will need to provide the following " \
- "information to set up a mobile " \
- "broadband connection to a cellular "\
- "(3G) network.")
+ explanation = _('You will need to provide the following information'
+ ' to set up a mobile broadband connection to a'
+ ' cellular (3G) network.')
self._text = gtk.Label(explanation)
self._text.set_width_chars(100)
self._text.set_line_wrap(True)
@@ -209,12 +216,12 @@ class ModemConfiguration(SectionView):
self._group.add_widget(self._pin_entry.label)
self.pack_start(self._pin_entry, expand=False)
self._pin_entry.show()
-
+
self._puk_entry = PukEntry(model)
self._puk_entry.connect('notify::is-valid',
self.__notify_is_valid_cb)
self._group.add_widget(self._puk_entry.label)
- self.pack_start(self._puk_entry, expand=False)
+ self.pack_start(self._puk_entry, expand=False)
self._puk_entry.show()
self.setup()
@@ -247,4 +254,3 @@ class ModemConfiguration(SectionView):
if entry.is_valid:
self.needs_restart = True
self._validate()
-
diff --git a/extensions/cpsection/network/__init__.py b/extensions/cpsection/network/__init__.py
index 8fea274..86546f7 100644
--- a/extensions/cpsection/network/__init__.py
+++ b/extensions/cpsection/network/__init__.py
@@ -20,6 +20,3 @@ CLASS = 'Network'
ICON = 'module-network'
TITLE = _('Network')
KEYWORDS = ['network', 'jabber', 'radio', 'server']
-
-
-
diff --git a/extensions/cpsection/network/model.py b/extensions/cpsection/network/model.py
index e8af179..916ce8c 100644
--- a/extensions/cpsection/network/model.py
+++ b/extensions/cpsection/network/model.py
@@ -17,28 +17,35 @@
import dbus
from gettext import gettext as _
-from jarabe.model import network
import gconf
+from jarabe.model import network
+
+
_NM_SERVICE = 'org.freedesktop.NetworkManager'
_NM_PATH = '/org/freedesktop/NetworkManager'
_NM_IFACE = 'org.freedesktop.NetworkManager'
KEYWORDS = ['network', 'jabber', 'radio', 'server']
+
class ReadError(Exception):
def __init__(self, value):
self.value = value
+
def __str__(self):
return repr(self.value)
+
def get_jabber():
client = gconf.client_get_default()
return client.get_string('/desktop/sugar/collaboration/jabber_server')
+
def print_jabber():
print get_jabber()
+
def set_jabber(server):
"""Set the jabber server
server : e.g. 'olpc.collabora.co.uk'
@@ -48,11 +55,12 @@ def set_jabber(server):
return 0
+
def get_radio():
try:
bus = dbus.SystemBus()
obj = bus.get_object(_NM_SERVICE, _NM_PATH)
- nm_props = dbus.Interface(obj, 'org.freedesktop.DBus.Properties')
+ nm_props = dbus.Interface(obj, dbus.PROPERTIES_IFACE)
except dbus.DBusException:
raise ReadError('%s service not available' % _NM_SERVICE)
@@ -62,18 +70,20 @@ def get_radio():
else:
raise ReadError(_('State is unknown.'))
+
def print_radio():
print ('off', 'on')[get_radio()]
-
+
+
def set_radio(state):
"""Turn Radio 'on' or 'off'
state : 'on/off'
- """
+ """
if state == 'on' or state == 1:
try:
bus = dbus.SystemBus()
obj = bus.get_object(_NM_SERVICE, _NM_PATH)
- nm_props = dbus.Interface(obj, 'org.freedesktop.DBus.Properties')
+ nm_props = dbus.Interface(obj, dbus.PROPERTIES_IFACE)
except dbus.DBusException:
raise ReadError('%s service not available' % _NM_SERVICE)
nm_props.Set(_NM_IFACE, 'WirelessEnabled', True)
@@ -81,15 +91,16 @@ def set_radio(state):
try:
bus = dbus.SystemBus()
obj = bus.get_object(_NM_SERVICE, _NM_PATH)
- nm_props = dbus.Interface(obj, 'org.freedesktop.DBus.Properties')
+ nm_props = dbus.Interface(obj, dbus.PROPERTIES_IFACE)
except dbus.DBusException:
raise ReadError('%s service not available' % _NM_SERVICE)
nm_props.Set(_NM_IFACE, 'WirelessEnabled', False)
else:
- raise ValueError(_("Error in specified radio argument use on/off."))
+ raise ValueError(_('Error in specified radio argument use on/off.'))
return 0
+
def clear_registration():
"""Clear the registration with the schoolserver
"""
@@ -97,28 +108,36 @@ def clear_registration():
client.set_string('/desktop/sugar/backup_url', '')
return 1
+
def clear_networks():
"""Clear saved passwords and network configurations.
"""
- network.clear_networks()
+ network.clear_wifi_connections()
+
+
+def have_networks():
+ return network.have_wifi_connections()
+
def get_publish_information():
client = gconf.client_get_default()
publish = client.get_bool('/desktop/sugar/collaboration/publish_gadget')
return publish
-
+
+
def print_publish_information():
print get_publish_information()
+
def set_publish_information(value):
- """ If set to true, Sugar will make you searchable for
+ """ If set to true, Sugar will make you searchable for
the other users of the Jabber server.
value: 0/1
"""
try:
value = (False, True)[int(value)]
except:
- raise ValueError(_("Error in specified argument use 0/1."))
+ raise ValueError(_('Error in specified argument use 0/1.'))
client = gconf.client_get_default()
client.set_bool('/desktop/sugar/collaboration/publish_gadget', value)
diff --git a/extensions/cpsection/network/view.py b/extensions/cpsection/network/view.py
index 588daeb..381dcb6 100644
--- a/extensions/cpsection/network/view.py
+++ b/extensions/cpsection/network/view.py
@@ -23,18 +23,20 @@ from sugar.graphics import style
from jarabe.controlpanel.sectionview import SectionView
from jarabe.controlpanel.inlinealert import InlineAlert
+
CLASS = 'Network'
ICON = 'module-network'
TITLE = _('Network')
_APPLY_TIMEOUT = 3000
+
class Network(SectionView):
def __init__(self, model, alerts):
SectionView.__init__(self)
- self._model = model
- self.restart_alerts = alerts
+ self._model = model
+ self.restart_alerts = alerts
self._jabber_sid = 0
self._jabber_valid = True
self._radio_valid = True
@@ -64,8 +66,8 @@ class Network(SectionView):
box_wireless.set_border_width(style.DEFAULT_SPACING * 2)
box_wireless.set_spacing(style.DEFAULT_SPACING)
- radio_info = gtk.Label(_("Turn off the wireless radio to save "
- "battery life"))
+ radio_info = gtk.Label(_('Turn off the wireless radio to save battery'
+ ' life'))
radio_info.set_alignment(0, 0)
radio_info.set_line_wrap(True)
radio_info.show()
@@ -93,8 +95,8 @@ class Network(SectionView):
self._radio_alert.props.msg = self.restart_msg
self._radio_alert.show()
- history_info = gtk.Label(_("Discard network history if you "
- "have trouble connecting to the network"))
+ history_info = gtk.Label(_('Discard network history if you have'
+ ' trouble connecting to the network'))
history_info.set_alignment(0, 0)
history_info.set_line_wrap(True)
history_info.show()
@@ -104,6 +106,8 @@ class Network(SectionView):
self._clear_history_button = gtk.Button()
self._clear_history_button.set_label(_('Discard network history'))
box_clear_history.pack_start(self._clear_history_button, expand=False)
+ if not self._model.have_networks():
+ self._clear_history_button.set_sensitive(False)
self._clear_history_button.show()
box_wireless.pack_start(box_clear_history, expand=False)
box_clear_history.show()
@@ -135,24 +139,24 @@ class Network(SectionView):
box_server = gtk.HBox(spacing=style.DEFAULT_SPACING)
label_server = gtk.Label(_('Server:'))
label_server.set_alignment(1, 0.5)
- label_server.modify_fg(gtk.STATE_NORMAL,
+ label_server.modify_fg(gtk.STATE_NORMAL,
style.COLOR_SELECTION_GREY.get_gdk_color())
box_server.pack_start(label_server, expand=False)
group.add_widget(label_server)
- label_server.show()
+ label_server.show()
self._entry = gtk.Entry()
self._entry.set_alignment(0)
- self._entry.modify_bg(gtk.STATE_INSENSITIVE,
+ self._entry.modify_bg(gtk.STATE_INSENSITIVE,
style.COLOR_WHITE.get_gdk_color())
- self._entry.modify_base(gtk.STATE_INSENSITIVE,
- style.COLOR_WHITE.get_gdk_color())
+ self._entry.modify_base(gtk.STATE_INSENSITIVE,
+ style.COLOR_WHITE.get_gdk_color())
self._entry.set_size_request(int(gtk.gdk.screen_width() / 3), -1)
box_server.pack_start(self._entry, expand=False)
- self._entry.show()
+ self._entry.show()
box_mesh.pack_start(box_server, expand=False)
box_server.show()
-
- self._jabber_alert = InlineAlert()
+
+ self._jabber_alert = InlineAlert()
label_jabber_error = gtk.Label()
group.add_widget(label_jabber_error)
self._jabber_alert_box.pack_start(label_jabber_error, expand=False)
@@ -176,13 +180,13 @@ class Network(SectionView):
self.setup()
def setup(self):
- self._entry.set_text(self._model.get_jabber())
- try:
- radio_state = self._model.get_radio()
+ self._entry.set_text(self._model.get_jabber())
+ try:
+ radio_state = self._model.get_radio()
except self._model.ReadError, detail:
- self._radio_alert.props.msg = detail
+ self._radio_alert.props.msg = detail
self._radio_alert.show()
- else:
+ else:
self._button.set_active(radio_state)
self._jabber_valid = True
@@ -195,13 +199,13 @@ class Network(SectionView):
self._network_configuration_reset_handler = \
self._clear_history_button.connect( \
'clicked', self.__network_configuration_reset_cb)
-
+
def undo(self):
self._button.disconnect(self._radio_change_handler)
self._entry.disconnect(self._jabber_change_handler)
self._model.undo()
self._jabber_alert.hide()
- self._radio_alert.hide()
+ self._radio_alert.hide()
def _validate(self):
if self._jabber_valid and self._radio_valid:
@@ -209,7 +213,7 @@ class Network(SectionView):
else:
self.props.is_valid = False
- def __radio_toggled_cb(self, widget, data=None):
+ def __radio_toggled_cb(self, widget, data=None):
radio_state = widget.get_active()
try:
self._model.set_radio(radio_state)
@@ -217,18 +221,21 @@ class Network(SectionView):
self._radio_alert.props.msg = detail
self._radio_valid = False
else:
- self._radio_valid = True
+ self._radio_valid = True
+ if self._model.have_networks():
+ self._clear_history_button.set_sensitive(True)
self._validate()
return False
- def __jabber_changed_cb(self, widget, data=None):
+ def __jabber_changed_cb(self, widget, data=None):
if self._jabber_sid:
gobject.source_remove(self._jabber_sid)
- self._jabber_sid = gobject.timeout_add(_APPLY_TIMEOUT,
- self.__jabber_timeout_cb, widget)
-
- def __jabber_timeout_cb(self, widget):
+ self._jabber_sid = gobject.timeout_add(_APPLY_TIMEOUT,
+ self.__jabber_timeout_cb,
+ widget)
+
+ def __jabber_timeout_cb(self, widget):
self._jabber_sid = 0
if widget.get_text() == self._model.get_jabber:
return
@@ -240,11 +247,15 @@ class Network(SectionView):
self._jabber_alert.show()
self.restart_alerts.append('jabber')
else:
- self._jabber_valid = True
+ self._jabber_valid = True
self._jabber_alert.hide()
self._validate()
return False
def __network_configuration_reset_cb(self, widget):
+ # FIXME: takes effect immediately, not after CP is closed with
+ # confirmation button
self._model.clear_networks()
+ if not self._model.have_networks():
+ self._clear_history_button.set_sensitive(False)
diff --git a/extensions/cpsection/power/__init__.py b/extensions/cpsection/power/__init__.py
index 8b2e85f..35f7efd 100644
--- a/extensions/cpsection/power/__init__.py
+++ b/extensions/cpsection/power/__init__.py
@@ -20,4 +20,3 @@ CLASS = 'Power'
ICON = 'module-power'
TITLE = _('Power')
KEYWORDS = ['automatic', 'extreme', 'power', 'suspend', 'battery']
-
diff --git a/extensions/cpsection/power/model.py b/extensions/cpsection/power/model.py
index 48d05de..041e5cf 100644
--- a/extensions/cpsection/power/model.py
+++ b/extensions/cpsection/power/model.py
@@ -35,14 +35,17 @@ _logger = logging.getLogger('ControlPanel - Power')
class ReadError(Exception):
def __init__(self, value):
self.value = value
+
def __str__(self):
return repr(self.value)
+
def using_powerd():
# directory exists if powerd running, and it's recent
# enough to be controllable.
return os.access(POWERD_FLAG_DIR, os.W_OK)
+
def get_automatic_pm():
if using_powerd():
return not os.access(POWERD_INHIBIT_FLAG, os.R_OK)
@@ -51,9 +54,11 @@ def get_automatic_pm():
client = gconf.client_get_default()
return client.get_bool('/desktop/sugar/power/automatic')
+
def print_automatic_pm():
print ('off', 'on')[get_automatic_pm()]
+
def set_automatic_pm(enabled):
"""Automatic suspends on/off."""
@@ -74,42 +79,45 @@ def set_automatic_pm(enabled):
bus = dbus.SystemBus()
proxy = bus.get_object(OHM_SERVICE_NAME, OHM_SERVICE_PATH)
keystore = dbus.Interface(proxy, OHM_SERVICE_IFACE)
-
+
if enabled == 'on' or enabled == 1:
- keystore.SetKey("suspend.automatic_pm", 1)
+ keystore.SetKey('suspend.automatic_pm', 1)
enabled = True
elif enabled == 'off' or enabled == 0:
- keystore.SetKey("suspend.automatic_pm", 0)
+ keystore.SetKey('suspend.automatic_pm', 0)
enabled = False
else:
- raise ValueError(_("Error in automatic pm argument, use on/off."))
+ raise ValueError(_('Error in automatic pm argument, use on/off.'))
client = gconf.client_get_default()
client.set_bool('/desktop/sugar/power/automatic', enabled)
return
+
def get_extreme_pm():
client = gconf.client_get_default()
return client.get_bool('/desktop/sugar/power/extreme')
+
def print_extreme_pm():
print ('off', 'on')[get_extreme_pm()]
+
def set_extreme_pm(enabled):
"""Extreme power management on/off."""
-
+
bus = dbus.SystemBus()
proxy = bus.get_object(OHM_SERVICE_NAME, OHM_SERVICE_PATH)
keystore = dbus.Interface(proxy, OHM_SERVICE_IFACE)
-
+
if enabled == 'on' or enabled == 1:
- keystore.SetKey("suspend.extreme_pm", 1)
+ keystore.SetKey('suspend.extreme_pm', 1)
enabled = True
elif enabled == 'off' or enabled == 0:
- keystore.SetKey("suspend.extreme_pm", 0)
+ keystore.SetKey('suspend.extreme_pm', 0)
enabled = False
else:
- raise ValueError(_("Error in extreme pm argument, use on/off."))
+ raise ValueError(_('Error in extreme pm argument, use on/off.'))
client = gconf.client_get_default()
client.set_bool('/desktop/sugar/power/extreme', enabled)
diff --git a/extensions/cpsection/power/view.py b/extensions/cpsection/power/view.py
index 8f1ed56..fd89efa 100644
--- a/extensions/cpsection/power/view.py
+++ b/extensions/cpsection/power/view.py
@@ -22,6 +22,7 @@ from sugar.graphics import style
from jarabe.controlpanel.sectionview import SectionView
from jarabe.controlpanel.inlinealert import InlineAlert
+
class Power(SectionView):
def __init__(self, model, alerts):
SectionView.__init__(self)
diff --git a/extensions/cpsection/updater/backends/aslo.py b/extensions/cpsection/updater/backends/aslo.py
index 5f257f9..6504e9e 100644
--- a/extensions/cpsection/updater/backends/aslo.py
+++ b/extensions/cpsection/updater/backends/aslo.py
@@ -15,7 +15,7 @@
# along with this program; if not, write to the Free Software
# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
-'''Activity information microformat parser.
+"""Activity information microformat parser.
Activity information is embedded in HTML/XHTML/XML pages using a
Resource Description Framework (RDF) http://www.w3.org/RDF/ .
@@ -46,7 +46,7 @@ An example::
</RDF:Description>
</em:targetApplication>
</RDF:Description></RDF:RDF>
-'''
+"""
import logging
from xml.etree.ElementTree import XML
@@ -54,6 +54,9 @@ import traceback
import gio
+from sugar.bundle.bundleversion import NormalizedVersion
+from sugar.bundle.bundleversion import InvalidVersionError
+
from jarabe import config
_FIND_DESCRIPTION = \
@@ -127,17 +130,17 @@ class _UpdateFetcher(object):
size = None
else:
try:
- version = int(document.find(_FIND_VERSION).text)
- except ValueError:
- logging.error(traceback.format_exc())
- version = 0
+ version = NormalizedVersion(document.find(_FIND_VERSION).text)
+ except InvalidVersionError:
+ logging.exception('Exception occured while parsing version')
+ version = '0'
link = document.find(_FIND_LINK).text
try:
size = long(document.find(_FIND_SIZE).text) * 1024
except ValueError:
- logging.error(traceback.format_exc())
+ logging.exception('Exception occured while parsing size')
size = 0
global _fetcher
@@ -146,13 +149,13 @@ class _UpdateFetcher(object):
def fetch_update_info(bundle, completion_cb):
- '''Queries the server for a newer version of the ActivityBundle.
+ """Queries the server for a newer version of the ActivityBundle.
completion_cb receives bundle, version, link, size and possibly an error
message:
-
+
def completion_cb(bundle, version, link, size, error_message):
- '''
+ """
global _fetcher
if _fetcher is not None:
diff --git a/extensions/cpsection/updater/model.py b/extensions/cpsection/updater/model.py
index 9845371..7ea445f 100755
--- a/extensions/cpsection/updater/model.py
+++ b/extensions/cpsection/updater/model.py
@@ -14,12 +14,12 @@
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
-'''Sugar bundle updater: model.
+"""Sugar bundle updater: model.
This module implements the non-GUI portions of the bundle updater, including
list of installed bundls, whether updates are needed, and the URL at which to
find the bundle updated.
-'''
+"""
import os
import logging
@@ -33,6 +33,7 @@ import gio
from sugar import env
from sugar.datastore import datastore
from sugar.bundle.activitybundle import ActivityBundle
+from sugar.bundle.bundleversion import NormalizedVersion
from jarabe.model import bundleregistry
@@ -64,14 +65,16 @@ class UpdateModel(gobject.GObject):
def check_updates(self):
self.updates = []
- self._bundles_to_check = \
- [bundle for bundle in bundleregistry.get_registry()]
+ self._bundles_to_check = list(bundleregistry.get_registry())
self._check_next_update()
def _check_next_update(self):
total = len(bundleregistry.get_registry())
current = total - len(self._bundles_to_check)
+ if not self._bundles_to_check:
+ return False
+
bundle = self._bundles_to_check.pop()
self.emit('progress', UpdateModel.ACTION_CHECKING, bundle.get_name(),
current, total)
@@ -83,7 +86,8 @@ class UpdateModel(gobject.GObject):
logging.error('Error getting update information from server:\n'
'%s' % error_message)
- if version is not None and version > bundle.get_activity_version():
+ if version is not None and \
+ version > NormalizedVersion(bundle.get_activity_version()):
self.updates.append(BundleUpdate(bundle, version, link, size))
if self._cancelling:
@@ -196,14 +200,17 @@ class UpdateModel(gobject.GObject):
logging.debug('UpdateModel._cancel_checking')
total = len(bundleregistry.get_registry())
current = total - len(self._bundles_to_check)
- self.emit('progress', UpdateModel.ACTION_CHECKING, '', current, current)
+ self.emit('progress', UpdateModel.ACTION_CHECKING, '', current,
+ current)
self._bundles_to_check = None
self._cancelling = False
def _cancel_updating(self):
logging.debug('UpdateModel._cancel_updating')
- current = self._total_bundles_to_update - len(self._bundles_to_update) - 1
- self.emit('progress', UpdateModel.ACTION_UPDATING, '', current, current)
+ current = (self._total_bundles_to_update -
+ len(self._bundles_to_update) - 1)
+ self.emit('progress', UpdateModel.ACTION_UPDATING, '', current,
+ current)
if self._downloader is not None:
self._downloader.cancel()
@@ -216,6 +223,7 @@ class UpdateModel(gobject.GObject):
self._bundles_to_update = None
self._cancelling = False
+
class BundleUpdate(object):
def __init__(self, bundle, version, link, size):
@@ -226,7 +234,7 @@ class BundleUpdate(object):
class _Downloader(gobject.GObject):
- _CHUNK_SIZE = 10240 # 10K
+ _CHUNK_SIZE = 10240 # 10K
__gsignals__ = {
'progress': (gobject.SIGNAL_RUN_FIRST,
gobject.TYPE_NONE,
@@ -262,7 +270,7 @@ class _Downloader(gobject.GObject):
except:
self.emit('error', traceback.format_exc())
return
-
+
temp_file_path = self._get_temp_file_path(self.bundle_update.link)
self._output_file = gio.File(temp_file_path)
self._output_stream = self._output_file.create()
diff --git a/extensions/cpsection/updater/view.py b/extensions/cpsection/updater/view.py
index 2164c0b..814658f 100644
--- a/extensions/cpsection/updater/view.py
+++ b/extensions/cpsection/updater/view.py
@@ -145,7 +145,7 @@ class ActivityUpdater(SectionView):
top_message = gobject.markup_escape_text(top_message)
self._top_label.set_markup('<big>%s</big>' % top_message)
-
+
if not available_updates:
self._clear_center()
else:
@@ -161,7 +161,8 @@ class ActivityUpdater(SectionView):
self._model.check_updates()
def __install_button_clicked_cb(self, button):
- self._top_label.set_markup('<big>%s</big>' % _('Installing updates...'))
+ text = '<big>%s</big>' % _('Installing updates...')
+ self._top_label.set_markup(text)
self._model.update(self._update_box.get_bundles_to_update())
def __cancel_button_clicked_cb(self, button):
@@ -176,12 +177,13 @@ class ActivityUpdater(SectionView):
self._top_label.set_markup('<big>%s</big>' % top_message)
self._clear_center()
- def undo(self):
+ def undo(self):
self._model.cancel()
+
class ProgressPane(gtk.VBox):
- '''Container which replaces the `ActivityPane` during refresh or
- install.'''
+ """Container which replaces the `ActivityPane` during refresh or
+ install."""
def __init__(self):
gtk.VBox.__init__(self)
@@ -359,7 +361,7 @@ class UpdateListModel(gtk.ListStore):
row[self.SELECTED] = True
row[self.ICON_FILE_NAME] = bundle_update.bundle.get_icon()
- details = _('From version %(current)d to %(new)s (Size: %(size)s)')
+ details = _('From version %(current)s to %(new)s (Size: %(size)s)')
details = details % \
{'current': bundle_update.bundle.get_activity_version(),
'new': bundle_update.version,
@@ -374,9 +376,7 @@ class UpdateListModel(gtk.ListStore):
def _format_size(size):
- '''
- Convert a given size in bytes to a nicer better readable unit
- '''
+ """Convert a given size in bytes to a nicer better readable unit"""
if size == 0:
# TRANS: download size is 0
return _('None')
@@ -385,7 +385,7 @@ def _format_size(size):
return _('1 KB')
elif size < 1024 * 1024:
# TRANS: download size of small updates, e.g. '250 KB'
- return locale.format(_('%.0f KB'), size / 1024.0)
+ return locale.format_string(_('%.0f KB'), size / 1024.0)
else:
# TRANS: download size of updates, e.g. '2.3 MB'
- return locale.format(_('%.1f MB'), size / 1024.0 / 1024)
+ return locale.format_string(_('%.1f MB'), size / 1024.0 / 1024)
diff --git a/extensions/deviceicon/Makefile.am b/extensions/deviceicon/Makefile.am
index d46ddde..118d866 100644
--- a/extensions/deviceicon/Makefile.am
+++ b/extensions/deviceicon/Makefile.am
@@ -5,5 +5,5 @@ sugar_PYTHON = \
battery.py \
network.py \
speaker.py \
- touchpad.py \
+ touchpad.py \
volume.py
diff --git a/extensions/deviceicon/battery.py b/extensions/deviceicon/battery.py
index edfcce4..4c1ef37 100644
--- a/extensions/deviceicon/battery.py
+++ b/extensions/deviceicon/battery.py
@@ -16,8 +16,9 @@
import logging
from gettext import gettext as _
-import gconf
+import sys
+import gconf
import gobject
import gtk
import dbus
@@ -30,6 +31,7 @@ from sugar.graphics.xocolor import XoColor
from jarabe.frame.frameinvoker import FrameWidgetInvoker
+
_ICON_NAME = 'battery'
_STATUS_CHARGING = 0
@@ -37,35 +39,38 @@ _STATUS_DISCHARGING = 1
_STATUS_FULLY_CHARGED = 2
_STATUS_NOT_PRESENT = 3
-_LEVEL_PROP = 'battery.charge_level.percentage'
-_CHARGING_PROP = 'battery.rechargeable.is_charging'
-_DISCHARGING_PROP = 'battery.rechargeable.is_discharging'
-_PRESENT_PROP = 'battery.present'
+_UP_DEVICE_IFACE = 'org.freedesktop.UPower.Device'
+
+_UP_TYPE_BATTERY = 2
+
+_UP_STATE_UNKNOWN = 0
+_UP_STATE_CHARGING = 1
+_UP_STATE_DISCHARGING = 2
+_UP_STATE_EMPTY = 3
+_UP_STATE_FULL = 4
+_UP_STATE_CHARGE_PENDING = 5
+_UP_STATE_DISCHARGE_PENDING = 6
+
+_WARN_MIN_PERCENTAGE = 15
+
class DeviceView(TrayIcon):
FRAME_POSITION_RELATIVE = 102
- def __init__(self, udi):
- client = gconf.client_get_default()
+ def __init__(self, battery):
+ client = gconf.client_get_default()
self._color = XoColor(client.get_string('/desktop/sugar/user/color'))
TrayIcon.__init__(self, icon_name=_ICON_NAME, xo_color=self._color)
self.set_palette_invoker(FrameWidgetInvoker(self))
- self._model = DeviceModel(udi)
+ self._model = DeviceModel(battery)
self.palette = BatteryPalette(_('My Battery'))
self.palette.set_group_id('frame')
-
- self._model.connect('notify::level',
- self._battery_status_changed_cb)
- self._model.connect('notify::charging',
- self._battery_status_changed_cb)
- self._model.connect('notify::discharging',
- self._battery_status_changed_cb)
- self._model.connect('notify::present',
- self._battery_status_changed_cb)
+ self._model.connect('updated',
+ self.__battery_status_changed_cb)
self._update_info()
def _update_info(self):
@@ -86,27 +91,30 @@ class DeviceView(TrayIcon):
style.COLOR_WHITE.get_svg()))
elif self._model.props.discharging:
status = _STATUS_DISCHARGING
- if current_level <= 15:
+ if current_level <= _WARN_MIN_PERCENTAGE:
badge_name = 'emblem-warning'
else:
status = _STATUS_FULLY_CHARGED
- self.icon.props.icon_name = get_icon_state(name, current_level, step=-5)
+ self.icon.props.icon_name = get_icon_state(name, current_level,
+ step=-5)
self.icon.props.xo_color = xo_color
self.icon.props.badge_name = badge_name
- self.palette.set_level(current_level)
- self.palette.set_status(status)
+ self.palette.set_info(current_level, self._model.props.time_remaining,
+ status)
- def _battery_status_changed_cb(self, pspec, param):
+ def __battery_status_changed_cb(self, model):
self._update_info()
+
class BatteryPalette(Palette):
def __init__(self, primary_text):
Palette.__init__(self, primary_text)
-
self._level = 0
+ self._time = 0
+ self._status = _STATUS_NOT_PRESENT
self._progress_bar = gtk.ProgressBar()
self._progress_bar.set_size_request(
style.zoom(style.GRID_CELL_SIZE * 4), -1)
@@ -122,130 +130,128 @@ class BatteryPalette(Palette):
self._progress_widget = vbox
self.set_content(self._progress_widget)
- def set_level(self, percent):
- self._level = percent
- fraction = percent / 100.0
- self._progress_bar.set_fraction(fraction)
+ def set_info(self, percentage, seconds, status):
+ self._level = percentage
+ self._time = seconds
+ self._status = status
+ self._progress_bar.set_fraction(percentage / 100.0)
+ self._update_secondary()
- def set_status(self, status):
- current_level = self._level
+ def _update_secondary(self):
secondary_text = ''
- status_text = '%s%%' % current_level
+ status_text = '%s%%' % (self._level, )
progress_widget = self._progress_widget
- if status == _STATUS_NOT_PRESENT:
+ if self._status == _STATUS_NOT_PRESENT:
secondary_text = _('Removed')
progress_widget = None
- elif status == _STATUS_CHARGING:
+ elif self._status == _STATUS_CHARGING:
secondary_text = _('Charging')
- elif status == _STATUS_DISCHARGING:
- if current_level <= 15:
+ elif self._status == _STATUS_DISCHARGING:
+ if self._level <= _WARN_MIN_PERCENTAGE:
secondary_text = _('Very little power remaining')
else:
- #TODO: make this less of an wild/educated guess
- minutes_remaining = int(current_level / 0.59)
- remaining_hourpart = minutes_remaining / 60
+ minutes_remaining = self._time // 60
+ remaining_hourpart = minutes_remaining // 60
remaining_minpart = minutes_remaining % 60
secondary_text = _('%(hour)d:%(min).2d remaining') % \
{'hour': remaining_hourpart, 'min': remaining_minpart}
else:
secondary_text = _('Charged')
+
self.set_content(progress_widget)
self.props.secondary_text = secondary_text
self._status_label.set_text(status_text)
+
class DeviceModel(gobject.GObject):
__gproperties__ = {
- 'level' : (int, None, None, 0, 100, 0,
- gobject.PARAM_READABLE),
- 'charging' : (bool, None, None, False,
- gobject.PARAM_READABLE),
- 'discharging' : (bool, None, None, False,
- gobject.PARAM_READABLE),
- 'present' : (bool, None, None, False,
- gobject.PARAM_READABLE)
+ 'level': (int, None, None, 0, 100, 0, gobject.PARAM_READABLE),
+ 'time-remaining': (int, None, None, 0, sys.maxint, 0,
+ gobject.PARAM_READABLE), # unit: seconds
+ 'charging': (bool, None, None, False, gobject.PARAM_READABLE),
+ 'discharging': (bool, None, None, False, gobject.PARAM_READABLE),
+ 'present': (bool, None, None, False, gobject.PARAM_READABLE),
}
- def __init__(self, udi):
- gobject.GObject.__init__(self)
-
- bus = dbus.Bus(dbus.Bus.TYPE_SYSTEM)
- proxy = bus.get_object('org.freedesktop.Hal', udi,
- follow_name_owner_changes=True)
- self._battery = dbus.Interface(proxy, 'org.freedesktop.Hal.Device')
- bus.add_signal_receiver(self._battery_changed,
- 'PropertyModified',
- 'org.freedesktop.Hal.Device',
- 'org.freedesktop.Hal',
- udi)
-
- self._level = self._get_level()
- self._charging = self._get_charging()
- self._discharging = self._get_discharging()
- self._present = self._get_present()
-
- def _get_level(self):
- try:
- return self._battery.GetProperty(_LEVEL_PROP)
- except dbus.DBusException:
- logging.error('Cannot access %s', _LEVEL_PROP)
- return 0
-
- def _get_charging(self):
- try:
- return self._battery.GetProperty(_CHARGING_PROP)
- except dbus.DBusException:
- logging.error('Cannot access %s', _CHARGING_PROP)
- return False
+ __gsignals__ = {
+ 'updated': (gobject.SIGNAL_RUN_FIRST, gobject.TYPE_NONE, ([])),
+ }
- def _get_discharging(self):
+ def __init__(self, battery):
+ gobject.GObject.__init__(self)
+ self._battery = battery
+ self._battery_props_iface = dbus.Interface(self._battery,
+ dbus.PROPERTIES_IFACE)
+ self._battery.connect_to_signal('Changed',
+ self.__battery_properties_changed_cb,
+ dbus_interface=_UP_DEVICE_IFACE)
+ self._fetch_properties_from_upower()
+
+ def _fetch_properties_from_upower(self):
+ """Get current values from UPower."""
+ # pylint: disable=W0201
try:
- return self._battery.GetProperty(_DISCHARGING_PROP)
+ dbus_props = self._battery_props_iface.GetAll(_UP_DEVICE_IFACE)
except dbus.DBusException:
- logging.error('Cannot access %s', _DISCHARGING_PROP)
- return False
+ logging.error('Cannot access battery properties')
+ dbus_props = {}
- def _get_present(self):
- try:
- return self._battery.GetProperty(_PRESENT_PROP)
- except dbus.DBusException:
- logging.error('Cannot access %s', _PRESENT_PROP)
- return False
+ self._level = dbus_props.get('Percentage', 0)
+ self._state = dbus_props.get('State', _UP_STATE_UNKNOWN)
+ self._present = dbus_props.get('IsPresent', False)
+ self._time_to_empty = dbus_props.get('TimeToEmpty', 0)
+ self._time_to_full = dbus_props.get('TimeToFull', 0)
def do_get_property(self, pspec):
+ """Return current value of given GObject property."""
if pspec.name == 'level':
- return self._level
+ return self._level
if pspec.name == 'charging':
- return self._charging
+ return self._state == _UP_STATE_CHARGING
if pspec.name == 'discharging':
- return self._discharging
+ return self._state == _UP_STATE_DISCHARGING
if pspec.name == 'present':
return self._present
+ if pspec.name == 'time-remaining':
+ if self._state == _UP_STATE_CHARGING:
+ return self._time_to_full
+ if self._state == _UP_STATE_DISCHARGING:
+ return self._time_to_empty
+ return 0
def get_type(self):
return 'battery'
- def _battery_changed(self, num_changes, changes_list):
- for change in changes_list:
- if change[0] == _LEVEL_PROP:
- self._level = self._get_level()
- self.notify('level')
- elif change[0] == _CHARGING_PROP:
- self._charging = self._get_charging()
- self.notify('charging')
- elif change[0] == _DISCHARGING_PROP:
- self._discharging = self._get_discharging()
- self.notify('discharging')
- elif change[0] == _PRESENT_PROP:
- self._present = self._get_present()
- self.notify('present')
+ def __battery_properties_changed_cb(self):
+ old_level = self._level
+ old_state = self._state
+ old_present = self._present
+ old_time = self.props.time_remaining
+ self._fetch_properties_from_upower()
+ if self._level != old_level:
+ self.notify('level')
+ if self._state != old_state:
+ self.notify('charging')
+ self.notify('discharging')
+ if self._present != old_present:
+ self.notify('present')
+ if self.props.time_remaining != old_time:
+ self.notify('time-remaining')
+
+ self.emit('updated')
+
def setup(tray):
bus = dbus.Bus(dbus.Bus.TYPE_SYSTEM)
- proxy = bus.get_object('org.freedesktop.Hal',
- '/org/freedesktop/Hal/Manager')
- hal_manager = dbus.Interface(proxy, 'org.freedesktop.Hal.Manager')
-
- for udi in hal_manager.FindDeviceByCapability('battery'):
- tray.add_device(DeviceView(udi))
+ up_proxy = bus.get_object('org.freedesktop.UPower',
+ '/org/freedesktop/UPower')
+ upower = dbus.Interface(up_proxy, 'org.freedesktop.UPower')
+
+ for device_path in upower.EnumerateDevices():
+ device = bus.get_object('org.freedesktop.UPower', device_path)
+ device_prop_iface = dbus.Interface(device, dbus.PROPERTIES_IFACE)
+ device_type = device_prop_iface.Get(_UP_DEVICE_IFACE, 'Type')
+ if device_type == _UP_TYPE_BATTERY:
+ tray.add_device(DeviceView(device))
diff --git a/extensions/deviceicon/network.py b/extensions/deviceicon/network.py
index 0789f9c..4c4f339 100644
--- a/extensions/deviceicon/network.py
+++ b/extensions/deviceicon/network.py
@@ -23,7 +23,6 @@ import logging
import hashlib
import socket
import struct
-import re
import datetime
import time
import gtk
@@ -40,16 +39,14 @@ from sugar.graphics.tray import TrayIcon
from sugar.graphics.menuitem import MenuItem
from sugar.graphics.icon import Icon
from sugar.graphics import xocolor
-from sugar.util import unique_id
from sugar import profile
from jarabe.model import network
-from jarabe.model.network import Settings
-from jarabe.model.network import IP4Config
from jarabe.frame.frameinvoker import FrameWidgetInvoker
from jarabe.view.pulsingicon import PulsingIcon
-IP_ADDRESS_TEXT_TEMPLATE = _("IP address: %s")
+
+IP_ADDRESS_TEXT_TEMPLATE = _('IP address: %s')
_NM_SERVICE = 'org.freedesktop.NetworkManager'
_NM_IFACE = 'org.freedesktop.NetworkManager'
@@ -73,8 +70,8 @@ class WirelessPalette(Palette):
__gtype_name__ = 'SugarWirelessPalette'
__gsignals__ = {
- 'deactivate-connection' : (gobject.SIGNAL_RUN_FIRST,
- gobject.TYPE_NONE, ([]))
+ 'deactivate-connection': (gobject.SIGNAL_RUN_FIRST, gobject.TYPE_NONE,
+ ([])),
}
def __init__(self, primary_text):
@@ -107,7 +104,8 @@ class WirelessPalette(Palette):
self._disconnect_item = MenuItem(_('Disconnect...'))
icon = Icon(icon_size=gtk.ICON_SIZE_MENU, icon_name='media-eject')
self._disconnect_item.set_image(icon)
- self._disconnect_item.connect('activate', self.__disconnect_activate_cb)
+ self._disconnect_item.connect('activate',
+ self.__disconnect_activate_cb)
self.menu.append(self._disconnect_item)
def set_connecting(self):
@@ -141,7 +139,7 @@ class WirelessPalette(Palette):
self._set_channel(channel)
def _set_channel(self, channel):
- self._channel_label.set_text("%s: %d" % (_("Channel"), channel))
+ self._channel_label.set_text('%s: %d' % (_('Channel'), channel))
def _set_ip_address(self, ip_address):
if ip_address is not None:
@@ -189,7 +187,7 @@ class WiredPalette(Palette):
def _inet_ntoa(self, iaddress):
address = ['%s' % ((iaddress >> i) % 256) for i in [0, 8, 16, 24]]
- return ".".join(address)
+ return '.'.join(address)
def _set_ip_address(self, ip_address):
if ip_address is not None:
@@ -199,14 +197,13 @@ class WiredPalette(Palette):
ip_address_text = ""
self._ip_address_label.set_text(ip_address_text)
+
class GsmPalette(Palette):
__gtype_name__ = 'SugarGsmPalette'
__gsignals__ = {
- 'gsm-connect' : (gobject.SIGNAL_RUN_FIRST,
- gobject.TYPE_NONE, ([])),
- 'gsm-disconnect' : (gobject.SIGNAL_RUN_FIRST,
- gobject.TYPE_NONE, ([])),
+ 'gsm-connect': (gobject.SIGNAL_RUN_FIRST, gobject.TYPE_NONE, ([])),
+ 'gsm-disconnect': (gobject.SIGNAL_RUN_FIRST, gobject.TYPE_NONE, ([])),
}
def __init__(self):
@@ -302,7 +299,7 @@ class GsmPalette(Palette):
icon = Icon(icon_name='media-eject', \
icon_size=gtk.ICON_SIZE_MENU)
self._toggle_state_item.set_image(icon)
-
+
elif self._current_state == _GSM_STATE_FAILED:
message_error = self._get_error_by_nm_reason(reason)
self.add_alert(message_error[0], message_error[1])
@@ -327,7 +324,8 @@ class GsmPalette(Palette):
def add_alert(self, error, suggestion):
self._failed_connection = True
- self._toggle_state_item.get_child().set_label(_('Try connection again'))
+ action = _('Try connection again')
+ self._toggle_state_item.get_child().set_label(action)
title = _('Error: %s') % error
self.error_title_label.set_markup('<b>%s</b>' % title)
@@ -347,8 +345,8 @@ class GsmPalette(Palette):
def update_stats(self, in_bytes, out_bytes):
in_KBytes = in_bytes / 1024
out_KBytes = out_bytes / 1024
- self._data_label_up.set_text(_("%d KB") % (out_KBytes))
- self._data_label_down.set_text(_("%d KB") % (in_KBytes))
+ self._data_label_up.set_text(_('%d KB') % (out_KBytes))
+ self._data_label_down.set_text(_('%d KB') % (in_KBytes))
def _get_error_by_nm_reason(self, reason):
if reason in [network.NM_DEVICE_STATE_REASON_NO_SECRETS,
@@ -390,8 +388,8 @@ class WirelessDeviceView(ToolButton):
self._icon = PulsingIcon()
self._icon.props.icon_name = get_icon_state('network-wireless', 0)
- self._inactive_color = xocolor.XoColor( \
- "%s,%s" % (style.COLOR_BUTTON_GREY.get_svg(),
+ self._inactive_color = xocolor.XoColor(
+ '%s,%s' % (style.COLOR_BUTTON_GREY.get_svg(),
style.COLOR_TRANSPARENT.get_svg()))
self._icon.props.pulse_color = self._inactive_color
self._icon.props.base_color = self._inactive_color
@@ -406,9 +404,9 @@ class WirelessDeviceView(ToolButton):
self.set_palette(self._palette)
self._palette.set_group_id('frame')
- self._device_props = dbus.Interface(self._device,
- 'org.freedesktop.DBus.Properties')
- self._device_props.GetAll(_NM_DEVICE_IFACE, byte_arrays=True,
+ self._device_props = dbus.Interface(self._device,
+ dbus.PROPERTIES_IFACE)
+ self._device_props.GetAll(_NM_DEVICE_IFACE, byte_arrays=True,
reply_handler=self.__get_device_props_reply_cb,
error_handler=self.__get_device_props_error_cb)
@@ -448,7 +446,7 @@ class WirelessDeviceView(ToolButton):
return
self._active_ap_op = active_ap_op
active_ap = self._bus.get_object(_NM_SERVICE, active_ap_op)
- props = dbus.Interface(active_ap, 'org.freedesktop.DBus.Properties')
+ props = dbus.Interface(active_ap, dbus.PROPERTIES_IFACE)
props.GetAll(_NM_ACCESSPOINT_IFACE, byte_arrays=True,
reply_handler=self.__get_all_ap_props_reply_cb,
@@ -497,7 +495,7 @@ class WirelessDeviceView(ToolButton):
digest = hash(sha_hash.digest())
index = digest % len(xocolor.colors)
- self._color = xocolor.XoColor('%s,%s' %
+ self._color = xocolor.XoColor('%s,%s' %
(xocolor.colors[index][0],
xocolor.colors[index][1]))
self._update()
@@ -510,7 +508,7 @@ class WirelessDeviceView(ToolButton):
def _update(self):
if self._flags == network.NM_802_11_AP_FLAGS_PRIVACY:
- self._icon.props.badge_name = "emblem-locked"
+ self._icon.props.badge_name = 'emblem-locked'
else:
self._icon.props.badge_name = None
@@ -552,7 +550,8 @@ class WirelessDeviceView(ToolButton):
self._icon.props.pulsing = True
elif state == network.DEVICE_STATE_ACTIVATED:
address = self._device_props.Get(_NM_DEVICE_IFACE, 'Ip4Address')
- self._palette.set_connected_with_frequency(self._frequency, address)
+ self._palette.set_connected_with_frequency(self._frequency,
+ address)
self._icon.props.pulsing = False
else:
self._icon.props.badge_name = None
@@ -565,21 +564,12 @@ class WirelessDeviceView(ToolButton):
self._icon.props.base_color = self._color
def __deactivate_connection_cb(self, palette, data=None):
- if self._active_ap_op is not None:
- obj = self._bus.get_object(_NM_SERVICE, _NM_PATH)
- netmgr = dbus.Interface(obj, _NM_IFACE)
- netmgr_props = dbus.Interface(
- netmgr, 'org.freedesktop.DBus.Properties')
- active_connections_o = netmgr_props.Get(_NM_IFACE,
- 'ActiveConnections')
-
- for conn_o in active_connections_o:
- obj = self._bus.get_object(_NM_IFACE, conn_o)
- props = dbus.Interface(obj, 'org.freedesktop.DBus.Properties')
- ap_op = props.Get(_NM_ACTIVE_CONN_IFACE, 'SpecificObject')
- if ap_op == self._active_ap_op:
- netmgr.DeactivateConnection(conn_o)
- break
+ if self._mode == network.NM_802_11_MODE_INFRA:
+ connection = network.find_connection_by_ssid(self._name)
+ if connection:
+ connection.disable_autoconnect()
+
+ network.disconnect_access_points([self._active_ap_op])
def __activate_reply_cb(self, connection):
logging.debug('Network created: %s', connection)
@@ -602,8 +592,8 @@ class OlpcMeshDeviceView(ToolButton):
self._channel = 0
self._icon = PulsingIcon(icon_name=self._ICON_NAME)
- self._inactive_color = xocolor.XoColor( \
- "%s,%s" % (style.COLOR_BUTTON_GREY.get_svg(),
+ self._inactive_color = xocolor.XoColor(
+ '%s,%s' % (style.COLOR_BUTTON_GREY.get_svg(),
style.COLOR_TRANSPARENT.get_svg()))
self._icon.props.pulse_color = profile.get_color()
self._icon.props.base_color = self._inactive_color
@@ -612,7 +602,7 @@ class OlpcMeshDeviceView(ToolButton):
self._icon.show()
self.set_palette_invoker(FrameWidgetInvoker(self))
- self._palette = WirelessPalette(_("Mesh Network"))
+ self._palette = WirelessPalette(_('Mesh Network'))
self._palette.connect('deactivate-connection',
self.__deactivate_connection)
self.set_palette(self._palette)
@@ -621,7 +611,7 @@ class OlpcMeshDeviceView(ToolButton):
self.update_state(state)
self._device_props = dbus.Interface(self._device,
- 'org.freedesktop.DBus.Properties')
+ dbus.PROPERTIES_IFACE)
self._device_props.Get(_NM_OLPC_MESH_IFACE, 'ActiveChannel',
reply_handler=self.__get_active_channel_reply_cb,
error_handler=self.__get_active_channel_error_cb)
@@ -655,7 +645,7 @@ class OlpcMeshDeviceView(ToolButton):
def _update_text(self):
channel = str(self._channel)
- text = _("Mesh Network %s") % glib.markup_escape_text(channel)
+ text = _('Mesh Network %s') % glib.markup_escape_text(channel)
self._palette.props.primary_text = text
def _update(self):
@@ -683,21 +673,21 @@ class OlpcMeshDeviceView(ToolButton):
def __deactivate_connection(self, palette, data=None):
obj = self._bus.get_object(_NM_SERVICE, _NM_PATH)
netmgr = dbus.Interface(obj, _NM_IFACE)
- netmgr_props = dbus.Interface(netmgr, 'org.freedesktop.DBus.Properties')
+ netmgr_props = dbus.Interface(netmgr, dbus.PROPERTIES_IFACE)
active_connections_o = netmgr_props.Get(_NM_IFACE,
'ActiveConnections')
for conn_o in active_connections_o:
# The connection path for a mesh connection is the device itself.
obj = self._bus.get_object(_NM_IFACE, conn_o)
- props = dbus.Interface(obj, 'org.freedesktop.DBus.Properties')
+ props = dbus.Interface(obj, dbus.PROPERTIES_IFACE)
ap_op = props.Get(_NM_ACTIVE_CONN_IFACE, 'SpecificObject')
try:
obj = self._bus.get_object(_NM_IFACE, ap_op)
- props = dbus.Interface(obj, 'org.freedesktop.DBus.Properties')
- type = props.Get(_NM_DEVICE_IFACE, 'DeviceType')
- if type == network.DEVICE_TYPE_802_11_OLPC_MESH:
+ props = dbus.Interface(obj, dbus.PROPERTIES_IFACE)
+ device_type = props.Get(_NM_DEVICE_IFACE, 'DeviceType')
+ if device_type == network.DEVICE_TYPE_802_11_OLPC_MESH:
netmgr.DeactivateConnection(conn_o)
break
except dbus.exceptions.DBusException:
@@ -749,6 +739,7 @@ class GsmDeviceView(TrayIcon):
signal_name='PppStats',
path=self._device.object_path,
dbus_interface=_NM_SERIAL_IFACE)
+
def create_palette(self):
palette = GsmPalette()
@@ -758,7 +749,7 @@ class GsmDeviceView(TrayIcon):
self._palette = palette
- props = dbus.Interface(self._device, 'org.freedesktop.DBus.Properties')
+ props = dbus.Interface(self._device, dbus.PROPERTIES_IFACE)
props.GetAll(_NM_DEVICE_IFACE, byte_arrays=True,
reply_handler=self.__current_state_check_cb,
error_handler=self.__current_state_check_error_cb)
@@ -791,12 +782,12 @@ class GsmDeviceView(TrayIcon):
def __gsm_disconnect_cb(self, palette, data=None):
obj = self._bus.get_object(_NM_SERVICE, _NM_PATH)
netmgr = dbus.Interface(obj, _NM_IFACE)
- netmgr_props = dbus.Interface(netmgr, 'org.freedesktop.DBus.Properties')
+ netmgr_props = dbus.Interface(netmgr, dbus.PROPERTIES_IFACE)
active_connections_o = netmgr_props.Get(_NM_IFACE, 'ActiveConnections')
for conn_o in active_connections_o:
obj = self._bus.get_object(_NM_IFACE, conn_o)
- props = dbus.Interface(obj, 'org.freedesktop.DBus.Properties')
+ props = dbus.Interface(obj, dbus.PROPERTIES_IFACE)
devices = props.Get(_NM_ACTIVE_CONN_IFACE, 'Devices')
if self._device.object_path in devices:
netmgr.DeactivateConnection(
@@ -961,7 +952,7 @@ class WiredDeviceObserver(object):
self._device_view = None
self._tray = tray
- props = dbus.Interface(self._device, 'org.freedesktop.DBus.Properties')
+ props = dbus.Interface(self._device, dbus.PROPERTIES_IFACE)
props.GetAll(_NM_DEVICE_IFACE, byte_arrays=True,
reply_handler=self.__get_device_props_reply_cb,
error_handler=self.__get_device_props_error_cb)
@@ -989,8 +980,7 @@ class WiredDeviceObserver(object):
def _update_state(self, state):
if state == network.DEVICE_STATE_ACTIVATED:
- props = dbus.Interface(self._device,
- 'org.freedesktop.DBus.Properties')
+ props = dbus.Interface(self._device, dbus.PROPERTIES_IFACE)
address = props.Get(_NM_DEVICE_IFACE, 'Ip4Address')
speed = props.Get(_NM_WIRED_IFACE, 'Speed')
self._device_view = WiredDeviceView(speed, address)
@@ -1001,6 +991,7 @@ class WiredDeviceObserver(object):
del self._device_view
self._device_view = None
+
class GsmDeviceObserver(object):
def __init__(self, device, tray):
self._device = device
@@ -1015,6 +1006,7 @@ class GsmDeviceObserver(object):
self._tray.remove_device(self._device_view)
self._device_view = None
+
class NetworkManagerObserver(object):
def __init__(self, tray):
self._bus = dbus.SystemBus()
@@ -1048,7 +1040,7 @@ class NetworkManagerObserver(object):
def _check_device(self, device_op):
nm_device = self._bus.get_object(_NM_SERVICE, device_op)
- props = dbus.Interface(nm_device, 'org.freedesktop.DBus.Properties')
+ props = dbus.Interface(nm_device, dbus.PROPERTIES_IFACE)
device_type = props.Get(_NM_DEVICE_IFACE, 'DeviceType')
if device_type == network.DEVICE_TYPE_802_3_ETHERNET:
@@ -1073,5 +1065,6 @@ class NetworkManagerObserver(object):
device.disconnect()
del self._devices[device_op]
+
def setup(tray):
device_observer = NetworkManagerObserver(tray)
diff --git a/extensions/deviceicon/speaker.py b/extensions/deviceicon/speaker.py
index 3a54464..d396bfb 100644
--- a/extensions/deviceicon/speaker.py
+++ b/extensions/deviceicon/speaker.py
@@ -32,12 +32,13 @@ from jarabe.model import sound
_ICON_NAME = 'speaker'
+
class DeviceView(TrayIcon):
FRAME_POSITION_RELATIVE = 103
def __init__(self):
- client = gconf.client_get_default()
+ client = gconf.client_get_default()
self._color = XoColor(client.get_string('/desktop/sugar/user/color'))
TrayIcon.__init__(self, icon_name=_ICON_NAME, xo_color=self._color)
@@ -70,22 +71,24 @@ class DeviceView(TrayIcon):
xo_color = XoColor('%s,%s' % (style.COLOR_WHITE.get_svg(),
style.COLOR_WHITE.get_svg()))
- self.icon.props.icon_name = get_icon_state(name, current_level, step=-1)
+ self.icon.props.icon_name = get_icon_state(name, current_level,
+ step=-1)
self.icon.props.xo_color = xo_color
def __button_release_event_cb(self, widget, event):
- if event.button == 1:
- self._model.props.muted = not self._model.props.muted
- return True
- else:
+ if event.button != 1:
return False
+ self.palette_invoker.notify_right_click()
+ return True
+
def __expose_event_cb(self, *args):
self._update_info()
def __speaker_status_changed_cb(self, pspec_, param_):
self._update_info()
+
class SpeakerPalette(Palette):
def __init__(self, primary_text, model):
@@ -167,10 +170,11 @@ class SpeakerPalette(Palette):
self._update_level()
self._update_muted()
+
class DeviceModel(gobject.GObject):
__gproperties__ = {
- 'level' : (int, None, None, 0, 100, 0, gobject.PARAM_READWRITE),
- 'muted' : (bool, None, None, False, gobject.PARAM_READWRITE),
+ 'level': (int, None, None, 0, 100, 0, gobject.PARAM_READWRITE),
+ 'muted': (bool, None, None, False, gobject.PARAM_READWRITE),
}
def __init__(self):
@@ -201,16 +205,17 @@ class DeviceModel(gobject.GObject):
return 'speaker'
def do_get_property(self, pspec):
- if pspec.name == "level":
+ if pspec.name == 'level':
return self._get_level()
- elif pspec.name == "muted":
+ elif pspec.name == 'muted':
return self._get_muted()
def do_set_property(self, pspec, value):
- if pspec.name == "level":
+ if pspec.name == 'level':
self._set_level(value)
- elif pspec.name == "muted":
+ elif pspec.name == 'muted':
self._set_muted(value)
+
def setup(tray):
tray.add_device(DeviceView())
diff --git a/extensions/deviceicon/touchpad.py b/extensions/deviceicon/touchpad.py
index d9521c2..b3b34f5 100644
--- a/extensions/deviceicon/touchpad.py
+++ b/extensions/deviceicon/touchpad.py
@@ -33,10 +33,14 @@ from jarabe.frame.frameinvoker import FrameWidgetInvoker
TOUCHPAD_MODE_CAPACITIVE = 'capacitive'
TOUCHPAD_MODE_RESISTIVE = 'resistive'
TOUCHPAD_MODES = [TOUCHPAD_MODE_CAPACITIVE, TOUCHPAD_MODE_RESISTIVE]
-STATUS_TEXT = {TOUCHPAD_MODE_CAPACITIVE: _('finger'),
- TOUCHPAD_MODE_RESISTIVE: _('stylus')}
-STATUS_ICON = {TOUCHPAD_MODE_CAPACITIVE: 'touchpad-' + TOUCHPAD_MODE_CAPACITIVE,
- TOUCHPAD_MODE_RESISTIVE: 'touchpad-' + TOUCHPAD_MODE_RESISTIVE}
+STATUS_TEXT = {
+ TOUCHPAD_MODE_CAPACITIVE: _('finger'),
+ TOUCHPAD_MODE_RESISTIVE: _('stylus'),
+}
+STATUS_ICON = {
+ TOUCHPAD_MODE_CAPACITIVE: 'touchpad-' + TOUCHPAD_MODE_CAPACITIVE,
+ TOUCHPAD_MODE_RESISTIVE: 'touchpad-' + TOUCHPAD_MODE_RESISTIVE,
+}
# NODE_PATH is used to communicate with the touchpad device.
NODE_PATH = '/sys/devices/platform/i8042/serio1/ptmode'
diff --git a/extensions/deviceicon/volume.py b/extensions/deviceicon/volume.py
index e7f62a2..ea2377d 100644
--- a/extensions/deviceicon/volume.py
+++ b/extensions/deviceicon/volume.py
@@ -28,8 +28,10 @@ from jarabe.journal import journalactivity
from jarabe.view.palettes import VolumePalette
from jarabe.frame.frameinvoker import FrameWidgetInvoker
+
_icons = {}
+
class DeviceView(TrayIcon):
FRAME_POSITION_RELATIVE = 500
@@ -70,9 +72,11 @@ class DeviceView(TrayIcon):
journal.reveal()
return True
+
def setup(tray):
gobject.idle_add(_setup_volumes, tray)
+
def _setup_volumes(tray):
volume_monitor = gio.volume_monitor_get()
@@ -86,9 +90,11 @@ def _setup_volumes(tray):
volume_monitor.connect('mount-added', _mount_added_cb, tray)
volume_monitor.connect('mount-removed', _mount_removed_cb, tray)
+
def _volume_added_cb(volume_monitor, volume, tray):
_mount(volume, tray)
+
def _mount(volume, tray):
# Follow Nautilus behaviour here
# since it has the same issue with removable device
@@ -102,20 +108,23 @@ def _mount(volume, tray):
#TODO: pass None as mount_operation, or better, SugarMountOperation
volume.mount(gtk.MountOperation(tray.get_toplevel()), _mount_cb)
+
def _mount_cb(volume, result):
logging.debug('_mount_cb %r %r', volume, result)
volume.mount_finish(result)
+
def _mount_added_cb(volume_monitor, mount, tray):
_add_device(mount, tray)
+
def _mount_removed_cb(volume_monitor, mount, tray):
icon = _icons[mount]
tray.remove_device(icon)
del _icons[mount]
+
def _add_device(mount, tray):
icon = DeviceView(mount)
_icons[mount] = icon
tray.add_device(icon)
-
diff --git a/extensions/globalkey/screenshot.py b/extensions/globalkey/screenshot.py
index 8b4d4c2..0afe964 100644
--- a/extensions/globalkey/screenshot.py
+++ b/extensions/globalkey/screenshot.py
@@ -17,7 +17,6 @@
import os
import tempfile
-import time
from gettext import gettext as _
import gtk
@@ -31,6 +30,7 @@ from jarabe.model import shell
BOUND_KEYS = ['<alt>1', 'Print']
+
def handle_key_press(key):
tmp_dir = os.path.join(env.get_profile_path(), 'data')
fd, file_path = tempfile.mkstemp(dir=tmp_dir)
@@ -45,7 +45,7 @@ def handle_key_press(key):
height=height)
screenshot.get_from_drawable(window, window.get_colormap(), x_orig,
y_orig, 0, 0, width, height)
- screenshot.save(file_path, "png")
+ screenshot.save(file_path, 'png')
client = gconf.client_get_default()
color = client.get_string('/desktop/sugar/user/color')
@@ -87,14 +87,15 @@ def handle_key_press(key):
jobject.destroy()
del jobject
+
def _get_preview_data(screenshot):
preview = screenshot.scale_simple(style.zoom(300), style.zoom(225),
gtk.gdk.INTERP_BILINEAR)
preview_data = []
+
def save_func(buf, data):
data.append(buf)
preview.save_to_callback(save_func, 'png', user_data=preview_data)
return dbus.ByteArray(''.join(preview_data))
-
diff --git a/extensions/globalkey/viewsource.py b/extensions/globalkey/viewsource.py
index df3cd9e..96e7c6b 100644
--- a/extensions/globalkey/viewsource.py
+++ b/extensions/globalkey/viewsource.py
@@ -18,8 +18,10 @@
from jarabe.view.viewsource import setup_view_source
from jarabe.model import shell
+
BOUND_KEYS = ['0xEC', '<alt><shift>v']
+
def handle_key_press(key):
shell_model = shell.get_model()
activity = shell_model.get_active_activity()
diff --git a/po/Makevars b/po/Makevars
new file mode 100644
index 0000000..da4dba6
--- /dev/null
+++ b/po/Makevars
@@ -0,0 +1 @@
+XGETTEXT_OPTIONS = --keyword=_ --keyword=N_ --keyword=C_:1c,2 --keyword=NC_:1c,2 --keyword=Q_ --keyword=g_dgettext:2 --keyword=g_dngettext:2,3 --keyword=g_dpgettext:2 --keyword=g_dpgettext2=2c,3 --keyword=pgettext:1c,2
diff --git a/po/ar.po b/po/ar.po
index df5b323..d1fb825 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: 2010-01-30 00:31-0500\n"
-"PO-Revision-Date: 2010-02-07 17:12+0200\n"
+"PO-Revision-Date: 2011-01-24 00:25+0200\n"
"Last-Translator: Khaled Hosny <khaledhosny@eglug.org>\n"
"Language-Team: Arabic <doc@arabeyes.org>\n"
"Language: ar\n"
@@ -16,7 +16,7 @@ msgstr ""
"Content-Transfer-Encoding: 8bit\n"
"Plural-Forms: nplurals=6; plural=n==0 ? 0 : n==1 ? 1 : n==2 ? 2 : n%100>=3 "
"&& n%100<=10 ? 3 : n%100>=11 && n%100<=99 ? 4 : 5;\n"
-"X-Generator: Pootle 2.0.1\n"
+"X-Generator: Pootle 2.0.3\n"
"Nplurals=6; Plural=N==0 ? 0: n==1 ? 1 : n==2 ? 2 : n%100>=3 && n%100<=10 ? 3 "
": n%100>=11 && n%100<=99 ? 4 : 5;\n"
@@ -321,12 +321,12 @@ msgstr "برمجيات محدّثة"
#, python-format
msgid "You can install %s update"
msgid_plural "You can install %s updates"
-msgstr[0] "يمكنك تنزيل %s تحديث"
-msgstr[1] "يمكنك تنزيل تحديث واحد"
-msgstr[2] "يمكنك تنزيل تحديثين"
-msgstr[3] "يمكنك تنزيل %s تحديثات"
-msgstr[4] "يمكنك تنزيل %s تحديثا"
-msgstr[5] "يمكنك تنزيل %s تحديث"
+msgstr[0] "لا تحديثات لتثبيتها%.0s"
+msgstr[1] "يمكنك تثبيت تحديث واحد%.0s"
+msgstr[2] "يمكنك تثبيت تحديثين%.0s"
+msgstr[3] "يمكنك تثبيت %s تحديثات"
+msgstr[4] "يمكنك تثبيت %s تحديثا"
+msgstr[5] "يمكنك تثبيت %s تحديث"
#: ../extensions/cpsection/updater/view.py:159
msgid "Checking for updates..."
@@ -340,9 +340,9 @@ msgstr "يُثبّت التحديثات..."
#, python-format
msgid "%s update was installed"
msgid_plural "%s updates were installed"
-msgstr[0] "لم تُثبّت أي تحديثات"
-msgstr[1] "ثُبّت تحديث واحد"
-msgstr[2] "ثُبّت تحديثين"
+msgstr[0] "لم تُثبّت أي تحديثات%.0s"
+msgstr[1] "ثُبّت تحديث واحد%.0s"
+msgstr[2] "ثُبّت تحديثين%.0s"
msgstr[3] "ثُبّتت %s تحديثات"
msgstr[4] "ثُبّت %s تحديثا"
msgstr[5] "ثُبّت %s تحديث"
diff --git a/po/de.po b/po/de.po
index 5ca6d88..1624694 100644
--- a/po/de.po
+++ b/po/de.po
@@ -10,14 +10,42 @@
# 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.
+# SOME DESCRIPTIVE TITLE.
+# 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.
+# SOME DESCRIPTIVE TITLE.
+# 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.
+# SOME DESCRIPTIVE TITLE.
+# 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.
+# SOME DESCRIPTIVE TITLE.
+# 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.
+# SOME DESCRIPTIVE TITLE.
+# 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.
+# SOME DESCRIPTIVE TITLE.
+# 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.
+# SOME DESCRIPTIVE TITLE.
+# 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.
# This file is distributed under the same license as the PACKAGE package.
# Fabian Affolter <fab@fedoraproject.org>, 2007.
msgid ""
msgstr ""
"Project-Id-Version: sugar\n"
"Report-Msgid-Bugs-To: \n"
-"POT-Creation-Date: 2010-03-11 00:31-0500\n"
-"PO-Revision-Date: 2010-03-29 01:49+0200\n"
+"POT-Creation-Date: 2010-12-23 01:15-0500\n"
+"PO-Revision-Date: 2011-01-18 10:34+0200\n"
"Last-Translator: Markus <m.slg@gmx.de>\n"
"Language-Team: German <fedora-trans-de@redhat.com>\n"
"Language: de\n"
@@ -32,43 +60,39 @@ msgstr ""
msgid "About Me"
msgstr "Über mich"
-#: ../extensions/cpsection/aboutme/model.py:43
+#: ../extensions/cpsection/aboutme/model.py:48
msgid "You must enter a name."
msgstr "Bitte einen Namen eingeben."
-#: ../extensions/cpsection/aboutme/model.py:68
+#: ../extensions/cpsection/aboutme/model.py:75
#, python-format
msgid "stroke: color=%s hue=%s"
msgstr "Linie: Farbe=%s Farbton=%s"
-#: ../extensions/cpsection/aboutme/model.py:71
+#: ../extensions/cpsection/aboutme/model.py:78
#, python-format
msgid "stroke: %s"
msgstr "Linie: %s"
-#: ../extensions/cpsection/aboutme/model.py:73
+#: ../extensions/cpsection/aboutme/model.py:80
#, python-format
msgid "fill: color=%s hue=%s"
-msgstr "Füllung: Farbe=%s Farbton=%s"
+msgstr "Füllung: Farbe=%s Farbton=%s"
-#: ../extensions/cpsection/aboutme/model.py:75
+#: ../extensions/cpsection/aboutme/model.py:82
#, python-format
msgid "fill: %s"
-msgstr "Füllung: %s"
+msgstr "Füllung: %s"
-#: ../extensions/cpsection/aboutme/model.py:86
+#: ../extensions/cpsection/aboutme/model.py:94
msgid "Error in specified color modifiers."
msgstr "Fehler in den angegebenen Farbänderungen."
-#: ../extensions/cpsection/aboutme/model.py:89
+#: ../extensions/cpsection/aboutme/model.py:97
msgid "Error in specified colors."
msgstr "Fehler in den angegebenen Farben."
-#: ../extensions/cpsection/aboutme/view.py:94 ../src/jarabe/intro/window.py:93
-msgid "Name:"
-msgstr "Name:"
-
-#: ../extensions/cpsection/aboutme/view.py:128
+#: ../extensions/cpsection/aboutme/view.py:235
msgid "Click to change your color:"
msgstr "Klicken, um deine Farbe zu wechseln:"
@@ -76,43 +100,43 @@ msgstr "Klicken, um deine Farbe zu wechseln:"
msgid "About my Computer"
msgstr "Über meinen Computer"
-#: ../extensions/cpsection/aboutcomputer/model.py:28
+#: ../extensions/cpsection/aboutcomputer/model.py:29
msgid "Not available"
msgstr "Nicht verfügbar"
-#: ../extensions/cpsection/aboutcomputer/view.py:60
+#: ../extensions/cpsection/aboutcomputer/view.py:61
msgid "Identity"
msgstr "Identität"
-#: ../extensions/cpsection/aboutcomputer/view.py:69
+#: ../extensions/cpsection/aboutcomputer/view.py:70
msgid "Serial Number:"
msgstr "Seriennummer:"
-#: ../extensions/cpsection/aboutcomputer/view.py:91
+#: ../extensions/cpsection/aboutcomputer/view.py:92
msgid "Software"
msgstr "Software"
-#: ../extensions/cpsection/aboutcomputer/view.py:100
+#: ../extensions/cpsection/aboutcomputer/view.py:101
msgid "Build:"
msgstr "Version:"
-#: ../extensions/cpsection/aboutcomputer/view.py:115
+#: ../extensions/cpsection/aboutcomputer/view.py:116
msgid "Sugar:"
msgstr "Sugar:"
-#: ../extensions/cpsection/aboutcomputer/view.py:131
+#: ../extensions/cpsection/aboutcomputer/view.py:132
msgid "Firmware:"
msgstr "Firmware:"
-#: ../extensions/cpsection/aboutcomputer/view.py:146
+#: ../extensions/cpsection/aboutcomputer/view.py:147
msgid "Wireless Firmware:"
msgstr "WLAN-Firmware:"
-#: ../extensions/cpsection/aboutcomputer/view.py:169
+#: ../extensions/cpsection/aboutcomputer/view.py:170
msgid "Copyright and License"
msgstr "Copyright und Lizenz"
-#: ../extensions/cpsection/aboutcomputer/view.py:184
+#: ../extensions/cpsection/aboutcomputer/view.py:188
msgid ""
"Sugar is the graphical user interface that you are looking at. Sugar is free "
"software, covered by the GNU General Public License, and you are welcome to "
@@ -124,7 +148,7 @@ msgstr ""
"darin festgelegten Bedingungen ist es erlaubt, die Software zu verändern "
"und/oder Kopien davon zu erstellen und zu verteilen."
-#: ../extensions/cpsection/aboutcomputer/view.py:196
+#: ../extensions/cpsection/aboutcomputer/view.py:200
msgid "Full license:"
msgstr "Vollständige Lizenz:"
@@ -132,11 +156,11 @@ msgstr "Vollständige Lizenz:"
msgid "Date & Time"
msgstr "Datum & Uhrzeit"
-#: ../extensions/cpsection/datetime/model.py:87
+#: ../extensions/cpsection/datetime/model.py:92
msgid "Error timezone does not exist."
msgstr "Fehler: unbekannte Zeitzone."
-#: ../extensions/cpsection/datetime/view.py:68 ../data/sugar.schemas.in.h:47
+#: ../extensions/cpsection/datetime/view.py:70 ../data/sugar.schemas.in.h:52
msgid "Timezone"
msgstr "Zeitzone"
@@ -145,51 +169,51 @@ msgstr "Zeitzone"
msgid "Frame"
msgstr "Rahmen"
-#: ../extensions/cpsection/frame/model.py:38
-#: ../extensions/cpsection/frame/model.py:60
+#: ../extensions/cpsection/frame/model.py:41
+#: ../extensions/cpsection/frame/model.py:66
msgid "Value must be an integer."
msgstr "Der Wert muss ganzzahlig sein."
-#: ../extensions/cpsection/frame/view.py:26
+#: ../extensions/cpsection/frame/view.py:27
msgid "never"
msgstr "nie"
# (Markus S.) ' unmittelbar'?
-#: ../extensions/cpsection/frame/view.py:27
+#: ../extensions/cpsection/frame/view.py:28
msgid "instantaneous"
msgstr "sofort"
-#: ../extensions/cpsection/frame/view.py:28
+#: ../extensions/cpsection/frame/view.py:29
#, python-format
msgid "%s seconds"
msgstr "%s Sekunden"
-#: ../extensions/cpsection/frame/view.py:52
+#: ../extensions/cpsection/frame/view.py:54
msgid "Activation Delay"
msgstr "Aktivierungsverzögerung"
-#: ../extensions/cpsection/frame/view.py:76
+#: ../extensions/cpsection/frame/view.py:78
msgid "Corner"
msgstr "Ecke"
-#: ../extensions/cpsection/frame/view.py:111
+#: ../extensions/cpsection/frame/view.py:113
msgid "Edge"
-msgstr "Kante"
+msgstr "Rand"
#: ../extensions/cpsection/keyboard/__init__.py:21
-#: ../extensions/cpsection/keyboard/view.py:31
+#: ../extensions/cpsection/keyboard/view.py:32
msgid "Keyboard"
msgstr "Tastatur"
-#: ../extensions/cpsection/keyboard/view.py:189
+#: ../extensions/cpsection/keyboard/view.py:190
msgid "Keyboard Model"
msgstr "Tastaturmodell"
-#: ../extensions/cpsection/keyboard/view.py:248
+#: ../extensions/cpsection/keyboard/view.py:250
msgid "Key(s) to change layout"
msgstr "Taste(n) zum Layoutwechsel"
-#: ../extensions/cpsection/keyboard/view.py:318
+#: ../extensions/cpsection/keyboard/view.py:319
msgid "Keyboard Layout(s)"
msgstr "Tastaturlayout(s)"
@@ -198,21 +222,21 @@ msgstr "Tastaturlayout(s)"
msgid "Language"
msgstr "Sprache"
-#: ../extensions/cpsection/language/model.py:28
+#: ../extensions/cpsection/language/model.py:30
msgid "Could not access ~/.i18n. Create standard settings."
msgstr "Zugriff auf ~/.i18n nicht möglich. Erzeuge daher Standardeinstellungen."
-#: ../extensions/cpsection/language/model.py:124
+#: ../extensions/cpsection/language/model.py:131
#, python-format
msgid "Language for code=%s could not be determined."
msgstr "Sprache für Code=%s konnte nicht ermittelt werden."
-#: ../extensions/cpsection/language/model.py:144
+#: ../extensions/cpsection/language/model.py:152
#, python-format
msgid "Sorry I do not speak '%s'."
msgstr "Entschuldigung, ich spreche nicht '%s'."
-#: ../extensions/cpsection/language/view.py:56
+#: ../extensions/cpsection/language/view.py:57
msgid ""
"Add languages in the order you prefer. If a translation is not available, "
"the next in the list will be used."
@@ -224,31 +248,31 @@ msgstr ""
msgid "Modem Configuration"
msgstr "Modem-Konfiguration"
-#: ../extensions/cpsection/modemconfiguration/view.py:91
+#: ../extensions/cpsection/modemconfiguration/view.py:94
msgid "Username:"
msgstr "Benutzername:"
-#: ../extensions/cpsection/modemconfiguration/view.py:102
+#: ../extensions/cpsection/modemconfiguration/view.py:106
msgid "Password:"
msgstr "Passwort:"
-#: ../extensions/cpsection/modemconfiguration/view.py:113
+#: ../extensions/cpsection/modemconfiguration/view.py:118
msgid "Number:"
msgstr "Nummer:"
-#: ../extensions/cpsection/modemconfiguration/view.py:124
+#: ../extensions/cpsection/modemconfiguration/view.py:130
msgid "Access Point Name (APN):"
-msgstr "Access-Point-Name (APN):"
+msgstr "Name des Zugangspunktes (APN):"
-#: ../extensions/cpsection/modemconfiguration/view.py:135
+#: ../extensions/cpsection/modemconfiguration/view.py:142
msgid "Personal Identity Number (PIN):"
msgstr "Persönliche Kennnumer (PIN):"
-#: ../extensions/cpsection/modemconfiguration/view.py:146
+#: ../extensions/cpsection/modemconfiguration/view.py:154
msgid "Personal Unblocking Key (PUK):"
msgstr "Persönlicher Freischaltschlüssel (PUK):"
-#: ../extensions/cpsection/modemconfiguration/view.py:167
+#: ../extensions/cpsection/modemconfiguration/view.py:175
msgid ""
"You will need to provide the following information to set up a mobile "
"broadband connection to a cellular (3G) network."
@@ -257,52 +281,52 @@ msgstr ""
"Mobilfunknetz (3G) aufzubauen."
#: ../extensions/cpsection/network/__init__.py:21
-#: ../extensions/cpsection/network/view.py:28
+#: ../extensions/cpsection/network/view.py:29
msgid "Network"
msgstr "Netzwerk"
-#: ../extensions/cpsection/network/model.py:79
+#: ../extensions/cpsection/network/model.py:68
msgid "State is unknown."
msgstr "Status ist nicht bekannt."
# (Markus S.) vgl. http://lists.laptop.org/pipermail/localization/2008-July/001232.html
-#: ../extensions/cpsection/network/model.py:105
+#: ../extensions/cpsection/network/model.py:96
msgid "Error in specified radio argument use on/off."
msgstr "Fehler im angegebenen Funknetzparameter -- on/off verwenden."
# (Markus S.) vgl. http://lists.laptop.org/pipermail/localization/2008-July/001232.html
-#: ../extensions/cpsection/network/model.py:137
+#: ../extensions/cpsection/network/model.py:133
msgid "Error in specified argument use 0/1."
msgstr "Fehler im angegebenen Parameter -- 0/1 verwenden."
-#: ../extensions/cpsection/network/view.py:59
+#: ../extensions/cpsection/network/view.py:61
msgid "Wireless"
msgstr "Funknetzwerk"
-#: ../extensions/cpsection/network/view.py:67
+#: ../extensions/cpsection/network/view.py:69
msgid "Turn off the wireless radio to save battery life"
msgstr "Schalte das Funknetz aus, um die Lebensdauer der Batterie zu erhöhen."
# (Markus S,) war 'Radio:'
-#: ../extensions/cpsection/network/view.py:80
+#: ../extensions/cpsection/network/view.py:82
msgid "Radio"
msgstr "Funknetz"
-#: ../extensions/cpsection/network/view.py:96
+#: ../extensions/cpsection/network/view.py:98
msgid "Discard network history if you have trouble connecting to the network"
msgstr ""
"Verwirf die Netzwerk-Chronik, wenn du Schwierigkeiten hast, dich mit dem "
"Netzwerk zu verbinden."
-#: ../extensions/cpsection/network/view.py:105
+#: ../extensions/cpsection/network/view.py:107
msgid "Discard network history"
msgstr "Netzwerk-Chronik verwerfen"
-#: ../extensions/cpsection/network/view.py:118
+#: ../extensions/cpsection/network/view.py:120
msgid "Collaboration"
msgstr "Zusammenarbeit"
-#: ../extensions/cpsection/network/view.py:126
+#: ../extensions/cpsection/network/view.py:128
msgid ""
"The server is the equivalent of what room you are in; people on the same "
"server will be able to see each other, even when they aren't on the same "
@@ -312,7 +336,7 @@ msgstr ""
"Server können einander sehen, selbst wenn sie sich nicht im selben Netzwerk "
"befinden."
-#: ../extensions/cpsection/network/view.py:136
+#: ../extensions/cpsection/network/view.py:138
msgid "Server:"
msgstr "Server:"
@@ -321,25 +345,25 @@ msgid "Power"
msgstr "Energieversorgung"
# (Markus S.) vgl. http://lists.laptop.org/pipermail/localization/2008-July/001232.html
-#: ../extensions/cpsection/power/model.py:85
+#: ../extensions/cpsection/power/model.py:90
msgid "Error in automatic pm argument, use on/off."
msgstr ""
"Fehler im automatischen Energieverwaltungsparameter -- on/off verwenden."
# (Markus S.) vgl. http://lists.laptop.org/pipermail/localization/2008-July/001232.html
-#: ../extensions/cpsection/power/model.py:112
+#: ../extensions/cpsection/power/model.py:120
msgid "Error in extreme pm argument, use on/off."
msgstr "Fehler im extremen Energieverwaltungsparameter -- on/off verwenden."
-#: ../extensions/cpsection/power/view.py:47
+#: ../extensions/cpsection/power/view.py:48
msgid "Power management"
msgstr "Energieverwaltung"
-#: ../extensions/cpsection/power/view.py:57
+#: ../extensions/cpsection/power/view.py:58
msgid "Automatic power management (increases battery life)"
msgstr "Automatische Energieverwaltung (erhöht die Lebensdauer der Batterie)"
-#: ../extensions/cpsection/power/view.py:85
+#: ../extensions/cpsection/power/view.py:86
msgid ""
"Extreme power management (disableswireless radio, increases battery life)"
msgstr ""
@@ -381,37 +405,37 @@ msgstr "Deine Software ist auf dem neuesten Stand."
#, python-format
msgid "You can install %s update"
msgid_plural "You can install %s updates"
-msgstr[0] "Du kannst %s Update installieren."
-msgstr[1] "Du kannst %s Updates installieren."
+msgstr[0] "Du kannst %s Aktualisierung installieren."
+msgstr[1] "Du kannst %s Aktualisierungen installieren."
#: ../extensions/cpsection/updater/view.py:159
msgid "Checking for updates..."
-msgstr "Suche nach Updates..."
+msgstr "Suche nach Aktualisierungen..."
#: ../extensions/cpsection/updater/view.py:164
msgid "Installing updates..."
-msgstr "Installiere Updates..."
+msgstr "Installiere Aktualisierungen..."
-#: ../extensions/cpsection/updater/view.py:172
+#: ../extensions/cpsection/updater/view.py:173
#, python-format
msgid "%s update was installed"
msgid_plural "%s updates were installed"
-msgstr[0] "%s Update wurde installiert."
-msgstr[1] "%s Updates wurden installiert."
+msgstr[0] "%s Aktualisierung wurde installiert."
+msgstr[1] "%s Aktualisierungen wurden installiert."
-#: ../extensions/cpsection/updater/view.py:253
+#: ../extensions/cpsection/updater/view.py:255
msgid "Install selected"
msgstr "Auswahl installieren"
-#: ../extensions/cpsection/updater/view.py:274
+#: ../extensions/cpsection/updater/view.py:276
#, python-format
msgid "Download size: %s"
msgstr "Downloadgröße: %s"
-#: ../extensions/cpsection/updater/view.py:362
+#: ../extensions/cpsection/updater/view.py:364
#, python-format
-msgid "From version %(current)d to %(new)s (Size: %(size)s)"
-msgstr "Von Version %(current)d auf %(new)s (Größe: %(size)s)"
+msgid "From version %(current)s to %(new)s (Size: %(size)s)"
+msgstr "Von Version %(current)s auf %(new)s (Größe: %(size)s)"
#. TRANS: download size is 0
#: ../extensions/cpsection/updater/view.py:382
@@ -435,28 +459,28 @@ msgstr "%.0f KB"
msgid "%.1f MB"
msgstr "%.1f MB"
-#: ../extensions/deviceicon/battery.py:58
+#: ../extensions/deviceicon/battery.py:60
msgid "My Battery"
msgstr "Meine Batterie"
-#: ../extensions/deviceicon/battery.py:137
+#: ../extensions/deviceicon/battery.py:141
msgid "Removed"
msgstr "Entfernt"
-#: ../extensions/deviceicon/battery.py:140
+#: ../extensions/deviceicon/battery.py:144
msgid "Charging"
-msgstr "Aufladen"
+msgstr "Wird aufgeladen"
-#: ../extensions/deviceicon/battery.py:143
+#: ../extensions/deviceicon/battery.py:147
msgid "Very little power remaining"
msgstr "Sehr wenig Ladung verbleibend"
-#: ../extensions/deviceicon/battery.py:149
+#: ../extensions/deviceicon/battery.py:153
#, python-format
msgid "%(hour)d:%(min).2d remaining"
msgstr "%(hour)d:%(min).2d verbleibend"
-#: ../extensions/deviceicon/battery.py:152
+#: ../extensions/deviceicon/battery.py:156
msgid "Charged"
msgstr "Aufgeladen"
@@ -469,134 +493,180 @@ msgstr "IP-Addresse: %s"
# priority over the normal wireless device. NM doesn't have a "disconnect"
# method for a device either (for various reasons) so this doesn't
# have a good mapping
-#: ../extensions/deviceicon/network.py:112
+#: ../extensions/deviceicon/network.py:104
msgid "Disconnect..."
msgstr "Verbindung trennen..."
-#: ../extensions/deviceicon/network.py:117
-msgid "Create new wireless network"
-msgstr "Neues Funknetzwerk erstellen"
-
# Only show disconnect when there's a mesh device, because mesh takes
# priority over the normal wireless device. NM doesn't have a "disconnect"
# method for a device either (for various reasons) so this doesn't
# have a good mapping
-#: ../extensions/deviceicon/network.py:123
-#: ../extensions/deviceicon/network.py:285
-#: ../src/jarabe/desktop/meshbox.py:247 ../src/jarabe/desktop/meshbox.py:536
+#: ../extensions/deviceicon/network.py:112
+#: ../extensions/deviceicon/network.py:290
+#: ../src/jarabe/desktop/networkviews.py:239
+#: ../src/jarabe/desktop/networkviews.py:538
+#: ../src/jarabe/desktop/networkviews.py:667
msgid "Connecting..."
msgstr "Verbinde..."
# TODO: show the channel number
-#: ../extensions/deviceicon/network.py:127
-#: ../extensions/deviceicon/network.py:199
-#: ../extensions/deviceicon/network.py:289
-#: ../src/jarabe/desktop/meshbox.py:253 ../src/jarabe/desktop/meshbox.py:542
+#: ../extensions/deviceicon/network.py:116
+#: ../extensions/deviceicon/network.py:182
+#: ../src/jarabe/desktop/networkviews.py:249
+#: ../src/jarabe/desktop/networkviews.py:544
+#: ../src/jarabe/desktop/networkviews.py:673
msgid "Connected"
msgstr "Verbunden"
-#: ../extensions/deviceicon/network.py:159
+#: ../extensions/deviceicon/network.py:142
msgid "Channel"
msgstr "Kanal"
-#: ../extensions/deviceicon/network.py:174
+#: ../extensions/deviceicon/network.py:157
msgid "Wired Network"
msgstr "Kabelnetzwerk"
# (Markus S.) War 'Geschwindigkeit'
-#: ../extensions/deviceicon/network.py:202
+#: ../extensions/deviceicon/network.py:185
msgid "Speed"
msgstr "Übertragungsrate"
-#: ../extensions/deviceicon/network.py:229
+#: ../extensions/deviceicon/network.py:211
msgid "Wireless modem"
msgstr "Funkmodem"
-#: ../extensions/deviceicon/network.py:277
+#: ../extensions/deviceicon/network.py:278
msgid "Please wait..."
msgstr "Bitte warten..."
-#: ../extensions/deviceicon/network.py:280
-#: ../src/jarabe/desktop/meshbox.py:163 ../src/jarabe/desktop/meshbox.py:493
+#: ../extensions/deviceicon/network.py:282
+#: ../src/jarabe/desktop/networkviews.py:149
+#: ../src/jarabe/desktop/networkviews.py:492
+#: ../src/jarabe/desktop/networkviews.py:624
msgid "Connect"
msgstr "Verbinden"
-#: ../extensions/deviceicon/network.py:281
+#: ../extensions/deviceicon/network.py:283
msgid "Disconnected"
msgstr "Nicht verbunden"
-#: ../extensions/deviceicon/network.py:284
-#: ../src/jarabe/controlpanel/toolbar.py:115
-#: ../src/jarabe/desktop/homebox.py:68
-#: ../src/jarabe/frame/activitiestray.py:700
-#: ../src/jarabe/frame/activitiestray.py:799
-#: ../src/jarabe/frame/activitiestray.py:827
+#: ../extensions/deviceicon/network.py:289
+#: ../src/jarabe/controlpanel/toolbar.py:119
+#: ../src/jarabe/desktop/homebox.py:70
+#: ../src/jarabe/frame/activitiestray.py:587
+#: ../src/jarabe/frame/activitiestray.py:687
+#: ../src/jarabe/frame/activitiestray.py:715
msgid "Cancel"
msgstr "Abbrechen"
# (mschlager) war 'Nicht verbunden', ich würde aber eher erwarten, dass das die Beschriftung eines Menüeintrags ist, mit dem man eine Verbindung trennt, was dann in der Folge die Meldung 'Disconnecting...' liefert.
-#: ../extensions/deviceicon/network.py:288
-#: ../src/jarabe/desktop/meshbox.py:167
+#: ../extensions/deviceicon/network.py:297
+#: ../src/jarabe/desktop/networkviews.py:153
+#: ../src/jarabe/desktop/networkviews.py:496
msgid "Disconnect"
msgstr "Verbindung trennen"
-#: ../extensions/deviceicon/network.py:292
-msgid "Sim requires Pin/Puk"
-msgstr "Sim benötigt PIN/PUK"
+#: ../extensions/deviceicon/network.py:327
+msgid "Try connection again"
+msgstr "Erneuter Verbindungsversuch"
+
+#: ../extensions/deviceicon/network.py:330
+#, python-format
+msgid "Error: %s"
+msgstr "Fehler: %s"
+
+#: ../extensions/deviceicon/network.py:334
+#, python-format
+msgid "Suggestion: %s"
+msgstr "Vorschlag: %s"
-#: ../extensions/deviceicon/network.py:293
-msgid "Authentication Error"
-msgstr "Authentifizierungsfehler"
+#: ../extensions/deviceicon/network.py:340
+#: ../extensions/deviceicon/network.py:343
+#, python-format
+msgid "Connected for %s"
+msgstr "Verbunden für %s"
-#: ../extensions/deviceicon/network.py:538
+#: ../extensions/deviceicon/network.py:348
+#: ../extensions/deviceicon/network.py:349
#, python-format
-msgid "%s's network"
-msgstr "Netzwerk von %s"
+msgid "%d KB"
+msgstr "%d KB"
+
+#: ../extensions/deviceicon/network.py:354
+msgid "Check your Pin/Puk configuration."
+msgstr "Überprüfe deine Pin/Puk-Einstellungen."
+
+#: ../extensions/deviceicon/network.py:357
+msgid "Check your Access Point Name (APN) configuration"
+msgstr "Überprüfe deine Einstellung für den Namen des Zugangspunktes (APN)."
+
+#: ../extensions/deviceicon/network.py:361
+msgid "Check the Number configuration."
+msgstr "Überprüfe deine Einstellung der Nummer."
-#: ../extensions/deviceicon/network.py:605
-#: ../extensions/deviceicon/network.py:664
+#: ../extensions/deviceicon/network.py:363
+msgid "Check your configuration."
+msgstr "Überprüfe deine Einstellungen."
+
+#: ../extensions/deviceicon/network.py:615
msgid "Mesh Network"
msgstr "Maschennetzwerk"
-#: ../extensions/deviceicon/network.py:869
+#: ../extensions/deviceicon/network.py:658
#, python-format
-msgid "Data sent %d KB / received %d KB"
-msgstr "gesendet %d KB / empfangen %d KB"
+msgid "Mesh Network %s"
+msgstr "Maschennetzwerk %s"
+
+#: ../extensions/deviceicon/network.py:782
+msgid "No GSM connection available."
+msgstr "Keine GSM-Verbindung verfügbar."
-#: ../extensions/deviceicon/network.py:880
-msgid "Connection time "
-msgstr "Verbindungsdauer "
+#: ../extensions/deviceicon/network.py:783
+msgid "Create a connection in the control panel."
+msgstr "Verbindung in der Menüleiste erstellen."
-#: ../extensions/deviceicon/speaker.py:59
+#: ../extensions/deviceicon/speaker.py:60
msgid "My Speakers"
msgstr "Meine Lautsprecher"
-#: ../extensions/deviceicon/speaker.py:133
+#: ../extensions/deviceicon/speaker.py:136
msgid "Unmute"
msgstr "Laut schalten"
-#: ../extensions/deviceicon/speaker.py:136
+#: ../extensions/deviceicon/speaker.py:139
msgid "Mute"
msgstr "Stumm schalten"
+#: ../extensions/deviceicon/touchpad.py:37
+msgid "finger"
+msgstr "Finger"
+
+#: ../extensions/deviceicon/touchpad.py:38
+msgid "stylus"
+msgstr "Stift"
+
+#: ../extensions/deviceicon/touchpad.py:67
+msgid "My touchpad"
+msgstr "Mein Touchpad"
+
# (Markus S.) 'Zelle'?
#: ../extensions/globalkey/screenshot.py:59
msgid "Mesh"
msgstr "Masche"
#: ../extensions/globalkey/screenshot.py:61
-#: ../src/jarabe/frame/zoomtoolbar.py:39
+#: ../src/jarabe/frame/zoomtoolbar.py:40
msgid "Group"
msgstr "Gruppe"
# (Markus S.) war 'Zuhause', vgl. stuffer-sheet
#: ../extensions/globalkey/screenshot.py:63
-#: ../src/jarabe/frame/zoomtoolbar.py:41
+#: ../src/jarabe/frame/zoomtoolbar.py:42
msgid "Home"
msgstr "Startbildschirm"
#: ../extensions/globalkey/screenshot.py:69
-#: ../src/jarabe/frame/zoomtoolbar.py:43
+#: ../src/jarabe/frame/zoomtoolbar.py:44
msgid "Activity"
msgstr "Aktivität"
@@ -627,6 +697,10 @@ msgid "Backup URL"
msgstr "Backup-URL"
#: ../data/sugar.schemas.in.h:4
+msgid "Bundle IDs of protected activities"
+msgstr "IDs geschützter Aktivitäten bündeln"
+
+#: ../data/sugar.schemas.in.h:5
msgid ""
"Color for the XO icon that is used throughout the desktop. The string is "
"composed of the stroke color and fill color, format is that of rbg colors. "
@@ -636,103 +710,103 @@ msgstr ""
"Zeichenkette setzt sich aus der Linien- und der Füllfarbe zusammen, die "
"jeweils als RGB-Farben angeben werden. Beispiel: #AC32FF,#9A5200"
-#: ../data/sugar.schemas.in.h:5
+#: ../data/sugar.schemas.in.h:6
msgid "Corner Delay"
msgstr "Eckenverzögerung"
-#: ../data/sugar.schemas.in.h:6
+#: ../data/sugar.schemas.in.h:7
msgid "Default font face"
msgstr "Standard-Schriftart"
-#: ../data/sugar.schemas.in.h:7
+#: ../data/sugar.schemas.in.h:8
msgid "Default font size"
msgstr "Standard-Schriftgröße"
-#: ../data/sugar.schemas.in.h:8
+#: ../data/sugar.schemas.in.h:9
msgid "Default nick"
msgstr "Standard-Benutzername"
-#: ../data/sugar.schemas.in.h:9
+#: ../data/sugar.schemas.in.h:10
msgid "Delay for the activation of the frame using the corners."
msgstr "Verzögerung bei der Aktivierung eines Rahmens über die Ecken."
-#: ../data/sugar.schemas.in.h:10
+#: ../data/sugar.schemas.in.h:11
msgid "Delay for the activation of the frame using the edges."
msgstr "Verzögerung bei der Aktivierung eines Rahmens über die Ränder."
-#: ../data/sugar.schemas.in.h:11
+#: ../data/sugar.schemas.in.h:12
msgid "Directory to search for translations"
msgstr "Verzeichnis zur Suche nach Übersetzungen"
-#: ../data/sugar.schemas.in.h:12
+#: ../data/sugar.schemas.in.h:13
msgid "Edge Delay"
msgstr "Randverzögerung"
-#: ../data/sugar.schemas.in.h:13
+#: ../data/sugar.schemas.in.h:14
msgid "Favorites Layout"
msgstr "Favoriten-Layout"
-#: ../data/sugar.schemas.in.h:14
+#: ../data/sugar.schemas.in.h:15
msgid "Favorites resume mode"
msgstr "Favoriten-Wiederaufnahmemodus"
-#: ../data/sugar.schemas.in.h:15
+#: ../data/sugar.schemas.in.h:16
msgid "Font face that is used throughout the desktop."
msgstr "Schriftart, die auf dem Desktop benutzt wird."
-#: ../data/sugar.schemas.in.h:16
+#: ../data/sugar.schemas.in.h:17
msgid "Font size that is used throughout the desktop."
msgstr "Schriftgröße, die auf dem Desktop benutzt wird."
-#: ../data/sugar.schemas.in.h:17
+#: ../data/sugar.schemas.in.h:18
msgid "GSM network APN"
msgstr "GSM-Netzwerk APN"
-#: ../data/sugar.schemas.in.h:18
+#: ../data/sugar.schemas.in.h:19
msgid "GSM network PIN"
msgstr "GSM-Netzwerk PIN"
-#: ../data/sugar.schemas.in.h:19
+#: ../data/sugar.schemas.in.h:20
msgid "GSM network PUK"
msgstr "GSM-Netzwerk PUK"
-#: ../data/sugar.schemas.in.h:20
+#: ../data/sugar.schemas.in.h:21
msgid "GSM network access point name configuration"
-msgstr "GSM-Netzwerk Namenseinstellung Zugriffspunkt"
+msgstr "GSM-Netzwerk Einstellung des Namens des Zugangspunktes"
-#: ../data/sugar.schemas.in.h:21
+#: ../data/sugar.schemas.in.h:22
msgid "GSM network number"
msgstr "GSM-Netzwerk Nummer"
-#: ../data/sugar.schemas.in.h:22
+#: ../data/sugar.schemas.in.h:23
msgid "GSM network password"
msgstr "GSM-Netzwerk Passwort"
-#: ../data/sugar.schemas.in.h:23
+#: ../data/sugar.schemas.in.h:24
msgid "GSM network password configuration"
msgstr "GSM-Netzwerk Passworteinstellung"
-#: ../data/sugar.schemas.in.h:24
+#: ../data/sugar.schemas.in.h:25
msgid "GSM network personal identification number configuration"
msgstr "GSM-Netzwerk PIN-Einstellung"
-#: ../data/sugar.schemas.in.h:25
+#: ../data/sugar.schemas.in.h:26
msgid "GSM network personal unlock key configuration"
msgstr "GSM-Netzwerk PUK-Einstellung"
-#: ../data/sugar.schemas.in.h:26
+#: ../data/sugar.schemas.in.h:27
msgid "GSM network telephone number configuration"
-msgstr "GSM-Netzwerk Telefonnummereinstellung"
+msgstr "GSM-Netzwerk Telefonnummerneinstellung"
-#: ../data/sugar.schemas.in.h:27
+#: ../data/sugar.schemas.in.h:28
msgid "GSM network username"
msgstr "GSM-Netzwerk Benutzername"
-#: ../data/sugar.schemas.in.h:28
+#: ../data/sugar.schemas.in.h:29
msgid "GSM network username configuration"
-msgstr "GSM-Netzwerk Benutzernameneinstellung"
+msgstr "GSM-Netzwerk Benutzernamenseinstellung"
-#: ../data/sugar.schemas.in.h:29
+#: ../data/sugar.schemas.in.h:30
msgid ""
"If TRUE, Sugar will make us searchable for the other users of the Jabber "
"server."
@@ -740,112 +814,140 @@ msgstr ""
"Falls WAHR, wird Sugar es für andere Nutzer des Jabber-Servers zulassen, uns "
"zu suchen."
-#: ../data/sugar.schemas.in.h:30
+#: ../data/sugar.schemas.in.h:31
msgid "If TRUE, Sugar will show a \"Log out\" option."
msgstr "Falls WAHR, wird Sugar die Option \"Abmelden\" anzeigen."
-#: ../data/sugar.schemas.in.h:31
+#: ../data/sugar.schemas.in.h:32
+msgid "If TRUE, Sugar will show a \"Restart\" option."
+msgstr "Falls WAHR, wird Sugar die Option \"Neustart\" anzeigen."
+
+#: ../data/sugar.schemas.in.h:33
+msgid ""
+"If TRUE, Sugar will show default Ad-hoc networks for channel 1,6 and 11. If "
+"Sugar sees no \"known\" network when it starts, it does autoconnect to an Ad-"
+"hoc network."
+msgstr ""
+"Falls WAHR, wird Sugar standardmäßige Ad-hoc-Netzwerke für Kanal 1, 6 und 11 "
+"anzeigen. Wenn Sugar beim Start kein \"bekanntes\" Netzwerk erkennt, "
+"verbindet es sich automatisch mit einem Ad-hoc-Netzwerk."
+
+#: ../data/sugar.schemas.in.h:34
msgid "Jabber Server"
msgstr "Jabber-Server"
-#: ../data/sugar.schemas.in.h:32
+#: ../data/sugar.schemas.in.h:35
msgid "Keyboard layouts"
msgstr "Tastaturlayouts"
-#: ../data/sugar.schemas.in.h:33
+#: ../data/sugar.schemas.in.h:36
msgid "Keyboard model"
msgstr "Tastaturmodell"
-#: ../data/sugar.schemas.in.h:34
+#: ../data/sugar.schemas.in.h:37
msgid "Keyboard options"
msgstr "Tastatureinstellungen"
-#: ../data/sugar.schemas.in.h:35
+#: ../data/sugar.schemas.in.h:38
msgid "Layout of the favorites view."
msgstr "Layout der Favoriten-Ansicht."
-#: ../data/sugar.schemas.in.h:36
+#: ../data/sugar.schemas.in.h:39
msgid ""
"List of keyboard layouts. Each entry should be in the form layout(variant)"
msgstr ""
"Liste der Tastaturlayouts. Jeder Eintrag sollte von der Form "
"Layout(Variante) sein."
-#: ../data/sugar.schemas.in.h:37
+#: ../data/sugar.schemas.in.h:40
msgid "List of keyboard options."
msgstr "Liste der Tastatureinstellungen."
-#: ../data/sugar.schemas.in.h:38
+#: ../data/sugar.schemas.in.h:41
msgid "Power Automatic"
msgstr "Automatische Energieverwaltung"
-#: ../data/sugar.schemas.in.h:39
+#: ../data/sugar.schemas.in.h:42
msgid "Power Automatic."
msgstr "Automatische Energieverwaltung."
# (Markus S.) war 'Extreme Energieverwaltung'
-#: ../data/sugar.schemas.in.h:40
+#: ../data/sugar.schemas.in.h:43
msgid "Power Extreme"
msgstr "Extremes Energiesparen"
# (Markus S.) war 'Extreme Energieverwaltung'
-#: ../data/sugar.schemas.in.h:41
+#: ../data/sugar.schemas.in.h:44
msgid "Power Extreme."
msgstr "Extremes Energiesparen."
-#: ../data/sugar.schemas.in.h:42
+#: ../data/sugar.schemas.in.h:45
msgid "Publish to Gadget"
msgstr "Veröffentlichen auf Gerät"
-#: ../data/sugar.schemas.in.h:43
+#: ../data/sugar.schemas.in.h:46
msgid "Setting for muting the sound device."
msgstr "Einstellung zum Stummschalten der Audio-Ausgabe."
-#: ../data/sugar.schemas.in.h:44
+#: ../data/sugar.schemas.in.h:47
msgid "Show Log out"
msgstr "Abmelden anzeigen"
-#: ../data/sugar.schemas.in.h:45
+#: ../data/sugar.schemas.in.h:48
+msgid "Show Restart"
+msgstr "Neustart anzeigen"
+
+#: ../data/sugar.schemas.in.h:49
+msgid "Show Sugar Ad-hoc networks"
+msgstr "Sugar-Ad-hoc-Netzwerke anzeigen"
+
+#: ../data/sugar.schemas.in.h:50
msgid "Sound Muted"
msgstr "Stummgeschaltet"
-#: ../data/sugar.schemas.in.h:46
+#: ../data/sugar.schemas.in.h:51
msgid "The keyboard model to be used"
msgstr "Das zu verwendende Tastaturmodell"
-#: ../data/sugar.schemas.in.h:48
+#: ../data/sugar.schemas.in.h:53
msgid "Timezone setting for the system."
msgstr "Zeitzoneneinstellung des Systems."
-#: ../data/sugar.schemas.in.h:49
+#: ../data/sugar.schemas.in.h:54
msgid "Url of the jabber server to use."
msgstr "URL des zu nutzenden Jabber-Servers."
-#: ../data/sugar.schemas.in.h:50
+#: ../data/sugar.schemas.in.h:55
msgid "Url where the backup is saved to."
msgstr "URL, unter der das Backup gespeichert wird."
-#: ../data/sugar.schemas.in.h:51
+#: ../data/sugar.schemas.in.h:56
msgid "User Color"
msgstr "Benutzerfarbe"
-#: ../data/sugar.schemas.in.h:52
+#: ../data/sugar.schemas.in.h:57
msgid "User Name"
msgstr "Benutzername"
-#: ../data/sugar.schemas.in.h:53
+#: ../data/sugar.schemas.in.h:58
msgid "User name that is used throughout the desktop."
msgstr "Benutzername, der überall auf dem Desktop benutzt wird."
-#: ../data/sugar.schemas.in.h:54
+#: ../data/sugar.schemas.in.h:59
+msgid ""
+"Users will not be allowed to erase these activities through the list view."
+msgstr ""
+"Benutzer werden diese Aktivitäten nicht in der Listenansicht löschen können."
+
+#: ../data/sugar.schemas.in.h:60
msgid "Volume Level"
msgstr "Lautstärke"
-#: ../data/sugar.schemas.in.h:55
+#: ../data/sugar.schemas.in.h:61
msgid "Volume level for the sound device."
msgstr "Lautstärkepegel für die Audio-Ausgabe."
-#: ../data/sugar.schemas.in.h:56
+#: ../data/sugar.schemas.in.h:62
msgid ""
"When in resume mode, clicking on a favorite icon will cause the last entry "
"for that activity to be resumed."
@@ -877,7 +979,7 @@ msgstr "sugar-control-panel: %s"
# which must appear in the translated string (msgstr) as well.
#. TRANS: Translators, there's a empty line at the end of this string,
#. which must appear in the translated string (msgstr) as well.
-#: ../src/jarabe/controlpanel/cmd.py:37
+#: ../src/jarabe/controlpanel/cmd.py:38
msgid ""
"Usage: sugar-control-panel [ option ] key [ args ... ] \n"
" Control for the sugar environment. \n"
@@ -899,52 +1001,54 @@ msgstr ""
" -g Parameter Den aktuellen Wert für diesen Parameter auslesen\n"
" -s Parameter Den aktuellen Wert für diesen Parameter festlegen\n"
" -c Parameter Den aktuellen Wert für diesen Parameter zurücksetzen\n"
-" "
+" "
-#: ../src/jarabe/controlpanel/cmd.py:50
+#: ../src/jarabe/controlpanel/cmd.py:52
msgid "To apply your changes you have to restart sugar.\n"
msgstr "Um die Änderungen zu übernehmen, muss Sugar neu gestartet werden.\n"
-#: ../src/jarabe/controlpanel/gui.py:281
+#: ../src/jarabe/controlpanel/gui.py:285
+#: ../src/jarabe/journal/journaltoolbox.py:437
+#: ../src/jarabe/journal/volumestoolbar.py:158
msgid "Warning"
msgstr "Warnung"
-#: ../src/jarabe/controlpanel/gui.py:282
-#: ../src/jarabe/controlpanel/sectionview.py:42
+#: ../src/jarabe/controlpanel/gui.py:286
+#: ../src/jarabe/controlpanel/sectionview.py:41
msgid "Changes require restart"
msgstr "Neustart zur Übernahme der Änderungen notwendig"
-#: ../src/jarabe/controlpanel/gui.py:285
+#: ../src/jarabe/controlpanel/gui.py:289
msgid "Cancel changes"
msgstr "Änderungen verwerfen"
-#: ../src/jarabe/controlpanel/gui.py:290 ../src/jarabe/desktop/homebox.py:70
+#: ../src/jarabe/controlpanel/gui.py:294 ../src/jarabe/desktop/homebox.py:72
msgid "Later"
msgstr "Später"
-#: ../src/jarabe/controlpanel/gui.py:294
+#: ../src/jarabe/controlpanel/gui.py:298
msgid "Restart now"
msgstr "Jetzt neu starten"
-#: ../src/jarabe/controlpanel/toolbar.py:61 ../src/jarabe/intro/window.py:206
+#: ../src/jarabe/controlpanel/toolbar.py:63 ../src/jarabe/intro/window.py:211
msgid "Done"
msgstr "Fertig"
-#: ../src/jarabe/controlpanel/toolbar.py:121
-#: ../src/jarabe/desktop/favoritesview.py:333
+#: ../src/jarabe/controlpanel/toolbar.py:125
+#: ../src/jarabe/desktop/favoritesview.py:336
msgid "Ok"
msgstr "Ok"
-#: ../src/jarabe/desktop/activitieslist.py:236
+#: ../src/jarabe/desktop/activitieslist.py:230
#, python-format
msgid "Version %s"
msgstr "Version %s"
-#: ../src/jarabe/desktop/activitieslist.py:357
+#: ../src/jarabe/desktop/activitieslist.py:354
msgid "Confirm erase"
msgstr "Löschen bestätigen"
-#: ../src/jarabe/desktop/activitieslist.py:359
+#: ../src/jarabe/desktop/activitieslist.py:356
#, python-format
msgid "Confirm erase: Do you want to permanently erase %s?"
msgstr "Löschen bestätigen: Willst du %s wirklich dauerhaft löschen?"
@@ -953,388 +1057,444 @@ msgstr "Löschen bestätigen: Willst du %s wirklich dauerhaft löschen?"
# TODO: Implement stopping downloads
# self._stop_item.connect('activate', self._stop_item_activate_cb)
# self.append_menu_item(self._stop_item)
-#: ../src/jarabe/desktop/activitieslist.py:363
-#: ../src/jarabe/frame/clipboardmenu.py:63
-#: ../src/jarabe/view/viewsource.py:218
+#: ../src/jarabe/desktop/activitieslist.py:360
+#: ../src/jarabe/frame/clipboardmenu.py:64
+#: ../src/jarabe/view/viewsource.py:221
msgid "Keep"
msgstr "Behalten"
-#: ../src/jarabe/desktop/activitieslist.py:366
-#: ../src/jarabe/desktop/activitieslist.py:409
-#: ../src/jarabe/journal/journaltoolbox.py:360
-#: ../src/jarabe/journal/palettes.py:106
+#: ../src/jarabe/desktop/activitieslist.py:363
+#: ../src/jarabe/desktop/activitieslist.py:417
+#: ../src/jarabe/journal/journaltoolbox.py:391
+#: ../src/jarabe/journal/palettes.py:112
msgid "Erase"
msgstr "Löschen"
-#: ../src/jarabe/desktop/activitieslist.py:430
+#: ../src/jarabe/desktop/activitieslist.py:432
msgid "Remove favorite"
msgstr "Favorit entfernen"
-#: ../src/jarabe/desktop/activitieslist.py:434
+#: ../src/jarabe/desktop/activitieslist.py:436
msgid "Make favorite"
msgstr "Zum Favoriten machen"
# TRANS: label for the freeform layout in the favorites view
#. TRANS: label for the freeform layout in the favorites view
-#: ../src/jarabe/desktop/favoriteslayout.py:116
+#: ../src/jarabe/desktop/favoriteslayout.py:127
msgid "Freeform"
msgstr "Freie Form"
# TRANS: label for the ring layout in the favorites view
#. TRANS: label for the ring layout in the favorites view
-#: ../src/jarabe/desktop/favoriteslayout.py:198
+#: ../src/jarabe/desktop/favoriteslayout.py:215
msgid "Ring"
msgstr "Ring"
# TRANS: label for the spiral layout in the favorites view
#. TRANS: label for the spiral layout in the favorites view
-#: ../src/jarabe/desktop/favoriteslayout.py:337
+#: ../src/jarabe/desktop/favoriteslayout.py:402
msgid "Spiral"
msgstr "Spirale"
# TRANS: label for the box layout in the favorites view
#. TRANS: label for the box layout in the favorites view
-#: ../src/jarabe/desktop/favoriteslayout.py:404
+#: ../src/jarabe/desktop/favoriteslayout.py:472
msgid "Box"
msgstr "Rechteck"
# TRANS: label for the box layout in the favorites view
#. TRANS: label for the box layout in the favorites view
-#: ../src/jarabe/desktop/favoriteslayout.py:445
+#: ../src/jarabe/desktop/favoriteslayout.py:515
msgid "Triangle"
msgstr "Dreieck"
-#: ../src/jarabe/desktop/favoritesview.py:324
+#: ../src/jarabe/desktop/favoritesview.py:327
msgid "Registration Failed"
msgstr "Anmeldung fehlgeschlagen"
-#: ../src/jarabe/desktop/favoritesview.py:325
+#: ../src/jarabe/desktop/favoritesview.py:328
#, python-format
msgid "%s"
msgstr "%s"
-#: ../src/jarabe/desktop/favoritesview.py:327
+#: ../src/jarabe/desktop/favoritesview.py:330
msgid "Registration Successful"
msgstr "Anmeldung erfolgreich"
-#: ../src/jarabe/desktop/favoritesview.py:328
+#: ../src/jarabe/desktop/favoritesview.py:331
msgid "You are now registered with your school server."
msgstr "Du bist nun an deinem Schulserver angemeldet."
-#: ../src/jarabe/desktop/favoritesview.py:631
+#: ../src/jarabe/desktop/favoritesview.py:626
msgid "Register"
msgstr "Am Schulserver anmelden"
-#: ../src/jarabe/desktop/homebox.py:63
+#: ../src/jarabe/desktop/homebox.py:65
msgid "Software Update"
msgstr "Software-Aktualisierung"
-#: ../src/jarabe/desktop/homebox.py:64
+#: ../src/jarabe/desktop/homebox.py:66
msgid "Update your activities to ensure compatibility with your new software"
msgstr ""
"Aktualisiere deine Aktivitäten, um die Kompatibilität mit deiner neuen "
"Software sicherzustellen."
-#: ../src/jarabe/desktop/homebox.py:73
+#: ../src/jarabe/desktop/homebox.py:75
msgid "Check now"
msgstr "Jetzt prüfen"
-#: ../src/jarabe/desktop/homebox.py:192
+#: ../src/jarabe/desktop/homebox.py:193
msgid "List view"
msgstr "Listenansicht"
-#: ../src/jarabe/desktop/homebox.py:193
+#: ../src/jarabe/desktop/homebox.py:194
msgid "<Ctrl>2"
msgstr "<Ctrl>2"
-#: ../src/jarabe/desktop/homebox.py:255
+#: ../src/jarabe/desktop/homebox.py:257
msgid "Favorites view"
msgstr "Favoritenansicht"
-#: ../src/jarabe/desktop/homebox.py:256
+#: ../src/jarabe/desktop/homebox.py:258
msgid "<Ctrl>1"
msgstr "<Ctrl>1"
-#: ../src/jarabe/desktop/keydialog.py:135
+#: ../src/jarabe/desktop/keydialog.py:143
msgid "Key Type:"
msgstr "Schlüsseltyp:"
-#: ../src/jarabe/desktop/keydialog.py:155
+#: ../src/jarabe/desktop/keydialog.py:163
msgid "Authentication Type:"
msgstr "Authentifizierungstyp:"
-#: ../src/jarabe/desktop/keydialog.py:220
+#: ../src/jarabe/desktop/keydialog.py:229
msgid "WPA & WPA2 Personal"
msgstr "WPA & WPA2 Personal"
-#: ../src/jarabe/desktop/keydialog.py:229
+#: ../src/jarabe/desktop/keydialog.py:238
msgid "Wireless Security:"
msgstr "WLAN-Sicherheit:"
-#: ../src/jarabe/desktop/meshbox.py:491
-#, python-format
-msgid "Mesh Network %d"
-msgstr "Maschennetzwerk %d"
-
# TRANS: Action label for resuming an activity.
#. TRANS: Action label for resuming an activity.
-#: ../src/jarabe/desktop/meshbox.py:628
-#: ../src/jarabe/frame/activitiestray.py:735
-#: ../src/jarabe/journal/journaltoolbox.py:428
-#: ../src/jarabe/journal/palettes.py:66 ../src/jarabe/view/palettes.py:67
+#: ../src/jarabe/desktop/meshbox.py:109
+#: ../src/jarabe/frame/activitiestray.py:622
+#: ../src/jarabe/journal/journaltoolbox.py:485
+#: ../src/jarabe/journal/palettes.py:66 ../src/jarabe/view/palettes.py:78
msgid "Resume"
msgstr "Fortsetzen"
-#: ../src/jarabe/desktop/meshbox.py:633
-#: ../src/jarabe/frame/activitiestray.py:233
+#: ../src/jarabe/desktop/meshbox.py:114
+#: ../src/jarabe/frame/activitiestray.py:173
msgid "Join"
-msgstr "Mitmachen"
+msgstr "Beitreten"
+
+#: ../src/jarabe/desktop/networkviews.py:489
+#, python-format
+msgid "Ad-hoc Network %d"
+msgstr "Ad-hoc-Netzwerk %d"
+
+#: ../src/jarabe/desktop/networkviews.py:622
+#, python-format
+msgid "Mesh Network %d"
+msgstr "Maschennetzwerk %d"
-#: ../src/jarabe/desktop/schoolserver.py:104
+#: ../src/jarabe/desktop/schoolserver.py:131
msgid "Cannot connect to the server."
msgstr "Kann nicht mit dem Server verbinden."
-#: ../src/jarabe/desktop/schoolserver.py:109
+#: ../src/jarabe/desktop/schoolserver.py:136
msgid "The server could not complete the request."
msgstr "Der Server konnte die Anforderung nicht erfüllen."
-#: ../src/jarabe/frame/activitiestray.py:238
-#: ../src/jarabe/frame/activitiestray.py:672
+#: ../src/jarabe/frame/activitiestray.py:178
+#: ../src/jarabe/frame/activitiestray.py:559
msgid "Decline"
msgstr "Ablehnen"
-#: ../src/jarabe/frame/activitiestray.py:624
+#: ../src/jarabe/frame/activitiestray.py:509
#, python-format
msgid "%dB"
msgstr "%dB"
-#: ../src/jarabe/frame/activitiestray.py:626
+#: ../src/jarabe/frame/activitiestray.py:511
#, python-format
msgid "%dKB"
msgstr "%dKB"
-#: ../src/jarabe/frame/activitiestray.py:628
+#: ../src/jarabe/frame/activitiestray.py:513
#, python-format
msgid "%dMB"
msgstr "%dMB"
-#: ../src/jarabe/frame/activitiestray.py:645
+#: ../src/jarabe/frame/activitiestray.py:530
#, python-format
msgid "%s of %s"
msgstr "%s von %s"
-#: ../src/jarabe/frame/activitiestray.py:657
+#: ../src/jarabe/frame/activitiestray.py:544
#, python-format
msgid "Transfer from %r"
msgstr "Übertragung von %r"
-#: ../src/jarabe/frame/activitiestray.py:667
+#: ../src/jarabe/frame/activitiestray.py:554
msgid "Accept"
msgstr "Akzeptieren"
-#: ../src/jarabe/frame/activitiestray.py:690
-#: ../src/jarabe/frame/activitiestray.py:817
+#: ../src/jarabe/frame/activitiestray.py:577
+#: ../src/jarabe/frame/activitiestray.py:705
#, python-format
msgid "%s (%s)"
msgstr "%s (%s)"
-#: ../src/jarabe/frame/activitiestray.py:724
-#: ../src/jarabe/frame/activitiestray.py:852
+#: ../src/jarabe/frame/activitiestray.py:611
+#: ../src/jarabe/frame/activitiestray.py:740
msgid "Dismiss"
msgstr "Verwerfen"
-#: ../src/jarabe/frame/activitiestray.py:787
+#: ../src/jarabe/frame/activitiestray.py:675
#, python-format
msgid "Transfer to %r"
msgstr "Übertragung zu %r"
-#: ../src/jarabe/frame/clipboardmenu.py:53 ../src/jarabe/view/palettes.py:221
+#: ../src/jarabe/frame/clipboardmenu.py:54 ../src/jarabe/view/palettes.py:220
msgid "Remove"
msgstr "Entfernen"
-#: ../src/jarabe/frame/clipboardmenu.py:58
-#: ../src/jarabe/frame/clipboardmenu.py:81
+#: ../src/jarabe/frame/clipboardmenu.py:59
+#: ../src/jarabe/frame/clipboardmenu.py:82
msgid "Open"
msgstr "Öffnen"
-#: ../src/jarabe/frame/clipboardmenu.py:86
+#: ../src/jarabe/frame/clipboardmenu.py:87
msgid "Open with"
msgstr "Öffnen mit"
# (Markus S.) 'clipping', nicht 'clipped'
-#: ../src/jarabe/frame/clipboardobject.py:49
+#: ../src/jarabe/frame/clipboardobject.py:50
#, python-format
msgid "%s clipping"
msgstr "%s ausgeschnitten"
-#: ../src/jarabe/frame/zoomtoolbar.py:37
+#: ../src/jarabe/frame/zoomtoolbar.py:38
msgid "Neighborhood"
msgstr "Umgebung"
-#: ../src/jarabe/frame/zoomtoolbar.py:37
+#: ../src/jarabe/frame/zoomtoolbar.py:38
msgid "F1"
msgstr "F1"
-#: ../src/jarabe/frame/zoomtoolbar.py:39
+#: ../src/jarabe/frame/zoomtoolbar.py:40
msgid "F2"
msgstr "F2"
-#: ../src/jarabe/frame/zoomtoolbar.py:41
+#: ../src/jarabe/frame/zoomtoolbar.py:42
msgid "F3"
msgstr "F3"
-#: ../src/jarabe/frame/zoomtoolbar.py:43
+#: ../src/jarabe/frame/zoomtoolbar.py:44
msgid "F4"
msgstr "F4"
-#: ../src/jarabe/intro/window.py:128
+#: ../src/jarabe/intro/window.py:96
+msgid "Name:"
+msgstr "Name:"
+
+#: ../src/jarabe/intro/window.py:132
msgid "Click to change color:"
msgstr "Klicken zum Wechseln der Farbe:"
-#: ../src/jarabe/intro/window.py:192 ../src/jarabe/journal/detailview.py:103
+#: ../src/jarabe/intro/window.py:197 ../src/jarabe/journal/detailview.py:105
msgid "Back"
msgstr "Zurück"
# (Markus S.) war 'Nächste'
-#: ../src/jarabe/intro/window.py:209
+#: ../src/jarabe/intro/window.py:214
msgid "Next"
msgstr "Vor"
-#: ../src/jarabe/journal/expandedentry.py:151
-#: ../src/jarabe/journal/palettes.py:60
+#: ../src/jarabe/journal/expandedentry.py:154
+#: ../src/jarabe/journal/listmodel.py:144 ../src/jarabe/journal/palettes.py:59
msgid "Untitled"
msgstr "Ohne Titel"
-#: ../src/jarabe/journal/expandedentry.py:242
+#: ../src/jarabe/journal/expandedentry.py:243
msgid "No preview"
msgstr "Keine Vorschau"
-#: ../src/jarabe/journal/expandedentry.py:261
+#: ../src/jarabe/journal/expandedentry.py:262
#, python-format
msgid "Kind: %s"
msgstr "Art: %s"
-#: ../src/jarabe/journal/expandedentry.py:261
+#: ../src/jarabe/journal/expandedentry.py:262
+#: ../src/jarabe/journal/listmodel.py:150
+#: ../src/jarabe/journal/listmodel.py:157
+#: ../src/jarabe/journal/listmodel.py:165
msgid "Unknown"
msgstr "Unbekannt"
-#: ../src/jarabe/journal/expandedentry.py:262
+#: ../src/jarabe/journal/expandedentry.py:263
#, python-format
msgid "Date: %s"
msgstr "Datum: %s"
-#: ../src/jarabe/journal/expandedentry.py:263
+#: ../src/jarabe/journal/expandedentry.py:264
#, python-format
msgid "Size: %s"
msgstr "Größe: %s"
-#: ../src/jarabe/journal/expandedentry.py:285 ../src/jarabe/journal/misc.py:93
+#: ../src/jarabe/journal/expandedentry.py:292
+#: ../src/jarabe/journal/misc.py:108
msgid "No date"
msgstr "Kein Datum"
-#: ../src/jarabe/journal/expandedentry.py:292
+#: ../src/jarabe/journal/expandedentry.py:299
msgid "Participants:"
msgstr "Teilnehmer:"
-#: ../src/jarabe/journal/expandedentry.py:315
+#: ../src/jarabe/journal/expandedentry.py:321
msgid "Description:"
msgstr "Beschreibung:"
-#: ../src/jarabe/journal/expandedentry.py:340
+#: ../src/jarabe/journal/expandedentry.py:346
msgid "Tags:"
msgstr "Stichwörter:"
-#: ../src/jarabe/journal/journalactivity.py:108
-#: ../src/jarabe/journal/volumestoolbar.py:47
+#: ../src/jarabe/journal/journalactivity.py:115
+#: ../src/jarabe/journal/journaltoolbox.py:456
+#: ../src/jarabe/journal/volumestoolbar.py:50
msgid "Journal"
msgstr "Tagebuch"
-#: ../src/jarabe/journal/journaltoolbox.py:67
+#: ../src/jarabe/journal/journaltoolbox.py:69
msgid "Search"
msgstr "Suchen"
-#: ../src/jarabe/journal/journaltoolbox.py:126
+#: ../src/jarabe/journal/journaltoolbox.py:136
msgid "Anytime"
msgstr "Beliebiges Datum"
-#: ../src/jarabe/journal/journaltoolbox.py:128
+#: ../src/jarabe/journal/journaltoolbox.py:138
msgid "Today"
msgstr "Heute"
-#: ../src/jarabe/journal/journaltoolbox.py:130
+#: ../src/jarabe/journal/journaltoolbox.py:140
msgid "Since yesterday"
msgstr "Seit gestern"
# TRANS: Filter entries modified during the last 7 days.
#. TRANS: Filter entries modified during the last 7 days.
-#: ../src/jarabe/journal/journaltoolbox.py:132
+#: ../src/jarabe/journal/journaltoolbox.py:142
msgid "Past week"
msgstr "Vergangene Woche"
# TRANS: Filter entries modified during the last 30 days.
#. TRANS: Filter entries modified during the last 30 days.
-#: ../src/jarabe/journal/journaltoolbox.py:134
+#: ../src/jarabe/journal/journaltoolbox.py:144
msgid "Past month"
msgstr "Vergangener Monat"
# TRANS: Filter entries modified during the last 356 days.
#. TRANS: Filter entries modified during the last 356 days.
-#: ../src/jarabe/journal/journaltoolbox.py:136
+#: ../src/jarabe/journal/journaltoolbox.py:146
msgid "Past year"
msgstr "Vergangenes Jahr"
-#: ../src/jarabe/journal/journaltoolbox.py:143
+#: ../src/jarabe/journal/journaltoolbox.py:153
msgid "Anyone"
msgstr "Alle"
-#: ../src/jarabe/journal/journaltoolbox.py:145
+#: ../src/jarabe/journal/journaltoolbox.py:155
msgid "My friends"
msgstr "Meine Freunde"
-#: ../src/jarabe/journal/journaltoolbox.py:146
+#: ../src/jarabe/journal/journaltoolbox.py:156
msgid "My class"
msgstr "Meine Klasse"
# TRANS: Item in a combo box that filters by entry type.
-#: ../src/jarabe/journal/journaltoolbox.py:274
+#: ../src/jarabe/journal/journaltoolbox.py:298
msgid "Anything"
msgstr "Alles"
# TODO: Add "Start with" menu item
-#: ../src/jarabe/journal/journaltoolbox.py:350
-#: ../src/jarabe/journal/palettes.py:84
+#: ../src/jarabe/journal/journaltoolbox.py:381
+#: ../src/jarabe/journal/palettes.py:90
msgid "Copy"
msgstr "Kopieren"
+#: ../src/jarabe/journal/journaltoolbox.py:436
+#: ../src/jarabe/journal/volumestoolbar.py:157
+msgid "Entries without a file cannot be copied."
+msgstr "Einträge ohne eine Datei lassen sich nicht kopieren."
+
+#: ../src/jarabe/journal/journaltoolbox.py:445
+#: ../src/jarabe/journal/volumestoolbar.py:166
+#, python-format
+msgid "Error while copying the entry. %s"
+msgstr "Fehler beim Kopieren des Eintrags. %s"
+
+#: ../src/jarabe/journal/journaltoolbox.py:446
+#: ../src/jarabe/journal/volumestoolbar.py:167
+msgid "Error"
+msgstr "Fehler"
+
# TRANS: Action label for starting an entry.
#. TRANS: Action label for starting an entry.
-#: ../src/jarabe/journal/journaltoolbox.py:431
+#: ../src/jarabe/journal/journaltoolbox.py:488
#: ../src/jarabe/journal/palettes.py:69
msgid "Start"
msgstr "Start"
-#: ../src/jarabe/journal/listview.py:373
+#: ../src/jarabe/journal/journaltoolbox.py:516
+msgid "Sort by date modified"
+msgstr "Nach Änderungsdatum sortieren"
+
+#: ../src/jarabe/journal/journaltoolbox.py:517
+msgid "Sort by date created"
+msgstr "Nach Erstellungsdatum sortieren"
+
+#: ../src/jarabe/journal/journaltoolbox.py:518
+msgid "Sort by size"
+msgstr "Nach Größe sortieren"
+
+#: ../src/jarabe/journal/journaltoolbox.py:527
+msgid "Sort view"
+msgstr "Ansicht sortieren"
+
+#: ../src/jarabe/journal/listview.py:380
msgid "Your Journal is empty"
msgstr "Dein Tagebuch ist leer."
-#: ../src/jarabe/journal/listview.py:375
+#: ../src/jarabe/journal/listview.py:382
msgid "No matching entries"
msgstr "Keine passenden Einträge"
-#: ../src/jarabe/journal/listview.py:386
+#: ../src/jarabe/journal/listview.py:393
msgid "Clear search"
msgstr "Suchfeld leeren"
-#: ../src/jarabe/journal/modalalert.py:63
+#: ../src/jarabe/journal/misc.py:273
+#, python-format
+msgid "Older Version Of %s Activity"
+msgstr "Ältere Version von %s Aktivität"
+
+#: ../src/jarabe/journal/misc.py:274
+#, python-format
+msgid "Do you want to downgrade to version %s "
+msgstr "Möchtest Du auf Version %s zurücksetzen?"
+
+#: ../src/jarabe/journal/modalalert.py:64
msgid "Your Journal is full"
msgstr "Dein Tagebuch ist voll."
-#: ../src/jarabe/journal/modalalert.py:67
+#: ../src/jarabe/journal/modalalert.py:68
msgid "Please delete some old Journal entries to make space for new ones."
msgstr ""
"Lösche bitte einige alte Tagebucheinträge, um Platz für neue zu schaffen."
-#: ../src/jarabe/journal/modalalert.py:79
+#: ../src/jarabe/journal/modalalert.py:80
msgid "Show Journal"
msgstr "Tagebuch anzeigen"
@@ -1343,7 +1503,7 @@ msgid "Choose an object"
msgstr "Ein Objekt auswählen"
#: ../src/jarabe/journal/objectchooser.py:151
-#: ../src/jarabe/view/viewsource.py:310
+#: ../src/jarabe/view/viewsource.py:311
msgid "Close"
msgstr "Schließen"
@@ -1355,102 +1515,306 @@ msgstr "Fortsetzen mit"
msgid "Start with"
msgstr "Beginnen mit"
-#: ../src/jarabe/journal/palettes.py:92
+#: ../src/jarabe/journal/palettes.py:83 ../src/jarabe/journal/palettes.py:216
+msgid "No activity to start entry"
+msgstr "Keine Aktivität, um den Eintrag zu beginnen"
+
+#: ../src/jarabe/journal/palettes.py:98
msgid "Send to"
msgstr "Senden an"
-#: ../src/jarabe/journal/palettes.py:101
+#: ../src/jarabe/journal/palettes.py:107
msgid "View Details"
msgstr "Details betrachten"
-#: ../src/jarabe/journal/palettes.py:179
+#: ../src/jarabe/journal/palettes.py:181
msgid "No friends present"
msgstr "Keine Freunde anwesend"
-#: ../src/jarabe/journal/palettes.py:184
+#: ../src/jarabe/journal/palettes.py:186
msgid "No valid connection found"
msgstr "Keine gültige Verbindung gefunden"
-#: ../src/jarabe/journal/palettes.py:212
+#: ../src/jarabe/journal/palettes.py:214
msgid "No activity to resume entry"
msgstr "Keine Aktivität, um den Eintrag fortzusetzen"
-#: ../src/jarabe/journal/palettes.py:214
-msgid "No activity to start entry"
-msgstr "Keine Aktivität, um den Eintrag zu beginnen"
+#: ../src/jarabe/model/network.py:158
+msgid "The reason for the device state change is unknown."
+msgstr "Der Grund für die Zustandsänderung des Gerätes ist unbekannt."
+
+#: ../src/jarabe/model/network.py:160
+msgid "The state change is normal."
+msgstr "Die Zustandsänderung ist normal."
+
+#: ../src/jarabe/model/network.py:162
+msgid "The device is now managed."
+msgstr "Das Gerät wird nun verwaltet."
+
+#: ../src/jarabe/model/network.py:164
+msgid "The device is no longer managed."
+msgstr "Das Gerät wird nicht länger verwaltet."
+
+#: ../src/jarabe/model/network.py:166
+msgid "The device could not be readied for configuration."
+msgstr "Das Gerät konnte nicht für die Konfiguration bereitgestellt werden."
+
+#: ../src/jarabe/model/network.py:168
+msgid ""
+"IP configuration could not be reserved (no available address, timeout, etc)."
+msgstr ""
+"Die IP-Konfiguration konnte nicht umgesetzt werden (keine Adresse verfügbar, "
+"Zeitüberschreitung etc.)."
+
+#: ../src/jarabe/model/network.py:171
+msgid "The IP configuration is no longer valid."
+msgstr "Die IP-Konfiguration ist nicht länger gültig."
+
+#: ../src/jarabe/model/network.py:173
+msgid "Secrets were required, but not provided."
+msgstr "Geheimnisse wurden angefordert, aber nicht bereitgestellt."
+
+#: ../src/jarabe/model/network.py:175
+msgid ""
+"The 802.1X supplicant disconnected from the access point or authentication "
+"server."
+msgstr ""
+"Der 802.1X-Supplikant wurde vom Zugangspunkt oder Authentifizierungsserver "
+"getrennt."
+
+#: ../src/jarabe/model/network.py:178
+msgid "Configuration of the 802.1X supplicant failed."
+msgstr "Konfiguration des 802.1X-Supplikanten schlug fehl."
+
+#: ../src/jarabe/model/network.py:180
+msgid "The 802.1X supplicant quit or failed unexpectedly."
+msgstr "Der 802.1X-Supplikant brach ab oder scheiterte unerwartet."
+
+#: ../src/jarabe/model/network.py:182
+msgid "The 802.1X supplicant took too long to authenticate."
+msgstr "Der 802.1X-Supplikant benötigte zu lange für die Authentifizierung."
+
+#: ../src/jarabe/model/network.py:184
+msgid "The PPP service failed to start within the allowed time."
+msgstr "Der PPP-Dienst startete nicht in der vorgegebenen Zeit."
+
+#: ../src/jarabe/model/network.py:186
+msgid "The PPP service disconnected unexpectedly."
+msgstr "Der PPP-Dienst wurde unerwartet getrennt."
+
+#: ../src/jarabe/model/network.py:188
+msgid "The PPP service quit or failed unexpectedly."
+msgstr "Der PPP-Dienst brach ab oder scheiterte unerwartet."
+
+#: ../src/jarabe/model/network.py:190
+msgid "The DHCP service failed to start within the allowed time."
+msgstr "Der DHCP-Dienst startete nicht in der vorgegebenen Zeit."
+
+#: ../src/jarabe/model/network.py:192
+msgid "The DHCP service reported an unexpected error."
+msgstr "Der DHCP-Dienst meldete einen unerwarteten Fehler."
+
+#: ../src/jarabe/model/network.py:194
+msgid "The DHCP service quit or failed unexpectedly."
+msgstr "Der DHCP-Dienst brach ab oder scheiterte unerwartet."
+
+#: ../src/jarabe/model/network.py:196
+msgid "The shared connection service failed to start."
+msgstr "Der Dienst für geteilte Verbindungen konnte nicht starten."
+
+#: ../src/jarabe/model/network.py:198
+msgid "The shared connection service quit or failed unexpectedly."
+msgstr ""
+"Der Dienst für geteilte Verbindungen brach ab oder scheiterte unerwartet."
-#: ../src/jarabe/view/buddymenu.py:62
+#: ../src/jarabe/model/network.py:201
+msgid "The AutoIP service failed to start."
+msgstr "Der AutoIP-Dienst konnte nicht starten."
+
+#: ../src/jarabe/model/network.py:203
+msgid "The AutoIP service reported an unexpected error."
+msgstr "Der AutoIP-Dienst meldete einen unerwarteten Fehler."
+
+#: ../src/jarabe/model/network.py:205
+msgid "The AutoIP service quit or failed unexpectedly."
+msgstr "Der AutoIP-Dienst brach ab oder scheiterte unerwartet."
+
+#: ../src/jarabe/model/network.py:207
+msgid "Dialing failed because the line was busy."
+msgstr "Die Einwahl schlug fehl, weil die Leitung belegt war."
+
+#: ../src/jarabe/model/network.py:209
+msgid "Dialing failed because there was no dial tone."
+msgstr "Die Einwahl schlug mangels Einwahlton fehl."
+
+#: ../src/jarabe/model/network.py:211
+msgid "Dialing failed because there was no carrier."
+msgstr "Die Einwahl schlug mangels Leitung fehl."
+
+#: ../src/jarabe/model/network.py:213
+msgid "Dialing timed out."
+msgstr "Zeitüberschreitung bei der Einwahl."
+
+#: ../src/jarabe/model/network.py:215
+msgid "Dialing failed."
+msgstr "Einwahl fehlgeschlagen."
+
+#: ../src/jarabe/model/network.py:217
+msgid "Modem initialization failed."
+msgstr "Initialisierung des Modems fehlgeschlagen."
+
+#: ../src/jarabe/model/network.py:219
+msgid "Failed to select the specified GSM APN"
+msgstr "Konnte den angegebenen GSM-Zugangspunkt (APN) nicht anwählen."
+
+#: ../src/jarabe/model/network.py:221
+msgid "Not searching for networks."
+msgstr "Suche nicht nach Netzwerken."
+
+#: ../src/jarabe/model/network.py:223
+msgid "Network registration was denied."
+msgstr "Die Netzwerkregistrierung wurde verweigert."
+
+#: ../src/jarabe/model/network.py:225
+msgid "Network registration timed out."
+msgstr "Zeitüberschreitung bei der Netzwerkregistrierung."
+
+#: ../src/jarabe/model/network.py:227
+msgid "Failed to register with the requested GSM network."
+msgstr "Registrierung bei dem angeforderten GSM-Netzwerk fehlgeschlagen."
+
+#: ../src/jarabe/model/network.py:229
+msgid "PIN check failed."
+msgstr "PIN-Überprüfung fehlgeschlagen."
+
+#: ../src/jarabe/model/network.py:231
+msgid "Necessary firmware for the device may be missing."
+msgstr "Möglicherweise fehlt die nötige Firmware für das Gerät."
+
+#: ../src/jarabe/model/network.py:233
+msgid "The device was removed."
+msgstr "Das Gerät wurde entfernt."
+
+#: ../src/jarabe/model/network.py:235
+msgid "NetworkManager went to sleep."
+msgstr "Der Netzwerk-Manager ist nun im Ruhezustand."
+
+#: ../src/jarabe/model/network.py:237
+msgid "The device's active connection was removed or disappeared."
+msgstr "Die aktive Verbindung des Gerätes wurde entfernt oder ist verschwunden."
+
+#: ../src/jarabe/model/network.py:240
+msgid "A user or client requested the disconnection."
+msgstr "Ein Benutzer oder Client forderte die Verbindungstrennung."
+
+#: ../src/jarabe/model/network.py:242
+msgid "The device's carrier/link changed."
+msgstr "Die Leitung/Verbindung des Gerätes hat sich geändert."
+
+#: ../src/jarabe/view/buddymenu.py:63
msgid "Remove friend"
msgstr "Freund entfernen"
-#: ../src/jarabe/view/buddymenu.py:65
+#: ../src/jarabe/view/buddymenu.py:66
msgid "Make friend"
msgstr "Freunde werden"
-#: ../src/jarabe/view/buddymenu.py:82
+#: ../src/jarabe/view/buddymenu.py:83
msgid "Shutdown"
-msgstr "Rechner Ausschalten"
+msgstr "Rechner ausschalten"
-#: ../src/jarabe/view/buddymenu.py:90
+#: ../src/jarabe/view/buddymenu.py:91
+msgid "Restart"
+msgstr "Rechner neu starten"
+
+#: ../src/jarabe/view/buddymenu.py:97
msgid "Logout"
-msgstr "Benutzer Abmelden"
+msgstr "Benutzer abmelden"
-#: ../src/jarabe/view/buddymenu.py:95
+#: ../src/jarabe/view/buddymenu.py:102
msgid "My Settings"
msgstr "Meine Einstellungen"
-#: ../src/jarabe/view/buddymenu.py:130
+#: ../src/jarabe/view/buddymenu.py:137
#, python-format
msgid "Invite to %s"
msgstr "Einladen zu %s"
-#: ../src/jarabe/view/launcher.py:192
+#: ../src/jarabe/view/launcher.py:190
#, python-format
msgid "<b>%s</b> failed to start."
msgstr "<b>%s</b> konnte nicht gestartet werden."
-#: ../src/jarabe/view/palettes.py:45
+#: ../src/jarabe/view/palettes.py:46
msgid "Starting..."
msgstr "Starte..."
+#: ../src/jarabe/view/palettes.py:56
+msgid "Activity failed to start"
+msgstr "Aktivität konnte nicht gestartet werden."
+
#. TODO: share-with, keep
-#: ../src/jarabe/view/palettes.py:74
+#: ../src/jarabe/view/palettes.py:85
msgid "View Source"
-msgstr "Quelltext betrachten"
+msgstr "Quelltext anzeigen"
-#: ../src/jarabe/view/palettes.py:85
+#: ../src/jarabe/view/palettes.py:96
msgid "Stop"
msgstr "Beenden"
-#: ../src/jarabe/view/palettes.py:125
+#: ../src/jarabe/view/palettes.py:132
msgid "Start new"
msgstr "Neu beginnen"
-#: ../src/jarabe/view/palettes.py:174
+#: ../src/jarabe/view/palettes.py:172
msgid "Show contents"
msgstr "Inhalte anzeigen"
-#: ../src/jarabe/view/palettes.py:196 ../src/jarabe/view/palettes.py:246
+#: ../src/jarabe/view/palettes.py:194 ../src/jarabe/view/palettes.py:245
#, python-format
msgid "%(free_space)d MB Free"
msgstr "%(free_space)d MB frei"
-#: ../src/jarabe/view/viewsource.py:208
+#: ../src/jarabe/view/viewsource.py:211
msgid "Instance Source"
msgstr "Quelltext der Instanz"
-#: ../src/jarabe/view/viewsource.py:233
+#: ../src/jarabe/view/viewsource.py:236
msgid "Source"
msgstr "Quelltext"
-#: ../src/jarabe/view/viewsource.py:294
+#: ../src/jarabe/view/viewsource.py:295
msgid "Activity Bundle Source"
msgstr "Quelltext des Aktivitätenbündels"
-#: ../src/jarabe/view/viewsource.py:301
+#: ../src/jarabe/view/viewsource.py:302
#, python-format
msgid "View source: %r"
-msgstr "Quelltext betrachten: %r"
+msgstr "Quelltext anzeigen: %r"
+
+#: ../src/jarabe/util/emulator.py:40
+msgid "Sugar in a window"
+msgstr "Sugar in einem Fenster"
+
+#~ msgid "Create new wireless network"
+#~ msgstr "Neues Funknetzwerk erstellen"
+
+#~ msgid "Sim requires Pin/Puk"
+#~ msgstr "Sim benötigt PIN/PUK"
+
+#~ msgid "Authentication Error"
+#~ msgstr "Authentifizierungsfehler"
+
+#, python-format
+#~ msgid "%s's network"
+#~ msgstr "Netzwerk von %s"
+
+#, python-format
+#~ msgid "Data sent %d KB / received %d KB"
+#~ msgstr "gesendet %d KB / empfangen %d KB"
+
+#~ msgid "Connection time "
+#~ msgstr "Verbindungsdauer "
#~ msgid "APN:"
#~ msgstr "APN (Zugangspunkt):"
@@ -1470,9 +1834,6 @@ msgstr "Quelltext betrachten: %r"
#~ msgid "Unmount"
#~ msgstr "Einbindung lösen"
-#~ msgid "Restart"
-#~ msgstr "Neustart"
-
#~ msgid ""
#~ "© 2008 One Laptop per Child Association Inc; Red Hat Inc; and Contributors."
#~ msgstr ""
diff --git a/po/es.po b/po/es.po
index 587608f..a28bcd9 100644
--- a/po/es.po
+++ b/po/es.po
@@ -2,20 +2,40 @@
# 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.
+# SOME DESCRIPTIVE TITLE.
+# 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.
+# SOME DESCRIPTIVE TITLE.
+# 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.
+# SOME DESCRIPTIVE TITLE.
+# 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.
+# SOME DESCRIPTIVE TITLE.
+# 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.
+# SOME DESCRIPTIVE TITLE.
+# 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.
msgid ""
msgstr ""
"Project-Id-Version: olpc-sugar\n"
"Report-Msgid-Bugs-To: \n"
-"POT-Creation-Date: 2009-09-05 00:31-0400\n"
-"PO-Revision-Date: 2010-01-18 19:18+0200\n"
-"Last-Translator: Chris <cjl@laptop.org>\n"
+"POT-Creation-Date: 2011-02-06 00:30-0500\n"
+"PO-Revision-Date: 2011-02-10 18:26+0200\n"
+"Last-Translator: Gonzalo <godiard@sugarlabs.org>\n"
"Language-Team: Fedora Spanish <fedora-trans-es@redhat.com>\n"
"Language: es\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 2.0.1\n"
+"X-Generator: Pootle 2.0.3\n"
"X-Poedit-Language: Spanish\n"
"X-Poedit-SourceCharset: utf-8\n"
"X-Poedit-Basepath: .\n"
@@ -24,43 +44,39 @@ msgstr ""
msgid "About Me"
msgstr "Acerca de mí"
-#: ../extensions/cpsection/aboutme/model.py:43
+#: ../extensions/cpsection/aboutme/model.py:48
msgid "You must enter a name."
msgstr "Debe ingresar un nombre."
-#: ../extensions/cpsection/aboutme/model.py:68
+#: ../extensions/cpsection/aboutme/model.py:75
#, python-format
msgid "stroke: color=%s hue=%s"
msgstr "borde: color=%s tonalidad=%s"
-#: ../extensions/cpsection/aboutme/model.py:71
+#: ../extensions/cpsection/aboutme/model.py:78
#, python-format
msgid "stroke: %s"
msgstr "borde: %s"
-#: ../extensions/cpsection/aboutme/model.py:73
+#: ../extensions/cpsection/aboutme/model.py:80
#, python-format
msgid "fill: color=%s hue=%s"
msgstr "relleno: color=%s tonalidad=%s"
-#: ../extensions/cpsection/aboutme/model.py:75
+#: ../extensions/cpsection/aboutme/model.py:82
#, python-format
msgid "fill: %s"
msgstr "relleno: %s"
-#: ../extensions/cpsection/aboutme/model.py:86
+#: ../extensions/cpsection/aboutme/model.py:94
msgid "Error in specified color modifiers."
msgstr "Error en modificadores de color especificados."
-#: ../extensions/cpsection/aboutme/model.py:89
+#: ../extensions/cpsection/aboutme/model.py:97
msgid "Error in specified colors."
msgstr "Error en colores especificados."
-#: ../extensions/cpsection/aboutme/view.py:94 ../src/jarabe/intro/window.py:92
-msgid "Name:"
-msgstr "Nombre:"
-
-#: ../extensions/cpsection/aboutme/view.py:128
+#: ../extensions/cpsection/aboutme/view.py:235
msgid "Click to change your color:"
msgstr "Clic para cambiar su color:"
@@ -68,56 +84,61 @@ msgstr "Clic para cambiar su color:"
msgid "About my Computer"
msgstr "Acerca de mi computadora"
-#: ../extensions/cpsection/aboutcomputer/model.py:28
+#: ../extensions/cpsection/aboutcomputer/model.py:37
msgid "Not available"
msgstr "No disponible"
-#: ../extensions/cpsection/aboutcomputer/view.py:60
+#: ../extensions/cpsection/aboutcomputer/model.py:158
+#, python-format
+msgid "%(interface)s: %(version)s"
+msgstr "%(interface)s: %(version)s"
+
+#: ../extensions/cpsection/aboutcomputer/view.py:61
msgid "Identity"
msgstr "Identidad"
-#: ../extensions/cpsection/aboutcomputer/view.py:69
+#: ../extensions/cpsection/aboutcomputer/view.py:70
msgid "Serial Number:"
msgstr "Número de serie:"
-#: ../extensions/cpsection/aboutcomputer/view.py:91
+#: ../extensions/cpsection/aboutcomputer/view.py:92
msgid "Software"
msgstr "Software"
# Por ahora..
-#: ../extensions/cpsection/aboutcomputer/view.py:100
+#: ../extensions/cpsection/aboutcomputer/view.py:101
msgid "Build:"
msgstr "Ensamble:"
-#: ../extensions/cpsection/aboutcomputer/view.py:115
+#: ../extensions/cpsection/aboutcomputer/view.py:116
msgid "Sugar:"
msgstr "Azúcar:"
-#: ../extensions/cpsection/aboutcomputer/view.py:131
+#: ../extensions/cpsection/aboutcomputer/view.py:132
msgid "Firmware:"
msgstr "Firmware:"
-#: ../extensions/cpsection/aboutcomputer/view.py:146
+#: ../extensions/cpsection/aboutcomputer/view.py:147
msgid "Wireless Firmware:"
-msgstr "Firmware Wireless:"
+msgstr "Firmware de la red inalámbrica:"
-#: ../extensions/cpsection/aboutcomputer/view.py:169
+#: ../extensions/cpsection/aboutcomputer/view.py:170
msgid "Copyright and License"
-msgstr "Licencia y Copyright"
+msgstr "Licencia y derechos de autor"
-#: ../extensions/cpsection/aboutcomputer/view.py:184
+#: ../extensions/cpsection/aboutcomputer/view.py:188
msgid ""
"Sugar is the graphical user interface that you are looking at. Sugar is free "
"software, covered by the GNU General Public License, and you are welcome to "
"change it and/or distribute copies of it under certain conditions described "
"therein."
msgstr ""
-"Azucar es la interfaz gráfica de usuario que usted esta mirando. Azucar es "
+"Azucar es la interfaz gráfica de usuario que usted esta mirando. Azucar es "
"software libre, cubierto bajo la licencia GNU Licencia Publica General, y "
"esta invitado a cambiarla y/o distribuir copias bajo ciertas condiciones que "
"se describen en ella."
-#: ../extensions/cpsection/aboutcomputer/view.py:196
+#: ../extensions/cpsection/aboutcomputer/view.py:200
msgid "Full license:"
msgstr "Licencia completa:"
@@ -125,11 +146,11 @@ msgstr "Licencia completa:"
msgid "Date & Time"
msgstr "Fecha y hora"
-#: ../extensions/cpsection/datetime/model.py:87
+#: ../extensions/cpsection/datetime/model.py:92
msgid "Error timezone does not exist."
msgstr "Error, zona horaria no existe."
-#: ../extensions/cpsection/datetime/view.py:68 ../data/sugar.schemas.in.h:27
+#: ../extensions/cpsection/datetime/view.py:70 ../data/sugar.schemas.in.h:52
msgid "Timezone"
msgstr "Zona horaria"
@@ -137,50 +158,50 @@ msgstr "Zona horaria"
msgid "Frame"
msgstr "Cuadro"
-#: ../extensions/cpsection/frame/model.py:38
-#: ../extensions/cpsection/frame/model.py:60
+#: ../extensions/cpsection/frame/model.py:41
+#: ../extensions/cpsection/frame/model.py:66
msgid "Value must be an integer."
msgstr "El valor debe ser un número entero."
-#: ../extensions/cpsection/frame/view.py:26
+#: ../extensions/cpsection/frame/view.py:27
msgid "never"
msgstr "nunca"
-#: ../extensions/cpsection/frame/view.py:27
+#: ../extensions/cpsection/frame/view.py:28
msgid "instantaneous"
msgstr "instantáneo"
-#: ../extensions/cpsection/frame/view.py:28
+#: ../extensions/cpsection/frame/view.py:29
#, python-format
msgid "%s seconds"
msgstr "%s segundos"
-#: ../extensions/cpsection/frame/view.py:52
+#: ../extensions/cpsection/frame/view.py:54
msgid "Activation Delay"
msgstr "Retraso de activación"
-#: ../extensions/cpsection/frame/view.py:76
+#: ../extensions/cpsection/frame/view.py:78
msgid "Corner"
msgstr "Esquina"
-#: ../extensions/cpsection/frame/view.py:111
+#: ../extensions/cpsection/frame/view.py:113
msgid "Edge"
msgstr "Borde"
#: ../extensions/cpsection/keyboard/__init__.py:21
-#: ../extensions/cpsection/keyboard/view.py:31
+#: ../extensions/cpsection/keyboard/view.py:32
msgid "Keyboard"
msgstr "Teclado"
-#: ../extensions/cpsection/keyboard/view.py:187
+#: ../extensions/cpsection/keyboard/view.py:190
msgid "Keyboard Model"
msgstr "Modelo de teclado"
-#: ../extensions/cpsection/keyboard/view.py:243
+#: ../extensions/cpsection/keyboard/view.py:250
msgid "Key(s) to change layout"
msgstr "Tecla(s) para cambiar el diseño"
-#: ../extensions/cpsection/keyboard/view.py:311
+#: ../extensions/cpsection/keyboard/view.py:319
msgid "Keyboard Layout(s)"
msgstr "Diseño(s) de teclado"
@@ -189,22 +210,22 @@ msgstr "Diseño(s) de teclado"
msgid "Language"
msgstr "Idioma"
-#: ../extensions/cpsection/language/model.py:28
+#: ../extensions/cpsection/language/model.py:30
msgid "Could not access ~/.i18n. Create standard settings."
msgstr ""
"No se puede acceder a ~/.i18n. Crear configuración internacional estándar."
-#: ../extensions/cpsection/language/model.py:124
+#: ../extensions/cpsection/language/model.py:131
#, python-format
msgid "Language for code=%s could not be determined."
msgstr "El lenguaje del código=%s no pudo ser determinado."
-#: ../extensions/cpsection/language/model.py:144
+#: ../extensions/cpsection/language/model.py:152
#, python-format
msgid "Sorry I do not speak '%s'."
msgstr "Lo siento, yo no hablo '%s'."
-#: ../extensions/cpsection/language/view.py:56
+#: ../extensions/cpsection/language/view.py:57
msgid ""
"Add languages in the order you prefer. If a translation is not available, "
"the next in the list will be used."
@@ -212,48 +233,84 @@ msgstr ""
"Añade idiomas en el orden que prefieres. Si una traducción no se encuentra "
"disponible, se usará la siguiente en la lista."
+#: ../extensions/cpsection/modemconfiguration/__init__.py:21
+msgid "Modem Configuration"
+msgstr "Configuración del módem"
+
+#: ../extensions/cpsection/modemconfiguration/view.py:94
+msgid "Username:"
+msgstr "Nombre de usuario:"
+
+#: ../extensions/cpsection/modemconfiguration/view.py:106
+msgid "Password:"
+msgstr "Contraseña:"
+
+#: ../extensions/cpsection/modemconfiguration/view.py:118
+msgid "Number:"
+msgstr "Número:"
+
+#: ../extensions/cpsection/modemconfiguration/view.py:130
+msgid "Access Point Name (APN):"
+msgstr "Nombre de punto de acceso (APN):"
+
+#: ../extensions/cpsection/modemconfiguration/view.py:142
+msgid "Personal Identity Number (PIN):"
+msgstr "Número de identificación personal (PIN):"
+
+#: ../extensions/cpsection/modemconfiguration/view.py:154
+msgid "Personal Unblocking Key (PUK):"
+msgstr "Clave personal de desbloqueo (PUK):"
+
+#: ../extensions/cpsection/modemconfiguration/view.py:175
+msgid ""
+"You will need to provide the following information to set up a mobile "
+"broadband connection to a cellular (3G) network."
+msgstr ""
+"Necesitará proveer la información siguiente para configurar una conexión de "
+"banda ancha (3G) de red de telefonía celular."
+
#: ../extensions/cpsection/network/__init__.py:21
-#: ../extensions/cpsection/network/view.py:28
+#: ../extensions/cpsection/network/view.py:29
msgid "Network"
msgstr "Red"
-#: ../extensions/cpsection/network/model.py:79
+#: ../extensions/cpsection/network/model.py:71
msgid "State is unknown."
msgstr "Estado desconocido."
-#: ../extensions/cpsection/network/model.py:105
+#: ../extensions/cpsection/network/model.py:99
msgid "Error in specified radio argument use on/off."
msgstr "Error en argumento especificado de radio use on/off."
-#: ../extensions/cpsection/network/model.py:137
+#: ../extensions/cpsection/network/model.py:140
msgid "Error in specified argument use 0/1."
msgstr "Error en argumento especificado use 0/1."
-#: ../extensions/cpsection/network/view.py:59
+#: ../extensions/cpsection/network/view.py:61
msgid "Wireless"
msgstr "Inalámbrica"
-#: ../extensions/cpsection/network/view.py:67
+#: ../extensions/cpsection/network/view.py:69
msgid "Turn off the wireless radio to save battery life"
msgstr "Apague la radio inalámbrica y ahorre vida de batería"
-#: ../extensions/cpsection/network/view.py:80
+#: ../extensions/cpsection/network/view.py:82
msgid "Radio"
msgstr "Radio"
-#: ../extensions/cpsection/network/view.py:96
+#: ../extensions/cpsection/network/view.py:98
msgid "Discard network history if you have trouble connecting to the network"
msgstr "Descarte el historial de la red si tiene problemas de conexión"
-#: ../extensions/cpsection/network/view.py:105
+#: ../extensions/cpsection/network/view.py:107
msgid "Discard network history"
msgstr "Descarte historial de la red"
-#: ../extensions/cpsection/network/view.py:118
+#: ../extensions/cpsection/network/view.py:122
msgid "Collaboration"
msgstr "Colaboración"
-#: ../extensions/cpsection/network/view.py:126
+#: ../extensions/cpsection/network/view.py:130
msgid ""
"The server is the equivalent of what room you are in; people on the same "
"server will be able to see each other, even when they aren't on the same "
@@ -262,7 +319,7 @@ msgstr ""
"El servidor es equivalente al cuarto en el cual se esta; la gente en el "
"mismo servidor podrá verse entre ellos, aun cuando no esten en la misma red."
-#: ../extensions/cpsection/network/view.py:136
+#: ../extensions/cpsection/network/view.py:140
msgid "Server:"
msgstr "Servidor:"
@@ -270,24 +327,24 @@ msgstr "Servidor:"
msgid "Power"
msgstr "Energía"
-#: ../extensions/cpsection/power/model.py:54
+#: ../extensions/cpsection/power/model.py:90
msgid "Error in automatic pm argument, use on/off."
-msgstr "Error en argumento automático de pm, use on/off."
+msgstr "Error en argumento automático de manejo de energía, use on/off."
-#: ../extensions/cpsection/power/model.py:81
+#: ../extensions/cpsection/power/model.py:120
msgid "Error in extreme pm argument, use on/off."
-msgstr "Error en argumento extremo de pm, use on/off."
+msgstr "Error en argumento extremo de manejo de energía, use on/off."
-#: ../extensions/cpsection/power/view.py:47
+#: ../extensions/cpsection/power/view.py:48
msgid "Power management"
msgstr "Manejo de energía"
-#: ../extensions/cpsection/power/view.py:57
+#: ../extensions/cpsection/power/view.py:58
msgid "Automatic power management (increases battery life)"
msgstr "Manejo automático de energía (incrementa la vida de la batería)"
# best translationfor now
-#: ../extensions/cpsection/power/view.py:85
+#: ../extensions/cpsection/power/view.py:86
msgid ""
"Extreme power management (disableswireless radio, increases battery life)"
msgstr ""
@@ -296,9 +353,9 @@ msgstr ""
#: ../extensions/cpsection/updater/__init__.py:21
msgid "Software update"
-msgstr "Actualización de Software"
+msgstr "Actualización de software"
-#: ../extensions/cpsection/updater/view.py:62
+#: ../extensions/cpsection/updater/view.py:63
msgid ""
"Software updates correct errors, eliminate security vulnerabilities, and "
"provide new features."
@@ -306,109 +363,109 @@ msgstr ""
"Las actualizaciones de software corrigen errores, eliminan vulnerabilidades "
"de seguridad y proveen nuevas características."
-#: ../extensions/cpsection/updater/view.py:122
+#: ../extensions/cpsection/updater/view.py:125
#, python-format
msgid "Checking %s..."
msgstr "Probando %s..."
-#: ../extensions/cpsection/updater/view.py:124
+#: ../extensions/cpsection/updater/view.py:127
#, python-format
msgid "Downloading %s..."
msgstr "Descargando %s..."
-#: ../extensions/cpsection/updater/view.py:126
+#: ../extensions/cpsection/updater/view.py:129
#, python-format
msgid "Updating %s..."
msgstr "Actualizando %s..."
-#: ../extensions/cpsection/updater/view.py:135
+#: ../extensions/cpsection/updater/view.py:139
msgid "Your software is up-to-date"
msgstr "Tu software esta actualizado"
-#: ../extensions/cpsection/updater/view.py:137
+#: ../extensions/cpsection/updater/view.py:141
#, python-format
msgid "You can install %s update"
msgid_plural "You can install %s updates"
msgstr[0] "Puedes instalar %s actualización"
msgstr[1] "Puedes instalar %s actualizaciones"
-#: ../extensions/cpsection/updater/view.py:155
+#: ../extensions/cpsection/updater/view.py:159
msgid "Checking for updates..."
msgstr "Buscando actualizaciones..."
-#: ../extensions/cpsection/updater/view.py:160
+#: ../extensions/cpsection/updater/view.py:164
msgid "Installing updates..."
msgstr "Instalando actualizaciones..."
-#: ../extensions/cpsection/updater/view.py:165
+#: ../extensions/cpsection/updater/view.py:173
#, python-format
msgid "%s update was installed"
msgid_plural "%s updates were installed"
msgstr[0] "%s actualización fue instalada"
msgstr[1] "%s actualizaciones fueron instaladas"
-#: ../extensions/cpsection/updater/view.py:244
+#: ../extensions/cpsection/updater/view.py:255
msgid "Install selected"
msgstr "Instalación seleccionada"
-#: ../extensions/cpsection/updater/view.py:265
+#: ../extensions/cpsection/updater/view.py:276
#, python-format
msgid "Download size: %s"
msgstr "Tamaño de descarga: %s"
-#: ../extensions/cpsection/updater/view.py:353
+#: ../extensions/cpsection/updater/view.py:364
#, python-format
-msgid "From version %(current)d to %(new)s (Size: %(size)s)"
-msgstr "Desde la version %(current)d hacia %(new)s (Size: %(size)s)"
+msgid "From version %(current)s to %(new)s (Size: %(size)s)"
+msgstr "Desde la version %(current)s hacia %(new)s (Size: %(size)s)"
#. TRANS: download size is 0
-#: ../extensions/cpsection/updater/view.py:373
+#: ../extensions/cpsection/updater/view.py:382
msgid "None"
msgstr "Ninguno"
#. TRANS: download size of very small updates
-#: ../extensions/cpsection/updater/view.py:376
+#: ../extensions/cpsection/updater/view.py:385
msgid "1 KB"
msgstr "1 KB"
#. TRANS: download size of small updates, e.g. '250 KB'
-#: ../extensions/cpsection/updater/view.py:379
+#: ../extensions/cpsection/updater/view.py:388
#, python-format
msgid "%.0f KB"
msgstr "%.0f KB"
#. TRANS: download size of updates, e.g. '2.3 MB'
-#: ../extensions/cpsection/updater/view.py:382
+#: ../extensions/cpsection/updater/view.py:391
#, python-format
msgid "%.1f MB"
msgstr "%.1f MB"
-#: ../extensions/deviceicon/battery.py:58
+#: ../extensions/deviceicon/battery.py:60
msgid "My Battery"
msgstr "Mi batería"
-#: ../extensions/deviceicon/battery.py:137
+#: ../extensions/deviceicon/battery.py:141
msgid "Removed"
msgstr "Eliminado"
-#: ../extensions/deviceicon/battery.py:140
+#: ../extensions/deviceicon/battery.py:144
msgid "Charging"
msgstr "Cargando"
-#: ../extensions/deviceicon/battery.py:143
+#: ../extensions/deviceicon/battery.py:147
msgid "Very little power remaining"
msgstr "Queda muy poca batería"
-#: ../extensions/deviceicon/battery.py:149
+#: ../extensions/deviceicon/battery.py:153
#, python-format
msgid "%(hour)d:%(min).2d remaining"
msgstr "Quedan %(hour)d:%(min).2d"
-#: ../extensions/deviceicon/battery.py:152
+#: ../extensions/deviceicon/battery.py:156
msgid "Charged"
msgstr "Cargada"
-#: ../extensions/deviceicon/network.py:44
+#: ../extensions/deviceicon/network.py:49
#, python-format
msgid "IP address: %s"
msgstr "Direccion IP: %s"
@@ -417,125 +474,336 @@ msgstr "Direccion IP: %s"
# priority over the normal wireless device. NM doesn't have a "disconnect"
# method for a device either (for various reasons) so this doesn't
# have a good mapping
-#: ../extensions/deviceicon/network.py:110
+#: ../extensions/deviceicon/network.py:104
msgid "Disconnect..."
msgstr "Desconectando..."
-#: ../extensions/deviceicon/network.py:114
-msgid "Create new wireless network"
-msgstr "Crear nueva red inalámbrica"
-
-#: ../extensions/deviceicon/network.py:120
-#: ../src/jarabe/desktop/meshbox.py:264
+#: ../extensions/deviceicon/network.py:112
+#: ../extensions/deviceicon/network.py:290
+#: ../src/jarabe/desktop/networkviews.py:241
+#: ../src/jarabe/desktop/networkviews.py:546
+#: ../src/jarabe/desktop/networkviews.py:673
msgid "Connecting..."
msgstr "Conectando..."
# TODO: show the channel number
-#: ../extensions/deviceicon/network.py:124
-#: ../extensions/deviceicon/network.py:186
-#: ../src/jarabe/desktop/meshbox.py:270
+#: ../extensions/deviceicon/network.py:116
+#: ../extensions/deviceicon/network.py:182
+#: ../src/jarabe/desktop/networkviews.py:251
+#: ../src/jarabe/desktop/networkviews.py:552
+#: ../src/jarabe/desktop/networkviews.py:679
msgid "Connected"
msgstr "Conectado"
-#: ../extensions/deviceicon/network.py:146
+#: ../extensions/deviceicon/network.py:142
msgid "Channel"
msgstr "Canal"
-#: ../extensions/deviceicon/network.py:161
+#: ../extensions/deviceicon/network.py:157
msgid "Wired Network"
msgstr "Red Cableada"
-#: ../extensions/deviceicon/network.py:189
+#: ../extensions/deviceicon/network.py:185
msgid "Speed"
msgstr "Velocidad"
-#: ../extensions/deviceicon/network.py:415
+#: ../extensions/deviceicon/network.py:211
+msgid "Wireless modem"
+msgstr "Módem inalámbrico"
+
+#: ../extensions/deviceicon/network.py:278
+msgid "Please wait..."
+msgstr "Espere por favor..."
+
+#: ../extensions/deviceicon/network.py:282
+#: ../src/jarabe/desktop/networkviews.py:134
+#: ../src/jarabe/desktop/networkviews.py:500
+#: ../src/jarabe/desktop/networkviews.py:630
+msgid "Connect"
+msgstr "Conectar"
+
+#: ../extensions/deviceicon/network.py:283
+msgid "Disconnected"
+msgstr "Desconectado"
+
+#: ../extensions/deviceicon/network.py:289
+#: ../src/jarabe/controlpanel/toolbar.py:119
+#: ../src/jarabe/desktop/homebox.py:70
+#: ../src/jarabe/frame/activitiestray.py:587
+#: ../src/jarabe/frame/activitiestray.py:687
+#: ../src/jarabe/frame/activitiestray.py:715
+msgid "Cancel"
+msgstr "Cancelar"
+
+#: ../extensions/deviceicon/network.py:297
+#: ../src/jarabe/desktop/networkviews.py:138
+#: ../src/jarabe/desktop/networkviews.py:504
+msgid "Disconnect"
+msgstr "Desconectar"
+
+#: ../extensions/deviceicon/network.py:327
+msgid "Try connection again"
+msgstr "Probar la conexión nuevamente"
+
+#: ../extensions/deviceicon/network.py:330
+#, python-format
+msgid "Error: %s"
+msgstr "Error: %s"
+
+#: ../extensions/deviceicon/network.py:334
+#, python-format
+msgid "Suggestion: %s"
+msgstr "Sugerencia: %s"
+
+#: ../extensions/deviceicon/network.py:340
+#: ../extensions/deviceicon/network.py:343
+#, python-format
+msgid "Connected for %s"
+msgstr "Conectado a %s"
+
+#: ../extensions/deviceicon/network.py:348
+#: ../extensions/deviceicon/network.py:349
+#, python-format
+msgid "%d KB"
+msgstr "%d KB"
+
+#: ../extensions/deviceicon/network.py:354
+msgid "Check your Pin/Puk configuration."
+msgstr "Revise la configuración de su Pin/Puk."
+
+#: ../extensions/deviceicon/network.py:357
+msgid "Check your Access Point Name (APN) configuration"
+msgstr "Revise la configuración del nombre de su punto de acceso (APN)"
+
+#: ../extensions/deviceicon/network.py:361
+msgid "Check the Number configuration."
+msgstr "Revise el Número en la configuración."
+
+#: ../extensions/deviceicon/network.py:363
+msgid "Check your configuration."
+msgstr "Revise su configuración."
+
+#: ../extensions/deviceicon/network.py:605
+msgid "Mesh Network"
+msgstr "Red Malla"
+
+#: ../extensions/deviceicon/network.py:648
+#, python-format
+msgid "Mesh Network %s"
+msgstr "Red Malla %s"
+
+#: ../extensions/deviceicon/network.py:771
+msgid "No GSM connection available."
+msgstr "No se dispone de conexión GSM."
+
+#: ../extensions/deviceicon/network.py:772
+msgid "Create a connection in the control panel."
+msgstr "Crear una conexión en el panel de control."
+
+#: ../extensions/deviceicon/resources.py:48
+msgid "System resources"
+msgstr "Recursos del sistema"
+
+#: ../extensions/deviceicon/resources.py:170
#, python-format
-msgid "%s's network %s"
-msgstr "%s's red %s"
+msgid "CPU in use: %d%%"
+msgstr "CPU en uso: %d%%"
-#: ../extensions/deviceicon/speaker.py:59
+#: ../extensions/deviceicon/resources.py:172
+#, python-format
+msgid "Memory in use: %d%%"
+msgstr "Memoria en uso: %d%%"
+
+#: ../extensions/deviceicon/resources.py:202
+msgid "Cannot compute CPU and memory usage statistics!"
+msgstr "No puedo calcular las estadísticas de uso de CPU y memoria!"
+
+#: ../extensions/deviceicon/speaker.py:60
msgid "My Speakers"
msgstr "Mis parlantes"
# la traducción la tome del AlsaMixer de Gnome.
-#: ../extensions/deviceicon/speaker.py:133
+#: ../extensions/deviceicon/speaker.py:136
msgid "Unmute"
msgstr "Dar voz"
-#: ../extensions/deviceicon/speaker.py:136
+#: ../extensions/deviceicon/speaker.py:139
msgid "Mute"
msgstr "Silenciar"
-#: ../extensions/globalkey/screenshot.py:56
+#: ../extensions/deviceicon/touchpad.py:37
+msgid "finger"
+msgstr "dedo"
+
+#: ../extensions/deviceicon/touchpad.py:38
+msgid "stylus"
+msgstr "estilo"
+
+#: ../extensions/deviceicon/touchpad.py:67
+msgid "My touchpad"
+msgstr "Mi superficie táctil"
+
+#: ../extensions/globalkey/screenshot.py:59
msgid "Mesh"
msgstr "Malla"
-#: ../extensions/globalkey/screenshot.py:58
-#: ../src/jarabe/frame/zoomtoolbar.py:39
+#: ../extensions/globalkey/screenshot.py:61
+#: ../src/jarabe/frame/zoomtoolbar.py:40
msgid "Group"
msgstr "Grupo"
-#: ../extensions/globalkey/screenshot.py:60
-#: ../src/jarabe/frame/zoomtoolbar.py:41
+#: ../extensions/globalkey/screenshot.py:63
+#: ../src/jarabe/frame/zoomtoolbar.py:42
msgid "Home"
msgstr "Hogar"
-#: ../extensions/globalkey/screenshot.py:66
-#: ../src/jarabe/frame/zoomtoolbar.py:43
+#: ../extensions/globalkey/screenshot.py:69
+#: ../src/jarabe/frame/zoomtoolbar.py:44
msgid "Activity"
msgstr "Actividad"
-#: ../extensions/globalkey/screenshot.py:69
+#: ../extensions/globalkey/screenshot.py:72
msgid "Screenshot"
msgstr "Captura de pantalla"
-#: ../extensions/globalkey/screenshot.py:71
+#: ../extensions/globalkey/screenshot.py:74
#, python-format
msgid "Screenshot of \"%s\""
msgstr "Captura pantalla de \"%s\""
#: ../data/sugar.schemas.in.h:1
+msgid ""
+"\"disabled\" to ask nick on initialization; \"system\" to reuse UNIX account "
+"long name."
+msgstr ""
+"\"disabled\" (desactivado) para preguntar apodo al inicio; \"system\" (sistema) "
+"para reutilizar el nombre largo de la cuenta UNIX."
+
+#: ../data/sugar.schemas.in.h:2
+msgid "Additional directories which can contain updated translations."
+msgstr "Directorios adicionales que pueden contener traducciones actualizadas."
+
+#: ../data/sugar.schemas.in.h:3
msgid "Backup URL"
msgstr "URL de Respaldo"
-#: ../data/sugar.schemas.in.h:2
+#: ../data/sugar.schemas.in.h:4
+msgid "Bundle IDs of protected activities"
+msgstr "Bundle IDs de actividades protegidas"
+
+#: ../data/sugar.schemas.in.h:5
msgid ""
"Color for the XO icon that is used throughout the desktop. The string is "
-"composed of the stroke color and fill color, format is that of rbg colors. "
+"composed of the stroke color and fill color, format is that of rgb colors. "
"Example: #AC32FF,#9A5200"
msgstr ""
"El color para el ícono del XO se utiliza en todo el escritorio. La cadena "
"está compuesta por el trazo y color de relleno de color, el formato es el de "
-"colores RBG. Ejemplo: #AC32FF, #9A5200"
+"colores RGB. Ejemplo: #AC32FF, #9A5200"
# es la mejor traduccion ?
-#: ../data/sugar.schemas.in.h:3
+#: ../data/sugar.schemas.in.h:6
msgid "Corner Delay"
msgstr "Retraso de las Esquinas"
-#: ../data/sugar.schemas.in.h:4
+#: ../data/sugar.schemas.in.h:7
+msgid "Default font face"
+msgstr "Tipo de letra predeterminado"
+
+#: ../data/sugar.schemas.in.h:8
+msgid "Default font size"
+msgstr "Tamaño de letra predeterminado"
+
+#: ../data/sugar.schemas.in.h:9
+msgid "Default nick"
+msgstr "Apodo predeterminado"
+
+#: ../data/sugar.schemas.in.h:10
msgid "Delay for the activation of the frame using the corners."
msgstr "Retraso para la activación del cuadro utilizando las esquinas."
-#: ../data/sugar.schemas.in.h:5
+#: ../data/sugar.schemas.in.h:11
msgid "Delay for the activation of the frame using the edges."
msgstr "Retraso para la activación del cuadro utilizando los bordes."
+#: ../data/sugar.schemas.in.h:12
+msgid "Directory to search for translations"
+msgstr "Directorio a buscar para traducciones"
+
# es la mejor traduccion ?
-#: ../data/sugar.schemas.in.h:6
+#: ../data/sugar.schemas.in.h:13
msgid "Edge Delay"
msgstr "Retraso del Borde"
-#: ../data/sugar.schemas.in.h:7
+#: ../data/sugar.schemas.in.h:14
msgid "Favorites Layout"
msgstr "Diseño de favoritos"
-#: ../data/sugar.schemas.in.h:8
+#: ../data/sugar.schemas.in.h:15
msgid "Favorites resume mode"
msgstr "Modo de reanudar favoritos"
-#: ../data/sugar.schemas.in.h:9
+#: ../data/sugar.schemas.in.h:16
+msgid "Font face that is used throughout the desktop."
+msgstr "Tipo de letra que se utiliza en todo el escritorio."
+
+#: ../data/sugar.schemas.in.h:17
+msgid "Font size that is used throughout the desktop."
+msgstr "Tamaño de letra que se utiliza en todo el escritorio."
+
+#: ../data/sugar.schemas.in.h:18
+msgid "GSM network APN"
+msgstr "APN de la red GSM"
+
+#: ../data/sugar.schemas.in.h:19
+msgid "GSM network PIN"
+msgstr "PIN de la red GSM"
+
+#: ../data/sugar.schemas.in.h:20
+msgid "GSM network PUK"
+msgstr "PUK de la red GSM"
+
+# Puede evitarse el texto "(APN)"; pero es bueno ser preciso en detallarlo para usuarios no técnicos.
+#: ../data/sugar.schemas.in.h:21
+msgid "GSM network access point name configuration"
+msgstr "Configuración del nombre del punto de acceso (APN) de la red GSM"
+
+#: ../data/sugar.schemas.in.h:22
+msgid "GSM network number"
+msgstr "Número de la red GSM"
+
+# Puede usarse el sinónimo "Clave" mas hay que usar el término conocido por el usuario.
+#: ../data/sugar.schemas.in.h:23
+msgid "GSM network password"
+msgstr "Contraseña de la red GSM"
+
+#: ../data/sugar.schemas.in.h:24
+msgid "GSM network password configuration"
+msgstr "Configuración de la contraseña de la red GSM"
+
+# Puede excluirse el texto "(PIN)" mas es de ser precisos para usuarios no técnicos.
+#: ../data/sugar.schemas.in.h:25
+msgid "GSM network personal identification number configuration"
+msgstr "Configuración del numero de identificación personal (PIN) de la red GSM"
+
+# Puede no usarse el texto "(PUK)" pero es válido ser específico.
+#: ../data/sugar.schemas.in.h:26
+msgid "GSM network personal unlock key configuration"
+msgstr "Configuración de la clave de desbloqueo personal (PUK) de la red GSM"
+
+#: ../data/sugar.schemas.in.h:27
+msgid "GSM network telephone number configuration"
+msgstr "Configuración del número de teléfono de la red GSM"
+
+#: ../data/sugar.schemas.in.h:28
+msgid "GSM network username"
+msgstr "Nombre de usuario de la red GSM"
+
+#: ../data/sugar.schemas.in.h:29
+msgid "GSM network username configuration"
+msgstr "Configuración del nombre de usuario de la red GSM"
+
+#: ../data/sugar.schemas.in.h:30
msgid ""
"If TRUE, Sugar will make us searchable for the other users of the Jabber "
"server."
@@ -543,110 +811,139 @@ msgstr ""
"Si es TRUE, Azúcar habilitará que otros usuarios nos busquen en el servidor "
"Jabber."
-#: ../data/sugar.schemas.in.h:10
+#: ../data/sugar.schemas.in.h:31
msgid "If TRUE, Sugar will show a \"Log out\" option."
msgstr "Si es TRUE, Azúcar mostrará una opción \"Terminar Sesión\"."
-#: ../data/sugar.schemas.in.h:11
+#: ../data/sugar.schemas.in.h:32
+msgid "If TRUE, Sugar will show a \"Restart\" option."
+msgstr "Si es TRUE, Azúcar mostrará una opción \"Reiniciar Sesión\"."
+
+#: ../data/sugar.schemas.in.h:33
+msgid ""
+"If TRUE, Sugar will show default Ad-hoc networks for channel 1,6 and 11. If "
+"Sugar sees no \"known\" network when it starts, it does autoconnect to an Ad-"
+"hoc network."
+msgstr ""
+"Sí es TRUE, Azúcar mostrara las redes ad-hoc predefinidas para canales 1,6, "
+"y 11. Sí Azúcar no ve redes conocidas cuando inicia, se conectará "
+"automáticamente a una red ad-hoc."
+
+#: ../data/sugar.schemas.in.h:34
msgid "Jabber Server"
msgstr "Servidor Jabber"
-#: ../data/sugar.schemas.in.h:12
+#: ../data/sugar.schemas.in.h:35
msgid "Keyboard layouts"
msgstr "Distribuciones del teclado"
-#: ../data/sugar.schemas.in.h:13
+#: ../data/sugar.schemas.in.h:36
msgid "Keyboard model"
msgstr "Modelo del teclado"
-#: ../data/sugar.schemas.in.h:14
+#: ../data/sugar.schemas.in.h:37
msgid "Keyboard options"
msgstr "Opciones del teclado"
-#: ../data/sugar.schemas.in.h:15
+#: ../data/sugar.schemas.in.h:38
msgid "Layout of the favorites view."
msgstr "Distribución de las actividades favoritas."
-#: ../data/sugar.schemas.in.h:16
+#: ../data/sugar.schemas.in.h:39
msgid ""
"List of keyboard layouts. Each entry should be in the form layout(variant)"
msgstr ""
"Lista de las distribuciones de teclado. Cada entrada debe ser en la forma "
"distribución(variante)"
-#: ../data/sugar.schemas.in.h:17
+#: ../data/sugar.schemas.in.h:40
msgid "List of keyboard options."
msgstr "Lista de las opciones del teclado."
-#: ../data/sugar.schemas.in.h:18
+#: ../data/sugar.schemas.in.h:41
msgid "Power Automatic"
msgstr "Manejo automática de energía"
-#: ../data/sugar.schemas.in.h:19
+#: ../data/sugar.schemas.in.h:42
msgid "Power Automatic."
msgstr "Manejo automática de energía."
-#: ../data/sugar.schemas.in.h:20
+#: ../data/sugar.schemas.in.h:43
msgid "Power Extreme"
msgstr "Manejo extremo de energía"
-#: ../data/sugar.schemas.in.h:21
+#: ../data/sugar.schemas.in.h:44
msgid "Power Extreme."
msgstr "Manejo extremo de energía."
-#: ../data/sugar.schemas.in.h:22
+#: ../data/sugar.schemas.in.h:45
msgid "Publish to Gadget"
msgstr "Publicar en Gadget"
-#: ../data/sugar.schemas.in.h:23
+#: ../data/sugar.schemas.in.h:46
msgid "Setting for muting the sound device."
msgstr "Configuración para silenciar el dispositivo de sonido."
-#: ../data/sugar.schemas.in.h:24
+#: ../data/sugar.schemas.in.h:47
msgid "Show Log out"
msgstr "Mostrar Terminar Sesión"
-#: ../data/sugar.schemas.in.h:25
+#: ../data/sugar.schemas.in.h:48
+msgid "Show Restart"
+msgstr "Mostrar Reiniciar"
+
+#: ../data/sugar.schemas.in.h:49
+msgid "Show Sugar Ad-hoc networks"
+msgstr "Mostrar redes específicas de Azúcar"
+
+#: ../data/sugar.schemas.in.h:50
msgid "Sound Muted"
msgstr "Sonido silenciado"
-#: ../data/sugar.schemas.in.h:26
+#: ../data/sugar.schemas.in.h:51
msgid "The keyboard model to be used"
msgstr "El modelo del teclado que se utilizará"
-#: ../data/sugar.schemas.in.h:28
+#: ../data/sugar.schemas.in.h:53
msgid "Timezone setting for the system."
msgstr "Configuración de zona horaria para el sistema."
-#: ../data/sugar.schemas.in.h:29
+#: ../data/sugar.schemas.in.h:54
msgid "Url of the jabber server to use."
msgstr "URL del servidor de Jabber para usar."
-#: ../data/sugar.schemas.in.h:30
+#: ../data/sugar.schemas.in.h:55
msgid "Url where the backup is saved to."
msgstr "URL donde se guarda el backup."
-#: ../data/sugar.schemas.in.h:31
+#: ../data/sugar.schemas.in.h:56
msgid "User Color"
msgstr "Color del usuario"
-#: ../data/sugar.schemas.in.h:32
+#: ../data/sugar.schemas.in.h:57
msgid "User Name"
msgstr "Nombre de usuario"
-#: ../data/sugar.schemas.in.h:33
+#: ../data/sugar.schemas.in.h:58
msgid "User name that is used throughout the desktop."
msgstr "Nombre de usuario que se utiliza en todo el escritorio."
-#: ../data/sugar.schemas.in.h:34
+#: ../data/sugar.schemas.in.h:59
+msgid ""
+"Users will not be allowed to erase these activities through the list view."
+msgstr ""
+"Usuarios que no se les permitirá borrar actividades a través de la vista de "
+"lista."
+
+#: ../data/sugar.schemas.in.h:60
msgid "Volume Level"
msgstr "Nivel de volumen"
-#: ../data/sugar.schemas.in.h:35
+#: ../data/sugar.schemas.in.h:61
msgid "Volume level for the sound device."
msgstr "Nivel de volumen para el dispositivo de sonido."
-#: ../data/sugar.schemas.in.h:36
+#: ../data/sugar.schemas.in.h:62
msgid ""
"When in resume mode, clicking on a favorite icon will cause the last entry "
"for that activity to be resumed."
@@ -677,7 +974,7 @@ msgstr "sugar-control-panel: %s"
# which must appear in the translated string (msgstr) as well.
#. TRANS: Translators, there's a empty line at the end of this string,
#. which must appear in the translated string (msgstr) as well.
-#: ../src/jarabe/controlpanel/cmd.py:37
+#: ../src/jarabe/controlpanel/cmd.py:38
msgid ""
"Usage: sugar-control-panel [ option ] key [ args ... ] \n"
" Control for the sugar environment. \n"
@@ -701,72 +998,52 @@ msgstr ""
" -c clave vaciar el valor actual de la clave \n"
" "
-#: ../src/jarabe/controlpanel/cmd.py:50
+#: ../src/jarabe/controlpanel/cmd.py:52
msgid "To apply your changes you have to restart sugar.\n"
msgstr "Para aplicar sus cambios tiene que reiniciar Azúcar.\n"
-#: ../src/jarabe/controlpanel/gui.py:280
+#: ../src/jarabe/controlpanel/gui.py:297
+#: ../src/jarabe/journal/journaltoolbox.py:437
+#: ../src/jarabe/journal/volumestoolbar.py:158
msgid "Warning"
msgstr "Advertencia"
-#: ../src/jarabe/controlpanel/gui.py:281
-#: ../src/jarabe/controlpanel/sectionview.py:42
+#: ../src/jarabe/controlpanel/gui.py:298
+#: ../src/jarabe/controlpanel/sectionview.py:41
msgid "Changes require restart"
msgstr "Los cambios requieren reiniciar"
-#: ../src/jarabe/controlpanel/gui.py:284
+#: ../src/jarabe/controlpanel/gui.py:301
msgid "Cancel changes"
msgstr "Cancelar cambios"
-#: ../src/jarabe/controlpanel/gui.py:289 ../src/jarabe/desktop/homebox.py:70
+#: ../src/jarabe/controlpanel/gui.py:306 ../src/jarabe/desktop/homebox.py:72
msgid "Later"
msgstr "Después"
-#: ../src/jarabe/controlpanel/gui.py:293
+#: ../src/jarabe/controlpanel/gui.py:310
msgid "Restart now"
msgstr "Reiniciar ahora"
-#: ../src/jarabe/controlpanel/toolbar.py:61 ../src/jarabe/intro/window.py:188
+#: ../src/jarabe/controlpanel/toolbar.py:63 ../src/jarabe/intro/window.py:212
msgid "Done"
msgstr "Hecho"
-#: ../src/jarabe/controlpanel/toolbar.py:115
-#: ../src/jarabe/desktop/homebox.py:68
-#: ../src/jarabe/frame/activitiestray.py:726
-#: ../src/jarabe/frame/activitiestray.py:822
-#: ../src/jarabe/frame/activitiestray.py:850
-msgid "Cancel"
-msgstr "Cancelar"
-
-#: ../src/jarabe/controlpanel/toolbar.py:121
-#: ../src/jarabe/desktop/favoritesview.py:332
+#: ../src/jarabe/controlpanel/toolbar.py:125
+#: ../src/jarabe/desktop/favoritesview.py:336
msgid "Ok"
-msgstr "Ok"
-
-#: ../src/jarabe/desktop/activitieslist.py:80
-#: ../src/jarabe/journal/listview.py:147
-msgid "Title"
-msgstr "Título"
-
-#: ../src/jarabe/desktop/activitieslist.py:91
-msgid "Version"
-msgstr "Versión"
-
-#: ../src/jarabe/desktop/activitieslist.py:105
-#: ../src/jarabe/journal/listview.py:178
-msgid "Date"
-msgstr "Fecha"
+msgstr "Aceptar"
-#: ../src/jarabe/desktop/activitieslist.py:234
+#: ../src/jarabe/desktop/activitieslist.py:230
#, python-format
msgid "Version %s"
msgstr "Versión %s"
-#: ../src/jarabe/desktop/activitieslist.py:355
+#: ../src/jarabe/desktop/activitieslist.py:354
msgid "Confirm erase"
msgstr "Confirmar borrado"
-#: ../src/jarabe/desktop/activitieslist.py:357
+#: ../src/jarabe/desktop/activitieslist.py:356
#, python-format
msgid "Confirm erase: Do you want to permanently erase %s?"
msgstr "Confirmar el borrado: ¿Quiere borrar %s de forma permanente?"
@@ -775,390 +1052,448 @@ msgstr "Confirmar el borrado: ¿Quiere borrar %s de forma permanente?"
# TODO: Implement stopping downloads
# self._stop_item.connect('activate', self._stop_item_activate_cb)
# self.append_menu_item(self._stop_item)
-#: ../src/jarabe/desktop/activitieslist.py:361
-#: ../src/jarabe/frame/clipboardmenu.py:62
-#: ../src/jarabe/view/viewsource.py:218
+#: ../src/jarabe/desktop/activitieslist.py:360
+#: ../src/jarabe/frame/clipboardmenu.py:64
+#: ../src/jarabe/view/viewsource.py:221
msgid "Keep"
msgstr "Guardar"
-#: ../src/jarabe/desktop/activitieslist.py:364
-#: ../src/jarabe/desktop/activitieslist.py:407
-#: ../src/jarabe/journal/journaltoolbox.py:360
+#: ../src/jarabe/desktop/activitieslist.py:363
+#: ../src/jarabe/desktop/activitieslist.py:417
+#: ../src/jarabe/journal/journaltoolbox.py:391
#: ../src/jarabe/journal/palettes.py:112
msgid "Erase"
msgstr "Borrar"
-#: ../src/jarabe/desktop/activitieslist.py:428
+#: ../src/jarabe/desktop/activitieslist.py:432
msgid "Remove favorite"
msgstr "Remover favorito"
-#: ../src/jarabe/desktop/activitieslist.py:432
+#: ../src/jarabe/desktop/activitieslist.py:436
msgid "Make favorite"
msgstr "Hacer favorito"
# TRANS: label for the freeform layout in the favorites view
#. TRANS: label for the freeform layout in the favorites view
-#: ../src/jarabe/desktop/favoriteslayout.py:116
+#: ../src/jarabe/desktop/favoriteslayout.py:127
msgid "Freeform"
msgstr "Forma libre"
# TRANS: label for the ring layout in the favorites view
#. TRANS: label for the ring layout in the favorites view
-#: ../src/jarabe/desktop/favoriteslayout.py:198
+#: ../src/jarabe/desktop/favoriteslayout.py:215
msgid "Ring"
msgstr "Anillo"
# TRANS: label for the spiral layout in the favorites view
#. TRANS: label for the spiral layout in the favorites view
-#: ../src/jarabe/desktop/favoriteslayout.py:337
+#: ../src/jarabe/desktop/favoriteslayout.py:402
msgid "Spiral"
msgstr "Espiral"
# TRANS: label for the box layout in the favorites view
#. TRANS: label for the box layout in the favorites view
-#: ../src/jarabe/desktop/favoriteslayout.py:404
+#: ../src/jarabe/desktop/favoriteslayout.py:472
msgid "Box"
msgstr "Caja"
# TRANS: label for the box layout in the favorites view
#. TRANS: label for the box layout in the favorites view
-#: ../src/jarabe/desktop/favoriteslayout.py:445
+#: ../src/jarabe/desktop/favoriteslayout.py:515
msgid "Triangle"
msgstr "Triángulo"
-#: ../src/jarabe/desktop/favoritesview.py:323
+#: ../src/jarabe/desktop/favoritesview.py:327
msgid "Registration Failed"
-msgstr "Registro fallido"
+msgstr "Error al registrar"
-#: ../src/jarabe/desktop/favoritesview.py:324
+#: ../src/jarabe/desktop/favoritesview.py:328
#, python-format
msgid "%s"
msgstr "%s"
-#: ../src/jarabe/desktop/favoritesview.py:326
+#: ../src/jarabe/desktop/favoritesview.py:330
msgid "Registration Successful"
msgstr "Registro exitoso"
-#: ../src/jarabe/desktop/favoritesview.py:327
+#: ../src/jarabe/desktop/favoritesview.py:331
msgid "You are now registered with your school server."
msgstr "Ahora estás registrado en el servidor de colegio."
-#: ../src/jarabe/desktop/favoritesview.py:671
+#: ../src/jarabe/desktop/favoritesview.py:627
msgid "Register"
msgstr "Registro"
-#: ../src/jarabe/desktop/homebox.py:63
+#: ../src/jarabe/desktop/favoritesview.py:629
+#: ../src/jarabe/desktop/favoritesview.py:646
+msgid "Register again"
+msgstr "Registrar nuevamente"
+
+#: ../src/jarabe/desktop/homebox.py:65
msgid "Software Update"
msgstr "Actualización de Software"
-#: ../src/jarabe/desktop/homebox.py:64
+#: ../src/jarabe/desktop/homebox.py:66
msgid "Update your activities to ensure compatibility with your new software"
msgstr ""
"Actualice sus actividades para asegurar compatibilidad con su nuevo software"
-#: ../src/jarabe/desktop/homebox.py:73
+#: ../src/jarabe/desktop/homebox.py:75
msgid "Check now"
msgstr "Pruebe ahora"
-#: ../src/jarabe/desktop/homebox.py:192
+#: ../src/jarabe/desktop/homebox.py:193
msgid "List view"
msgstr "Vista en lista"
-#: ../src/jarabe/desktop/homebox.py:193
+#: ../src/jarabe/desktop/homebox.py:194
msgid "<Ctrl>2"
msgstr "<Ctrl>2"
-#: ../src/jarabe/desktop/homebox.py:255
+#: ../src/jarabe/desktop/homebox.py:257
msgid "Favorites view"
msgstr "Vista de favoritos"
-#: ../src/jarabe/desktop/homebox.py:256
+#: ../src/jarabe/desktop/homebox.py:258
msgid "<Ctrl>1"
msgstr "<Ctrl>1"
# This is an encryption key type, not a keyboard key
-#: ../src/jarabe/desktop/keydialog.py:131
+#: ../src/jarabe/desktop/keydialog.py:143
msgid "Key Type:"
msgstr "Tipo de clave:"
-#: ../src/jarabe/desktop/keydialog.py:151
+#: ../src/jarabe/desktop/keydialog.py:163
msgid "Authentication Type:"
msgstr "Tipo de autenticación:"
-#: ../src/jarabe/desktop/keydialog.py:215
+#: ../src/jarabe/desktop/keydialog.py:229
msgid "WPA & WPA2 Personal"
msgstr "WPA y WPA2 Personal"
-#: ../src/jarabe/desktop/keydialog.py:224
+#: ../src/jarabe/desktop/keydialog.py:238
msgid "Wireless Security:"
msgstr "Seguridad inalámbrica:"
-#: ../src/jarabe/desktop/meshbox.py:136
-msgid "Connect"
-msgstr "Conectar"
-
-#: ../src/jarabe/desktop/meshbox.py:140
-msgid "Disconnect"
-msgstr "Desconectar"
-
# TRANS: Action label for resuming an activity.
#. TRANS: Action label for resuming an activity.
-#: ../src/jarabe/desktop/meshbox.py:466
-#: ../src/jarabe/frame/activitiestray.py:761
-#: ../src/jarabe/journal/journaltoolbox.py:428
-#: ../src/jarabe/journal/palettes.py:72 ../src/jarabe/view/palettes.py:64
+#: ../src/jarabe/desktop/meshbox.py:109
+#: ../src/jarabe/frame/activitiestray.py:622
+#: ../src/jarabe/journal/journaltoolbox.py:485
+#: ../src/jarabe/journal/palettes.py:66 ../src/jarabe/view/palettes.py:78
msgid "Resume"
msgstr "Retomar"
-#: ../src/jarabe/desktop/meshbox.py:471
-#: ../src/jarabe/frame/activitiestray.py:235
+#: ../src/jarabe/desktop/meshbox.py:114
+#: ../src/jarabe/frame/activitiestray.py:173
msgid "Join"
msgstr "Unirse"
-#: ../src/jarabe/desktop/schoolserver.py:103
+#: ../src/jarabe/desktop/networkviews.py:497
+#, python-format
+msgid "Ad-hoc Network %d"
+msgstr "Red específica %d"
+
+#: ../src/jarabe/desktop/networkviews.py:628
+#, python-format
+msgid "Mesh Network %d"
+msgstr "Red Malla %d"
+
+#: ../src/jarabe/desktop/schoolserver.py:131
msgid "Cannot connect to the server."
msgstr "No se puede conectar al servidor."
-#: ../src/jarabe/desktop/schoolserver.py:108
+#: ../src/jarabe/desktop/schoolserver.py:136
msgid "The server could not complete the request."
msgstr "El servidor no pudo completar el pedido."
-#: ../src/jarabe/frame/activitiestray.py:240
-#: ../src/jarabe/frame/activitiestray.py:698
+#: ../src/jarabe/frame/activitiestray.py:178
+#: ../src/jarabe/frame/activitiestray.py:559
msgid "Decline"
msgstr "Rechazar"
-#: ../src/jarabe/frame/activitiestray.py:650
+#: ../src/jarabe/frame/activitiestray.py:509
#, python-format
msgid "%dB"
msgstr "%dB"
-#: ../src/jarabe/frame/activitiestray.py:652
+#: ../src/jarabe/frame/activitiestray.py:511
#, python-format
msgid "%dKB"
msgstr "%dKB"
-#: ../src/jarabe/frame/activitiestray.py:654
+#: ../src/jarabe/frame/activitiestray.py:513
#, python-format
msgid "%dMB"
msgstr "%dMB"
-#: ../src/jarabe/frame/activitiestray.py:671
+#: ../src/jarabe/frame/activitiestray.py:530
#, python-format
msgid "%s of %s"
msgstr "%s de %s"
-#: ../src/jarabe/frame/activitiestray.py:683
+#: ../src/jarabe/frame/activitiestray.py:544
#, python-format
msgid "Transfer from %r"
msgstr "Transferencia desde %r"
-#: ../src/jarabe/frame/activitiestray.py:693
+#: ../src/jarabe/frame/activitiestray.py:554
msgid "Accept"
msgstr "Aceptar"
-#: ../src/jarabe/frame/activitiestray.py:716
-#: ../src/jarabe/frame/activitiestray.py:840
+#: ../src/jarabe/frame/activitiestray.py:577
+#: ../src/jarabe/frame/activitiestray.py:705
#, python-format
msgid "%s (%s)"
msgstr "%s (%s)"
-#: ../src/jarabe/frame/activitiestray.py:750
-#: ../src/jarabe/frame/activitiestray.py:875
+#: ../src/jarabe/frame/activitiestray.py:611
+#: ../src/jarabe/frame/activitiestray.py:740
msgid "Dismiss"
msgstr "Descartar"
-#: ../src/jarabe/frame/activitiestray.py:810
+#: ../src/jarabe/frame/activitiestray.py:675
#, python-format
msgid "Transfer to %r"
msgstr "Transferencia a %r"
-#: ../src/jarabe/frame/clipboardmenu.py:52 ../src/jarabe/view/palettes.py:218
+#: ../src/jarabe/frame/clipboardmenu.py:54 ../src/jarabe/view/palettes.py:220
msgid "Remove"
msgstr "Eliminar"
-#: ../src/jarabe/frame/clipboardmenu.py:57
-#: ../src/jarabe/frame/clipboardmenu.py:80
+#: ../src/jarabe/frame/clipboardmenu.py:59
+#: ../src/jarabe/frame/clipboardmenu.py:82
msgid "Open"
msgstr "Abrir"
-#: ../src/jarabe/frame/clipboardmenu.py:85
+#: ../src/jarabe/frame/clipboardmenu.py:87
msgid "Open with"
msgstr "Abrir con"
-#: ../src/jarabe/frame/clipboardobject.py:49
+#: ../src/jarabe/frame/clipboardobject.py:50
#, python-format
msgid "%s clipping"
msgstr "recorte de %s"
-#: ../src/jarabe/frame/zoomtoolbar.py:37
+#: ../src/jarabe/frame/zoomtoolbar.py:38
msgid "Neighborhood"
msgstr "Vecindario"
-#: ../src/jarabe/frame/zoomtoolbar.py:37
+#: ../src/jarabe/frame/zoomtoolbar.py:38
msgid "F1"
msgstr "F1"
-#: ../src/jarabe/frame/zoomtoolbar.py:39
+#: ../src/jarabe/frame/zoomtoolbar.py:40
msgid "F2"
msgstr "F2"
-#: ../src/jarabe/frame/zoomtoolbar.py:41
+#: ../src/jarabe/frame/zoomtoolbar.py:42
msgid "F3"
msgstr "F3"
-#: ../src/jarabe/frame/zoomtoolbar.py:43
+#: ../src/jarabe/frame/zoomtoolbar.py:44
msgid "F4"
msgstr "F4"
-#: ../src/jarabe/intro/window.py:124
+#: ../src/jarabe/intro/window.py:97
+msgid "Name:"
+msgstr "Nombre:"
+
+#: ../src/jarabe/intro/window.py:133
msgid "Click to change color:"
msgstr "Clic para cambiar de color:"
-#: ../src/jarabe/intro/window.py:174 ../src/jarabe/journal/detailview.py:103
+#: ../src/jarabe/intro/window.py:198 ../src/jarabe/journal/detailview.py:105
msgid "Back"
msgstr "Atrás"
-#: ../src/jarabe/intro/window.py:191
+#: ../src/jarabe/intro/window.py:215
msgid "Next"
msgstr "Siguiente"
-#: ../src/jarabe/journal/expandedentry.py:164
-#: ../src/jarabe/journal/palettes.py:66
+#: ../src/jarabe/journal/expandedentry.py:154
+#: ../src/jarabe/journal/listmodel.py:144 ../src/jarabe/journal/palettes.py:59
msgid "Untitled"
msgstr "Sin título"
-#: ../src/jarabe/journal/expandedentry.py:210
+#: ../src/jarabe/journal/expandedentry.py:243
msgid "No preview"
msgstr "Sin vista previa"
-#: ../src/jarabe/journal/expandedentry.py:229
+#: ../src/jarabe/journal/expandedentry.py:262
#, python-format
msgid "Kind: %s"
msgstr "Tipo: %s"
-#: ../src/jarabe/journal/expandedentry.py:229
+#: ../src/jarabe/journal/expandedentry.py:262
+#: ../src/jarabe/journal/listmodel.py:150
+#: ../src/jarabe/journal/listmodel.py:158
+#: ../src/jarabe/journal/listmodel.py:166
msgid "Unknown"
msgstr "Desconocido"
-#: ../src/jarabe/journal/expandedentry.py:230
+#: ../src/jarabe/journal/expandedentry.py:263
#, python-format
msgid "Date: %s"
msgstr "Fecha: %s"
-#: ../src/jarabe/journal/expandedentry.py:231
+#: ../src/jarabe/journal/expandedentry.py:264
#, python-format
msgid "Size: %s"
msgstr "Tamaño: %s"
-#: ../src/jarabe/journal/expandedentry.py:253 ../src/jarabe/journal/misc.py:92
+#: ../src/jarabe/journal/expandedentry.py:292
+#: ../src/jarabe/journal/misc.py:108
msgid "No date"
msgstr "Sin fecha"
-#: ../src/jarabe/journal/expandedentry.py:260
+#: ../src/jarabe/journal/expandedentry.py:299
msgid "Participants:"
msgstr "Participantes:"
-#: ../src/jarabe/journal/expandedentry.py:283
+#: ../src/jarabe/journal/expandedentry.py:321
msgid "Description:"
msgstr "Descripción:"
-#: ../src/jarabe/journal/expandedentry.py:309
+#: ../src/jarabe/journal/expandedentry.py:346
msgid "Tags:"
msgstr "Etiquetas:"
-#: ../src/jarabe/journal/journalactivity.py:108
-#: ../src/jarabe/journal/volumestoolbar.py:47
+#: ../src/jarabe/journal/journalactivity.py:115
+#: ../src/jarabe/journal/journaltoolbox.py:456
+#: ../src/jarabe/journal/volumestoolbar.py:50
msgid "Journal"
msgstr "Diario"
-#: ../src/jarabe/journal/journaltoolbox.py:67
+#: ../src/jarabe/journal/journaltoolbox.py:69
msgid "Search"
msgstr "Buscar"
-#: ../src/jarabe/journal/journaltoolbox.py:126
+#: ../src/jarabe/journal/journaltoolbox.py:136
msgid "Anytime"
msgstr "Cualquier momento"
-#: ../src/jarabe/journal/journaltoolbox.py:128
+#: ../src/jarabe/journal/journaltoolbox.py:138
msgid "Today"
msgstr "Hoy"
-#: ../src/jarabe/journal/journaltoolbox.py:130
+#: ../src/jarabe/journal/journaltoolbox.py:140
msgid "Since yesterday"
msgstr "Desde ayer"
# TRANS: Filter entries modified during the last 7 days.
#. TRANS: Filter entries modified during the last 7 days.
-#: ../src/jarabe/journal/journaltoolbox.py:132
+#: ../src/jarabe/journal/journaltoolbox.py:142
msgid "Past week"
msgstr "Última semana"
# TRANS: Filter entries modified during the last 30 days.
#. TRANS: Filter entries modified during the last 30 days.
-#: ../src/jarabe/journal/journaltoolbox.py:134
+#: ../src/jarabe/journal/journaltoolbox.py:144
msgid "Past month"
msgstr "Último mes"
# TRANS: Filter entries modified during the last 356 days.
#. TRANS: Filter entries modified during the last 356 days.
-#: ../src/jarabe/journal/journaltoolbox.py:136
+#: ../src/jarabe/journal/journaltoolbox.py:146
msgid "Past year"
msgstr "Último año"
-#: ../src/jarabe/journal/journaltoolbox.py:143
+#: ../src/jarabe/journal/journaltoolbox.py:153
msgid "Anyone"
msgstr "Cualquiera"
-#: ../src/jarabe/journal/journaltoolbox.py:145
+#: ../src/jarabe/journal/journaltoolbox.py:155
msgid "My friends"
msgstr "Mis amigos"
-#: ../src/jarabe/journal/journaltoolbox.py:146
+#: ../src/jarabe/journal/journaltoolbox.py:156
msgid "My class"
msgstr "Mi clase"
# TRANS: Item in a combo box that filters by entry type.
-#: ../src/jarabe/journal/journaltoolbox.py:274
+#: ../src/jarabe/journal/journaltoolbox.py:298
msgid "Anything"
msgstr "Cualquiera"
# TODO: Add "Start with" menu item
-#: ../src/jarabe/journal/journaltoolbox.py:350
+#: ../src/jarabe/journal/journaltoolbox.py:381
#: ../src/jarabe/journal/palettes.py:90
msgid "Copy"
msgstr "Copiar"
+#: ../src/jarabe/journal/journaltoolbox.py:436
+#: ../src/jarabe/journal/volumestoolbar.py:157
+msgid "Entries without a file cannot be copied."
+msgstr "Entradas sin un archivo no pueden ser copiadas."
+
+#: ../src/jarabe/journal/journaltoolbox.py:445
+#: ../src/jarabe/journal/volumestoolbar.py:166
+#, python-format
+msgid "Error while copying the entry. %s"
+msgstr "Error mientras se copiaba la entrada. %s"
+
+#: ../src/jarabe/journal/journaltoolbox.py:446
+#: ../src/jarabe/journal/volumestoolbar.py:167
+msgid "Error"
+msgstr "Error"
+
# TRANS: Action label for starting an entry.
#. TRANS: Action label for starting an entry.
-#: ../src/jarabe/journal/journaltoolbox.py:431
-#: ../src/jarabe/journal/palettes.py:75
+#: ../src/jarabe/journal/journaltoolbox.py:488
+#: ../src/jarabe/journal/palettes.py:69
msgid "Start"
msgstr "Iniciar"
-#: ../src/jarabe/journal/listview.py:361
+#: ../src/jarabe/journal/journaltoolbox.py:516
+msgid "Sort by date modified"
+msgstr "Ordenar por fecha de modificación"
+
+#: ../src/jarabe/journal/journaltoolbox.py:517
+msgid "Sort by date created"
+msgstr "Ordenar por fecha de creación"
+
+#: ../src/jarabe/journal/journaltoolbox.py:518
+msgid "Sort by size"
+msgstr "Ordenar por tamaño"
+
+#: ../src/jarabe/journal/journaltoolbox.py:527
+msgid "Sort view"
+msgstr "Ordenar vista"
+
+#: ../src/jarabe/journal/listview.py:380
msgid "Your Journal is empty"
msgstr "Su diario está vacío"
-#: ../src/jarabe/journal/listview.py:363
+#: ../src/jarabe/journal/listview.py:382
msgid "No matching entries"
msgstr "No hay entradas coincidentes"
-#: ../src/jarabe/journal/listview.py:374
+#: ../src/jarabe/journal/listview.py:393
msgid "Clear search"
msgstr "Limpiar búsqueda"
-#: ../src/jarabe/journal/modalalert.py:63
+#: ../src/jarabe/journal/misc.py:273
+#, python-format
+msgid "Older Version Of %s Activity"
+msgstr "Versión más antigua de la actividad %s"
+
+#: ../src/jarabe/journal/misc.py:274
+#, python-format
+msgid "Do you want to downgrade to version %s"
+msgstr "¿Desea instalar la versión %s, mas antigua? "
+
+#: ../src/jarabe/journal/modalalert.py:64
msgid "Your Journal is full"
-msgstr "Su diario está vacío"
+msgstr "Su diario está lleno"
-#: ../src/jarabe/journal/modalalert.py:67
+#: ../src/jarabe/journal/modalalert.py:68
msgid "Please delete some old Journal entries to make space for new ones."
msgstr ""
-"Por favor borre las entradas viejas del diario para hacer espacio a las "
+"Por favor borre algunas entradas viejas del diario para hacer espacio a las "
"nuevas entradas."
-#: ../src/jarabe/journal/modalalert.py:79
+#: ../src/jarabe/journal/modalalert.py:80
msgid "Show Journal"
msgstr "Mostrar diario"
@@ -1167,18 +1502,22 @@ msgid "Choose an object"
msgstr "Escoja un objeto"
#: ../src/jarabe/journal/objectchooser.py:151
-#: ../src/jarabe/view/viewsource.py:308
+#: ../src/jarabe/view/viewsource.py:311
msgid "Close"
msgstr "Cerrar"
-#: ../src/jarabe/journal/palettes.py:73
+#: ../src/jarabe/journal/palettes.py:67
msgid "Resume with"
msgstr "Reiniciar con"
-#: ../src/jarabe/journal/palettes.py:76
+#: ../src/jarabe/journal/palettes.py:70
msgid "Start with"
msgstr "Empezar con"
+#: ../src/jarabe/journal/palettes.py:83 ../src/jarabe/journal/palettes.py:216
+msgid "No activity to start entry"
+msgstr "No se encontró una actividad para iniciar la entrada"
+
#: ../src/jarabe/journal/palettes.py:98
msgid "Send to"
msgstr "Enviar a"
@@ -1187,103 +1526,313 @@ msgstr "Enviar a"
msgid "View Details"
msgstr "Ver detalles"
-#: ../src/jarabe/journal/palettes.py:185
+#: ../src/jarabe/journal/palettes.py:181
msgid "No friends present"
msgstr "No hay amigos presentes"
# tildes
-#: ../src/jarabe/journal/palettes.py:190
+#: ../src/jarabe/journal/palettes.py:186
msgid "No valid connection found"
msgstr "No se encontró una conexión válida"
# tildes...
-#: ../src/jarabe/journal/palettes.py:218
+#: ../src/jarabe/journal/palettes.py:214
msgid "No activity to resume entry"
msgstr "No se encontró una actividad para retomar la entrada"
-#: ../src/jarabe/journal/palettes.py:220
-msgid "No activity to start entry"
-msgstr "No se encontró una actividad para iniciar la entrada"
+#: ../src/jarabe/model/network.py:163
+msgid "The reason for the device state change is unknown."
+msgstr "La razón para el cambio de estado del dispositivo es desconocida."
+
+#: ../src/jarabe/model/network.py:165
+msgid "The state change is normal."
+msgstr "El cambio de estado es normal."
+
+#: ../src/jarabe/model/network.py:167
+msgid "The device is now managed."
+msgstr "El dispositivo está siendo administrado."
+
+#: ../src/jarabe/model/network.py:169
+msgid "The device is no longer managed."
+msgstr "El dispositivo ya no está siendo administrado."
+
+#: ../src/jarabe/model/network.py:171
+msgid "The device could not be readied for configuration."
+msgstr "El dispositivo no pudo ser preparado para su configuración."
+
+#: ../src/jarabe/model/network.py:173
+msgid ""
+"IP configuration could not be reserved (no available address, timeout, etc)."
+msgstr ""
+"La configuración IP no pudo ser reservada (no hay dirección disponible, "
+"tiempo fuera, etc)."
+
+#: ../src/jarabe/model/network.py:176
+msgid "The IP configuration is no longer valid."
+msgstr "La configuración IP ya no es válida."
+
+#: ../src/jarabe/model/network.py:178
+msgid "Secrets were required, but not provided."
+msgstr "Claves requeridas, pero no fueron suministradas."
+
+#: ../src/jarabe/model/network.py:180
+msgid ""
+"The 802.1X supplicant disconnected from the access point or authentication "
+"server."
+msgstr ""
+"El cliente 802.1X fué desconectado del punto de acceso o del server de "
+"autenticación."
+
+#: ../src/jarabe/model/network.py:183
+msgid "Configuration of the 802.1X supplicant failed."
+msgstr "Configuración del cliente 802.1X fallada."
+
+#: ../src/jarabe/model/network.py:185
+msgid "The 802.1X supplicant quit or failed unexpectedly."
+msgstr "El cliente 802.1X ha abandonado o fallado inesperadamente."
+
+#: ../src/jarabe/model/network.py:187
+msgid "The 802.1X supplicant took too long to authenticate."
+msgstr "El cliente 802.1X ha tomado demasiado tiempo para autenticar."
+
+#: ../src/jarabe/model/network.py:189
+msgid "The PPP service failed to start within the allowed time."
+msgstr "El servicio PPP ha fallado en comenzar en el tiempo permitido."
+
+#: ../src/jarabe/model/network.py:191
+msgid "The PPP service disconnected unexpectedly."
+msgstr "El servicio PPP se ha desconectado inesperadamente."
+
+#: ../src/jarabe/model/network.py:193
+msgid "The PPP service quit or failed unexpectedly."
+msgstr "El servicio PPP ha abandonado o fallado inesperadamente."
+
+#: ../src/jarabe/model/network.py:195
+msgid "The DHCP service failed to start within the allowed time."
+msgstr "El servicio DHCP ha fallado en comenzar en el tiempo permitido."
+
+#: ../src/jarabe/model/network.py:197
+msgid "The DHCP service reported an unexpected error."
+msgstr "El servicio DHCP ha reportado un error inesperado."
+
+#: ../src/jarabe/model/network.py:199
+msgid "The DHCP service quit or failed unexpectedly."
+msgstr "El servicio DHCP ha abandonado o fallado inesperadamente."
+
+#: ../src/jarabe/model/network.py:201
+msgid "The shared connection service failed to start."
+msgstr "El servicio de conexión compartida ha fallado al iniciar."
+
+#: ../src/jarabe/model/network.py:203
+msgid "The shared connection service quit or failed unexpectedly."
+msgstr ""
+"El servicio de conexión compartida ha abandonado o fallado inesperadamente."
+
+#: ../src/jarabe/model/network.py:206
+msgid "The AutoIP service failed to start."
+msgstr "El servicio AutoIP ha fallado al iniciar."
+
+#: ../src/jarabe/model/network.py:208
+msgid "The AutoIP service reported an unexpected error."
+msgstr "El servicio AutoIP ha reportado un error inesperado."
+
+#: ../src/jarabe/model/network.py:210
+msgid "The AutoIP service quit or failed unexpectedly."
+msgstr "El servicio AutoIP ha abandonado o fallado inesperadamente."
+
+#: ../src/jarabe/model/network.py:212
+msgid "Dialing failed because the line was busy."
+msgstr "Conexión fallada porque la línea estaba ocupada."
+
+#: ../src/jarabe/model/network.py:214
+msgid "Dialing failed because there was no dial tone."
+msgstr "Conexión fallada porque no había tono de llamada."
+
+#: ../src/jarabe/model/network.py:216
+msgid "Dialing failed because there was no carrier."
+msgstr "Conexión fallada porque no había portadora."
+
+#: ../src/jarabe/model/network.py:218
+msgid "Dialing timed out."
+msgstr "Llamada expiró por tiempo."
+
+#: ../src/jarabe/model/network.py:220
+msgid "Dialing failed."
+msgstr "Llamada falló."
+
+#: ../src/jarabe/model/network.py:222
+msgid "Modem initialization failed."
+msgstr "Fallo en inicialización de modem."
+
+#: ../src/jarabe/model/network.py:224
+msgid "Failed to select the specified GSM APN"
+msgstr "Fallo al seleccionar el punto de acceso (APN) GSM"
+
+#: ../src/jarabe/model/network.py:226
+msgid "Not searching for networks."
+msgstr "No se buscan redes."
+
+#: ../src/jarabe/model/network.py:228
+msgid "Network registration was denied."
+msgstr "Registración en la red fué rechazada."
+
+#: ../src/jarabe/model/network.py:230
+msgid "Network registration timed out."
+msgstr "Registración en la red expiró."
+
+#: ../src/jarabe/model/network.py:232
+msgid "Failed to register with the requested GSM network."
+msgstr "Falló la registración con la red GSM solicitada."
+
+#: ../src/jarabe/model/network.py:234
+msgid "PIN check failed."
+msgstr "Control de PIN fallado."
+
+#: ../src/jarabe/model/network.py:236
+msgid "Necessary firmware for the device may be missing."
+msgstr "Firmware necesario para el dispositivo puede faltar."
+
+#: ../src/jarabe/model/network.py:238
+msgid "The device was removed."
+msgstr "El dispositivo fué quitado."
+
+#: ../src/jarabe/model/network.py:240
+msgid "NetworkManager went to sleep."
+msgstr "NetworkManager fue dormido."
+
+#: ../src/jarabe/model/network.py:242
+msgid "The device's active connection was removed or disappeared."
+msgstr ""
+"Las conexiones activas del dispositivo fueron removidas o desaparecieron."
+
+#: ../src/jarabe/model/network.py:245
+msgid "A user or client requested the disconnection."
+msgstr "Un usuario o cliente solicitó la desconexión."
+
+#: ../src/jarabe/model/network.py:247
+msgid "The device's carrier/link changed."
+msgstr "La portadora/link del dispositivo a cambiado."
# "Eliminate friend"??? That's a bit harsh. Wouldn't "quitar amigo" be a better choice?--
# agree but i preffer remover :). that verbe has the exact meaning we are looking on here.
-#: ../src/jarabe/view/buddymenu.py:62
+#: ../src/jarabe/view/buddymenu.py:63
msgid "Remove friend"
msgstr "Remover amigo"
-#: ../src/jarabe/view/buddymenu.py:65
+#: ../src/jarabe/view/buddymenu.py:66
msgid "Make friend"
msgstr "Agregar amigo"
-#: ../src/jarabe/view/buddymenu.py:82
+#: ../src/jarabe/view/buddymenu.py:83
msgid "Shutdown"
msgstr "Apagar"
-#: ../src/jarabe/view/buddymenu.py:90
+#: ../src/jarabe/view/buddymenu.py:91
+msgid "Restart"
+msgstr "Reiniciar"
+
+#: ../src/jarabe/view/buddymenu.py:97
msgid "Logout"
msgstr "Salir"
-#: ../src/jarabe/view/buddymenu.py:95
+#: ../src/jarabe/view/buddymenu.py:102
msgid "My Settings"
msgstr "Mis ajustes"
-#: ../src/jarabe/view/buddymenu.py:130
+#: ../src/jarabe/view/buddymenu.py:137
#, python-format
msgid "Invite to %s"
msgstr "Invitar a %s"
-#: ../src/jarabe/view/palettes.py:45
+#: ../src/jarabe/view/launcher.py:190
+#, python-format
+msgid "<b>%s</b> failed to start."
+msgstr "<b>%s</b> falló al iniciar."
+
+#: ../src/jarabe/view/palettes.py:46
msgid "Starting..."
msgstr "Iniciando..."
+#: ../src/jarabe/view/palettes.py:56
+msgid "Activity failed to start"
+msgstr "Actividad falló al iniciar"
+
#. TODO: share-with, keep
-#: ../src/jarabe/view/palettes.py:71
+#: ../src/jarabe/view/palettes.py:85
msgid "View Source"
msgstr "Ver fuente"
-#: ../src/jarabe/view/palettes.py:82
+#: ../src/jarabe/view/palettes.py:96
msgid "Stop"
msgstr "Parar"
-#: ../src/jarabe/view/palettes.py:122
+#: ../src/jarabe/view/palettes.py:132
msgid "Start new"
msgstr "Empezar nuevo"
-#: ../src/jarabe/view/palettes.py:171
+#: ../src/jarabe/view/palettes.py:172
msgid "Show contents"
msgstr "Mostrar contenidos"
-#: ../src/jarabe/view/palettes.py:193 ../src/jarabe/view/palettes.py:243
+#: ../src/jarabe/view/palettes.py:194 ../src/jarabe/view/palettes.py:245
#, python-format
msgid "%(free_space)d MB Free"
msgstr "%(free_space)d MB libres"
-#: ../src/jarabe/view/viewsource.py:208
+#: ../src/jarabe/view/viewsource.py:211
msgid "Instance Source"
msgstr "Fuente de la instancia"
-#: ../src/jarabe/view/viewsource.py:233
+#: ../src/jarabe/view/viewsource.py:236
msgid "Source"
msgstr "Fuente"
-#: ../src/jarabe/view/viewsource.py:292
+#: ../src/jarabe/view/viewsource.py:295
msgid "Activity Bundle Source"
msgstr "Fuente del paquete de la actividad"
-#: ../src/jarabe/view/viewsource.py:299
+#: ../src/jarabe/view/viewsource.py:302
#, python-format
msgid "View source: %r"
msgstr "Ver código fuente: %r"
+#: ../src/jarabe/util/emulator.py:40
+msgid "Sugar in a window"
+msgstr "Sugar en una ventana"
+
+# Access point name for GPRS network
+#~ msgid "APN:"
+#~ msgstr "Nombre del Punto de Acceso:"
+
+#~ msgid "Create new wireless network"
+#~ msgstr "Crear nueva red inalámbrica"
+
+#, python-format
+#~ msgid "%s's network"
+#~ msgstr "Red de %s"
+
+#, python-format
+#~ msgid "Data sent %d kb / received %d kb"
+#~ msgstr "Datos enviados %d kb / recibidos %d kb"
+
+#~ msgid "Connection time "
+#~ msgstr "Tiempo de conexión "
+
+#~ msgid "Title"
+#~ msgstr "Título"
+
+#~ msgid "Version"
+#~ msgstr "Versión"
+
+#~ msgid "Date"
+#~ msgstr "Fecha"
+
#~ msgid "Cannot obtain data needed for registration."
#~ msgstr "No se puede obtener datos necesarios para el registro"
#~ msgid "Unmount"
#~ msgstr "Desmontar"
-#~ msgid "Restart"
-#~ msgstr "Reiniciar"
-
#~ msgid ""
#~ "© 2008 One Laptop per Child Association Inc; Red Hat Inc; and Contributors."
#~ msgstr ""
@@ -1306,12 +1855,6 @@ msgstr "Ver código fuente: %r"
#~ msgid "Disconnecting..."
#~ msgstr "Desconectando..."
-#~ msgid "Mesh Network"
-#~ msgstr "Red Malla"
-
-#~ msgid "Disconnected"
-#~ msgstr "Desconectado"
-
#~ msgid "About my XO"
#~ msgstr "Acerca de mi XO"
diff --git a/po/fr.po b/po/fr.po
index caf42af..b383cc4 100644
--- a/po/fr.po
+++ b/po/fr.po
@@ -1,3 +1,15 @@
+# SOME DESCRIPTIVE TITLE.
+# 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.
+# SOME DESCRIPTIVE TITLE.
+# 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.
+# SOME DESCRIPTIVE TITLE.
+# 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.
# translation of sugar.po to french
# Copyright (C) 2007 the Package Owner
# This file is distributed under the same license as the sugar graphical shell package.
@@ -6,8 +18,8 @@ msgid ""
msgstr ""
"Project-Id-Version: sugar\n"
"Report-Msgid-Bugs-To: \n"
-"POT-Creation-Date: 2010-02-11 00:32-0500\n"
-"PO-Revision-Date: 2010-08-08 11:26+0200\n"
+"POT-Creation-Date: 2011-02-06 00:30-0500\n"
+"PO-Revision-Date: 2011-02-11 18:23+0200\n"
"Last-Translator: samy boutayeb <s.boutayeb@free.fr>\n"
"Language-Team: French <traduc@traduc.org>\n"
"Language: fr\n"
@@ -21,43 +33,39 @@ msgstr ""
msgid "About Me"
msgstr "Moi"
-#: ../extensions/cpsection/aboutme/model.py:43
+#: ../extensions/cpsection/aboutme/model.py:48
msgid "You must enter a name."
msgstr "Vous devez indiquer un nom."
-#: ../extensions/cpsection/aboutme/model.py:68
+#: ../extensions/cpsection/aboutme/model.py:75
#, python-format
msgid "stroke: color=%s hue=%s"
msgstr "stroke: color=%s hue=%s"
-#: ../extensions/cpsection/aboutme/model.py:71
+#: ../extensions/cpsection/aboutme/model.py:78
#, python-format
msgid "stroke: %s"
msgstr "stroke: %s"
-#: ../extensions/cpsection/aboutme/model.py:73
+#: ../extensions/cpsection/aboutme/model.py:80
#, python-format
msgid "fill: color=%s hue=%s"
msgstr "fill: color=%s hue=%s"
-#: ../extensions/cpsection/aboutme/model.py:75
+#: ../extensions/cpsection/aboutme/model.py:82
#, python-format
msgid "fill: %s"
msgstr "fill: %s"
-#: ../extensions/cpsection/aboutme/model.py:86
+#: ../extensions/cpsection/aboutme/model.py:94
msgid "Error in specified color modifiers."
msgstr "Erreur dans les modificateurs de couleur spécifiés."
-#: ../extensions/cpsection/aboutme/model.py:89
+#: ../extensions/cpsection/aboutme/model.py:97
msgid "Error in specified colors."
msgstr "Erreur dans les couleurs spécifiées."
-#: ../extensions/cpsection/aboutme/view.py:94 ../src/jarabe/intro/window.py:93
-msgid "Name:"
-msgstr "Nom :"
-
-#: ../extensions/cpsection/aboutme/view.py:128
+#: ../extensions/cpsection/aboutme/view.py:235
msgid "Click to change your color:"
msgstr "Cliquer pour changer de couleur :"
@@ -65,43 +73,48 @@ msgstr "Cliquer pour changer de couleur :"
msgid "About my Computer"
msgstr "Mon ordinateur"
-#: ../extensions/cpsection/aboutcomputer/model.py:28
+#: ../extensions/cpsection/aboutcomputer/model.py:37
msgid "Not available"
msgstr "Non disponible"
-#: ../extensions/cpsection/aboutcomputer/view.py:60
+#: ../extensions/cpsection/aboutcomputer/model.py:158
+#, python-format
+msgid "%(interface)s: %(version)s"
+msgstr "%(interface)s : %(version)s"
+
+#: ../extensions/cpsection/aboutcomputer/view.py:61
msgid "Identity"
msgstr "Identité"
-#: ../extensions/cpsection/aboutcomputer/view.py:69
+#: ../extensions/cpsection/aboutcomputer/view.py:70
msgid "Serial Number:"
msgstr "Numéro de série :"
-#: ../extensions/cpsection/aboutcomputer/view.py:91
+#: ../extensions/cpsection/aboutcomputer/view.py:92
msgid "Software"
msgstr "Logiciel"
-#: ../extensions/cpsection/aboutcomputer/view.py:100
+#: ../extensions/cpsection/aboutcomputer/view.py:101
msgid "Build:"
msgstr "Version :"
-#: ../extensions/cpsection/aboutcomputer/view.py:115
+#: ../extensions/cpsection/aboutcomputer/view.py:116
msgid "Sugar:"
msgstr "Sugar :"
-#: ../extensions/cpsection/aboutcomputer/view.py:131
+#: ../extensions/cpsection/aboutcomputer/view.py:132
msgid "Firmware:"
msgstr "Micrologiciel :"
-#: ../extensions/cpsection/aboutcomputer/view.py:146
+#: ../extensions/cpsection/aboutcomputer/view.py:147
msgid "Wireless Firmware:"
msgstr "Micrologiciel sans fil :"
-#: ../extensions/cpsection/aboutcomputer/view.py:169
+#: ../extensions/cpsection/aboutcomputer/view.py:170
msgid "Copyright and License"
msgstr "Copyright et licence"
-#: ../extensions/cpsection/aboutcomputer/view.py:184
+#: ../extensions/cpsection/aboutcomputer/view.py:188
msgid ""
"Sugar is the graphical user interface that you are looking at. Sugar is free "
"software, covered by the GNU General Public License, and you are welcome to "
@@ -113,7 +126,7 @@ msgstr ""
"License). Vous êtes autorisé à le modifier et/ou à en distribuer des copies "
"aux conditions spécifiées."
-#: ../extensions/cpsection/aboutcomputer/view.py:196
+#: ../extensions/cpsection/aboutcomputer/view.py:200
msgid "Full license:"
msgstr "Licence complète :"
@@ -121,11 +134,11 @@ msgstr "Licence complète :"
msgid "Date & Time"
msgstr "Date & heure"
-#: ../extensions/cpsection/datetime/model.py:87
+#: ../extensions/cpsection/datetime/model.py:92
msgid "Error timezone does not exist."
msgstr "Erreur : le fuseau horaire n'existe pas."
-#: ../extensions/cpsection/datetime/view.py:68 ../data/sugar.schemas.in.h:33
+#: ../extensions/cpsection/datetime/view.py:70 ../data/sugar.schemas.in.h:52
msgid "Timezone"
msgstr "Fuseau horaire"
@@ -133,50 +146,50 @@ msgstr "Fuseau horaire"
msgid "Frame"
msgstr "Cadre"
-#: ../extensions/cpsection/frame/model.py:38
-#: ../extensions/cpsection/frame/model.py:60
+#: ../extensions/cpsection/frame/model.py:41
+#: ../extensions/cpsection/frame/model.py:66
msgid "Value must be an integer."
msgstr "La valeur doit être un entier."
-#: ../extensions/cpsection/frame/view.py:26
+#: ../extensions/cpsection/frame/view.py:27
msgid "never"
msgstr "jamais"
-#: ../extensions/cpsection/frame/view.py:27
+#: ../extensions/cpsection/frame/view.py:28
msgid "instantaneous"
msgstr "immédiat"
-#: ../extensions/cpsection/frame/view.py:28
+#: ../extensions/cpsection/frame/view.py:29
#, python-format
msgid "%s seconds"
msgstr "%s secondes"
-#: ../extensions/cpsection/frame/view.py:52
+#: ../extensions/cpsection/frame/view.py:54
msgid "Activation Delay"
msgstr "Délai d'activation"
-#: ../extensions/cpsection/frame/view.py:76
+#: ../extensions/cpsection/frame/view.py:78
msgid "Corner"
msgstr "Coin"
-#: ../extensions/cpsection/frame/view.py:111
+#: ../extensions/cpsection/frame/view.py:113
msgid "Edge"
msgstr "Bord"
#: ../extensions/cpsection/keyboard/__init__.py:21
-#: ../extensions/cpsection/keyboard/view.py:31
+#: ../extensions/cpsection/keyboard/view.py:32
msgid "Keyboard"
msgstr "Clavier"
-#: ../extensions/cpsection/keyboard/view.py:189
+#: ../extensions/cpsection/keyboard/view.py:190
msgid "Keyboard Model"
msgstr "Modèle de clavier"
-#: ../extensions/cpsection/keyboard/view.py:248
+#: ../extensions/cpsection/keyboard/view.py:250
msgid "Key(s) to change layout"
msgstr "Touche(s) de modification de la disposition"
-#: ../extensions/cpsection/keyboard/view.py:318
+#: ../extensions/cpsection/keyboard/view.py:319
msgid "Keyboard Layout(s)"
msgstr "Disposition(s) du clavier"
@@ -185,21 +198,21 @@ msgstr "Disposition(s) du clavier"
msgid "Language"
msgstr "Langue"
-#: ../extensions/cpsection/language/model.py:28
+#: ../extensions/cpsection/language/model.py:30
msgid "Could not access ~/.i18n. Create standard settings."
msgstr "Accès impossible à ~/.i18n. Création de paramètres par défaut."
-#: ../extensions/cpsection/language/model.py:124
+#: ../extensions/cpsection/language/model.py:131
#, python-format
msgid "Language for code=%s could not be determined."
msgstr "La langue associée au code = %s n'a pas pu être déterminée."
-#: ../extensions/cpsection/language/model.py:144
+#: ../extensions/cpsection/language/model.py:152
#, python-format
msgid "Sorry I do not speak '%s'."
msgstr "Désolé je ne parle pas '%s'."
-#: ../extensions/cpsection/language/view.py:56
+#: ../extensions/cpsection/language/view.py:57
msgid ""
"Add languages in the order you prefer. If a translation is not available, "
"the next in the list will be used."
@@ -211,66 +224,82 @@ msgstr ""
msgid "Modem Configuration"
msgstr "Configuration du modem"
-#: ../extensions/cpsection/modemconfiguration/view.py:90
+#: ../extensions/cpsection/modemconfiguration/view.py:94
msgid "Username:"
msgstr "Identifiant :"
-#: ../extensions/cpsection/modemconfiguration/view.py:101
+#: ../extensions/cpsection/modemconfiguration/view.py:106
msgid "Password:"
msgstr "Mot de passe :"
-#: ../extensions/cpsection/modemconfiguration/view.py:112
+#: ../extensions/cpsection/modemconfiguration/view.py:118
msgid "Number:"
msgstr "Numéro :"
-#: ../extensions/cpsection/modemconfiguration/view.py:123
-msgid "APN:"
-msgstr "APN :"
+#: ../extensions/cpsection/modemconfiguration/view.py:130
+msgid "Access Point Name (APN):"
+msgstr "Nom du Point d'Accès (APN) :"
+
+#: ../extensions/cpsection/modemconfiguration/view.py:142
+msgid "Personal Identity Number (PIN):"
+msgstr "Numéro d'Identité Personnel (PIN) :"
+
+#: ../extensions/cpsection/modemconfiguration/view.py:154
+msgid "Personal Unblocking Key (PUK):"
+msgstr "Clé de Déblocage Personnelle (PUK) :"
+
+#: ../extensions/cpsection/modemconfiguration/view.py:175
+msgid ""
+"You will need to provide the following information to set up a mobile "
+"broadband connection to a cellular (3G) network."
+msgstr ""
+"Fournir les informations ci-après pour configurer une connexion large bande "
+"à un réseau cellulaire (3G)."
#: ../extensions/cpsection/network/__init__.py:21
-#: ../extensions/cpsection/network/view.py:28
+#: ../extensions/cpsection/network/view.py:29
msgid "Network"
msgstr "Réseau"
-#: ../extensions/cpsection/network/model.py:79
+#: ../extensions/cpsection/network/model.py:71
msgid "State is unknown."
msgstr "État inconnu."
-#: ../extensions/cpsection/network/model.py:105
+#: ../extensions/cpsection/network/model.py:99
msgid "Error in specified radio argument use on/off."
msgstr "Argument 'radio' spécifié incorrect. Utiliser marche/arrêt."
-#: ../extensions/cpsection/network/model.py:137
+#: ../extensions/cpsection/network/model.py:140
msgid "Error in specified argument use 0/1."
msgstr "Argument spécifié incorrect. Utiliser 0/1."
-#: ../extensions/cpsection/network/view.py:59
+#: ../extensions/cpsection/network/view.py:61
msgid "Wireless"
msgstr "Réseau sans fil"
-#: ../extensions/cpsection/network/view.py:67
+#: ../extensions/cpsection/network/view.py:69
msgid "Turn off the wireless radio to save battery life"
msgstr "Désactiver la radio sans fil pour prolonger la batterie"
-#: ../extensions/cpsection/network/view.py:80
+#: ../extensions/cpsection/network/view.py:82
msgid "Radio"
msgstr "Radio"
-#: ../extensions/cpsection/network/view.py:96
+#: ../extensions/cpsection/network/view.py:98
msgid "Discard network history if you have trouble connecting to the network"
msgstr ""
"Ignorer l'historique du réseau si vous avez du mal à vous connecter au "
"réseau"
-#: ../extensions/cpsection/network/view.py:105
+#: ../extensions/cpsection/network/view.py:107
msgid "Discard network history"
msgstr "Ignorer l'historique du réseau"
-#: ../extensions/cpsection/network/view.py:118
+#: ../extensions/cpsection/network/view.py:122
msgid "Collaboration"
msgstr "Collaboration"
-#: ../extensions/cpsection/network/view.py:126
+#: ../extensions/cpsection/network/view.py:130
msgid ""
"The server is the equivalent of what room you are in; people on the same "
"server will be able to see each other, even when they aren't on the same "
@@ -280,7 +309,7 @@ msgstr ""
"personnes présentes sur le même serveur pourront se voir même si elles ne se "
"trouvent pas sur le même réseau."
-#: ../extensions/cpsection/network/view.py:136
+#: ../extensions/cpsection/network/view.py:140
msgid "Server:"
msgstr "Serveur :"
@@ -288,23 +317,23 @@ msgstr "Serveur :"
msgid "Power"
msgstr "Alimentation"
-#: ../extensions/cpsection/power/model.py:54
+#: ../extensions/cpsection/power/model.py:90
msgid "Error in automatic pm argument, use on/off."
msgstr "Erreur dans l'argument gestion de l'alimentation automatique."
-#: ../extensions/cpsection/power/model.py:81
+#: ../extensions/cpsection/power/model.py:120
msgid "Error in extreme pm argument, use on/off."
msgstr "Erreur dans l'argument gestion de l'alimentation extrême."
-#: ../extensions/cpsection/power/view.py:47
+#: ../extensions/cpsection/power/view.py:48
msgid "Power management"
msgstr "Gestion de l'alimentation"
-#: ../extensions/cpsection/power/view.py:57
+#: ../extensions/cpsection/power/view.py:58
msgid "Automatic power management (increases battery life)"
msgstr "Gestion automatique de l'alimentation (prolonge la batterie)"
-#: ../extensions/cpsection/power/view.py:85
+#: ../extensions/cpsection/power/view.py:86
msgid ""
"Extreme power management (disableswireless radio, increases battery life)"
msgstr ""
@@ -357,26 +386,26 @@ msgstr "Vérification des mises à jour..."
msgid "Installing updates..."
msgstr "Installation des mises à jour..."
-#: ../extensions/cpsection/updater/view.py:172
+#: ../extensions/cpsection/updater/view.py:173
#, python-format
msgid "%s update was installed"
msgid_plural "%s updates were installed"
msgstr[0] "%s mise à jour a été installée"
msgstr[1] "%s mises à jour ont été installées"
-#: ../extensions/cpsection/updater/view.py:253
+#: ../extensions/cpsection/updater/view.py:255
msgid "Install selected"
msgstr "Installer les activités sélectionnées"
-#: ../extensions/cpsection/updater/view.py:274
+#: ../extensions/cpsection/updater/view.py:276
#, python-format
msgid "Download size: %s"
msgstr "Taille du téléchargement : %s"
-#: ../extensions/cpsection/updater/view.py:362
+#: ../extensions/cpsection/updater/view.py:364
#, python-format
-msgid "From version %(current)d to %(new)s (Size: %(size)s)"
-msgstr "De la version %(current)d à %(new)s (taille : %(size)s)"
+msgid "From version %(current)s to %(new)s (Size: %(size)s)"
+msgstr "De la version %(current)s à %(new)s (taille : %(size)s)"
#. TRANS: download size is 0
#: ../extensions/cpsection/updater/view.py:382
@@ -400,28 +429,28 @@ msgstr "%.0f Ko"
msgid "%.1f MB"
msgstr "%.1f Mo"
-#: ../extensions/deviceicon/battery.py:58
+#: ../extensions/deviceicon/battery.py:60
msgid "My Battery"
msgstr "Ma batterie"
-#: ../extensions/deviceicon/battery.py:137
+#: ../extensions/deviceicon/battery.py:141
msgid "Removed"
msgstr "Retiré"
-#: ../extensions/deviceicon/battery.py:140
+#: ../extensions/deviceicon/battery.py:144
msgid "Charging"
msgstr "En charge"
-#: ../extensions/deviceicon/battery.py:143
+#: ../extensions/deviceicon/battery.py:147
msgid "Very little power remaining"
msgstr "La batterie est pratiquement déchargée"
-#: ../extensions/deviceicon/battery.py:149
+#: ../extensions/deviceicon/battery.py:153
#, python-format
msgid "%(hour)d:%(min).2d remaining"
msgstr "%(hour)d:%(min).2d restantes"
-#: ../extensions/deviceicon/battery.py:152
+#: ../extensions/deviceicon/battery.py:156
msgid "Charged"
msgstr "Charge complète"
@@ -434,118 +463,192 @@ msgstr "Adresse IP : %s"
# priority over the normal wireless device. NM doesn't have a "disconnect"
# method for a device either (for various reasons) so this doesn't
# have a good mapping
-#: ../extensions/deviceicon/network.py:111
+#: ../extensions/deviceicon/network.py:104
msgid "Disconnect..."
msgstr "Déconnexion..."
-#: ../extensions/deviceicon/network.py:116
-msgid "Create new wireless network"
-msgstr "Créer un nouveau réseau sans fil"
-
-#: ../extensions/deviceicon/network.py:122
-#: ../extensions/deviceicon/network.py:284
-#: ../src/jarabe/desktop/meshbox.py:248 ../src/jarabe/desktop/meshbox.py:537
+#: ../extensions/deviceicon/network.py:112
+#: ../extensions/deviceicon/network.py:290
+#: ../src/jarabe/desktop/networkviews.py:241
+#: ../src/jarabe/desktop/networkviews.py:546
+#: ../src/jarabe/desktop/networkviews.py:673
msgid "Connecting..."
msgstr "Connexion..."
# TODO: show the channel number
-#: ../extensions/deviceicon/network.py:126
-#: ../extensions/deviceicon/network.py:198
-#: ../extensions/deviceicon/network.py:288
-#: ../src/jarabe/desktop/meshbox.py:254 ../src/jarabe/desktop/meshbox.py:543
+#: ../extensions/deviceicon/network.py:116
+#: ../extensions/deviceicon/network.py:182
+#: ../src/jarabe/desktop/networkviews.py:251
+#: ../src/jarabe/desktop/networkviews.py:552
+#: ../src/jarabe/desktop/networkviews.py:679
msgid "Connected"
msgstr "Connecté"
-#: ../extensions/deviceicon/network.py:158
+#: ../extensions/deviceicon/network.py:142
msgid "Channel"
msgstr "Canal"
-#: ../extensions/deviceicon/network.py:173
+#: ../extensions/deviceicon/network.py:157
msgid "Wired Network"
msgstr "Réseau filaire"
-#: ../extensions/deviceicon/network.py:201
+#: ../extensions/deviceicon/network.py:185
msgid "Speed"
msgstr "Vitesse"
-#: ../extensions/deviceicon/network.py:228
+#: ../extensions/deviceicon/network.py:211
msgid "Wireless modem"
msgstr "Modem sans fil"
-#: ../extensions/deviceicon/network.py:276
+#: ../extensions/deviceicon/network.py:278
msgid "Please wait..."
msgstr "Patienter..."
-#: ../extensions/deviceicon/network.py:279
-#: ../src/jarabe/desktop/meshbox.py:164 ../src/jarabe/desktop/meshbox.py:494
+#: ../extensions/deviceicon/network.py:282
+#: ../src/jarabe/desktop/networkviews.py:134
+#: ../src/jarabe/desktop/networkviews.py:500
+#: ../src/jarabe/desktop/networkviews.py:630
msgid "Connect"
msgstr "Connecter"
-#: ../extensions/deviceicon/network.py:280
+#: ../extensions/deviceicon/network.py:283
msgid "Disconnected"
msgstr "Déconnecté"
-#: ../extensions/deviceicon/network.py:283
-#: ../src/jarabe/controlpanel/toolbar.py:115
-#: ../src/jarabe/desktop/homebox.py:68
-#: ../src/jarabe/frame/activitiestray.py:700
-#: ../src/jarabe/frame/activitiestray.py:799
-#: ../src/jarabe/frame/activitiestray.py:827
+#: ../extensions/deviceicon/network.py:289
+#: ../src/jarabe/controlpanel/toolbar.py:119
+#: ../src/jarabe/desktop/homebox.py:70
+#: ../src/jarabe/frame/activitiestray.py:587
+#: ../src/jarabe/frame/activitiestray.py:687
+#: ../src/jarabe/frame/activitiestray.py:715
msgid "Cancel"
msgstr "Annuler"
-#: ../extensions/deviceicon/network.py:287
-#: ../src/jarabe/desktop/meshbox.py:168
+#: ../extensions/deviceicon/network.py:297
+#: ../src/jarabe/desktop/networkviews.py:138
+#: ../src/jarabe/desktop/networkviews.py:504
msgid "Disconnect"
msgstr "Déconnecter"
-#: ../extensions/deviceicon/network.py:530
+#: ../extensions/deviceicon/network.py:327
+msgid "Try connection again"
+msgstr "Essayez de vous reconnecter"
+
+#: ../extensions/deviceicon/network.py:330
+#, python-format
+msgid "Error: %s"
+msgstr "Erreur : %s"
+
+#: ../extensions/deviceicon/network.py:334
#, python-format
-msgid "%s's network"
-msgstr "Réseau %s"
+msgid "Suggestion: %s"
+msgstr "Suggestion : %s"
+
+#: ../extensions/deviceicon/network.py:340
+#: ../extensions/deviceicon/network.py:343
+#, python-format
+msgid "Connected for %s"
+msgstr "Connecté depuis %s"
+
+#: ../extensions/deviceicon/network.py:348
+#: ../extensions/deviceicon/network.py:349
+#, python-format
+msgid "%d KB"
+msgstr "%d Ko"
+
+#: ../extensions/deviceicon/network.py:354
+msgid "Check your Pin/Puk configuration."
+msgstr "Vérifiez votre configuration Pin/Puk."
+
+#: ../extensions/deviceicon/network.py:357
+msgid "Check your Access Point Name (APN) configuration"
+msgstr "Vérifiez la configuration de votre nom de point d'accès (APN)."
+
+#: ../extensions/deviceicon/network.py:361
+msgid "Check the Number configuration."
+msgstr "Vérifiez la configuration du numéro."
+
+#: ../extensions/deviceicon/network.py:363
+msgid "Check your configuration."
+msgstr "Vérifiez votre configuration."
-#: ../extensions/deviceicon/network.py:597
-#: ../extensions/deviceicon/network.py:656
+#: ../extensions/deviceicon/network.py:605
msgid "Mesh Network"
msgstr "Réseau maillé"
-#: ../extensions/deviceicon/network.py:857
+#: ../extensions/deviceicon/network.py:648
#, python-format
-msgid "Data sent %d kb / received %d kb"
-msgstr "Données envoyées %d ko / reçues %d ko"
+msgid "Mesh Network %s"
+msgstr "Réseau maillé %s"
-#: ../extensions/deviceicon/network.py:868
-msgid "Connection time "
-msgstr "Durée de connexion"
+#: ../extensions/deviceicon/network.py:771
+msgid "No GSM connection available."
+msgstr "Aucune connexion GSM disponible."
-#: ../extensions/deviceicon/speaker.py:59
+#: ../extensions/deviceicon/network.py:772
+msgid "Create a connection in the control panel."
+msgstr "Créez une connexion dans le panneau de contrôle."
+
+#: ../extensions/deviceicon/resources.py:48
+msgid "System resources"
+msgstr "Ressources système"
+
+#: ../extensions/deviceicon/resources.py:170
+#, python-format
+msgid "CPU in use: %d%%"
+msgstr "Processeur utilisé : %d%%"
+
+#: ../extensions/deviceicon/resources.py:172
+#, python-format
+msgid "Memory in use: %d%%"
+msgstr "Mémoire utilisée : %d%%"
+
+#: ../extensions/deviceicon/resources.py:202
+msgid "Cannot compute CPU and memory usage statistics!"
+msgstr ""
+"Calcul des statistiques d'utilisation du processeur et de la mémoire "
+"impossible !"
+
+#: ../extensions/deviceicon/speaker.py:60
msgid "My Speakers"
msgstr "Haut-parleurs"
-#: ../extensions/deviceicon/speaker.py:133
+#: ../extensions/deviceicon/speaker.py:136
msgid "Unmute"
msgstr "Activer le son"
-#: ../extensions/deviceicon/speaker.py:136
+#: ../extensions/deviceicon/speaker.py:139
msgid "Mute"
msgstr "Mettre en sourdine"
+#: ../extensions/deviceicon/touchpad.py:37
+msgid "finger"
+msgstr "doigt"
+
+#: ../extensions/deviceicon/touchpad.py:38
+msgid "stylus"
+msgstr "stylet"
+
+#: ../extensions/deviceicon/touchpad.py:67
+msgid "My touchpad"
+msgstr "Mon pavé tactile"
+
#: ../extensions/globalkey/screenshot.py:59
msgid "Mesh"
msgstr "Réseau maillé"
#: ../extensions/globalkey/screenshot.py:61
-#: ../src/jarabe/frame/zoomtoolbar.py:39
+#: ../src/jarabe/frame/zoomtoolbar.py:40
msgid "Group"
msgstr "Groupe"
#: ../extensions/globalkey/screenshot.py:63
-#: ../src/jarabe/frame/zoomtoolbar.py:41
+#: ../src/jarabe/frame/zoomtoolbar.py:42
msgid "Home"
msgstr "Accueil"
#: ../extensions/globalkey/screenshot.py:69
-#: ../src/jarabe/frame/zoomtoolbar.py:43
+#: ../src/jarabe/frame/zoomtoolbar.py:44
msgid "Activity"
msgstr "Activité"
@@ -567,64 +670,125 @@ msgstr ""
"pour réutiliser l'identifiant long du compte UNIX."
#: ../data/sugar.schemas.in.h:2
+msgid "Additional directories which can contain updated translations."
+msgstr ""
+"Les dossiers supplémentaires peuvent comporter des traductions mises à jour."
+
+#: ../data/sugar.schemas.in.h:3
msgid "Backup URL"
msgstr "Sauvegarde de l'URL"
-#: ../data/sugar.schemas.in.h:3
+#: ../data/sugar.schemas.in.h:4
+msgid "Bundle IDs of protected activities"
+msgstr "Identifiant des bundles des activités protégées"
+
+#: ../data/sugar.schemas.in.h:5
msgid ""
"Color for the XO icon that is used throughout the desktop. The string is "
-"composed of the stroke color and fill color, format is that of rbg colors. "
+"composed of the stroke color and fill color, format is that of rgb colors. "
"Example: #AC32FF,#9A5200"
msgstr ""
-"Couleur du XO utilisée sur le Bureau. La chaîne indique la couleur du trait "
-"et du remplissage. Le format correspond aux couleurs RVB. Exemple : "
-"#AC32FF,#9A5200"
+"Couleur de l'icône du XO utilisée sur le Bureau. La chaîne indique la "
+"couleur du trait et du remplissage. Le format correspond aux couleurs RVB. "
+"Exemple : #AC32FF,#9A5200"
-#: ../data/sugar.schemas.in.h:4
+#: ../data/sugar.schemas.in.h:6
msgid "Corner Delay"
msgstr "Délai des coins"
-#: ../data/sugar.schemas.in.h:5
+#: ../data/sugar.schemas.in.h:7
msgid "Default font face"
msgstr "Police par défaut"
-#: ../data/sugar.schemas.in.h:6
+#: ../data/sugar.schemas.in.h:8
msgid "Default font size"
msgstr "Corps de la police par défaut"
-#: ../data/sugar.schemas.in.h:7
+#: ../data/sugar.schemas.in.h:9
msgid "Default nick"
msgstr "Pseudo par défaut"
-#: ../data/sugar.schemas.in.h:8
+#: ../data/sugar.schemas.in.h:10
msgid "Delay for the activation of the frame using the corners."
msgstr "Délai d'activation du cadre à l'aide des coins."
-#: ../data/sugar.schemas.in.h:9
+#: ../data/sugar.schemas.in.h:11
msgid "Delay for the activation of the frame using the edges."
msgstr "Délai d'activation du cadre à l'aide des bords."
-#: ../data/sugar.schemas.in.h:10
+#: ../data/sugar.schemas.in.h:12
+msgid "Directory to search for translations"
+msgstr "Répertoire de recherche des traductions"
+
+#: ../data/sugar.schemas.in.h:13
msgid "Edge Delay"
msgstr "Délai des bords"
-#: ../data/sugar.schemas.in.h:11
+#: ../data/sugar.schemas.in.h:14
msgid "Favorites Layout"
msgstr "Disposition favorite"
-#: ../data/sugar.schemas.in.h:12
+#: ../data/sugar.schemas.in.h:15
msgid "Favorites resume mode"
msgstr "Mode de reprise favori"
-#: ../data/sugar.schemas.in.h:13
+#: ../data/sugar.schemas.in.h:16
msgid "Font face that is used throughout the desktop."
msgstr "Police utilisée sur le bureau."
-#: ../data/sugar.schemas.in.h:14
+#: ../data/sugar.schemas.in.h:17
msgid "Font size that is used throughout the desktop."
msgstr "Corps de la police utilisée sur le bureau."
-#: ../data/sugar.schemas.in.h:15
+#: ../data/sugar.schemas.in.h:18
+msgid "GSM network APN"
+msgstr "Code APN du réseau GSM"
+
+#: ../data/sugar.schemas.in.h:19
+msgid "GSM network PIN"
+msgstr "Code PIN du réseau GSM"
+
+#: ../data/sugar.schemas.in.h:20
+msgid "GSM network PUK"
+msgstr "Code PUK du réseau GSM"
+
+#: ../data/sugar.schemas.in.h:21
+msgid "GSM network access point name configuration"
+msgstr "Configuration du nom du point d'accès au réseau GSM"
+
+#: ../data/sugar.schemas.in.h:22
+msgid "GSM network number"
+msgstr "Numéro du réseau GSM"
+
+#: ../data/sugar.schemas.in.h:23
+msgid "GSM network password"
+msgstr "Mot de passe du réseau GSM"
+
+#: ../data/sugar.schemas.in.h:24
+msgid "GSM network password configuration"
+msgstr "Configuration du mot de passe du réseau GSM"
+
+#: ../data/sugar.schemas.in.h:25
+msgid "GSM network personal identification number configuration"
+msgstr "Configuration du numéro d'identification personnel du réseau GSM"
+
+#: ../data/sugar.schemas.in.h:26
+msgid "GSM network personal unlock key configuration"
+msgstr "Configuration de la clé de déblocage personnelle du réseau GSM"
+
+#: ../data/sugar.schemas.in.h:27
+msgid "GSM network telephone number configuration"
+msgstr "Configuration du numéro de téléphone du réseau GSM"
+
+#: ../data/sugar.schemas.in.h:28
+msgid "GSM network username"
+msgstr "Nom d'utilisateur du réseau GSM"
+
+#: ../data/sugar.schemas.in.h:29
+msgid "GSM network username configuration"
+msgstr "Configuration du nom d'utilisateur du réseau GSM"
+
+#: ../data/sugar.schemas.in.h:30
msgid ""
"If TRUE, Sugar will make us searchable for the other users of the Jabber "
"server."
@@ -632,110 +796,139 @@ msgstr ""
"Si VRAI, Sugar permettra aux autres utilisateurs du serveur Jabber de nous "
"retrouver."
-#: ../data/sugar.schemas.in.h:16
+#: ../data/sugar.schemas.in.h:31
msgid "If TRUE, Sugar will show a \"Log out\" option."
msgstr "Si VRAI, Sugar affichera une option \"Déconnexion\"."
-#: ../data/sugar.schemas.in.h:17
+#: ../data/sugar.schemas.in.h:32
+msgid "If TRUE, Sugar will show a \"Restart\" option."
+msgstr "Si VRAI, Sugar affichera une option \"Redémarrer\"."
+
+#: ../data/sugar.schemas.in.h:33
+msgid ""
+"If TRUE, Sugar will show default Ad-hoc networks for channel 1,6 and 11. If "
+"Sugar sees no \"known\" network when it starts, it does autoconnect to an Ad-"
+"hoc network."
+msgstr ""
+"Si VRAI, Sugar affichera les réseaux ad-hoc des canaux 1,6 et 11. si Sugar "
+"ne voit aucun réseau \"connu\" au démarrage, il se connecte automatiquement à "
+"un réseau ad-hoc."
+
+#: ../data/sugar.schemas.in.h:34
msgid "Jabber Server"
msgstr "Serveur Jabber"
-#: ../data/sugar.schemas.in.h:18
+#: ../data/sugar.schemas.in.h:35
msgid "Keyboard layouts"
msgstr "Dispositions du clavier"
-#: ../data/sugar.schemas.in.h:19
+#: ../data/sugar.schemas.in.h:36
msgid "Keyboard model"
msgstr "Modèle de clavier"
-#: ../data/sugar.schemas.in.h:20
+#: ../data/sugar.schemas.in.h:37
msgid "Keyboard options"
msgstr "Options du clavier"
-#: ../data/sugar.schemas.in.h:21
+#: ../data/sugar.schemas.in.h:38
msgid "Layout of the favorites view."
msgstr "Disposition de la vue favorite."
-#: ../data/sugar.schemas.in.h:22
+#: ../data/sugar.schemas.in.h:39
msgid ""
"List of keyboard layouts. Each entry should be in the form layout(variant)"
msgstr ""
"Liste des dispositions de claviers. Chaque ligne doit avoir la forme "
"disposition(variante)"
-#: ../data/sugar.schemas.in.h:23
+#: ../data/sugar.schemas.in.h:40
msgid "List of keyboard options."
msgstr "Liste des options de clavier."
-#: ../data/sugar.schemas.in.h:24
+#: ../data/sugar.schemas.in.h:41
msgid "Power Automatic"
msgstr "Alimentation automatique"
-#: ../data/sugar.schemas.in.h:25
+#: ../data/sugar.schemas.in.h:42
msgid "Power Automatic."
msgstr "Alimentation automatique."
-#: ../data/sugar.schemas.in.h:26
+#: ../data/sugar.schemas.in.h:43
msgid "Power Extreme"
msgstr "Alimentation extrême"
-#: ../data/sugar.schemas.in.h:27
+#: ../data/sugar.schemas.in.h:44
msgid "Power Extreme."
msgstr "Alimentation extrême."
-#: ../data/sugar.schemas.in.h:28
+#: ../data/sugar.schemas.in.h:45
msgid "Publish to Gadget"
msgstr "Publication vers Gadget"
-#: ../data/sugar.schemas.in.h:29
+#: ../data/sugar.schemas.in.h:46
msgid "Setting for muting the sound device."
msgstr "Configuration de la mise en sourdine du périphérique audio."
-#: ../data/sugar.schemas.in.h:30
+#: ../data/sugar.schemas.in.h:47
msgid "Show Log out"
msgstr "Afficher Déconnexion"
-#: ../data/sugar.schemas.in.h:31
+#: ../data/sugar.schemas.in.h:48
+msgid "Show Restart"
+msgstr "Afficher Redémarrer"
+
+#: ../data/sugar.schemas.in.h:49
+msgid "Show Sugar Ad-hoc networks"
+msgstr "Afficher les réseaux ad-hoc Sugar"
+
+#: ../data/sugar.schemas.in.h:50
msgid "Sound Muted"
msgstr "Audio désactivé"
-#: ../data/sugar.schemas.in.h:32
+#: ../data/sugar.schemas.in.h:51
msgid "The keyboard model to be used"
msgstr "Modèle de clavier à utiliser"
-#: ../data/sugar.schemas.in.h:34
+#: ../data/sugar.schemas.in.h:53
msgid "Timezone setting for the system."
msgstr "Configuration du fuseau horaire du système."
-#: ../data/sugar.schemas.in.h:35
+#: ../data/sugar.schemas.in.h:54
msgid "Url of the jabber server to use."
msgstr "URL du serveur Jabber à utiliser."
-#: ../data/sugar.schemas.in.h:36
+#: ../data/sugar.schemas.in.h:55
msgid "Url where the backup is saved to."
msgstr "URL d'enregistrement de la sauvegarde."
-#: ../data/sugar.schemas.in.h:37
+#: ../data/sugar.schemas.in.h:56
msgid "User Color"
msgstr "Couleurs de l'utilisateur"
-#: ../data/sugar.schemas.in.h:38
+#: ../data/sugar.schemas.in.h:57
msgid "User Name"
msgstr "Nom de l'utilisateur"
-#: ../data/sugar.schemas.in.h:39
+#: ../data/sugar.schemas.in.h:58
msgid "User name that is used throughout the desktop."
msgstr "Nom identifiant l'utilisateur sur le bureau."
-#: ../data/sugar.schemas.in.h:40
+#: ../data/sugar.schemas.in.h:59
+msgid ""
+"Users will not be allowed to erase these activities through the list view."
+msgstr ""
+"Les utilisateurs ne sont pas autorisés à supprimer ces activités depuis la "
+"vue liste."
+
+#: ../data/sugar.schemas.in.h:60
msgid "Volume Level"
msgstr "Niveau de volume"
-#: ../data/sugar.schemas.in.h:41
+#: ../data/sugar.schemas.in.h:61
msgid "Volume level for the sound device."
msgstr "Niveau de volume du périphérique audio."
-#: ../data/sugar.schemas.in.h:42
+#: ../data/sugar.schemas.in.h:62
msgid ""
"When in resume mode, clicking on a favorite icon will cause the last entry "
"for that activity to be resumed."
@@ -766,7 +959,7 @@ msgstr "sugar-control-panel: %s"
# which must appear in the translated string (msgstr) as well.
#. TRANS: Translators, there's a empty line at the end of this string,
#. which must appear in the translated string (msgstr) as well.
-#: ../src/jarabe/controlpanel/cmd.py:37
+#: ../src/jarabe/controlpanel/cmd.py:38
msgid ""
"Usage: sugar-control-panel [ option ] key [ args ... ] \n"
" Control for the sugar environment. \n"
@@ -789,51 +982,53 @@ msgstr ""
" -s clé définir la valeur actuelle de cette clé \n"
" "
-#: ../src/jarabe/controlpanel/cmd.py:50
+#: ../src/jarabe/controlpanel/cmd.py:52
msgid "To apply your changes you have to restart sugar.\n"
msgstr "Redémarrer sugar pour que les changements prennent effet.\n"
-#: ../src/jarabe/controlpanel/gui.py:281
+#: ../src/jarabe/controlpanel/gui.py:297
+#: ../src/jarabe/journal/journaltoolbox.py:437
+#: ../src/jarabe/journal/volumestoolbar.py:158
msgid "Warning"
msgstr "Attention"
-#: ../src/jarabe/controlpanel/gui.py:282
-#: ../src/jarabe/controlpanel/sectionview.py:42
+#: ../src/jarabe/controlpanel/gui.py:298
+#: ../src/jarabe/controlpanel/sectionview.py:41
msgid "Changes require restart"
msgstr "Relancer pour valider"
-#: ../src/jarabe/controlpanel/gui.py:285
+#: ../src/jarabe/controlpanel/gui.py:301
msgid "Cancel changes"
msgstr "Abandonner"
-#: ../src/jarabe/controlpanel/gui.py:290 ../src/jarabe/desktop/homebox.py:70
+#: ../src/jarabe/controlpanel/gui.py:306 ../src/jarabe/desktop/homebox.py:72
msgid "Later"
msgstr "Plus tard"
-#: ../src/jarabe/controlpanel/gui.py:294
+#: ../src/jarabe/controlpanel/gui.py:310
msgid "Restart now"
msgstr "Maintenant"
-#: ../src/jarabe/controlpanel/toolbar.py:61 ../src/jarabe/intro/window.py:206
+#: ../src/jarabe/controlpanel/toolbar.py:63 ../src/jarabe/intro/window.py:212
msgid "Done"
msgstr "Accepter"
-#: ../src/jarabe/controlpanel/toolbar.py:121
-#: ../src/jarabe/desktop/favoritesview.py:333
+#: ../src/jarabe/controlpanel/toolbar.py:125
+#: ../src/jarabe/desktop/favoritesview.py:336
msgid "Ok"
msgstr "Ok"
-#: ../src/jarabe/desktop/activitieslist.py:236
+#: ../src/jarabe/desktop/activitieslist.py:230
#, python-format
msgid "Version %s"
msgstr "Version %s"
-#: ../src/jarabe/desktop/activitieslist.py:357
+#: ../src/jarabe/desktop/activitieslist.py:354
msgid "Confirm erase"
msgstr "Confirmer la suppression"
# Conformer la suppression : faut-il supprimer %s définitivement ?
-#: ../src/jarabe/desktop/activitieslist.py:359
+#: ../src/jarabe/desktop/activitieslist.py:356
#, python-format
msgid "Confirm erase: Do you want to permanently erase %s?"
msgstr "Confirmer la suppression : faut-il supprimer %s définitivement ?"
@@ -842,251 +1037,265 @@ msgstr "Confirmer la suppression : faut-il supprimer %s définitivement ?"
# TODO: Implement stopping downloads
# self._stop_item.connect('activate', self._stop_item_activate_cb)
# self.append_menu_item(self._stop_item)
-#: ../src/jarabe/desktop/activitieslist.py:363
-#: ../src/jarabe/frame/clipboardmenu.py:63
-#: ../src/jarabe/view/viewsource.py:218
+#: ../src/jarabe/desktop/activitieslist.py:360
+#: ../src/jarabe/frame/clipboardmenu.py:64
+#: ../src/jarabe/view/viewsource.py:221
msgid "Keep"
msgstr "Conserver"
-#: ../src/jarabe/desktop/activitieslist.py:366
-#: ../src/jarabe/desktop/activitieslist.py:409
-#: ../src/jarabe/journal/journaltoolbox.py:360
-#: ../src/jarabe/journal/palettes.py:105
+#: ../src/jarabe/desktop/activitieslist.py:363
+#: ../src/jarabe/desktop/activitieslist.py:417
+#: ../src/jarabe/journal/journaltoolbox.py:391
+#: ../src/jarabe/journal/palettes.py:112
msgid "Erase"
msgstr "Supprimer"
-#: ../src/jarabe/desktop/activitieslist.py:430
+#: ../src/jarabe/desktop/activitieslist.py:432
msgid "Remove favorite"
msgstr "Retirer le favori"
-#: ../src/jarabe/desktop/activitieslist.py:434
+#: ../src/jarabe/desktop/activitieslist.py:436
msgid "Make favorite"
msgstr "Ajouter aux favoris"
# TRANS: label for the freeform layout in the favorites view
#. TRANS: label for the freeform layout in the favorites view
-#: ../src/jarabe/desktop/favoriteslayout.py:116
+#: ../src/jarabe/desktop/favoriteslayout.py:127
msgid "Freeform"
msgstr "Libre"
# TRANS: label for the ring layout in the favorites view
#. TRANS: label for the ring layout in the favorites view
-#: ../src/jarabe/desktop/favoriteslayout.py:198
+#: ../src/jarabe/desktop/favoriteslayout.py:215
msgid "Ring"
msgstr "Concentrique"
# TRANS: label for the spiral layout in the favorites view
#. TRANS: label for the spiral layout in the favorites view
-#: ../src/jarabe/desktop/favoriteslayout.py:337
+#: ../src/jarabe/desktop/favoriteslayout.py:402
msgid "Spiral"
msgstr "Spirale"
# TRANS: label for the box layout in the favorites view
#. TRANS: label for the box layout in the favorites view
-#: ../src/jarabe/desktop/favoriteslayout.py:404
+#: ../src/jarabe/desktop/favoriteslayout.py:472
msgid "Box"
msgstr "Boîte"
# TRANS: label for the box layout in the favorites view
#. TRANS: label for the box layout in the favorites view
-#: ../src/jarabe/desktop/favoriteslayout.py:445
+#: ../src/jarabe/desktop/favoriteslayout.py:515
msgid "Triangle"
msgstr "Triangle"
-#: ../src/jarabe/desktop/favoritesview.py:324
+#: ../src/jarabe/desktop/favoritesview.py:327
msgid "Registration Failed"
msgstr "Echec de l'enregistrement"
-#: ../src/jarabe/desktop/favoritesview.py:325
+#: ../src/jarabe/desktop/favoritesview.py:328
#, python-format
msgid "%s"
msgstr "%s"
-#: ../src/jarabe/desktop/favoritesview.py:327
+#: ../src/jarabe/desktop/favoritesview.py:330
msgid "Registration Successful"
msgstr "Enregistrement réussi"
-#: ../src/jarabe/desktop/favoritesview.py:328
+#: ../src/jarabe/desktop/favoritesview.py:331
msgid "You are now registered with your school server."
msgstr "Vous êtes maintenant enregistré sur le serveur de l'école."
-#: ../src/jarabe/desktop/favoritesview.py:630
+#: ../src/jarabe/desktop/favoritesview.py:627
msgid "Register"
msgstr "S'enregistrer"
-#: ../src/jarabe/desktop/homebox.py:63
+#: ../src/jarabe/desktop/favoritesview.py:629
+#: ../src/jarabe/desktop/favoritesview.py:646
+msgid "Register again"
+msgstr "S'enregistrer à nouveau"
+
+#: ../src/jarabe/desktop/homebox.py:65
msgid "Software Update"
msgstr "Mise à jour logicielle"
-#: ../src/jarabe/desktop/homebox.py:64
+#: ../src/jarabe/desktop/homebox.py:66
msgid "Update your activities to ensure compatibility with your new software"
msgstr "Actualiser les activités pour assurer la compatibilité logicielle"
-#: ../src/jarabe/desktop/homebox.py:73
+#: ../src/jarabe/desktop/homebox.py:75
msgid "Check now"
msgstr "Vérifier maintenant"
-#: ../src/jarabe/desktop/homebox.py:192
+#: ../src/jarabe/desktop/homebox.py:193
msgid "List view"
msgstr "Écran liste"
-#: ../src/jarabe/desktop/homebox.py:193
+#: ../src/jarabe/desktop/homebox.py:194
msgid "<Ctrl>2"
msgstr "<Ctrl>2"
-#: ../src/jarabe/desktop/homebox.py:255
+#: ../src/jarabe/desktop/homebox.py:257
msgid "Favorites view"
msgstr "Écran favoris"
-#: ../src/jarabe/desktop/homebox.py:256
+#: ../src/jarabe/desktop/homebox.py:258
msgid "<Ctrl>1"
msgstr "<Ctrl>1"
-#: ../src/jarabe/desktop/keydialog.py:135
+#: ../src/jarabe/desktop/keydialog.py:143
msgid "Key Type:"
msgstr "Type de clé :"
-#: ../src/jarabe/desktop/keydialog.py:155
+#: ../src/jarabe/desktop/keydialog.py:163
msgid "Authentication Type:"
msgstr "Type d'authentification :"
-#: ../src/jarabe/desktop/keydialog.py:220
+#: ../src/jarabe/desktop/keydialog.py:229
msgid "WPA & WPA2 Personal"
msgstr "WPA & WPA2 Personal"
-#: ../src/jarabe/desktop/keydialog.py:229
+#: ../src/jarabe/desktop/keydialog.py:238
msgid "Wireless Security:"
msgstr "Sécurité sans fil :"
-#: ../src/jarabe/desktop/meshbox.py:492
-#, python-format
-msgid "Mesh Network %d"
-msgstr "Réseau maillé %d"
-
# TRANS: Action label for resuming an activity.
#. TRANS: Action label for resuming an activity.
-#: ../src/jarabe/desktop/meshbox.py:629
-#: ../src/jarabe/frame/activitiestray.py:735
-#: ../src/jarabe/journal/journaltoolbox.py:428
-#: ../src/jarabe/journal/palettes.py:65 ../src/jarabe/view/palettes.py:67
+#: ../src/jarabe/desktop/meshbox.py:109
+#: ../src/jarabe/frame/activitiestray.py:622
+#: ../src/jarabe/journal/journaltoolbox.py:485
+#: ../src/jarabe/journal/palettes.py:66 ../src/jarabe/view/palettes.py:78
msgid "Resume"
msgstr "Reprendre"
-#: ../src/jarabe/desktop/meshbox.py:634
-#: ../src/jarabe/frame/activitiestray.py:233
+#: ../src/jarabe/desktop/meshbox.py:114
+#: ../src/jarabe/frame/activitiestray.py:173
msgid "Join"
msgstr "Rejoindre"
-#: ../src/jarabe/desktop/schoolserver.py:103
+#: ../src/jarabe/desktop/networkviews.py:497
+#, python-format
+msgid "Ad-hoc Network %d"
+msgstr "Réseau ad-hoc %d"
+
+#: ../src/jarabe/desktop/networkviews.py:628
+#, python-format
+msgid "Mesh Network %d"
+msgstr "Réseau maillé %d"
+
+#: ../src/jarabe/desktop/schoolserver.py:131
msgid "Cannot connect to the server."
msgstr "Impossible de se connecter au serveur."
-#: ../src/jarabe/desktop/schoolserver.py:108
+#: ../src/jarabe/desktop/schoolserver.py:136
msgid "The server could not complete the request."
msgstr "Le serveur n'a pas pu achever la requête."
-#: ../src/jarabe/frame/activitiestray.py:238
-#: ../src/jarabe/frame/activitiestray.py:672
+#: ../src/jarabe/frame/activitiestray.py:178
+#: ../src/jarabe/frame/activitiestray.py:559
msgid "Decline"
msgstr "Refuser"
-#: ../src/jarabe/frame/activitiestray.py:624
+#: ../src/jarabe/frame/activitiestray.py:509
#, python-format
msgid "%dB"
msgstr "%do"
-#: ../src/jarabe/frame/activitiestray.py:626
+#: ../src/jarabe/frame/activitiestray.py:511
#, python-format
msgid "%dKB"
msgstr "%dKo"
-#: ../src/jarabe/frame/activitiestray.py:628
+#: ../src/jarabe/frame/activitiestray.py:513
#, python-format
msgid "%dMB"
msgstr "%dMo"
-#: ../src/jarabe/frame/activitiestray.py:645
+#: ../src/jarabe/frame/activitiestray.py:530
#, python-format
msgid "%s of %s"
msgstr "%s sur %s"
-#: ../src/jarabe/frame/activitiestray.py:657
+#: ../src/jarabe/frame/activitiestray.py:544
#, python-format
msgid "Transfer from %r"
msgstr "Transfert depuis %r"
-#: ../src/jarabe/frame/activitiestray.py:667
+#: ../src/jarabe/frame/activitiestray.py:554
msgid "Accept"
msgstr "Accepter"
-#: ../src/jarabe/frame/activitiestray.py:690
-#: ../src/jarabe/frame/activitiestray.py:817
+#: ../src/jarabe/frame/activitiestray.py:577
+#: ../src/jarabe/frame/activitiestray.py:705
#, python-format
msgid "%s (%s)"
msgstr "%s (%s)"
-#: ../src/jarabe/frame/activitiestray.py:724
-#: ../src/jarabe/frame/activitiestray.py:852
+#: ../src/jarabe/frame/activitiestray.py:611
+#: ../src/jarabe/frame/activitiestray.py:740
msgid "Dismiss"
msgstr "Refuser"
-#: ../src/jarabe/frame/activitiestray.py:787
+#: ../src/jarabe/frame/activitiestray.py:675
#, python-format
msgid "Transfer to %r"
msgstr "Transfert vers %r"
-#: ../src/jarabe/frame/clipboardmenu.py:53 ../src/jarabe/view/palettes.py:221
+#: ../src/jarabe/frame/clipboardmenu.py:54 ../src/jarabe/view/palettes.py:220
msgid "Remove"
msgstr "Retirer"
-#: ../src/jarabe/frame/clipboardmenu.py:58
-#: ../src/jarabe/frame/clipboardmenu.py:81
+#: ../src/jarabe/frame/clipboardmenu.py:59
+#: ../src/jarabe/frame/clipboardmenu.py:82
msgid "Open"
msgstr "Ouvrir"
-#: ../src/jarabe/frame/clipboardmenu.py:86
+#: ../src/jarabe/frame/clipboardmenu.py:87
msgid "Open with"
msgstr "Ouvrir avec"
-#: ../src/jarabe/frame/clipboardobject.py:49
+#: ../src/jarabe/frame/clipboardobject.py:50
#, python-format
msgid "%s clipping"
msgstr "%s coupure"
-#: ../src/jarabe/frame/zoomtoolbar.py:37
+#: ../src/jarabe/frame/zoomtoolbar.py:38
msgid "Neighborhood"
msgstr "Voisinage"
-#: ../src/jarabe/frame/zoomtoolbar.py:37
+#: ../src/jarabe/frame/zoomtoolbar.py:38
msgid "F1"
msgstr "F1"
-#: ../src/jarabe/frame/zoomtoolbar.py:39
+#: ../src/jarabe/frame/zoomtoolbar.py:40
msgid "F2"
msgstr "F2"
-#: ../src/jarabe/frame/zoomtoolbar.py:41
+#: ../src/jarabe/frame/zoomtoolbar.py:42
msgid "F3"
msgstr "F3"
-#: ../src/jarabe/frame/zoomtoolbar.py:43
+#: ../src/jarabe/frame/zoomtoolbar.py:44
msgid "F4"
msgstr "F4"
-#: ../src/jarabe/intro/window.py:128
+#: ../src/jarabe/intro/window.py:97
+msgid "Name:"
+msgstr "Nom :"
+
+#: ../src/jarabe/intro/window.py:133
msgid "Click to change color:"
msgstr "Cliquer pour changer de couleur :"
-#: ../src/jarabe/intro/window.py:192 ../src/jarabe/journal/detailview.py:103
+#: ../src/jarabe/intro/window.py:198 ../src/jarabe/journal/detailview.py:105
msgid "Back"
msgstr "Précédent"
-#: ../src/jarabe/intro/window.py:209
+#: ../src/jarabe/intro/window.py:215
msgid "Next"
msgstr "Suivant"
-#: ../src/jarabe/journal/expandedentry.py:152
-#: ../src/jarabe/journal/palettes.py:59
+#: ../src/jarabe/journal/expandedentry.py:154
+#: ../src/jarabe/journal/listmodel.py:144 ../src/jarabe/journal/palettes.py:59
msgid "Untitled"
msgstr "Sans titre"
@@ -1100,6 +1309,9 @@ msgid "Kind: %s"
msgstr "Variante : %s"
#: ../src/jarabe/journal/expandedentry.py:262
+#: ../src/jarabe/journal/listmodel.py:150
+#: ../src/jarabe/journal/listmodel.py:158
+#: ../src/jarabe/journal/listmodel.py:166
msgid "Unknown"
msgstr "Inconnu"
@@ -1113,114 +1325,158 @@ msgstr "Date : %s"
msgid "Size: %s"
msgstr "Taille : %s"
-#: ../src/jarabe/journal/expandedentry.py:286 ../src/jarabe/journal/misc.py:93
+#: ../src/jarabe/journal/expandedentry.py:292
+#: ../src/jarabe/journal/misc.py:108
msgid "No date"
msgstr "Sans date"
-#: ../src/jarabe/journal/expandedentry.py:293
+#: ../src/jarabe/journal/expandedentry.py:299
msgid "Participants:"
msgstr "Participants :"
-#: ../src/jarabe/journal/expandedentry.py:316
+#: ../src/jarabe/journal/expandedentry.py:321
msgid "Description:"
msgstr "Description :"
-#: ../src/jarabe/journal/expandedentry.py:341
+#: ../src/jarabe/journal/expandedentry.py:346
msgid "Tags:"
msgstr "Étiquettes :"
-#: ../src/jarabe/journal/journalactivity.py:108
-#: ../src/jarabe/journal/volumestoolbar.py:47
+#: ../src/jarabe/journal/journalactivity.py:115
+#: ../src/jarabe/journal/journaltoolbox.py:456
+#: ../src/jarabe/journal/volumestoolbar.py:50
msgid "Journal"
msgstr "Journal"
-#: ../src/jarabe/journal/journaltoolbox.py:67
+#: ../src/jarabe/journal/journaltoolbox.py:69
msgid "Search"
msgstr "Rechercher"
-#: ../src/jarabe/journal/journaltoolbox.py:126
+#: ../src/jarabe/journal/journaltoolbox.py:136
msgid "Anytime"
msgstr "N'importe quand"
-#: ../src/jarabe/journal/journaltoolbox.py:128
+#: ../src/jarabe/journal/journaltoolbox.py:138
msgid "Today"
msgstr "Aujourd'hui"
-#: ../src/jarabe/journal/journaltoolbox.py:130
+#: ../src/jarabe/journal/journaltoolbox.py:140
msgid "Since yesterday"
msgstr "Depuis hier"
# TRANS: Filter entries modified during the last 7 days.
#. TRANS: Filter entries modified during the last 7 days.
-#: ../src/jarabe/journal/journaltoolbox.py:132
+#: ../src/jarabe/journal/journaltoolbox.py:142
msgid "Past week"
msgstr "Depuis une semaine"
# TRANS: Filter entries modified during the last 30 days.
#. TRANS: Filter entries modified during the last 30 days.
-#: ../src/jarabe/journal/journaltoolbox.py:134
+#: ../src/jarabe/journal/journaltoolbox.py:144
msgid "Past month"
msgstr "Depuis un mois"
# TRANS: Filter entries modified during the last 356 days.
#. TRANS: Filter entries modified during the last 356 days.
-#: ../src/jarabe/journal/journaltoolbox.py:136
+#: ../src/jarabe/journal/journaltoolbox.py:146
msgid "Past year"
msgstr "Depuis une année"
-#: ../src/jarabe/journal/journaltoolbox.py:143
+#: ../src/jarabe/journal/journaltoolbox.py:153
msgid "Anyone"
msgstr "Tout le monde"
-#: ../src/jarabe/journal/journaltoolbox.py:145
+#: ../src/jarabe/journal/journaltoolbox.py:155
msgid "My friends"
msgstr "Mes amis"
-#: ../src/jarabe/journal/journaltoolbox.py:146
+#: ../src/jarabe/journal/journaltoolbox.py:156
msgid "My class"
msgstr "Ma classe"
# TRANS: Item in a combo box that filters by entry type.
-#: ../src/jarabe/journal/journaltoolbox.py:274
+#: ../src/jarabe/journal/journaltoolbox.py:298
msgid "Anything"
msgstr "Tout"
# TODO: Add "Start with" menu item
-#: ../src/jarabe/journal/journaltoolbox.py:350
-#: ../src/jarabe/journal/palettes.py:83
+#: ../src/jarabe/journal/journaltoolbox.py:381
+#: ../src/jarabe/journal/palettes.py:90
msgid "Copy"
msgstr "Copier"
+#: ../src/jarabe/journal/journaltoolbox.py:436
+#: ../src/jarabe/journal/volumestoolbar.py:157
+msgid "Entries without a file cannot be copied."
+msgstr "Impossible de copier les entrées sans fichier."
+
+#: ../src/jarabe/journal/journaltoolbox.py:445
+#: ../src/jarabe/journal/volumestoolbar.py:166
+#, python-format
+msgid "Error while copying the entry. %s"
+msgstr "Erreur lors de la copie de l'entrée. %s"
+
+#: ../src/jarabe/journal/journaltoolbox.py:446
+#: ../src/jarabe/journal/volumestoolbar.py:167
+msgid "Error"
+msgstr "Erreur"
+
# TRANS: Action label for starting an entry.
#. TRANS: Action label for starting an entry.
-#: ../src/jarabe/journal/journaltoolbox.py:431
-#: ../src/jarabe/journal/palettes.py:68
+#: ../src/jarabe/journal/journaltoolbox.py:488
+#: ../src/jarabe/journal/palettes.py:69
msgid "Start"
msgstr "Lancer"
-#: ../src/jarabe/journal/listview.py:373
+#: ../src/jarabe/journal/journaltoolbox.py:516
+msgid "Sort by date modified"
+msgstr "Trier sur la date de modification"
+
+#: ../src/jarabe/journal/journaltoolbox.py:517
+msgid "Sort by date created"
+msgstr "Trier sur la date de création"
+
+#: ../src/jarabe/journal/journaltoolbox.py:518
+msgid "Sort by size"
+msgstr "Trier sur la taille"
+
+#: ../src/jarabe/journal/journaltoolbox.py:527
+msgid "Sort view"
+msgstr "Trier l'affichage"
+
+#: ../src/jarabe/journal/listview.py:380
msgid "Your Journal is empty"
msgstr "Le journal est vide"
-#: ../src/jarabe/journal/listview.py:375
+#: ../src/jarabe/journal/listview.py:382
msgid "No matching entries"
msgstr "Aucune entrée correspondante"
-#: ../src/jarabe/journal/listview.py:386
+#: ../src/jarabe/journal/listview.py:393
msgid "Clear search"
msgstr "Effacer la recherche"
-#: ../src/jarabe/journal/modalalert.py:63
+#: ../src/jarabe/journal/misc.py:273
+#, python-format
+msgid "Older Version Of %s Activity"
+msgstr "Ancienne version de l'activité %s"
+
+#: ../src/jarabe/journal/misc.py:274
+#, python-format
+msgid "Do you want to downgrade to version %s"
+msgstr "Voulez-vous revenir à la version %s"
+
+#: ../src/jarabe/journal/modalalert.py:64
msgid "Your Journal is full"
msgstr "Votre journal est plein"
-#: ../src/jarabe/journal/modalalert.py:67
+#: ../src/jarabe/journal/modalalert.py:68
msgid "Please delete some old Journal entries to make space for new ones."
msgstr ""
"Effacer des entrées anciennes du Journal pour libérer de la place pour les "
"nouvelles entrées."
-#: ../src/jarabe/journal/modalalert.py:79
+#: ../src/jarabe/journal/modalalert.py:80
msgid "Show Journal"
msgstr "Montre le Journal"
@@ -1229,110 +1485,315 @@ msgid "Choose an object"
msgstr "Choisir un objet"
#: ../src/jarabe/journal/objectchooser.py:151
-#: ../src/jarabe/view/viewsource.py:308
+#: ../src/jarabe/view/viewsource.py:311
msgid "Close"
msgstr "Fermer"
-#: ../src/jarabe/journal/palettes.py:66
+#: ../src/jarabe/journal/palettes.py:67
msgid "Resume with"
msgstr "Reprendre avec"
-#: ../src/jarabe/journal/palettes.py:69
+#: ../src/jarabe/journal/palettes.py:70
msgid "Start with"
msgstr "Commencer avec"
-#: ../src/jarabe/journal/palettes.py:91
+#: ../src/jarabe/journal/palettes.py:83 ../src/jarabe/journal/palettes.py:216
+msgid "No activity to start entry"
+msgstr "Acune activité pour démarrer l'entrée"
+
+#: ../src/jarabe/journal/palettes.py:98
msgid "Send to"
msgstr "Envoyer à"
-#: ../src/jarabe/journal/palettes.py:100
+#: ../src/jarabe/journal/palettes.py:107
msgid "View Details"
msgstr "Afficher les détails"
-#: ../src/jarabe/journal/palettes.py:178
+#: ../src/jarabe/journal/palettes.py:181
msgid "No friends present"
msgstr "Aucun ami présent"
-#: ../src/jarabe/journal/palettes.py:183
+#: ../src/jarabe/journal/palettes.py:186
msgid "No valid connection found"
msgstr "Aucune connexion valide trouvée"
-#: ../src/jarabe/journal/palettes.py:211
+#: ../src/jarabe/journal/palettes.py:214
msgid "No activity to resume entry"
msgstr "Aucune activité pour reprendre l'entrée"
-#: ../src/jarabe/journal/palettes.py:213
-msgid "No activity to start entry"
-msgstr "Acune activité pour démarrer l'entrée"
+#: ../src/jarabe/model/network.py:163
+msgid "The reason for the device state change is unknown."
+msgstr "La raison du changement d'état du périphérique est inconnue."
+
+#: ../src/jarabe/model/network.py:165
+msgid "The state change is normal."
+msgstr "Le changement d'état est normal."
+
+#: ../src/jarabe/model/network.py:167
+msgid "The device is now managed."
+msgstr "Le périphérique est géré."
+
+#: ../src/jarabe/model/network.py:169
+msgid "The device is no longer managed."
+msgstr "Le périphérique n'est plus géré."
+
+#: ../src/jarabe/model/network.py:171
+msgid "The device could not be readied for configuration."
+msgstr "Le périphérique n'est pas disponible pour être configuré."
+
+#: ../src/jarabe/model/network.py:173
+msgid ""
+"IP configuration could not be reserved (no available address, timeout, etc)."
+msgstr ""
+"Impossible de réserver la configuration IP (adresse indisponible, "
+"dépassement de délai, etc.)."
+
+#: ../src/jarabe/model/network.py:176
+msgid "The IP configuration is no longer valid."
+msgstr "La configuration IP n'est plus valide."
+
+#: ../src/jarabe/model/network.py:178
+msgid "Secrets were required, but not provided."
+msgstr "Secrets requis mais non fournis."
+
+#: ../src/jarabe/model/network.py:180
+msgid ""
+"The 802.1X supplicant disconnected from the access point or authentication "
+"server."
+msgstr ""
+"Déconnexion du supplicant 802.1X du point d'accès ou du serveur "
+"d'authentification."
+
+#: ../src/jarabe/model/network.py:183
+msgid "Configuration of the 802.1X supplicant failed."
+msgstr "Echec de la configuration du supplicant 802.1X."
+
+#: ../src/jarabe/model/network.py:185
+msgid "The 802.1X supplicant quit or failed unexpectedly."
+msgstr "Arrêt ou échec inattendu du supplicant 802.1X."
+
+#: ../src/jarabe/model/network.py:187
+msgid "The 802.1X supplicant took too long to authenticate."
+msgstr "Délai d'authentification trop long du supplicant 802.1X."
+
+#: ../src/jarabe/model/network.py:189
+msgid "The PPP service failed to start within the allowed time."
+msgstr "Echec du démarrage du service PPP dans le délai autorisé."
+
+#: ../src/jarabe/model/network.py:191
+msgid "The PPP service disconnected unexpectedly."
+msgstr "Déconnexion inattendue du service PPP."
+
+#: ../src/jarabe/model/network.py:193
+msgid "The PPP service quit or failed unexpectedly."
+msgstr "Arrêt ou échec inattendu du service PPP."
+
+#: ../src/jarabe/model/network.py:195
+msgid "The DHCP service failed to start within the allowed time."
+msgstr "Echec du démarrage du service DHCP dans le délai autorisé."
+
+#: ../src/jarabe/model/network.py:197
+msgid "The DHCP service reported an unexpected error."
+msgstr "Le service DHCP a signalé une erreur inattendue."
+
+#: ../src/jarabe/model/network.py:199
+msgid "The DHCP service quit or failed unexpectedly."
+msgstr "Arrêt ou échec inattendu du service DHCP."
+
+#: ../src/jarabe/model/network.py:201
+msgid "The shared connection service failed to start."
+msgstr "Echec du démarrage du service de connexion partagée."
+
+#: ../src/jarabe/model/network.py:203
+msgid "The shared connection service quit or failed unexpectedly."
+msgstr "Arrêt ou échec inattendu du service de connexion partagée."
+
+#: ../src/jarabe/model/network.py:206
+msgid "The AutoIP service failed to start."
+msgstr "Echec du démarrage du service AutoIP."
+
+#: ../src/jarabe/model/network.py:208
+msgid "The AutoIP service reported an unexpected error."
+msgstr "Le service AutoIP a signalé une erreur inattendue."
+
+#: ../src/jarabe/model/network.py:210
+msgid "The AutoIP service quit or failed unexpectedly."
+msgstr "Arrêt ou échec inattendu du service AutoIP."
+
+#: ../src/jarabe/model/network.py:212
+msgid "Dialing failed because the line was busy."
+msgstr "Echec de la numérotation car la ligne était occupée."
+
+#: ../src/jarabe/model/network.py:214
+msgid "Dialing failed because there was no dial tone."
+msgstr "Echec de la numérotation en l'absence de tonalité."
-#: ../src/jarabe/view/buddymenu.py:62
+#: ../src/jarabe/model/network.py:216
+msgid "Dialing failed because there was no carrier."
+msgstr "Echec de la numérotation résultant de l'absence de porteuse."
+
+#: ../src/jarabe/model/network.py:218
+msgid "Dialing timed out."
+msgstr "Délai de la numérotation dépassé."
+
+#: ../src/jarabe/model/network.py:220
+msgid "Dialing failed."
+msgstr "Echec de la numérotation."
+
+#: ../src/jarabe/model/network.py:222
+msgid "Modem initialization failed."
+msgstr "Echec de l'initialisation du modem."
+
+#: ../src/jarabe/model/network.py:224
+msgid "Failed to select the specified GSM APN"
+msgstr "Echec de la sélection de l'APN du GSM spécifié."
+
+#: ../src/jarabe/model/network.py:226
+msgid "Not searching for networks."
+msgstr "Pas de recherche de réseaux."
+
+#: ../src/jarabe/model/network.py:228
+msgid "Network registration was denied."
+msgstr "Enregistrement du réseau refusé."
+
+#: ../src/jarabe/model/network.py:230
+msgid "Network registration timed out."
+msgstr "Enregistrement du réseau expiré."
+
+#: ../src/jarabe/model/network.py:232
+msgid "Failed to register with the requested GSM network."
+msgstr "Echec de l'enregistrement avec le réseau GSM demandé."
+
+#: ../src/jarabe/model/network.py:234
+msgid "PIN check failed."
+msgstr "Echec de la vérification du code PIN."
+
+#: ../src/jarabe/model/network.py:236
+msgid "Necessary firmware for the device may be missing."
+msgstr "Le firmware requis pour le périphérique est peut-être absent."
+
+#: ../src/jarabe/model/network.py:238
+msgid "The device was removed."
+msgstr "Le périphérique a été retiré."
+
+#: ../src/jarabe/model/network.py:240
+msgid "NetworkManager went to sleep."
+msgstr "NetworkManager est en veille."
+
+#: ../src/jarabe/model/network.py:242
+msgid "The device's active connection was removed or disappeared."
+msgstr "La connexion active du périphérique a été supprimée ou a disparu."
+
+#: ../src/jarabe/model/network.py:245
+msgid "A user or client requested the disconnection."
+msgstr "Un utilisateur ou un client a demandé la déconnexion."
+
+#: ../src/jarabe/model/network.py:247
+msgid "The device's carrier/link changed."
+msgstr "La porteuse/le lien du périphérique a changé."
+
+#: ../src/jarabe/view/buddymenu.py:63
msgid "Remove friend"
msgstr "Retirer de mes amis"
-#: ../src/jarabe/view/buddymenu.py:65
+#: ../src/jarabe/view/buddymenu.py:66
msgid "Make friend"
msgstr "Ajouter à mes amis"
-#: ../src/jarabe/view/buddymenu.py:82
+#: ../src/jarabe/view/buddymenu.py:83
msgid "Shutdown"
msgstr "Éteindre"
-#: ../src/jarabe/view/buddymenu.py:90
+#: ../src/jarabe/view/buddymenu.py:91
+msgid "Restart"
+msgstr "Redémarrer"
+
+#: ../src/jarabe/view/buddymenu.py:97
msgid "Logout"
msgstr "Se déconnecter"
-#: ../src/jarabe/view/buddymenu.py:95
+#: ../src/jarabe/view/buddymenu.py:102
msgid "My Settings"
msgstr "Mes paramètres"
-#: ../src/jarabe/view/buddymenu.py:130
+#: ../src/jarabe/view/buddymenu.py:137
#, python-format
msgid "Invite to %s"
msgstr "Inviter à %s"
-#: ../src/jarabe/view/palettes.py:45
+#: ../src/jarabe/view/launcher.py:190
+#, python-format
+msgid "<b>%s</b> failed to start."
+msgstr "<b>%s</b> n'a pas pu être démarré."
+
+#: ../src/jarabe/view/palettes.py:46
msgid "Starting..."
msgstr "Démarrage..."
+#: ../src/jarabe/view/palettes.py:56
+msgid "Activity failed to start"
+msgstr "Echec du démarrage de l'activité"
+
#. TODO: share-with, keep
-#: ../src/jarabe/view/palettes.py:74
+#: ../src/jarabe/view/palettes.py:85
msgid "View Source"
msgstr "Afficher la source"
-#: ../src/jarabe/view/palettes.py:85
+#: ../src/jarabe/view/palettes.py:96
msgid "Stop"
msgstr "Arrêter"
-#: ../src/jarabe/view/palettes.py:125
+#: ../src/jarabe/view/palettes.py:132
msgid "Start new"
msgstr "Commencer un nouveau"
-#: ../src/jarabe/view/palettes.py:174
+#: ../src/jarabe/view/palettes.py:172
msgid "Show contents"
msgstr "Afficher les contenus"
-#: ../src/jarabe/view/palettes.py:196 ../src/jarabe/view/palettes.py:246
+#: ../src/jarabe/view/palettes.py:194 ../src/jarabe/view/palettes.py:245
#, python-format
msgid "%(free_space)d MB Free"
msgstr "%(free_space)d Mo de libre"
-#: ../src/jarabe/view/viewsource.py:208
+#: ../src/jarabe/view/viewsource.py:211
msgid "Instance Source"
msgstr "Instancie source"
-#: ../src/jarabe/view/viewsource.py:233
+#: ../src/jarabe/view/viewsource.py:236
msgid "Source"
msgstr "Source"
-#: ../src/jarabe/view/viewsource.py:292
+#: ../src/jarabe/view/viewsource.py:295
msgid "Activity Bundle Source"
msgstr "Source du paquet activité"
-#: ../src/jarabe/view/viewsource.py:299
+#: ../src/jarabe/view/viewsource.py:302
#, python-format
msgid "View source: %r"
msgstr "Afficher le code source : %r"
+#: ../src/jarabe/util/emulator.py:40
+msgid "Sugar in a window"
+msgstr "Sugar dans une fenêtre"
+
+#~ msgid "APN:"
+#~ msgstr "APN :"
+
+#~ msgid "Create new wireless network"
+#~ msgstr "Créer un nouveau réseau sans fil"
+
+#, python-format
+#~ msgid "%s's network"
+#~ msgstr "Réseau %s"
+
+#, python-format
+#~ msgid "Data sent %d kb / received %d kb"
+#~ msgstr "Données envoyées %d ko / reçues %d ko"
+
+#~ msgid "Connection time "
+#~ msgstr "Durée de connexion"
+
#~ msgid "Title"
#~ msgstr "Titre"
@@ -1348,9 +1809,6 @@ msgstr "Afficher le code source : %r"
#~ msgid "Unmount"
#~ msgstr "Démonter"
-#~ msgid "Restart"
-#~ msgstr "Redémarrer"
-
#~ msgid ""
#~ "© 2008 One Laptop per Child Association Inc; Red Hat Inc; and Contributors."
#~ msgstr ""
diff --git a/po/it.po b/po/it.po
index d9a8548..a660a05 100644
--- a/po/it.po
+++ b/po/it.po
@@ -2,12 +2,20 @@
# 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.
+# SOME DESCRIPTIVE TITLE.
+# 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.
+# SOME DESCRIPTIVE TITLE.
+# 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.
msgid ""
msgstr ""
"Project-Id-Version: PACKAGE VERSION\n"
"Report-Msgid-Bugs-To: \n"
-"POT-Creation-Date: 2010-02-11 00:32-0500\n"
-"PO-Revision-Date: 2010-03-17 17:21+0200\n"
+"POT-Creation-Date: 2010-12-23 01:15-0500\n"
+"PO-Revision-Date: 2011-02-09 17:49+0200\n"
"Last-Translator: Carlo Falciola <cfalciola@yahoo.it>\n"
"Language-Team: LANGUAGE <LL@li.org>\n"
"Language: it\n"
@@ -21,43 +29,39 @@ msgstr ""
msgid "About Me"
msgstr "Informazioni su"
-#: ../extensions/cpsection/aboutme/model.py:43
+#: ../extensions/cpsection/aboutme/model.py:48
msgid "You must enter a name."
msgstr "Devi inserire un nome."
-#: ../extensions/cpsection/aboutme/model.py:68
+#: ../extensions/cpsection/aboutme/model.py:75
#, python-format
msgid "stroke: color=%s hue=%s"
msgstr "linea: colore=%s tinta=%s"
-#: ../extensions/cpsection/aboutme/model.py:71
+#: ../extensions/cpsection/aboutme/model.py:78
#, python-format
msgid "stroke: %s"
msgstr "linea: %s"
-#: ../extensions/cpsection/aboutme/model.py:73
+#: ../extensions/cpsection/aboutme/model.py:80
#, python-format
msgid "fill: color=%s hue=%s"
msgstr "riempimento: colore=%s tinta=%s"
-#: ../extensions/cpsection/aboutme/model.py:75
+#: ../extensions/cpsection/aboutme/model.py:82
#, python-format
msgid "fill: %s"
msgstr "riempimento: %s"
-#: ../extensions/cpsection/aboutme/model.py:86
+#: ../extensions/cpsection/aboutme/model.py:94
msgid "Error in specified color modifiers."
-msgstr "Errore nella variazione dei colori richiesta"
+msgstr "Errore nella variazione dei colori richiesta."
-#: ../extensions/cpsection/aboutme/model.py:89
+#: ../extensions/cpsection/aboutme/model.py:97
msgid "Error in specified colors."
msgstr "Errore nella definizione dei colori."
-#: ../extensions/cpsection/aboutme/view.py:94 ../src/jarabe/intro/window.py:93
-msgid "Name:"
-msgstr "Nome:"
-
-#: ../extensions/cpsection/aboutme/view.py:128
+#: ../extensions/cpsection/aboutme/view.py:235
msgid "Click to change your color:"
msgstr "Seleziona per cambiare il tuo colore:"
@@ -65,43 +69,43 @@ msgstr "Seleziona per cambiare il tuo colore:"
msgid "About my Computer"
msgstr "Il mio Computer"
-#: ../extensions/cpsection/aboutcomputer/model.py:28
+#: ../extensions/cpsection/aboutcomputer/model.py:29
msgid "Not available"
msgstr "Non disponibile"
-#: ../extensions/cpsection/aboutcomputer/view.py:60
+#: ../extensions/cpsection/aboutcomputer/view.py:61
msgid "Identity"
msgstr "Identità"
-#: ../extensions/cpsection/aboutcomputer/view.py:69
+#: ../extensions/cpsection/aboutcomputer/view.py:70
msgid "Serial Number:"
msgstr "Numero di Serie:"
-#: ../extensions/cpsection/aboutcomputer/view.py:91
+#: ../extensions/cpsection/aboutcomputer/view.py:92
msgid "Software"
msgstr "Software"
-#: ../extensions/cpsection/aboutcomputer/view.py:100
+#: ../extensions/cpsection/aboutcomputer/view.py:101
msgid "Build:"
msgstr "Build:"
-#: ../extensions/cpsection/aboutcomputer/view.py:115
+#: ../extensions/cpsection/aboutcomputer/view.py:116
msgid "Sugar:"
msgstr "Sugar:"
-#: ../extensions/cpsection/aboutcomputer/view.py:131
+#: ../extensions/cpsection/aboutcomputer/view.py:132
msgid "Firmware:"
msgstr "Firmware:"
-#: ../extensions/cpsection/aboutcomputer/view.py:146
+#: ../extensions/cpsection/aboutcomputer/view.py:147
msgid "Wireless Firmware:"
msgstr "Wireless Firmware:"
-#: ../extensions/cpsection/aboutcomputer/view.py:169
+#: ../extensions/cpsection/aboutcomputer/view.py:170
msgid "Copyright and License"
msgstr "Copyright e Licenza"
-#: ../extensions/cpsection/aboutcomputer/view.py:184
+#: ../extensions/cpsection/aboutcomputer/view.py:188
msgid ""
"Sugar is the graphical user interface that you are looking at. Sugar is free "
"software, covered by the GNU General Public License, and you are welcome to "
@@ -113,7 +117,7 @@ msgstr ""
"chiunque è il benvenuto per apportare modifiche e migliorie e/o distribuirne "
"copie, alle condizioni descritte nella licenza medesima."
-#: ../extensions/cpsection/aboutcomputer/view.py:196
+#: ../extensions/cpsection/aboutcomputer/view.py:200
msgid "Full license:"
msgstr "Testo della Licenza:"
@@ -121,11 +125,11 @@ msgstr "Testo della Licenza:"
msgid "Date & Time"
msgstr "Data e Ora"
-#: ../extensions/cpsection/datetime/model.py:87
+#: ../extensions/cpsection/datetime/model.py:92
msgid "Error timezone does not exist."
msgstr "Errore, timezone non esistente."
-#: ../extensions/cpsection/datetime/view.py:68 ../data/sugar.schemas.in.h:33
+#: ../extensions/cpsection/datetime/view.py:70 ../data/sugar.schemas.in.h:52
msgid "Timezone"
msgstr "Timezone"
@@ -133,50 +137,50 @@ msgstr "Timezone"
msgid "Frame"
msgstr "Cornice"
-#: ../extensions/cpsection/frame/model.py:38
-#: ../extensions/cpsection/frame/model.py:60
+#: ../extensions/cpsection/frame/model.py:41
+#: ../extensions/cpsection/frame/model.py:66
msgid "Value must be an integer."
msgstr "Valore deve essere un intero."
-#: ../extensions/cpsection/frame/view.py:26
+#: ../extensions/cpsection/frame/view.py:27
msgid "never"
msgstr "mai"
-#: ../extensions/cpsection/frame/view.py:27
+#: ../extensions/cpsection/frame/view.py:28
msgid "instantaneous"
msgstr "istantaneamente"
-#: ../extensions/cpsection/frame/view.py:28
+#: ../extensions/cpsection/frame/view.py:29
#, python-format
msgid "%s seconds"
msgstr "%s secondi"
-#: ../extensions/cpsection/frame/view.py:52
+#: ../extensions/cpsection/frame/view.py:54
msgid "Activation Delay"
msgstr "Ritardo attivazione"
-#: ../extensions/cpsection/frame/view.py:76
+#: ../extensions/cpsection/frame/view.py:78
msgid "Corner"
msgstr "Angolo"
-#: ../extensions/cpsection/frame/view.py:111
+#: ../extensions/cpsection/frame/view.py:113
msgid "Edge"
msgstr "Margine"
#: ../extensions/cpsection/keyboard/__init__.py:21
-#: ../extensions/cpsection/keyboard/view.py:31
+#: ../extensions/cpsection/keyboard/view.py:32
msgid "Keyboard"
msgstr "Tastiera"
-#: ../extensions/cpsection/keyboard/view.py:189
+#: ../extensions/cpsection/keyboard/view.py:190
msgid "Keyboard Model"
msgstr "Modello Tastiera"
-#: ../extensions/cpsection/keyboard/view.py:248
+#: ../extensions/cpsection/keyboard/view.py:250
msgid "Key(s) to change layout"
msgstr "Tasto/i per cambiare la disposizione"
-#: ../extensions/cpsection/keyboard/view.py:318
+#: ../extensions/cpsection/keyboard/view.py:319
msgid "Keyboard Layout(s)"
msgstr "Disposizione Tastiera"
@@ -185,21 +189,21 @@ msgstr "Disposizione Tastiera"
msgid "Language"
msgstr "Lingua"
-#: ../extensions/cpsection/language/model.py:28
+#: ../extensions/cpsection/language/model.py:30
msgid "Could not access ~/.i18n. Create standard settings."
msgstr "Impossibile accedere a ~/.i18n. Creazione configurazione standard."
-#: ../extensions/cpsection/language/model.py:124
+#: ../extensions/cpsection/language/model.py:131
#, python-format
msgid "Language for code=%s could not be determined."
msgstr "Linguaggio con codice=%s sconosciuto."
-#: ../extensions/cpsection/language/model.py:144
+#: ../extensions/cpsection/language/model.py:152
#, python-format
msgid "Sorry I do not speak '%s'."
msgstr "Spiacente, ma non parlo '%s'."
-#: ../extensions/cpsection/language/view.py:56
+#: ../extensions/cpsection/language/view.py:57
msgid ""
"Add languages in the order you prefer. If a translation is not available, "
"the next in the list will be used."
@@ -211,66 +215,82 @@ msgstr ""
msgid "Modem Configuration"
msgstr "Configurazione del modem"
-#: ../extensions/cpsection/modemconfiguration/view.py:90
+#: ../extensions/cpsection/modemconfiguration/view.py:94
msgid "Username:"
msgstr "Utente:"
-#: ../extensions/cpsection/modemconfiguration/view.py:101
+#: ../extensions/cpsection/modemconfiguration/view.py:106
msgid "Password:"
msgstr "Password:"
-#: ../extensions/cpsection/modemconfiguration/view.py:112
+#: ../extensions/cpsection/modemconfiguration/view.py:118
msgid "Number:"
msgstr "Numero:"
-#: ../extensions/cpsection/modemconfiguration/view.py:123
-msgid "APN:"
-msgstr "APN:"
+#: ../extensions/cpsection/modemconfiguration/view.py:130
+msgid "Access Point Name (APN):"
+msgstr "Nome Access Point (APN):"
+
+#: ../extensions/cpsection/modemconfiguration/view.py:142
+msgid "Personal Identity Number (PIN):"
+msgstr "Personal Identity Number (PIN):"
+
+#: ../extensions/cpsection/modemconfiguration/view.py:154
+msgid "Personal Unblocking Key (PUK):"
+msgstr "Personal Unblocking Key (PUK):"
+
+#: ../extensions/cpsection/modemconfiguration/view.py:175
+msgid ""
+"You will need to provide the following information to set up a mobile "
+"broadband connection to a cellular (3G) network."
+msgstr ""
+"Dovresti fornire le informazioni richieste per configurare una connessione "
+"mobile in banda larga ad una rete cellulare (3G)."
#: ../extensions/cpsection/network/__init__.py:21
-#: ../extensions/cpsection/network/view.py:28
+#: ../extensions/cpsection/network/view.py:29
msgid "Network"
msgstr "Network"
-#: ../extensions/cpsection/network/model.py:79
+#: ../extensions/cpsection/network/model.py:68
msgid "State is unknown."
msgstr "Stato sconosciuto."
-#: ../extensions/cpsection/network/model.py:105
+#: ../extensions/cpsection/network/model.py:96
msgid "Error in specified radio argument use on/off."
msgstr "Errore nel campo specificato, utilizzare on/off."
-#: ../extensions/cpsection/network/model.py:137
+#: ../extensions/cpsection/network/model.py:133
msgid "Error in specified argument use 0/1."
msgstr "Errore nel campo specificato, utilizzare 0/1."
-#: ../extensions/cpsection/network/view.py:59
+#: ../extensions/cpsection/network/view.py:61
msgid "Wireless"
msgstr "Wireless"
-#: ../extensions/cpsection/network/view.py:67
+#: ../extensions/cpsection/network/view.py:69
msgid "Turn off the wireless radio to save battery life"
msgstr "Spegni il trasmettitore wireless per risparmiare carica della batteria"
-#: ../extensions/cpsection/network/view.py:80
+#: ../extensions/cpsection/network/view.py:82
msgid "Radio"
msgstr "Radio"
-#: ../extensions/cpsection/network/view.py:96
+#: ../extensions/cpsection/network/view.py:98
msgid "Discard network history if you have trouble connecting to the network"
msgstr ""
"Elimina la storia delle connessioni di rete effettuate nel caso di problemi "
"di connessione"
-#: ../extensions/cpsection/network/view.py:105
+#: ../extensions/cpsection/network/view.py:107
msgid "Discard network history"
msgstr "Elimina la storia delle connessioni di rete"
-#: ../extensions/cpsection/network/view.py:118
+#: ../extensions/cpsection/network/view.py:120
msgid "Collaboration"
msgstr "Collaborazione"
-#: ../extensions/cpsection/network/view.py:126
+#: ../extensions/cpsection/network/view.py:128
msgid ""
"The server is the equivalent of what room you are in; people on the same "
"server will be able to see each other, even when they aren't on the same "
@@ -280,7 +300,7 @@ msgstr ""
"stesso server sono in grado di vedersi fra loro, anche se collegate a reti "
"differenti."
-#: ../extensions/cpsection/network/view.py:136
+#: ../extensions/cpsection/network/view.py:138
msgid "Server:"
msgstr "Server:"
@@ -288,26 +308,27 @@ msgstr "Server:"
msgid "Power"
msgstr "Energia"
-#: ../extensions/cpsection/power/model.py:54
+#: ../extensions/cpsection/power/model.py:90
msgid "Error in automatic pm argument, use on/off."
msgstr ""
-"Errore nel campo Gestione Automatica Risparmio Energetico, utilizza on/off"
+"Errore nel campo Gestione Automatica Risparmio Energetico, utilizza on/off."
-#: ../extensions/cpsection/power/model.py:81
+#: ../extensions/cpsection/power/model.py:120
msgid "Error in extreme pm argument, use on/off."
-msgstr "Errore nel campo Gestione Estrema Risparmio Energetico, utilizza on/off"
+msgstr ""
+"Errore nel campo Gestione Estrema Risparmio Energetico, utilizza on/off."
-#: ../extensions/cpsection/power/view.py:47
+#: ../extensions/cpsection/power/view.py:48
msgid "Power management"
msgstr "Gestione Risparmio Energetico (power management)"
-#: ../extensions/cpsection/power/view.py:57
+#: ../extensions/cpsection/power/view.py:58
msgid "Automatic power management (increases battery life)"
msgstr ""
"Gestione Automatica Risparmio Energetico (incrementa la durata delle "
"batterie)"
-#: ../extensions/cpsection/power/view.py:85
+#: ../extensions/cpsection/power/view.py:86
msgid ""
"Extreme power management (disableswireless radio, increases battery life)"
msgstr ""
@@ -324,7 +345,7 @@ msgid ""
"provide new features."
msgstr ""
"Gli aggiornamenti software correggono errori, eliminano vulnerabilità del "
-"codice ed offrono nuove funzioni. "
+"codice ed offrono nuove funzioni."
#: ../extensions/cpsection/updater/view.py:125
#, python-format
@@ -360,26 +381,26 @@ msgstr "Ricerca aggiornamenti..."
msgid "Installing updates..."
msgstr "Installazione aggiornamenti..."
-#: ../extensions/cpsection/updater/view.py:172
+#: ../extensions/cpsection/updater/view.py:173
#, python-format
msgid "%s update was installed"
msgid_plural "%s updates were installed"
msgstr[0] "%s aggiornamento è stato installato"
msgstr[1] "%s aggiornamenti sono stati installati"
-#: ../extensions/cpsection/updater/view.py:253
+#: ../extensions/cpsection/updater/view.py:255
msgid "Install selected"
msgstr "Installa selezionati"
-#: ../extensions/cpsection/updater/view.py:274
+#: ../extensions/cpsection/updater/view.py:276
#, python-format
msgid "Download size: %s"
msgstr "Dimensione dati da scaricare: %s"
-#: ../extensions/cpsection/updater/view.py:362
+#: ../extensions/cpsection/updater/view.py:364
#, python-format
-msgid "From version %(current)d to %(new)s (Size: %(size)s)"
-msgstr "Dalla versione %(current)d alla %(new)s (Dimensione: %(size)s)"
+msgid "From version %(current)s to %(new)s (Size: %(size)s)"
+msgstr "Dalla versione %(current)s alla %(new)s (Dimensione: %(size)s)"
#. TRANS: download size is 0
#: ../extensions/cpsection/updater/view.py:382
@@ -403,28 +424,28 @@ msgstr "%.0f KB"
msgid "%.1f MB"
msgstr "%.1f MB"
-#: ../extensions/deviceicon/battery.py:58
+#: ../extensions/deviceicon/battery.py:60
msgid "My Battery"
msgstr "La mia Batteria"
-#: ../extensions/deviceicon/battery.py:137
+#: ../extensions/deviceicon/battery.py:141
msgid "Removed"
msgstr "Rimosso"
-#: ../extensions/deviceicon/battery.py:140
+#: ../extensions/deviceicon/battery.py:144
msgid "Charging"
msgstr "Caricando"
-#: ../extensions/deviceicon/battery.py:143
+#: ../extensions/deviceicon/battery.py:147
msgid "Very little power remaining"
msgstr "Pochissima carica rimanente"
-#: ../extensions/deviceicon/battery.py:149
+#: ../extensions/deviceicon/battery.py:153
#, python-format
msgid "%(hour)d:%(min).2d remaining"
msgstr "%(hour)d:%(min).2d rimanenti"
-#: ../extensions/deviceicon/battery.py:152
+#: ../extensions/deviceicon/battery.py:156
msgid "Charged"
msgstr "Carica"
@@ -437,119 +458,174 @@ msgstr "Indirizzo IP: %s"
# priority over the normal wireless device. NM doesn't have a "disconnect"
# method for a device either (for various reasons) so this doesn't
# have a good mapping
-#: ../extensions/deviceicon/network.py:111
+#: ../extensions/deviceicon/network.py:104
msgid "Disconnect..."
msgstr "Disconnessione..."
-#: ../extensions/deviceicon/network.py:116
-msgid "Create new wireless network"
-msgstr "Crea una nuova rete wireless"
-
-#: ../extensions/deviceicon/network.py:122
-#: ../extensions/deviceicon/network.py:284
-#: ../src/jarabe/desktop/meshbox.py:248 ../src/jarabe/desktop/meshbox.py:537
+#: ../extensions/deviceicon/network.py:112
+#: ../extensions/deviceicon/network.py:290
+#: ../src/jarabe/desktop/networkviews.py:239
+#: ../src/jarabe/desktop/networkviews.py:538
+#: ../src/jarabe/desktop/networkviews.py:667
msgid "Connecting..."
msgstr "Connessione..."
# TODO: show the channel number
-#: ../extensions/deviceicon/network.py:126
-#: ../extensions/deviceicon/network.py:198
-#: ../extensions/deviceicon/network.py:288
-#: ../src/jarabe/desktop/meshbox.py:254 ../src/jarabe/desktop/meshbox.py:543
+#: ../extensions/deviceicon/network.py:116
+#: ../extensions/deviceicon/network.py:182
+#: ../src/jarabe/desktop/networkviews.py:249
+#: ../src/jarabe/desktop/networkviews.py:544
+#: ../src/jarabe/desktop/networkviews.py:673
msgid "Connected"
msgstr "Connesso"
-#: ../extensions/deviceicon/network.py:158
+#: ../extensions/deviceicon/network.py:142
msgid "Channel"
msgstr "Canale"
-#: ../extensions/deviceicon/network.py:173
+#: ../extensions/deviceicon/network.py:157
msgid "Wired Network"
msgstr "Rete su cavo"
-#: ../extensions/deviceicon/network.py:201
+#: ../extensions/deviceicon/network.py:185
msgid "Speed"
msgstr "Velocità"
-#: ../extensions/deviceicon/network.py:228
+#: ../extensions/deviceicon/network.py:211
msgid "Wireless modem"
msgstr "Modem Wireless"
-#: ../extensions/deviceicon/network.py:276
+#: ../extensions/deviceicon/network.py:278
msgid "Please wait..."
msgstr "Attendi..."
-#: ../extensions/deviceicon/network.py:279
-#: ../src/jarabe/desktop/meshbox.py:164 ../src/jarabe/desktop/meshbox.py:494
+#: ../extensions/deviceicon/network.py:282
+#: ../src/jarabe/desktop/networkviews.py:149
+#: ../src/jarabe/desktop/networkviews.py:492
+#: ../src/jarabe/desktop/networkviews.py:624
msgid "Connect"
msgstr "Connetti"
-#: ../extensions/deviceicon/network.py:280
+#: ../extensions/deviceicon/network.py:283
msgid "Disconnected"
msgstr "Disconnesso"
-#: ../extensions/deviceicon/network.py:283
-#: ../src/jarabe/controlpanel/toolbar.py:115
-#: ../src/jarabe/desktop/homebox.py:68
-#: ../src/jarabe/frame/activitiestray.py:700
-#: ../src/jarabe/frame/activitiestray.py:799
-#: ../src/jarabe/frame/activitiestray.py:827
+#: ../extensions/deviceicon/network.py:289
+#: ../src/jarabe/controlpanel/toolbar.py:119
+#: ../src/jarabe/desktop/homebox.py:70
+#: ../src/jarabe/frame/activitiestray.py:587
+#: ../src/jarabe/frame/activitiestray.py:687
+#: ../src/jarabe/frame/activitiestray.py:715
msgid "Cancel"
msgstr "Cancella"
-#: ../extensions/deviceicon/network.py:287
-#: ../src/jarabe/desktop/meshbox.py:168
+#: ../extensions/deviceicon/network.py:297
+#: ../src/jarabe/desktop/networkviews.py:153
+#: ../src/jarabe/desktop/networkviews.py:496
msgid "Disconnect"
msgstr "Disconnetti"
-#: ../extensions/deviceicon/network.py:530
+#: ../extensions/deviceicon/network.py:327
+msgid "Try connection again"
+msgstr "Prova nuovamente a connetterti"
+
+#: ../extensions/deviceicon/network.py:330
#, python-format
-msgid "%s's network"
-msgstr "rete di %s"
+msgid "Error: %s"
+msgstr "Errore: %s"
+
+#: ../extensions/deviceicon/network.py:334
+#, python-format
+msgid "Suggestion: %s"
+msgstr "Suggerimento: %s"
+
+#: ../extensions/deviceicon/network.py:340
+#: ../extensions/deviceicon/network.py:343
+#, python-format
+msgid "Connected for %s"
+msgstr "Connesso per %s"
+
+#: ../extensions/deviceicon/network.py:348
+#: ../extensions/deviceicon/network.py:349
+#, python-format
+msgid "%d KB"
+msgstr "%d KB"
+
+#: ../extensions/deviceicon/network.py:354
+msgid "Check your Pin/Puk configuration."
+msgstr "Verifica la configurazione di Pin/Puk ."
+
+#: ../extensions/deviceicon/network.py:357
+msgid "Check your Access Point Name (APN) configuration"
+msgstr "Verifica la configurazione dell'Access Point Name (APN)"
+
+#: ../extensions/deviceicon/network.py:361
+msgid "Check the Number configuration."
+msgstr "Verifica la configurazione del Numero"
+
+#: ../extensions/deviceicon/network.py:363
+msgid "Check your configuration."
+msgstr "Verifica la configurazione."
# A complete translation in italian: "rete a maglie" becames a tautology
-#: ../extensions/deviceicon/network.py:597
-#: ../extensions/deviceicon/network.py:656
+#: ../extensions/deviceicon/network.py:615
msgid "Mesh Network"
msgstr "Rete Mesh"
-#: ../extensions/deviceicon/network.py:857
+# A complete translation in italian: "rete a maglie" becames a tautology
+#: ../extensions/deviceicon/network.py:658
#, python-format
-msgid "Data sent %d kb / received %d kb"
-msgstr "Dati %d kb inviati / %d kb ricevuti"
+msgid "Mesh Network %s"
+msgstr "Rete Mesh %s"
+
+#: ../extensions/deviceicon/network.py:782
+msgid "No GSM connection available."
+msgstr "Connessione GSM non disponibile."
-#: ../extensions/deviceicon/network.py:868
-msgid "Connection time "
-msgstr "Tempo di connessione"
+#: ../extensions/deviceicon/network.py:783
+msgid "Create a connection in the control panel."
+msgstr "Definisci una connessione nel Pannello di Controllo."
-#: ../extensions/deviceicon/speaker.py:59
+#: ../extensions/deviceicon/speaker.py:60
msgid "My Speakers"
msgstr "I miei Altoparlanti"
-#: ../extensions/deviceicon/speaker.py:133
+#: ../extensions/deviceicon/speaker.py:136
msgid "Unmute"
msgstr "Attiva"
-#: ../extensions/deviceicon/speaker.py:136
+#: ../extensions/deviceicon/speaker.py:139
msgid "Mute"
msgstr "Silenzia"
+#: ../extensions/deviceicon/touchpad.py:37
+msgid "finger"
+msgstr "dito"
+
+#: ../extensions/deviceicon/touchpad.py:38
+msgid "stylus"
+msgstr "stilo"
+
+#: ../extensions/deviceicon/touchpad.py:67
+msgid "My touchpad"
+msgstr "Il mio Touchpad"
+
#: ../extensions/globalkey/screenshot.py:59
msgid "Mesh"
msgstr "Mesh"
#: ../extensions/globalkey/screenshot.py:61
-#: ../src/jarabe/frame/zoomtoolbar.py:39
+#: ../src/jarabe/frame/zoomtoolbar.py:40
msgid "Group"
msgstr "Gruppo"
#: ../extensions/globalkey/screenshot.py:63
-#: ../src/jarabe/frame/zoomtoolbar.py:41
+#: ../src/jarabe/frame/zoomtoolbar.py:42
msgid "Home"
msgstr "Casa"
#: ../extensions/globalkey/screenshot.py:69
-#: ../src/jarabe/frame/zoomtoolbar.py:43
+#: ../src/jarabe/frame/zoomtoolbar.py:44
msgid "Activity"
msgstr "Attività"
@@ -568,13 +644,21 @@ msgid ""
"long name."
msgstr ""
"se \"disabled\" viene richiesto il nome alla inizializzazione; se \"system\" "
-"verrà utilizzato il nome presente nell'account UNIX."
+"verrà utilizzato il nome presente nell'account UNIX."
#: ../data/sugar.schemas.in.h:2
+msgid "Additional directories which can contain updated translations."
+msgstr "Ulteriori directory contenenti traduzioni aggiornate."
+
+#: ../data/sugar.schemas.in.h:3
msgid "Backup URL"
msgstr "URL di salvataggio"
-#: ../data/sugar.schemas.in.h:3
+#: ../data/sugar.schemas.in.h:4
+msgid "Bundle IDs of protected activities"
+msgstr "ID dei pacchetti di attività protette"
+
+#: ../data/sugar.schemas.in.h:5
msgid ""
"Color for the XO icon that is used throughout the desktop. The string is "
"composed of the stroke color and fill color, format is that of rbg colors. "
@@ -584,52 +668,105 @@ msgstr ""
"composta dal colore della linea e dal colore del riempimento, il formato è "
"quello dei colori rbg. Esempio: #AC32FF,#9A5200"
-#: ../data/sugar.schemas.in.h:4
+#: ../data/sugar.schemas.in.h:6
msgid "Corner Delay"
msgstr "Ritardo dell'angolo"
-#: ../data/sugar.schemas.in.h:5
+#: ../data/sugar.schemas.in.h:7
msgid "Default font face"
msgstr "Tipo di carattere di default"
-#: ../data/sugar.schemas.in.h:6
+#: ../data/sugar.schemas.in.h:8
msgid "Default font size"
msgstr "Dimensione del carattere di default"
-#: ../data/sugar.schemas.in.h:7
+#: ../data/sugar.schemas.in.h:9
msgid "Default nick"
msgstr "Nome di default"
-#: ../data/sugar.schemas.in.h:8
+#: ../data/sugar.schemas.in.h:10
msgid "Delay for the activation of the frame using the corners."
msgstr ""
"Ritardo nella attivazione della cornice portando il puntatore in un angolo."
-#: ../data/sugar.schemas.in.h:9
+#: ../data/sugar.schemas.in.h:11
msgid "Delay for the activation of the frame using the edges."
-msgstr "Ritardo nella attivazione della cornice portando il puntatore sui bordi"
+msgstr ""
+"Ritardo nella attivazione della cornice portando il puntatore sui bordi."
-#: ../data/sugar.schemas.in.h:10
+#: ../data/sugar.schemas.in.h:12
+msgid "Directory to search for translations"
+msgstr "Directory in cui cercare traduzioni"
+
+#: ../data/sugar.schemas.in.h:13
msgid "Edge Delay"
msgstr "Ritardo del bordo"
-#: ../data/sugar.schemas.in.h:11
+#: ../data/sugar.schemas.in.h:14
msgid "Favorites Layout"
msgstr "Disposizione delle attività preferite"
-#: ../data/sugar.schemas.in.h:12
+#: ../data/sugar.schemas.in.h:15
msgid "Favorites resume mode"
msgstr "Modalità di richiamo delle attività preferite"
-#: ../data/sugar.schemas.in.h:13
+#: ../data/sugar.schemas.in.h:16
msgid "Font face that is used throughout the desktop."
msgstr "Tipo di carattere di default utilizzato in tutto il sistema."
-#: ../data/sugar.schemas.in.h:14
+#: ../data/sugar.schemas.in.h:17
msgid "Font size that is used throughout the desktop."
msgstr "Dimensione del carattere utilizzato in tutto il sistema."
-#: ../data/sugar.schemas.in.h:15
+#: ../data/sugar.schemas.in.h:18
+msgid "GSM network APN"
+msgstr " APN rete GSM"
+
+#: ../data/sugar.schemas.in.h:19
+msgid "GSM network PIN"
+msgstr "PIN rete GSM"
+
+#: ../data/sugar.schemas.in.h:20
+msgid "GSM network PUK"
+msgstr "PUK rete GSM"
+
+#: ../data/sugar.schemas.in.h:21
+msgid "GSM network access point name configuration"
+msgstr "configurazione di access point name rete GSM"
+
+#: ../data/sugar.schemas.in.h:22
+msgid "GSM network number"
+msgstr "numero di rete GSM"
+
+#: ../data/sugar.schemas.in.h:23
+msgid "GSM network password"
+msgstr "password di rete GSM"
+
+#: ../data/sugar.schemas.in.h:24
+msgid "GSM network password configuration"
+msgstr "configurazione della password di rete GSM"
+
+#: ../data/sugar.schemas.in.h:25
+msgid "GSM network personal identification number configuration"
+msgstr "configurazione del personal identification number (PIN) della rete GSM"
+
+#: ../data/sugar.schemas.in.h:26
+msgid "GSM network personal unlock key configuration"
+msgstr "configurazione della chiave personale di sblocco (PUK) della rete GSM"
+
+#: ../data/sugar.schemas.in.h:27
+msgid "GSM network telephone number configuration"
+msgstr "configurazione del numero telefonico della rete GSM"
+
+#: ../data/sugar.schemas.in.h:28
+msgid "GSM network username"
+msgstr "username dela rete GSM"
+
+#: ../data/sugar.schemas.in.h:29
+msgid "GSM network username configuration"
+msgstr "configurazione dello username della rete GSM"
+
+#: ../data/sugar.schemas.in.h:30
msgid ""
"If TRUE, Sugar will make us searchable for the other users of the Jabber "
"server."
@@ -637,110 +774,136 @@ msgstr ""
"Se TRUE, Sugar renderà il computer rintracciabile dagli altri utenti del "
"server Jabber."
-#: ../data/sugar.schemas.in.h:16
+#: ../data/sugar.schemas.in.h:31
msgid "If TRUE, Sugar will show a \"Log out\" option."
-msgstr "Se TRUE, Sugar mostrerà una opzione di \"Disconnessione\"."
+msgstr "Se TRUE, Sugar mostrerà una opzione di \"Disconnessione\"."
-#: ../data/sugar.schemas.in.h:17
+#: ../data/sugar.schemas.in.h:32
+msgid "If TRUE, Sugar will show a \"Restart\" option."
+msgstr "Se TRUE, Sugar mostrerà una opzione di \"Riavvia\"."
+
+#: ../data/sugar.schemas.in.h:33
+msgid ""
+"If TRUE, Sugar will show default Ad-hoc networks for channel 1,6 and 11. If "
+"Sugar sees no \"known\" network when it starts, it does autoconnect to an Ad-"
+"hoc network."
+msgstr ""
+
+#: ../data/sugar.schemas.in.h:34
msgid "Jabber Server"
msgstr "Jabber Server"
-#: ../data/sugar.schemas.in.h:18
+#: ../data/sugar.schemas.in.h:35
msgid "Keyboard layouts"
msgstr "Disposizioni tastiera"
-#: ../data/sugar.schemas.in.h:19
+#: ../data/sugar.schemas.in.h:36
msgid "Keyboard model"
msgstr "Modello tastiera"
-#: ../data/sugar.schemas.in.h:20
+#: ../data/sugar.schemas.in.h:37
msgid "Keyboard options"
msgstr "Opzioni tastiera"
-#: ../data/sugar.schemas.in.h:21
+#: ../data/sugar.schemas.in.h:38
msgid "Layout of the favorites view."
msgstr "Disposizione della vista dei favoriti."
-#: ../data/sugar.schemas.in.h:22
+#: ../data/sugar.schemas.in.h:39
msgid ""
"List of keyboard layouts. Each entry should be in the form layout(variant)"
msgstr ""
"Elenco di disposizioni della tastiera. Ogni voce deve essere nel formato "
-"layout(variant) "
+"layout(variant)"
-#: ../data/sugar.schemas.in.h:23
+#: ../data/sugar.schemas.in.h:40
msgid "List of keyboard options."
msgstr "Lista di opzioni per la tastiera."
-#: ../data/sugar.schemas.in.h:24
+#: ../data/sugar.schemas.in.h:41
msgid "Power Automatic"
msgstr "Economizzazione Automatica"
-#: ../data/sugar.schemas.in.h:25
+#: ../data/sugar.schemas.in.h:42
msgid "Power Automatic."
msgstr "Economizzazione Automatica."
-#: ../data/sugar.schemas.in.h:26
+#: ../data/sugar.schemas.in.h:43
msgid "Power Extreme"
msgstr "Economizzazione Massima"
-#: ../data/sugar.schemas.in.h:27
+#: ../data/sugar.schemas.in.h:44
msgid "Power Extreme."
msgstr "Economizzazione Massima."
-#: ../data/sugar.schemas.in.h:28
+#: ../data/sugar.schemas.in.h:45
msgid "Publish to Gadget"
msgstr "Pubblica su Gadget"
-#: ../data/sugar.schemas.in.h:29
+#: ../data/sugar.schemas.in.h:46
msgid "Setting for muting the sound device."
msgstr "Selezione per silenziare il riproduttore sonoro."
-#: ../data/sugar.schemas.in.h:30
+#: ../data/sugar.schemas.in.h:47
msgid "Show Log out"
msgstr "Mostra Disconnessione"
-#: ../data/sugar.schemas.in.h:31
+#: ../data/sugar.schemas.in.h:48
+msgid "Show Restart"
+msgstr "Mostra Riavvia"
+
+#: ../data/sugar.schemas.in.h:49
+msgid "Show Sugar Ad-hoc networks"
+msgstr "Mostra rete ad-hoc di Sugar"
+
+#: ../data/sugar.schemas.in.h:50
msgid "Sound Muted"
msgstr "Suono Silenziato"
-#: ../data/sugar.schemas.in.h:32
+#: ../data/sugar.schemas.in.h:51
msgid "The keyboard model to be used"
msgstr "Modello di tastiera da utilizzare"
-#: ../data/sugar.schemas.in.h:34
+#: ../data/sugar.schemas.in.h:53
msgid "Timezone setting for the system."
-msgstr "Selezione per il Timezone del sistema"
+msgstr "Selezione per il Timezone del sistema."
-#: ../data/sugar.schemas.in.h:35
+#: ../data/sugar.schemas.in.h:54
msgid "Url of the jabber server to use."
msgstr "Url del server jabber da utilizzare."
-#: ../data/sugar.schemas.in.h:36
+#: ../data/sugar.schemas.in.h:55
msgid "Url where the backup is saved to."
msgstr "Url su cui effettuare i salvataggi."
-#: ../data/sugar.schemas.in.h:37
+#: ../data/sugar.schemas.in.h:56
msgid "User Color"
-msgstr "Colore dell'Utente "
+msgstr "Colore dell'Utente"
-#: ../data/sugar.schemas.in.h:38
+#: ../data/sugar.schemas.in.h:57
msgid "User Name"
msgstr "Nome Utente"
-#: ../data/sugar.schemas.in.h:39
+#: ../data/sugar.schemas.in.h:58
msgid "User name that is used throughout the desktop."
msgstr "Nome Utente utilizzato in tutto il sistema."
-#: ../data/sugar.schemas.in.h:40
+#: ../data/sugar.schemas.in.h:59
+msgid ""
+"Users will not be allowed to erase these activities through the list view."
+msgstr ""
+"Gli utenti non saranno abilitati alla cancellazione di queste attività dalla "
+"Visualizzazione a lista"
+
+#: ../data/sugar.schemas.in.h:60
msgid "Volume Level"
msgstr "Livello Volume"
-#: ../data/sugar.schemas.in.h:41
+#: ../data/sugar.schemas.in.h:61
msgid "Volume level for the sound device."
msgstr "Livello del volume del riproduttore di suoni."
-#: ../data/sugar.schemas.in.h:42
+#: ../data/sugar.schemas.in.h:62
msgid ""
"When in resume mode, clicking on a favorite icon will cause the last entry "
"for that activity to be resumed."
@@ -773,7 +936,7 @@ msgstr "sugar-control-panel: %s"
# which must appear in the translated string (msgstr) as well.
#. TRANS: Translators, there's a empty line at the end of this string,
#. which must appear in the translated string (msgstr) as well.
-#: ../src/jarabe/controlpanel/cmd.py:37
+#: ../src/jarabe/controlpanel/cmd.py:38
msgid ""
"Usage: sugar-control-panel [ option ] key [ args ... ] \n"
" Control for the sugar environment. \n"
@@ -796,50 +959,52 @@ msgstr ""
" -s key assegna il valore corrente alla \"key\" \n"
" "
-#: ../src/jarabe/controlpanel/cmd.py:50
+#: ../src/jarabe/controlpanel/cmd.py:52
msgid "To apply your changes you have to restart sugar.\n"
msgstr "Per applicare le modifiche è necessario riavviare sugar.\n"
-#: ../src/jarabe/controlpanel/gui.py:281
+#: ../src/jarabe/controlpanel/gui.py:285
+#: ../src/jarabe/journal/journaltoolbox.py:437
+#: ../src/jarabe/journal/volumestoolbar.py:158
msgid "Warning"
msgstr "Attenzione"
-#: ../src/jarabe/controlpanel/gui.py:282
-#: ../src/jarabe/controlpanel/sectionview.py:42
+#: ../src/jarabe/controlpanel/gui.py:286
+#: ../src/jarabe/controlpanel/sectionview.py:41
msgid "Changes require restart"
msgstr "Le modifiche rendono necessario un riavvio"
-#: ../src/jarabe/controlpanel/gui.py:285
+#: ../src/jarabe/controlpanel/gui.py:289
msgid "Cancel changes"
msgstr "Annulla modifiche"
-#: ../src/jarabe/controlpanel/gui.py:290 ../src/jarabe/desktop/homebox.py:70
+#: ../src/jarabe/controlpanel/gui.py:294 ../src/jarabe/desktop/homebox.py:72
msgid "Later"
msgstr "Dopo"
-#: ../src/jarabe/controlpanel/gui.py:294
+#: ../src/jarabe/controlpanel/gui.py:298
msgid "Restart now"
msgstr "Riavvia adesso"
-#: ../src/jarabe/controlpanel/toolbar.py:61 ../src/jarabe/intro/window.py:206
+#: ../src/jarabe/controlpanel/toolbar.py:63 ../src/jarabe/intro/window.py:211
msgid "Done"
msgstr "Fatto"
-#: ../src/jarabe/controlpanel/toolbar.py:121
-#: ../src/jarabe/desktop/favoritesview.py:333
+#: ../src/jarabe/controlpanel/toolbar.py:125
+#: ../src/jarabe/desktop/favoritesview.py:336
msgid "Ok"
msgstr "Ok"
-#: ../src/jarabe/desktop/activitieslist.py:236
+#: ../src/jarabe/desktop/activitieslist.py:230
#, python-format
msgid "Version %s"
msgstr "Versione %s"
-#: ../src/jarabe/desktop/activitieslist.py:357
+#: ../src/jarabe/desktop/activitieslist.py:354
msgid "Confirm erase"
msgstr "Conferma cancellazione"
-#: ../src/jarabe/desktop/activitieslist.py:359
+#: ../src/jarabe/desktop/activitieslist.py:356
#, python-format
msgid "Confirm erase: Do you want to permanently erase %s?"
msgstr ""
@@ -849,255 +1014,264 @@ msgstr ""
# TODO: Implement stopping downloads
# self._stop_item.connect('activate', self._stop_item_activate_cb)
# self.append_menu_item(self._stop_item)
-#: ../src/jarabe/desktop/activitieslist.py:363
-#: ../src/jarabe/frame/clipboardmenu.py:63
-#: ../src/jarabe/view/viewsource.py:218
+#: ../src/jarabe/desktop/activitieslist.py:360
+#: ../src/jarabe/frame/clipboardmenu.py:64
+#: ../src/jarabe/view/viewsource.py:221
msgid "Keep"
msgstr "Memorizza"
-#: ../src/jarabe/desktop/activitieslist.py:366
-#: ../src/jarabe/desktop/activitieslist.py:409
-#: ../src/jarabe/journal/journaltoolbox.py:360
-#: ../src/jarabe/journal/palettes.py:105
+#: ../src/jarabe/desktop/activitieslist.py:363
+#: ../src/jarabe/desktop/activitieslist.py:417
+#: ../src/jarabe/journal/journaltoolbox.py:391
+#: ../src/jarabe/journal/palettes.py:112
msgid "Erase"
msgstr "Elimina"
-#: ../src/jarabe/desktop/activitieslist.py:430
+#: ../src/jarabe/desktop/activitieslist.py:432
msgid "Remove favorite"
msgstr "Rimuovi preferito"
-#: ../src/jarabe/desktop/activitieslist.py:434
+#: ../src/jarabe/desktop/activitieslist.py:436
msgid "Make favorite"
msgstr "Definisci preferito"
# TRANS: label for the freeform layout in the favorites view
#. TRANS: label for the freeform layout in the favorites view
-#: ../src/jarabe/desktop/favoriteslayout.py:116
+#: ../src/jarabe/desktop/favoriteslayout.py:127
msgid "Freeform"
msgstr "Formato libero"
# TRANS: label for the ring layout in the favorites view
#. TRANS: label for the ring layout in the favorites view
-#: ../src/jarabe/desktop/favoriteslayout.py:198
+#: ../src/jarabe/desktop/favoriteslayout.py:215
msgid "Ring"
msgstr "Anello"
# TRANS: label for the spiral layout in the favorites view
#. TRANS: label for the spiral layout in the favorites view
-#: ../src/jarabe/desktop/favoriteslayout.py:337
+#: ../src/jarabe/desktop/favoriteslayout.py:402
msgid "Spiral"
msgstr "Spirale"
# TRANS: label for the box layout in the favorites view
#. TRANS: label for the box layout in the favorites view
-#: ../src/jarabe/desktop/favoriteslayout.py:404
+#: ../src/jarabe/desktop/favoriteslayout.py:472
msgid "Box"
msgstr "Scatola"
# TRANS: label for the box layout in the favorites view
#. TRANS: label for the box layout in the favorites view
-#: ../src/jarabe/desktop/favoriteslayout.py:445
+#: ../src/jarabe/desktop/favoriteslayout.py:515
msgid "Triangle"
msgstr "Triangolo"
-#: ../src/jarabe/desktop/favoritesview.py:324
+#: ../src/jarabe/desktop/favoritesview.py:327
msgid "Registration Failed"
msgstr "Registrazione Fallita"
-#: ../src/jarabe/desktop/favoritesview.py:325
+#: ../src/jarabe/desktop/favoritesview.py:328
#, python-format
msgid "%s"
msgstr "%s"
-#: ../src/jarabe/desktop/favoritesview.py:327
+#: ../src/jarabe/desktop/favoritesview.py:330
msgid "Registration Successful"
msgstr "Registrazione Effettuata"
-#: ../src/jarabe/desktop/favoritesview.py:328
+#: ../src/jarabe/desktop/favoritesview.py:331
msgid "You are now registered with your school server."
-msgstr "Ora sei registrato sul tuo server di scuola"
+msgstr "Ora sei registrato sul tuo server di scuola."
-#: ../src/jarabe/desktop/favoritesview.py:630
+#: ../src/jarabe/desktop/favoritesview.py:626
msgid "Register"
msgstr "Registra"
-#: ../src/jarabe/desktop/homebox.py:63
+#: ../src/jarabe/desktop/homebox.py:65
msgid "Software Update"
msgstr "Aggiornamento software"
-#: ../src/jarabe/desktop/homebox.py:64
+#: ../src/jarabe/desktop/homebox.py:66
msgid "Update your activities to ensure compatibility with your new software"
msgstr ""
"Aggiorna le tue attività perchè siano compatibili con il tuo sistema "
-"aggiornato."
+"aggiornato"
-#: ../src/jarabe/desktop/homebox.py:73
+#: ../src/jarabe/desktop/homebox.py:75
msgid "Check now"
msgstr "Verifica adesso"
-#: ../src/jarabe/desktop/homebox.py:192
+#: ../src/jarabe/desktop/homebox.py:193
msgid "List view"
msgstr "Vista Elenco"
-#: ../src/jarabe/desktop/homebox.py:193
+#: ../src/jarabe/desktop/homebox.py:194
msgid "<Ctrl>2"
msgstr "<Ctrl>2"
-#: ../src/jarabe/desktop/homebox.py:255
+#: ../src/jarabe/desktop/homebox.py:257
msgid "Favorites view"
msgstr "Visualizza i Preferiti"
-#: ../src/jarabe/desktop/homebox.py:256
+#: ../src/jarabe/desktop/homebox.py:258
msgid "<Ctrl>1"
msgstr "<Ctrl>1"
-#: ../src/jarabe/desktop/keydialog.py:135
+#: ../src/jarabe/desktop/keydialog.py:143
msgid "Key Type:"
msgstr "Tipo Chiave:"
-#: ../src/jarabe/desktop/keydialog.py:155
+#: ../src/jarabe/desktop/keydialog.py:163
msgid "Authentication Type:"
msgstr "Tipo di Autenticazione:"
-#: ../src/jarabe/desktop/keydialog.py:220
+#: ../src/jarabe/desktop/keydialog.py:229
msgid "WPA & WPA2 Personal"
msgstr "WPA & WPA2 Personal"
-#: ../src/jarabe/desktop/keydialog.py:229
+#: ../src/jarabe/desktop/keydialog.py:238
msgid "Wireless Security:"
msgstr "Wireless Security:"
-# A complete translation in italian: "rete a maglie" becames a tautology
-#: ../src/jarabe/desktop/meshbox.py:492
-#, python-format
-msgid "Mesh Network %d"
-msgstr "Rete Mesh %d"
-
# TRANS: Action label for resuming an activity.
#. TRANS: Action label for resuming an activity.
-#: ../src/jarabe/desktop/meshbox.py:629
-#: ../src/jarabe/frame/activitiestray.py:735
-#: ../src/jarabe/journal/journaltoolbox.py:428
-#: ../src/jarabe/journal/palettes.py:65 ../src/jarabe/view/palettes.py:67
+#: ../src/jarabe/desktop/meshbox.py:109
+#: ../src/jarabe/frame/activitiestray.py:622
+#: ../src/jarabe/journal/journaltoolbox.py:485
+#: ../src/jarabe/journal/palettes.py:66 ../src/jarabe/view/palettes.py:78
msgid "Resume"
msgstr "Riprendi"
-#: ../src/jarabe/desktop/meshbox.py:634
-#: ../src/jarabe/frame/activitiestray.py:233
+#: ../src/jarabe/desktop/meshbox.py:114
+#: ../src/jarabe/frame/activitiestray.py:173
msgid "Join"
msgstr "Associa"
-#: ../src/jarabe/desktop/schoolserver.py:103
+#: ../src/jarabe/desktop/networkviews.py:489
+#, python-format
+msgid "Ad-hoc Network %d"
+msgstr "Rete Ad-hoc %d"
+
+# A complete translation in italian: "rete a maglie" becames a tautology
+#: ../src/jarabe/desktop/networkviews.py:622
+#, python-format
+msgid "Mesh Network %d"
+msgstr "Rete Mesh %d"
+
+#: ../src/jarabe/desktop/schoolserver.py:131
msgid "Cannot connect to the server."
msgstr "Impossibile connettersi al server."
-#: ../src/jarabe/desktop/schoolserver.py:108
+#: ../src/jarabe/desktop/schoolserver.py:136
msgid "The server could not complete the request."
msgstr "Il server non può completare la richiesta."
-#: ../src/jarabe/frame/activitiestray.py:238
-#: ../src/jarabe/frame/activitiestray.py:672
+#: ../src/jarabe/frame/activitiestray.py:178
+#: ../src/jarabe/frame/activitiestray.py:559
msgid "Decline"
msgstr "Rinuncia"
-#: ../src/jarabe/frame/activitiestray.py:624
+#: ../src/jarabe/frame/activitiestray.py:509
#, python-format
msgid "%dB"
msgstr "%dB"
-#: ../src/jarabe/frame/activitiestray.py:626
+#: ../src/jarabe/frame/activitiestray.py:511
#, python-format
msgid "%dKB"
msgstr "%dKB"
-#: ../src/jarabe/frame/activitiestray.py:628
+#: ../src/jarabe/frame/activitiestray.py:513
#, python-format
msgid "%dMB"
msgstr "%dMB"
-#: ../src/jarabe/frame/activitiestray.py:645
+#: ../src/jarabe/frame/activitiestray.py:530
#, python-format
msgid "%s of %s"
msgstr "%s di %s"
-#: ../src/jarabe/frame/activitiestray.py:657
+#: ../src/jarabe/frame/activitiestray.py:544
#, python-format
msgid "Transfer from %r"
msgstr "Trasferisci da %r"
-#: ../src/jarabe/frame/activitiestray.py:667
+#: ../src/jarabe/frame/activitiestray.py:554
msgid "Accept"
msgstr "Accetta"
-#: ../src/jarabe/frame/activitiestray.py:690
-#: ../src/jarabe/frame/activitiestray.py:817
+#: ../src/jarabe/frame/activitiestray.py:577
+#: ../src/jarabe/frame/activitiestray.py:705
#, python-format
msgid "%s (%s)"
msgstr "%s (%s)"
-#: ../src/jarabe/frame/activitiestray.py:724
-#: ../src/jarabe/frame/activitiestray.py:852
+#: ../src/jarabe/frame/activitiestray.py:611
+#: ../src/jarabe/frame/activitiestray.py:740
msgid "Dismiss"
msgstr "Abbandona"
-#: ../src/jarabe/frame/activitiestray.py:787
+#: ../src/jarabe/frame/activitiestray.py:675
#, python-format
msgid "Transfer to %r"
msgstr "Trasferisci verso %r"
-#: ../src/jarabe/frame/clipboardmenu.py:53 ../src/jarabe/view/palettes.py:221
+#: ../src/jarabe/frame/clipboardmenu.py:54 ../src/jarabe/view/palettes.py:220
msgid "Remove"
msgstr "Rimuovi"
-#: ../src/jarabe/frame/clipboardmenu.py:58
-#: ../src/jarabe/frame/clipboardmenu.py:81
+#: ../src/jarabe/frame/clipboardmenu.py:59
+#: ../src/jarabe/frame/clipboardmenu.py:82
msgid "Open"
msgstr "Apri"
-#: ../src/jarabe/frame/clipboardmenu.py:86
+#: ../src/jarabe/frame/clipboardmenu.py:87
msgid "Open with"
msgstr "Apri con"
-#: ../src/jarabe/frame/clipboardobject.py:49
+#: ../src/jarabe/frame/clipboardobject.py:50
#, python-format
msgid "%s clipping"
msgstr "ritaglio %s"
# Letterale "Vicinato", sperimentale: I miei vicini
-#: ../src/jarabe/frame/zoomtoolbar.py:37
+#: ../src/jarabe/frame/zoomtoolbar.py:38
msgid "Neighborhood"
msgstr "I miei vicini"
-#: ../src/jarabe/frame/zoomtoolbar.py:37
+#: ../src/jarabe/frame/zoomtoolbar.py:38
msgid "F1"
msgstr "F1"
-#: ../src/jarabe/frame/zoomtoolbar.py:39
+#: ../src/jarabe/frame/zoomtoolbar.py:40
msgid "F2"
msgstr "F2"
-#: ../src/jarabe/frame/zoomtoolbar.py:41
+#: ../src/jarabe/frame/zoomtoolbar.py:42
msgid "F3"
msgstr "F3"
-#: ../src/jarabe/frame/zoomtoolbar.py:43
+#: ../src/jarabe/frame/zoomtoolbar.py:44
msgid "F4"
msgstr "F4"
-#: ../src/jarabe/intro/window.py:128
+#: ../src/jarabe/intro/window.py:96
+msgid "Name:"
+msgstr "Nome:"
+
+#: ../src/jarabe/intro/window.py:132
msgid "Click to change color:"
msgstr "Seleziona per cambiare colore:"
-#: ../src/jarabe/intro/window.py:192 ../src/jarabe/journal/detailview.py:103
+#: ../src/jarabe/intro/window.py:197 ../src/jarabe/journal/detailview.py:105
msgid "Back"
msgstr "Indietro"
-#: ../src/jarabe/intro/window.py:209
+#: ../src/jarabe/intro/window.py:214
msgid "Next"
msgstr "Prossimo"
-#: ../src/jarabe/journal/expandedentry.py:152
-#: ../src/jarabe/journal/palettes.py:59
+#: ../src/jarabe/journal/expandedentry.py:154
+#: ../src/jarabe/journal/listmodel.py:144 ../src/jarabe/journal/palettes.py:59
msgid "Untitled"
msgstr "Senza titolo"
@@ -1111,6 +1285,9 @@ msgid "Kind: %s"
msgstr "Tipo: %s"
#: ../src/jarabe/journal/expandedentry.py:262
+#: ../src/jarabe/journal/listmodel.py:150
+#: ../src/jarabe/journal/listmodel.py:157
+#: ../src/jarabe/journal/listmodel.py:165
msgid "Unknown"
msgstr "Sconosciuto"
@@ -1124,114 +1301,158 @@ msgstr "Data: %s"
msgid "Size: %s"
msgstr "Dimensione: %s"
-#: ../src/jarabe/journal/expandedentry.py:286 ../src/jarabe/journal/misc.py:93
+#: ../src/jarabe/journal/expandedentry.py:292
+#: ../src/jarabe/journal/misc.py:108
msgid "No date"
msgstr "Nessuna data"
-#: ../src/jarabe/journal/expandedentry.py:293
+#: ../src/jarabe/journal/expandedentry.py:299
msgid "Participants:"
msgstr "Partecipanti:"
-#: ../src/jarabe/journal/expandedentry.py:316
+#: ../src/jarabe/journal/expandedentry.py:321
msgid "Description:"
msgstr "Descrizione:"
-#: ../src/jarabe/journal/expandedentry.py:341
+#: ../src/jarabe/journal/expandedentry.py:346
msgid "Tags:"
msgstr "Etichette:"
-#: ../src/jarabe/journal/journalactivity.py:108
-#: ../src/jarabe/journal/volumestoolbar.py:47
+#: ../src/jarabe/journal/journalactivity.py:115
+#: ../src/jarabe/journal/journaltoolbox.py:456
+#: ../src/jarabe/journal/volumestoolbar.py:50
msgid "Journal"
msgstr "Diario"
-#: ../src/jarabe/journal/journaltoolbox.py:67
+#: ../src/jarabe/journal/journaltoolbox.py:69
msgid "Search"
msgstr "Cerca"
-#: ../src/jarabe/journal/journaltoolbox.py:126
+#: ../src/jarabe/journal/journaltoolbox.py:136
msgid "Anytime"
msgstr "Sempre"
-#: ../src/jarabe/journal/journaltoolbox.py:128
+#: ../src/jarabe/journal/journaltoolbox.py:138
msgid "Today"
msgstr "Oggi"
-#: ../src/jarabe/journal/journaltoolbox.py:130
+#: ../src/jarabe/journal/journaltoolbox.py:140
msgid "Since yesterday"
msgstr "Da ieri"
# TRANS: Filter entries modified during the last 7 days.
#. TRANS: Filter entries modified during the last 7 days.
-#: ../src/jarabe/journal/journaltoolbox.py:132
+#: ../src/jarabe/journal/journaltoolbox.py:142
msgid "Past week"
msgstr "Settimana scorsa"
# TRANS: Filter entries modified during the last 30 days.
#. TRANS: Filter entries modified during the last 30 days.
-#: ../src/jarabe/journal/journaltoolbox.py:134
+#: ../src/jarabe/journal/journaltoolbox.py:144
msgid "Past month"
msgstr "Mese scorso"
# TRANS: Filter entries modified during the last 356 days.
#. TRANS: Filter entries modified during the last 356 days.
-#: ../src/jarabe/journal/journaltoolbox.py:136
+#: ../src/jarabe/journal/journaltoolbox.py:146
msgid "Past year"
msgstr "Anno scorso"
-#: ../src/jarabe/journal/journaltoolbox.py:143
+#: ../src/jarabe/journal/journaltoolbox.py:153
msgid "Anyone"
msgstr "Tutti"
-#: ../src/jarabe/journal/journaltoolbox.py:145
+#: ../src/jarabe/journal/journaltoolbox.py:155
msgid "My friends"
msgstr "I miei amici"
-#: ../src/jarabe/journal/journaltoolbox.py:146
+#: ../src/jarabe/journal/journaltoolbox.py:156
msgid "My class"
msgstr "La mia classe"
# TRANS: Item in a combo box that filters by entry type.
-#: ../src/jarabe/journal/journaltoolbox.py:274
+#: ../src/jarabe/journal/journaltoolbox.py:298
msgid "Anything"
msgstr "Qualsiasi"
# TODO: Add "Start with" menu item
-#: ../src/jarabe/journal/journaltoolbox.py:350
-#: ../src/jarabe/journal/palettes.py:83
+#: ../src/jarabe/journal/journaltoolbox.py:381
+#: ../src/jarabe/journal/palettes.py:90
msgid "Copy"
msgstr "Copia"
+#: ../src/jarabe/journal/journaltoolbox.py:436
+#: ../src/jarabe/journal/volumestoolbar.py:157
+msgid "Entries without a file cannot be copied."
+msgstr "Elementi senza file non possono essere copiati"
+
+#: ../src/jarabe/journal/journaltoolbox.py:445
+#: ../src/jarabe/journal/volumestoolbar.py:166
+#, python-format
+msgid "Error while copying the entry. %s"
+msgstr "Errore durante la copia dell'elemento. %s"
+
+#: ../src/jarabe/journal/journaltoolbox.py:446
+#: ../src/jarabe/journal/volumestoolbar.py:167
+msgid "Error"
+msgstr "Errore"
+
# TRANS: Action label for starting an entry.
#. TRANS: Action label for starting an entry.
-#: ../src/jarabe/journal/journaltoolbox.py:431
-#: ../src/jarabe/journal/palettes.py:68
+#: ../src/jarabe/journal/journaltoolbox.py:488
+#: ../src/jarabe/journal/palettes.py:69
msgid "Start"
msgstr "Avvia"
-#: ../src/jarabe/journal/listview.py:373
+#: ../src/jarabe/journal/journaltoolbox.py:516
+msgid "Sort by date modified"
+msgstr ""
+
+#: ../src/jarabe/journal/journaltoolbox.py:517
+msgid "Sort by date created"
+msgstr ""
+
+#: ../src/jarabe/journal/journaltoolbox.py:518
+msgid "Sort by size"
+msgstr ""
+
+#: ../src/jarabe/journal/journaltoolbox.py:527
+msgid "Sort view"
+msgstr ""
+
+#: ../src/jarabe/journal/listview.py:380
msgid "Your Journal is empty"
msgstr "Il tuo Diario è vuoto"
-#: ../src/jarabe/journal/listview.py:375
+#: ../src/jarabe/journal/listview.py:382
msgid "No matching entries"
msgstr "Non ci sono registrazioni corrispondenti"
-#: ../src/jarabe/journal/listview.py:386
+#: ../src/jarabe/journal/listview.py:393
msgid "Clear search"
msgstr "Annulla ricerca"
-#: ../src/jarabe/journal/modalalert.py:63
+#: ../src/jarabe/journal/misc.py:273
+#, python-format
+msgid "Older Version Of %s Activity"
+msgstr ""
+
+#: ../src/jarabe/journal/misc.py:274
+#, python-format
+msgid "Do you want to downgrade to version %s "
+msgstr ""
+
+#: ../src/jarabe/journal/modalalert.py:64
msgid "Your Journal is full"
msgstr "Il tuo Diario è pieno"
-#: ../src/jarabe/journal/modalalert.py:67
+#: ../src/jarabe/journal/modalalert.py:68
msgid "Please delete some old Journal entries to make space for new ones."
msgstr ""
"Per favore cancella alcune registrazioni vecchie dal Diario per far spazio "
"alle nuove."
-#: ../src/jarabe/journal/modalalert.py:79
+#: ../src/jarabe/journal/modalalert.py:80
msgid "Show Journal"
msgstr "Apri il Diario"
@@ -1240,110 +1461,311 @@ msgid "Choose an object"
msgstr "Scegli un oggetto"
#: ../src/jarabe/journal/objectchooser.py:151
-#: ../src/jarabe/view/viewsource.py:308
+#: ../src/jarabe/view/viewsource.py:311
msgid "Close"
msgstr "Chiudi"
-#: ../src/jarabe/journal/palettes.py:66
+#: ../src/jarabe/journal/palettes.py:67
msgid "Resume with"
msgstr "Riprendi con"
-#: ../src/jarabe/journal/palettes.py:69
+#: ../src/jarabe/journal/palettes.py:70
msgid "Start with"
msgstr "Inizia con"
-#: ../src/jarabe/journal/palettes.py:91
+#: ../src/jarabe/journal/palettes.py:83 ../src/jarabe/journal/palettes.py:216
+msgid "No activity to start entry"
+msgstr "Attività per riprendere la sessione non presente"
+
+#: ../src/jarabe/journal/palettes.py:98
msgid "Send to"
msgstr "Invia a"
-#: ../src/jarabe/journal/palettes.py:100
+#: ../src/jarabe/journal/palettes.py:107
msgid "View Details"
msgstr "Visualizza Dettagli"
-#: ../src/jarabe/journal/palettes.py:178
+#: ../src/jarabe/journal/palettes.py:181
msgid "No friends present"
msgstr "Non ci sono amici presenti"
-#: ../src/jarabe/journal/palettes.py:183
+#: ../src/jarabe/journal/palettes.py:186
msgid "No valid connection found"
msgstr "Connessione non trovata"
-#: ../src/jarabe/journal/palettes.py:211
+#: ../src/jarabe/journal/palettes.py:214
msgid "No activity to resume entry"
msgstr "Sessione dell'Attività da riprendere non presente"
-#: ../src/jarabe/journal/palettes.py:213
-msgid "No activity to start entry"
-msgstr "Attività per riprendere la sessione non presente"
+#: ../src/jarabe/model/network.py:158
+msgid "The reason for the device state change is unknown."
+msgstr ""
+
+#: ../src/jarabe/model/network.py:160
+msgid "The state change is normal."
+msgstr ""
+
+#: ../src/jarabe/model/network.py:162
+msgid "The device is now managed."
+msgstr ""
+
+#: ../src/jarabe/model/network.py:164
+msgid "The device is no longer managed."
+msgstr ""
+
+#: ../src/jarabe/model/network.py:166
+msgid "The device could not be readied for configuration."
+msgstr ""
+
+#: ../src/jarabe/model/network.py:168
+msgid ""
+"IP configuration could not be reserved (no available address, timeout, etc)."
+msgstr ""
+
+#: ../src/jarabe/model/network.py:171
+msgid "The IP configuration is no longer valid."
+msgstr ""
+
+#: ../src/jarabe/model/network.py:173
+msgid "Secrets were required, but not provided."
+msgstr ""
+
+#: ../src/jarabe/model/network.py:175
+msgid ""
+"The 802.1X supplicant disconnected from the access point or authentication "
+"server."
+msgstr ""
+
+#: ../src/jarabe/model/network.py:178
+msgid "Configuration of the 802.1X supplicant failed."
+msgstr ""
+
+#: ../src/jarabe/model/network.py:180
+msgid "The 802.1X supplicant quit or failed unexpectedly."
+msgstr ""
+
+#: ../src/jarabe/model/network.py:182
+msgid "The 802.1X supplicant took too long to authenticate."
+msgstr ""
-#: ../src/jarabe/view/buddymenu.py:62
+#: ../src/jarabe/model/network.py:184
+msgid "The PPP service failed to start within the allowed time."
+msgstr ""
+
+#: ../src/jarabe/model/network.py:186
+msgid "The PPP service disconnected unexpectedly."
+msgstr ""
+
+#: ../src/jarabe/model/network.py:188
+msgid "The PPP service quit or failed unexpectedly."
+msgstr ""
+
+#: ../src/jarabe/model/network.py:190
+msgid "The DHCP service failed to start within the allowed time."
+msgstr ""
+
+#: ../src/jarabe/model/network.py:192
+msgid "The DHCP service reported an unexpected error."
+msgstr ""
+
+#: ../src/jarabe/model/network.py:194
+msgid "The DHCP service quit or failed unexpectedly."
+msgstr ""
+
+#: ../src/jarabe/model/network.py:196
+msgid "The shared connection service failed to start."
+msgstr ""
+
+#: ../src/jarabe/model/network.py:198
+msgid "The shared connection service quit or failed unexpectedly."
+msgstr ""
+
+#: ../src/jarabe/model/network.py:201
+msgid "The AutoIP service failed to start."
+msgstr ""
+
+#: ../src/jarabe/model/network.py:203
+msgid "The AutoIP service reported an unexpected error."
+msgstr ""
+
+#: ../src/jarabe/model/network.py:205
+msgid "The AutoIP service quit or failed unexpectedly."
+msgstr ""
+
+#: ../src/jarabe/model/network.py:207
+msgid "Dialing failed because the line was busy."
+msgstr ""
+
+#: ../src/jarabe/model/network.py:209
+msgid "Dialing failed because there was no dial tone."
+msgstr ""
+
+#: ../src/jarabe/model/network.py:211
+msgid "Dialing failed because there was no carrier."
+msgstr ""
+
+#: ../src/jarabe/model/network.py:213
+msgid "Dialing timed out."
+msgstr ""
+
+#: ../src/jarabe/model/network.py:215
+msgid "Dialing failed."
+msgstr ""
+
+#: ../src/jarabe/model/network.py:217
+msgid "Modem initialization failed."
+msgstr ""
+
+#: ../src/jarabe/model/network.py:219
+msgid "Failed to select the specified GSM APN"
+msgstr ""
+
+#: ../src/jarabe/model/network.py:221
+msgid "Not searching for networks."
+msgstr ""
+
+#: ../src/jarabe/model/network.py:223
+msgid "Network registration was denied."
+msgstr ""
+
+#: ../src/jarabe/model/network.py:225
+msgid "Network registration timed out."
+msgstr ""
+
+#: ../src/jarabe/model/network.py:227
+msgid "Failed to register with the requested GSM network."
+msgstr ""
+
+#: ../src/jarabe/model/network.py:229
+msgid "PIN check failed."
+msgstr ""
+
+#: ../src/jarabe/model/network.py:231
+msgid "Necessary firmware for the device may be missing."
+msgstr ""
+
+#: ../src/jarabe/model/network.py:233
+msgid "The device was removed."
+msgstr ""
+
+#: ../src/jarabe/model/network.py:235
+msgid "NetworkManager went to sleep."
+msgstr ""
+
+#: ../src/jarabe/model/network.py:237
+msgid "The device's active connection was removed or disappeared."
+msgstr ""
+
+#: ../src/jarabe/model/network.py:240
+msgid "A user or client requested the disconnection."
+msgstr ""
+
+#: ../src/jarabe/model/network.py:242
+msgid "The device's carrier/link changed."
+msgstr ""
+
+#: ../src/jarabe/view/buddymenu.py:63
msgid "Remove friend"
msgstr "Rimuovi l'amico"
-#: ../src/jarabe/view/buddymenu.py:65
+#: ../src/jarabe/view/buddymenu.py:66
msgid "Make friend"
msgstr "Aggiungi agli amici"
-#: ../src/jarabe/view/buddymenu.py:82
+#: ../src/jarabe/view/buddymenu.py:83
msgid "Shutdown"
msgstr "Spegni"
-#: ../src/jarabe/view/buddymenu.py:90
+#: ../src/jarabe/view/buddymenu.py:91
+msgid "Restart"
+msgstr "Riavvia"
+
+#: ../src/jarabe/view/buddymenu.py:97
msgid "Logout"
msgstr "Disconnessione"
-#: ../src/jarabe/view/buddymenu.py:95
+#: ../src/jarabe/view/buddymenu.py:102
msgid "My Settings"
msgstr "Le mie Preferenze"
-#: ../src/jarabe/view/buddymenu.py:130
+#: ../src/jarabe/view/buddymenu.py:137
#, python-format
msgid "Invite to %s"
msgstr "Invito per %s"
-#: ../src/jarabe/view/palettes.py:45
+#: ../src/jarabe/view/launcher.py:190
+#, python-format
+msgid "<b>%s</b> failed to start."
+msgstr ""
+
+#: ../src/jarabe/view/palettes.py:46
msgid "Starting..."
msgstr "Inizio..."
+#: ../src/jarabe/view/palettes.py:56
+msgid "Activity failed to start"
+msgstr ""
+
#. TODO: share-with, keep
-#: ../src/jarabe/view/palettes.py:74
+#: ../src/jarabe/view/palettes.py:85
msgid "View Source"
msgstr "Visualizza Sorgente"
-#: ../src/jarabe/view/palettes.py:85
+#: ../src/jarabe/view/palettes.py:96
msgid "Stop"
msgstr "Chiudi"
-#: ../src/jarabe/view/palettes.py:125
+#: ../src/jarabe/view/palettes.py:132
msgid "Start new"
msgstr "Inizia nuovo"
-#: ../src/jarabe/view/palettes.py:174
+#: ../src/jarabe/view/palettes.py:172
msgid "Show contents"
msgstr "Mostra i contenuti"
-#: ../src/jarabe/view/palettes.py:196 ../src/jarabe/view/palettes.py:246
+#: ../src/jarabe/view/palettes.py:194 ../src/jarabe/view/palettes.py:245
#, python-format
msgid "%(free_space)d MB Free"
msgstr "%(free_space)d MB Liberi"
-#: ../src/jarabe/view/viewsource.py:208
+#: ../src/jarabe/view/viewsource.py:211
msgid "Instance Source"
msgstr "Sorgente Istanza"
-#: ../src/jarabe/view/viewsource.py:233
+#: ../src/jarabe/view/viewsource.py:236
msgid "Source"
msgstr "Sorgente"
-#: ../src/jarabe/view/viewsource.py:292
+#: ../src/jarabe/view/viewsource.py:295
msgid "Activity Bundle Source"
msgstr "Sorgente della Attività"
-#: ../src/jarabe/view/viewsource.py:299
+#: ../src/jarabe/view/viewsource.py:302
#, python-format
msgid "View source: %r"
msgstr "Vedi codice sorgente: %r"
+#: ../src/jarabe/util/emulator.py:40
+msgid "Sugar in a window"
+msgstr ""
+
+#~ msgid "APN:"
+#~ msgstr "APN:"
+
+#~ msgid "Create new wireless network"
+#~ msgstr "Crea una nuova rete wireless"
+
+#, python-format
+#~ msgid "%s's network"
+#~ msgstr "rete di %s"
+
+#, python-format
+#~ msgid "Data sent %d kb / received %d kb"
+#~ msgstr "Dati %d kb inviati / %d kb ricevuti"
+
+#~ msgid "Connection time "
+#~ msgstr "Tempo di connessione"
+
#~ msgid "Title"
#~ msgstr "Titolo"
@@ -1359,9 +1781,6 @@ msgstr "Vedi codice sorgente: %r"
#~ msgid "Unmount"
#~ msgstr "Rimuovi"
-#~ msgid "Restart"
-#~ msgstr "Riavvia"
-
#~ msgid ""
#~ "© 2008 One Laptop per Child Association Inc; Red Hat Inc; and Contributors."
#~ msgstr ""
diff --git a/src/jarabe/__init__.py b/src/jarabe/__init__.py
index 41b4b1c..ed2f639 100644
--- a/src/jarabe/__init__.py
+++ b/src/jarabe/__init__.py
@@ -23,4 +23,3 @@ refer to a command-line "shell" interface.
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
-
diff --git a/src/jarabe/config.py.in b/src/jarabe/config.py.in
index 6c418e9..d22ee9a 100644
--- a/src/jarabe/config.py.in
+++ b/src/jarabe/config.py.in
@@ -14,7 +14,7 @@
# along with this program; if not, write to the Free Software
# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
-# pylint: disable-msg=C0301
+# pylint: disable=C0301
prefix = '@prefix@'
data_path = '@prefix@/share/sugar/data'
diff --git a/src/jarabe/controlpanel/__init__.py b/src/jarabe/controlpanel/__init__.py
index a9dd95a..85f6a24 100644
--- a/src/jarabe/controlpanel/__init__.py
+++ b/src/jarabe/controlpanel/__init__.py
@@ -13,4 +13,3 @@
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
-
diff --git a/src/jarabe/controlpanel/cmd.py b/src/jarabe/controlpanel/cmd.py
index 7144b33..fe8f1a4 100644
--- a/src/jarabe/controlpanel/cmd.py
+++ b/src/jarabe/controlpanel/cmd.py
@@ -18,20 +18,21 @@ import sys
import getopt
import os
from gettext import gettext as _
-import traceback
import logging
from jarabe import config
+
_RESTART = 1
-_same_option_warning = _("sugar-control-panel: WARNING, found more than"
- " one option with the same name: %s module: %r")
-_no_option_error = _("sugar-control-panel: key=%s not an available option")
-_general_error = _("sugar-control-panel: %s")
+_same_option_warning = _('sugar-control-panel: WARNING, found more than one'
+ ' option with the same name: %s module: %r')
+_no_option_error = _('sugar-control-panel: key=%s not an available option')
+_general_error = _('sugar-control-panel: %s')
+
def cmd_help():
- '''Print the help to the screen'''
+ """Print the help to the screen"""
# TRANS: Translators, there's a empty line at the end of this string,
# which must appear in the translated string (msgstr) as well.
print _('Usage: sugar-control-panel [ option ] key [ args ... ] \n\
@@ -45,14 +46,16 @@ def cmd_help():
-c key clear the current value for the key \n\
')
+
def note_restart():
- '''Instructions how to restart sugar'''
+ """Instructions how to restart sugar"""
print _('To apply your changes you have to restart sugar.\n' +
'Hit ctrl+alt+erase on the keyboard to trigger a restart.')
+
def load_modules():
- '''Build a list of pointers to available modules and import them.
- '''
+ """Build a list of pointers to available modules and import them.
+ """
modules = []
path = os.path.join(config.ext_path, 'cpsection')
@@ -65,16 +68,16 @@ def load_modules():
module = __import__('.'.join(('cpsection', item, 'model')),
globals(), locals(), ['model'])
except Exception:
- logging.error('Exception while loading extension:\n' + \
- ''.join(traceback.format_exception(*sys.exc_info())))
+ logging.exception('Exception while loading extension:')
else:
modules.append(module)
return modules
+
def main():
try:
- options, args = getopt.getopt(sys.argv[1:], "h:s:g:c:l", [])
+ options, args = getopt.getopt(sys.argv[1:], 'h:s:g:c:l', [])
except getopt.GetoptError:
cmd_help()
sys.exit(2)
@@ -87,7 +90,7 @@ def main():
for option, key in options:
found = 0
- if option in ("-h"):
+ if option in ('-h'):
for module in modules:
method = getattr(module, 'set_' + key, None)
if method:
@@ -98,7 +101,7 @@ def main():
print _(_same_option_warning % (key, module))
if found == 0:
print _(_no_option_error % key)
- if option in ("-l"):
+ if option in ('-l'):
for module in modules:
methods = dir(module)
print '%s:' % module.__name__.split('.')[1]
@@ -106,9 +109,9 @@ def main():
if method.startswith('get_'):
print ' %s' % method[4:]
elif method.startswith('clear_'):
- print " %s (use the -c argument with this option)" \
+ print ' %s (use the -c argument with this option)' \
% method[6:]
- if option in ("-g"):
+ if option in ('-g'):
for module in modules:
method = getattr(module, 'print_' + key, None)
if method:
@@ -122,7 +125,7 @@ def main():
print _(_same_option_warning % (key, module))
if found == 0:
print _(_no_option_error % key)
- if option in ("-s"):
+ if option in ('-s'):
for module in modules:
method = getattr(module, 'set_' + key, None)
if method:
@@ -139,7 +142,7 @@ def main():
print _(_same_option_warning % (key, module))
if found == 0:
print _(_no_option_error % key)
- if option in ("-c"):
+ if option in ('-c'):
for module in modules:
method = getattr(module, 'clear_' + key, None)
if method:
diff --git a/src/jarabe/controlpanel/gui.py b/src/jarabe/controlpanel/gui.py
index 51d9820..2f55951 100644
--- a/src/jarabe/controlpanel/gui.py
+++ b/src/jarabe/controlpanel/gui.py
@@ -17,8 +17,6 @@
import os
import logging
from gettext import gettext as _
-import sys
-import traceback
import gobject
import gtk
@@ -32,8 +30,9 @@ from jarabe.controlpanel.toolbar import MainToolbar
from jarabe.controlpanel.toolbar import SectionToolbar
from jarabe import config
+
_logger = logging.getLogger('ControlPanel')
-_MAX_COLUMNS = 5
+
class ControlPanel(gtk.Window):
__gtype_name__ = 'SugarControlPanel'
@@ -41,6 +40,9 @@ class ControlPanel(gtk.Window):
def __init__(self):
gtk.Window.__init__(self)
+ self._max_columns = int(0.285 * (float(gtk.gdk.screen_width()) /
+ style.GRID_CELL_SIZE - 3))
+
self.set_border_width(style.LINE_WIDTH)
offset = style.GRID_CELL_SIZE
width = gtk.gdk.screen_width() - offset * 2
@@ -74,7 +76,7 @@ class ControlPanel(gtk.Window):
self.add(self._vbox)
self._vbox.show()
- self.connect("realize", self.__realize_cb)
+ self.connect('realize', self.__realize_cb)
self._options = self._get_options()
self._current_option = None
@@ -110,6 +112,7 @@ class ControlPanel(gtk.Window):
self._table = gtk.Table()
self._table.set_col_spacings(style.GRID_CELL_SIZE)
+ self._table.set_row_spacings(style.GRID_CELL_SIZE)
self._table.set_border_width(style.GRID_CELL_SIZE)
self._scrolledwindow = gtk.ScrolledWindow()
@@ -134,8 +137,17 @@ class ControlPanel(gtk.Window):
except ImportError:
del self._options['keyboard']
- row = 0
- column = 2
+ # If the screen width only supports two columns, start
+ # placing from the second row.
+ if self._max_columns == 2:
+ row = 1
+ column = 0
+ else:
+ # About Me and About my computer are hardcoded below to use the
+ # first two slots so we need to leave them free.
+ row = 0
+ column = 2
+
options = self._options.keys()
options.sort()
@@ -157,7 +169,7 @@ class ControlPanel(gtk.Window):
column, column + 1,
row, row + 1)
column += 1
- if column == _MAX_COLUMNS:
+ if column == self._max_columns:
column = 0
row += 1
@@ -214,11 +226,16 @@ class ControlPanel(gtk.Window):
globals(), locals(), ['model'])
model = ModelWrapper(mod)
- self._section_view = view_class(model,
- self._options[option]['alerts'])
+ try:
+ self.get_window().set_cursor(gtk.gdk.Cursor(gtk.gdk.WATCH))
+ self._section_view = view_class(model,
+ self._options[option]['alerts'])
+
+ self._set_canvas(self._section_view)
+ self._section_view.show()
+ finally:
+ self.get_window().set_cursor(None)
- self._set_canvas(self._section_view)
- self._section_view.show()
self._section_view.connect('notify::is-valid',
self.__valid_section_cb)
self._section_view.connect('request-close',
@@ -227,13 +244,13 @@ class ControlPanel(gtk.Window):
style.COLOR_WHITE.get_gdk_color())
def set_section_view_auto_close(self):
- '''Automatically close the control panel if there is "nothing to do"
- '''
+ """Automatically close the control panel if there is "nothing to do"
+ """
self._section_view.auto_close = True
def _get_options(self):
- '''Get the available option information from the extensions
- '''
+ """Get the available option information from the extensions
+ """
options = {}
path = os.path.join(config.ext_path, 'cpsection')
@@ -259,11 +276,9 @@ class ControlPanel(gtk.Window):
keywords.append(item)
options[item]['keywords'] = keywords
else:
- _logger.error('There is no CLASS constant specifieds ' \
- 'in the view file \'%s\'.' % item)
+ _logger.error('no CLASS attribute in %r', item)
except Exception:
- logging.error('Exception while loading extension:\n' + \
- ''.join(traceback.format_exception(*sys.exc_info())))
+ logging.exception('Exception while loading extension:')
return options
@@ -333,6 +348,7 @@ class ControlPanel(gtk.Window):
section_is_valid = section_view.props.is_valid
self._section_toolbar.accept_button.set_sensitive(section_is_valid)
+
class ModelWrapper(object):
def __init__(self, module):
self._module = module
@@ -360,18 +376,15 @@ class ModelWrapper(object):
except Exception, detail:
_logger.debug('Error undo option: %s', detail)
+
class _SectionIcon(gtk.EventBox):
- __gtype_name__ = "SugarSectionIcon"
+ __gtype_name__ = 'SugarSectionIcon'
__gproperties__ = {
- 'icon-name' : (str, None, None, None,
- gobject.PARAM_READWRITE),
- 'pixel-size' : (object, None, None,
- gobject.PARAM_READWRITE),
- 'xo-color' : (object, None, None,
- gobject.PARAM_READWRITE),
- 'title' : (str, None, None, None,
- gobject.PARAM_READWRITE)
+ 'icon-name': (str, None, None, None, gobject.PARAM_READWRITE),
+ 'pixel-size': (object, None, None, gobject.PARAM_READWRITE),
+ 'xo-color': (object, None, None, gobject.PARAM_READWRITE),
+ 'title': (str, None, None, None, gobject.PARAM_READWRITE),
}
def __init__(self, **kwargs):
diff --git a/src/jarabe/controlpanel/inlinealert.py b/src/jarabe/controlpanel/inlinealert.py
index b1880da..f970af4 100644
--- a/src/jarabe/controlpanel/inlinealert.py
+++ b/src/jarabe/controlpanel/inlinealert.py
@@ -21,6 +21,7 @@ import pango
from sugar.graphics import style
from sugar.graphics.icon import Icon
+
class InlineAlert(gtk.HBox):
"""UI interface for Inline alerts
@@ -36,11 +37,9 @@ class InlineAlert(gtk.HBox):
__gtype_name__ = 'SugarInlineAlert'
__gproperties__ = {
- 'msg' : (str, None, None, None,
- gobject.PARAM_READWRITE),
- 'icon' : (object, None, None,
- gobject.PARAM_WRITABLE)
- }
+ 'msg': (str, None, None, None, gobject.PARAM_READWRITE),
+ 'icon': (object, None, None, gobject.PARAM_WRITABLE),
+ }
def __init__(self, **kwargs):
@@ -80,4 +79,3 @@ class InlineAlert(gtk.HBox):
def do_get_property(self, pspec):
if pspec.name == 'msg':
return self._msg
-
diff --git a/src/jarabe/controlpanel/sectionview.py b/src/jarabe/controlpanel/sectionview.py
index 4de27a2..4b5751f 100644
--- a/src/jarabe/controlpanel/sectionview.py
+++ b/src/jarabe/controlpanel/sectionview.py
@@ -18,18 +18,17 @@ import gobject
import gtk
from gettext import gettext as _
+
class SectionView(gtk.VBox):
__gtype_name__ = 'SugarSectionView'
__gsignals__ = {
- 'request-close': (gobject.SIGNAL_RUN_FIRST,
- gobject.TYPE_NONE, ([]))
- }
+ 'request-close': (gobject.SIGNAL_RUN_FIRST, gobject.TYPE_NONE, ([])),
+ }
__gproperties__ = {
- 'is_valid' : (bool, None, None, True,
- gobject.PARAM_READWRITE)
- }
+ 'is_valid': (bool, None, None, True, gobject.PARAM_READWRITE),
+ }
_APPLY_TIMEOUT = 1000
@@ -51,5 +50,5 @@ class SectionView(gtk.VBox):
return self._is_valid
def undo(self):
- '''Undo here the changes that have been made in this section.'''
+ """Undo here the changes that have been made in this section."""
pass
diff --git a/src/jarabe/controlpanel/toolbar.py b/src/jarabe/controlpanel/toolbar.py
index 320a8eb..fca34a0 100644
--- a/src/jarabe/controlpanel/toolbar.py
+++ b/src/jarabe/controlpanel/toolbar.py
@@ -25,6 +25,7 @@ from sugar.graphics.toolbutton import ToolButton
from sugar.graphics import iconentry
from sugar.graphics import style
+
class MainToolbar(gtk.Toolbar):
""" Main toolbar of the control panel
"""
@@ -36,8 +37,9 @@ class MainToolbar(gtk.Toolbar):
([])),
'search-changed': (gobject.SIGNAL_RUN_FIRST,
gobject.TYPE_NONE,
- ([str]))
+ ([str])),
}
+
def __init__(self):
gtk.Toolbar.__init__(self)
@@ -83,6 +85,7 @@ class MainToolbar(gtk.Toolbar):
def __stop_clicked_cb(self, button):
self.emit('stop-clicked')
+
class SectionToolbar(gtk.Toolbar):
""" Toolbar of the sections of the control panel
"""
@@ -94,8 +97,9 @@ class SectionToolbar(gtk.Toolbar):
([])),
'accept-clicked': (gobject.SIGNAL_RUN_FIRST,
gobject.TYPE_NONE,
- ([]))
+ ([])),
}
+
def __init__(self):
gtk.Toolbar.__init__(self)
@@ -154,4 +158,3 @@ class SectionToolbar(gtk.Toolbar):
def __accept_button_clicked_cb(self, widget, data=None):
self.emit('accept-clicked')
-
diff --git a/src/jarabe/desktop/__init__.py b/src/jarabe/desktop/__init__.py
index a9dd95a..85f6a24 100644
--- a/src/jarabe/desktop/__init__.py
+++ b/src/jarabe/desktop/__init__.py
@@ -13,4 +13,3 @@
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
-
diff --git a/src/jarabe/desktop/activitieslist.py b/src/jarabe/desktop/activitieslist.py
index 56b3b5f..0370ef3 100644
--- a/src/jarabe/desktop/activitieslist.py
+++ b/src/jarabe/desktop/activitieslist.py
@@ -30,20 +30,18 @@ from sugar.graphics.icon import Icon, CellRendererIcon
from sugar.graphics.xocolor import XoColor
from sugar.graphics.menuitem import MenuItem
from sugar.graphics.alert import Alert
-from sugar.activity import activityfactory
-from sugar.activity.activityhandle import ActivityHandle
from jarabe.model import bundleregistry
from jarabe.view.palettes import ActivityPalette
-from jarabe.view import launcher
from jarabe.journal import misc
+
class ActivitiesTreeView(gtk.TreeView):
__gtype_name__ = 'SugarActivitiesTreeView'
__gsignals__ = {
- 'erase-activated' : (gobject.SIGNAL_RUN_FIRST,
- gobject.TYPE_NONE, ([str]))
+ 'erase-activated': (gobject.SIGNAL_RUN_FIRST, gobject.TYPE_NONE,
+ ([str])),
}
def __init__(self):
@@ -154,6 +152,7 @@ class ActivitiesTreeView(gtk.TreeView):
title = model[tree_iter][ListModel.COLUMN_TITLE]
return title is not None and title.lower().find(self._query) > -1
+
class ListModel(gtk.TreeModelSort):
__gtype_name__ = 'SugarListModel'
@@ -167,7 +166,7 @@ class ListModel(gtk.TreeModelSort):
COLUMN_DATE_TEXT = 7
def __init__(self):
- self._model = gtk.ListStore(str, bool, str, str, int, str, int, str)
+ self._model = gtk.ListStore(str, bool, str, str, str, str, int, str)
self._model_filter = self._model.filter_new()
gtk.TreeModelSort.__init__(self, self._model_filter)
@@ -238,6 +237,7 @@ class ListModel(gtk.TreeModelSort):
def refilter(self):
self._model_filter.refilter()
+
class CellRendererFavorite(CellRendererIcon):
__gtype_name__ = 'SugarCellRendererFavorite'
@@ -252,12 +252,13 @@ class CellRendererFavorite(CellRendererIcon):
self.props.prelit_stroke_color = style.COLOR_BUTTON_GREY.get_svg()
self.props.prelit_fill_color = style.COLOR_BUTTON_GREY.get_svg()
+
class CellRendererActivityIcon(CellRendererIcon):
__gtype_name__ = 'SugarCellRendererActivityIcon'
__gsignals__ = {
- 'erase-activated' : (gobject.SIGNAL_RUN_FIRST,
- gobject.TYPE_NONE, ([str]))
+ 'erase-activated': (gobject.SIGNAL_RUN_FIRST, gobject.TYPE_NONE,
+ ([str])),
}
def __init__(self, tree_view):
@@ -290,6 +291,7 @@ class CellRendererActivityIcon(CellRendererIcon):
def __erase_activated_cb(self, palette, bundle_id):
self.emit('erase-activated', bundle_id)
+
class ActivitiesList(gtk.VBox):
__gtype_name__ = 'SugarActivitiesList'
@@ -373,12 +375,13 @@ class ActivitiesList(gtk.VBox):
bundle = registry.get_bundle(bundle_id)
registry.uninstall(bundle, delete_profile=True)
+
class ActivityListPalette(ActivityPalette):
__gtype_name__ = 'SugarActivityListPalette'
__gsignals__ = {
- 'erase-activated' : (gobject.SIGNAL_RUN_FIRST,
- gobject.TYPE_NONE, ([str]))
+ 'erase-activated': (gobject.SIGNAL_RUN_FIRST, gobject.TYPE_NONE,
+ ([str])),
}
def __init__(self, activity_info):
@@ -417,8 +420,8 @@ class ActivityListPalette(ActivityPalette):
menu_item.show()
if not os.access(activity_info.get_path(), os.W_OK) or \
- registry.is_activity_protected(self._bundle_id):
- menu_item.props.sensitive = False
+ registry.is_activity_protected(self._bundle_id):
+ menu_item.props.sensitive = False
def __destroy_cb(self, palette):
self.disconnect(self._activity_changed_sid)
@@ -432,7 +435,7 @@ class ActivityListPalette(ActivityPalette):
else:
label.set_text(_('Make favorite'))
client = gconf.client_get_default()
- xo_color = XoColor(client.get_string("/desktop/sugar/user/color"))
+ xo_color = XoColor(client.get_string('/desktop/sugar/user/color'))
self._favorite_icon.props.xo_color = xo_color
@@ -452,4 +455,3 @@ class ActivityListPalette(ActivityPalette):
def __erase_activate_cb(self, menu_item):
self.emit('erase-activated', self._bundle_id)
-
diff --git a/src/jarabe/desktop/favoriteslayout.py b/src/jarabe/desktop/favoriteslayout.py
index 7b847ac..360c147 100644
--- a/src/jarabe/desktop/favoriteslayout.py
+++ b/src/jarabe/desktop/favoriteslayout.py
@@ -29,6 +29,7 @@ from sugar.graphics import style
from jarabe.model import bundleregistry
from jarabe.desktop.grid import Grid
+
_logger = logging.getLogger('FavoritesLayout')
_CELL_SIZE = 4
@@ -89,7 +90,8 @@ class FavoritesLayout(gobject.GObject, hippo.CanvasLayout):
if icon not in self.box.get_children():
raise ValueError('Child not in box.')
- if not(hasattr(icon, 'get_bundle_id') and hasattr(icon, 'get_version')):
+ if not (hasattr(icon, 'get_bundle_id') and
+ hasattr(icon, 'get_version')):
logging.debug('Not an activity icon %r', icon)
return
@@ -109,6 +111,7 @@ class FavoritesLayout(gobject.GObject, hippo.CanvasLayout):
def allow_dnd(self):
return False
+
class RandomLayout(FavoritesLayout):
"""Lay out icons randomly; try to nudge them around to resolve overlaps."""
@@ -189,6 +192,7 @@ class RandomLayout(FavoritesLayout):
def allow_dnd(self):
return True
+
_MINIMUM_RADIUS = style.XLARGE_ICON_SIZE / 2 + style.DEFAULT_SPACING + \
style.STANDARD_ICON_SIZE * 2
_MAXIMUM_RADIUS = (gtk.gdk.screen_height() - style.GRID_CELL_SIZE) / 2 - \
@@ -239,32 +243,34 @@ class RingLayout(FavoritesLayout):
self._spiral_mode = False
distance = style.MEDIUM_ICON_SIZE + style.DEFAULT_SPACING * \
_ICON_SPACING_FACTORS[_ICON_SIZES.index(style.MEDIUM_ICON_SIZE)]
- radius = max(children_count * distance / (2 * math.pi), _MINIMUM_RADIUS)
+ radius = max(children_count * distance / (2 * math.pi),
+ _MINIMUM_RADIUS)
if radius < _MAXIMUM_RADIUS:
return radius, style.MEDIUM_ICON_SIZE
distance = style.STANDARD_ICON_SIZE + style.DEFAULT_SPACING * \
_ICON_SPACING_FACTORS[_ICON_SIZES.index(style.STANDARD_ICON_SIZE)]
- radius = max(children_count * distance / (2 * math.pi), _MINIMUM_RADIUS)
+ radius = max(children_count * distance / (2 * math.pi),
+ _MINIMUM_RADIUS)
if radius < _MAXIMUM_RADIUS:
return radius, style.STANDARD_ICON_SIZE
self._spiral_mode = True
icon_size = style.STANDARD_ICON_SIZE
- angle, radius = self._calculate_angle_and_radius(children_count,
- icon_size)
+ angle_, radius = self._calculate_angle_and_radius(children_count,
+ icon_size)
while radius > _MAXIMUM_RADIUS:
i = _ICON_SIZES.index(icon_size)
if i < len(_ICON_SIZES) - 1:
icon_size = _ICON_SIZES[i + 1]
- angle, radius = self._calculate_angle_and_radius(
+ angle_, radius = self._calculate_angle_and_radius(
children_count, icon_size)
else:
break
return radius, icon_size
- def _calculate_position(self, radius, icon_size, icon_index, children_count,
- sin=math.sin, cos=math.cos):
+ def _calculate_position(self, radius, icon_size, icon_index,
+ children_count, sin=math.sin, cos=math.cos):
""" Calculate an icon position on a circle or a spiral. """
width, height = self.box.get_allocation()
if self._spiral_mode:
@@ -298,7 +304,7 @@ class RingLayout(FavoritesLayout):
_ICON_SPACING_FACTORS[_ICON_SIZES.index(icon_size)]
angle = _INITIAL_ANGLE
radius = _MINIMUM_RADIUS - (icon_size * _MIMIMUM_RADIUS_ENCROACHMENT)
- for i in range(icon_count):
+ for i_ in range(icon_count):
circumference = radius * 2 * math.pi
n = circumference / icon_spacing
angle += (2 * math.pi / n)
@@ -351,6 +357,7 @@ class RingLayout(FavoritesLayout):
else:
return 0
+
_SUNFLOWER_CONSTANT = style.STANDARD_ICON_SIZE * .75
"""Chose a constant such that STANDARD_ICON_SIZE icons are nicely spaced."""
@@ -376,6 +383,7 @@ This is the golden angle: http://en.wikipedia.org/wiki/Golden_angle
Calculation: math.radians(360) / ( _GOLDEN_RATIO * _GOLDEN_RATIO )
"""
+
class SunflowerLayout(RingLayout):
"""Spiral layout based on Fibonacci ratio in phyllotaxis.
@@ -403,7 +411,8 @@ class SunflowerLayout(RingLayout):
return None, style.STANDARD_ICON_SIZE
def adjust_index(self, i):
- """Skip floret indices which end up outside the desired bounding box."""
+ """Skip floret indices which end up outside the desired bounding box.
+ """
for idx in self.skipped_indices:
if i < idx:
break
@@ -434,7 +443,7 @@ class SunflowerLayout(RingLayout):
# removed to make room for the "active activity" icon.
x = r * cos(phi) + (width - icon_size) / 2
y = r * sin(phi) + (height - icon_size - \
- (style.GRID_CELL_SIZE / 2) ) / 2
+ (style.GRID_CELL_SIZE / 2)) / 2
# skip allocations outside the allocation box.
# give up once we can't fit
@@ -442,10 +451,12 @@ class SunflowerLayout(RingLayout):
if y < 0 or y > (height - icon_size) or \
x < 0 or x > (width - icon_size):
self.skipped_indices.append(index)
- continue # try again
+ # try again
+ continue
return x, y
+
class BoxLayout(RingLayout):
"""Lay out icons in a square around the XO man."""
@@ -478,14 +489,16 @@ class BoxLayout(RingLayout):
return (90 - d) / 45.
if d < 225:
return -1
- return cos_d(360 - d) # mirror around 180
+ # mirror around 180
+ return cos_d(360 - d)
cos = lambda r: cos_d(math.degrees(r))
sin = lambda r: cos_d(math.degrees(r) - 90)
- return RingLayout._calculate_position\
- (self, radius, icon_size, index, children_count,
- sin=sin, cos=cos)
+ return RingLayout._calculate_position(self, radius, icon_size, index,
+ children_count, sin=sin,
+ cos=cos)
+
class TriangleLayout(RingLayout):
"""Lay out icons in a triangle around the XO man."""
@@ -524,7 +537,8 @@ class TriangleLayout(RingLayout):
return (d + 90) / 120.
if d <= 90:
return (90 - d) / 60.
- return -cos_d(180 - d) # mirror around 90
+ # mirror around 90
+ return -cos_d(180 - d)
sqrt_3 = math.sqrt(3)
@@ -535,11 +549,12 @@ class TriangleLayout(RingLayout):
return ((d + 90) / 120.) * sqrt_3 - 1
if d <= 90:
return sqrt_3 - 1
- return sin_d(180 - d) # mirror around 90
+ # mirror around 90
+ return sin_d(180 - d)
cos = lambda r: cos_d(math.degrees(r))
sin = lambda r: sin_d(math.degrees(r))
- return RingLayout._calculate_position\
- (self, radius, icon_size, index, children_count,
- sin=sin, cos=cos)
+ return RingLayout._calculate_position(self, radius, icon_size, index,
+ children_count, sin=sin,
+ cos=cos)
diff --git a/src/jarabe/desktop/favoritesview.py b/src/jarabe/desktop/favoritesview.py
index ac847e2..b4a4e75 100644
--- a/src/jarabe/desktop/favoritesview.py
+++ b/src/jarabe/desktop/favoritesview.py
@@ -30,7 +30,6 @@ from sugar.graphics.menuitem import MenuItem
from sugar.graphics.alert import Alert
from sugar.graphics.xocolor import XoColor
from sugar.activity import activityfactory
-from sugar.activity.activityhandle import ActivityHandle
from sugar import dispatch
from sugar.datastore import datastore
@@ -38,7 +37,6 @@ from jarabe.view.palettes import JournalPalette
from jarabe.view.palettes import CurrentActivityPalette, ActivityPalette
from jarabe.view.buddyicon import BuddyIcon
from jarabe.view.buddymenu import BuddyMenu
-from jarabe.view import launcher
from jarabe.model.buddy import get_owner_instance
from jarabe.model import shell
from jarabe.model import bundleregistry
@@ -48,6 +46,7 @@ from jarabe.desktop import schoolserver
from jarabe.desktop.schoolserver import RegisterError
from jarabe.desktop import favoriteslayout
+
_logger = logging.getLogger('FavoritesView')
_ICON_DND_TARGET = ('activity-icon', gtk.TARGET_SAME_WIDGET, 0)
@@ -61,6 +60,9 @@ LAYOUT_MAP = {favoriteslayout.RingLayout.key: favoriteslayout.RingLayout,
`FavoritesLayout` which implement the layouts. Additional information
about the layout can be accessed with fields of the class."""
+_favorites_settings = None
+
+
class FavoritesView(hippo.Canvas):
__gtype_name__ = 'SugarFavoritesView'
@@ -171,7 +173,8 @@ class FavoritesView(hippo.Canvas):
height = allocation.height
min_w_, my_icon_width = self._my_icon.get_width_request()
- min_h_, my_icon_height = self._my_icon.get_height_request(my_icon_width)
+ min_h_, my_icon_height = self._my_icon.get_height_request(
+ my_icon_width)
x = (width - my_icon_width) / 2
y = (height - my_icon_height - style.GRID_CELL_SIZE) / 2
self._layout.move_icon(self._my_icon, x, y, locked=True)
@@ -189,7 +192,8 @@ class FavoritesView(hippo.Canvas):
# TODO: Dnd methods. This should be merged somehow inside hippo-canvas.
def __button_press_event_cb(self, widget, event):
if event.button == 1 and event.type == gtk.gdk.BUTTON_PRESS:
- self._last_clicked_icon = self._get_icon_at_coords(event.x, event.y)
+ self._last_clicked_icon = self._get_icon_at_coords(event.x,
+ event.y)
if self._last_clicked_icon is not None:
self._pressed_button = event.button
self._press_start_x = event.x
@@ -202,9 +206,9 @@ class FavoritesView(hippo.Canvas):
icon_x, icon_y = icon.get_context().translate_to_widget(icon)
icon_width, icon_height = icon.get_allocation()
- if (x >= icon_x ) and (x <= icon_x + icon_width) and \
- (y >= icon_y ) and (y <= icon_y + icon_height) and \
- isinstance(icon, ActivityIcon):
+ if (x >= icon_x) and (x <= icon_x + icon_width) and \
+ (y >= icon_y) and (y <= icon_y + icon_height) and \
+ isinstance(icon, ActivityIcon):
return icon
return None
@@ -273,7 +277,7 @@ class FavoritesView(hippo.Canvas):
def _set_layout(self, layout):
if layout not in LAYOUT_MAP:
- logging.warn('Unknown favorites layout: %r' % layout)
+ logging.warn('Unknown favorites layout: %r', layout)
layout = favoriteslayout.RingLayout.key
assert layout in LAYOUT_MAP
@@ -326,7 +330,7 @@ class FavoritesView(hippo.Canvas):
alert.props.title = _('Registration Successful')
alert.props.msg = _('You are now registered ' \
'with your school server.')
- self._my_icon.remove_register_menu()
+ self._my_icon.set_registered()
ok_icon = Icon(icon_name='dialog-ok')
alert.add_button(gtk.RESPONSE_OK, _('Ok'), ok_icon)
@@ -386,7 +390,7 @@ class ActivityIcon(CanvasIcon):
break
def _get_last_activity_async(self, bundle_id, properties):
- query = {'activity': bundle_id}
+ query = {'activity': bundle_id}
datastore.find(query, sorting=['+timestamp'],
limit=self._MAX_RESUME_ENTRIES,
properties=properties,
@@ -394,8 +398,8 @@ class ActivityIcon(CanvasIcon):
error_handler=self.__get_last_activity_error_handler_cb)
def __get_last_activity_reply_handler_cb(self, entries, total_count):
- # If there's a problem with the DS index, we may get entries not related
- # to this activity.
+ # If there's a problem with the DS index, we may get entries not
+ # related to this activity.
checked_entries = []
for entry in entries:
if entry['activity'] == self.bundle_id:
@@ -506,6 +510,7 @@ class ActivityIcon(CanvasIcon):
self._resume_mode = resume_mode
self._update()
+
class FavoritePalette(ActivityPalette):
__gtype_name__ = 'SugarFavoritePalette'
@@ -554,6 +559,7 @@ class FavoritePalette(ActivityPalette):
if entry is not None:
self.emit('entry-activate', entry)
+
class CurrentActivityIcon(CanvasIcon, hippo.CanvasItem):
def __init__(self):
CanvasIcon.__init__(self, cache=True)
@@ -592,13 +598,15 @@ class CurrentActivityIcon(CanvasIcon, hippo.CanvasItem):
self._home_activity = home_activity
self._update()
+
class OwnerIcon(BuddyIcon):
__gtype_name__ = 'SugarFavoritesOwnerIcon'
__gsignals__ = {
- 'register-activate' : (gobject.SIGNAL_RUN_FIRST,
- gobject.TYPE_NONE, ([]))
+ 'register-activate': (gobject.SIGNAL_RUN_FIRST, gobject.TYPE_NONE,
+ ([])),
}
+
def __init__(self, size):
BuddyIcon.__init__(self, buddy=get_owner_instance(), size=size)
@@ -614,11 +622,16 @@ class OwnerIcon(BuddyIcon):
client = gconf.client_get_default()
backup_url = client.get_string('/desktop/sugar/backup_url')
+
if not backup_url:
self._register_menu = MenuItem(_('Register'), 'media-record')
- self._register_menu.connect('activate', self.__register_activate_cb)
- palette.menu.append(self._register_menu)
- self._register_menu.show()
+ else:
+ self._register_menu = MenuItem(_('Register again'),
+ 'media-record')
+
+ self._register_menu.connect('activate', self.__register_activate_cb)
+ palette.menu.append(self._register_menu)
+ self._register_menu.show()
return palette
@@ -628,12 +641,17 @@ class OwnerIcon(BuddyIcon):
def __register_activate_cb(self, menuitem):
self.emit('register-activate')
- def remove_register_menu(self):
+ def set_registered(self):
self.palette.menu.remove(self._register_menu)
+ self._register_menu = MenuItem(_('Register again'), 'media-record')
+ self._register_menu.connect('activate', self.__register_activate_cb)
+ self.palette.menu.append(self._register_menu)
+ self._register_menu.show()
+
class FavoritesSetting(object):
- _FAVORITES_KEY = "/desktop/sugar/desktop/favorites_layout"
+ _FAVORITES_KEY = '/desktop/sugar/desktop/favorites_layout'
def __init__(self):
client = gconf.client_get_default()
@@ -659,7 +677,6 @@ class FavoritesSetting(object):
layout = property(get_layout, set_layout)
-_favorites_settings = None
def get_settings():
global _favorites_settings
diff --git a/src/jarabe/desktop/friendview.py b/src/jarabe/desktop/friendview.py
index 53b8f5e..8dab35f 100644
--- a/src/jarabe/desktop/friendview.py
+++ b/src/jarabe/desktop/friendview.py
@@ -23,6 +23,7 @@ from sugar.graphics import style
from jarabe.view.buddyicon import BuddyIcon
from jarabe.model import bundleregistry
+
class FriendView(hippo.CanvasBox):
def __init__(self, buddy, **kwargs):
hippo.CanvasBox.__init__(self, **kwargs)
@@ -81,4 +82,3 @@ class FriendView(hippo.CanvasBox):
def __buddy_notify_color_cb(self, buddy, pspec):
# TODO: shouldn't this change self._buddy_icon instead?
self._activity_icon.props.xo_color = buddy.props.color
-
diff --git a/src/jarabe/desktop/grid.py b/src/jarabe/desktop/grid.py
index f3412c9..eab4033 100644
--- a/src/jarabe/desktop/grid.py
+++ b/src/jarabe/desktop/grid.py
@@ -22,17 +22,19 @@ import gtk
from sugar import _sugarext
+
_PLACE_TRIALS = 20
_MAX_WEIGHT = 255
_REFRESH_RATE = 200
_MAX_COLLISIONS_PER_REFRESH = 20
+
class Grid(_sugarext.Grid):
__gsignals__ = {
- 'child-changed' : (gobject.SIGNAL_RUN_FIRST,
- gobject.TYPE_NONE,
- ([gobject.TYPE_PYOBJECT]))
+ 'child-changed': (gobject.SIGNAL_RUN_FIRST, gobject.TYPE_NONE,
+ ([gobject.TYPE_PYOBJECT])),
}
+
def __init__(self, width, height):
gobject.GObject.__init__(self)
@@ -185,7 +187,8 @@ class Grid(_sugarext.Grid):
for c in self._children:
intersection = child_rect.intersect(self._child_rects[c])
if c != child and intersection.width > 0:
- if c not in self._locked_children and c not in self._collisions:
+ if (c not in self._locked_children and
+ c not in self._collisions):
collision_found = True
self._collisions.append(c)
diff --git a/src/jarabe/desktop/groupbox.py b/src/jarabe/desktop/groupbox.py
index 89043fe..ed8f8ae 100644
--- a/src/jarabe/desktop/groupbox.py
+++ b/src/jarabe/desktop/groupbox.py
@@ -30,10 +30,12 @@ from jarabe.model import friends
from jarabe.desktop.friendview import FriendView
from jarabe.desktop.spreadlayout import SpreadLayout
+
class GroupBox(hippo.Canvas):
__gtype_name__ = 'SugarGroupBox'
+
def __init__(self):
- logging.debug("STARTUP: Loading the group view")
+ logging.debug('STARTUP: Loading the group view')
gobject.GObject.__init__(self)
@@ -47,7 +49,7 @@ class GroupBox(hippo.Canvas):
self._box.set_layout(self._layout)
client = gconf.client_get_default()
- color = XoColor(client.get_string("/desktop/sugar/user/color"))
+ color = XoColor(client.get_string('/desktop/sugar/user/color'))
self._owner_icon = CanvasIcon(icon_name='computer-xo', cache=True,
xo_color=color)
diff --git a/src/jarabe/desktop/homebox.py b/src/jarabe/desktop/homebox.py
index 85279ff..661326e 100644
--- a/src/jarabe/desktop/homebox.py
+++ b/src/jarabe/desktop/homebox.py
@@ -30,16 +30,18 @@ from sugar.graphics.icon import Icon
from jarabe.desktop import favoritesview
from jarabe.desktop.activitieslist import ActivitiesList
+
_FAVORITES_VIEW = 0
_LIST_VIEW = 1
_AUTOSEARCH_TIMEOUT = 1000
+
class HomeBox(gtk.VBox):
__gtype_name__ = 'SugarHomeBox'
def __init__(self):
- logging.debug("STARTUP: Loading the home view")
+ logging.debug('STARTUP: Loading the home view')
gobject.GObject.__init__(self)
@@ -57,7 +59,7 @@ class HomeBox(gtk.VBox):
def show_software_updates_alert(self):
alert = Alert()
updater_icon = Icon(icon_name='module-updater',
- pixel_size = style.STANDARD_ICON_SIZE)
+ pixel_size=style.STANDARD_ICON_SIZE)
alert.props.icon = updater_icon
updater_icon.show()
alert.props.title = _('Software Update')
@@ -125,7 +127,7 @@ class HomeBox(gtk.VBox):
else:
raise ValueError('Invalid view: %r' % view)
- _REDRAW_TIMEOUT = 5 * 60 * 1000 # 5 minutes
+ _REDRAW_TIMEOUT = 5 * 60 * 1000 # 5 minutes
def resume(self):
pass
@@ -144,16 +146,15 @@ class HomeBox(gtk.VBox):
def set_resume_mode(self, resume_mode):
self._favorites_view.set_resume_mode(resume_mode)
+
class HomeToolbar(gtk.Toolbar):
__gtype_name__ = 'SugarHomeToolbar'
__gsignals__ = {
- 'query-changed': (gobject.SIGNAL_RUN_FIRST,
- gobject.TYPE_NONE,
+ 'query-changed': (gobject.SIGNAL_RUN_FIRST, gobject.TYPE_NONE,
([str])),
- 'view-changed': (gobject.SIGNAL_RUN_FIRST,
- gobject.TYPE_NONE,
- ([object]))
+ 'view-changed': (gobject.SIGNAL_RUN_FIRST, gobject.TYPE_NONE,
+ ([object])),
}
def __init__(self):
@@ -239,13 +240,14 @@ class HomeToolbar(gtk.Toolbar):
if self._autosearch_timer:
gobject.source_remove(self._autosearch_timer)
self._autosearch_timer = gobject.timeout_add(_AUTOSEARCH_TIMEOUT,
- self.__autosearch_timer_cb)
+ self.__autosearch_timer_cb)
def __autosearch_timer_cb(self):
self._autosearch_timer = None
self.search_entry.activate()
return False
+
class FavoritesButton(RadioToolButton):
__gtype_name__ = 'SugarFavoritesButton'
@@ -295,4 +297,3 @@ class FavoritesButton(RadioToolButton):
def _update_icon(self):
self.props.named_icon = favoritesview.LAYOUT_MAP[self._layout]\
.icon_name
-
diff --git a/src/jarabe/desktop/homewindow.py b/src/jarabe/desktop/homewindow.py
index fec4289..07deff7 100644
--- a/src/jarabe/desktop/homewindow.py
+++ b/src/jarabe/desktop/homewindow.py
@@ -16,6 +16,7 @@
import logging
+import gobject
import gtk
from sugar.graphics import style
@@ -28,11 +29,15 @@ from jarabe.desktop.transitionbox import TransitionBox
from jarabe.model.shell import ShellModel
from jarabe.model import shell
-_HOME_PAGE = 0
-_GROUP_PAGE = 1
-_MESH_PAGE = 2
+
+_HOME_PAGE = 0
+_GROUP_PAGE = 1
+_MESH_PAGE = 2
_TRANSITION_PAGE = 3
+_instance = None
+
+
class HomeWindow(gtk.Window):
def __init__(self):
logging.debug('STARTUP: Loading the desktop window')
@@ -75,7 +80,7 @@ class HomeWindow(gtk.Window):
self.__zoom_level_changed_cb)
def _deactivate_view(self, level):
- group = palettegroup.get_group("default")
+ group = palettegroup.get_group('default')
group.popdown()
if level == ShellModel.ZOOM_HOME:
self._home_box.suspend()
@@ -183,11 +188,22 @@ class HomeWindow(gtk.Window):
def get_home_box(self):
return self._home_box
-_instance = None
+ def busy_during_delayed_action(self, action):
+ """Use busy cursor during execution of action, scheduled via idle_add.
+ """
+ def action_wrapper(old_cursor):
+ try:
+ action()
+ finally:
+ self.get_window().set_cursor(old_cursor)
+
+ old_cursor = self.get_window().get_cursor()
+ self.get_window().set_cursor(gtk.gdk.Cursor(gtk.gdk.WATCH))
+ gobject.idle_add(action_wrapper, old_cursor)
+
def get_instance():
global _instance
if not _instance:
_instance = HomeWindow()
return _instance
-
diff --git a/src/jarabe/desktop/keydialog.py b/src/jarabe/desktop/keydialog.py
index 1e6d17a..6241b9b 100644
--- a/src/jarabe/desktop/keydialog.py
+++ b/src/jarabe/desktop/keydialog.py
@@ -24,8 +24,14 @@ import dbus
from jarabe.model import network
from jarabe.model.network import Secrets
+
IW_AUTH_ALG_OPEN_SYSTEM = 'open'
-IW_AUTH_ALG_SHARED_KEY = 'shared'
+IW_AUTH_ALG_SHARED_KEY = 'shared'
+
+WEP_PASSPHRASE = 1
+WEP_HEX = 2
+WEP_ASCII = 3
+
def string_is_hex(key):
is_hex = True
@@ -34,6 +40,7 @@ def string_is_hex(key):
is_hex = False
return is_hex
+
def string_is_ascii(string):
try:
string.encode('ascii')
@@ -41,12 +48,14 @@ def string_is_ascii(string):
except UnicodeEncodeError:
return False
+
def string_to_hex(passphrase):
key = ''
for c in passphrase:
key += '%02x' % ord(c)
return key
+
def hash_passphrase(passphrase):
# passphrase must have a length of 64
if len(passphrase) > 64:
@@ -57,16 +66,18 @@ def hash_passphrase(passphrase):
passphrase = hashlib.md5(passphrase).digest()
return string_to_hex(passphrase)[:26]
+
class CanceledKeyRequestError(dbus.DBusException):
def __init__(self):
dbus.DBusException.__init__(self)
self._dbus_error_name = network.NM_SETTINGS_IFACE + '.CanceledError'
+
class KeyDialog(gtk.Dialog):
def __init__(self, ssid, flags, wpa_flags, rsn_flags, dev_caps, settings,
response):
gtk.Dialog.__init__(self, flags=gtk.DIALOG_MODAL)
- self.set_title("Wireless Key Required")
+ self.set_title('Wireless Key Required')
self._settings = settings
self._response = response
@@ -108,9 +119,6 @@ class KeyDialog(gtk.Dialog):
def get_response_object(self):
return self._response
-WEP_PASSPHRASE = 1
-WEP_HEX = 2
-WEP_ASCII = 3
class WEPKeyDialog(KeyDialog):
def __init__(self, ssid, flags, wpa_flags, rsn_flags, dev_caps, settings,
@@ -120,9 +128,9 @@ class WEPKeyDialog(KeyDialog):
# WEP key type
self.key_store = gtk.ListStore(str, int)
- self.key_store.append(["Passphrase (128-bit)", WEP_PASSPHRASE])
- self.key_store.append(["Hex (40/128-bit)", WEP_HEX])
- self.key_store.append(["ASCII (40/128-bit)", WEP_ASCII])
+ self.key_store.append(['Passphrase (128-bit)', WEP_PASSPHRASE])
+ self.key_store.append(['Hex (40/128-bit)', WEP_HEX])
+ self.key_store.append(['ASCII (40/128-bit)', WEP_ASCII])
self.key_combo = gtk.ComboBox(self.key_store)
cell = gtk.CellRendererText()
@@ -132,7 +140,7 @@ class WEPKeyDialog(KeyDialog):
self.key_combo.connect('changed', self._key_combo_changed_cb)
hbox = gtk.HBox()
- hbox.pack_start(gtk.Label(_("Key Type:")))
+ hbox.pack_start(gtk.Label(_('Key Type:')))
hbox.pack_start(self.key_combo)
hbox.show_all()
self.vbox.pack_start(hbox)
@@ -142,8 +150,8 @@ class WEPKeyDialog(KeyDialog):
# WEP authentication mode
self.auth_store = gtk.ListStore(str, str)
- self.auth_store.append(["Open System", IW_AUTH_ALG_OPEN_SYSTEM])
- self.auth_store.append(["Shared Key", IW_AUTH_ALG_SHARED_KEY])
+ self.auth_store.append(['Open System', IW_AUTH_ALG_OPEN_SYSTEM])
+ self.auth_store.append(['Shared Key', IW_AUTH_ALG_SHARED_KEY])
self.auth_combo = gtk.ComboBox(self.auth_store)
cell = gtk.CellRendererText()
@@ -152,7 +160,7 @@ class WEPKeyDialog(KeyDialog):
self.auth_combo.set_active(0)
hbox = gtk.HBox()
- hbox.pack_start(gtk.Label(_("Authentication Type:")))
+ hbox.pack_start(gtk.Label(_('Authentication Type:')))
hbox.pack_start(self.auth_combo)
hbox.show_all()
@@ -179,8 +187,8 @@ class WEPKeyDialog(KeyDialog):
def print_security(self):
(key, auth_alg) = self._get_security()
- print "Key: %s" % key
- print "Auth: %d" % auth_alg
+ print 'Key: %s' % key
+ print 'Auth: %d' % auth_alg
def create_security(self):
(key, auth_alg) = self._get_security()
@@ -209,6 +217,7 @@ class WEPKeyDialog(KeyDialog):
self.set_response_sensitive(gtk.RESPONSE_OK, valid)
+
class WPAKeyDialog(KeyDialog):
def __init__(self, ssid, flags, wpa_flags, rsn_flags, dev_caps, settings,
response):
@@ -217,7 +226,7 @@ class WPAKeyDialog(KeyDialog):
self.add_key_entry()
self.store = gtk.ListStore(str)
- self.store.append([_("WPA & WPA2 Personal")])
+ self.store.append([_('WPA & WPA2 Personal')])
self.combo = gtk.ComboBox(self.store)
cell = gtk.CellRendererText()
@@ -226,7 +235,7 @@ class WPAKeyDialog(KeyDialog):
self.combo.set_active(0)
self.hbox = gtk.HBox()
- self.hbox.pack_start(gtk.Label(_("Wireless Security:")))
+ self.hbox.pack_start(gtk.Label(_('Wireless Security:')))
self.hbox.pack_start(self.combo)
self.hbox.show_all()
@@ -246,21 +255,21 @@ class WPAKeyDialog(KeyDialog):
from subprocess import Popen, PIPE
p = Popen(['wpa_passphrase', ssid, key], stdout=PIPE)
for line in p.stdout:
- if line.strip().startswith("psk="):
+ if line.strip().startswith('psk='):
real_key = line.strip()[4:]
if p.wait() != 0:
- raise RuntimeError("Error hashing passphrase")
+ raise RuntimeError('Error hashing passphrase')
if real_key and len(real_key) != 64:
real_key = None
if not real_key:
- raise RuntimeError("Invalid key")
+ raise RuntimeError('Invalid key')
return real_key
def print_security(self):
key = self._get_security()
- print "Key: %s" % key
+ print 'Key: %s' % key
def create_security(self):
secrets = Secrets(self._settings)
@@ -281,6 +290,7 @@ class WPAKeyDialog(KeyDialog):
self.set_response_sensitive(gtk.RESPONSE_OK, valid)
return False
+
def create(ssid, flags, wpa_flags, rsn_flags, dev_caps, settings, response):
if wpa_flags == network.NM_802_11_AP_SEC_NONE and \
rsn_flags == network.NM_802_11_AP_SEC_NONE:
@@ -290,13 +300,15 @@ def create(ssid, flags, wpa_flags, rsn_flags, dev_caps, settings, response):
key_dialog = WPAKeyDialog(ssid, flags, wpa_flags, rsn_flags,
dev_caps, settings, response)
- key_dialog.connect("response", _key_dialog_response_cb)
- key_dialog.connect("destroy", _key_dialog_destroy_cb)
+ key_dialog.connect('response', _key_dialog_response_cb)
+ key_dialog.connect('destroy', _key_dialog_destroy_cb)
key_dialog.show_all()
+
def _key_dialog_destroy_cb(key_dialog, data=None):
_key_dialog_response_cb(key_dialog, gtk.RESPONSE_CANCEL)
+
def _key_dialog_response_cb(key_dialog, response_id):
response = key_dialog.get_response_object()
secrets = None
@@ -308,10 +320,9 @@ def _key_dialog_response_cb(key_dialog, response_id):
response.set_error(CanceledKeyRequestError())
elif response_id == gtk.RESPONSE_OK:
if not secrets:
- raise RuntimeError("Invalid security arguments.")
+ raise RuntimeError('Invalid security arguments.')
response.set_secrets(secrets)
else:
- raise RuntimeError("Unhandled key dialog response %d" % response_id)
+ raise RuntimeError('Unhandled key dialog response %d' % response_id)
key_dialog.destroy()
-
diff --git a/src/jarabe/desktop/meshbox.py b/src/jarabe/desktop/meshbox.py
index 036f00a..ad4b873 100644
--- a/src/jarabe/desktop/meshbox.py
+++ b/src/jarabe/desktop/meshbox.py
@@ -47,6 +47,7 @@ from jarabe.model.olpcmesh import OlpcMeshManager
from jarabe.model.adhoc import get_adhoc_manager_instance
from jarabe.journal import misc
+
_NM_SERVICE = 'org.freedesktop.NetworkManager'
_NM_IFACE = 'org.freedesktop.NetworkManager'
_NM_PATH = '/org/freedesktop/NetworkManager'
@@ -59,6 +60,9 @@ _NM_ACTIVE_CONN_IFACE = 'org.freedesktop.NetworkManager.Connection.Active'
_AP_ICON_NAME = 'network-wireless'
_OLPC_MESH_ICON_NAME = 'network-mesh'
+_AUTOSEARCH_TIMEOUT = 1000
+
+
class ActivityView(hippo.CanvasBox):
def __init__(self, model):
hippo.CanvasBox.__init__(self)
@@ -115,7 +119,7 @@ class ActivityView(hippo.CanvasBox):
return p
def has_buddy_icon(self, key):
- return self._icons.has_key(key)
+ return key in self._icons
def __buddy_added_cb(self, activity, buddy):
self._add_buddy(buddy)
@@ -148,16 +152,13 @@ class ActivityView(hippo.CanvasBox):
if hasattr(icon, 'set_filter'):
icon.set_filter(query)
-_AUTOSEARCH_TIMEOUT = 1000
-
class MeshToolbar(gtk.Toolbar):
__gtype_name__ = 'MeshToolbar'
__gsignals__ = {
- 'query-changed': (gobject.SIGNAL_RUN_FIRST,
- gobject.TYPE_NONE,
- ([str]))
+ 'query-changed': (gobject.SIGNAL_RUN_FIRST, gobject.TYPE_NONE,
+ ([str])),
}
def __init__(self):
@@ -225,16 +226,18 @@ class DeviceObserver(gobject.GObject):
'access-point-added': (gobject.SIGNAL_RUN_FIRST, gobject.TYPE_NONE,
([gobject.TYPE_PYOBJECT])),
'access-point-removed': (gobject.SIGNAL_RUN_FIRST, gobject.TYPE_NONE,
- ([gobject.TYPE_PYOBJECT]))
+ ([gobject.TYPE_PYOBJECT])),
}
+
def __init__(self, device):
gobject.GObject.__init__(self)
self._bus = dbus.SystemBus()
self.device = device
wireless = dbus.Interface(device, _NM_WIRELESS_IFACE)
- wireless.GetAccessPoints(reply_handler=self._get_access_points_reply_cb,
- error_handler=self._get_access_points_error_cb)
+ wireless.GetAccessPoints(
+ reply_handler=self._get_access_points_reply_cb,
+ error_handler=self._get_access_points_error_cb)
self._bus.add_signal_receiver(self.__access_point_added_cb,
signal_name='AccessPointAdded',
@@ -315,13 +318,12 @@ class NetworkManagerObserver(object):
# FIXME It would be better to do all of this async, but I cannot think
# of a good way to. NM could really use some love here.
- netmgr_props = dbus.Interface(
- self._netmgr, 'org.freedesktop.DBus.Properties')
+ netmgr_props = dbus.Interface(self._netmgr, dbus.PROPERTIES_IFACE)
active_connections_o = netmgr_props.Get(_NM_IFACE, 'ActiveConnections')
for conn_o in active_connections_o:
obj = self._bus.get_object(_NM_IFACE, conn_o)
- props = dbus.Interface(obj, 'org.freedesktop.DBus.Properties')
+ props = dbus.Interface(obj, dbus.PROPERTIES_IFACE)
state = props.Get(_NM_ACTIVE_CONN_IFACE, 'State')
if state == network.NM_ACTIVE_CONNECTION_STATE_ACTIVATING:
ap_o = props.Get(_NM_ACTIVE_CONN_IFACE, 'SpecificObject')
@@ -333,8 +335,8 @@ class NetworkManagerObserver(object):
settings = kwargs['connection'].get_settings()
net.create_keydialog(settings, kwargs['response'])
if not found:
- logging.error('Could not determine AP for'
- ' specific object %s' % conn_o)
+ logging.error('Could not determine AP for specific object'
+ ' %s', conn_o)
def __get_devices_reply_cb(self, devices_o):
for dev_o in devices_o:
@@ -345,7 +347,7 @@ class NetworkManagerObserver(object):
def _check_device(self, device_o):
device = self._bus.get_object(_NM_SERVICE, device_o)
- props = dbus.Interface(device, 'org.freedesktop.DBus.Properties')
+ props = dbus.Interface(device, dbus.PROPERTIES_IFACE)
device_type = props.Get(_NM_DEVICE_IFACE, 'DeviceType')
if device_type == network.DEVICE_TYPE_802_11_WIRELESS:
@@ -399,7 +401,7 @@ class MeshBox(gtk.VBox):
__gtype_name__ = 'SugarMeshBox'
def __init__(self):
- logging.debug("STARTUP: Loading the mesh view")
+ logging.debug('STARTUP: Loading the mesh view')
gobject.GObject.__init__(self)
@@ -520,56 +522,59 @@ class MeshBox(gtk.VBox):
# add AP to its corresponding network icon on the desktop,
# creating one if it doesn't already exist
def _add_ap_to_network(self, ap):
- hash = ap.network_hash()
- if hash in self.wireless_networks:
- self.wireless_networks[hash].add_ap(ap)
+ hash_value = ap.network_hash()
+ if hash_value in self.wireless_networks:
+ self.wireless_networks[hash_value].add_ap(ap)
else:
# this is a new network
icon = WirelessNetworkView(ap)
- self.wireless_networks[hash] = icon
+ self.wireless_networks[hash_value] = icon
self._layout.add(icon)
if hasattr(icon, 'set_filter'):
icon.set_filter(self._query)
- def _remove_net_if_empty(self, net, hash):
+ def _remove_net_if_empty(self, net, hash_value):
# remove a network if it has no APs left
if net.num_aps() == 0:
net.disconnect()
self._layout.remove(net)
- del self.wireless_networks[hash]
+ del self.wireless_networks[hash_value]
- def _ap_props_changed_cb(self, ap, old_hash):
+ def _ap_props_changed_cb(self, ap, old_hash_value):
# if we have mesh hardware, ignore OLPC mesh networks that appear as
# normal wifi networks
if len(self._mesh) > 0 and ap.mode == network.NM_802_11_MODE_ADHOC \
- and ap.name == "olpc-mesh":
- logging.debug("ignoring OLPC mesh IBSS")
+ and ap.name == 'olpc-mesh':
+ logging.debug('ignoring OLPC mesh IBSS')
ap.disconnect()
return
if self._adhoc_manager is not None and \
network.is_sugar_adhoc_network(ap.name) and \
ap.mode == network.NM_802_11_MODE_ADHOC:
- if old_hash is None: # new Ad-hoc network finished initializing
+ if old_hash_value is None:
+ # new Ad-hoc network finished initializing
self._adhoc_manager.add_access_point(ap)
# we are called as well in other cases but we do not need to
# act here as we don't display signal strength for Ad-hoc networks
return
- if old_hash is None: # new AP finished initializing
+ if old_hash_value is None:
+ # new AP finished initializing
self._add_ap_to_network(ap)
return
- hash = ap.network_hash()
- if old_hash == hash:
+ hash_value = ap.network_hash()
+ if old_hash_value == hash_value:
# no change in network identity, so just update signal strengths
- self.wireless_networks[hash].update_strength()
+ self.wireless_networks[hash_value].update_strength()
return
# properties change includes a change of the identity of the network
# that it is on. so create this as a new network.
- self.wireless_networks[old_hash].remove_ap(ap)
- self._remove_net_if_empty(self.wireless_networks[old_hash], old_hash)
+ self.wireless_networks[old_hash_value].remove_ap(ap)
+ self._remove_net_if_empty(self.wireless_networks[old_hash_value],
+ old_hash_value)
self._add_ap_to_network(ap)
def add_access_point(self, device, ap_o):
@@ -597,7 +602,7 @@ class MeshBox(gtk.VBox):
# it's not an error if the AP isn't found, since we might have ignored
# it (e.g. olpc-mesh adhoc network)
- logging.debug('Can not remove access point %s' % ap_o)
+ logging.debug('Can not remove access point %s', ap_o)
def add_adhoc_networks(self, device):
if self._adhoc_manager is None:
@@ -631,15 +636,15 @@ class MeshBox(gtk.VBox):
# the OLPC mesh can be recognised as a "normal" wifi network. remove
# any such normal networks if they have been created
- for hash, net in self.wireless_networks.iteritems():
+ for hash_value, net in self.wireless_networks.iteritems():
if not net.is_olpc_mesh():
continue
- logging.debug("removing OLPC mesh IBSS")
+ logging.debug('removing OLPC mesh IBSS')
net.remove_all_aps()
net.disconnect()
self._layout.remove(net)
- del self.wireless_networks[hash]
+ del self.wireless_networks[hash_value]
def disable_olpc_mesh(self, mesh_device):
for icon in self._mesh:
diff --git a/src/jarabe/desktop/networkviews.py b/src/jarabe/desktop/networkviews.py
index 87f182f..99d46b6 100644
--- a/src/jarabe/desktop/networkviews.py
+++ b/src/jarabe/desktop/networkviews.py
@@ -41,6 +41,7 @@ from jarabe.model.network import IP4Config
from jarabe.model.network import WirelessSecurity
from jarabe.model.adhoc import get_adhoc_manager_instance
+
_NM_SERVICE = 'org.freedesktop.NetworkManager'
_NM_IFACE = 'org.freedesktop.NetworkManager'
_NM_PATH = '/org/freedesktop/NetworkManager'
@@ -74,7 +75,6 @@ class WirelessNetworkView(CanvasPulsingIcon):
self._rsn_flags = initial_ap.rsn_flags
self._device_caps = 0
self._device_state = None
- self._connection = None
self._color = None
if self._mode == network.NM_802_11_MODE_ADHOC and \
@@ -100,23 +100,9 @@ class WirelessNetworkView(CanvasPulsingIcon):
self._palette = self._create_palette()
self.set_palette(self._palette)
self._palette_icon.props.xo_color = self._color
+ self._update_badge()
- if self._mode != network.NM_802_11_MODE_ADHOC:
- if network.find_connection_by_ssid(self._name) is not None:
- self.props.badge_name = "emblem-favorite"
- self._palette_icon.props.badge_name = "emblem-favorite"
- elif self._flags == network.NM_802_11_AP_FLAGS_PRIVACY:
- self.props.badge_name = "emblem-locked"
- self._palette_icon.props.badge_name = "emblem-locked"
- else:
- self.props.badge_name = None
- self._palette_icon.props.badge_name = None
- else:
- self.props.badge_name = None
- self._palette_icon.props.badge_name = None
-
- interface_props = dbus.Interface(self._device,
- 'org.freedesktop.DBus.Properties')
+ interface_props = dbus.Interface(self._device, dbus.PROPERTIES_IFACE)
interface_props.Get(_NM_DEVICE_IFACE, 'State',
reply_handler=self.__get_device_state_reply_cb,
error_handler=self.__get_device_state_error_cb)
@@ -160,6 +146,7 @@ class WirelessNetworkView(CanvasPulsingIcon):
self._device_state = new_state
self._update_state()
self._update_icon()
+ self._update_badge()
def __update_active_ap(self, ap_path):
if ap_path in self._access_points:
@@ -192,6 +179,7 @@ class WirelessNetworkView(CanvasPulsingIcon):
self._device_state = state
self._update_state()
self._update_color()
+ self._update_badge()
def __get_device_state_error_cb(self, err):
logging.error('Error getting the device state: %s', err)
@@ -222,6 +210,21 @@ class WirelessNetworkView(CanvasPulsingIcon):
icon = self._palette.props.icon
icon.props.icon_name = icon_name
+ def _update_badge(self):
+ if self._mode != network.NM_802_11_MODE_ADHOC:
+ if network.find_connection_by_ssid(self._name) is not None:
+ self.props.badge_name = 'emblem-favorite'
+ self._palette_icon.props.badge_name = 'emblem-favorite'
+ elif self._flags == network.NM_802_11_AP_FLAGS_PRIVACY:
+ self.props.badge_name = 'emblem-locked'
+ self._palette_icon.props.badge_name = 'emblem-locked'
+ else:
+ self.props.badge_name = None
+ self._palette_icon.props.badge_name = None
+ else:
+ self.props.badge_name = None
+ self._palette_icon.props.badge_name = None
+
def _update_state(self):
if self._active_ap is not None:
state = self._device_state
@@ -262,24 +265,30 @@ class WirelessNetworkView(CanvasPulsingIcon):
self.props.base_color = self._color
def _disconnect_activate_cb(self, item):
- pass
+ if self._mode == network.NM_802_11_MODE_INFRA:
+ connection = network.find_connection_by_ssid(self._name)
+ if connection:
+ connection.disable_autoconnect()
+
+ ap_paths = self._access_points.keys()
+ network.disconnect_access_points(ap_paths)
def _add_ciphers_from_flags(self, flags, pairwise):
ciphers = []
if pairwise:
if flags & network.NM_802_11_AP_SEC_PAIR_TKIP:
- ciphers.append("tkip")
+ ciphers.append('tkip')
if flags & network.NM_802_11_AP_SEC_PAIR_CCMP:
- ciphers.append("ccmp")
+ ciphers.append('ccmp')
else:
if flags & network.NM_802_11_AP_SEC_GROUP_WEP40:
- ciphers.append("wep40")
+ ciphers.append('wep40')
if flags & network.NM_802_11_AP_SEC_GROUP_WEP104:
- ciphers.append("wep104")
+ ciphers.append('wep104')
if flags & network.NM_802_11_AP_SEC_GROUP_TKIP:
- ciphers.append("tkip")
+ ciphers.append('tkip')
if flags & network.NM_802_11_AP_SEC_GROUP_CCMP:
- ciphers.append("ccmp")
+ ciphers.append('ccmp')
return ciphers
def _get_security(self):
@@ -363,7 +372,7 @@ class WirelessNetworkView(CanvasPulsingIcon):
netmgr.ActivateConnection(network.SETTINGS_SERVICE, connection.path,
self._device.object_path,
- "/",
+ '/',
reply_handler=self.__activate_reply_cb,
error_handler=self.__activate_error_cb)
@@ -380,7 +389,8 @@ class WirelessNetworkView(CanvasPulsingIcon):
def create_keydialog(self, settings, response):
keydialog.create(self._name, self._flags, self._wpa_flags,
- self._rsn_flags, self._device_caps, settings, response)
+ self._rsn_flags, self._device_caps, settings,
+ response)
def update_strength(self):
if self._active_ap is not None:
@@ -419,7 +429,7 @@ class WirelessNetworkView(CanvasPulsingIcon):
def is_olpc_mesh(self):
return self._mode == network.NM_802_11_MODE_ADHOC \
- and self.name == "olpc-mesh"
+ and self.name == 'olpc-mesh'
def remove_all_aps(self):
for ap in self._access_points.values():
@@ -438,6 +448,7 @@ class WirelessNetworkView(CanvasPulsingIcon):
path=self._device.object_path,
dbus_interface=_NM_WIRELESS_IFACE)
+
class SugarAdhocView(CanvasPulsingIcon):
"""To mimic the mesh behavior on devices where mesh hardware is
not available we support the creation of an Ad-hoc network on
@@ -483,7 +494,7 @@ class SugarAdhocView(CanvasPulsingIcon):
icon_name=self._ICON_NAME + str(self._channel),
icon_size=style.STANDARD_ICON_SIZE)
- palette_ = palette.Palette(_("Ad-hoc Network %d") % self._channel,
+ palette_ = palette.Palette(_('Ad-hoc Network %d') % self._channel,
icon=self._palette_icon)
self._connect_item = MenuItem(_('Connect'), 'dialog-ok')
@@ -517,9 +528,6 @@ class SugarAdhocView(CanvasPulsingIcon):
else:
icon_name = self._ICON_NAME + str(self._channel)
- self.props.base_color = self._state_color
- self._palette_icon.props.xo_color = self._state_color
-
if icon_name is not None:
self.props.icon_name = icon_name
icon = self._palette.props.icon
@@ -549,6 +557,7 @@ class SugarAdhocView(CanvasPulsingIcon):
def _update_color(self):
if self._greyed_out:
+ self.props.pulsing = False
self.props.base_color = XoColor('#D5D5D5,#D5D5D5')
else:
self.props.base_color = self._state_color
@@ -557,12 +566,12 @@ class SugarAdhocView(CanvasPulsingIcon):
if channel == self._channel:
if has_members == True:
self._state_color = profile.get_color()
- self.props.base_color = self._state_color
- self._palette_icon.props.xo_color = self._state_color
else:
color = '%s,%s' % (profile.get_color().get_stroke_color(),
style.COLOR_TRANSPARENT.get_svg())
self._state_color = XoColor(color)
+
+ if not self._greyed_out:
self.props.base_color = self._state_color
self._palette_icon.props.xo_color = self._state_color
@@ -584,14 +593,12 @@ class OlpcMeshView(CanvasPulsingIcon):
self._greyed_out = False
self._name = ''
self._device_state = None
- self._connection = None
self._active = False
device = mesh_mgr.mesh_device
self.connect('button-release-event', self.__button_release_event_cb)
- interface_props = dbus.Interface(device,
- 'org.freedesktop.DBus.Properties')
+ interface_props = dbus.Interface(device, dbus.PROPERTIES_IFACE)
interface_props.Get(_NM_DEVICE_IFACE, 'State',
reply_handler=self.__get_device_state_reply_cb,
error_handler=self.__get_device_state_error_cb)
@@ -616,7 +623,7 @@ class OlpcMeshView(CanvasPulsingIcon):
self.set_palette(self._palette)
def _create_palette(self):
- _palette = palette.Palette(_("Mesh Network %d") % self._channel)
+ _palette = palette.Palette(_('Mesh Network %d') % self._channel)
self._connect_item = MenuItem(_('Connect'), 'dialog-ok')
self._connect_item.connect('activate', self.__connect_activate_cb)
@@ -712,4 +719,3 @@ class OlpcMeshView(CanvasPulsingIcon):
signal_name='PropertiesChanged',
path=device_object_path,
dbus_interface=_NM_OLPC_MESH_IFACE)
-
diff --git a/src/jarabe/desktop/schoolserver.py b/src/jarabe/desktop/schoolserver.py
index a05f56c..aea2357 100644
--- a/src/jarabe/desktop/schoolserver.py
+++ b/src/jarabe/desktop/schoolserver.py
@@ -16,8 +16,9 @@
import logging
from gettext import gettext as _
-from xmlrpclib import ServerProxy, Error
+import xmlrpclib
import socket
+import httplib
import os
from string import ascii_uppercase
import random
@@ -29,15 +30,17 @@ import gconf
from sugar import env
from sugar.profile import get_profile
-REGISTER_URL = 'http://schoolserver:8080/'
+_REGISTER_URL = 'http://schoolserver:8080/'
+_REGISTER_TIMEOUT = 8
-def generate_serial_number():
+
+def _generate_serial_number():
""" Generates a serial number based on 3 random uppercase letters
and the last 8 digits of the current unix seconds. """
serial_part1 = []
- for y_ in range(3) :
+ for y_ in range(3):
serial_part1.append(random.choice(ascii_uppercase))
serial_part1 = ''.join(serial_part1)
@@ -46,7 +49,8 @@ def generate_serial_number():
return serial
-def store_identifiers(serial_number, uuid, backup_url):
+
+def _store_identifiers(serial_number, uuid_, backup_url):
""" Stores the serial number, uuid and backup_url
in the identifier folder inside the profile directory
so that these identifiers can be used for backup. """
@@ -64,7 +68,7 @@ def store_identifiers(serial_number, uuid, backup_url):
if os.path.exists(os.path.join(identifier_path, 'uuid')):
os.remove(os.path.join(identifier_path, 'uuid'))
uuid_file = open(os.path.join(identifier_path, 'uuid'), 'w')
- uuid_file.write(uuid)
+ uuid_file.write(uuid_)
uuid_file.close()
if os.path.exists(os.path.join(identifier_path, 'backup_url')):
@@ -73,33 +77,56 @@ def store_identifiers(serial_number, uuid, backup_url):
backup_url_file.write(backup_url)
backup_url_file.close()
+
class RegisterError(Exception):
pass
-def register_laptop(url=REGISTER_URL):
+
+class _TimeoutHTTP(httplib.HTTP):
+
+ def __init__(self, host='', port=None, strict=None, timeout=None):
+ if port == 0:
+ port = None
+ # FIXME: Depending on undocumented internals that can break between
+ # Python releases. Please have a look at SL #2350
+ self._setup(self._connection_class(host,
+ port, strict, timeout=_REGISTER_TIMEOUT))
+
+
+class _TimeoutTransport(xmlrpclib.Transport):
+
+ def make_connection(self, host):
+ host, extra_headers, x509_ = self.get_host_info(host)
+ return _TimeoutHTTP(host, timeout=_REGISTER_TIMEOUT)
+
+
+def register_laptop(url=_REGISTER_URL):
profile = get_profile()
client = gconf.client_get_default()
- if have_ofw_tree():
- sn = read_ofw('mfg-data/SN')
- uuid_ = read_ofw('mfg-data/U#')
+ if _have_ofw_tree():
+ sn = _read_ofw('mfg-data/SN')
+ uuid_ = _read_ofw('mfg-data/U#')
sn = sn or 'SHF00000000'
uuid_ = uuid_ or '00000000-0000-0000-0000-000000000000'
else:
- sn = generate_serial_number()
+ sn = _generate_serial_number()
uuid_ = str(uuid.uuid1())
- setting_name = '/desktop/sugar/collaboration/jabber_server'
- jabber_server = client.get_string(setting_name)
- store_identifiers(sn, uuid_, jabber_server)
+
+ setting_name = '/desktop/sugar/collaboration/jabber_server'
+ jabber_server = client.get_string(setting_name)
+ _store_identifiers(sn, uuid_, jabber_server)
+
+ if jabber_server:
url = 'http://' + jabber_server + ':8080/'
nick = client.get_string('/desktop/sugar/user/nick')
- server = ServerProxy(url)
+ server = xmlrpclib.ServerProxy(url, _TimeoutTransport())
try:
data = server.register(sn, nick, uuid_, profile.pubkey)
- except (Error, TypeError, socket.error):
+ except (xmlrpclib.Error, TypeError, socket.error):
logging.exception('Registration: cannot connect to server')
raise RegisterError(_('Cannot connect to the server.'))
@@ -114,10 +141,12 @@ def register_laptop(url=REGISTER_URL):
return True
-def have_ofw_tree():
+
+def _have_ofw_tree():
return os.path.exists('/ofw')
-def read_ofw(path):
+
+def _read_ofw(path):
path = os.path.join('/ofw', path)
if not os.path.exists(path):
return None
diff --git a/src/jarabe/desktop/snowflakelayout.py b/src/jarabe/desktop/snowflakelayout.py
index 5782cff..e4963ba 100644
--- a/src/jarabe/desktop/snowflakelayout.py
+++ b/src/jarabe/desktop/snowflakelayout.py
@@ -21,11 +21,14 @@ import hippo
from sugar.graphics import style
+
_BASE_DISTANCE = style.zoom(25)
_CHILDREN_FACTOR = style.zoom(3)
+
class SnowflakeLayout(gobject.GObject, hippo.CanvasLayout):
__gtype_name__ = 'SugarSnowflakeLayout'
+
def __init__(self):
gobject.GObject.__init__(self)
self._nflakes = 0
diff --git a/src/jarabe/desktop/spreadlayout.py b/src/jarabe/desktop/spreadlayout.py
index ffc5bc7..9200361 100644
--- a/src/jarabe/desktop/spreadlayout.py
+++ b/src/jarabe/desktop/spreadlayout.py
@@ -22,10 +22,13 @@ from sugar.graphics import style
from jarabe.desktop.grid import Grid
+
_CELL_SIZE = 4.0
+
class SpreadLayout(gobject.GObject, hippo.CanvasLayout):
__gtype_name__ = 'SugarSpreadLayout'
+
def __init__(self):
gobject.GObject.__init__(self)
self._box = None
@@ -80,4 +83,3 @@ class SpreadLayout(gobject.GObject, hippo.CanvasLayout):
def _grid_child_changed_cb(self, grid, child):
child.emit_request_changed()
-
diff --git a/src/jarabe/desktop/transitionbox.py b/src/jarabe/desktop/transitionbox.py
index cf9e0d6..4042044 100644
--- a/src/jarabe/desktop/transitionbox.py
+++ b/src/jarabe/desktop/transitionbox.py
@@ -23,6 +23,7 @@ from sugar.graphics import animator
from jarabe.model.buddy import get_owner_instance
from jarabe.view.buddyicon import BuddyIcon
+
class _Animation(animator.Animation):
def __init__(self, icon, start_size, end_size):
animator.Animation.__init__(self, 0.0, 1.0)
@@ -35,8 +36,10 @@ class _Animation(animator.Animation):
d = (self.end_size - self.start_size) * current
self._icon.props.size = self.start_size + d
+
class _Layout(gobject.GObject, hippo.CanvasLayout):
__gtype_name__ = 'SugarTransitionBoxLayout'
+
def __init__(self):
gobject.GObject.__init__(self)
self._box = None
@@ -60,12 +63,12 @@ class _Layout(gobject.GObject, hippo.CanvasLayout):
y + (height - child_height) / 2,
child_width, child_height, origin_changed)
+
class TransitionBox(hippo.Canvas):
__gtype_name__ = 'SugarTransitionBox'
__gsignals__ = {
- 'completed': (gobject.SIGNAL_RUN_FIRST,
- gobject.TYPE_NONE, ([]))
+ 'completed': (gobject.SIGNAL_RUN_FIRST, gobject.TYPE_NONE, ([])),
}
def __init__(self):
diff --git a/src/jarabe/frame/__init__.py b/src/jarabe/frame/__init__.py
index d7aec3d..b3e4b80 100644
--- a/src/jarabe/frame/__init__.py
+++ b/src/jarabe/frame/__init__.py
@@ -16,8 +16,10 @@
from jarabe.frame.frame import Frame
+
_view = None
+
def get_view():
global _view
if not _view:
diff --git a/src/jarabe/frame/activitiestray.py b/src/jarabe/frame/activitiestray.py
index 6bd2a1b..6e08fc0 100644
--- a/src/jarabe/frame/activitiestray.py
+++ b/src/jarabe/frame/activitiestray.py
@@ -98,7 +98,6 @@ class ActivityButton(RadioToolButton):
self._icon.props.pulsing = False
-
class InviteButton(ToolButton):
"""Invite to shared activity"""
def __init__(self, invite):
@@ -209,7 +208,8 @@ class ActivitiesTray(HTray):
self._home_model = shell.get_model()
self._home_model.connect('activity-added', self.__activity_added_cb)
- self._home_model.connect('activity-removed', self.__activity_removed_cb)
+ self._home_model.connect('activity-removed',
+ self.__activity_removed_cb)
self._home_model.connect('active-activity-changed',
self.__activity_changed_cb)
self._home_model.connect('tabbing-activity-changed',
@@ -313,6 +313,7 @@ class ActivitiesTray(HTray):
self.add_item(button)
button.show()
+
class BaseTransferButton(ToolButton):
"""Button with a notification attached
"""
@@ -349,6 +350,7 @@ class BaseTransferButton(ToolButton):
filetransfer.FT_REASON_LOCAL_STOPPED:
self.remove()
+
class IncomingTransferButton(BaseTransferButton):
"""UI element representing an ongoing incoming file transfer
"""
@@ -429,6 +431,7 @@ class IncomingTransferButton(BaseTransferButton):
def __dismiss_clicked_cb(self, palette):
self.remove()
+
class OutgoingTransferButton(BaseTransferButton):
"""UI element representing an ongoing outgoing file transfer
"""
@@ -446,7 +449,7 @@ class OutgoingTransferButton(BaseTransferButton):
break
client = gconf.client_get_default()
- icon_color = XoColor(client.get_string("/desktop/sugar/user/color"))
+ icon_color = XoColor(client.get_string('/desktop/sugar/user/color'))
self.props.icon_widget.props.xo_color = icon_color
self.notif_icon.props.xo_color = icon_color
@@ -464,14 +467,14 @@ class OutgoingTransferButton(BaseTransferButton):
def __dismiss_clicked_cb(self, palette):
self.remove()
+
class BaseTransferPalette(Palette):
"""Base palette class for frame or notification icon for file transfers
"""
- __gtype_name__ = "SugarBaseTransferPalette"
+ __gtype_name__ = 'SugarBaseTransferPalette'
__gsignals__ = {
- 'dismiss-clicked': (gobject.SIGNAL_RUN_FIRST,
- gobject.TYPE_NONE, ([])),
+ 'dismiss-clicked': (gobject.SIGNAL_RUN_FIRST, gobject.TYPE_NONE, ([])),
}
def __init__(self, file_transfer):
@@ -526,10 +529,12 @@ class BaseTransferPalette(Palette):
total = self._format_size(self.file_transfer.file_size)
self.progress_label.props.label = _('%s of %s') % (transferred, total)
+
class IncomingTransferPalette(BaseTransferPalette):
"""Palette for frame or notification icon for incoming file transfers
"""
- __gtype_name__ = "SugarIncomingTransferPalette"
+ __gtype_name__ = 'SugarIncomingTransferPalette'
+
def __init__(self, file_transfer):
BaseTransferPalette.__init__(self, file_transfer)
@@ -652,10 +657,11 @@ class IncomingTransferPalette(BaseTransferPalette):
def __dismiss_activate_cb(self, menu_item):
self.emit('dismiss-clicked')
+
class OutgoingTransferPalette(BaseTransferPalette):
"""Palette for frame or notification icon for outgoing file transfers
"""
- __gtype_name__ = "SugarOutgoingTransferPalette"
+ __gtype_name__ = 'SugarOutgoingTransferPalette'
def __init__(self, file_transfer):
BaseTransferPalette.__init__(self, file_transfer)
diff --git a/src/jarabe/frame/clipboard.py b/src/jarabe/frame/clipboard.py
index 3b9f745..be2b902 100644
--- a/src/jarabe/frame/clipboard.py
+++ b/src/jarabe/frame/clipboard.py
@@ -26,6 +26,10 @@ from sugar import mime
from jarabe.frame.clipboardobject import ClipboardObject, Format
+
+_instance = None
+
+
class Clipboard(gobject.GObject):
__gsignals__ = {
@@ -34,7 +38,7 @@ class Clipboard(gobject.GObject):
'object-deleted': (gobject.SIGNAL_RUN_FIRST, gobject.TYPE_NONE,
([int])),
'object-state-changed': (gobject.SIGNAL_RUN_FIRST, gobject.TYPE_NONE,
- ([object]))
+ ([object])),
}
def __init__(self):
@@ -69,7 +73,7 @@ class Clipboard(gobject.GObject):
+ ' with path at ' + new_uri)
else:
cb_object.add_format(Format(format_type, data, on_disk))
- logging.debug('Added in-memory format of type ' + format_type + '.')
+ logging.debug('Added in-memory format of type %s.', format_type)
self.emit('object-state-changed', cb_object)
@@ -82,9 +86,9 @@ class Clipboard(gobject.GObject):
def set_object_percent(self, object_id, percent):
cb_object = self._objects[object_id]
if percent < 0 or percent > 100:
- raise ValueError("invalid percentage")
+ raise ValueError('invalid percentage')
if cb_object.get_percent() > percent:
- raise ValueError("invalid percentage; less than current percent")
+ raise ValueError('invalid percentage; less than current percent')
if cb_object.get_percent() == percent:
# ignore setting same percentage
return
@@ -126,21 +130,21 @@ class Clipboard(gobject.GObject):
def _copy_file(self, original_uri):
uri = urlparse.urlparse(original_uri)
- path_, file_name = os.path.split(uri.path)
+ path = uri.path # pylint: disable=E1101
+ directory_, file_name = os.path.split(path)
root, ext = os.path.splitext(file_name)
if not ext or ext == '.':
- mime_type = mime.get_for_file(uri.path)
+ mime_type = mime.get_for_file(path)
ext = '.' + mime.get_primary_extension(mime_type)
f_, new_file_path = tempfile.mkstemp(ext, root)
del f_
- shutil.copyfile(uri.path, new_file_path)
+ shutil.copyfile(path, new_file_path)
os.chmod(new_file_path, 0644)
return 'file://' + new_file_path
-_instance = None
def get_instance():
global _instance
diff --git a/src/jarabe/frame/clipboardicon.py b/src/jarabe/frame/clipboardicon.py
index 279db08..aa72d8a 100644
--- a/src/jarabe/frame/clipboardicon.py
+++ b/src/jarabe/frame/clipboardicon.py
@@ -31,6 +31,7 @@ from jarabe.frame.frameinvoker import FrameWidgetInvoker
from jarabe.frame.notification import NotificationIcon
import jarabe.frame
+
class ClipboardIcon(RadioToolButton):
__gtype_name__ = 'SugarClipboardIcon'
@@ -71,7 +72,8 @@ class ClipboardIcon(RadioToolButton):
def _drag_data_get_cb(self, widget, context, selection, target_type,
event_time):
- logging.debug('_drag_data_get_cb: requested target ' + selection.target)
+ logging.debug('_drag_data_get_cb: requested target %s',
+ selection.target)
data = self._cb_object.get_formats()[selection.target].get_data()
selection.set(selection.target, 8, data)
@@ -79,8 +81,8 @@ class ClipboardIcon(RadioToolButton):
logging.debug('ClipboardIcon._put_in_clipboard')
if self._cb_object.get_percent() < 100:
- raise ValueError('Object is not complete,' \
- ' cannot be put into the clipboard.')
+ raise ValueError('Object is not complete, cannot be put into the'
+ ' clipboard.')
targets = self._get_targets()
if targets:
diff --git a/src/jarabe/frame/clipboardmenu.py b/src/jarabe/frame/clipboardmenu.py
index b998110..d11538d 100644
--- a/src/jarabe/frame/clipboardmenu.py
+++ b/src/jarabe/frame/clipboardmenu.py
@@ -35,6 +35,7 @@ from jarabe.frame import clipboard
from jarabe.journal import misc
from jarabe.model import bundleregistry
+
class ClipboardMenu(Palette):
def __init__(self, cb_object):
@@ -212,7 +213,8 @@ class ClipboardMenu(Palette):
if most_significant_mime_type == 'text/uri-list':
uris = mime.split_uri_list(format_.get_data())
if len(uris) == 1 and uris[0].startswith('file://'):
- file_path = urlparse.urlparse(uris[0]).path
+ parsed_url = urlparse.urlparse(uris[0])
+ file_path = parsed_url.path # pylint: disable=E1101
transfer_ownership = False
mime_type = mime.get_for_file(file_path)
else:
@@ -221,7 +223,8 @@ class ClipboardMenu(Palette):
mime_type = 'text/uri-list'
else:
if format_.is_on_disk():
- file_path = urlparse.urlparse(format_.get_data()).path
+ parsed_url = urlparse.urlparse(format_.get_data())
+ file_path = parsed_url.path # pylint: disable=E1101
transfer_ownership = False
mime_type = mime.get_for_file(file_path)
else:
diff --git a/src/jarabe/frame/clipboardobject.py b/src/jarabe/frame/clipboardobject.py
index e9403f9..407af2f 100644
--- a/src/jarabe/frame/clipboardobject.py
+++ b/src/jarabe/frame/clipboardobject.py
@@ -24,6 +24,7 @@ from gettext import gettext as _
from sugar import mime
from sugar.bundle.activitybundle import ActivityBundle
+
class ClipboardObject(object):
def __init__(self, object_path, name):
@@ -105,15 +106,18 @@ class ClipboardObject(object):
if format_ == 'text/uri-list':
data = self._formats['text/uri-list'].get_data()
uri = urlparse.urlparse(mime.split_uri_list(data)[0], 'file')
- if uri.scheme == 'file':
- if os.path.exists(uri.path):
- format_ = mime.get_for_file(uri.path)
+ scheme = uri.scheme # pylint: disable=E1101
+ if scheme == 'file':
+ path = uri.path # pylint: disable=E1101
+ if os.path.exists(path):
+ format_ = mime.get_for_file(path)
else:
- format_ = mime.get_from_file_name(uri.path)
+ format_ = mime.get_from_file_name(path)
logging.debug('Chose %r!', format_)
return format_
+
class Format(object):
def __init__(self, mime_type, data, on_disk):
@@ -126,8 +130,9 @@ class Format(object):
def destroy(self):
if self._on_disk:
uri = urlparse.urlparse(self._data)
- if os.path.isfile(uri.path):
- os.remove(uri.path)
+ path = uri.path # pylint: disable=E1101
+ if os.path.isfile(path):
+ os.remove(path)
def get_type(self):
return self._type
diff --git a/src/jarabe/frame/clipboardpanelwindow.py b/src/jarabe/frame/clipboardpanelwindow.py
index ac324f4..f5d537c 100644
--- a/src/jarabe/frame/clipboardpanelwindow.py
+++ b/src/jarabe/frame/clipboardpanelwindow.py
@@ -25,6 +25,7 @@ from jarabe.frame.clipboardtray import ClipboardTray
from jarabe.frame import clipboard
+
class ClipboardPanelWindow(FrameWindow):
def __init__(self, frame, orientation):
FrameWindow.__init__(self, orientation)
@@ -35,7 +36,7 @@ class ClipboardPanelWindow(FrameWindow):
# NOTE: we need to keep a reference to gtk.Clipboard in order to keep
# listening to it.
self._clipboard = gtk.Clipboard()
- self._clipboard.connect("owner-change", self._owner_change_cb)
+ self._clipboard.connect('owner-change', self._owner_change_cb)
self._clipboard_tray = ClipboardTray()
canvas_widget = hippo.CanvasWidget(widget=self._clipboard_tray)
@@ -43,14 +44,14 @@ class ClipboardPanelWindow(FrameWindow):
# Receiving dnd drops
self.drag_dest_set(0, [], 0)
- self.connect("drag_motion", self._clipboard_tray.drag_motion_cb)
- self.connect("drag_leave", self._clipboard_tray.drag_leave_cb)
- self.connect("drag_drop", self._clipboard_tray.drag_drop_cb)
- self.connect("drag_data_received",
+ self.connect('drag_motion', self._clipboard_tray.drag_motion_cb)
+ self.connect('drag_leave', self._clipboard_tray.drag_leave_cb)
+ self.connect('drag_drop', self._clipboard_tray.drag_drop_cb)
+ self.connect('drag_data_received',
self._clipboard_tray.drag_data_received_cb)
def _owner_change_cb(self, x_clipboard, event):
- logging.debug("owner_change_cb")
+ logging.debug('owner_change_cb')
if self._clipboard_tray.owns_clipboard():
return
@@ -100,4 +101,3 @@ class ClipboardPanelWindow(FrameWindow):
selection.type,
selection.data,
on_disk=False)
-
diff --git a/src/jarabe/frame/clipboardtray.py b/src/jarabe/frame/clipboardtray.py
index 8beb6a8..f49b799 100644
--- a/src/jarabe/frame/clipboardtray.py
+++ b/src/jarabe/frame/clipboardtray.py
@@ -27,6 +27,7 @@ from sugar.graphics import style
from jarabe.frame import clipboard
from jarabe.frame.clipboardicon import ClipboardIcon
+
class _ContextMap(object):
"""Maps a drag context to the clipboard object involved in the dragging."""
def __init__(self):
@@ -40,8 +41,8 @@ class _ContextMap(object):
def get_object_id(self, context):
"""Retrieves the object_id associated with context.
- Will release the association when this function was called as many times
- as the number of data_types that this clipboard object contains.
+ Will release the association when this function was called as many
+ times as the number of data_types that this clipboard object contains.
"""
[object_id, data_types_left] = self._context_map[context]
@@ -56,6 +57,7 @@ class _ContextMap(object):
def has_context(self, context):
return context in self._context_map
+
class ClipboardTray(tray.VTray):
MAX_ITEMS = gtk.gdk.screen_height() / style.GRID_CELL_SIZE - 2
@@ -154,7 +156,7 @@ class ClipboardTray(tray.VTray):
if 'XdndDirectSave0' in context.targets:
window = context.source_window
prop_type, format_, filename = \
- window.property_get('XdndDirectSave0','text/plain')
+ window.property_get('XdndDirectSave0', 'text/plain')
# FIXME query the clipboard service for a filename?
base_dir = tempfile.gettempdir()
@@ -192,12 +194,13 @@ class ClipboardTray(tray.VTray):
if selection.data == 'S':
window = context.source_window
- prop_type, format_, dest = \
- window.property_get('XdndDirectSave0', 'text/plain')
+ prop_type, format_, dest = window.property_get(
+ 'XdndDirectSave0', 'text/plain')
clipboardservice = clipboard.get_instance()
- clipboardservice.add_object_format( \
- object_id, 'XdndDirectSave0', dest, on_disk=True)
+ clipboardservice.add_object_format(object_id,
+ 'XdndDirectSave0',
+ dest, on_disk=True)
else:
self._add_selection(object_id, selection)
@@ -213,4 +216,3 @@ class ClipboardTray(tray.VTray):
return True
else:
return False
-
diff --git a/src/jarabe/frame/devicestray.py b/src/jarabe/frame/devicestray.py
index 72affe3..c5db639 100644
--- a/src/jarabe/frame/devicestray.py
+++ b/src/jarabe/frame/devicestray.py
@@ -15,14 +15,13 @@
# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
import os
-import sys
-import traceback
import logging
from sugar.graphics import tray
from jarabe import config
+
class DevicesTray(tray.HTray):
def __init__(self):
tray.HTray.__init__(self, align=tray.ALIGN_TO_END)
@@ -35,14 +34,14 @@ class DevicesTray(tray.HTray):
locals(), [module_name])
mod.setup(self)
except Exception:
- logging.error('Exception while loading extension:\n' + \
- ''.join(traceback.format_exception(*sys.exc_info())))
+ logging.exception('Exception while loading extension:')
def add_device(self, view):
index = 0
- relative_index = getattr(view, "FRAME_POSITION_RELATIVE", -1)
+ relative_index = getattr(view, 'FRAME_POSITION_RELATIVE', -1)
for item in self.get_children():
- current_relative_index = getattr(item, "FRAME_POSITION_RELATIVE", 0)
+ current_relative_index = getattr(item, 'FRAME_POSITION_RELATIVE',
+ 0)
if current_relative_index >= relative_index:
index += 1
else:
diff --git a/src/jarabe/frame/eventarea.py b/src/jarabe/frame/eventarea.py
index 166aaf5..1b5bf86 100644
--- a/src/jarabe/frame/eventarea.py
+++ b/src/jarabe/frame/eventarea.py
@@ -19,14 +19,14 @@ import gobject
import wnck
import gconf
+
_MAX_DELAY = 1000
+
class EventArea(gobject.GObject):
__gsignals__ = {
- 'enter': (gobject.SIGNAL_RUN_FIRST,
- gobject.TYPE_NONE, ([])),
- 'leave': (gobject.SIGNAL_RUN_FIRST,
- gobject.TYPE_NONE, ([]))
+ 'enter': (gobject.SIGNAL_RUN_FIRST, gobject.TYPE_NONE, ([])),
+ 'leave': (gobject.SIGNAL_RUN_FIRST, gobject.TYPE_NONE, ([])),
}
def __init__(self):
@@ -37,10 +37,11 @@ class EventArea(gobject.GObject):
self._sids = {}
client = gconf.client_get_default()
self._edge_delay = client.get_int('/desktop/sugar/frame/edge_delay')
- self._corner_delay = client.get_int('/desktop/sugar/frame/corner_delay')
+ self._corner_delay = client.get_int('/desktop/sugar/frame'
+ '/corner_delay')
right = gtk.gdk.screen_width() - 1
- bottom = gtk.gdk.screen_height() -1
+ bottom = gtk.gdk.screen_height() - 1
width = gtk.gdk.screen_width() - 2
height = gtk.gdk.screen_height() - 2
@@ -94,6 +95,7 @@ class EventArea(gobject.GObject):
invisible.connect('drag_leave', self._drag_leave_cb)
invisible.realize()
+ # pylint: disable=E1101
invisible.window.set_events(gtk.gdk.POINTER_MOTION_MASK |
gtk.gdk.ENTER_NOTIFY_MASK |
gtk.gdk.LEAVE_NOTIFY_MASK)
diff --git a/src/jarabe/frame/frame.py b/src/jarabe/frame/frame.py
index 7dde55b..079eeeb 100644
--- a/src/jarabe/frame/frame.py
+++ b/src/jarabe/frame/frame.py
@@ -35,6 +35,7 @@ from jarabe.frame.clipboardpanelwindow import ClipboardPanelWindow
from jarabe.frame.notification import NotificationIcon, NotificationWindow
from jarabe.model import notifications
+
TOP_RIGHT = 0
TOP_LEFT = 1
BOTTOM_RIGHT = 2
@@ -43,6 +44,7 @@ BOTTOM_LEFT = 3
_FRAME_HIDING_DELAY = 500
_NOTIFICATION_DURATION = 5000
+
class _Animation(animator.Animation):
def __init__(self, frame, end):
start = frame.current_position
@@ -52,6 +54,7 @@ class _Animation(animator.Animation):
def next_frame(self, current):
self._frame.move(current)
+
class _MouseListener(object):
def __init__(self, frame):
self._frame = frame
@@ -79,6 +82,7 @@ class _MouseListener(object):
self._hide_sid = gobject.timeout_add(
_FRAME_HIDING_DELAY, self._hide_frame_timeout_cb)
+
class _KeyListener(object):
def __init__(self, frame):
self._frame = frame
@@ -90,13 +94,14 @@ class _KeyListener(object):
else:
self._frame.show(Frame.MODE_KEYBOARD)
+
class Frame(object):
- MODE_MOUSE = 0
+ MODE_MOUSE = 0
MODE_KEYBOARD = 1
MODE_NON_INTERACTIVE = 2
def __init__(self):
- logging.debug("STARTUP: Loading the frame")
+ logging.debug('STARTUP: Loading the frame')
self.mode = None
self._palette_group = palettegroup.get_group('frame')
@@ -173,12 +178,12 @@ class Frame(object):
def _create_top_panel(self):
panel = self._create_panel(gtk.POS_TOP)
- # TODO: setting box_width and hippo.PACK_EXPAND looks like a hack to me.
- # Why hippo isn't respecting the request size of these controls?
+ # TODO: setting box_width and hippo.PACK_EXPAND looks like a hack to
+ # me. Why hippo isn't respecting the request size of these controls?
zoom_toolbar = ZoomToolbar()
panel.append(hippo.CanvasWidget(widget=zoom_toolbar,
- box_width=4*style.GRID_CELL_SIZE))
+ box_width=4 * style.GRID_CELL_SIZE))
zoom_toolbar.show()
activities_tray = ActivitiesTray()
@@ -193,7 +198,8 @@ class Frame(object):
# TODO: same issue as in _create_top_panel()
devices_tray = DevicesTray()
- panel.append(hippo.CanvasWidget(widget=devices_tray), hippo.PACK_EXPAND)
+ panel.append(hippo.CanvasWidget(widget=devices_tray),
+ hippo.PACK_EXPAND)
devices_tray.show()
return panel
@@ -348,4 +354,3 @@ class Frame(object):
# Do nothing for now. Our notification UI is so simple, there's no
# point yet.
pass
-
diff --git a/src/jarabe/frame/frameinvoker.py b/src/jarabe/frame/frameinvoker.py
index e4a13e1..a4abfa8 100644
--- a/src/jarabe/frame/frameinvoker.py
+++ b/src/jarabe/frame/frameinvoker.py
@@ -19,6 +19,7 @@ import gtk
from sugar.graphics import style
from sugar.graphics.palette import WidgetInvoker
+
def _get_screen_area():
frame_thickness = style.GRID_CELL_SIZE
@@ -28,6 +29,7 @@ def _get_screen_area():
return gtk.gdk.Rectangle(x, y, width, height)
+
class FrameWidgetInvoker(WidgetInvoker):
def __init__(self, widget):
WidgetInvoker.__init__(self, widget, widget.child)
diff --git a/src/jarabe/frame/framewindow.py b/src/jarabe/frame/framewindow.py
index a7d8fe7..c77e76c 100644
--- a/src/jarabe/frame/framewindow.py
+++ b/src/jarabe/frame/framewindow.py
@@ -19,6 +19,7 @@ import hippo
from sugar.graphics import style
+
class FrameWindow(gtk.Window):
__gtype_name__ = 'SugarFrameWindow'
diff --git a/src/jarabe/frame/friendstray.py b/src/jarabe/frame/friendstray.py
index 141505b..31a9809 100644
--- a/src/jarabe/frame/friendstray.py
+++ b/src/jarabe/frame/friendstray.py
@@ -24,6 +24,7 @@ from jarabe.model import shell
from jarabe.model.buddy import get_owner_instance
from jarabe.model import neighborhood
+
class FriendIcon(TrayIcon):
def __init__(self, buddy):
TrayIcon.__init__(self, icon_name='computer-xo',
@@ -34,6 +35,7 @@ class FriendIcon(TrayIcon):
self.palette.props.icon_visible = False
self.palette.set_group_id('frame')
+
class FriendsTray(VTray):
def __init__(self):
VTray.__init__(self)
@@ -48,7 +50,7 @@ class FriendsTray(VTray):
self.__neighborhood_activity_added_cb)
def add_buddy(self, buddy):
- if self._buddies.has_key(buddy.props.key):
+ if buddy.props.key in self._buddies:
return
icon = FriendIcon(buddy)
@@ -58,7 +60,7 @@ class FriendsTray(VTray):
self._buddies[buddy.props.key] = icon
def remove_buddy(self, buddy):
- if not self._buddies.has_key(buddy.props.key):
+ if buddy.props.key not in self._buddies:
return
self.remove_item(self._buddies[buddy.props.key])
diff --git a/src/jarabe/frame/notification.py b/src/jarabe/frame/notification.py
index 83dc27e..3471e2c 100644
--- a/src/jarabe/frame/notification.py
+++ b/src/jarabe/frame/notification.py
@@ -22,13 +22,14 @@ from sugar.graphics.xocolor import XoColor
from jarabe.view.pulsingicon import PulsingIcon
+
class NotificationIcon(gtk.EventBox):
__gtype_name__ = 'SugarNotificationIcon'
__gproperties__ = {
- 'xo-color' : (object, None, None, gobject.PARAM_READWRITE),
- 'icon-name' : (str, None, None, None, gobject.PARAM_READWRITE),
- 'icon-filename' : (str, None, None, None, gobject.PARAM_READWRITE)
+ 'xo-color': (object, None, None, gobject.PARAM_READWRITE),
+ 'icon-name': (str, None, None, None, gobject.PARAM_READWRITE),
+ 'icon-filename': (str, None, None, None, gobject.PARAM_READWRITE),
}
_PULSE_TIMEOUT = 3
@@ -45,7 +46,8 @@ class NotificationIcon(gtk.EventBox):
self.add(self._icon)
self._icon.show()
- gobject.timeout_add_seconds(self._PULSE_TIMEOUT, self.__stop_pulsing_cb)
+ gobject.timeout_add_seconds(self._PULSE_TIMEOUT,
+ self.__stop_pulsing_cb)
self.set_size_request(style.GRID_CELL_SIZE, style.GRID_CELL_SIZE)
@@ -80,6 +82,7 @@ class NotificationIcon(gtk.EventBox):
palette = property(_get_palette, _set_palette)
+
class NotificationWindow(gtk.Window):
__gtype_name__ = 'SugarNotificationWindow'
@@ -97,4 +100,3 @@ class NotificationWindow(gtk.Window):
color = gtk.gdk.color_parse(style.COLOR_TOOLBAR_GREY.get_html())
self.modify_bg(gtk.STATE_NORMAL, color)
-
diff --git a/src/jarabe/frame/zoomtoolbar.py b/src/jarabe/frame/zoomtoolbar.py
index 2ed3c54..6c10c61 100644
--- a/src/jarabe/frame/zoomtoolbar.py
+++ b/src/jarabe/frame/zoomtoolbar.py
@@ -26,6 +26,7 @@ from sugar.graphics.radiotoolbutton import RadioToolButton
from jarabe.frame.frameinvoker import FrameWidgetInvoker
from jarabe.model import shell
+
class ZoomToolbar(gtk.Toolbar):
def __init__(self):
gtk.Toolbar.__init__(self)
@@ -86,4 +87,3 @@ class ZoomToolbar(gtk.Toolbar):
self._activity_button.props.active = True
else:
raise ValueError('Invalid zoom level: %r' % (new_level))
-
diff --git a/src/jarabe/intro/Makefile.am b/src/jarabe/intro/Makefile.am
index a9fb96b..2ea7cea 100644
--- a/src/jarabe/intro/Makefile.am
+++ b/src/jarabe/intro/Makefile.am
@@ -1,7 +1,3 @@
-imagedir = $(pythondir)/jarabe/intro
-image_DATA = default-picture.png
-
-EXTRA_DIST = $(conf_DATA) $(image_DATA)
sugardir = $(pythondir)/jarabe/intro
sugar_PYTHON = \
__init__.py \
diff --git a/src/jarabe/intro/__init__.py b/src/jarabe/intro/__init__.py
index ca4f64d..d2932f1 100644
--- a/src/jarabe/intro/__init__.py
+++ b/src/jarabe/intro/__init__.py
@@ -8,6 +8,7 @@ from sugar.profile import get_profile
from jarabe.intro.window import IntroWindow
from jarabe.intro.window import create_profile
+
def check_profile():
profile = get_profile()
diff --git a/src/jarabe/intro/colorpicker.py b/src/jarabe/intro/colorpicker.py
index a939857..997199b 100644
--- a/src/jarabe/intro/colorpicker.py
+++ b/src/jarabe/intro/colorpicker.py
@@ -20,6 +20,7 @@ from sugar.graphics.icon import CanvasIcon
from sugar.graphics import style
from sugar.graphics.xocolor import XoColor
+
class ColorPicker(hippo.CanvasBox, hippo.CanvasItem):
def __init__(self, **kwargs):
hippo.CanvasBox.__init__(self, **kwargs)
diff --git a/src/jarabe/intro/default-picture.png b/src/jarabe/intro/default-picture.png
deleted file mode 100644
index e26b9b0..0000000
--- a/src/jarabe/intro/default-picture.png
+++ /dev/null
Binary files differ
diff --git a/src/jarabe/intro/window.py b/src/jarabe/intro/window.py
index 35c0cda..df19fbf 100644
--- a/src/jarabe/intro/window.py
+++ b/src/jarabe/intro/window.py
@@ -32,38 +32,34 @@ from sugar.graphics.xocolor import XoColor
from jarabe.intro import colorpicker
+
_BACKGROUND_COLOR = style.COLOR_WHITE
-def create_profile(name, color=None, pixbuf=None):
- if not pixbuf:
- path = os.path.join(os.path.dirname(__file__), 'default-picture.png')
- pixbuf = gtk.gdk.pixbuf_new_from_file(path)
+def create_profile(name, color=None):
if not color:
color = XoColor()
- icon_path = os.path.join(env.get_profile_path(), "buddy-icon.jpg")
- pixbuf.save(icon_path, "jpeg", {"quality":"85"})
-
client = gconf.client_get_default()
- client.set_string("/desktop/sugar/user/nick", name)
- client.set_string("/desktop/sugar/user/color", color.to_string())
+ client.set_string('/desktop/sugar/user/nick', name)
+ client.set_string('/desktop/sugar/user/color', color.to_string())
+ client.suggest_sync()
# Generate keypair
import commands
- keypath = os.path.join(env.get_profile_path(), "owner.key")
+ keypath = os.path.join(env.get_profile_path(), 'owner.key')
if not os.path.isfile(keypath):
cmd = "ssh-keygen -q -t dsa -f %s -C '' -N ''" % keypath
(s, o) = commands.getstatusoutput(cmd)
if s != 0:
- logging.error("Could not generate key pair: %d %s", s, o)
+ logging.error('Could not generate key pair: %d %s', s, o)
else:
- logging.error("Keypair exists, skip generation.")
+ logging.error('Keypair exists, skip generation.')
+
class _Page(hippo.CanvasBox):
__gproperties__ = {
- 'valid' : (bool, None, None, False,
- gobject.PARAM_READABLE)
+ 'valid': (bool, None, None, False, gobject.PARAM_READABLE),
}
def __init__(self, **kwargs):
@@ -81,6 +77,7 @@ class _Page(hippo.CanvasBox):
def activate(self):
pass
+
class _NamePage(_Page):
def __init__(self, intro):
_Page.__init__(self, xalign=hippo.ALIGNMENT_CENTER,
@@ -90,7 +87,7 @@ class _NamePage(_Page):
self._intro = intro
- label = hippo.CanvasText(text=_("Name:"))
+ label = hippo.CanvasText(text=_('Name:'))
self.append(label)
self._entry = CanvasEntry(box_width=style.zoom(300))
@@ -118,6 +115,7 @@ class _NamePage(_Page):
def activate(self):
self._entry.props.widget.grab_focus()
+
class _ColorPage(_Page):
def __init__(self, **kwargs):
_Page.__init__(self, xalign=hippo.ALIGNMENT_CENTER,
@@ -125,7 +123,7 @@ class _ColorPage(_Page):
spacing=style.DEFAULT_SPACING,
yalign=hippo.ALIGNMENT_CENTER, **kwargs)
- self._label = hippo.CanvasText(text=_("Click to change color:"),
+ self._label = hippo.CanvasText(text=_('Click to change color:'),
xalign=hippo.ALIGNMENT_CENTER)
self.append(self._label)
@@ -138,10 +136,11 @@ class _ColorPage(_Page):
def get_color(self):
return self._cp.get_color()
+
class _IntroBox(hippo.CanvasBox):
__gsignals__ = {
'done': (gobject.SIGNAL_RUN_FIRST, gobject.TYPE_NONE,
- ([gobject.TYPE_PYOBJECT, gobject.TYPE_PYOBJECT]))
+ ([gobject.TYPE_PYOBJECT, gobject.TYPE_PYOBJECT])),
}
PAGE_NAME = 0
@@ -166,13 +165,9 @@ class _IntroBox(hippo.CanvasBox):
self._page = self.PAGE_COLOR
if default_nick == 'system':
pwd_entry = pwd.getpwuid(os.getuid())
- if pwd_entry.pw_gecos:
- nick = pwd_entry.pw_gecos.split(',')[0]
- self._name_page.set_name(nick)
- else:
- self._name_page.set_name(pwd_entry.pw_name)
- else:
- self._name_page.set_name(default_nick)
+ default_nick = (pwd_entry.pw_gecos.split(',')[0] or
+ pwd_entry.pw_name)
+ self._name_page.set_name(default_nick)
self._setup_page()
@@ -255,6 +250,7 @@ class _IntroBox(hippo.CanvasBox):
self.emit('done', name, color)
+
class IntroWindow(gtk.Window):
def __init__(self):
gtk.Window.__init__(self)
@@ -282,16 +278,16 @@ class IntroWindow(gtk.Window):
return False
def __key_press_cb(self, widget, event):
- if gtk.gdk.keyval_name(event.keyval) == "Return":
+ if gtk.gdk.keyval_name(event.keyval) == 'Return':
self._intro_box.next()
return True
- elif gtk.gdk.keyval_name(event.keyval) == "Escape":
+ elif gtk.gdk.keyval_name(event.keyval) == 'Escape':
self._intro_box.back()
return True
return False
-if __name__ == "__main__":
+if __name__ == '__main__':
w = IntroWindow()
w.show()
w.connect('destroy', gtk.main_quit)
diff --git a/src/jarabe/journal/Makefile.am b/src/jarabe/journal/Makefile.am
index f4bf273..ba29062 100644
--- a/src/jarabe/journal/Makefile.am
+++ b/src/jarabe/journal/Makefile.am
@@ -6,6 +6,7 @@ sugar_PYTHON = \
journalactivity.py \
journalentrybundle.py \
journaltoolbox.py \
+ journalwindow.py \
keepicon.py \
listmodel.py \
listview.py \
diff --git a/src/jarabe/journal/detailview.py b/src/jarabe/journal/detailview.py
index b4a2339..aa8c039 100644
--- a/src/jarabe/journal/detailview.py
+++ b/src/jarabe/journal/detailview.py
@@ -27,11 +27,12 @@ from sugar.graphics.icon import CanvasIcon
from jarabe.journal.expandedentry import ExpandedEntry
from jarabe.journal import model
+
class DetailView(gtk.VBox):
__gtype_name__ = 'DetailView'
__gsignals__ = {
- 'go-back-clicked': (gobject.SIGNAL_RUN_FIRST, gobject.TYPE_NONE, ([]))
+ 'go-back-clicked': (gobject.SIGNAL_RUN_FIRST, gobject.TYPE_NONE, ([])),
}
def __init__(self, **kwargs):
@@ -84,6 +85,7 @@ class DetailView(gtk.VBox):
metadata = gobject.property(
type=object, getter=get_metadata, setter=set_metadata)
+
class BackBar(hippo.CanvasBox):
def __init__(self):
hippo.CanvasBox.__init__(self,
diff --git a/src/jarabe/journal/expandedentry.py b/src/jarabe/journal/expandedentry.py
index 725c0f9..fe2f320 100644
--- a/src/jarabe/journal/expandedentry.py
+++ b/src/jarabe/journal/expandedentry.py
@@ -36,6 +36,7 @@ from jarabe.journal.palettes import ObjectPalette, BuddyPalette
from jarabe.journal import misc
from jarabe.journal import model
+
class Separator(hippo.CanvasBox, hippo.CanvasItem):
def __init__(self, orientation):
hippo.CanvasBox.__init__(self,
@@ -46,6 +47,7 @@ class Separator(hippo.CanvasBox, hippo.CanvasItem):
else:
self.props.box_height = style.LINE_WIDTH
+
class BuddyList(hippo.CanvasBox):
def __init__(self, buddies):
hippo.CanvasBox.__init__(self, xalign=hippo.ALIGNMENT_START,
@@ -61,6 +63,7 @@ class BuddyList(hippo.CanvasBox):
hbox.append(icon)
self.append(hbox)
+
class ExpandedEntry(hippo.CanvasBox):
def __init__(self):
hippo.CanvasBox.__init__(self)
@@ -209,9 +212,7 @@ class ExpandedEntry(hippo.CanvasBox):
height = style.zoom(240)
box = hippo.CanvasBox()
- if self._metadata.has_key('preview') and \
- len(self._metadata['preview']) > 4:
-
+ if len(self._metadata.get('preview', '')) > 4:
if self._metadata['preview'][1:4] == 'PNG':
preview_data = self._metadata['preview']
else:
@@ -280,10 +281,15 @@ class ExpandedEntry(hippo.CanvasBox):
def _format_date(self):
if 'timestamp' in self._metadata:
- timestamp = float(self._metadata['timestamp'])
- return time.strftime('%x', time.localtime(timestamp))
- else:
- return _('No date')
+ try:
+ timestamp = float(self._metadata['timestamp'])
+ except (ValueError, TypeError):
+ logging.warning('Invalid timestamp for %r: %r',
+ self._metadata['uid'],
+ self._metadata['timestamp'])
+ else:
+ return time.strftime('%x', time.localtime(timestamp))
+ return _('No date')
def _create_buddy_list(self):
@@ -301,8 +307,7 @@ class ExpandedEntry(hippo.CanvasBox):
vbox.append(text)
- if self._metadata.has_key('buddies') and \
- self._metadata['buddies']:
+ if self._metadata.get('buddies'):
buddies = simplejson.loads(self._metadata['buddies']).values()
vbox.append(BuddyList(buddies))
return vbox
diff --git a/src/jarabe/journal/journalactivity.py b/src/jarabe/journal/journalactivity.py
index 44cc018..a33038a 100644
--- a/src/jarabe/journal/journalactivity.py
+++ b/src/jarabe/journal/journalactivity.py
@@ -17,8 +17,6 @@
import logging
from gettext import gettext as _
-import sys
-import traceback
import uuid
import gtk
@@ -44,6 +42,8 @@ from jarabe.journal.journalentrybundle import JournalEntryBundle
from jarabe.journal.objectchooser import ObjectChooser
from jarabe.journal.modalalert import ModalAlert
from jarabe.journal import model
+from jarabe.journal.journalwindow import JournalWindow
+
J_DBUS_SERVICE = 'org.laptop.Journal'
J_DBUS_INTERFACE = 'org.laptop.Journal'
@@ -52,6 +52,9 @@ J_DBUS_PATH = '/org/laptop/Journal'
_SPACE_TRESHOLD = 52428800
_BUNDLE_ID = 'org.laptop.JournalActivity'
+_journal = None
+
+
class JournalActivityDBusService(dbus.service.Object):
def __init__(self, parent):
self._parent = parent
@@ -81,7 +84,8 @@ class JournalActivityDBusService(dbus.service.Object):
chooser.destroy()
del chooser
- @dbus.service.method(J_DBUS_INTERFACE, in_signature='is', out_signature='s')
+ @dbus.service.method(J_DBUS_INTERFACE, in_signature='is',
+ out_signature='s')
def ChooseObject(self, parent_xid, what_filter=''):
chooser_id = uuid.uuid4().hex
if parent_xid > 0:
@@ -94,18 +98,19 @@ class JournalActivityDBusService(dbus.service.Object):
return chooser_id
- @dbus.service.signal(J_DBUS_INTERFACE, signature="ss")
+ @dbus.service.signal(J_DBUS_INTERFACE, signature='ss')
def ObjectChooserResponse(self, chooser_id, object_id):
pass
- @dbus.service.signal(J_DBUS_INTERFACE, signature="s")
+ @dbus.service.signal(J_DBUS_INTERFACE, signature='s')
def ObjectChooserCancelled(self, chooser_id):
pass
-class JournalActivity(Window):
+
+class JournalActivity(JournalWindow):
def __init__(self):
- logging.debug("STARTUP: Loading the journal")
- Window.__init__(self)
+ logging.debug('STARTUP: Loading the journal')
+ JournalWindow.__init__(self)
self.set_title(_('Journal'))
@@ -223,8 +228,7 @@ class JournalActivity(Window):
try:
self._detail_toolbox.entry_toolbar.set_metadata(metadata)
except Exception:
- logging.error('Exception while displaying entry:\n' + \
- ''.join(traceback.format_exception(*sys.exc_info())))
+ logging.exception('Exception while displaying entry:')
self.set_toolbar_box(self._detail_toolbox)
self._detail_toolbox.show()
@@ -232,8 +236,7 @@ class JournalActivity(Window):
try:
self._detail_view.props.metadata = metadata
except Exception:
- logging.error('Exception while displaying entry:\n' + \
- ''.join(traceback.format_exception(*sys.exc_info())))
+ logging.exception('Exception while displaying entry:')
self.set_canvas(self._secondary_view)
self._secondary_view.show()
@@ -327,11 +330,11 @@ class JournalActivity(Window):
self._list_view.set_is_visible(visible)
def _check_available_space(self):
- ''' Check available space on device
+ """Check available space on device
If the available space is below 50MB an alert will be
shown which encourages to delete old journal entries.
- '''
+ """
if self._critical_space_alert:
return
@@ -358,7 +361,6 @@ class JournalActivity(Window):
self.show_main_view()
self.search_grab_focus()
-_journal = None
def get_journal():
global _journal
@@ -367,6 +369,6 @@ def get_journal():
_journal.show()
return _journal
+
def start():
get_journal()
-
diff --git a/src/jarabe/journal/journalentrybundle.py b/src/jarabe/journal/journalentrybundle.py
index 41777c7..c220c09 100644
--- a/src/jarabe/journal/journalentrybundle.py
+++ b/src/jarabe/journal/journalentrybundle.py
@@ -25,6 +25,7 @@ from sugar.bundle.bundle import Bundle, MalformedBundleException
from jarabe.journal import model
+
class JournalEntryBundle(Bundle):
"""A Journal entry bundle
@@ -41,7 +42,7 @@ class JournalEntryBundle(Bundle):
Bundle.__init__(self, path)
def install(self, uid=''):
- if os.environ.has_key('SUGAR_ACTIVITY_ROOT'):
+ if 'SUGAR_ACTIVITY_ROOT' in os.environ:
install_dir = os.path.join(os.environ['SUGAR_ACTIVITY_ROOT'],
'data')
else:
@@ -91,4 +92,3 @@ class JournalEntryBundle(Bundle):
def is_installed(self):
# These bundles can be reinstalled as many times as desired.
return False
-
diff --git a/src/jarabe/journal/journaltoolbox.py b/src/jarabe/journal/journaltoolbox.py
index cbf105d..cdf998d 100644
--- a/src/jarabe/journal/journaltoolbox.py
+++ b/src/jarabe/journal/journaltoolbox.py
@@ -43,6 +43,7 @@ from jarabe.model import bundleregistry
from jarabe.journal import misc
from jarabe.journal import model
+
_AUTOSEARCH_TIMEOUT = 1000
_ACTION_ANYTIME = 0
@@ -68,13 +69,13 @@ class MainToolbox(Toolbox):
self.add_toolbar(_('Search'), self.search_toolbar)
self.search_toolbar.show()
+
class SearchToolbar(gtk.Toolbar):
__gtype_name__ = 'SearchToolbar'
__gsignals__ = {
- 'query-changed': (gobject.SIGNAL_RUN_FIRST,
- gobject.TYPE_NONE,
- ([object]))
+ 'query-changed': (gobject.SIGNAL_RUN_FIRST, gobject.TYPE_NONE,
+ ([object])),
}
def __init__(self):
@@ -109,8 +110,6 @@ class SearchToolbar(gtk.Toolbar):
self.insert(tool_item, -1)
tool_item.show()
- self._add_separator(expand=True)
-
self._sorting_button = SortingButton()
self._sorting_button.connect('clicked',
self.__sorting_button_clicked_cb)
@@ -164,17 +163,6 @@ class SearchToolbar(gtk.Toolbar):
with_search.connect('changed', self._combo_changed_cb)
return with_search
- def _add_separator(self, expand=False):
- separator = gtk.SeparatorToolItem()
- separator.props.draw = False
- if expand:
- separator.set_expand(True)
- else:
- separator.set_size_request(style.GRID_CELL_SIZE,
- style.GRID_CELL_SIZE)
- self.insert(separator, -1)
- separator.show()
-
def _add_widget(self, widget, expand=False):
tool_item = gtk.ToolItem()
tool_item.set_expand(expand)
@@ -355,6 +343,7 @@ class SearchToolbar(gtk.Toolbar):
self._when_search_combo.set_active(0)
self._favorite_button.props.active = False
+
class DetailToolbox(Toolbox):
def __init__(self):
Toolbox.__init__(self)
@@ -363,12 +352,13 @@ class DetailToolbox(Toolbox):
self.add_toolbar('', self.entry_toolbar)
self.entry_toolbar.show()
+
class EntryToolbar(gtk.Toolbar):
__gsignals__ = {
- 'volume-error': (gobject.SIGNAL_RUN_FIRST,
- gobject.TYPE_NONE,
- ([str, str]))
+ 'volume-error': (gobject.SIGNAL_RUN_FIRST, gobject.TYPE_NONE,
+ ([str, str])),
}
+
def __init__(self):
gtk.Toolbar.__init__(self)
@@ -451,7 +441,7 @@ class EntryToolbar(gtk.Toolbar):
model.copy(self._metadata, mount_point)
except IOError, e:
logging.exception('Error while copying the entry. %s', e.strerror)
- self.emit('volume-error',
+ self.emit('volume-error',
_('Error while copying the entry. %s') % e.strerror,
_('Error'))
diff --git a/src/jarabe/journal/journalwindow.py b/src/jarabe/journal/journalwindow.py
new file mode 100644
index 0000000..31bc790
--- /dev/null
+++ b/src/jarabe/journal/journalwindow.py
@@ -0,0 +1,33 @@
+#Copyright (C) 2010 Software for Education, Entertainment and Training
+#Activities
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+
+from sugar.graphics.window import Window
+
+_journal_window = None
+
+
+class JournalWindow(Window):
+
+ def __init__(self):
+
+ global _journal_window
+ Window.__init__(self)
+ _journal_window = self
+
+
+def get_journal_window():
+ return _journal_window
diff --git a/src/jarabe/journal/keepicon.py b/src/jarabe/journal/keepicon.py
index 2c692c6..1253afc 100644
--- a/src/jarabe/journal/keepicon.py
+++ b/src/jarabe/journal/keepicon.py
@@ -22,6 +22,7 @@ from sugar.graphics.icon import CanvasIcon
from sugar.graphics import style
from sugar.graphics.xocolor import XoColor
+
class KeepIcon(CanvasIcon):
def __init__(self, keep):
CanvasIcon.__init__(self, icon_name='emblem-favorite',
diff --git a/src/jarabe/journal/listmodel.py b/src/jarabe/journal/listmodel.py
index 3378350..3902eba 100644
--- a/src/jarabe/journal/listmodel.py
+++ b/src/jarabe/journal/listmodel.py
@@ -19,7 +19,6 @@ import logging
import simplejson
import gobject
import gtk
-import time
from gettext import gettext as _
from sugar.graphics.xocolor import XoColor
@@ -29,20 +28,18 @@ from sugar import util
from jarabe.journal import model
from jarabe.journal import misc
+
DS_DBUS_SERVICE = 'org.laptop.sugar.DataStore'
DS_DBUS_INTERFACE = 'org.laptop.sugar.DataStore'
DS_DBUS_PATH = '/org/laptop/sugar/DataStore'
+
class ListModel(gtk.GenericTreeModel, gtk.TreeDragSource):
__gtype_name__ = 'JournalListModel'
__gsignals__ = {
- 'ready': (gobject.SIGNAL_RUN_FIRST,
- gobject.TYPE_NONE,
- ([])),
- 'progress': (gobject.SIGNAL_RUN_FIRST,
- gobject.TYPE_NONE,
- ([])),
+ 'ready': (gobject.SIGNAL_RUN_FIRST, gobject.TYPE_NONE, ([])),
+ 'progress': (gobject.SIGNAL_RUN_FIRST, gobject.TYPE_NONE, ([])),
}
COLUMN_UID = 0
@@ -58,18 +55,20 @@ class ListModel(gtk.GenericTreeModel, gtk.TreeDragSource):
COLUMN_BUDDY_2 = 10
COLUMN_BUDDY_3 = 11
- _COLUMN_TYPES = {COLUMN_UID: str,
- COLUMN_FAVORITE: bool,
- COLUMN_ICON: str,
- COLUMN_ICON_COLOR: object,
- COLUMN_TITLE: str,
- COLUMN_TIMESTAMP: str,
- COLUMN_CREATION_TIME: str,
- COLUMN_FILESIZE: str,
- COLUMN_PROGRESS: int,
- COLUMN_BUDDY_1: object,
- COLUMN_BUDDY_3: object,
- COLUMN_BUDDY_2: object}
+ _COLUMN_TYPES = {
+ COLUMN_UID: str,
+ COLUMN_FAVORITE: bool,
+ COLUMN_ICON: str,
+ COLUMN_ICON_COLOR: object,
+ COLUMN_TITLE: str,
+ COLUMN_TIMESTAMP: str,
+ COLUMN_CREATION_TIME: str,
+ COLUMN_FILESIZE: str,
+ COLUMN_PROGRESS: int,
+ COLUMN_BUDDY_1: object,
+ COLUMN_BUDDY_3: object,
+ COLUMN_BUDDY_2: object,
+ }
_PAGE_SIZE = 10
@@ -141,11 +140,17 @@ class ListModel(gtk.GenericTreeModel, gtk.TreeDragSource):
xo_color = misc.get_icon_color(metadata)
self._cached_row.append(xo_color)
- title = gobject.markup_escape_text(metadata.get('title', None))
- self._cached_row.append('<b>%s</b>' % title)
+ title = gobject.markup_escape_text(metadata.get('title',
+ _('Untitled')))
+ self._cached_row.append('<b>%s</b>' % (title, ))
- timestamp = int(metadata.get('timestamp', 0))
- self._cached_row.append(util.timestamp_to_elapsed_string(timestamp))
+ try:
+ timestamp = float(metadata.get('timestamp', 0))
+ except (TypeError, ValueError):
+ timestamp_content = _('Unknown')
+ else:
+ timestamp_content = util.timestamp_to_elapsed_string(timestamp)
+ self._cached_row.append(timestamp_content)
try:
creation_time = float(metadata.get('creation_time'))
@@ -162,19 +167,37 @@ class ListModel(gtk.GenericTreeModel, gtk.TreeDragSource):
else:
self._cached_row.append(util.format_size(size))
- self._cached_row.append(int(metadata.get('progress', 100)))
-
- if metadata.get('buddies', ''):
- buddies = simplejson.loads(metadata['buddies']).values()
- else:
+ try:
+ progress = int(float(metadata.get('progress', 100)))
+ except (TypeError, ValueError):
+ progress = 100
+ self._cached_row.append(progress)
+
+ buddies = []
+ if metadata.get('buddies'):
+ try:
+ buddies = simplejson.loads(metadata['buddies']).values()
+ except simplejson.decoder.JSONDecodeError, exception:
+ logging.warning('Cannot decode buddies for %r: %s',
+ metadata['uid'], exception)
+
+ if not isinstance(buddies, list):
+ logging.warning('Content of buddies for %r is not a list: %r',
+ metadata['uid'], buddies)
buddies = []
for n_ in xrange(0, 3):
if buddies:
- nick, color = buddies.pop(0)
- self._cached_row.append((nick, XoColor(color)))
- else:
- self._cached_row.append(None)
+ try:
+ nick, color = buddies.pop(0)
+ except (AttributeError, ValueError), exception:
+ logging.warning('Malformed buddies for %r: %s',
+ metadata['uid'], exception)
+ else:
+ self._cached_row.append((nick, XoColor(color)))
+ continue
+
+ self._cached_row.append(None)
return self._cached_row[column]
@@ -219,4 +242,3 @@ class ListModel(gtk.GenericTreeModel, gtk.TreeDragSource):
return True
return False
-
diff --git a/src/jarabe/journal/listview.py b/src/jarabe/journal/listview.py
index 3d6281a..0aee1b7 100644
--- a/src/jarabe/journal/listview.py
+++ b/src/jarabe/journal/listview.py
@@ -34,11 +34,13 @@ from jarabe.journal.palettes import ObjectPalette, BuddyPalette
from jarabe.journal import model
from jarabe.journal import misc
+
UPDATE_INTERVAL = 300
MESSAGE_EMPTY_JOURNAL = 0
MESSAGE_NO_MATCH = 1
+
class TreeView(gtk.TreeView):
__gtype_name__ = 'JournalTreeView'
@@ -47,8 +49,8 @@ class TreeView(gtk.TreeView):
self.set_headers_visible(False)
def do_size_request(self, requisition):
- # HACK: We tell the model that the view is just resizing so it can avoid
- # hitting both D-Bus and disk.
+ # HACK: We tell the model that the view is just resizing so it can
+ # avoid hitting both D-Bus and disk.
tree_model = self.get_model()
if tree_model is not None:
tree_model.view_is_resizing = True
@@ -58,13 +60,12 @@ class TreeView(gtk.TreeView):
if tree_model is not None:
tree_model.view_is_resizing = False
+
class BaseListView(gtk.Bin):
__gtype_name__ = 'JournalBaseListView'
__gsignals__ = {
- 'clear-clicked': (gobject.SIGNAL_RUN_FIRST,
- gobject.TYPE_NONE,
- ([]))
+ 'clear-clicked': (gobject.SIGNAL_RUN_FIRST, gobject.TYPE_NONE, ([])),
}
def __init__(self):
@@ -81,7 +82,8 @@ class BaseListView(gtk.Bin):
self.connect('destroy', self.__destroy_cb)
self._scrolled_window = gtk.ScrolledWindow()
- self._scrolled_window.set_policy(gtk.POLICY_NEVER, gtk.POLICY_AUTOMATIC)
+ self._scrolled_window.set_policy(gtk.POLICY_NEVER,
+ gtk.POLICY_AUTOMATIC)
self.add(self._scrolled_window)
self._scrolled_window.show()
@@ -141,7 +143,8 @@ class BaseListView(gtk.Bin):
column.props.sizing = gtk.TREE_VIEW_COLUMN_FIXED
column.props.fixed_width = self.cell_icon.props.width
column.pack_start(self.cell_icon)
- column.add_attribute(self.cell_icon, 'file-name', ListModel.COLUMN_ICON)
+ column.add_attribute(self.cell_icon, 'file-name',
+ ListModel.COLUMN_ICON)
column.add_attribute(self.cell_icon, 'xo-color',
ListModel.COLUMN_ICON_COLOR)
self.tree_view.append_column(column)
@@ -163,7 +166,8 @@ class BaseListView(gtk.Bin):
buddies_column.props.sizing = gtk.TREE_VIEW_COLUMN_FIXED
self.tree_view.append_column(buddies_column)
- for column_index in [ListModel.COLUMN_BUDDY_1, ListModel.COLUMN_BUDDY_2,
+ for column_index in [ListModel.COLUMN_BUDDY_1,
+ ListModel.COLUMN_BUDDY_2,
ListModel.COLUMN_BUDDY_3]:
cell_icon = CellRendererBuddy(self.tree_view,
column_index=column_index)
@@ -197,7 +201,8 @@ class BaseListView(gtk.Bin):
self.sort_column.props.resizable = True
self.sort_column.props.clickable = True
self.sort_column.pack_start(cell_text)
- self.sort_column.add_attribute(cell_text, 'text', ListModel.COLUMN_TIMESTAMP)
+ self.sort_column.add_attribute(cell_text, 'text',
+ ListModel.COLUMN_TIMESTAMP)
self.tree_view.append_column(self.sort_column)
def _get_width_for_string(self, text):
@@ -321,12 +326,9 @@ class BaseListView(gtk.Bin):
def _is_query_empty(self):
# FIXME: This is a hack, we shouldn't have to update this every time
# a new search term is added.
- if self._query.get('query', '') or self._query.get('mime_type', '') or \
- self._query.get('keep', '') or self._query.get('mtime', '') or \
- self._query.get('activity', ''):
- return False
- else:
- return True
+ return not (self._query.get('query') or self._query.get('mime_type') or
+ self._query.get('keep') or self._query.get('mtime') or
+ self._query.get('activity'))
def __model_progress_cb(self, tree_model):
if self._progress_bar is None:
@@ -370,8 +372,8 @@ class BaseListView(gtk.Bin):
icon = CanvasIcon(size=style.LARGE_ICON_SIZE,
icon_name='activity-journal',
- stroke_color = style.COLOR_BUTTON_GREY.get_svg(),
- fill_color = style.COLOR_TRANSPARENT.get_svg())
+ stroke_color=style.COLOR_BUTTON_GREY.get_svg(),
+ fill_color=style.COLOR_TRANSPARENT.get_svg())
box.append(icon)
if message == MESSAGE_EMPTY_JOURNAL:
@@ -384,7 +386,7 @@ class BaseListView(gtk.Bin):
text = hippo.CanvasText(text=text,
xalign=hippo.ALIGNMENT_CENTER,
font_desc=style.FONT_BOLD.get_pango_desc(),
- color = style.COLOR_BUTTON_GREY.get_int())
+ color=style.COLOR_BUTTON_GREY.get_int())
box.append(text)
if message == MESSAGE_NO_MATCH:
@@ -420,7 +422,7 @@ class BaseListView(gtk.Bin):
while True:
x, y, width, height = self.tree_view.get_cell_area(path,
- self.sort_column)
+ self.sort_column)
x, y = self.tree_view.convert_tree_to_widget_coords(x, y)
self.tree_view.queue_draw_area(x, y, width, height)
if path == end_path:
@@ -460,13 +462,13 @@ class BaseListView(gtk.Bin):
self.update_dates()
return True
+
class ListView(BaseListView):
__gtype_name__ = 'JournalListView'
__gsignals__ = {
- 'detail-clicked': (gobject.SIGNAL_RUN_FIRST,
- gobject.TYPE_NONE,
- ([object]))
+ 'detail-clicked': (gobject.SIGNAL_RUN_FIRST, gobject.TYPE_NONE,
+ ([object])),
}
def __init__(self):
@@ -538,6 +540,7 @@ class ListView(BaseListView):
def __editing_canceled_cb(self, cell):
self.cell_title.props.editable = False
+
class CellRendererFavorite(CellRendererIcon):
__gtype_name__ = 'JournalCellRendererFavorite'
@@ -552,6 +555,7 @@ class CellRendererFavorite(CellRendererIcon):
self.props.prelit_stroke_color = style.COLOR_BUTTON_GREY.get_svg()
self.props.prelit_fill_color = style.COLOR_BUTTON_GREY.get_svg()
+
class CellRendererDetail(CellRendererIcon):
__gtype_name__ = 'JournalCellRendererDetail'
@@ -568,12 +572,12 @@ class CellRendererDetail(CellRendererIcon):
self.props.prelit_stroke_color = style.COLOR_TRANSPARENT.get_svg()
self.props.prelit_fill_color = style.COLOR_BLACK.get_svg()
+
class CellRendererActivityIcon(CellRendererIcon):
__gtype_name__ = 'JournalCellRendererActivityIcon'
__gsignals__ = {
- 'detail-clicked': (gobject.SIGNAL_RUN_FIRST,
- gobject.TYPE_NONE,
+ 'detail-clicked': (gobject.SIGNAL_RUN_FIRST, gobject.TYPE_NONE,
([str])),
}
@@ -610,6 +614,7 @@ class CellRendererActivityIcon(CellRendererIcon):
show_palette = gobject.property(type=bool, default=True,
setter=set_show_palette)
+
class CellRendererBuddy(CellRendererIcon):
__gtype_name__ = 'JournalCellRendererBuddy'
@@ -643,4 +648,3 @@ class CellRendererBuddy(CellRendererIcon):
self.props.xo_color = xo_color
buddy = gobject.property(type=object, setter=set_buddy)
-
diff --git a/src/jarabe/journal/misc.py b/src/jarabe/journal/misc.py
index 657b60e..1431d5f 100644
--- a/src/jarabe/journal/misc.py
+++ b/src/jarabe/journal/misc.py
@@ -27,8 +27,10 @@ from sugar.activity import activityfactory
from sugar.activity.activityhandle import ActivityHandle
from sugar.graphics.icon import get_icon_file_name
from sugar.graphics.xocolor import XoColor
+from sugar.graphics.alert import ConfirmationAlert
from sugar import mime
from sugar.bundle.activitybundle import ActivityBundle
+from sugar.bundle.bundle import AlreadyInstalledException
from sugar.bundle.contentbundle import ContentBundle
from sugar import util
@@ -36,6 +38,8 @@ from jarabe.view import launcher
from jarabe.model import bundleregistry, shell
from jarabe.journal.journalentrybundle import JournalEntryBundle
from jarabe.journal import model
+from jarabe.journal import journalwindow
+
def _get_icon_for_mime(mime_type):
generic_types = mime.get_all_generic_types()
@@ -52,6 +56,7 @@ def _get_icon_for_mime(mime_type):
if file_name is not None:
return file_name
+
def get_icon_name(metadata):
file_name = None
@@ -81,35 +86,46 @@ def get_icon_name(metadata):
return file_name
+
def get_date(metadata):
""" Convert from a string in iso format to a more human-like format. """
- if metadata.has_key('timestamp'):
- timestamp = float(metadata['timestamp'])
- return util.timestamp_to_elapsed_string(timestamp)
- elif metadata.has_key('mtime'):
- ti = time.strptime(metadata['mtime'], "%Y-%m-%dT%H:%M:%S")
- return util.timestamp_to_elapsed_string(time.mktime(ti))
- else:
- return _('No date')
+ if 'timestamp' in metadata:
+ try:
+ timestamp = float(metadata['timestamp'])
+ except (TypeError, ValueError):
+ logging.warning('Invalid timestamp: %r', metadata['timestamp'])
+ else:
+ return util.timestamp_to_elapsed_string(timestamp)
+
+ if 'mtime' in metadata:
+ try:
+ ti = time.strptime(metadata['mtime'], '%Y-%m-%dT%H:%M:%S')
+ except (TypeError, ValueError):
+ logging.warning('Invalid mtime: %r', metadata['mtime'])
+ else:
+ return util.timestamp_to_elapsed_string(time.mktime(ti))
+
+ return _('No date')
+
def get_bundle(metadata):
try:
if is_activity_bundle(metadata):
- file_path = util.TempFilePath(model.get_file(metadata['uid']))
+ file_path = model.get_file(metadata['uid'])
if not os.path.exists(file_path):
logging.warning('Invalid path: %r', file_path)
return None
return ActivityBundle(file_path)
elif is_content_bundle(metadata):
- file_path = util.TempFilePath(model.get_file(metadata['uid']))
+ file_path = model.get_file(metadata['uid'])
if not os.path.exists(file_path):
logging.warning('Invalid path: %r', file_path)
return None
return ContentBundle(file_path)
elif is_journal_bundle(metadata):
- file_path = util.TempFilePath(model.get_file(metadata['uid']))
+ file_path = model.get_file(metadata['uid'])
if not os.path.exists(file_path):
logging.warning('Invalid path: %r', file_path)
return None
@@ -120,6 +136,7 @@ def get_bundle(metadata):
logging.exception('Incorrect bundle')
return None
+
def _get_activities_for_mime(mime_type):
registry = bundleregistry.get_registry()
result = registry.get_activities_for_type(mime_type)
@@ -130,6 +147,7 @@ def _get_activities_for_mime(mime_type):
result.append(activity)
return result
+
def get_activities(metadata):
activities = []
@@ -148,6 +166,7 @@ def get_activities(metadata):
return activities
+
def resume(metadata, bundle_id=None):
registry = bundleregistry.get_registry()
@@ -159,19 +178,16 @@ def resume(metadata, bundle_id=None):
bundle = ActivityBundle(file_path)
if not registry.is_installed(bundle):
logging.debug('Installing activity bundle')
- registry.install(bundle)
+ try:
+ registry.install(bundle)
+ except AlreadyInstalledException:
+ _downgrade_option_alert(bundle)
+ return
else:
logging.debug('Upgrading activity bundle')
registry.upgrade(bundle)
- logging.debug('activityfactory.creating bundle with id %r',
- bundle.get_bundle_id())
- installed_bundle = registry.get_bundle(bundle.get_bundle_id())
- if installed_bundle:
- launch(installed_bundle)
- else:
- logging.error('Bundle %r is not installed.',
- bundle.get_bundle_id())
+ _launch_bundle(bundle)
elif is_content_bundle(metadata) and bundle_id is None:
@@ -206,7 +222,6 @@ def resume(metadata, bundle_id=None):
bundle = registry.get_bundle(bundle_id)
-
if metadata.get('mountpoint', '/') == '/':
object_id = metadata['uid']
else:
@@ -215,9 +230,22 @@ def resume(metadata, bundle_id=None):
launch(bundle, activity_id=activity_id, object_id=object_id,
color=get_icon_color(metadata))
+
+def _launch_bundle(bundle):
+ registry = bundleregistry.get_registry()
+ logging.debug('activityfactory.creating bundle with id %r',
+ bundle.get_bundle_id())
+ installed_bundle = registry.get_bundle(bundle.get_bundle_id())
+ if installed_bundle:
+ launch(installed_bundle)
+ else:
+ logging.error('Bundle %r is not installed.',
+ bundle.get_bundle_id())
+
+
def launch(bundle, activity_id=None, object_id=None, uri=None, color=None,
invited=False):
- if activity_id is None:
+ if activity_id is None or not activity_id:
activity_id = activityfactory.create_activity_id()
logging.debug('launch bundle_id=%s activity_id=%s object_id=%s uri=%s',
@@ -239,21 +267,46 @@ def launch(bundle, activity_id=None, object_id=None, uri=None, color=None,
object_id=object_id, uri=uri, invited=invited)
activityfactory.create(bundle, activity_handle)
+
+def _downgrade_option_alert(bundle):
+ alert = ConfirmationAlert()
+ alert.props.title = _('Older Version Of %s Activity') % (bundle.get_name())
+ alert.props.msg = _('Do you want to downgrade to version %s') % \
+ bundle.get_activity_version()
+ alert.connect('response', _downgrade_alert_response_cb, bundle)
+ journalwindow.get_journal_window().add_alert(alert)
+ alert.show()
+
+
+def _downgrade_alert_response_cb(alert, response_id, bundle):
+ if response_id is gtk.RESPONSE_OK:
+ journalwindow.get_journal_window().remove_alert(alert)
+ registry = bundleregistry.get_registry()
+ registry.install(bundle, force_downgrade=True)
+ _launch_bundle(bundle)
+ elif response_id is gtk.RESPONSE_CANCEL:
+ journalwindow.get_journal_window().remove_alert(alert)
+
+
def is_activity_bundle(metadata):
mime_type = metadata.get('mime_type', '')
return mime_type == ActivityBundle.MIME_TYPE or \
mime_type == ActivityBundle.DEPRECATED_MIME_TYPE
+
def is_content_bundle(metadata):
return metadata.get('mime_type', '') == ContentBundle.MIME_TYPE
+
def is_journal_bundle(metadata):
return metadata.get('mime_type', '') == JournalEntryBundle.MIME_TYPE
+
def is_bundle(metadata):
return is_activity_bundle(metadata) or is_content_bundle(metadata) or \
is_journal_bundle(metadata)
+
def get_icon_color(metadata):
if metadata is None or not 'icon-color' in metadata:
client = gconf.client_get_default()
diff --git a/src/jarabe/journal/modalalert.py b/src/jarabe/journal/modalalert.py
index c7c6a0a..6880941 100644
--- a/src/jarabe/journal/modalalert.py
+++ b/src/jarabe/journal/modalalert.py
@@ -22,6 +22,7 @@ from sugar.graphics.icon import Icon
from sugar.graphics import style
from sugar.graphics.xocolor import XoColor
+
class ModalAlert(gtk.Window):
__gtype_name__ = 'SugarModalAlert'
@@ -84,14 +85,12 @@ class ModalAlert(gtk.Window):
self.add(self._main_view)
self._main_view.show()
- self.connect("realize", self.__realize_cb)
+ self.connect('realize', self.__realize_cb)
def __realize_cb(self, widget):
self.window.set_type_hint(gtk.gdk.WINDOW_TYPE_HINT_DIALOG)
self.window.set_accept_focus(True)
def __show_journal_cb(self, button):
- '''The opener will listen on the destroy signal
- '''
+ """The opener will listen on the destroy signal"""
self.destroy()
-
diff --git a/src/jarabe/journal/model.py b/src/jarabe/journal/model.py
index 81ca7d4..320e577 100644
--- a/src/jarabe/journal/model.py
+++ b/src/jarabe/journal/model.py
@@ -1,4 +1,4 @@
-# Copyright (C) 2007-2008, One Laptop Per Child
+# Copyright (C) 2007-2010, One Laptop per Child
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
@@ -16,10 +16,11 @@
import logging
import os
+import errno
from datetime import datetime
import time
import shutil
-from stat import S_IFMT, S_IFDIR, S_IFREG
+from stat import S_IFLNK, S_IFMT, S_IFDIR, S_IFREG
import re
from operator import itemgetter
@@ -32,18 +33,25 @@ from sugar import dispatch
from sugar import mime
from sugar import util
+
DS_DBUS_SERVICE = 'org.laptop.sugar.DataStore'
DS_DBUS_INTERFACE = 'org.laptop.sugar.DataStore'
DS_DBUS_PATH = '/org/laptop/sugar/DataStore'
# Properties the journal cares about.
-PROPERTIES = ['uid', 'title', 'mtime', 'timestamp', 'creation_time', 'filesize',
- 'keep', 'buddies', 'icon-color', 'mime_type', 'progress',
- 'activity', 'mountpoint', 'activity_id', 'bundle_id']
+PROPERTIES = ['activity', 'activity_id', 'buddies', 'bundle_id',
+ 'creation_time', 'filesize', 'icon-color', 'keep', 'mime_type',
+ 'mountpoint', 'mtime', 'progress', 'timestamp', 'title', 'uid']
MIN_PAGES_TO_CACHE = 3
MAX_PAGES_TO_CACHE = 5
+_datastore = None
+created = dispatch.Signal()
+updated = dispatch.Signal()
+deleted = dispatch.Signal()
+
+
class _Cache(object):
__gtype_name__ = 'model_Cache'
@@ -74,7 +82,7 @@ class BaseResultSet(object):
"""
def __init__(self, query, page_size):
- self._total_count = -1
+ self._total_count = -1
self._position = -1
self._query = query
self._page_size = page_size
@@ -141,7 +149,8 @@ class BaseResultSet(object):
self._cache.append_all(entries)
self._offset = offset
- elif remaining_forward_entries <= 0 and remaining_backwards_entries > 0:
+ elif (remaining_forward_entries <= 0 and
+ remaining_backwards_entries > 0):
# Add one page to the end of cache
logging.debug('appending one more page, offset: %r',
@@ -186,6 +195,7 @@ class BaseResultSet(object):
return self._cache[self._position - self._offset]
+
class DatastoreResultSet(BaseResultSet):
"""Encapsulates the result of a query on the datastore
"""
@@ -213,6 +223,7 @@ class DatastoreResultSet(BaseResultSet):
return entries, total_count
+
class InplaceResultSet(BaseResultSet):
"""Encapsulates the result of a query on a mount point
"""
@@ -220,7 +231,9 @@ class InplaceResultSet(BaseResultSet):
BaseResultSet.__init__(self, query, page_size)
self._mount_point = mount_point
self._file_list = None
- self._pending_directories = 0
+ self._pending_directories = []
+ self._visited_directories = []
+ self._pending_files = []
self._stopped = False
query_text = query.get('query', '')
@@ -247,7 +260,10 @@ class InplaceResultSet(BaseResultSet):
def setup(self):
self._file_list = []
- self._recurse_dir(self._mount_point)
+ self._pending_directories = [self._mount_point]
+ self._visited_directories = []
+ self._pending_files = []
+ gobject.idle_add(self._scan)
def stop(self):
self._stopped = True
@@ -256,10 +272,11 @@ class InplaceResultSet(BaseResultSet):
if self._sort[1:] == 'filesize':
keygetter = itemgetter(3)
else:
- keygetter = itemgetter(2) # timestamp
- self._file_list.sort(lambda a, b: b - a,
+ # timestamp
+ keygetter = itemgetter(2)
+ self._file_list.sort(lambda a, b: cmp(b, a),
key=keygetter,
- reverse=self._sort[0]=='-')
+ reverse=(self._sort[0] == '-'))
self.ready.send(self)
def find(self, query):
@@ -272,7 +289,7 @@ class InplaceResultSet(BaseResultSet):
t = time.time()
offset = int(query.get('offset', 0))
- limit = int(query.get('limit', len(self._file_list)))
+ limit = int(query.get('limit', len(self._file_list)))
total_count = len(self._file_list)
files = self._file_list[offset:offset + limit]
@@ -287,62 +304,101 @@ class InplaceResultSet(BaseResultSet):
return entries, total_count
- def _recurse_dir(self, dir_path):
- self._pending_directories += 1
- gobject.idle_add(self._idle_recurse_dir, dir_path)
+ def _scan(self):
+ if self._stopped:
+ return False
- def _idle_recurse_dir(self, dir_path):
- try:
- self._real_recurse_dir(dir_path)
- finally:
- self._pending_directories -= 1
- if self._pending_directories == 0:
- self.setup_ready()
+ self.progress.send(self)
- def _real_recurse_dir(self, dir_path):
- if self._stopped:
- return
+ if self._pending_files:
+ self._scan_a_file()
+ return True
+
+ if self._pending_directories:
+ self._scan_a_directory()
+ return True
+
+ self.setup_ready()
+ self._visited_directories = []
+ return False
+
+ def _scan_a_file(self):
+ full_path = self._pending_files.pop(0)
try:
- dirs = os.listdir(dir_path)
- except Exception:
- logging.exception('Error reading directory %r', dir_path)
- dirs = []
+ stat = os.lstat(full_path)
+ except OSError, e:
+ if e.errno != errno.ENOENT:
+ logging.exception(
+ 'Error reading metadata of file %r', full_path)
+ return
+
+ if S_IFMT(stat.st_mode) == S_IFLNK:
+ try:
+ link = os.readlink(full_path)
+ except OSError, e:
+ logging.exception(
+ 'Error reading target of link %r', full_path)
+ return
+
+ if not os.path.abspath(link).startswith(self._mount_point):
+ return
- for entry in dirs:
- if entry.startswith('.'):
- continue
- full_path = dir_path + '/' + entry
try:
stat = os.stat(full_path)
- if S_IFMT(stat.st_mode) == S_IFDIR:
- self._recurse_dir(full_path)
- elif S_IFMT(stat.st_mode) == S_IFREG:
- add_to_list = True
+ except OSError, e:
+ if e.errno != errno.ENOENT:
+ logging.exception(
+ 'Error reading metadata of linked file %r', full_path)
+ return
+
+ if S_IFMT(stat.st_mode) == S_IFDIR:
+ id_tuple = stat.st_ino, stat.st_dev
+ if not id_tuple in self._visited_directories:
+ self._visited_directories.append(id_tuple)
+ self._pending_directories.append(full_path)
+ return
- if self._regex is not None and \
- not self._regex.match(full_path):
- add_to_list = False
+ if S_IFMT(stat.st_mode) != S_IFREG:
+ return
- if None not in [self._date_start, self._date_end] and \
- (stat.st_mtime < self._date_start or
- stat.st_mtime > self._date_end):
- add_to_list = False
+ if self._regex is not None and \
+ not self._regex.match(full_path):
+ return
- if self._mime_types:
- mime_type = gio.content_type_guess(filename=full_path)
- if mime_type not in self._mime_types:
- add_to_list = False
+ if self._date_start is not None and stat.st_mtime < self._date_start:
+ return
- if add_to_list:
- file_info = (full_path, stat, int(stat.st_mtime), stat.st_size)
- self._file_list.append(file_info)
+ if self._date_end is not None and stat.st_mtime > self._date_end:
+ return
- self.progress.send(self)
+ if self._mime_types:
+ mime_type = gio.content_type_guess(filename=full_path)
+ if mime_type not in self._mime_types:
+ return
+
+ file_info = (full_path, stat, int(stat.st_mtime), stat.st_size)
+ self._file_list.append(file_info)
+
+ return
+
+ def _scan_a_directory(self):
+ dir_path = self._pending_directories.pop(0)
+
+ try:
+ entries = os.listdir(dir_path)
+ except OSError, e:
+ if e.errno != errno.EACCES:
+ logging.exception('Error reading directory %r', dir_path)
+ return
+
+ for entry in entries:
+ if entry.startswith('.'):
+ continue
+ self._pending_files.append(dir_path + '/' + entry)
+ return
- except Exception:
- logging.exception('Error reading file %r', full_path)
def _get_file_metadata(path, stat):
client = gconf.client_get_default()
@@ -356,7 +412,7 @@ def _get_file_metadata(path, stat):
'icon-color': client.get_string('/desktop/sugar/user/color'),
'description': path}
-_datastore = None
+
def _get_datastore():
global _datastore
if _datastore is None:
@@ -370,15 +426,19 @@ def _get_datastore():
return _datastore
+
def _datastore_created_cb(object_id):
created.send(None, object_id=object_id)
+
def _datastore_updated_cb(object_id):
updated.send(None, object_id=object_id)
+
def _datastore_deleted_cb(object_id):
deleted.send(None, object_id=object_id)
+
def find(query_, page_size):
"""Returns a ResultSet
"""
@@ -393,6 +453,7 @@ def find(query_, page_size):
else:
return InplaceResultSet(query, page_size, mount_points[0])
+
def _get_mount_point(path):
dir_path = os.path.dirname(path)
while True:
@@ -401,6 +462,7 @@ def _get_mount_point(path):
else:
dir_path = dir_path.rsplit(os.sep, 1)[0]
+
def get(object_id):
"""Returns the metadata for an object
"""
@@ -413,6 +475,7 @@ def get(object_id):
metadata['mountpoint'] = '/'
return metadata
+
def get_file(object_id):
"""Returns the file for an object
"""
@@ -427,6 +490,7 @@ def get_file(object_id):
else:
return None
+
def get_file_size(object_id):
"""Return the file size for an object
"""
@@ -442,12 +506,14 @@ def get_file_size(object_id):
return 0
+
def get_unique_values(key):
"""Returns a list with the different values a property has taken
"""
empty_dict = dbus.Dictionary({}, signature='ss')
return _get_datastore().get_uniquevaluesfor(key, empty_dict)
+
def delete(object_id):
"""Removes an object from persistent storage
"""
@@ -457,6 +523,7 @@ def delete(object_id):
else:
_get_datastore().delete(object_id)
+
def copy(metadata, mount_point):
"""Copies an object to another mount point
"""
@@ -468,6 +535,7 @@ def copy(metadata, mount_point):
return write(metadata, file_path, transfer_ownership=False)
+
def write(metadata, file_path='', update_mtime=True, transfer_ownership=True):
"""Creates or updates an entry for that id
"""
@@ -502,6 +570,7 @@ def write(metadata, file_path='', update_mtime=True, transfer_ownership=True):
return object_id
+
def _get_file_name(title, mime_type):
file_name = title
@@ -526,11 +595,12 @@ def _get_file_name(title, mime_type):
return file_name
+
def _get_unique_file_name(mount_point, file_name):
if os.path.exists(os.path.join(mount_point, file_name)):
i = 1
+ name, extension = os.path.splitext(file_name)
while len(file_name) <= 255:
- name, extension = os.path.splitext(file_name)
file_name = name + '_' + str(i) + extension
if not os.path.exists(os.path.join(mount_point, file_name)):
break
@@ -538,10 +608,7 @@ def _get_unique_file_name(mount_point, file_name):
return file_name
+
def is_editable(metadata):
mountpoint = metadata.get('mountpoint', '/')
return mountpoint == '/'
-
-created = dispatch.Signal()
-updated = dispatch.Signal()
-deleted = dispatch.Signal()
diff --git a/src/jarabe/journal/objectchooser.py b/src/jarabe/journal/objectchooser.py
index 49af3e6..ecb8ecf 100644
--- a/src/jarabe/journal/objectchooser.py
+++ b/src/jarabe/journal/objectchooser.py
@@ -29,14 +29,13 @@ from jarabe.journal.listmodel import ListModel
from jarabe.journal.journaltoolbox import SearchToolbar
from jarabe.journal.volumestoolbar import VolumesToolbar
+
class ObjectChooser(gtk.Window):
__gtype_name__ = 'ObjectChooser'
__gsignals__ = {
- 'response': (gobject.SIGNAL_RUN_FIRST,
- gobject.TYPE_NONE,
- ([int]))
+ 'response': (gobject.SIGNAL_RUN_FIRST, gobject.TYPE_NONE, ([int])),
}
def __init__(self, parent=None, what_filter=''):
@@ -136,6 +135,7 @@ class ObjectChooser(gtk.Window):
visible = event.state == gtk.gdk.VISIBILITY_FULLY_OBSCURED
self._list_view.set_is_visible(visible)
+
class TitleBox(VolumesToolbar):
__gtype_name__ = 'TitleBox'
@@ -162,6 +162,7 @@ class TitleBox(VolumesToolbar):
self.insert(tool_item, -1)
tool_item.show()
+
class ChooserListView(BaseListView):
__gtype_name__ = 'ChooserListView'
@@ -187,7 +188,7 @@ class ChooserListView(BaseListView):
if event.window != tree_view.get_bin_window():
return False
- pos = tree_view.get_path_at_pos(event.x, event.y)
+ pos = tree_view.get_path_at_pos(int(event.x), int(event.y))
if pos is None:
return False
@@ -196,4 +197,3 @@ class ChooserListView(BaseListView):
self.emit('entry-activated', uid)
return False
-
diff --git a/src/jarabe/journal/palettes.py b/src/jarabe/journal/palettes.py
index 7c3e5ff..9ae1afb 100644
--- a/src/jarabe/journal/palettes.py
+++ b/src/jarabe/journal/palettes.py
@@ -28,20 +28,19 @@ from sugar.graphics.icon import Icon
from sugar.graphics.xocolor import XoColor
from sugar import mime
-from jarabe.model import bundleregistry
from jarabe.model import friends
from jarabe.model import filetransfer
from jarabe.model import mimeregistry
from jarabe.journal import misc
from jarabe.journal import model
+
class ObjectPalette(Palette):
__gtype_name__ = 'ObjectPalette'
__gsignals__ = {
- 'detail-clicked': (gobject.SIGNAL_RUN_FIRST,
- gobject.TYPE_NONE,
+ 'detail-clicked': (gobject.SIGNAL_RUN_FIRST, gobject.TYPE_NONE,
([str])),
}
@@ -54,7 +53,7 @@ class ObjectPalette(Palette):
activity_icon.props.file = misc.get_icon_name(metadata)
activity_icon.props.xo_color = misc.get_icon_color(metadata)
- if metadata.has_key('title'):
+ if 'title' in metadata:
title = gobject.markup_escape_text(metadata['title'])
else:
title = _('Untitled')
@@ -62,22 +61,29 @@ class ObjectPalette(Palette):
Palette.__init__(self, primary_text=title,
icon=activity_icon)
- if metadata.get('activity_id', ''):
- resume_label = _('Resume')
- resume_with_label = _('Resume with')
- else:
- resume_label = _('Start')
- resume_with_label = _('Start with')
- menu_item = MenuItem(resume_label, 'activity-start')
- menu_item.connect('activate', self.__start_activate_cb)
- self.menu.append(menu_item)
- menu_item.show()
+ if misc.get_activities(metadata) or misc.is_bundle(metadata):
+ if metadata.get('activity_id', ''):
+ resume_label = _('Resume')
+ resume_with_label = _('Resume with')
+ else:
+ resume_label = _('Start')
+ resume_with_label = _('Start with')
+ menu_item = MenuItem(resume_label, 'activity-start')
+ menu_item.connect('activate', self.__start_activate_cb)
+ self.menu.append(menu_item)
+ menu_item.show()
- menu_item = MenuItem(resume_with_label, 'activity-start')
- self.menu.append(menu_item)
- menu_item.show()
- start_with_menu = StartWithMenu(self._metadata)
- menu_item.set_submenu(start_with_menu)
+ menu_item = MenuItem(resume_with_label, 'activity-start')
+ self.menu.append(menu_item)
+ menu_item.show()
+ start_with_menu = StartWithMenu(self._metadata)
+ menu_item.set_submenu(start_with_menu)
+
+ else:
+ menu_item = MenuItem(_('No activity to start entry'))
+ menu_item.set_sensitive(False)
+ self.menu.append(menu_item)
+ menu_item.show()
client = gconf.client_get_default()
color = XoColor(client.get_string('/desktop/sugar/user/color'))
@@ -147,12 +153,13 @@ class ObjectPalette(Palette):
filetransfer.start_transfer(buddy, file_name, title, description,
mime_type)
+
class FriendsMenu(gtk.Menu):
__gtype_name__ = 'JournalFriendsMenu'
__gsignals__ = {
- 'friend-selected' : (gobject.SIGNAL_RUN_FIRST, gobject.TYPE_NONE,
- ([object])),
+ 'friend-selected': (gobject.SIGNAL_RUN_FIRST, gobject.TYPE_NONE,
+ ([object])),
}
def __init__(self):
diff --git a/src/jarabe/journal/volumestoolbar.py b/src/jarabe/journal/volumestoolbar.py
index 4208c17..2d842f1 100644
--- a/src/jarabe/journal/volumestoolbar.py
+++ b/src/jarabe/journal/volumestoolbar.py
@@ -16,6 +16,7 @@
import logging
import os
+import statvfs
from gettext import gettext as _
import gobject
@@ -26,20 +27,20 @@ import gconf
from sugar.graphics.radiotoolbutton import RadioToolButton
from sugar.graphics.palette import Palette
from sugar.graphics.xocolor import XoColor
+from sugar import env
from jarabe.journal import model
from jarabe.view.palettes import VolumePalette
+
class VolumesToolbar(gtk.Toolbar):
__gtype_name__ = 'VolumesToolbar'
__gsignals__ = {
- 'volume-changed': (gobject.SIGNAL_RUN_FIRST,
- gobject.TYPE_NONE,
+ 'volume-changed': (gobject.SIGNAL_RUN_FIRST, gobject.TYPE_NONE,
([str])),
- 'volume-error': (gobject.SIGNAL_RUN_FIRST,
- gobject.TYPE_NONE,
- ([str, str]))
+ 'volume-error': (gobject.SIGNAL_RUN_FIRST, gobject.TYPE_NONE,
+ ([str, str])),
}
def __init__(self):
@@ -48,7 +49,6 @@ class VolumesToolbar(gtk.Toolbar):
self._mount_removed_hid = None
button = JournalButton()
- button.set_palette(Palette(_('Journal')))
button.connect('toggled', self._button_toggled_cb)
self.insert(button, 0)
button.show()
@@ -65,10 +65,10 @@ class VolumesToolbar(gtk.Toolbar):
def _set_up_volumes(self):
volume_monitor = gio.volume_monitor_get()
- self._mount_added_hid = \
- volume_monitor.connect('mount-added', self.__mount_added_cb)
- self._mount_removed_hid = \
- volume_monitor.connect('mount-removed', self.__mount_removed_cb)
+ self._mount_added_hid = volume_monitor.connect('mount-added',
+ self.__mount_added_cb)
+ self._mount_removed_hid = volume_monitor.connect('mount-removed',
+ self.__mount_removed_cb)
for mount in volume_monitor.get_mounts():
self._add_button(mount)
@@ -130,11 +130,11 @@ class VolumesToolbar(gtk.Toolbar):
button = self._get_button_for_mount(mount)
button.props.active = True
+
class BaseButton(RadioToolButton):
__gsignals__ = {
- 'volume-error': (gobject.SIGNAL_RUN_FIRST,
- gobject.TYPE_NONE,
- ([str, str]))
+ 'volume-error': (gobject.SIGNAL_RUN_FIRST, gobject.TYPE_NONE,
+ ([str, str])),
}
def __init__(self, mount_point):
@@ -147,8 +147,8 @@ class BaseButton(RadioToolButton):
gtk.gdk.ACTION_COPY)
self.connect('drag-data-received', self._drag_data_received_cb)
- def _drag_data_received_cb(self, widget, drag_context, x, y, selection_data,
- info, timestamp):
+ def _drag_data_received_cb(self, widget, drag_context, x, y,
+ selection_data, info, timestamp):
object_id = selection_data.data
metadata = model.get(object_id)
file_path = model.get_file(metadata['uid'])
@@ -167,6 +167,7 @@ class BaseButton(RadioToolButton):
_('Error while copying the entry. %s') % e.strerror,
_('Error'))
+
class VolumeButton(BaseButton):
def __init__(self, mount):
self._mount = mount
@@ -197,6 +198,7 @@ class VolumeButton(BaseButton):
#palette.set_group_id('frame')
return palette
+
class JournalButton(BaseButton):
def __init__(self):
BaseButton.__init__(self, mount_point='/')
@@ -207,3 +209,36 @@ class JournalButton(BaseButton):
color = XoColor(client.get_string('/desktop/sugar/user/color'))
self.props.xo_color = color
+ def create_palette(self):
+ palette = JournalButtonPalette(self)
+ return palette
+
+
+class JournalButtonPalette(Palette):
+
+ def __init__(self, mount):
+ Palette.__init__(self, _('Journal'))
+ vbox = gtk.VBox()
+ self.set_content(vbox)
+ vbox.show()
+
+ self._progress_bar = gtk.ProgressBar()
+ vbox.add(self._progress_bar)
+ self._progress_bar.show()
+
+ self._free_space_label = gtk.Label()
+ self._free_space_label.set_alignment(0.5, 0.5)
+ vbox.add(self._free_space_label)
+ self._free_space_label.show()
+
+ self.connect('popup', self.__popup_cb)
+
+ def __popup_cb(self, palette):
+ stat = os.statvfs(env.get_profile_path())
+ free_space = stat[statvfs.F_BSIZE] * stat[statvfs.F_BAVAIL]
+ total_space = stat[statvfs.F_BSIZE] * stat[statvfs.F_BLOCKS]
+
+ fraction = (total_space - free_space) / float(total_space)
+ self._progress_bar.props.fraction = fraction
+ self._free_space_label.props.label = _('%(free_space)d MB Free') % \
+ {'free_space': free_space / (1024 * 1024)}
diff --git a/src/jarabe/model/__init__.py b/src/jarabe/model/__init__.py
index a9dd95a..85f6a24 100644
--- a/src/jarabe/model/__init__.py
+++ b/src/jarabe/model/__init__.py
@@ -13,4 +13,3 @@
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
-
diff --git a/src/jarabe/model/adhoc.py b/src/jarabe/model/adhoc.py
index ad0c941..8842a5c 100644
--- a/src/jarabe/model/adhoc.py
+++ b/src/jarabe/model/adhoc.py
@@ -24,6 +24,7 @@ from jarabe.model.network import Settings
from sugar.util import unique_id
from jarabe.model.network import IP4Config
+
_NM_SERVICE = 'org.freedesktop.NetworkManager'
_NM_IFACE = 'org.freedesktop.NetworkManager'
_NM_PATH = '/org/freedesktop/NetworkManager'
@@ -32,8 +33,9 @@ _NM_WIRELESS_IFACE = 'org.freedesktop.NetworkManager.Device.Wireless'
_NM_ACCESSPOINT_IFACE = 'org.freedesktop.NetworkManager.AccessPoint'
_NM_ACTIVE_CONN_IFACE = 'org.freedesktop.NetworkManager.Connection.Active'
-
_adhoc_manager_instance = None
+
+
def get_adhoc_manager_instance():
global _adhoc_manager_instance
if _adhoc_manager_instance is None:
@@ -53,7 +55,7 @@ class AdHocManager(gobject.GObject):
'members-changed': (gobject.SIGNAL_RUN_FIRST, gobject.TYPE_NONE,
([gobject.TYPE_PYOBJECT, gobject.TYPE_PYOBJECT])),
'state-changed': (gobject.SIGNAL_RUN_FIRST, gobject.TYPE_NONE,
- ([gobject.TYPE_PYOBJECT, gobject.TYPE_PYOBJECT]))
+ ([gobject.TYPE_PYOBJECT, gobject.TYPE_PYOBJECT])),
}
_AUTOCONNECT_TIMEOUT = 30
@@ -82,7 +84,7 @@ class AdHocManager(gobject.GObject):
' only be called once.')
self._device = device
- props = dbus.Interface(device, 'org.freedesktop.DBus.Properties')
+ props = dbus.Interface(device, dbus.PROPERTIES_IFACE)
self._device_state = props.Get(_NM_DEVICE_IFACE, 'State')
self._bus.add_signal_receiver(self.__device_state_changed_cb,
@@ -158,7 +160,7 @@ class AdHocManager(gobject.GObject):
def __idle_check_cb(self):
if self._device_state == network.DEVICE_STATE_DISCONNECTED:
- logging.debug("Connect to Ad-hoc network due to inactivity.")
+ logging.debug('Connect to Ad-hoc network due to inactivity.')
self._autoconnect_adhoc()
return False
@@ -186,7 +188,7 @@ class AdHocManager(gobject.GObject):
self._connect(channel)
def _connect(self, channel):
- name = "Ad-hoc Network %d" % channel
+ name = 'Ad-hoc Network %d' % channel
connection = network.find_connection_by_ssid(name)
if connection is None:
settings = Settings()
diff --git a/src/jarabe/model/buddy.py b/src/jarabe/model/buddy.py
index 5f3176e..c580e68 100644
--- a/src/jarabe/model/buddy.py
+++ b/src/jarabe/model/buddy.py
@@ -28,8 +28,12 @@ from sugar.profile import get_profile
from jarabe.util.telepathy import connection_watcher
+
CONNECTION_INTERFACE_BUDDY_INFO = 'org.laptop.Telepathy.BuddyInfo'
+_owner_instance = None
+
+
class BaseBuddyModel(gobject.GObject):
__gtype_name__ = 'SugarBaseBuddyModel'
@@ -89,6 +93,7 @@ class BaseBuddyModel(gobject.GObject):
class OwnerBuddyModel(BaseBuddyModel):
__gtype_name__ = 'SugarOwnerBuddyModel'
+
def __init__(self):
BaseBuddyModel.__init__(self)
@@ -180,7 +185,6 @@ class OwnerBuddyModel(BaseBuddyModel):
return True
-_owner_instance = None
def get_owner_instance():
global _owner_instance
if _owner_instance is None:
@@ -190,6 +194,7 @@ def get_owner_instance():
class BuddyModel(BaseBuddyModel):
__gtype_name__ = 'SugarBuddyModel'
+
def __init__(self, **kwargs):
self._account = None
@@ -225,4 +230,5 @@ class BuddyModel(BaseBuddyModel):
def set_handle(self, handle):
self._handle = handle
- handle = gobject.property(type=object, getter=get_handle, setter=set_handle)
+ handle = gobject.property(type=object, getter=get_handle,
+ setter=set_handle)
diff --git a/src/jarabe/model/bundleregistry.py b/src/jarabe/model/bundleregistry.py
index 699e339..84d55c0 100644
--- a/src/jarabe/model/bundleregistry.py
+++ b/src/jarabe/model/bundleregistry.py
@@ -17,7 +17,6 @@
import os
import logging
-import traceback
import gconf
import gobject
@@ -26,6 +25,7 @@ import simplejson
from sugar.bundle.activitybundle import ActivityBundle
from sugar.bundle.contentbundle import ContentBundle
+from sugar.bundle.bundleversion import NormalizedVersion
from jarabe.journal.journalentrybundle import JournalEntryBundle
from sugar.bundle.bundle import MalformedBundleException, \
AlreadyInstalledException, RegistrationException
@@ -34,16 +34,20 @@ from sugar import env
from jarabe import config
from jarabe.model import mimeregistry
+
+_instance = None
+
+
class BundleRegistry(gobject.GObject):
"""Tracks the available activity bundles"""
__gsignals__ = {
- 'bundle-added': (gobject.SIGNAL_RUN_FIRST, gobject.TYPE_NONE,
- ([gobject.TYPE_PYOBJECT])),
+ 'bundle-added': (gobject.SIGNAL_RUN_FIRST, gobject.TYPE_NONE,
+ ([gobject.TYPE_PYOBJECT])),
'bundle-removed': (gobject.SIGNAL_RUN_FIRST, gobject.TYPE_NONE,
([gobject.TYPE_PYOBJECT])),
'bundle-changed': (gobject.SIGNAL_RUN_FIRST, gobject.TYPE_NONE,
- ([gobject.TYPE_PYOBJECT]))
+ ([gobject.TYPE_PYOBJECT])),
}
def __init__(self):
@@ -153,14 +157,16 @@ class BundleRegistry(gobject.GObject):
return
for bundle_id in default_activities:
- max_version = -1
+ max_version = '0'
for bundle in self._bundles:
if bundle.get_bundle_id() == bundle_id and \
- max_version < bundle.get_activity_version():
+ NormalizedVersion(max_version) < \
+ NormalizedVersion(bundle.get_activity_version()):
max_version = bundle.get_activity_version()
key = self._get_favorite_key(bundle_id, max_version)
- if max_version > -1 and key not in self._favorite_bundles:
+ if NormalizedVersion(max_version) > NormalizedVersion('0') and \
+ key not in self._favorite_bundles:
self._favorite_bundles[key] = None
logging.debug('After merging: %r', self._favorite_bundles)
@@ -168,20 +174,10 @@ class BundleRegistry(gobject.GObject):
self._write_favorites_file()
def get_bundle(self, bundle_id):
- """Returns a bundle given service name or substring,
- returns None if there is either no match, or more than one
- match by substring."""
- result = []
- key = bundle_id.lower()
-
+ """Returns an bundle given his service name"""
for bundle in self._bundles:
- name = bundle.get_bundle_id()
- if name == bundle_id:
+ if bundle.get_bundle_id() == bundle_id:
return bundle
- if key in name.lower():
- result.append(bundle)
- if len(result) == 1:
- return result[0]
return None
def __iter__(self):
@@ -204,19 +200,18 @@ class BundleRegistry(gobject.GObject):
if os.path.isdir(bundle_dir):
bundles[bundle_dir] = os.stat(bundle_dir).st_mtime
except Exception:
- logging.error('Error while processing installed activity ' \
- 'bundle %s:\n%s' % \
- (bundle_dir, traceback.format_exc()))
+ logging.exception('Error while processing installed activity'
+ ' bundle %s:', bundle_dir)
bundle_dirs = bundles.keys()
bundle_dirs.sort(lambda d1, d2: cmp(bundles[d1], bundles[d2]))
for folder in bundle_dirs:
try:
self._add_bundle(folder)
- except Exception, e:
- logging.error('Error while processing installed activity ' \
- 'bundle %s:\n%s' % \
- (folder, traceback.format_exc()))
+ except:
+ # pylint: disable=W0702
+ logging.exception('Error while processing installed activity'
+ ' bundle %s:', folder)
def add_bundle(self, bundle_path, install_mime_type=False):
bundle = self._add_bundle(bundle_path, install_mime_type)
@@ -243,8 +238,8 @@ class BundleRegistry(gobject.GObject):
installed = self.get_bundle(bundle_id)
if installed is not None:
- if installed.get_activity_version() >= \
- bundle.get_activity_version():
+ if NormalizedVersion(installed.get_activity_version()) >= \
+ NormalizedVersion(bundle.get_activity_version()):
logging.debug('Skip old version for %s', bundle_id)
return None
else:
@@ -270,8 +265,7 @@ class BundleRegistry(gobject.GObject):
default_bundle = None
for bundle in self._bundles:
- if bundle.get_mime_types() and mime_type in bundle.get_mime_types():
-
+ if mime_type in (bundle.get_mime_types() or []):
if bundle.get_bundle_id() == default_bundle_id:
default_bundle = bundle
elif self.get_default_for_type(mime_type) == \
@@ -286,10 +280,7 @@ class BundleRegistry(gobject.GObject):
return result
def get_default_for_type(self, mime_type):
- if self._mime_defaults.has_key(mime_type):
- return self._mime_defaults[mime_type]
- else:
- return None
+ return self._mime_defaults.get(mime_type)
def _find_bundle(self, bundle_id, version):
for bundle in self._bundles:
@@ -327,7 +318,8 @@ class BundleRegistry(gobject.GObject):
def set_bundle_position(self, bundle_id, version, x, y):
key = self._get_favorite_key(bundle_id, version)
if key not in self._favorite_bundles:
- raise ValueError('Bundle %s %s not favorite' % (bundle_id, version))
+ raise ValueError('Bundle %s %s not favorite' %
+ (bundle_id, version))
if self._favorite_bundles[key] is None:
self._favorite_bundles[key] = {}
@@ -368,19 +360,22 @@ class BundleRegistry(gobject.GObject):
for installed_bundle in self._bundles:
if bundle.get_bundle_id() == installed_bundle.get_bundle_id() and \
- bundle.get_activity_version() == \
- installed_bundle.get_activity_version():
+ NormalizedVersion(bundle.get_activity_version()) <= \
+ NormalizedVersion(installed_bundle.get_activity_version()):
return True
return False
- def install(self, bundle, uid=None):
+ def install(self, bundle, uid=None, force_downgrade=False):
activities_path = env.get_user_activities_path()
for installed_bundle in self._bundles:
if bundle.get_bundle_id() == installed_bundle.get_bundle_id() and \
- bundle.get_activity_version() <= \
- installed_bundle.get_activity_version():
- raise AlreadyInstalledException
+ NormalizedVersion(bundle.get_activity_version()) <= \
+ NormalizedVersion(installed_bundle.get_activity_version()):
+ if not force_downgrade:
+ raise AlreadyInstalledException
+ else:
+ self.uninstall(installed_bundle, force=True)
elif bundle.get_bundle_id() == installed_bundle.get_bundle_id():
self.uninstall(installed_bundle, force=True)
@@ -437,20 +432,17 @@ class BundleRegistry(gobject.GObject):
try:
self.uninstall(bundle, force=True)
except Exception:
- logging.error('Uninstall failed, still trying to install ' \
- 'newer bundle:\n' + \
- traceback.format_exc())
+ logging.exception('Uninstall failed, still trying to install'
+ ' newer bundle:')
else:
- logging.warning('Unable to uninstall system activity, ' \
+ logging.warning('Unable to uninstall system activity, '
'installing upgraded version in user activities')
self.install(bundle)
-_instance = None
def get_registry():
global _instance
if not _instance:
_instance = BundleRegistry()
return _instance
-
diff --git a/src/jarabe/model/filetransfer.py b/src/jarabe/model/filetransfer.py
index 0d21793..710c3a4 100644
--- a/src/jarabe/model/filetransfer.py
+++ b/src/jarabe/model/filetransfer.py
@@ -33,6 +33,7 @@ from sugar import dispatch
from jarabe.util.telepathy import connection_watcher
from jarabe.model import neighborhood
+
FT_STATE_NONE = 0
FT_STATE_PENDING = 1
FT_STATE_ACCEPTED = 2
@@ -52,14 +53,18 @@ FT_REASON_REMOTE_ERROR = 6
CHANNEL_TYPE_FILE_TRANSFER = \
'org.freedesktop.Telepathy.Channel.Type.FileTransfer'
+new_file_transfer = dispatch.Signal()
+
+
# TODO Move to use splice_async() in Sugar 0.88
class StreamSplicer(gobject.GObject):
- _CHUNK_SIZE = 10240 # 10K
+ _CHUNK_SIZE = 10240 # 10K
__gsignals__ = {
'finished': (gobject.SIGNAL_RUN_FIRST,
gobject.TYPE_NONE,
([])),
}
+
def __init__(self, input_stream, output_stream):
gobject.GObject.__init__(self)
@@ -105,6 +110,7 @@ class StreamSplicer(gobject.GObject):
gobject.PRIORITY_LOW,
user_data=data)
+
class BaseFileTransfer(gobject.GObject):
def __init__(self, connection):
@@ -176,6 +182,7 @@ class BaseFileTransfer(gobject.GObject):
def cancel(self):
self.channel[CHANNEL].Close()
+
class IncomingFileTransfer(BaseFileTransfer):
def __init__(self, connection, object_path, props):
BaseFileTransfer.__init__(self, connection)
@@ -220,6 +227,7 @@ class IncomingFileTransfer(BaseFileTransfer):
self._splicer = StreamSplicer(input_stream, output_stream)
self._splicer.start()
+
class OutgoingFileTransfer(BaseFileTransfer):
def __init__(self, buddy, file_name, title, description, mime_type):
@@ -283,6 +291,7 @@ class OutgoingFileTransfer(BaseFileTransfer):
def cancel(self):
self.channel[CHANNEL].Close()
+
def _new_channels_cb(connection, channels):
for object_path, props in channels:
if props[CHANNEL + '.ChannelType'] == CHANNEL_TYPE_FILE_TRANSFER and \
@@ -294,17 +303,21 @@ def _new_channels_cb(connection, channels):
object_path, props)
new_file_transfer.send(None, file_transfer=incoming_file_transfer)
+
def _monitor_connection(connection):
logging.debug('connection added %r', connection)
connection[CONNECTION_INTERFACE_REQUESTS].connect_to_signal('NewChannels',
lambda channels: _new_channels_cb(connection, channels))
+
def _connection_added_cb(conn_watcher, connection):
_monitor_connection(connection)
+
def _connection_removed_cb(conn_watcher, connection):
logging.debug('connection removed %r', connection)
+
def init():
conn_watcher = connection_watcher.get_instance()
conn_watcher.connect('connection-added', _connection_added_cb)
@@ -313,11 +326,13 @@ def init():
for connection in conn_watcher.get_connections():
_monitor_connection(connection)
+
def start_transfer(buddy, file_name, title, description, mime_type):
outgoing_file_transfer = OutgoingFileTransfer(buddy, file_name, title,
description, mime_type)
new_file_transfer.send(None, file_transfer=outgoing_file_transfer)
+
def file_transfer_available():
conn_watcher = connection_watcher.get_instance()
for connection in conn_watcher.get_connections():
@@ -337,18 +352,17 @@ def file_transfer_available():
return False
-new_file_transfer = dispatch.Signal()
if __name__ == '__main__':
import tempfile
- input_stream = gio.File('/home/tomeu/isos/Soas2-200904031934.iso').read()
- output_stream = gio.File(tempfile.mkstemp()[1]).append_to()
+ test_file_name = '/home/tomeu/isos/Soas2-200904031934.iso'
+ test_input_stream = gio.File(test_file_name).read()
+ test_output_stream = gio.File(tempfile.mkstemp()[1]).append_to()
# TODO: Use splice_async when it gets implemented
- splicer = StreamSplicer(input_stream, output_stream)
+ splicer = StreamSplicer(test_input_stream, test_output_stream)
splicer.start()
loop = gobject.MainLoop()
loop.run()
-
diff --git a/src/jarabe/model/friends.py b/src/jarabe/model/friends.py
index 98bff96..192f683 100644
--- a/src/jarabe/model/friends.py
+++ b/src/jarabe/model/friends.py
@@ -27,10 +27,14 @@ from sugar.graphics.xocolor import XoColor
from jarabe.model.buddy import BuddyModel
from jarabe.model import neighborhood
+
+_model = None
+
+
class FriendBuddyModel(BuddyModel):
__gtype_name__ = 'SugarFriendBuddyModel'
- _NOT_PRESENT_COLOR = "#D5D5D5,#FFFFFF"
+ _NOT_PRESENT_COLOR = '#D5D5D5,#FFFFFF'
def __init__(self, nick, key):
self._online_buddy = None
@@ -45,7 +49,7 @@ class FriendBuddyModel(BuddyModel):
if buddy is not None:
self._set_online_buddy(buddy)
- def __buddy_added_cb(self, neighborhood, buddy):
+ def __buddy_added_cb(self, model_, buddy):
if buddy.key != self.key:
return
self._set_online_buddy(buddy)
@@ -56,7 +60,7 @@ class FriendBuddyModel(BuddyModel):
self.notify('color')
self.notify('present')
- def __buddy_removed_cb(self, neighborhood, buddy):
+ def __buddy_removed_cb(self, model_, buddy):
if buddy.key != self.key:
return
self._online_buddy = None
@@ -87,12 +91,13 @@ class FriendBuddyModel(BuddyModel):
handle = gobject.property(type=object, getter=get_handle)
+
class Friends(gobject.GObject):
__gsignals__ = {
- 'friend-added': (gobject.SIGNAL_RUN_FIRST,
- gobject.TYPE_NONE, ([object])),
- 'friend-removed': (gobject.SIGNAL_RUN_FIRST,
- gobject.TYPE_NONE, ([str]))
+ 'friend-added': (gobject.SIGNAL_RUN_FIRST, gobject.TYPE_NONE,
+ ([object])),
+ 'friend-removed': (gobject.SIGNAL_RUN_FIRST, gobject.TYPE_NONE,
+ ([str])),
}
def __init__(self):
@@ -104,7 +109,7 @@ class Friends(gobject.GObject):
self.load()
def has_buddy(self, buddy):
- return self._friends.has_key(buddy.get_key())
+ return buddy.get_key() in self._friends
def add_friend(self, buddy_info):
self._friends[buddy_info.get_key()] = buddy_info
@@ -176,7 +181,6 @@ class Friends(gobject.GObject):
reply_handler=friends_synced,
error_handler=friends_synced_error)
-_model = None
def get_model():
global _model
diff --git a/src/jarabe/model/invites.py b/src/jarabe/model/invites.py
index e5a4d9d..d2a2e0c 100644
--- a/src/jarabe/model/invites.py
+++ b/src/jarabe/model/invites.py
@@ -38,9 +38,12 @@ from jarabe.model import bundleregistry
from jarabe.model import neighborhood
from jarabe.journal import misc
+
CONNECTION_INTERFACE_ACTIVITY_PROPERTIES = \
'org.laptop.Telepathy.ActivityProperties'
+_instance = None
+
class ActivityInvite(object):
"""Invitation to a shared activity."""
@@ -96,8 +99,8 @@ class ActivityInvite(object):
obj = bus.get_object(CHANNEL_DISPATCHER, self.dispatch_operation_path)
dispatch_operation = dbus.Interface(obj, CHANNEL_DISPATCH_OPERATION)
dispatch_operation.HandleWith(self._handler,
- reply_handler=self.__handle_with_reply_cb,
- error_handler=self.__handle_with_reply_cb)
+ reply_handler=self.__handle_with_reply_cb,
+ error_handler=self.__handle_with_reply_cb)
def __handle_with_reply_cb(self, error=None):
if error is not None:
@@ -105,12 +108,13 @@ class ActivityInvite(object):
else:
logging.debug('__handle_with_reply_cb')
+
class Invites(gobject.GObject):
__gsignals__ = {
- 'invite-added': (gobject.SIGNAL_RUN_FIRST,
- gobject.TYPE_NONE, ([object])),
- 'invite-removed': (gobject.SIGNAL_RUN_FIRST,
- gobject.TYPE_NONE, ([object]))
+ 'invite-added': (gobject.SIGNAL_RUN_FIRST, gobject.TYPE_NONE,
+ ([object])),
+ 'invite-removed': (gobject.SIGNAL_RUN_FIRST, gobject.TYPE_NONE,
+ ([object])),
}
def __init__(self):
@@ -199,8 +203,8 @@ class Invites(gobject.GObject):
obj = bus.get_object(CHANNEL_DISPATCHER, dispatch_operation_path)
dispatch_operation = dbus.Interface(obj, CHANNEL_DISPATCH_OPERATION)
dispatch_operation.HandleWith(handler,
- reply_handler=self.__handle_with_reply_cb,
- error_handler=self.__handle_with_reply_cb)
+ reply_handler=self.__handle_with_reply_cb,
+ error_handler=self.__handle_with_reply_cb)
def __handle_with_reply_cb(self, error=None):
if error is not None:
@@ -230,8 +234,6 @@ class Invites(gobject.GObject):
return self._dispatch_operations.values().__iter__()
-_instance = None
-
def get_instance():
global _instance
if not _instance:
diff --git a/src/jarabe/model/mimeregistry.py b/src/jarabe/model/mimeregistry.py
index 537f6f3..7fb5bcf 100644
--- a/src/jarabe/model/mimeregistry.py
+++ b/src/jarabe/model/mimeregistry.py
@@ -21,6 +21,7 @@ import gconf
_DEFAULTS_KEY = '/desktop/sugar/journal/defaults'
_GCONF_INVALID_CHARS = re.compile('[^a-zA-Z0-9-_/.]')
+
_instance = None
diff --git a/src/jarabe/model/neighborhood.py b/src/jarabe/model/neighborhood.py
index b808e12..ca4c5bf 100644
--- a/src/jarabe/model/neighborhood.py
+++ b/src/jarabe/model/neighborhood.py
@@ -48,6 +48,7 @@ from sugar.profile import get_profile
from jarabe.model.buddy import BuddyModel, get_owner_instance
from jarabe.model import bundleregistry
+
ACCOUNT_MANAGER_SERVICE = 'org.freedesktop.Telepathy.AccountManager'
ACCOUNT_MANAGER_PATH = '/org/freedesktop/Telepathy/AccountManager'
CHANNEL_DISPATCHER_SERVICE = 'org.freedesktop.Telepathy.ChannelDispatcher'
@@ -65,17 +66,21 @@ Time in seconds to wait when querying contact properties. Some jabber servers
will be very slow in returning these queries, so just be patient.
"""
+_model = None
+
+
class ActivityModel(gobject.GObject):
__gsignals__ = {
- 'current-buddy-added': (gobject.SIGNAL_RUN_FIRST,
- gobject.TYPE_NONE, ([object])),
- 'current-buddy-removed': (gobject.SIGNAL_RUN_FIRST,
- gobject.TYPE_NONE, ([object])),
- 'buddy-added': (gobject.SIGNAL_RUN_FIRST,
- gobject.TYPE_NONE, ([object])),
- 'buddy-removed': (gobject.SIGNAL_RUN_FIRST,
- gobject.TYPE_NONE, ([object])),
+ 'current-buddy-added': (gobject.SIGNAL_RUN_FIRST, gobject.TYPE_NONE,
+ ([object])),
+ 'current-buddy-removed': (gobject.SIGNAL_RUN_FIRST, gobject.TYPE_NONE,
+ ([object])),
+ 'buddy-added': (gobject.SIGNAL_RUN_FIRST, gobject.TYPE_NONE,
+ ([object])),
+ 'buddy-removed': (gobject.SIGNAL_RUN_FIRST, gobject.TYPE_NONE,
+ ([object])),
}
+
def __init__(self, activity_id, room_handle):
gobject.GObject.__init__(self)
@@ -102,7 +107,8 @@ class ActivityModel(gobject.GObject):
def set_bundle(self, bundle):
self._bundle = bundle
- bundle = gobject.property(type=object, getter=get_bundle, setter=set_bundle)
+ bundle = gobject.property(type=object, getter=get_bundle,
+ setter=set_bundle)
def get_name(self):
return self._name
@@ -151,31 +157,29 @@ class ActivityModel(gobject.GObject):
current_buddies = gobject.property(type=object, getter=get_current_buddies)
+
class _Account(gobject.GObject):
__gsignals__ = {
- 'activity-added': (gobject.SIGNAL_RUN_FIRST,
- gobject.TYPE_NONE, ([object, object])),
- 'activity-updated': (gobject.SIGNAL_RUN_FIRST,
- gobject.TYPE_NONE, ([object, object])),
- 'activity-removed': (gobject.SIGNAL_RUN_FIRST,
- gobject.TYPE_NONE, ([object])),
- 'buddy-added': (gobject.SIGNAL_RUN_FIRST,
- gobject.TYPE_NONE,
- ([object, object, object, object])),
- 'buddy-updated': (gobject.SIGNAL_RUN_FIRST,
- gobject.TYPE_NONE, ([object, object])),
- 'buddy-removed': (gobject.SIGNAL_RUN_FIRST,
- gobject.TYPE_NONE, ([object])),
- 'buddy-joined-activity': (gobject.SIGNAL_RUN_FIRST,
- gobject.TYPE_NONE, ([object, object])),
- 'buddy-left-activity': (gobject.SIGNAL_RUN_FIRST,
- gobject.TYPE_NONE, ([object, object])),
+ 'activity-added': (gobject.SIGNAL_RUN_FIRST, gobject.TYPE_NONE,
+ ([object, object])),
+ 'activity-updated': (gobject.SIGNAL_RUN_FIRST, gobject.TYPE_NONE,
+ ([object, object])),
+ 'activity-removed': (gobject.SIGNAL_RUN_FIRST, gobject.TYPE_NONE,
+ ([object])),
+ 'buddy-added': (gobject.SIGNAL_RUN_FIRST, gobject.TYPE_NONE,
+ ([object, object, object])),
+ 'buddy-updated': (gobject.SIGNAL_RUN_FIRST, gobject.TYPE_NONE,
+ ([object, object])),
+ 'buddy-removed': (gobject.SIGNAL_RUN_FIRST, gobject.TYPE_NONE,
+ ([object])),
+ 'buddy-joined-activity': (gobject.SIGNAL_RUN_FIRST, gobject.TYPE_NONE,
+ ([object, object])),
+ 'buddy-left-activity': (gobject.SIGNAL_RUN_FIRST, gobject.TYPE_NONE,
+ ([object, object])),
'current-activity-updated': (gobject.SIGNAL_RUN_FIRST,
gobject.TYPE_NONE, ([object, object])),
- 'connected': (gobject.SIGNAL_RUN_FIRST,
- gobject.TYPE_NONE, ([])),
- 'disconnected': (gobject.SIGNAL_RUN_FIRST,
- gobject.TYPE_NONE, ([])),
+ 'connected': (gobject.SIGNAL_RUN_FIRST, gobject.TYPE_NONE, ([])),
+ 'disconnected': (gobject.SIGNAL_RUN_FIRST, gobject.TYPE_NONE, ([])),
}
def __init__(self, account_path):
@@ -204,7 +208,8 @@ class _Account(gobject.GObject):
'AccountPropertyChanged', self.__account_property_changed_cb)
def __error_handler_cb(self, function_name, error):
- raise RuntimeError('Error when calling %s: %s' % (function_name, error))
+ raise RuntimeError('Error when calling %s: %s' % (function_name,
+ error))
def __got_connection_cb(self, connection_path):
logging.debug('_Account.__got_connection_cb %r', connection_path)
@@ -284,7 +289,8 @@ class _Account(gobject.GObject):
self.emit('connected')
else:
for contact_handle, contact_id in self._buddy_handles.items():
- self.emit('buddy-removed', contact_id)
+ if contact_id is not None:
+ self.emit('buddy-removed', contact_id)
for room_handle, activity_id in self._activity_handles.items():
self.emit('activity-removed', activity_id)
@@ -379,7 +385,8 @@ class _Account(gobject.GObject):
logging.debug('Got handle %r with nick %r, going to update',
handle, alias)
properties = {CONNECTION_INTERFACE_ALIASING + '/alias': alias}
- self.emit('buddy-updated', self._buddy_handles[handle], properties)
+ self.emit('buddy-updated', self._buddy_handles[handle],
+ properties)
def __presences_changed_cb(self, presences):
logging.debug('_Account.__presences_changed_cb %r', presences)
@@ -387,8 +394,9 @@ class _Account(gobject.GObject):
if handle in self._buddy_handles:
presence_type, status_, message_ = presence
if presence_type == CONNECTION_PRESENCE_TYPE_OFFLINE:
+ contact_id = self._buddy_handles[handle]
del self._buddy_handles[handle]
- self.emit('buddy-removed', handle)
+ self.emit('buddy-removed', contact_id)
def __buddy_info_updated_cb(self, handle, properties):
logging.debug('_Account.__buddy_info_updated_cb %r', handle)
@@ -535,8 +543,6 @@ class _Account(gobject.GObject):
def __got_buddy_info_cb(self, handle, nick, properties):
logging.debug('_Account.__got_buddy_info_cb %r', handle)
- self.emit('buddy-added', self._buddy_handles[handle], nick,
- properties.get('key', None), handle)
self.emit('buddy-updated', self._buddy_handles[handle], properties)
def __get_contact_attributes_cb(self, attributes):
@@ -574,7 +580,8 @@ class _Account(gobject.GObject):
connection.GetActivities(
handle,
- reply_handler=partial(self.__got_activities_cb, handle),
+ reply_handler=partial(self.__got_activities_cb,
+ handle),
error_handler=partial(self.__error_handler_cb,
'BuddyInfo.GetActivities'),
timeout=_QUERY_DBUS_TIMEOUT)
@@ -586,8 +593,8 @@ class _Account(gobject.GObject):
error_handler=partial(self.__error_handler_cb,
'BuddyInfo.GetCurrentActivity'),
timeout=_QUERY_DBUS_TIMEOUT)
- else:
- self.emit('buddy-added', contact_id, nick, None, handle)
+
+ self.emit('buddy-added', contact_id, nick, handle)
def __got_activities_cb(self, buddy_handle, activities):
logging.debug('_Account.__got_activities_cb %r %r', buddy_handle,
@@ -610,21 +617,22 @@ class _Account(gobject.GObject):
reply_handler=self.__set_enabled_cb,
error_handler=partial(self.__error_handler_cb,
'Account.SetEnabled'),
- dbus_interface='org.freedesktop.DBus.Properties')
+ dbus_interface=dbus.PROPERTIES_IFACE)
def __set_enabled_cb(self):
logging.debug('_Account.__set_enabled_cb success')
+
class Neighborhood(gobject.GObject):
__gsignals__ = {
- 'activity-added': (gobject.SIGNAL_RUN_FIRST,
- gobject.TYPE_NONE, ([object])),
- 'activity-removed': (gobject.SIGNAL_RUN_FIRST,
- gobject.TYPE_NONE, ([object])),
- 'buddy-added': (gobject.SIGNAL_RUN_FIRST,
- gobject.TYPE_NONE, ([object])),
- 'buddy-removed': (gobject.SIGNAL_RUN_FIRST,
- gobject.TYPE_NONE, ([object]))
+ 'activity-added': (gobject.SIGNAL_RUN_FIRST, gobject.TYPE_NONE,
+ ([object])),
+ 'activity-removed': (gobject.SIGNAL_RUN_FIRST, gobject.TYPE_NONE,
+ ([object])),
+ 'buddy-added': (gobject.SIGNAL_RUN_FIRST, gobject.TYPE_NONE,
+ ([object])),
+ 'buddy-removed': (gobject.SIGNAL_RUN_FIRST, gobject.TYPE_NONE,
+ ([object])),
}
def __init__(self):
@@ -636,7 +644,8 @@ class Neighborhood(gobject.GObject):
self._server_account = None
client = gconf.client_get_default()
- client.add_dir('/desktop/sugar/collaboration', gconf.CLIENT_PRELOAD_NONE)
+ client.add_dir('/desktop/sugar/collaboration',
+ gconf.CLIENT_PRELOAD_NONE)
client.notify_add('/desktop/sugar/collaboration/jabber_server',
self.__jabber_server_changed_cb)
client.add_dir('/desktop/sugar/user/nick', gconf.CLIENT_PRELOAD_NONE)
@@ -733,7 +742,8 @@ class Neighborhood(gobject.GObject):
client = gconf.client_get_default()
nick = client.get_string('/desktop/sugar/user/nick')
- server = client.get_string('/desktop/sugar/collaboration/jabber_server')
+ server = client.get_string('/desktop/sugar/collaboration'
+ '/jabber_server')
key_hash = get_profile().privkey_hash
params = {
@@ -765,7 +775,8 @@ class Neighborhood(gobject.GObject):
def _get_jabber_account_id(self):
public_key_hash = sha1(get_profile().pubkey).hexdigest()
client = gconf.client_get_default()
- server = client.get_string('/desktop/sugar/collaboration/jabber_server')
+ server = client.get_string('/desktop/sugar/collaboration'
+ '/jabber_server')
return '%s@%s' % (public_key_hash, server)
def __jabber_server_changed_cb(self, client, timestamp, entry, *extra):
@@ -775,7 +786,8 @@ class Neighborhood(gobject.GObject):
account = bus.get_object(ACCOUNT_MANAGER_SERVICE,
self._server_account.object_path)
- server = client.get_string('/desktop/sugar/collaboration/jabber_server')
+ server = client.get_string(
+ '/desktop/sugar/collaboration/jabber_server')
account_id = self._get_jabber_account_id()
needs_reconnect = account.UpdateParameters({'server': server,
'account': account_id,
@@ -810,7 +822,7 @@ class Neighborhood(gobject.GObject):
if needs_reconnect:
account.Reconnect()
- def __buddy_added_cb(self, account, contact_id, nick, key, handle):
+ def __buddy_added_cb(self, account, contact_id, nick, handle):
logging.debug('__buddy_added_cb %r', contact_id)
if contact_id in self._buddies:
@@ -821,23 +833,36 @@ class Neighborhood(gobject.GObject):
nick=nick,
account=account.object_path,
contact_id=contact_id,
- key=key,
handle=handle)
self._buddies[contact_id] = buddy
- self.emit('buddy-added', buddy)
-
def __buddy_updated_cb(self, account, contact_id, properties):
logging.debug('__buddy_updated_cb %r', contact_id)
+ if contact_id is None:
+ # Don't know the contact-id yet, will get the full state later
+ return
+
if contact_id not in self._buddies:
- logging.debug('__buddy_updated_cb Unknown buddy with contact_id %r',
- contact_id)
+ logging.debug('__buddy_updated_cb Unknown buddy with contact_id'
+ ' %r', contact_id)
return
buddy = self._buddies[contact_id]
+
+ is_new = buddy.props.key is None and 'key' in properties
+
if 'color' in properties:
buddy.props.color = XoColor(properties['color'])
+ if 'key' in properties:
+ buddy.props.key = properties['key']
+
+ if 'nick' in properties:
+ buddy.props.nick = properties['nick']
+
+ if is_new:
+ self.emit('buddy-added', buddy)
+
def __buddy_removed_cb(self, account, contact_id):
logging.debug('Neighborhood.__buddy_removed_cb %r', contact_id)
if contact_id not in self._buddies:
@@ -847,7 +872,9 @@ class Neighborhood(gobject.GObject):
buddy = self._buddies[contact_id]
del self._buddies[contact_id]
- self.emit('buddy-removed', buddy)
+
+ if buddy.props.key is not None:
+ self.emit('buddy-removed', buddy)
def __activity_added_cb(self, account, room_handle, activity_id):
logging.debug('__activity_added_cb %r %r', room_handle, activity_id)
@@ -891,7 +918,9 @@ class Neighborhood(gobject.GObject):
return
activity = self._activities[activity_id]
del self._activities[activity_id]
- self.emit('activity-removed', activity)
+
+ if activity.props.bundle is not None:
+ self.emit('activity-removed', activity)
def __current_activity_updated_cb(self, account, contact_id, activity_id):
logging.debug('__current_activity_updated_cb %r %r', contact_id,
@@ -901,8 +930,8 @@ class Neighborhood(gobject.GObject):
'contact_id %r', contact_id)
return
if activity_id and activity_id not in self._activities:
- logging.debug('__current_activity_updated_cb Unknown activity with '
- 'id %s', activity_id)
+ logging.debug('__current_activity_updated_cb Unknown activity with'
+ ' id %s', activity_id)
activity_id = ''
buddy = self._buddies[contact_id]
@@ -971,7 +1000,6 @@ class Neighborhood(gobject.GObject):
def get_activities(self):
return self._activities.values()
-_model = None
def get_model():
global _model
diff --git a/src/jarabe/model/network.py b/src/jarabe/model/network.py
index f4a4b71..f265ae4 100644
--- a/src/jarabe/model/network.py
+++ b/src/jarabe/model/network.py
@@ -34,6 +34,7 @@ from sugar import dispatch
from sugar import env
from sugar.util import unique_id
+
DEVICE_TYPE_802_3_ETHERNET = 1
DEVICE_TYPE_802_11_WIRELESS = 2
DEVICE_TYPE_GSM_MODEM = 3
@@ -129,11 +130,16 @@ NM_802_11_DEVICE_CAP_RSN = 0x00000020
SETTINGS_SERVICE = 'org.freedesktop.NetworkManagerUserSettings'
+NM_SERVICE = 'org.freedesktop.NetworkManager'
+NM_IFACE = 'org.freedesktop.NetworkManager'
+NM_PATH = '/org/freedesktop/NetworkManager'
+NM_DEVICE_IFACE = 'org.freedesktop.NetworkManager.Device'
NM_SETTINGS_PATH = '/org/freedesktop/NetworkManagerSettings'
NM_SETTINGS_IFACE = 'org.freedesktop.NetworkManagerSettings'
NM_CONNECTION_IFACE = 'org.freedesktop.NetworkManagerSettings.Connection'
NM_SECRETS_IFACE = 'org.freedesktop.NetworkManagerSettings.Connection.Secrets'
NM_ACCESSPOINT_IFACE = 'org.freedesktop.NetworkManager.AccessPoint'
+NM_ACTIVE_CONN_IFACE = 'org.freedesktop.NetworkManager.Connection.Active'
GSM_USERNAME_PATH = '/desktop/sugar/network/gsm/username'
GSM_PASSWORD_PATH = '/desktop/sugar/network/gsm/password'
@@ -147,102 +153,102 @@ _conn_counter = 0
_nm_device_state_reason_description = None
+
def get_error_by_reason(reason):
global _nm_device_state_reason_description
if _nm_device_state_reason_description is None:
_nm_device_state_reason_description = {
- NM_DEVICE_STATE_REASON_UNKNOWN: \
- _("The reason for the device state change \ is unknown."),
- NM_DEVICE_STATE_REASON_NONE: \
- _("The state change is normal."),
- NM_DEVICE_STATE_REASON_NOW_MANAGED: \
- _("The device is now managed."),
- NM_DEVICE_STATE_REASON_NOW_UNMANAGED: \
- _("The device is no longer managed."),
- NM_DEVICE_STATE_REASON_CONFIG_FAILED: \
- _("The device could not be readied for configuration."),
- NM_DEVICE_STATE_REASON_CONFIG_UNAVAILABLE : \
- _("IP configuration could not be reserved " \
- "(no available address, timeout, etc)."),
- NM_DEVICE_STATE_REASON_CONFIG_EXPIRED : \
- _("The IP configuration is no longer valid."),
- NM_DEVICE_STATE_REASON_NO_SECRETS : \
- _("Secrets were required, but not provided."),
- NM_DEVICE_STATE_REASON_SUPPLICANT_DISCONNECT : \
- _("The 802.1X supplicant disconnected from "\
- "the access point or authentication server."),
- NM_DEVICE_STATE_REASON_SUPPLICANT_CONFIG_FAILED : \
- _("Configuration of the 802.1X supplicant failed."),
- NM_DEVICE_STATE_REASON_SUPPLICANT_FAILED : \
- _("The 802.1X supplicant quit or failed unexpectedly."),
- NM_DEVICE_STATE_REASON_SUPPLICANT_TIMEOUT : \
- _("The 802.1X supplicant took too long to authenticate."),
- NM_DEVICE_STATE_REASON_PPP_START_FAILED : \
- _("The PPP service failed to start within the allowed time."),
- NM_DEVICE_STATE_REASON_PPP_DISCONNECT : \
- _("The PPP service disconnected unexpectedly."),
- NM_DEVICE_STATE_REASON_PPP_FAILED : \
- _("The PPP service quit or failed unexpectedly."),
- NM_DEVICE_STATE_REASON_DHCP_START_FAILED : \
- _("The DHCP service failed to start within the allowed time."),
- NM_DEVICE_STATE_REASON_DHCP_ERROR : \
- _("The DHCP service reported an unexpected error."),
- NM_DEVICE_STATE_REASON_DHCP_FAILED : \
- _("The DHCP service quit or failed unexpectedly."),
- NM_DEVICE_STATE_REASON_SHARED_START_FAILED : \
- _("The shared connection service failed to start."),
- NM_DEVICE_STATE_REASON_SHARED_FAILED : \
- _("The shared connection service quit or " \
- "failed unexpectedly."),
- NM_DEVICE_STATE_REASON_AUTOIP_START_FAILED : \
- _("The AutoIP service failed to start."),
- NM_DEVICE_STATE_REASON_AUTOIP_ERROR : \
- _("The AutoIP service reported an unexpected error."),
- NM_DEVICE_STATE_REASON_AUTOIP_FAILED : \
- _("The AutoIP service quit or failed unexpectedly."),
- NM_DEVICE_STATE_REASON_MODEM_BUSY : \
- _("Dialing failed because the line was busy."),
- NM_DEVICE_STATE_REASON_MODEM_NO_DIAL_TONE : \
- _("Dialing failed because there was no dial tone."),
- NM_DEVICE_STATE_REASON_MODEM_NO_CARRIER : \
- _("Dialing failed because there was no carrier."),
- NM_DEVICE_STATE_REASON_MODEM_DIAL_TIMEOUT : \
- _("Dialing timed out."),
- NM_DEVICE_STATE_REASON_MODEM_DIAL_FAILED : \
- _("Dialing failed."),
- NM_DEVICE_STATE_REASON_MODEM_INIT_FAILED : \
- _("Modem initialization failed."),
- NM_DEVICE_STATE_REASON_GSM_APN_FAILED : \
- _("Failed to select the specified GSM APN."),
- NM_DEVICE_STATE_REASON_GSM_REGISTRATION_NOT_SEARCHING : \
- _("Not searching for networks."),
- NM_DEVICE_STATE_REASON_GSM_REGISTRATION_DENIED : \
- _("Network registration was denied."),
- NM_DEVICE_STATE_REASON_GSM_REGISTRATION_TIMEOUT : \
- _("Network registration timed out."),
- NM_DEVICE_STATE_REASON_GSM_REGISTRATION_FAILED : \
- _("Failed to register with the requested GSM network."),
- NM_DEVICE_STATE_REASON_GSM_PIN_CHECK_FAILED : \
- _("PIN check failed."),
- NM_DEVICE_STATE_REASON_FIRMWARE_MISSING : \
- _("Necessary firmware for the device may be missing."),
- NM_DEVICE_STATE_REASON_REMOVED : \
- _("The device was removed."),
- NM_DEVICE_STATE_REASON_SLEEPING : \
- _("NetworkManager went to sleep."),
- NM_DEVICE_STATE_REASON_CONNECTION_REMOVED : \
- _("The device's active connection was removed " \
- "or disappeared."),
- NM_DEVICE_STATE_REASON_USER_REQUESTED : \
- _("A user or client requested the disconnection."),
- NM_DEVICE_STATE_REASON_CARRIER : \
+ NM_DEVICE_STATE_REASON_UNKNOWN:
+ _('The reason for the device state change is unknown.'),
+ NM_DEVICE_STATE_REASON_NONE:
+ _('The state change is normal.'),
+ NM_DEVICE_STATE_REASON_NOW_MANAGED:
+ _('The device is now managed.'),
+ NM_DEVICE_STATE_REASON_NOW_UNMANAGED:
+ _('The device is no longer managed.'),
+ NM_DEVICE_STATE_REASON_CONFIG_FAILED:
+ _('The device could not be readied for configuration.'),
+ NM_DEVICE_STATE_REASON_CONFIG_UNAVAILABLE:
+ _('IP configuration could not be reserved '
+ '(no available address, timeout, etc).'),
+ NM_DEVICE_STATE_REASON_CONFIG_EXPIRED:
+ _('The IP configuration is no longer valid.'),
+ NM_DEVICE_STATE_REASON_NO_SECRETS:
+ _('Secrets were required, but not provided.'),
+ NM_DEVICE_STATE_REASON_SUPPLICANT_DISCONNECT:
+ _('The 802.1X supplicant disconnected from '
+ 'the access point or authentication server.'),
+ NM_DEVICE_STATE_REASON_SUPPLICANT_CONFIG_FAILED:
+ _('Configuration of the 802.1X supplicant failed.'),
+ NM_DEVICE_STATE_REASON_SUPPLICANT_FAILED:
+ _('The 802.1X supplicant quit or failed unexpectedly.'),
+ NM_DEVICE_STATE_REASON_SUPPLICANT_TIMEOUT:
+ _('The 802.1X supplicant took too long to authenticate.'),
+ NM_DEVICE_STATE_REASON_PPP_START_FAILED:
+ _('The PPP service failed to start within the allowed time.'),
+ NM_DEVICE_STATE_REASON_PPP_DISCONNECT:
+ _('The PPP service disconnected unexpectedly.'),
+ NM_DEVICE_STATE_REASON_PPP_FAILED:
+ _('The PPP service quit or failed unexpectedly.'),
+ NM_DEVICE_STATE_REASON_DHCP_START_FAILED:
+ _('The DHCP service failed to start within the allowed time.'),
+ NM_DEVICE_STATE_REASON_DHCP_ERROR:
+ _('The DHCP service reported an unexpected error.'),
+ NM_DEVICE_STATE_REASON_DHCP_FAILED:
+ _('The DHCP service quit or failed unexpectedly.'),
+ NM_DEVICE_STATE_REASON_SHARED_START_FAILED:
+ _('The shared connection service failed to start.'),
+ NM_DEVICE_STATE_REASON_SHARED_FAILED:
+ _('The shared connection service quit or failed'
+ ' unexpectedly.'),
+ NM_DEVICE_STATE_REASON_AUTOIP_START_FAILED:
+ _('The AutoIP service failed to start.'),
+ NM_DEVICE_STATE_REASON_AUTOIP_ERROR:
+ _('The AutoIP service reported an unexpected error.'),
+ NM_DEVICE_STATE_REASON_AUTOIP_FAILED:
+ _('The AutoIP service quit or failed unexpectedly.'),
+ NM_DEVICE_STATE_REASON_MODEM_BUSY:
+ _('Dialing failed because the line was busy.'),
+ NM_DEVICE_STATE_REASON_MODEM_NO_DIAL_TONE:
+ _('Dialing failed because there was no dial tone.'),
+ NM_DEVICE_STATE_REASON_MODEM_NO_CARRIER:
+ _('Dialing failed because there was no carrier.'),
+ NM_DEVICE_STATE_REASON_MODEM_DIAL_TIMEOUT:
+ _('Dialing timed out.'),
+ NM_DEVICE_STATE_REASON_MODEM_DIAL_FAILED:
+ _('Dialing failed.'),
+ NM_DEVICE_STATE_REASON_MODEM_INIT_FAILED:
+ _('Modem initialization failed.'),
+ NM_DEVICE_STATE_REASON_GSM_APN_FAILED:
+ _('Failed to select the specified GSM APN'),
+ NM_DEVICE_STATE_REASON_GSM_REGISTRATION_NOT_SEARCHING:
+ _('Not searching for networks.'),
+ NM_DEVICE_STATE_REASON_GSM_REGISTRATION_DENIED:
+ _('Network registration was denied.'),
+ NM_DEVICE_STATE_REASON_GSM_REGISTRATION_TIMEOUT:
+ _('Network registration timed out.'),
+ NM_DEVICE_STATE_REASON_GSM_REGISTRATION_FAILED:
+ _('Failed to register with the requested GSM network.'),
+ NM_DEVICE_STATE_REASON_GSM_PIN_CHECK_FAILED:
+ _('PIN check failed.'),
+ NM_DEVICE_STATE_REASON_FIRMWARE_MISSING:
+ _('Necessary firmware for the device may be missing.'),
+ NM_DEVICE_STATE_REASON_REMOVED:
+ _('The device was removed.'),
+ NM_DEVICE_STATE_REASON_SLEEPING:
+ _('NetworkManager went to sleep.'),
+ NM_DEVICE_STATE_REASON_CONNECTION_REMOVED:
+ _("The device's active connection was removed "
+ "or disappeared."),
+ NM_DEVICE_STATE_REASON_USER_REQUESTED:
+ _('A user or client requested the disconnection.'),
+ NM_DEVICE_STATE_REASON_CARRIER:
_("The device's carrier/link changed.")}
return _nm_device_state_reason_description[reason]
-
def frequency_to_channel(frequency):
"""Returns the channel matching a given radio channel frequency. If a
frequency is not in the dictionary channel 1 will be returned.
@@ -258,11 +264,12 @@ def frequency_to_channel(frequency):
2452: 9, 2457: 10, 2462: 11, 2467: 12,
2472: 13}
if frequency not in ftoc:
- logging.warning("The frequency %s can not be mapped to a channel, " \
- "defaulting to channel 1.", frequency)
+ logging.warning('The frequency %s can not be mapped to a channel, '
+ 'defaulting to channel 1.', frequency)
return 1
return ftoc[frequency]
+
def is_sugar_adhoc_network(ssid):
"""Checks whether an access point is a sugar Ad-hoc network.
@@ -294,8 +301,9 @@ class WirelessSecurity(object):
wireless_security['group'] = self.group
return wireless_security
+
class Wireless(object):
- nm_name = "802-11-wireless"
+ nm_name = '802-11-wireless'
def __init__(self):
self.ssid = None
@@ -318,7 +326,7 @@ class Wireless(object):
class OlpcMesh(object):
- nm_name = "802-11-olpc-mesh"
+ nm_name = '802-11-olpc-mesh'
def __init__(self, channel, anycast_addr):
self.channel = channel
@@ -326,12 +334,12 @@ class OlpcMesh(object):
def get_dict(self):
ret = {
- "ssid": dbus.ByteArray("olpc-mesh"),
- "channel": self.channel,
+ 'ssid': dbus.ByteArray('olpc-mesh'),
+ 'channel': self.channel,
}
if self.anycast_addr:
- ret["dhcp-anycast-address"] = dbus.ByteArray(self.anycast_addr)
+ ret['dhcp-anycast-address'] = dbus.ByteArray(self.anycast_addr)
return ret
@@ -352,6 +360,7 @@ class Connection(object):
connection['timestamp'] = self.timestamp
return connection
+
class IP4Config(object):
def __init__(self):
self.method = None
@@ -362,6 +371,7 @@ class IP4Config(object):
ip4_config['method'] = self.method
return ip4_config
+
class Serial(object):
def __init__(self):
self.baud = None
@@ -374,6 +384,7 @@ class Serial(object):
return serial
+
class Ppp(object):
def __init__(self):
pass
@@ -382,6 +393,7 @@ class Ppp(object):
ppp = {}
return ppp
+
class Gsm(object):
def __init__(self):
self.apn = None
@@ -400,6 +412,7 @@ class Gsm(object):
return gsm
+
class Settings(object):
def __init__(self, wireless_cfg=None):
self.connection = Connection()
@@ -422,6 +435,7 @@ class Settings(object):
settings['ipv4'] = self.ip4_config.get_dict()
return settings
+
class Secrets(object):
def __init__(self, settings):
self.settings = settings
@@ -447,6 +461,7 @@ class Secrets(object):
return settings
+
class SettingsGsm(object):
def __init__(self):
self.connection = Connection()
@@ -466,22 +481,24 @@ class SettingsGsm(object):
return settings
+
class SecretsGsm(object):
def __init__(self):
self.password = None
self.pin = None
self.puk = None
-
+
def get_dict(self):
secrets = {}
if self.password is not None:
secrets['password'] = self.password
if self.pin is not None:
secrets['pin'] = self.pin
- if self.puk is not None:
+ if self.puk is not None:
secrets['puk'] = self.puk
return {'gsm': secrets}
+
class NMSettings(dbus.service.Object):
def __init__(self):
bus = dbus.SystemBus()
@@ -509,10 +526,19 @@ class NMSettings(dbus.service.Object):
self.secrets_request.send(self, connection=sender,
response=kwargs['response'])
+ def clear_wifi_connections(self):
+ for uuid in self.connections.keys():
+ conn = self.connections[uuid]
+ if conn._settings.connection.type == \
+ NM_CONNECTION_TYPE_802_11_WIRELESS:
+ conn.Removed()
+ self.connections.pop(uuid)
+
+
class SecretsResponse(object):
- ''' Intermediate object to report the secrets from the dialog
+ """Intermediate object to report the secrets from the dialog
back to the connection object and which will inform NM
- '''
+ """
def __init__(self, connection, reply_cb, error_cb):
self._connection = connection
self._reply_cb = reply_cb
@@ -525,6 +551,7 @@ class SecretsResponse(object):
def set_error(self, error):
self._error_cb(error)
+
class NMSettingsConnection(dbus.service.Object):
def __init__(self, path, settings, secrets):
bus = dbus.SystemBus()
@@ -537,15 +564,26 @@ class NMSettingsConnection(dbus.service.Object):
self._settings = settings
self._secrets = secrets
+ @dbus.service.signal(dbus_interface=NM_CONNECTION_IFACE,
+ signature='')
+ def Removed(self):
+ pass
+
+ @dbus.service.signal(dbus_interface=NM_CONNECTION_IFACE,
+ signature='a{sa{sv}}')
+ def Updated(self, settings):
+ pass
+
def set_connected(self):
if self._settings.connection.type == NM_CONNECTION_TYPE_GSM:
self._settings.connection.timestamp = int(time.time())
- else:
- if not self._settings.connection.autoconnect:
- self._settings.connection.autoconnect = True
- self._settings.connection.timestamp = int(time.time())
- if self._settings.connection.type == NM_CONNECTION_TYPE_802_11_WIRELESS:
- self.save()
+ elif not self._settings.connection.autoconnect:
+ self._settings.connection.autoconnect = True
+ self._settings.connection.timestamp = int(time.time())
+ if (self._settings.connection.type ==
+ NM_CONNECTION_TYPE_802_11_WIRELESS):
+ self.Updated(self._settings.get_dict())
+ self.save()
try:
# try to flush resolver cache - SL#1940
@@ -555,19 +593,28 @@ class NMSettingsConnection(dbus.service.Object):
res_init = getattr(libc, '__res_init')
res_init(None)
except:
+ # pylint: disable=W0702
logging.exception('Error calling libc.__res_init')
+ def disable_autoconnect(self):
+ if self._settings.connection.type != NM_CONNECTION_TYPE_GSM and \
+ self._settings.connection.autoconnect:
+ self._settings.connection.autoconnect = False
+ self._settings.connection.timestamp = None
+ self.Updated(self._settings.get_dict())
+ self.save()
+
def set_secrets(self, secrets):
self._secrets = secrets
- if self._settings.connection.type == NM_CONNECTION_TYPE_802_11_WIRELESS:
+ if self._settings.connection.type == \
+ NM_CONNECTION_TYPE_802_11_WIRELESS:
self.save()
def get_settings(self):
return self._settings
def save(self):
- profile_path = env.get_profile_path()
- config_path = os.path.join(profile_path, 'nm', 'connections.cfg')
+ config_path = _get_wifi_connections_path()
config = ConfigParser.ConfigParser()
try:
@@ -635,24 +682,28 @@ class NMSettingsConnection(dbus.service.Object):
self.path, request_new)
if self._settings.connection.type is not NM_CONNECTION_TYPE_GSM:
if request_new or self._secrets is None:
- # request_new is for example the case when the pw on the AP changes
+ # request_new is for example the case when the pw on the AP
+ # changes
response = SecretsResponse(self, reply, error)
try:
self.secrets_request.send(self, response=response)
except Exception:
- logging.exception('Error requesting the secrets via dialog')
+ logging.exception('Error requesting the secrets via'
+ ' dialog')
else:
reply(self._secrets.get_dict())
else:
if not request_new:
reply(self._secrets.get_dict())
else:
- raise Exception('The stored GSM secret has already been supplied ')
+ raise Exception('The stored GSM secret has already been'
+ ' supplied')
+
class AccessPoint(gobject.GObject):
__gsignals__ = {
'props-changed': (gobject.SIGNAL_RUN_FIRST, gobject.TYPE_NONE,
- ([gobject.TYPE_PYOBJECT]))
+ ([gobject.TYPE_PYOBJECT])),
}
def __init__(self, device, model):
@@ -672,8 +723,7 @@ class AccessPoint(gobject.GObject):
self.channel = 0
def initialize(self):
- model_props = dbus.Interface(self.model,
- 'org.freedesktop.DBus.Properties')
+ model_props = dbus.Interface(self.model, dbus.PROPERTIES_IFACE)
model_props.GetAll(NM_ACCESSPOINT_IFACE, byte_arrays=True,
reply_handler=self._ap_properties_changed_cb,
error_handler=self._get_all_props_error_cb)
@@ -718,7 +768,7 @@ class AccessPoint(gobject.GObject):
else:
fl |= 1 << 6
- hashstr = str(fl) + "@" + self.name
+ hashstr = str(fl) + '@' + self.name
return hash(hashstr)
def _update_properties(self, properties):
@@ -757,6 +807,7 @@ class AccessPoint(gobject.GObject):
path=self.model.object_path,
dbus_interface=NM_ACCESSPOINT_IFACE)
+
def get_settings():
global _nm_settings
if _nm_settings is None:
@@ -767,17 +818,20 @@ def get_settings():
load_connections()
return _nm_settings
+
def find_connection_by_ssid(ssid):
connections = get_settings().connections
for conn_index in connections:
connection = connections[conn_index]
- if connection._settings.connection.type == NM_CONNECTION_TYPE_802_11_WIRELESS:
- if connection._settings.wireless.ssid == ssid:
- return connection
+ if connection._settings.connection.type == \
+ NM_CONNECTION_TYPE_802_11_WIRELESS and \
+ connection._settings.wireless.ssid == ssid:
+ return connection
return None
+
def add_connection(uuid, settings, secrets=None):
global _conn_counter
@@ -788,19 +842,26 @@ def add_connection(uuid, settings, secrets=None):
_nm_settings.add_connection(uuid, conn)
return conn
-def load_wifi_connections():
+
+def _get_wifi_connections_path():
profile_path = env.get_profile_path()
- config_path = os.path.join(profile_path, 'nm', 'connections.cfg')
+ return os.path.join(profile_path, 'nm', 'connections.cfg')
- config = ConfigParser.ConfigParser()
+
+def _create_wifi_connections(config_path):
+ if not os.path.exists(os.path.dirname(config_path)):
+ os.makedirs(os.path.dirname(config_path), 0755)
+ f = open(config_path, 'w')
+ f.close()
+
+
+def load_wifi_connections():
+ config_path = _get_wifi_connections_path()
if not os.path.exists(config_path):
- if not os.path.exists(os.path.dirname(config_path)):
- os.makedirs(os.path.dirname(config_path), 0755)
- f = open(config_path, 'w')
- config.write(f)
- f.close()
+ _create_wifi_connections(config_path)
+ config = ConfigParser.ConfigParser()
try:
if not config.read(config_path):
logging.error('Error reading the nm config file')
@@ -856,21 +917,6 @@ def load_wifi_connections():
add_connection(uuid, settings, secrets)
-def clear_networks():
- global _nm_settings
- _nm_settings = None
-
- profile_path = env.get_profile_path()
- config_path = os.path.join(profile_path, 'nm', 'connections.cfg')
- config = ConfigParser.ConfigParser()
-
- if not os.path.exists(os.path.dirname(config_path)):
- os.makedirs(os.path.dirname(config_path), 0755)
- f = open(config_path, 'w')
- config.write(f)
- f.close()
-
-
def load_gsm_connection():
_BAUD_RATE = 115200
@@ -885,10 +931,10 @@ def load_gsm_connection():
if username and number and apn:
settings = SettingsGsm()
- settings.gsm.username = username
+ settings.gsm.username = username
settings.gsm.number = number
settings.gsm.apn = apn
-
+
secrets = SecretsGsm()
secrets.pin = pin
secrets.puk = puk
@@ -906,12 +952,14 @@ def load_gsm_connection():
except Exception:
logging.exception('Error adding gsm connection to NMSettings.')
else:
- logging.exception("No gsm connection was set in GConf.")
+ logging.warning('No gsm connection was set in GConf.')
+
def load_connections():
load_wifi_connections()
load_gsm_connection()
+
def find_gsm_connection():
connections = get_settings().connections
@@ -921,3 +969,39 @@ def find_gsm_connection():
logging.debug('There is no gsm connection in the NMSettings.')
return None
+
+
+def have_wifi_connections():
+ return bool(get_settings().connections)
+
+
+def clear_wifi_connections():
+ if _nm_settings is not None:
+ _nm_settings.clear_wifi_connections()
+
+ config_path = _get_wifi_connections_path()
+ _create_wifi_connections(config_path)
+
+
+def disconnect_access_points(ap_paths):
+ """
+ Disconnect all devices connected to any of the given access points.
+ """
+ bus = dbus.SystemBus()
+ netmgr_obj = bus.get_object(NM_SERVICE, NM_PATH)
+ netmgr = dbus.Interface(netmgr_obj, NM_IFACE)
+ netmgr_props = dbus.Interface(netmgr, dbus.PROPERTIES_IFACE)
+ active_connection_paths = netmgr_props.Get(NM_IFACE, 'ActiveConnections')
+
+ for conn_path in active_connection_paths:
+ conn_obj = bus.get_object(NM_IFACE, conn_path)
+ conn_props = dbus.Interface(conn_obj, dbus.PROPERTIES_IFACE)
+ ap_path = conn_props.Get(NM_ACTIVE_CONN_IFACE, 'SpecificObject')
+ if ap_path == '/' or ap_path not in ap_paths:
+ continue
+
+ dev_paths = conn_props.Get(NM_ACTIVE_CONN_IFACE, 'Devices')
+ for dev_path in dev_paths:
+ dev_obj = bus.get_object(NM_SERVICE, dev_path)
+ dev = dbus.Interface(dev_obj, NM_DEVICE_IFACE)
+ dev.Disconnect()
diff --git a/src/jarabe/model/notifications.py b/src/jarabe/model/notifications.py
index f2e2d65..ec14056 100644
--- a/src/jarabe/model/notifications.py
+++ b/src/jarabe/model/notifications.py
@@ -23,9 +23,13 @@ from sugar import dispatch
from jarabe import config
-_DBUS_SERVICE = "org.freedesktop.Notifications"
-_DBUS_IFACE = "org.freedesktop.Notifications"
-_DBUS_PATH = "/org/freedesktop/Notifications"
+
+_DBUS_SERVICE = 'org.freedesktop.Notifications'
+_DBUS_IFACE = 'org.freedesktop.Notifications'
+_DBUS_PATH = '/org/freedesktop/Notifications'
+
+_instance = None
+
class NotificationService(dbus.service.Object):
def __init__(self):
@@ -43,7 +47,8 @@ class NotificationService(dbus.service.Object):
hints, expire_timeout):
logging.debug('Received notification: %r', [app_name, replaces_id,
- '<app_icon>', summary, body, actions, '<hints>', expire_timeout])
+ '<app_icon>', summary, body, actions, '<hints>',
+ expire_timeout])
if replaces_id > 0:
notification_id = replaces_id
@@ -73,16 +78,14 @@ class NotificationService(dbus.service.Object):
def GetServerInformation(self, name, vendor, version):
return 'Sugar Shell', 'Sugar', config.version
-
- @dbus.service.signal(_DBUS_IFACE, signature="uu")
+ @dbus.service.signal(_DBUS_IFACE, signature='uu')
def NotificationClosed(self, notification_id, reason):
pass
- @dbus.service.signal(_DBUS_IFACE, signature="us")
+ @dbus.service.signal(_DBUS_IFACE, signature='us')
def ActionInvoked(self, notification_id, action_key):
pass
-_instance = None
def get_service():
global _instance
@@ -90,6 +93,6 @@ def get_service():
_instance = NotificationService()
return _instance
+
def init():
get_service()
-
diff --git a/src/jarabe/model/olpcmesh.py b/src/jarabe/model/olpcmesh.py
index 60f6be4..f070100 100644
--- a/src/jarabe/model/olpcmesh.py
+++ b/src/jarabe/model/olpcmesh.py
@@ -24,13 +24,14 @@ from jarabe.model.network import Settings
from jarabe.model.network import OlpcMesh as OlpcMeshSettings
from sugar.util import unique_id
+
_NM_SERVICE = 'org.freedesktop.NetworkManager'
_NM_IFACE = 'org.freedesktop.NetworkManager'
_NM_PATH = '/org/freedesktop/NetworkManager'
_NM_DEVICE_IFACE = 'org.freedesktop.NetworkManager.Device'
_NM_OLPC_MESH_IFACE = 'org.freedesktop.NetworkManager.Device.OlpcMesh'
-_XS_ANYCAST = "\xc0\x27\xc0\x27\xc0\x00"
+_XS_ANYCAST = '\xc0\x27\xc0\x27\xc0\x00'
DEVICE_STATE_UNKNOWN = 0
DEVICE_STATE_UNMANAGED = 1
@@ -43,6 +44,7 @@ DEVICE_STATE_IP_CONFIG = 7
DEVICE_STATE_ACTIVATED = 8
DEVICE_STATE_FAILED = 9
+
class OlpcMeshManager(object):
def __init__(self, mesh_device):
self._bus = dbus.SystemBus()
@@ -56,14 +58,12 @@ class OlpcMeshManager(object):
"""
- props = dbus.Interface(self.mesh_device,
- 'org.freedesktop.DBus.Properties')
+ props = dbus.Interface(self.mesh_device, dbus.PROPERTIES_IFACE)
props.Get(_NM_DEVICE_IFACE, 'State',
reply_handler=self.__get_mesh_state_reply_cb,
error_handler=self.__get_state_error_cb)
- props = dbus.Interface(self.eth_device,
- 'org.freedesktop.DBus.Properties')
+ props = dbus.Interface(self.eth_device, dbus.PROPERTIES_IFACE)
props.Get(_NM_DEVICE_IFACE, 'State',
reply_handler=self.__get_eth_state_reply_cb,
error_handler=self.__get_state_error_cb)
@@ -88,8 +88,7 @@ class OlpcMeshManager(object):
self._start_automesh()
def _get_companion_device(self):
- props = dbus.Interface(self.mesh_device,
- 'org.freedesktop.DBus.Properties')
+ props = dbus.Interface(self.mesh_device, dbus.PROPERTIES_IFACE)
eth_device_o = props.Get(_NM_OLPC_MESH_IFACE, 'Companion')
return self._bus.get_object(_NM_SERVICE, eth_device_o)
@@ -119,7 +118,7 @@ class OlpcMeshManager(object):
def __eth_device_state_changed_cb(self, new_state, old_state, reason):
"""If a connection is activated on the eth device, stop trying our
automatic connections.
-
+
"""
self._eth_device_state = new_state
self._maybe_schedule_idle_check()
@@ -147,7 +146,7 @@ class OlpcMeshManager(object):
def _idle_check(self):
if self._mesh_device_state == DEVICE_STATE_DISCONNECTED \
and self._eth_device_state == DEVICE_STATE_DISCONNECTED:
- logging.debug("starting automesh due to inactivity")
+ logging.debug('starting automesh due to inactivity')
self._start_automesh()
return False
@@ -170,7 +169,7 @@ class OlpcMeshManager(object):
logging.error('Failed to activate connection: %s', err)
def _activate_connection(self, channel, anycast_address=None):
- logging.debug("activate channel %d anycast %r",
+ logging.debug('activate channel %d anycast %r',
channel, anycast_address)
proxy = self._bus.get_object(_NM_SERVICE, _NM_PATH)
network_manager = dbus.Interface(proxy, _NM_IFACE)
@@ -211,4 +210,3 @@ class OlpcMeshManager(object):
self._connection_queue.append((6, _XS_ANYCAST))
self._connection_queue.append((1, _XS_ANYCAST))
self._try_next_connection_from_queue()
-
diff --git a/src/jarabe/model/screen.py b/src/jarabe/model/screen.py
index 4403c1c..7d34d45 100644
--- a/src/jarabe/model/screen.py
+++ b/src/jarabe/model/screen.py
@@ -18,12 +18,14 @@ import logging
import dbus
+
_HARDWARE_MANAGER_INTERFACE = 'org.freedesktop.ohm.Keystore'
_HARDWARE_MANAGER_SERVICE = 'org.freedesktop.ohm'
_HARDWARE_MANAGER_OBJECT_PATH = '/org/freedesktop/ohm/Keystore'
_ohm_service = None
+
def _get_ohm():
global _ohm_service
if _ohm_service is None:
@@ -35,9 +37,9 @@ def _get_ohm():
return _ohm_service
+
def set_dcon_freeze(frozen):
try:
- _get_ohm().SetKey("display.dcon_freeze", frozen)
+ _get_ohm().SetKey('display.dcon_freeze', frozen)
except dbus.DBusException:
logging.error('Cannot unfreeze the DCON')
-
diff --git a/src/jarabe/model/session.py b/src/jarabe/model/session.py
index 9e0f087..9b277ff 100644
--- a/src/jarabe/model/session.py
+++ b/src/jarabe/model/session.py
@@ -24,8 +24,10 @@ import logging
from sugar import session
from sugar import env
+
_session_manager = None
+
class SessionManager(session.SessionManager):
MODE_LOGOUT = 0
MODE_SHUTDOWN = 1
@@ -53,15 +55,15 @@ class SessionManager(session.SessionManager):
elif self._logout_mode != self.MODE_LOGOUT:
try:
bus = dbus.SystemBus()
- proxy = bus.get_object('org.freedesktop.Hal',
- '/org/freedesktop/Hal/devices/computer')
+ proxy = bus.get_object('org.freedesktop.ConsoleKit',
+ '/org/freedesktop/ConsoleKit/Manager')
pm = dbus.Interface(proxy,
- 'org.freedesktop.Hal.Device.SystemPowerManagement')
+ 'org.freedesktop.ConsoleKit.Manager')
if self._logout_mode == self.MODE_SHUTDOWN:
- pm.Shutdown()
+ pm.Stop()
elif self._logout_mode == self.MODE_REBOOT:
- pm.Reboot()
+ pm.Restart()
except:
logging.exception('Can not stop sugar')
self.session.cancel_shutdown()
@@ -73,14 +75,15 @@ class SessionManager(session.SessionManager):
def _close_emulator(self):
gtk.main_quit()
- if os.environ.has_key('SUGAR_EMULATOR_PID'):
+ if 'SUGAR_EMULATOR_PID' in os.environ:
pid = int(os.environ['SUGAR_EMULATOR_PID'])
os.kill(pid, signal.SIGTERM)
- # Need to call this ASAP so the atexit handlers get called before we get
- # killed by the X (dis)connection
+ # Need to call this ASAP so the atexit handlers get called before we
+ # get killed by the X (dis)connection
sys.exit()
+
def get_session_manager():
global _session_manager
diff --git a/src/jarabe/model/shell.py b/src/jarabe/model/shell.py
index db0e050..63f6173 100644
--- a/src/jarabe/model/shell.py
+++ b/src/jarabe/model/shell.py
@@ -31,9 +31,11 @@ from sugar.graphics.xocolor import XoColor
from jarabe.model.bundleregistry import get_registry
from jarabe.model import neighborhood
-_SERVICE_NAME = "org.laptop.Activity"
-_SERVICE_PATH = "/org/laptop/Activity"
-_SERVICE_INTERFACE = "org.laptop.Activity"
+_SERVICE_NAME = 'org.laptop.Activity'
+_SERVICE_PATH = '/org/laptop/Activity'
+_SERVICE_INTERFACE = 'org.laptop.Activity'
+
+_model = None
class Activity(gobject.GObject):
@@ -60,11 +62,12 @@ class Activity(gobject.GObject):
the "type" of activity being created.
activity_id -- unique identifier for this instance
of the activity type
- window -- Main WnckWindow of the activity
+ _windows -- WnckWindows registered for the activity. The lowest
+ one in the stack is the main window.
"""
gobject.GObject.__init__(self)
- self._window = None
+ self._windows = []
self._service = None
self._activity_id = activity_id
self._activity_info = activity_info
@@ -72,7 +75,7 @@ class Activity(gobject.GObject):
self._launch_status = Activity.LAUNCHING
if window is not None:
- self.set_window(window)
+ self.add_window(window)
self._retrieve_service()
@@ -81,8 +84,8 @@ class Activity(gobject.GObject):
bus = dbus.SessionBus()
self._name_owner_changed_handler = bus.add_signal_receiver(
self._name_owner_changed_cb,
- signal_name="NameOwnerChanged",
- dbus_interface="org.freedesktop.DBus")
+ signal_name='NameOwnerChanged',
+ dbus_interface='org.freedesktop.DBus')
self._launch_completed_hid = get_model().connect('launch-completed',
self.__launch_completed_cb)
@@ -94,15 +97,19 @@ class Activity(gobject.GObject):
launch_status = gobject.property(getter=get_launch_status)
- def set_window(self, window):
- """Set the window for the activity
-
- We allow resetting the window for an activity so that we
- can replace the launcher once we get its real window.
- """
+ def add_window(self, window):
+ """Add a window to the windows stack."""
if not window:
- raise ValueError("window must be valid")
- self._window = window
+ raise ValueError('window must be valid')
+ self._windows.append(window)
+
+ def remove_window_by_xid(self, xid):
+ """Remove a window from the windows stack."""
+ for wnd in self._windows:
+ if wnd.get_xid() == xid:
+ self._windows.remove(wnd)
+ return True
+ return False
def get_service(self):
"""Get the activity service
@@ -116,8 +123,8 @@ class Activity(gobject.GObject):
def get_title(self):
"""Retrieve the application's root window's suggested title"""
- if self._window:
- return self._window.get_name()
+ if self._windows:
+ return self._windows[0].get_name()
else:
return ''
@@ -157,7 +164,7 @@ class Activity(gobject.GObject):
return activity.props.color
else:
client = gconf.client_get_default()
- return XoColor(client.get_string("/desktop/sugar/user/color"))
+ return XoColor(client.get_string('/desktop/sugar/user/color'))
def get_activity_id(self):
"""Retrieve the "activity_id" passed in to our constructor
@@ -169,31 +176,44 @@ class Activity(gobject.GObject):
def get_xid(self):
"""Retrieve the X-windows ID of our root window"""
- if self._window is not None:
- return self._window.get_xid()
+ if self._windows:
+ return self._windows[0].get_xid()
else:
return None
+ def has_xid(self, xid):
+ """Check if an X-window with the given xid is in the windows stack"""
+ if self._windows:
+ for wnd in self._windows:
+ if wnd.get_xid() == xid:
+ return True
+ return False
+
def get_window(self):
"""Retrieve the X-windows root window of this application
- This was stored by the set_window method, which was
+ This was stored by the add_window method, which was
called by HomeModel._add_activity, which was called
via a callback that looks for all 'window-opened'
events.
+ We keep a stack of the windows. The lowest window in the
+ stack that is still valid we consider the main one.
+
HomeModel currently uses a dbus service query on the
activity to determine to which HomeActivity the newly
launched window belongs.
"""
- return self._window
+ if self._windows:
+ return self._windows[0]
+ return None
def get_type(self):
"""Retrieve the activity bundle id for future reference"""
- if self._window is None:
+ if not self._windows:
return None
else:
- return wm.get_bundle_id(self._window)
+ return wm.get_bundle_id(self._windows[0])
def is_journal(self):
"""Returns boolean if the activity is of type JournalActivity"""
@@ -209,7 +229,9 @@ class Activity(gobject.GObject):
def get_pid(self):
"""Returns the activity's PID"""
- return self._window.get_pid()
+ if not self._windows:
+ return None
+ return self._windows[0].get_pid()
def get_bundle_path(self):
"""Returns the activity's bundle directory"""
@@ -228,8 +250,8 @@ class Activity(gobject.GObject):
def equals(self, activity):
if self._activity_id and activity.get_activity_id():
return self._activity_id == activity.get_activity_id()
- if self._window.get_xid() and activity.get_xid():
- return self._window.get_xid() == activity.get_xid()
+ if self._windows[0].get_xid() and activity.get_xid():
+ return self._windows[0].get_xid() == activity.get_xid()
return False
def _get_service_name(self):
@@ -245,7 +267,7 @@ class Activity(gobject.GObject):
try:
bus = dbus.SessionBus()
proxy = bus.get_object(self._get_service_name(),
- _SERVICE_PATH + "/" + self._activity_id)
+ _SERVICE_PATH + '/' + self._activity_id)
self._service = dbus.Interface(proxy, _SERVICE_INTERFACE)
except dbus.DBusException:
self._service = None
@@ -275,7 +297,7 @@ class Activity(gobject.GObject):
pass
def _set_active_error(self, err):
- logging.error("set_active() failed: %s", err)
+ logging.error('set_active() failed: %s', err)
def _set_launch_status(self, value):
get_model().disconnect(self._launch_completed_hid)
@@ -310,27 +332,22 @@ class ShellModel(gobject.GObject):
"""
__gsignals__ = {
- 'activity-added': (gobject.SIGNAL_RUN_FIRST,
- gobject.TYPE_NONE,
- ([gobject.TYPE_PYOBJECT])),
- 'activity-removed': (gobject.SIGNAL_RUN_FIRST,
- gobject.TYPE_NONE,
- ([gobject.TYPE_PYOBJECT])),
+ 'activity-added': (gobject.SIGNAL_RUN_FIRST, gobject.TYPE_NONE,
+ ([gobject.TYPE_PYOBJECT])),
+ 'activity-removed': (gobject.SIGNAL_RUN_FIRST, gobject.TYPE_NONE,
+ ([gobject.TYPE_PYOBJECT])),
'active-activity-changed': (gobject.SIGNAL_RUN_FIRST,
gobject.TYPE_NONE,
- ([gobject.TYPE_PYOBJECT])),
+ ([gobject.TYPE_PYOBJECT])),
'tabbing-activity-changed': (gobject.SIGNAL_RUN_FIRST,
- gobject.TYPE_NONE,
- ([gobject.TYPE_PYOBJECT])),
- 'launch-started': (gobject.SIGNAL_RUN_FIRST,
- gobject.TYPE_NONE,
- ([gobject.TYPE_PYOBJECT])),
- 'launch-completed': (gobject.SIGNAL_RUN_FIRST,
- gobject.TYPE_NONE,
- ([gobject.TYPE_PYOBJECT])),
- 'launch-failed': (gobject.SIGNAL_RUN_FIRST,
- gobject.TYPE_NONE,
- ([gobject.TYPE_PYOBJECT]))
+ gobject.TYPE_NONE,
+ ([gobject.TYPE_PYOBJECT])),
+ 'launch-started': (gobject.SIGNAL_RUN_FIRST, gobject.TYPE_NONE,
+ ([gobject.TYPE_PYOBJECT])),
+ 'launch-completed': (gobject.SIGNAL_RUN_FIRST, gobject.TYPE_NONE,
+ ([gobject.TYPE_PYOBJECT])),
+ 'launch-failed': (gobject.SIGNAL_RUN_FIRST, gobject.TYPE_NONE,
+ ([gobject.TYPE_PYOBJECT])),
}
ZOOM_MESH = 0
@@ -460,7 +477,7 @@ class ShellModel(gobject.GObject):
def set_tabbing_activity(self, activity):
"""Sets the activity that is currently highlighted during tabbing"""
self._tabbing_activity = activity
- self.emit("tabbing-activity-changed", self._tabbing_activity)
+ self.emit('tabbing-activity-changed', self._tabbing_activity)
def _set_active_activity(self, home_activity):
if self._active_activity == home_activity:
@@ -488,6 +505,21 @@ class ShellModel(gobject.GObject):
return self._activities.index(obj)
def _window_opened_cb(self, screen, window):
+ """Handle the callback for the 'window opened' event.
+
+ Most activities will register 2 windows during
+ their lifetime: the launcher window, and the 'main'
+ app window.
+
+ When the main window appears, we send a signal to
+ the launcher window to close.
+
+ Some activities (notably non-native apps) open several
+ windows during their lifetime, switching from one to
+ the next as the 'main' window. We use a stack to track
+ them.
+
+ """
if window.get_window_type() == wnck.WINDOW_NORMAL:
home_activity = None
@@ -510,29 +542,36 @@ class ShellModel(gobject.GObject):
window.maximize()
if not home_activity:
+ logging.debug('first window registered for %s' % activity_id)
home_activity = Activity(activity_info, activity_id, window)
self._add_activity(home_activity)
else:
- home_activity.set_window(window)
+ logging.debug('window registered for %s' % activity_id)
+ home_activity.add_window(window)
- if wm.get_sugar_window_type(window) != 'launcher':
+ if wm.get_sugar_window_type(window) != 'launcher' \
+ and home_activity.get_launch_status() == Activity.LAUNCHING:
self.emit('launch-completed', home_activity)
-
startup_time = time.time() - home_activity.get_launch_time()
- logging.debug('%s launched in %f seconds.',
- home_activity.get_type(), startup_time)
+ logging.debug('%s launched in %f seconds.' %
+ (activity_id, startup_time))
if self._active_activity is None:
self._set_active_activity(home_activity)
def _window_closed_cb(self, screen, window):
if window.get_window_type() == wnck.WINDOW_NORMAL:
- if self._get_activity_by_xid(window.get_xid()) is not None:
- self._remove_activity_by_xid(window.get_xid())
+ xid = window.get_xid()
+ activity = self._get_activity_by_xid(xid)
+ if activity is not None:
+ activity.remove_window_by_xid(xid)
+ if activity.get_window() is None:
+ logging.debug('last window gone - remove activity %s' % activity)
+ self._remove_activity(activity)
def _get_activity_by_xid(self, xid):
for home_activity in self._activities:
- if home_activity.get_xid() == xid:
+ if home_activity.has_xid(xid):
return home_activity
return None
@@ -577,13 +616,6 @@ class ShellModel(gobject.GObject):
self.emit('activity-removed', home_activity)
self._activities.remove(home_activity)
- def _remove_activity_by_xid(self, xid):
- home_activity = self._get_activity_by_xid(xid)
- if home_activity:
- self._remove_activity(home_activity)
- else:
- logging.error('Model for window %d does not exist.', xid)
-
def notify_launch(self, activity_id, service_name):
registry = get_registry()
activity_info = registry.get_bundle(service_name)
@@ -606,7 +638,7 @@ class ShellModel(gobject.GObject):
def notify_launch_failed(self, activity_id):
home_activity = self.get_activity_by_id(activity_id)
if home_activity:
- logging.debug("Activity %s (%s) launch failed", activity_id,
+ logging.debug('Activity %s (%s) launch failed', activity_id,
home_activity.get_type())
if self.get_launcher(activity_id) is not None:
self.emit('launch-failed', home_activity)
@@ -631,11 +663,8 @@ class ShellModel(gobject.GObject):
return False
-_model = None
-
def get_model():
global _model
if _model is None:
_model = ShellModel()
return _model
-
diff --git a/src/jarabe/model/sound.py b/src/jarabe/model/sound.py
index 65090a4..9e1e748 100644
--- a/src/jarabe/model/sound.py
+++ b/src/jarabe/model/sound.py
@@ -20,17 +20,23 @@ from sugar import env
from sugar import _sugarext
from sugar import dispatch
+
VOLUME_STEP = 10
muted_changed = dispatch.Signal()
volume_changed = dispatch.Signal()
+_volume = _sugarext.VolumeAlsa()
+
+
def get_muted():
return _volume.get_mute()
+
def get_volume():
return _volume.get_volume()
+
def set_volume(new_volume):
old_volume = _volume.get_volume()
_volume.set_volume(new_volume)
@@ -38,6 +44,7 @@ def set_volume(new_volume):
volume_changed.send(None)
save()
+
def set_muted(new_state):
old_state = _volume.get_mute()
_volume.set_mute(new_state)
@@ -45,14 +52,14 @@ def set_muted(new_state):
muted_changed.send(None)
save()
+
def save():
if env.is_emulator() is False:
client = gconf.client_get_default()
client.set_int('/desktop/sugar/sound/volume', get_volume())
+
def restore():
if env.is_emulator() is False:
client = gconf.client_get_default()
set_volume(client.get_int('/desktop/sugar/sound/volume'))
-
-_volume = _sugarext.VolumeAlsa()
diff --git a/src/jarabe/model/telepathyclient.py b/src/jarabe/model/telepathyclient.py
index f4eccc3..c6fbac1 100644
--- a/src/jarabe/model/telepathyclient.py
+++ b/src/jarabe/model/telepathyclient.py
@@ -26,9 +26,13 @@ from telepathy.server import DBusProperties
from sugar import dispatch
+
SUGAR_CLIENT_SERVICE = 'org.freedesktop.Telepathy.Client.Sugar'
SUGAR_CLIENT_PATH = '/org/freedesktop/Telepathy/Client/Sugar'
+_instance = None
+
+
class TelepathyClient(dbus.service.Object, DBusProperties):
def __init__(self):
self._interfaces = set([CLIENT, CLIENT_HANDLER,
@@ -91,7 +95,6 @@ class TelepathyClient(dbus.service.Object, DBusProperties):
except Exception, e:
logging.exception(e)
-_instance = None
def get_instance():
global _instance
diff --git a/src/jarabe/util/__init__.py b/src/jarabe/util/__init__.py
index 1610dd0..9c80ecb 100644
--- a/src/jarabe/util/__init__.py
+++ b/src/jarabe/util/__init__.py
@@ -16,4 +16,3 @@
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
-
diff --git a/src/jarabe/util/emulator.py b/src/jarabe/util/emulator.py
index 6a43044..fda1b59 100644
--- a/src/jarabe/util/emulator.py
+++ b/src/jarabe/util/emulator.py
@@ -30,37 +30,37 @@ from sugar import env
ERROR_NO_DISPLAY = 30
ERROR_NO_SERVER = 31
+default_dimensions = (800, 600)
-default_dimensions = (800, 600)
def _run_xephyr(display, dpi, dimensions, fullscreen):
- cmd = [ 'Xephyr' ]
+ cmd = ['Xephyr']
cmd.append(':%d' % display)
- cmd.append('-ac')
+ cmd.append('-ac')
cmd += ['-title', _('Sugar in a window')]
screen_size = (gtk.gdk.screen_width(), gtk.gdk.screen_height())
if (not dimensions) and (fullscreen is None) and \
- (screen_size < default_dimensions) :
+ (screen_size <= default_dimensions):
# no forced settings, screen too small => fit screen
fullscreen = True
- elif (not dimensions) :
+ elif not dimensions:
# screen is big enough or user has en/disabled fullscreen manually
# => use default size (will get ignored for fullscreen)
dimensions = '%dx%d' % default_dimensions
- if not dpi :
+ if not dpi:
dpi = gtk.settings_get_default().get_property('gtk-xft-dpi') / 1024
- if fullscreen :
+ if fullscreen:
cmd.append('-fullscreen')
- if dimensions :
+ if dimensions:
cmd.append('-screen')
cmd.append(dimensions)
- if dpi :
+ if dpi:
cmd.append('-dpi')
cmd.append('%d' % dpi)
@@ -78,8 +78,8 @@ def _run_xephyr(display, dpi, dimensions, fullscreen):
def _check_server(display):
result = subprocess.call(['xdpyinfo', '-display', ':%d' % display],
- stdout=open(os.devnull, "w"),
- stderr=open(os.devnull, "w"))
+ stdout=open(os.devnull, 'w'),
+ stderr=open(os.devnull, 'w'))
return result == 0
@@ -118,6 +118,7 @@ def _start_window_manager():
gobject.spawn_async(cmd, flags=gobject.SPAWN_SEARCH_PATH)
+
def _setup_env(display, scaling, emulator_pid):
os.environ['SUGAR_EMULATOR'] = 'yes'
os.environ['GABBLE_LOGFILE'] = os.path.join(
@@ -128,7 +129,7 @@ def _setup_env(display, scaling, emulator_pid):
env.get_profile_path(), 'logs', 'mission-control.log')
os.environ['STREAM_ENGINE_LOGFILE'] = os.path.join(
env.get_profile_path(), 'logs', 'telepathy-stream-engine.log')
- os.environ['DISPLAY'] = ":%d" % (display)
+ os.environ['DISPLAY'] = ':%d' % (display)
os.environ['SUGAR_EMULATOR_PID'] = emulator_pid
os.environ['MC_ACCOUNT_DIR'] = os.path.join(
env.get_profile_path(), 'accounts')
@@ -136,11 +137,12 @@ def _setup_env(display, scaling, emulator_pid):
if scaling:
os.environ['SUGAR_SCALING'] = scaling
+
def main():
"""Script-level operations"""
parser = OptionParser()
- parser.add_option('-d', '--dpi', dest='dpi', type="int",
+ parser.add_option('-d', '--dpi', dest='dpi', type='int',
help='Emulator dpi')
parser.add_option('-s', '--scaling', dest='scaling',
help='Sugar scaling in %')
diff --git a/src/jarabe/util/telepathy/__init__.py b/src/jarabe/util/telepathy/__init__.py
index 387d09c..eee4abb 100644
--- a/src/jarabe/util/telepathy/__init__.py
+++ b/src/jarabe/util/telepathy/__init__.py
@@ -16,4 +16,3 @@
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
-
diff --git a/src/jarabe/util/telepathy/connection_watcher.py b/src/jarabe/util/telepathy/connection_watcher.py
index 391bdd5..96af1cf 100644
--- a/src/jarabe/util/telepathy/connection_watcher.py
+++ b/src/jarabe/util/telepathy/connection_watcher.py
@@ -28,12 +28,16 @@ from telepathy.interfaces import CONN_INTERFACE
from telepathy.constants import CONNECTION_STATUS_CONNECTED, \
CONNECTION_STATUS_DISCONNECTED
+
+_instance = None
+
+
class ConnectionWatcher(gobject.GObject):
__gsignals__ = {
'connection-added': (gobject.SIGNAL_RUN_FIRST, gobject.TYPE_NONE,
([gobject.TYPE_PYOBJECT])),
'connection-removed': (gobject.SIGNAL_RUN_FIRST, gobject.TYPE_NONE,
- ([gobject.TYPE_PYOBJECT]))
+ ([gobject.TYPE_PYOBJECT])),
}
def __init__(self, bus=None):
@@ -93,7 +97,6 @@ class ConnectionWatcher(gobject.GObject):
def get_connections(self):
return self._connections.values()
-_instance = None
def get_instance():
global _instance
@@ -101,14 +104,15 @@ def get_instance():
_instance = ConnectionWatcher()
return _instance
+
if __name__ == '__main__':
dbus.mainloop.glib.DBusGMainLoop(set_as_default=True)
def connection_added_cb(conn_watcher, conn):
- print "new connection", conn.service_name
+ print 'new connection', conn.service_name
def connection_removed_cb(conn_watcher, conn):
- print "removed connection", conn.service_name
+ print 'removed connection', conn.service_name
watcher = ConnectionWatcher()
watcher.connect('connection-added', connection_added_cb)
diff --git a/src/jarabe/view/__init__.py b/src/jarabe/view/__init__.py
index a9dd95a..85f6a24 100644
--- a/src/jarabe/view/__init__.py
+++ b/src/jarabe/view/__init__.py
@@ -13,4 +13,3 @@
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
-
diff --git a/src/jarabe/view/buddyicon.py b/src/jarabe/view/buddyicon.py
index 37b9167..a274605 100644
--- a/src/jarabe/view/buddyicon.py
+++ b/src/jarabe/view/buddyicon.py
@@ -19,6 +19,7 @@ from sugar.graphics import style
from jarabe.view.buddymenu import BuddyMenu
+
class BuddyIcon(CanvasIcon):
def __init__(self, buddy, size=style.STANDARD_ICON_SIZE):
CanvasIcon.__init__(self, icon_name='computer-xo', size=size)
@@ -28,6 +29,8 @@ class BuddyIcon(CanvasIcon):
self._buddy.connect('notify::present', self.__buddy_notify_present_cb)
self._buddy.connect('notify::color', self.__buddy_notify_color_cb)
+ self.palette_invoker.cache_palette = False
+
self._update_color()
def create_palette(self):
@@ -58,4 +61,3 @@ class BuddyIcon(CanvasIcon):
self._greyed_out = (self._buddy.get_nick().lower().find(query) == -1) \
and not self._buddy.is_owner()
self._update_color()
-
diff --git a/src/jarabe/view/buddymenu.py b/src/jarabe/view/buddymenu.py
index 0ba6cc1..f824e70 100644
--- a/src/jarabe/view/buddymenu.py
+++ b/src/jarabe/view/buddymenu.py
@@ -30,6 +30,8 @@ from jarabe.model import shell
from jarabe.model import friends
from jarabe.model.session import get_session_manager
from jarabe.controlpanel.gui import ControlPanel
+import jarabe.desktop.homewindow
+
class BuddyMenu(Palette):
def __init__(self, buddy):
@@ -86,6 +88,12 @@ class BuddyMenu(Palette):
client = gconf.client_get_default()
+ if client.get_bool('/desktop/sugar/show_restart'):
+ item = MenuItem(_('Restart'), 'system-restart')
+ item.connect('activate', self.__reboot_activate_cb)
+ self.menu.append(item)
+ item.show()
+
if client.get_bool('/desktop/sugar/show_logout'):
item = MenuItem(_('Logout'), 'system-logout')
item.connect('activate', self.__logout_activate_cb)
@@ -97,17 +105,18 @@ class BuddyMenu(Palette):
self.menu.append(item)
item.show()
+ def _quit(self, action):
+ home_window = jarabe.desktop.homewindow.get_instance()
+ home_window.busy_during_delayed_action(action)
+
def __logout_activate_cb(self, menu_item):
- session_manager = get_session_manager()
- session_manager.logout()
+ self._quit(get_session_manager().logout)
def __reboot_activate_cb(self, menu_item):
- session_manager = get_session_manager()
- session_manager.reboot()
+ self._quit(get_session_manager().reboot)
def __shutdown_activate_cb(self, menu_item):
- session_manager = get_session_manager()
- session_manager.shutdown()
+ self._quit(get_session_manager().shutdown)
def __controlpanel_activate_cb(self, menu_item):
panel = ControlPanel()
diff --git a/src/jarabe/view/keyhandler.py b/src/jarabe/view/keyhandler.py
index 8a85ac7..d79bfe6 100644
--- a/src/jarabe/view/keyhandler.py
+++ b/src/jarabe/view/keyhandler.py
@@ -17,7 +17,6 @@
import os
import logging
-import traceback
import dbus
import gtk
@@ -32,41 +31,46 @@ from jarabe.model.shell import ShellModel
from jarabe import config
from jarabe.journal import journalactivity
+
_VOLUME_STEP = sound.VOLUME_STEP
_VOLUME_MAX = 100
_TABBING_MODIFIER = gtk.gdk.MOD1_MASK
+
_actions_table = {
- 'F1' : 'zoom_mesh',
- 'F2' : 'zoom_group',
- 'F3' : 'zoom_home',
- 'F4' : 'zoom_activity',
- 'F5' : 'open_search',
- 'F6' : 'frame',
- 'XF86AudioMute' : 'volume_mute',
- 'F11' : 'volume_down',
- 'XF86AudioLowerVolume' : 'volume_down',
- 'F12' : 'volume_up',
- 'XF86AudioRaiseVolume' : 'volume_up',
- '<alt>F11' : 'volume_min',
- '<alt>F12' : 'volume_max',
- '0x93' : 'frame',
- '<alt>Tab' : 'next_window',
- '<alt><shift>Tab' : 'previous_window',
- '<alt>Escape' : 'close_window',
- '0xDC' : 'open_search',
+ 'F1': 'zoom_mesh',
+ 'F2': 'zoom_group',
+ 'F3': 'zoom_home',
+ 'F4': 'zoom_activity',
+ 'F5': 'open_search',
+ 'F6': 'frame',
+ 'XF86AudioMute': 'volume_mute',
+ 'F11': 'volume_down',
+ 'XF86AudioLowerVolume': 'volume_down',
+ 'F12': 'volume_up',
+ 'XF86AudioRaiseVolume': 'volume_up',
+ '<alt>F11': 'volume_min',
+ '<alt>F12': 'volume_max',
+ '0x93': 'frame',
+ '<alt>Tab': 'next_window',
+ '<alt><shift>Tab': 'previous_window',
+ '<alt>Escape': 'close_window',
+ '0xDC': 'open_search',
# the following are intended for emulator users
- '<alt><shift>f' : 'frame',
- '<alt><shift>q' : 'quit_emulator',
- 'XF86Search' : 'open_search',
- '<alt><shift>o' : 'open_search',
- '<alt><shift>s' : 'say_text',
+ '<alt><shift>f': 'frame',
+ '<alt><shift>q': 'quit_emulator',
+ 'XF86Search': 'open_search',
+ '<alt><shift>o': 'open_search',
+ '<alt><shift>s': 'say_text',
}
SPEECH_DBUS_SERVICE = 'org.laptop.Speech'
SPEECH_DBUS_PATH = '/org/laptop/Speech'
SPEECH_DBUS_INTERFACE = 'org.laptop.Speech'
+_instance = None
+
+
class KeyHandler(object):
def __init__(self, frame):
self._frame = frame
@@ -95,8 +99,7 @@ class KeyHandler(object):
raise ValueError('Key %r is already bound' % key)
_actions_table[key] = module
except Exception:
- logging.error('Exception while loading extension:\n' + \
- traceback.format_exc())
+ logging.exception('Exception while loading extension:')
self._key_grabber.grab_keys(_actions_table.keys())
@@ -126,11 +129,11 @@ class KeyHandler(object):
def _primary_selection_cb(self, clipboard, text, user_data):
logging.debug('KeyHandler._primary_selection_cb: %r', text)
if text:
- self._get_speech_proxy().SayText(text, reply_handler=lambda: None, \
+ self._get_speech_proxy().SayText(text, reply_handler=lambda: None,
error_handler=self._on_speech_err)
def handle_say_text(self, event_time):
- clipboard = gtk.clipboard_get(selection="PRIMARY")
+ clipboard = gtk.clipboard_get(selection='PRIMARY')
clipboard.request_text(self._primary_selection_cb)
def handle_previous_window(self, event_time):
@@ -197,7 +200,7 @@ class KeyHandler(object):
if self._tabbing_handler.is_tabbing():
# Only accept window tabbing events, everything else
# cancels the tabbing operation.
- if not action in ["next_window", "previous_window"]:
+ if not action in ['next_window', 'previous_window']:
self._tabbing_handler.stop(event_time)
return True
@@ -220,7 +223,7 @@ class KeyHandler(object):
return False
def _key_released_cb(self, grabber, keycode, state, event_time):
- logging.debug('_key_released_cb: %i %i' % (keycode, state))
+ logging.debug('_key_released_cb: %i %i', keycode, state)
if self._tabbing_handler.is_tabbing():
# We stop tabbing and switch to the new window as soon as the
# modifier key is raised again.
@@ -230,7 +233,6 @@ class KeyHandler(object):
return True
return False
-_instance = None
def setup(frame):
global _instance
@@ -239,4 +241,3 @@ def setup(frame):
del _instance
_instance = KeyHandler(frame)
-
diff --git a/src/jarabe/view/palettes.py b/src/jarabe/view/palettes.py
index 43612d4..d9c1f6b 100644
--- a/src/jarabe/view/palettes.py
+++ b/src/jarabe/view/palettes.py
@@ -28,13 +28,12 @@ from sugar.graphics.menuitem import MenuItem
from sugar.graphics.icon import Icon
from sugar.graphics import style
from sugar.graphics.xocolor import XoColor
-from sugar.activity import activityfactory
-from sugar.activity.activityhandle import ActivityHandle
from jarabe.model import shell
from jarabe.view.viewsource import setup_view_source
from jarabe.journal import misc
+
class BasePalette(Palette):
def __init__(self, home_activity):
Palette.__init__(self)
@@ -109,10 +108,6 @@ class CurrentActivityPalette(BasePalette):
self._home_activity.get_window().activate( \
gtk.get_current_event_time())
- def __active_window_changed_cb(self, screen, previous_window=None):
- setup_view_source()
- self._screen.disconnect(self._active_window_changed_sid)
-
def __stop_activate_cb(self, menu_item):
self._home_activity.get_window().close(1)
@@ -124,7 +119,7 @@ class ActivityPalette(Palette):
self._activity_info = activity_info
client = gconf.client_get_default()
- color = XoColor(client.get_string("/desktop/sugar/user/color"))
+ color = XoColor(client.get_string('/desktop/sugar/user/color'))
activity_icon = Icon(file=activity_info.get_icon(),
xo_color=color,
icon_size=gtk.ICON_SIZE_LARGE_TOOLBAR)
@@ -147,6 +142,7 @@ class ActivityPalette(Palette):
self.popdown(immediate=True)
misc.launch(self._activity_info)
+
class JournalPalette(BasePalette):
def __init__(self, home_activity):
self._home_activity = home_activity
@@ -198,6 +194,7 @@ class JournalPalette(BasePalette):
self._free_space_label.props.label = _('%(free_space)d MB Free') % \
{'free_space': free_space / (1024 * 1024)}
+
class VolumePalette(Palette):
def __init__(self, mount):
Palette.__init__(self, label=mount.get_name())
@@ -247,4 +244,3 @@ class VolumePalette(Palette):
self._progress_bar.props.fraction = fraction
self._free_space_label.props.label = _('%(free_space)d MB Free') % \
{'free_space': free_space / (1024 * 1024)}
-
diff --git a/src/jarabe/view/pulsingicon.py b/src/jarabe/view/pulsingicon.py
index 43ec358..392a404 100644
--- a/src/jarabe/view/pulsingicon.py
+++ b/src/jarabe/view/pulsingicon.py
@@ -21,9 +21,11 @@ import gobject
from sugar.graphics.icon import Icon, CanvasIcon
+
_INTERVAL = 100
_STEP = math.pi / 10 # must be a fraction of pi, for clean caching
+
class Pulser(object):
def __init__(self, icon):
self._pulse_hid = None
@@ -83,6 +85,7 @@ class Pulser(object):
return True
+
class PulsingIcon(Icon):
__gtype_name__ = 'SugarPulsingIcon'
@@ -161,6 +164,7 @@ class PulsingIcon(Icon):
if self._palette is not None:
self._palette.destroy()
+
class CanvasPulsingIcon(CanvasIcon):
__gtype_name__ = 'SugarCanvasPulsingIcon'
diff --git a/src/jarabe/view/service.py b/src/jarabe/view/service.py
index 7af778a..29e46b2 100644
--- a/src/jarabe/view/service.py
+++ b/src/jarabe/view/service.py
@@ -23,9 +23,11 @@ import gtk
from jarabe.model import shell
from jarabe.model import bundleregistry
-_DBUS_SERVICE = "org.laptop.Shell"
-_DBUS_SHELL_IFACE = "org.laptop.Shell"
-_DBUS_PATH = "/org/laptop/Shell"
+
+_DBUS_SERVICE = 'org.laptop.Shell'
+_DBUS_SHELL_IFACE = 'org.laptop.Shell'
+_DBUS_PATH = '/org/laptop/Shell'
+
class UIService(dbus.service.Object):
"""Provides d-bus service to script the shell's operations
@@ -54,7 +56,7 @@ class UIService(dbus.service.Object):
self._shell_model = shell.get_model()
@dbus.service.method(_DBUS_SHELL_IFACE,
- in_signature="s", out_signature="s")
+ in_signature='s', out_signature='s')
def GetBundlePath(self, bundle_id):
bundle = bundleregistry.get_registry().get_bundle(bundle_id)
if bundle:
@@ -63,11 +65,11 @@ class UIService(dbus.service.Object):
return ''
@dbus.service.method(_DBUS_SHELL_IFACE,
- in_signature="s", out_signature="b")
+ in_signature='s', out_signature='b')
def ActivateActivity(self, activity_id):
- """Switch to the window related to this activity_id and return a boolean
- indicating if there is a real (ie. not a launcher window) activity
- already open.
+ """Switch to the window related to this activity_id and return a
+ boolean indicating if there is a real (ie. not a launcher window)
+ activity already open.
"""
activity = self._shell_model.get_activity_by_id(activity_id)
@@ -78,12 +80,11 @@ class UIService(dbus.service.Object):
return False
@dbus.service.method(_DBUS_SHELL_IFACE,
- in_signature="ss", out_signature="")
+ in_signature='ss', out_signature='')
def NotifyLaunch(self, bundle_id, activity_id):
shell.get_model().notify_launch(activity_id, bundle_id)
@dbus.service.method(_DBUS_SHELL_IFACE,
- in_signature="s", out_signature="")
+ in_signature='s', out_signature='')
def NotifyLaunchFailure(self, activity_id):
shell.get_model().notify_launch_failed(activity_id)
-
diff --git a/src/jarabe/view/tabbinghandler.py b/src/jarabe/view/tabbinghandler.py
index f52bda3..0889792 100644
--- a/src/jarabe/view/tabbinghandler.py
+++ b/src/jarabe/view/tabbinghandler.py
@@ -21,8 +21,10 @@ import gtk
from jarabe.model import shell
+
_RAISE_DELAY = 250
+
class TabbingHandler(object):
def __init__(self, frame, modifier):
self._frame = frame
@@ -145,4 +147,3 @@ class TabbingHandler(object):
def is_tabbing(self):
return self._tabbing
-
diff --git a/src/jarabe/view/viewsource.py b/src/jarabe/view/viewsource.py
index 290df18..a1c0be3 100644
--- a/src/jarabe/view/viewsource.py
+++ b/src/jarabe/view/viewsource.py
@@ -17,7 +17,6 @@
import os
import logging
-import traceback
from gettext import gettext as _
import gobject
@@ -37,11 +36,13 @@ from sugar.bundle.activitybundle import ActivityBundle
from sugar.datastore import datastore
from sugar import mime
+
_SOURCE_FONT = pango.FontDescription('Monospace %d' % style.FONT_SIZE)
_logger = logging.getLogger('ViewSource')
map_activity_to_window = {}
+
def setup_view_source(activity):
service = activity.get_service()
if service is not None:
@@ -52,9 +53,9 @@ def setup_view_source(activity):
expected_exceptions = ['org.freedesktop.DBus.Error.UnknownMethod',
'org.freedesktop.DBus.Python.NotImplementedError']
if e.get_dbus_name() not in expected_exceptions:
- logging.error(traceback.format_exc())
+ logging.exception('Exception occured in HandleViewSource():')
except Exception:
- logging.error(traceback.format_exc())
+ logging.exception('Exception occured in HandleViewSource():')
window_xid = activity.get_xid()
if window_xid is None:
@@ -76,9 +77,9 @@ def setup_view_source(activity):
expected_exceptions = ['org.freedesktop.DBus.Error.UnknownMethod',
'org.freedesktop.DBus.Python.NotImplementedError']
if e.get_dbus_name() not in expected_exceptions:
- logging.error(traceback.format_exc())
+ logging.exception('Exception occured in GetDocumentPath():')
except Exception:
- logging.error(traceback.format_exc())
+ logging.exception('Exception occured in GetDocumentPath():')
if bundle_path is None and document_path is None:
_logger.debug('Activity without bundle_path nor document_path')
@@ -89,6 +90,7 @@ def setup_view_source(activity):
map_activity_to_window[window_xid] = view_source
view_source.show()
+
class ViewSource(gtk.Window):
__gtype_name__ = 'SugarViewSource'
@@ -129,10 +131,10 @@ class ViewSource(gtk.Window):
file_name = ''
activity_bundle = ActivityBundle(bundle_path)
- command = activity_bundle.get_command()
+ command = activity_bundle.get_command()
if len(command.split(' ')) > 1:
name = command.split(' ')[1].split('.')[0]
- file_name = name + '.py'
+ file_name = name + '.py'
path = os.path.join(activity_bundle.get_path(), file_name)
self._selected_file = path
@@ -195,6 +197,7 @@ class ViewSource(gtk.Window):
else:
self._source_display.file_path = None
+
class DocumentButton(RadioToolButton):
__gtype_name__ = 'SugarDocumentButton'
@@ -244,22 +247,20 @@ class DocumentButton(RadioToolButton):
error_handler=self.__internal_save_error_cb)
def __internal_save_cb(self):
- logging.debug("Saved Source object to datastore.")
+ logging.debug('Saved Source object to datastore.')
self._jobject.destroy()
def __internal_save_error_cb(self, err):
logging.debug('Error saving Source object to datastore: %s', err)
self._jobject.destroy()
+
class Toolbar(gtk.Toolbar):
__gtype_name__ = 'SugarViewSourceToolbar'
__gsignals__ = {
- 'stop-clicked': (gobject.SIGNAL_RUN_FIRST,
- gobject.TYPE_NONE,
- ([])),
- 'source-selected': (gobject.SIGNAL_RUN_FIRST,
- gobject.TYPE_NONE,
+ 'stop-clicked': (gobject.SIGNAL_RUN_FIRST, gobject.TYPE_NONE, ([])),
+ 'source-selected': (gobject.SIGNAL_RUN_FIRST, gobject.TYPE_NONE,
([str])),
}
@@ -339,6 +340,7 @@ class Toolbar(gtk.Toolbar):
if button.props.active:
self.emit('source-selected', path)
+
class FileViewer(gtk.ScrolledWindow):
__gtype_name__ = 'SugarFileViewer'
@@ -405,6 +407,7 @@ class FileViewer(gtk.ScrolledWindow):
file_path = model.get_value(tree_iter, 1)
self.emit('file-selected', file_path)
+
class SourceDisplay(gtk.ScrolledWindow):
__gtype_name__ = 'SugarSourceDisplay'
@@ -461,4 +464,3 @@ class SourceDisplay(gtk.ScrolledWindow):
return self._file_path
file_path = property(_get_file_path, _set_file_path)
-