Web   ·   Wiki   ·   Activities   ·   Blog   ·   Lists   ·   Chat   ·   Meeting   ·   Bugs   ·   Git   ·   Translate   ·   Archive   ·   People   ·   Donate
summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--NEWS9
-rw-r--r--bin/Makefile.am4
-rwxr-xr-xbin/sugar-control-panel (renamed from shell/controlpanel/sugar-control)11
-rwxr-xr-xbin/sugar-shell (renamed from shell/sugar-shell)0
-rw-r--r--configure.ac1
-rw-r--r--lib/sugar/activity/activity.py2
-rw-r--r--lib/sugar/activity/activityfactory.py9
-rw-r--r--po/POTFILES.in4
-rw-r--r--po/sugar.pot376
-rw-r--r--services/shell/objecttypeservice.py125
-rw-r--r--shell/Makefile.am4
-rw-r--r--shell/controlpanel/Makefile.am4
-rw-r--r--shell/controlpanel/__init__.py16
-rw-r--r--shell/controlpanel/control.py120
-rw-r--r--shell/hardware/keydialog.py135
-rw-r--r--shell/view/Shell.py5
-rw-r--r--shell/view/keyhandler.py22
17 files changed, 608 insertions, 239 deletions
diff --git a/NEWS b/NEWS
index a1e802e..f147a8a 100644
--- a/NEWS
+++ b/NEWS
@@ -1,4 +1,13 @@
* #4518: Encode nickname in UTF-8 when writing it out to .sugar/*/config (smcv)
+* sugar-control: Use NM for radio on/off, check for superuser (erikos)
+
+Snapshot b72f00e30b
+
+* #4517 Do not require a TakeScreenshot method on the dbus service (marco)
+* Add wep type combo. (dcbw)
+
+Snapshot 8c89bfaed7
+
* #4503: Do some standard Tubes boilerplate in sugar.presence, so activities
don't have to (smcv)
* #4428 Revert to the trial-3 frame behavior (marco)
diff --git a/bin/Makefile.am b/bin/Makefile.am
index fd72139..327df30 100644
--- a/bin/Makefile.am
+++ b/bin/Makefile.am
@@ -2,8 +2,10 @@ bin_SCRIPTS = \
sugar \
sugar-activity \
sugar-backup \
+ sugar-control-panel \
sugar-install-bundle \
- sugar-launch
+ sugar-launch \
+ sugar-shell
EXTRA_DIST = $(bin_SCRIPTS) sugar.in
diff --git a/shell/controlpanel/sugar-control b/bin/sugar-control-panel
index 4bee092..367372d 100755
--- a/shell/controlpanel/sugar-control
+++ b/bin/sugar-control-panel
@@ -17,9 +17,14 @@
# Free Software Foundation, Inc., 59 Temple Place - Suite 330,
# Boston, MA 02111-1307, USA.
-import getopt, sys
-
-import control
+import sys
+import getopt
+
+from sugar import env
+
+sys.path.insert(0, env.get_shell_path())
+
+from controlpanel import control
def cmd_help():
print 'Usage: sugar-control [ option ] key [ args ... ] \n\
diff --git a/shell/sugar-shell b/bin/sugar-shell
index 8f78289..8f78289 100755
--- a/shell/sugar-shell
+++ b/bin/sugar-shell
diff --git a/configure.ac b/configure.ac
index 7844455..01c5645 100644
--- a/configure.ac
+++ b/configure.ac
@@ -56,6 +56,7 @@ lib/sugar/datastore/Makefile
services/Makefile
services/shell/Makefile
shell/Makefile
+shell/controlpanel/Makefile
shell/intro/Makefile
shell/hardware/Makefile
shell/view/Makefile
diff --git a/lib/sugar/activity/activity.py b/lib/sugar/activity/activity.py
index 14cadd7..55000f3 100644
--- a/lib/sugar/activity/activity.py
+++ b/lib/sugar/activity/activity.py
@@ -683,7 +683,7 @@ class Activity(Window, gtk.Container):
if self._jobject.file_path:
self.write_file(self._jobject.file_path)
else:
- file_path = os.path.join(self.get_activity_root(), 'tmp',
+ file_path = os.path.join(self.get_activity_root(), 'data',
'%i' % time.time())
self.write_file(file_path)
self._owns_file = True
diff --git a/lib/sugar/activity/activityfactory.py b/lib/sugar/activity/activityfactory.py
index 39ebebc..cd75edd 100644
--- a/lib/sugar/activity/activityfactory.py
+++ b/lib/sugar/activity/activityfactory.py
@@ -79,7 +79,16 @@ def get_environment(activity):
environ = os.environ.copy()
bin_path = os.path.join(activity.path, 'bin')
+
activity_root = env.get_profile_path(activity.bundle_id)
+ if not os.path.exists(activity_root):
+ os.mkdir(activity_root)
+
+ data_dir = os.path.join(activity_root, 'data')
+ os.mkdir(data_dir)
+
+ tmp_dir = os.path.join(activity_root, 'tmp')
+ os.mkdir(tmp_dir)
environ['SUGAR_BUNDLE_PATH'] = activity.path
environ['SUGAR_ACTIVITY_ROOT'] = activity_root
diff --git a/po/POTFILES.in b/po/POTFILES.in
index c71aa55..aafd1e8 100644
--- a/po/POTFILES.in
+++ b/po/POTFILES.in
@@ -12,3 +12,7 @@ shell/view/devices/network/wireless.py
shell/view/frame/activitybutton.py
shell/view/frame/zoomtoolbar.py
lib/sugar/activity/activity.py
+lib/sugar/graphics/alert.py
+lib/sugar/graphics/objectchooser.py
+shell/controlpanel/control.py
+shell/view/devices/network/mesh.py
diff --git a/po/sugar.pot b/po/sugar.pot
new file mode 100644
index 0000000..3cd5557
--- /dev/null
+++ b/po/sugar.pot
@@ -0,0 +1,376 @@
+# 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.
+#
+#, fuzzy
+msgid ""
+msgstr ""
+"Project-Id-Version: PACKAGE VERSION\n"
+"Report-Msgid-Bugs-To: \n"
+"POT-Creation-Date: 2007-10-30 23:51+0100\n"
+"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
+"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
+"Language-Team: LANGUAGE <LL@li.org>\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=CHARSET\n"
+"Content-Transfer-Encoding: 8bit\n"
+
+#: ../shell/intro/intro.py:67
+msgid "Name:"
+msgstr ""
+
+#: ../shell/intro/intro.py:96
+msgid "Click to change color:"
+msgstr ""
+
+#: ../shell/intro/intro.py:146
+msgid "Back"
+msgstr ""
+
+#: ../shell/intro/intro.py:160
+msgid "Done"
+msgstr ""
+
+#: ../shell/intro/intro.py:163
+msgid "Next"
+msgstr ""
+
+#: ../shell/view/BuddyMenu.py:83
+msgid "Remove friend"
+msgstr ""
+
+#: ../shell/view/BuddyMenu.py:86
+msgid "Make friend"
+msgstr ""
+
+#: ../shell/view/BuddyMenu.py:92
+msgid "Invite"
+msgstr ""
+
+#: ../shell/view/clipboardmenu.py:59 ../shell/view/frame/activitybutton.py:58
+msgid "Remove"
+msgstr ""
+
+#: ../shell/view/clipboardmenu.py:64
+msgid "Open"
+msgstr ""
+
+#. self._stop_item = MenuItem(_('Stop download'), 'stock-close')
+#. TODO: Implement stopping downloads
+#. self._stop_item.connect('activate', self._stop_item_activate_cb)
+#. self.append_menu_item(self._stop_item)
+#: ../shell/view/clipboardmenu.py:74
+msgid "Add to journal"
+msgstr ""
+
+#: ../shell/view/clipboardmenu.py:200
+#, python-format
+msgid "Clipboard object: %s."
+msgstr ""
+
+#: ../shell/hardware/keydialog.py:149
+msgid "Key Type:"
+msgstr ""
+
+#: ../shell/hardware/keydialog.py:169
+msgid "Authentication Type:"
+msgstr ""
+
+#: ../shell/hardware/keydialog.py:250
+msgid "Encryption Type:"
+msgstr ""
+
+#: ../shell/view/home/activitiesdonut.py:90
+msgid "Starting..."
+msgstr ""
+
+#: ../shell/view/home/activitiesdonut.py:104
+msgid "Resume"
+msgstr ""
+
+#: ../shell/view/home/activitiesdonut.py:111
+#: ../lib/sugar/activity/activity.py:124
+msgid "Stop"
+msgstr ""
+
+#: ../shell/view/Shell.py:267
+msgid "Screenshot"
+msgstr ""
+
+#: ../shell/view/home/HomeBox.py:157
+msgid "Reboot"
+msgstr ""
+
+#: ../shell/view/home/HomeBox.py:162
+msgid "Shutdown"
+msgstr ""
+
+#: ../shell/view/home/HomeBox.py:168
+msgid "Register"
+msgstr ""
+
+#. Only show disconnect when there's a mesh device, because mesh takes
+#. priority over the normal wireless device. NM doesn't have a "disconnect"
+#. method for a device either (for various reasons) so this doesn't
+#. have a good mapping
+#: ../shell/view/home/MeshBox.py:87 ../shell/view/home/MeshBox.py:186
+#: ../shell/view/devices/network/wireless.py:113
+#: ../shell/view/devices/network/mesh.py:83
+msgid "Disconnect..."
+msgstr ""
+
+#: ../shell/view/home/MeshBox.py:184 ../shell/view/devices/network/mesh.py:37
+#: ../shell/view/devices/network/mesh.py:62
+#: ../shell/view/devices/network/mesh.py:66
+msgid "Mesh Network"
+msgstr ""
+
+#: ../shell/view/devices/battery.py:38
+msgid "My Battery life"
+msgstr ""
+
+#: ../shell/view/devices/battery.py:94
+msgid "Battery charging"
+msgstr ""
+
+#: ../shell/view/devices/battery.py:96
+msgid "Battery discharging"
+msgstr ""
+
+#: ../shell/view/devices/battery.py:98
+msgid "Battery fully charged"
+msgstr ""
+
+#: ../shell/view/devices/network/wireless.py:61
+msgid "Disconnected"
+msgstr ""
+
+#: ../shell/view/devices/network/wireless.py:131
+msgid "Channel"
+msgstr ""
+
+#: ../shell/view/frame/zoomtoolbar.py:42
+msgid "Neighborhood"
+msgstr ""
+
+#: ../shell/view/frame/zoomtoolbar.py:54
+msgid "Group"
+msgstr ""
+
+#: ../shell/view/frame/zoomtoolbar.py:66
+msgid "Home"
+msgstr ""
+
+#: ../shell/view/frame/zoomtoolbar.py:78
+msgid "Activity"
+msgstr ""
+
+#: ../lib/sugar/activity/activity.py:107
+msgid "Share with:"
+msgstr ""
+
+#: ../lib/sugar/activity/activity.py:109
+msgid "Private"
+msgstr ""
+
+#: ../lib/sugar/activity/activity.py:110
+msgid "My Neighborhood"
+msgstr ""
+
+#: ../lib/sugar/activity/activity.py:118
+msgid "Keep"
+msgstr ""
+
+#: ../lib/sugar/activity/activity.py:237
+msgid "Undo"
+msgstr ""
+
+#: ../lib/sugar/activity/activity.py:242
+msgid "Redo"
+msgstr ""
+
+#: ../lib/sugar/activity/activity.py:252
+msgid "Copy"
+msgstr ""
+
+#: ../lib/sugar/activity/activity.py:257
+msgid "Paste"
+msgstr ""
+
+#: ../lib/sugar/activity/activity.py:445
+#, python-format
+msgid "%s Activity"
+msgstr ""
+
+#: ../lib/sugar/graphics/alert.py:164 ../lib/sugar/graphics/alert.py:206
+msgid "Cancel"
+msgstr ""
+
+#: ../lib/sugar/graphics/alert.py:168
+msgid "Ok"
+msgstr ""
+
+#: ../lib/sugar/graphics/alert.py:216
+msgid "Continue"
+msgstr ""
+
+#: ../lib/sugar/graphics/alert.py:244
+msgid "OK"
+msgstr ""
+
+#: ../lib/sugar/graphics/objectchooser.py:175
+#, python-format
+msgid "%d year"
+msgstr ""
+
+#: ../lib/sugar/graphics/objectchooser.py:175
+#, python-format
+msgid "%d years"
+msgstr ""
+
+#: ../lib/sugar/graphics/objectchooser.py:176
+#, python-format
+msgid "%d month"
+msgstr ""
+
+#: ../lib/sugar/graphics/objectchooser.py:176
+#, python-format
+msgid "%d months"
+msgstr ""
+
+#: ../lib/sugar/graphics/objectchooser.py:177
+#, python-format
+msgid "%d week"
+msgstr ""
+
+#: ../lib/sugar/graphics/objectchooser.py:177
+#, python-format
+msgid "%d weeks"
+msgstr ""
+
+#: ../lib/sugar/graphics/objectchooser.py:178
+#, python-format
+msgid "%d day"
+msgstr ""
+
+#: ../lib/sugar/graphics/objectchooser.py:178
+#, python-format
+msgid "%d days"
+msgstr ""
+
+#: ../lib/sugar/graphics/objectchooser.py:179
+#, python-format
+msgid "%d hour"
+msgstr ""
+
+#: ../lib/sugar/graphics/objectchooser.py:179
+#, python-format
+msgid "%d hours"
+msgstr ""
+
+#: ../lib/sugar/graphics/objectchooser.py:180
+#, python-format
+msgid "%d minute"
+msgstr ""
+
+#: ../lib/sugar/graphics/objectchooser.py:180
+#, python-format
+msgid "%d minutes"
+msgstr ""
+
+#: ../lib/sugar/graphics/objectchooser.py:181
+#, python-format
+msgid "%d second"
+msgstr ""
+
+#: ../lib/sugar/graphics/objectchooser.py:181
+#, python-format
+msgid "%d seconds"
+msgstr ""
+
+#: ../lib/sugar/graphics/objectchooser.py:191
+msgid " and "
+msgstr ""
+
+#: ../lib/sugar/graphics/objectchooser.py:193
+msgid ", "
+msgstr ""
+
+#: ../shell/controlpanel/control.py:254
+msgid "Error in specified color modifiers."
+msgstr ""
+
+#: ../shell/controlpanel/control.py:257
+msgid "Error in specified colors."
+msgstr ""
+
+#: ../shell/controlpanel/control.py:306
+msgid "Error in specified radio argument use on/off."
+msgstr ""
+
+#: ../shell/controlpanel/control.py:323 ../shell/controlpanel/control.py:325
+#, python-format
+msgid "get_timezone: %s"
+msgstr ""
+
+#: ../shell/controlpanel/control.py:331
+msgid "Error in reading timezone"
+msgstr ""
+
+#: ../shell/controlpanel/control.py:344
+#, python-format
+msgid "Error copying timezone (from %s): %s"
+msgstr ""
+
+#: ../shell/controlpanel/control.py:349
+#, python-format
+msgid "Changing permission of timezone: %s"
+msgstr ""
+
+#: ../shell/controlpanel/control.py:360
+msgid "Error timezone does not exist."
+msgstr ""
+
+#: ../shell/controlpanel/control.py:379
+#, python-format
+msgid "Could not access %s"
+msgstr ""
+
+#: ../shell/controlpanel/control.py:415
+#, python-format
+msgid "Language for code=%s could not be determined."
+msgstr ""
+
+#: ../shell/controlpanel/control.py:424
+#, python-format
+msgid "Sorry I do not speak '%s'."
+msgstr ""
+
+#: ../shell/view/devices/network/mesh.py:105
+msgid "Connected to a School Mesh Portal"
+msgstr ""
+
+#: ../shell/view/devices/network/mesh.py:107
+msgid "Looking for a School Mesh Portal..."
+msgstr ""
+
+#: ../shell/view/devices/network/mesh.py:110
+msgid "Connected to an XO Mesh Portal"
+msgstr ""
+
+#: ../shell/view/devices/network/mesh.py:112
+msgid "Looking for an XO Mesh Portal..."
+msgstr ""
+
+#: ../shell/view/devices/network/mesh.py:115
+msgid "Connected to a Simple Mesh"
+msgstr ""
+
+#: ../shell/view/devices/network/mesh.py:117
+msgid "Starting a Simple Mesh"
+msgstr ""
+
+#: ../shell/view/devices/network/mesh.py:124
+msgid "Unknown Mesh"
+msgstr ""
diff --git a/services/shell/objecttypeservice.py b/services/shell/objecttypeservice.py
deleted file mode 100644
index c4910f7..0000000
--- a/services/shell/objecttypeservice.py
+++ /dev/null
@@ -1,125 +0,0 @@
-# Copyright (C) 2007, Red Hat, Inc.
-#
-# This program is free software; you can redistribute it and/or modify
-# it under the terms of the GNU General Public License as published by
-# the Free Software Foundation; either version 2 of the License, or
-# (at your option) any later version.
-#
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-# GNU General Public License for more details.
-#
-# You should have received a copy of the GNU General Public License
-# along with this program; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
-
-import dbus
-import dbus.service
-import gnomevfs
-import gtk
-
-from gettext import gettext as _
-
-import bundleregistry
-
-_REGISTRY_IFACE = "org.laptop.ObjectTypeRegistry"
-_REGISTRY_PATH = "/org/laptop/ObjectTypeRegistry"
-
-class ObjectTypeRegistry(dbus.service.Object):
- def __init__(self):
- bus = dbus.SessionBus()
- bus_name = dbus.service.BusName(_REGISTRY_IFACE, bus=bus)
- dbus.service.Object.__init__(self, bus_name, _REGISTRY_PATH)
-
- self._types = {}
-
- self._add_primitive('Text', _('Text'), 'text-x-generic',
- ['text/plain', 'text/rtf', 'application/pdf',
- 'application/x-pdf', 'text/html',
- 'application/vnd.oasis.opendocument.text',
- 'application/rtf', 'text/rtf'])
-
- self._add_primitive('Image', _('Image'), 'image-x-generic',
- ['image/png', 'image/gif', 'image/jpeg'])
-
- self._add_primitive('Audio', _('Audio'), 'audio-x-generic',
- ['audio/ogg', 'audio/x-wav', 'audio/wav'])
-
- self._add_primitive('Video', _('Video'), 'video-x-generic',
- ['video/ogg', 'application/ogg'])
-
- self._add_primitive('Etoys project', _('Etoys project'),
- 'application-x-squeak-project',
- ['application/x-squeak-project'])
-
- self._add_primitive('Link', _('Link'),
- 'text-uri-list',
- ['text/x-moz-url', 'text/uri-list'])
-
- self._activity_registry = bundleregistry.get_registry()
- for bundle in self._activity_registry:
- self._add_activity(self._activity_registry, bundle)
- self._activity_registry.connect('bundle-added', self._add_activity)
-
- def _add_primitive(self, type_id, name, icon, mime_types):
- object_type = {'type_id': type_id,
- 'name': name,
- 'icon': icon,
- 'mime_types': mime_types}
- self._types[type_id] = object_type
-
- def _add_activity(self, activity_registry, bundle):
- mime_types = bundle.get_mime_types()
- if mime_types is None:
- return
-
- icon_theme = gtk.icon_theme_get_default()
- for mime_type in mime_types:
- if self._get_type_for_mime(mime_type) is not None:
- continue
-
- name = gnomevfs.mime_get_description(mime_type)
- if name is None:
- continue
-
- icon = mime_type.replace('/', '-')
- if icon_theme.lookup_icon(icon, gtk.ICON_SIZE_BUTTON, 0) is None:
- continue
-
- object_type = {'type_id': mime_type,
- 'name': name,
- 'icon': icon,
- 'mime_types': [mime_type]}
- self._types[mime_type] = object_type
-
- def _get_type_for_mime(self, mime_type):
- for object_type in self._types.values():
- if mime_type in object_type['mime_types']:
- return object_type
- return None
-
- @dbus.service.method(_REGISTRY_IFACE,
- in_signature="s", out_signature="a{sv}")
- def GetType(self, type_id):
- if self._types.has_key(type_id):
- return self._types[type_id]
- else:
- return {}
-
- @dbus.service.method(_REGISTRY_IFACE,
- in_signature="s", out_signature="a{sv}")
- def GetTypeForMIME(self, mime_type):
- object_type = self._get_type_for_mime(mime_type)
- if object_type:
- return object_type
- else:
- return {}
-
-_instance = None
-
-def get_instance():
- global _instance
- if not _instance:
- _instance = ObjectTypeRegistry()
- return _instance
diff --git a/shell/Makefile.am b/shell/Makefile.am
index 56649be..4c9eac9 100644
--- a/shell/Makefile.am
+++ b/shell/Makefile.am
@@ -1,6 +1,4 @@
-SUBDIRS = hardware model view intro
-
-bin_SCRIPTS = sugar-shell
+SUBDIRS = controlpanel hardware model view intro
sugardir = $(pkgdatadir)/shell
sugar_PYTHON = \
diff --git a/shell/controlpanel/Makefile.am b/shell/controlpanel/Makefile.am
new file mode 100644
index 0000000..b772170
--- /dev/null
+++ b/shell/controlpanel/Makefile.am
@@ -0,0 +1,4 @@
+sugardir = $(pkgdatadir)/shell/controlpanel
+sugar_PYTHON = \
+ __init__.py \
+ control.py
diff --git a/shell/controlpanel/__init__.py b/shell/controlpanel/__init__.py
new file mode 100644
index 0000000..a9dd95a
--- /dev/null
+++ b/shell/controlpanel/__init__.py
@@ -0,0 +1,16 @@
+# Copyright (C) 2006-2007, Red Hat, Inc.
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+
diff --git a/shell/controlpanel/control.py b/shell/controlpanel/control.py
index 8987051..02ddfe3 100644
--- a/shell/controlpanel/control.py
+++ b/shell/controlpanel/control.py
@@ -27,10 +27,15 @@ import os
import string
import shutil
from gettext import gettext as _
+import dbus
from sugar import profile
from sugar.graphics.xocolor import XoColor
+NM_SERVICE_NAME = 'org.freedesktop.NetworkManager'
+NM_SERVICE_PATH = '/org/freedesktop/NetworkManager'
+NM_SERVICE_IFACE = 'org.freedesktop.NetworkManager'
+NM_ASLEEP = 1
_COLORS = {'red': {'dark':'#b20008', 'medium':'#e6000a', 'light':'#ffadce'},
'orange': {'dark':'#9a5200', 'medium':'#c97e00', 'light':'#ffc169'},
@@ -184,25 +189,16 @@ _LANGUAGES = {
'Zulu/South_Africa': ('zu_ZA.UTF-8', 'latarcyrheb-sun16')
}
-_timezones = []
def _initialize():
- _timezones = _read_zonetab()
+ timezones = _read_zonetab()
+
j=0
- for timezone in _timezones:
+ for timezone in timezones:
set_timezone.__doc__ += timezone+', '
j+=1
if j%3 == 0:
set_timezone.__doc__ += '\n'
-
- if not os.access(_TIMEZONE_CONFIG, os.R_OK):
- #Theres no /etc/sysconfig/clock file, so make one
- fd = open(_TIMEZONE_CONFIG, 'w')
- f.write(' The ZONE parameter is only evaluated by sugarcontrol.\n')
- f.write('The timezone of the system' +
- ' is defined by the contents of /etc/localtime.\n')
- f.write('ZONE="America/NEW_York"\n')
- f.close()
keys = _LANGUAGES.keys()
keys.sort()
@@ -222,7 +218,7 @@ def print_jabber():
def set_jabber(server):
"""Set the jabber server
- server : 'olpc.collabora.co.uk'
+ server : e.g. 'olpc.collabora.co.uk'
"""
pro = profile.get_profile()
pro.jabber_server = server
@@ -243,11 +239,11 @@ def print_color():
print 'fill: color=%s hue=%s'%(color, hue)
def set_color(stroke, fill, modstroke='medium', modfill='medium'):
- """Set the system color.
- fill : 'red, orange, yellow, blue, purple'
- stroke : 'red, orange, yellow, blue, purple'
- modstroke : 'dark, medium, light'
- modfill : ''dark, medium, light'
+ """Set the system color by setting a fill and stroke color.
+ fill : [red, orange, yellow, blue, purple]
+ stroke : [red, orange, yellow, blue, purple]
+ hue stroke : [dark, medium, light] (optional)
+ hue fill : [dark, medium, light] (optional)
"""
if modstroke not in _MODIFIERS or modfill not in _MODIFIERS:
@@ -276,36 +272,56 @@ def print_nick():
def set_nick(nick):
"""Set the nickname.
- nick : 'erikos'
+ nick : e.g. 'walter'
"""
pro = profile.get_profile()
pro.nick_name = nick
pro.save()
-def get_radio(state):
- return ''
+def get_radio():
+ bus = dbus.SystemBus()
+ proxy = bus.get_object(NM_SERVICE_NAME, NM_SERVICE_PATH)
+ nm = dbus.Interface(proxy, NM_SERVICE_IFACE)
+ state = nm.state()
+ if state:
+ if state == NM_ASLEEP:
+ return _('off')
+ else:
+ return _('on')
+ return _('State is unknown.')
-def print_radio(self):
+def print_radio():
print get_radio()
def set_radio(state):
- """Turn Radio off
+ """Turn Radio 'on' or 'off'
state : 'on/off'
"""
+
+ # TODO: NM 0.6.x does not return a reply yet
+ # so we ignore it for the moment
+
if state == 'on':
- cmd = '/sbin/iwconfig eth0 txpower on'
- handle = os.popen(cmd, 'r')
- print string.join(handle.readlines())
- handle.close()
+ dbus.SystemBus().call_async(NM_SERVICE_NAME, NM_SERVICE_PATH,
+ NM_SERVICE_IFACE, 'wake', '', (),
+ None, None)
elif state == 'off':
- cmd = '/sbin/iwconfig eth0 txpower off'
- handle = os.popen(cmd, 'r')
- print string.join(handle.readlines())
- handle.close()
+ dbus.SystemBus().call_async(NM_SERVICE_NAME, NM_SERVICE_PATH,
+ NM_SERVICE_IFACE, 'sleep', '', (),
+ None, None)
else:
print (_("Error in specified radio argument use on/off."))
-
+
+def _check_for_superuser():
+ if os.getuid():
+ print _("Permission denied. You need to be root to run this method.")
+ return False
+ return True
+
def get_timezone():
+ if not os.access(_TIMEZONE_CONFIG, os.R_OK):
+ # this is what the default is for the /etc/localtime
+ return "America/New_York"
fd = open(_TIMEZONE_CONFIG, "r")
lines = fd.readlines()
fd.close()
@@ -331,12 +347,30 @@ def print_timezone():
print (_("Error in reading timezone"))
else:
print timezone
-
+
+def _read_zonetab(fn='/usr/share/zoneinfo/zone.tab'):
+ fd = open (fn, 'r')
+ lines = fd.readlines()
+ fd.close()
+ timezones = []
+ for line in lines:
+ if line.startswith('#'):
+ continue
+ line = line.split()
+ if len(line) > 1:
+ timezones.append(line[2])
+ timezones.sort()
+ return timezones
+
def set_timezone(timezone):
"""Set the system timezone
timezone :
"""
- if timezone in _timezones:
+ if not _check_for_superuser():
+ return
+
+ timezones = _read_zonetab()
+ if timezone in timezones:
fromfile = os.path.join("/usr/share/zoneinfo/", timezone)
try:
shutil.copyfile(fromfile, "/etc/localtime")
@@ -358,20 +392,6 @@ def set_timezone(timezone):
fd.close()
else:
print (_("Error timezone does not exist."))
-
-def _read_zonetab(fn='/usr/share/zoneinfo/zone.tab'):
- fd = open (fn, 'r')
- lines = fd.readlines()
- fd.close()
- timezones = []
- for line in lines:
- if line.startswith('#'):
- continue
- line = line.split()
- if len(line) > 1:
- timezones.append(line[2])
- timezones.sort()
- return timezones
def _writeI18N(lang, sysfont):
path = '/etc/sysconfig/i18n'
@@ -418,11 +438,13 @@ def set_language(language):
"""Set the system language.
languages :
"""
+ if not _check_for_superuser():
+ return
if language in _LANGUAGES:
_writeI18N(_LANGUAGES[language][0], _LANGUAGES[language][1])
else:
print (_("Sorry I do not speak \'%s\'.")%language)
-
# inilialize the docstrings for the timezone and language
_initialize()
+
diff --git a/shell/hardware/keydialog.py b/shell/hardware/keydialog.py
index 6b5976c..d336ab9 100644
--- a/shell/hardware/keydialog.py
+++ b/shell/hardware/keydialog.py
@@ -47,8 +47,8 @@ IW_AUTH_CIPHER_TKIP = 0x00000004
IW_AUTH_CIPHER_CCMP = 0x00000008
IW_AUTH_CIPHER_WEP104 = 0x00000010
-IW_AUTH_KEY_MGMT_802_1X = 0x1
-IW_AUTH_KEY_MGMT_PSK = 0x2
+IW_AUTH_KEY_MGMT_802_1X = 0x1
+IW_AUTH_KEY_MGMT_PSK = 0x2
def string_is_hex(key):
is_hex = True
@@ -95,6 +95,12 @@ class KeyDialog(gtk.Dialog):
" the wireless network '%s'." % net.get_ssid())
self.vbox.pack_start(label)
+ self.add_buttons(gtk.STOCK_CANCEL, gtk.RESPONSE_CANCEL,
+ gtk.STOCK_OK, gtk.RESPONSE_OK)
+ self.set_default_response(gtk.RESPONSE_OK)
+ self.set_has_separator(True)
+
+ def add_key_entry(self):
self._entry = gtk.Entry()
#self._entry.props.visibility = False
self._entry.connect('changed', self._update_response_sensitivity)
@@ -103,14 +109,8 @@ class KeyDialog(gtk.Dialog):
self.vbox.set_spacing(6)
self.vbox.show_all()
- self.add_buttons(gtk.STOCK_CANCEL, gtk.RESPONSE_CANCEL,
- gtk.STOCK_OK, gtk.RESPONSE_OK)
- self.set_default_response(gtk.RESPONSE_OK)
-
self._update_response_sensitivity()
-
self._entry.grab_focus()
- self.set_has_separator(True)
def _entry_activate_cb(self, entry):
self.response(gtk.RESPONSE_OK)
@@ -124,39 +124,70 @@ class KeyDialog(gtk.Dialog):
def get_callbacks(self):
return (self._async_cb, self._async_err_cb)
+WEP_PASSPHRASE = 1
+WEP_HEX = 2
+WEP_ASCII = 3
+
class WEPKeyDialog(KeyDialog):
def __init__(self, net, async_cb, async_err_cb):
KeyDialog.__init__(self, net, async_cb, async_err_cb)
- self.store = gtk.ListStore(str, int)
- self.store.append(["Open System", IW_AUTH_ALG_OPEN_SYSTEM])
- self.store.append(["Shared Key", IW_AUTH_ALG_SHARED_KEY])
+ # 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.combo = gtk.ComboBox(self.store)
+ self.key_combo = gtk.ComboBox(self.key_store)
cell = gtk.CellRendererText()
- self.combo.pack_start(cell, True)
- self.combo.add_attribute(cell, 'text', 0)
- self.combo.set_active(0)
+ self.key_combo.pack_start(cell, True)
+ self.key_combo.add_attribute(cell, 'text', 0)
+ self.key_combo.set_active(0)
+ self.key_combo.connect('changed', self._key_combo_changed_cb)
+
+ hbox = gtk.HBox()
+ hbox.pack_start(gtk.Label(_("Key Type:")))
+ hbox.pack_start(self.key_combo)
+ hbox.show_all()
+ self.vbox.pack_start(hbox)
+
+ # Key entry field
+ self.add_key_entry()
+
+ # WEP authentication mode
+ self.auth_store = gtk.ListStore(str, int)
+ 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()
+ self.auth_combo.pack_start(cell, True)
+ self.auth_combo.add_attribute(cell, 'text', 0)
+ self.auth_combo.set_active(0)
- self.hbox = gtk.HBox()
- self.hbox.pack_start(gtk.Label(_("Authentication Type:")))
- self.hbox.pack_start(self.combo)
- self.hbox.show_all()
+ hbox = gtk.HBox()
+ hbox.pack_start(gtk.Label(_("Authentication Type:")))
+ hbox.pack_start(self.auth_combo)
+ hbox.show_all()
- self.vbox.pack_start(self.hbox)
+ self.vbox.pack_start(hbox)
- def create_security(self):
+ def _key_combo_changed_cb(self, widget):
+ self._update_response_sensitivity()
+
+ def _get_security(self):
key = self._entry.get_text()
- if key.startswith('$:'):
- key = key[2:]
- elif key.startswith('s:') and ((len(key) - 2) in [5, 13]):
- key = string_to_hex(key[2:])
- else:
+ it = self.key_combo.get_active_iter()
+ (key_type, ) = self.key_store.get(it, 1)
+
+ if key_type == WEP_PASSPHRASE:
key = hash_passphrase(key)
+ elif key_type == WEP_ASCII:
+ key = string_to_hex(key)
- it = self.combo.get_active_iter()
- (auth_alg, ) = self.store.get(it, 1)
+ it = self.auth_combo.get_active_iter()
+ (auth_alg, ) = self.auth_store.get(it, 1)
we_cipher = None
if len(key) == 26:
@@ -164,17 +195,43 @@ class WEPKeyDialog(KeyDialog):
elif len(key) == 10:
we_cipher = IW_AUTH_CIPHER_WEP40
+ return (we_cipher, key, auth_alg)
+
+ def print_security(self):
+ (we_cipher, key, auth_alg) = self._get_security()
+ print "Cipher: %d" % we_cipher
+ print "Key: %s" % key
+ print "Auth: %d" % auth_alg
+
+ def create_security(self):
+ (we_cipher, key, auth_alg) = self._get_security()
from nminfo import Security
return Security.new_from_args(we_cipher, (key, auth_alg))
def _update_response_sensitivity(self, ignored=None):
- # As the md5 passphrase can be of any length and has no indicator, we
- # cannot check for the validity of the input.
- self.set_response_sensitive(gtk.RESPONSE_OK, True)
+ key = self._entry.get_text()
+ it = self.key_combo.get_active_iter()
+ (key_type, ) = self.key_store.get(it, 1)
+
+ valid = False
+ if key_type == WEP_PASSPHRASE:
+ # As the md5 passphrase can be of any length and has no indicator,
+ # we cannot check for the validity of the input.
+ if len(key) > 0:
+ valid = True
+ elif key_type == WEP_ASCII:
+ if len(key) == 5 or len(key) == 13:
+ valid = string_is_ascii(key)
+ elif key_type == WEP_HEX:
+ if len(key) == 10 or len(key) == 26:
+ valid = string_is_hex(key)
+
+ self.set_response_sensitive(gtk.RESPONSE_OK, valid)
class WPAKeyDialog(KeyDialog):
def __init__(self, net, async_cb, async_err_cb):
KeyDialog.__init__(self, net, async_cb, async_err_cb)
+ self.add_key_entry()
self.store = gtk.ListStore(str, int)
self.store.append(["Automatic", NM_AUTH_TYPE_WPA_PSK_AUTO])
@@ -196,7 +253,7 @@ class WPAKeyDialog(KeyDialog):
self.vbox.pack_start(self.hbox)
- def create_security(self):
+ def _get_security(self):
ssid = self.get_network().get_ssid()
key = self._entry.get_text()
is_hex = string_is_hex(key)
@@ -229,8 +286,18 @@ class WPAKeyDialog(KeyDialog):
if caps & NM_802_11_CAP_PROTO_WPA2:
wpa_ver = IW_AUTH_WPA_VERSION_WPA2
+ return (we_cipher, real_key, wpa_ver)
+
+ def print_security(self):
+ (we_cipher, key, wpa_ver) = self._get_security()
+ print "Cipher: %d" % we_cipher
+ print "Key: %s" % key
+ print "WPA Ver: %d" % wpa_ver
+
+ def create_security(self):
+ (we_cipher, key, wpa_ver) = self._get_security()
from nminfo import Security
- return Security.new_from_args(we_cipher, (real_key, wpa_ver, IW_AUTH_KEY_MGMT_PSK))
+ return Security.new_from_args(we_cipher, (key, wpa_ver, IW_AUTH_KEY_MGMT_PSK))
def _update_response_sensitivity(self, ignored=None):
key = self._entry.get_text()
@@ -269,7 +336,7 @@ class FakeNet(object):
def response_cb(widget, response_id):
if response_id == gtk.RESPONSE_OK:
- print dialog.get_options()
+ print dialog.print_security()
else:
print "canceled"
widget.hide()
diff --git a/shell/view/Shell.py b/shell/view/Shell.py
index 541fb2e..a700587 100644
--- a/shell/view/Shell.py
+++ b/shell/view/Shell.py
@@ -172,7 +172,10 @@ class Shell(gobject.GObject):
home_model = self._model.get_home()
activity = home_model.get_active_activity()
if activity:
- activity.get_service().TakeScreenshot()
+ try:
+ activity.get_service().TakeScreenshot(timeout=2.0)
+ except dbus.DBusException, e:
+ logging.debug('Error raised by TakeScreenshot(): %s', e)
def set_zoom_level(self, level):
if level == self._zoom_level:
diff --git a/shell/view/keyhandler.py b/shell/view/keyhandler.py
index 768b6c3..26a9fd5 100644
--- a/shell/view/keyhandler.py
+++ b/shell/view/keyhandler.py
@@ -71,8 +71,6 @@ class KeyHandler(object):
self._key_grabber = KeyGrabber()
self._key_grabber.connect('key-pressed',
self._key_pressed_cb)
- self._key_grabber.connect('key-released',
- self._key_released_cb)
for key in _actions_table.keys():
self._key_grabber.grab(key)
@@ -197,23 +195,3 @@ class KeyHandler(object):
return True
return False
-
- def _key_released_cb(self, grabber, keycode, state):
- if self._keycode_pressed == keycode:
- self._keycode_pressed = 0
-
- if self._keystate_pressed == state:
- self._keystate_pressed = 0
-
- if not self._keycode_pressed and not self._keystate_pressed and \
- self._key_pressed:
- gtk.gdk.keyboard_ungrab(time=0L)
-
- if self._key_pressed == '<alt>f':
- self._shell.get_frame().notify_key_release()
- elif self._key_pressed == '0x93':
- self._shell.get_frame().notify_key_release()
-
- return True
-
- return False