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:07:19 (GMT)
committer Sascha Silbe <silbe@activitycentral.com>2011-03-12 17:07:19 (GMT)
commit719c590c48af95a1e43c1ceebe364ab6a49876d1 (patch)
tree5c4478beca3306f1c74c7319e777ea5da161bae6
parentb299638202e2fed008cba19d7767fe847e10c7d2 (diff)
parent132428cb62a031901e84067a99ff53ee58bdc74d (diff)
Merge branch 't/vnc+sugar-i18n-shell' into refs/top-bases/t/versions
* t/vnc+sugar-i18n-shell: (87 commits) 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 Revert "Add cpu and memory resource indicator to frame" as agreed on with erikos. Scheduling for inclusion in 0.94 after potential artwork changes based on feedback from the Design Team. ... Conflicts: extensions/cpsection/network/model.py extensions/deviceicon/battery.py extensions/deviceicon/network.py src/jarabe/desktop/meshbox.py src/jarabe/model/network.py
-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.py40
-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.py54
-rw-r--r--extensions/deviceicon/network.py114
-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.po791
-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.py76
-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.py95
-rw-r--r--src/jarabe/journal/modalalert.py7
-rw-r--r--src/jarabe/journal/model.py189
-rw-r--r--src/jarabe/journal/objectchooser.py8
-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.py112
-rw-r--r--src/jarabe/model/network.py336
-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.py9
-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.py5
-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, 5071 insertions, 2873 deletions
diff --git a/configure.ac b/configure.ac
index c1adad1..151eaa5 100644
--- a/configure.ac
+++ b/configure.ac
@@ -1,11 +1,11 @@
-AC_INIT([Sugar],[0.90.2],[],[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.90.0"
+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..a7ae17e 100644
--- a/extensions/cpsection/network/model.py
+++ b/extensions/cpsection/network/model.py
@@ -20,25 +20,33 @@ 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 +56,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 +71,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 +92,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 +109,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 3d092e5..4c1ef37 100644
--- a/extensions/deviceicon/battery.py
+++ b/extensions/deviceicon/battery.py
@@ -39,6 +39,8 @@ _STATUS_DISCHARGING = 1
_STATUS_FULLY_CHARGED = 2
_STATUS_NOT_PRESENT = 3
+_UP_DEVICE_IFACE = 'org.freedesktop.UPower.Device'
+
_UP_TYPE_BATTERY = 2
_UP_STATE_UNKNOWN = 0
@@ -68,7 +70,7 @@ class DeviceView(TrayIcon):
self.palette = BatteryPalette(_('My Battery'))
self.palette.set_group_id('frame')
self._model.connect('updated',
- self._battery_status_changed_cb)
+ self.__battery_status_changed_cb)
self._update_info()
def _update_info(self):
@@ -95,14 +97,14 @@ class DeviceView(TrayIcon):
status = _STATUS_FULLY_CHARGED
self.icon.props.icon_name = get_icon_state(name, current_level,
- step=-5)
+ step=-5)
self.icon.props.xo_color = xo_color
self.icon.props.badge_name = badge_name
self.palette.set_info(current_level, self._model.props.time_remaining,
- status)
+ status)
- def _battery_status_changed_cb(self, *args):
+ def __battery_status_changed_cb(self, model):
self._update_info()
@@ -128,16 +130,16 @@ class BatteryPalette(Palette):
self._progress_widget = vbox
self.set_content(self._progress_widget)
- def set_info(self, percent, seconds, status):
- self._level = percent
+ def set_info(self, percentage, seconds, status):
+ self._level = percentage
self._time = seconds
self._status = status
- self._progress_bar.set_fraction(percent / 100.0)
+ self._progress_bar.set_fraction(percentage / 100.0)
self._update_secondary()
def _update_secondary(self):
secondary_text = ''
- status_text = '%s%%' % self._level
+ status_text = '%s%%' % (self._level, )
progress_widget = self._progress_widget
if self._status == _STATUS_NOT_PRESENT:
@@ -156,6 +158,7 @@ class BatteryPalette(Palette):
{'hour': remaining_hourpart, 'min': remaining_minpart}
else:
secondary_text = _('Charged')
+
self.set_content(progress_widget)
self.props.secondary_text = secondary_text
@@ -166,7 +169,7 @@ class DeviceModel(gobject.GObject):
__gproperties__ = {
'level': (int, None, None, 0, 100, 0, gobject.PARAM_READABLE),
'time-remaining': (int, None, None, 0, sys.maxint, 0,
- gobject.PARAM_READABLE), # unit: seconds
+ 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),
@@ -180,17 +183,17 @@ class DeviceModel(gobject.GObject):
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_changed,
- dbus_interface='org.freedesktop.UPower.Device')
- self._fetch()
+ 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(self):
+ def _fetch_properties_from_upower(self):
"""Get current values from UPower."""
- # pylint: disable-msg=W0201
+ # pylint: disable=W0201
try:
- dbus_props = self._battery_props_iface.GetAll(
- 'org.freedesktop.UPower.Device')
+ dbus_props = self._battery_props_iface.GetAll(_UP_DEVICE_IFACE)
except dbus.DBusException:
logging.error('Cannot access battery properties')
dbus_props = {}
@@ -221,12 +224,12 @@ class DeviceModel(gobject.GObject):
def get_type(self):
return 'battery'
- def _battery_changed(self, *args):
+ 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()
+ self._fetch_properties_from_upower()
if self._level != old_level:
self.notify('level')
if self._state != old_state:
@@ -243,13 +246,12 @@ class DeviceModel(gobject.GObject):
def setup(tray):
bus = dbus.Bus(dbus.Bus.TYPE_SYSTEM)
up_proxy = bus.get_object('org.freedesktop.UPower',
- '/org/freedesktop/UPower')
+ '/org/freedesktop/UPower')
upower = dbus.Interface(up_proxy, 'org.freedesktop.UPower')
- for battery_path in upower.EnumerateDevices():
- battery = bus.get_object('org.freedesktop.UPower', battery_path)
- batt_prop_iface = dbus.Interface(battery, dbus.PROPERTIES_IFACE)
- device_type = batt_prop_iface.Get('org.freedesktop.UPower.Device',
- 'Type')
+ 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(battery))
+ tray.add_device(DeviceView(device))
diff --git a/extensions/deviceicon/network.py b/extensions/deviceicon/network.py
index 9d670f3..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,26 +564,12 @@ class WirelessDeviceView(ToolButton):
self._icon.props.base_color = self._color
def __deactivate_connection_cb(self, palette, data=None):
- connection = network.find_connection_by_ssid(self._name)
- if connection:
- if self._mode == network.NM_802_11_MODE_INFRA:
- connection.set_disconnected()
+ if self._mode == network.NM_802_11_MODE_INFRA:
+ connection = network.find_connection_by_ssid(self._name)
+ if connection:
+ connection.disable_autoconnect()
- 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
+ network.disconnect_access_points([self._active_ap_op])
def __activate_reply_cb(self, connection):
logging.debug('Network created: %s', connection)
@@ -607,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
@@ -617,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)
@@ -626,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)
@@ -660,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):
@@ -688,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:
@@ -754,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()
@@ -763,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)
@@ -796,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(
@@ -966,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)
@@ -994,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)
@@ -1006,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
@@ -1020,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()
@@ -1053,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:
@@ -1078,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 fbe3266..1624694 100644
--- a/po/de.po
+++ b/po/de.po
@@ -14,14 +14,38 @@
# 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-09-18 00:31-0400\n"
-"PO-Revision-Date: 2010-09-20 19:44+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"
@@ -36,35 +60,35 @@ 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."
@@ -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:187
+#: ../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:199
+#: ../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:50
+#: ../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 "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:29
+#: ../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:125
+#: ../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:145
+#: ../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 "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:62
+#: ../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:88
+#: ../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:120
+#: ../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,32 +459,32 @@ 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 "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"
-#: ../extensions/deviceicon/network.py:52
+#: ../extensions/deviceicon/network.py:49
#, python-format
msgid "IP address: %s"
msgstr "IP-Addresse: %s"
@@ -469,7 +493,7 @@ 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:107
+#: ../extensions/deviceicon/network.py:104
msgid "Disconnect..."
msgstr "Verbindung trennen..."
@@ -477,110 +501,110 @@ msgstr "Verbindung trennen..."
# 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:114
-#: ../extensions/deviceicon/network.py:293
-#: ../src/jarabe/desktop/networkviews.py:238
-#: ../src/jarabe/desktop/networkviews.py:535
-#: ../src/jarabe/desktop/networkviews.py:664
+#: ../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:118
-#: ../extensions/deviceicon/network.py:184
-#: ../src/jarabe/desktop/networkviews.py:248
-#: ../src/jarabe/desktop/networkviews.py:541
-#: ../src/jarabe/desktop/networkviews.py:670
+#: ../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:144
+#: ../extensions/deviceicon/network.py:142
msgid "Channel"
msgstr "Kanal"
-#: ../extensions/deviceicon/network.py:159
+#: ../extensions/deviceicon/network.py:157
msgid "Wired Network"
msgstr "Kabelnetzwerk"
# (Markus S.) War 'Geschwindigkeit'
-#: ../extensions/deviceicon/network.py:187
+#: ../extensions/deviceicon/network.py:185
msgid "Speed"
msgstr "Übertragungsrate"
-#: ../extensions/deviceicon/network.py:214
+#: ../extensions/deviceicon/network.py:211
msgid "Wireless modem"
msgstr "Funkmodem"
-#: ../extensions/deviceicon/network.py:281
+#: ../extensions/deviceicon/network.py:278
msgid "Please wait..."
msgstr "Bitte warten..."
-#: ../extensions/deviceicon/network.py:285
-#: ../src/jarabe/desktop/networkviews.py:148
-#: ../src/jarabe/desktop/networkviews.py:489
-#: ../src/jarabe/desktop/networkviews.py:621
+#: ../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:286
+#: ../extensions/deviceicon/network.py:283
msgid "Disconnected"
msgstr "Nicht verbunden"
-#: ../extensions/deviceicon/network.py:292
-#: ../src/jarabe/controlpanel/toolbar.py:115
-#: ../src/jarabe/desktop/homebox.py:68
-#: ../src/jarabe/frame/activitiestray.py:582
-#: ../src/jarabe/frame/activitiestray.py:681
-#: ../src/jarabe/frame/activitiestray.py:709
+#: ../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:300
-#: ../src/jarabe/desktop/networkviews.py:152
-#: ../src/jarabe/desktop/networkviews.py:493
+#: ../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:330
+#: ../extensions/deviceicon/network.py:327
msgid "Try connection again"
msgstr "Erneuter Verbindungsversuch"
-#: ../extensions/deviceicon/network.py:332
+#: ../extensions/deviceicon/network.py:330
#, python-format
msgid "Error: %s"
msgstr "Fehler: %s"
-#: ../extensions/deviceicon/network.py:336
+#: ../extensions/deviceicon/network.py:334
#, python-format
msgid "Suggestion: %s"
msgstr "Vorschlag: %s"
-#: ../extensions/deviceicon/network.py:342
-#: ../extensions/deviceicon/network.py:345
+#: ../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:350
-#: ../extensions/deviceicon/network.py:351
+#: ../extensions/deviceicon/network.py:348
+#: ../extensions/deviceicon/network.py:349
#, python-format
msgid "%d KB"
msgstr "%d KB"
-#: ../extensions/deviceicon/network.py:356
+#: ../extensions/deviceicon/network.py:354
msgid "Check your Pin/Puk configuration."
msgstr "Überprüfe deine Pin/Puk-Einstellungen."
-#: ../extensions/deviceicon/network.py:359
+#: ../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:363
+#: ../extensions/deviceicon/network.py:361
msgid "Check the Number configuration."
msgstr "Überprüfe deine Einstellung der Nummer."
-#: ../extensions/deviceicon/network.py:365
+#: ../extensions/deviceicon/network.py:363
msgid "Check your configuration."
msgstr "Überprüfe deine Einstellungen."
@@ -593,35 +617,35 @@ msgstr "Maschennetzwerk"
msgid "Mesh Network %s"
msgstr "Maschennetzwerk %s"
-#: ../extensions/deviceicon/network.py:780
+#: ../extensions/deviceicon/network.py:782
msgid "No GSM connection available."
msgstr "Keine GSM-Verbindung verfügbar."
-#: ../extensions/deviceicon/network.py:781
+#: ../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:36
+#: ../extensions/deviceicon/touchpad.py:37
msgid "finger"
msgstr "Finger"
-#: ../extensions/deviceicon/touchpad.py:37
+#: ../extensions/deviceicon/touchpad.py:38
msgid "stylus"
msgstr "Stift"
-#: ../extensions/deviceicon/touchpad.py:63
+#: ../extensions/deviceicon/touchpad.py:67
msgid "My touchpad"
msgstr "Mein Touchpad"
@@ -631,18 +655,18 @@ 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"
@@ -795,6 +819,10 @@ msgid "If TRUE, Sugar will show a \"Log out\" option."
msgstr "Falls WAHR, wird Sugar die Option \"Abmelden\" anzeigen."
#: ../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-"
@@ -802,120 +830,124 @@ msgid ""
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, "
-"vergbindet es sich automatisch mit einem Ad-hoc-Netzwerk."
+"verbindet es sich automatisch mit einem Ad-hoc-Netzwerk."
-#: ../data/sugar.schemas.in.h:33
+#: ../data/sugar.schemas.in.h:34
msgid "Jabber Server"
msgstr "Jabber-Server"
-#: ../data/sugar.schemas.in.h:34
+#: ../data/sugar.schemas.in.h:35
msgid "Keyboard layouts"
msgstr "Tastaturlayouts"
-#: ../data/sugar.schemas.in.h:35
+#: ../data/sugar.schemas.in.h:36
msgid "Keyboard model"
msgstr "Tastaturmodell"
-#: ../data/sugar.schemas.in.h:36
+#: ../data/sugar.schemas.in.h:37
msgid "Keyboard options"
msgstr "Tastatureinstellungen"
-#: ../data/sugar.schemas.in.h:37
+#: ../data/sugar.schemas.in.h:38
msgid "Layout of the favorites view."
msgstr "Layout der Favoriten-Ansicht."
-#: ../data/sugar.schemas.in.h:38
+#: ../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:39
+#: ../data/sugar.schemas.in.h:40
msgid "List of keyboard options."
msgstr "Liste der Tastatureinstellungen."
-#: ../data/sugar.schemas.in.h:40
+#: ../data/sugar.schemas.in.h:41
msgid "Power Automatic"
msgstr "Automatische Energieverwaltung"
-#: ../data/sugar.schemas.in.h:41
+#: ../data/sugar.schemas.in.h:42
msgid "Power Automatic."
msgstr "Automatische Energieverwaltung."
# (Markus S.) war 'Extreme Energieverwaltung'
-#: ../data/sugar.schemas.in.h:42
+#: ../data/sugar.schemas.in.h:43
msgid "Power Extreme"
msgstr "Extremes Energiesparen"
# (Markus S.) war 'Extreme Energieverwaltung'
-#: ../data/sugar.schemas.in.h:43
+#: ../data/sugar.schemas.in.h:44
msgid "Power Extreme."
msgstr "Extremes Energiesparen."
-#: ../data/sugar.schemas.in.h:44
+#: ../data/sugar.schemas.in.h:45
msgid "Publish to Gadget"
msgstr "Veröffentlichen auf Gerät"
-#: ../data/sugar.schemas.in.h:45
+#: ../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:46
+#: ../data/sugar.schemas.in.h:47
msgid "Show Log out"
msgstr "Abmelden anzeigen"
-#: ../data/sugar.schemas.in.h:47
+#: ../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:48
+#: ../data/sugar.schemas.in.h:50
msgid "Sound Muted"
msgstr "Stummgeschaltet"
-#: ../data/sugar.schemas.in.h:49
+#: ../data/sugar.schemas.in.h:51
msgid "The keyboard model to be used"
msgstr "Das zu verwendende Tastaturmodell"
-#: ../data/sugar.schemas.in.h:51
+#: ../data/sugar.schemas.in.h:53
msgid "Timezone setting for the system."
msgstr "Zeitzoneneinstellung des Systems."
-#: ../data/sugar.schemas.in.h:52
+#: ../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:53
+#: ../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:54
+#: ../data/sugar.schemas.in.h:56
msgid "User Color"
msgstr "Benutzerfarbe"
-#: ../data/sugar.schemas.in.h:55
+#: ../data/sugar.schemas.in.h:57
msgid "User Name"
msgstr "Benutzername"
-#: ../data/sugar.schemas.in.h:56
+#: ../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:57
+#: ../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:58
+#: ../data/sugar.schemas.in.h:60
msgid "Volume Level"
msgstr "Lautstärke"
-#: ../data/sugar.schemas.in.h:59
+#: ../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:60
+#: ../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."
@@ -947,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"
@@ -969,54 +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/journal/journaltoolbox.py:447
-#: ../src/jarabe/journal/volumestoolbar.py:159
+#: ../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:332
+#: ../src/jarabe/controlpanel/toolbar.py:125
+#: ../src/jarabe/desktop/favoritesview.py:336
msgid "Ok"
msgstr "Ok"
-#: ../src/jarabe/desktop/activitieslist.py:231
+#: ../src/jarabe/desktop/activitieslist.py:230
#, python-format
msgid "Version %s"
msgstr "Version %s"
-#: ../src/jarabe/desktop/activitieslist.py:352
+#: ../src/jarabe/desktop/activitieslist.py:354
msgid "Confirm erase"
msgstr "Löschen bestätigen"
-#: ../src/jarabe/desktop/activitieslist.py:354
+#: ../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?"
@@ -1025,432 +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:358
-#: ../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:361
-#: ../src/jarabe/desktop/activitieslist.py:414
-#: ../src/jarabe/journal/journaltoolbox.py:401
-#: ../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:429
+#: ../src/jarabe/desktop/activitieslist.py:432
msgid "Remove favorite"
msgstr "Favorit entfernen"
-#: ../src/jarabe/desktop/activitieslist.py:433
+#: ../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:124
+#: ../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:211
+#: ../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:394
+#: ../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:461
+#: ../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:502
+#: ../src/jarabe/desktop/favoriteslayout.py:515
msgid "Triangle"
msgstr "Dreieck"
-#: ../src/jarabe/desktop/favoritesview.py:323
+#: ../src/jarabe/desktop/favoritesview.py:327
msgid "Registration Failed"
msgstr "Anmeldung fehlgeschlagen"
-#: ../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 "Anmeldung erfolgreich"
-#: ../src/jarabe/desktop/favoritesview.py:327
+#: ../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:618
+#: ../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:"
# TRANS: Action label for resuming an activity.
#. TRANS: Action label for resuming an activity.
-#: ../src/jarabe/desktop/meshbox.py:105
-#: ../src/jarabe/frame/activitiestray.py:617
-#: ../src/jarabe/journal/journaltoolbox.py:495
-#: ../src/jarabe/journal/palettes.py:66 ../src/jarabe/view/palettes.py:79
+#: ../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:110
-#: ../src/jarabe/frame/activitiestray.py:174
+#: ../src/jarabe/desktop/meshbox.py:114
+#: ../src/jarabe/frame/activitiestray.py:173
msgid "Join"
-msgstr "Mitmachen"
+msgstr "Beitreten"
-#: ../src/jarabe/desktop/networkviews.py:486
+#: ../src/jarabe/desktop/networkviews.py:489
#, python-format
msgid "Ad-hoc Network %d"
msgstr "Ad-hoc-Netzwerk %d"
-#: ../src/jarabe/desktop/networkviews.py:619
+#: ../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:179
-#: ../src/jarabe/frame/activitiestray.py:554
+#: ../src/jarabe/frame/activitiestray.py:178
+#: ../src/jarabe/frame/activitiestray.py:559
msgid "Decline"
msgstr "Ablehnen"
-#: ../src/jarabe/frame/activitiestray.py:506
+#: ../src/jarabe/frame/activitiestray.py:509
#, python-format
msgid "%dB"
msgstr "%dB"
-#: ../src/jarabe/frame/activitiestray.py:508
+#: ../src/jarabe/frame/activitiestray.py:511
#, python-format
msgid "%dKB"
msgstr "%dKB"
-#: ../src/jarabe/frame/activitiestray.py:510
+#: ../src/jarabe/frame/activitiestray.py:513
#, python-format
msgid "%dMB"
msgstr "%dMB"
-#: ../src/jarabe/frame/activitiestray.py:527
+#: ../src/jarabe/frame/activitiestray.py:530
#, python-format
msgid "%s of %s"
msgstr "%s von %s"
-#: ../src/jarabe/frame/activitiestray.py:539
+#: ../src/jarabe/frame/activitiestray.py:544
#, python-format
msgid "Transfer from %r"
msgstr "Übertragung von %r"
-#: ../src/jarabe/frame/activitiestray.py:549
+#: ../src/jarabe/frame/activitiestray.py:554
msgid "Accept"
msgstr "Akzeptieren"
-#: ../src/jarabe/frame/activitiestray.py:572
-#: ../src/jarabe/frame/activitiestray.py:699
+#: ../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:606
-#: ../src/jarabe/frame/activitiestray.py:734
+#: ../src/jarabe/frame/activitiestray.py:611
+#: ../src/jarabe/frame/activitiestray.py:740
msgid "Dismiss"
msgstr "Verwerfen"
-#: ../src/jarabe/frame/activitiestray.py:669
+#: ../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:223
+#: ../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:93
+#: ../src/jarabe/intro/window.py:96
msgid "Name:"
msgstr "Name:"
-#: ../src/jarabe/intro/window.py:128
+#: ../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/listmodel.py:153
-#: ../src/jarabe/journal/listmodel.py:161
+#: ../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:286 ../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:293
+#: ../src/jarabe/journal/expandedentry.py:299
msgid "Participants:"
msgstr "Teilnehmer:"
-#: ../src/jarabe/journal/expandedentry.py:316
+#: ../src/jarabe/journal/expandedentry.py:321
msgid "Description:"
msgstr "Beschreibung:"
-#: ../src/jarabe/journal/expandedentry.py:341
+#: ../src/jarabe/journal/expandedentry.py:346
msgid "Tags:"
msgstr "Stichwörter:"
-#: ../src/jarabe/journal/journalactivity.py:110
-#: ../src/jarabe/journal/journaltoolbox.py:466
-#: ../src/jarabe/journal/volumestoolbar.py:51
+#: ../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:68
+#: ../src/jarabe/journal/journaltoolbox.py:69
msgid "Search"
msgstr "Suchen"
-#: ../src/jarabe/journal/journaltoolbox.py:137
+#: ../src/jarabe/journal/journaltoolbox.py:136
msgid "Anytime"
msgstr "Beliebiges Datum"
-#: ../src/jarabe/journal/journaltoolbox.py:139
+#: ../src/jarabe/journal/journaltoolbox.py:138
msgid "Today"
msgstr "Heute"
-#: ../src/jarabe/journal/journaltoolbox.py:141
+#: ../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:143
+#: ../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:145
+#: ../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:147
+#: ../src/jarabe/journal/journaltoolbox.py:146
msgid "Past year"
msgstr "Vergangenes Jahr"
-#: ../src/jarabe/journal/journaltoolbox.py:154
+#: ../src/jarabe/journal/journaltoolbox.py:153
msgid "Anyone"
msgstr "Alle"
-#: ../src/jarabe/journal/journaltoolbox.py:156
+#: ../src/jarabe/journal/journaltoolbox.py:155
msgid "My friends"
msgstr "Meine Freunde"
-#: ../src/jarabe/journal/journaltoolbox.py:157
+#: ../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:310
+#: ../src/jarabe/journal/journaltoolbox.py:298
msgid "Anything"
msgstr "Alles"
# TODO: Add "Start with" menu item
-#: ../src/jarabe/journal/journaltoolbox.py:391
-#: ../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:446
-#: ../src/jarabe/journal/volumestoolbar.py:158
+#: ../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:455
-#: ../src/jarabe/journal/volumestoolbar.py:167
+#: ../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:456
-#: ../src/jarabe/journal/volumestoolbar.py:168
+#: ../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:498
+#: ../src/jarabe/journal/journaltoolbox.py:488
#: ../src/jarabe/journal/palettes.py:69
msgid "Start"
msgstr "Start"
-#: ../src/jarabe/journal/journaltoolbox.py:526
+#: ../src/jarabe/journal/journaltoolbox.py:516
msgid "Sort by date modified"
msgstr "Nach Änderungsdatum sortieren"
-#: ../src/jarabe/journal/journaltoolbox.py:527
+#: ../src/jarabe/journal/journaltoolbox.py:517
msgid "Sort by date created"
msgstr "Nach Erstellungsdatum sortieren"
-#: ../src/jarabe/journal/journaltoolbox.py:528
+#: ../src/jarabe/journal/journaltoolbox.py:518
msgid "Sort by size"
msgstr "Nach Größe sortieren"
-#: ../src/jarabe/journal/journaltoolbox.py:537
+#: ../src/jarabe/journal/journaltoolbox.py:527
msgid "Sort view"
msgstr "Ansicht sortieren"
-#: ../src/jarabe/journal/listview.py:378
+#: ../src/jarabe/journal/listview.py:380
msgid "Your Journal is empty"
msgstr "Dein Tagebuch ist leer."
-#: ../src/jarabe/journal/listview.py:380
+#: ../src/jarabe/journal/listview.py:382
msgid "No matching entries"
msgstr "Keine passenden Einträge"
-#: ../src/jarabe/journal/listview.py:391
+#: ../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"
@@ -1459,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"
@@ -1471,66 +1515,66 @@ 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:174
+#: ../src/jarabe/journal/palettes.py:181
msgid "No friends present"
msgstr "Keine Freunde anwesend"
-#: ../src/jarabe/journal/palettes.py:179
+#: ../src/jarabe/journal/palettes.py:186
msgid "No valid connection found"
msgstr "Keine gültige Verbindung gefunden"
-#: ../src/jarabe/journal/palettes.py:207
+#: ../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:209
-msgid "No activity to start entry"
-msgstr "Keine Aktivität, um den Eintrag zu beginnen"
-
-#: ../src/jarabe/model/network.py:156
-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: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:160
+#: ../src/jarabe/model/network.py:162
msgid "The device is now managed."
msgstr "Das Gerät wird nun verwaltet."
-#: ../src/jarabe/model/network.py:162
+#: ../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:164
+#: ../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:166
+#: ../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:169
+#: ../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:171
+#: ../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:173
+#: ../src/jarabe/model/network.py:175
msgid ""
"The 802.1X supplicant disconnected from the access point or authentication "
"server."
@@ -1538,156 +1582,160 @@ msgstr ""
"Der 802.1X-Supplikant wurde vom Zugangspunkt oder Authentifizierungsserver "
"getrennt."
-#: ../src/jarabe/model/network.py:176
+#: ../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:178
+#: ../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:180
+#: ../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:182
+#: ../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:184
+#: ../src/jarabe/model/network.py:186
msgid "The PPP service disconnected unexpectedly."
msgstr "Der PPP-Dienst wurde unerwartet getrennt."
-#: ../src/jarabe/model/network.py:186
+#: ../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:188
+#: ../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:190
+#: ../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:192
+#: ../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:194
+#: ../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:196
+#: ../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/model/network.py:199
+#: ../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:201
+#: ../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:203
+#: ../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:205
+#: ../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:207
+#: ../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:209
+#: ../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:211
+#: ../src/jarabe/model/network.py:213
msgid "Dialing timed out."
msgstr "Zeitüberschreitung bei der Einwahl."
-#: ../src/jarabe/model/network.py:213
+#: ../src/jarabe/model/network.py:215
msgid "Dialing failed."
msgstr "Einwahl fehlgeschlagen."
-#: ../src/jarabe/model/network.py:215
+#: ../src/jarabe/model/network.py:217
msgid "Modem initialization failed."
msgstr "Initialisierung des Modems fehlgeschlagen."
-#: ../src/jarabe/model/network.py:217
-msgid "Failed to select the specified GSM APN."
-msgstr "Konnte den angegebenen GSM-Zugangspunkt nicht anwählen."
-
#: ../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:221
+#: ../src/jarabe/model/network.py:223
msgid "Network registration was denied."
msgstr "Die Netzwerkregistrierung wurde verweigert."
-#: ../src/jarabe/model/network.py:223
+#: ../src/jarabe/model/network.py:225
msgid "Network registration timed out."
msgstr "Zeitüberschreitung bei der Netzwerkregistrierung."
-#: ../src/jarabe/model/network.py:225
+#: ../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:227
+#: ../src/jarabe/model/network.py:229
msgid "PIN check failed."
msgstr "PIN-Überprüfung fehlgeschlagen."
-#: ../src/jarabe/model/network.py:229
+#: ../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:231
+#: ../src/jarabe/model/network.py:233
msgid "The device was removed."
msgstr "Das Gerät wurde entfernt."
-#: ../src/jarabe/model/network.py:233
+#: ../src/jarabe/model/network.py:235
msgid "NetworkManager went to sleep."
msgstr "Der Netzwerk-Manager ist nun im Ruhezustand."
-#: ../src/jarabe/model/network.py:235
+#: ../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:238
+#: ../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:240
+#: ../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:62
+#: ../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:91
+msgid "Restart"
+msgstr "Rechner neu starten"
-#: ../src/jarabe/view/buddymenu.py:90
+#: ../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"
@@ -1697,52 +1745,52 @@ msgstr "Einladen zu %s"
msgid "<b>%s</b> failed to start."
msgstr "<b>%s</b> konnte nicht gestartet werden."
-#: ../src/jarabe/view/palettes.py:47
+#: ../src/jarabe/view/palettes.py:46
msgid "Starting..."
msgstr "Starte..."
-#: ../src/jarabe/view/palettes.py:57
+#: ../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:86
+#: ../src/jarabe/view/palettes.py:85
msgid "View Source"
-msgstr "Quelltext betrachten"
+msgstr "Quelltext anzeigen"
-#: ../src/jarabe/view/palettes.py:97
+#: ../src/jarabe/view/palettes.py:96
msgid "Stop"
msgstr "Beenden"
-#: ../src/jarabe/view/palettes.py:137
+#: ../src/jarabe/view/palettes.py:132
msgid "Start new"
msgstr "Neu beginnen"
-#: ../src/jarabe/view/palettes.py:176
+#: ../src/jarabe/view/palettes.py:172
msgid "Show contents"
msgstr "Inhalte anzeigen"
-#: ../src/jarabe/view/palettes.py:198 ../src/jarabe/view/palettes.py:248
+#: ../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"
@@ -1786,9 +1834,6 @@ msgstr "Sugar in einem Fenster"
#~ 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 fdc1e45..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,8 @@ _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):
@@ -116,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)
@@ -149,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):
@@ -226,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',
@@ -316,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')
@@ -334,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:
@@ -346,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:
@@ -400,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)
@@ -521,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):
@@ -598,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:
@@ -632,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 07e834f..2ab5de2 100644
--- a/src/jarabe/frame/activitiestray.py
+++ b/src/jarabe/frame/activitiestray.py
@@ -115,7 +115,6 @@ class ActivityButton(RadioToolButton):
self._icon.props.icon_name = None
self._icon.props.file = util.TempFilePath(path)
-
class InviteButton(ToolButton):
"""Invite to shared activity"""
def __init__(self, invite):
@@ -226,7 +225,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',
@@ -334,6 +334,7 @@ class ActivitiesTray(HTray):
self.add_item(button)
button.show()
+
class BaseTransferButton(ToolButton):
"""Button with a notification attached
"""
@@ -370,6 +371,7 @@ class BaseTransferButton(ToolButton):
filetransfer.FT_REASON_LOCAL_STOPPED:
self.remove()
+
class IncomingTransferButton(BaseTransferButton):
"""UI element representing an ongoing incoming file transfer
"""
@@ -450,6 +452,7 @@ class IncomingTransferButton(BaseTransferButton):
def __dismiss_clicked_cb(self, palette):
self.remove()
+
class OutgoingTransferButton(BaseTransferButton):
"""UI element representing an ongoing outgoing file transfer
"""
@@ -467,7 +470,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
@@ -485,14 +488,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):
@@ -547,10 +550,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)
@@ -673,10 +678,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 32a2847..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,6 +230,19 @@ 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 or not activity_id:
@@ -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 16e6c4b..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'
@@ -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 91dd059..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,30 +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])),
- '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):
@@ -203,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)
@@ -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)
@@ -573,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)
@@ -609,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):
@@ -635,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)
@@ -732,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 = {
@@ -764,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):
@@ -774,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,
@@ -830,8 +843,8 @@ class Neighborhood(gobject.GObject):
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]
@@ -917,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]
@@ -987,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 a7eef8c..504c723 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,6 +481,7 @@ class SettingsGsm(object):
return settings
+
class SecretsGsm(object):
def __init__(self):
self.password = None
@@ -482,6 +498,7 @@ class SecretsGsm(object):
secrets['puk'] = self.puk
return {'gsm': secrets}
+
class NMSettings(dbus.service.Object):
def __init__(self):
bus = dbus.SystemBus()
@@ -509,15 +526,19 @@ class NMSettings(dbus.service.Object):
self.secrets_request.send(self, connection=sender,
response=kwargs['response'])
- def clear_connections(self):
- for connection in self.connections.values():
- connection.Removed()
- self.connections = {}
+ 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
@@ -530,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()
@@ -555,13 +577,13 @@ class NMSettingsConnection(dbus.service.Object):
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.Updated(self._settings.get_dict())
- 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
@@ -571,10 +593,12 @@ 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 set_disconnected(self):
- if self._settings.connection.autoconnect:
+ 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())
@@ -582,15 +606,15 @@ class NMSettingsConnection(dbus.service.Object):
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:
@@ -658,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):
@@ -695,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)
@@ -741,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):
@@ -780,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:
@@ -794,6 +822,7 @@ def get_settings():
return None
return _nm_settings
+
def find_connection_by_ssid(ssid):
settings = get_settings()
if settings is None:
@@ -803,12 +832,14 @@ def find_connection_by_ssid(ssid):
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
@@ -819,19 +850,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')
@@ -936,12 +974,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():
settings = get_settings()
if settings is None:
@@ -955,3 +995,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 e7b70cd..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
@@ -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 4ec3203..8201295 100644
--- a/src/jarabe/util/emulator.py
+++ b/src/jarabe/util/emulator.py
@@ -84,7 +84,7 @@ def _run_server(display, dpi, dimensions, fullscreen):
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):
dimensions = '%dx%d' % screen_size
elif fullscreen:
dimensions = '%dx%d' % screen_size
@@ -191,6 +191,7 @@ def _start_window_manager():
pipe_ = subprocess.Popen(command)
+
def _setup_env(display, scaling, emulator_pid):
"""Set up environment variables for running Sugar inside the new X server.
"""
@@ -216,7 +217,7 @@ def _setup_env(display, scaling, emulator_pid):
def _parse_args():
"""Parse command line arguments."""
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)
-