Merge branch 'master' of git+ssh://dev.laptop.org/git/sugar

Conflicts:

	NEWS
This commit is contained in:
Simon McVittie 2007-10-31 11:58:44 +00:00
commit b0c7a0546d
17 changed files with 609 additions and 240 deletions

9
NEWS
View File

@ -1,4 +1,13 @@
* #4518: Encode nickname in UTF-8 when writing it out to .sugar/*/config (smcv) * #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 * #4503: Do some standard Tubes boilerplate in sugar.presence, so activities
don't have to (smcv) don't have to (smcv)
* #4428 Revert to the trial-3 frame behavior (marco) * #4428 Revert to the trial-3 frame behavior (marco)

View File

@ -2,8 +2,10 @@ bin_SCRIPTS = \
sugar \ sugar \
sugar-activity \ sugar-activity \
sugar-backup \ sugar-backup \
sugar-control-panel \
sugar-install-bundle \ sugar-install-bundle \
sugar-launch sugar-launch \
sugar-shell
EXTRA_DIST = $(bin_SCRIPTS) sugar.in EXTRA_DIST = $(bin_SCRIPTS) sugar.in

View File

@ -17,9 +17,14 @@
# Free Software Foundation, Inc., 59 Temple Place - Suite 330, # Free Software Foundation, Inc., 59 Temple Place - Suite 330,
# Boston, MA 02111-1307, USA. # Boston, MA 02111-1307, USA.
import getopt, sys import sys
import getopt
import control
from sugar import env
sys.path.insert(0, env.get_shell_path())
from controlpanel import control
def cmd_help(): def cmd_help():
print 'Usage: sugar-control [ option ] key [ args ... ] \n\ print 'Usage: sugar-control [ option ] key [ args ... ] \n\

View File

@ -56,6 +56,7 @@ lib/sugar/datastore/Makefile
services/Makefile services/Makefile
services/shell/Makefile services/shell/Makefile
shell/Makefile shell/Makefile
shell/controlpanel/Makefile
shell/intro/Makefile shell/intro/Makefile
shell/hardware/Makefile shell/hardware/Makefile
shell/view/Makefile shell/view/Makefile

View File

@ -683,7 +683,7 @@ class Activity(Window, gtk.Container):
if self._jobject.file_path: if self._jobject.file_path:
self.write_file(self._jobject.file_path) self.write_file(self._jobject.file_path)
else: else:
file_path = os.path.join(self.get_activity_root(), 'tmp', file_path = os.path.join(self.get_activity_root(), 'data',
'%i' % time.time()) '%i' % time.time())
self.write_file(file_path) self.write_file(file_path)
self._owns_file = True self._owns_file = True

View File

@ -79,7 +79,16 @@ def get_environment(activity):
environ = os.environ.copy() environ = os.environ.copy()
bin_path = os.path.join(activity.path, 'bin') bin_path = os.path.join(activity.path, 'bin')
activity_root = env.get_profile_path(activity.bundle_id) 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_BUNDLE_PATH'] = activity.path
environ['SUGAR_ACTIVITY_ROOT'] = activity_root environ['SUGAR_ACTIVITY_ROOT'] = activity_root

View File

@ -12,3 +12,7 @@ shell/view/devices/network/wireless.py
shell/view/frame/activitybutton.py shell/view/frame/activitybutton.py
shell/view/frame/zoomtoolbar.py shell/view/frame/zoomtoolbar.py
lib/sugar/activity/activity.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

376
po/sugar.pot Normal file
View File

@ -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 ""

View File

@ -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

View File

@ -1,6 +1,4 @@
SUBDIRS = hardware model view intro SUBDIRS = controlpanel hardware model view intro
bin_SCRIPTS = sugar-shell
sugardir = $(pkgdatadir)/shell sugardir = $(pkgdatadir)/shell
sugar_PYTHON = \ sugar_PYTHON = \

View File

@ -0,0 +1,4 @@
sugardir = $(pkgdatadir)/shell/controlpanel
sugar_PYTHON = \
__init__.py \
control.py

View File

@ -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

View File

@ -27,10 +27,15 @@ import os
import string import string
import shutil import shutil
from gettext import gettext as _ from gettext import gettext as _
import dbus
from sugar import profile from sugar import profile
from sugar.graphics.xocolor import XoColor 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'}, _COLORS = {'red': {'dark':'#b20008', 'medium':'#e6000a', 'light':'#ffadce'},
'orange': {'dark':'#9a5200', 'medium':'#c97e00', 'light':'#ffc169'}, 'orange': {'dark':'#9a5200', 'medium':'#c97e00', 'light':'#ffc169'},
@ -184,25 +189,16 @@ _LANGUAGES = {
'Zulu/South_Africa': ('zu_ZA.UTF-8', 'latarcyrheb-sun16') 'Zulu/South_Africa': ('zu_ZA.UTF-8', 'latarcyrheb-sun16')
} }
_timezones = []
def _initialize(): def _initialize():
_timezones = _read_zonetab() timezones = _read_zonetab()
j=0 j=0
for timezone in _timezones: for timezone in timezones:
set_timezone.__doc__ += timezone+', ' set_timezone.__doc__ += timezone+', '
j+=1 j+=1
if j%3 == 0: if j%3 == 0:
set_timezone.__doc__ += '\n' 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 = _LANGUAGES.keys()
keys.sort() keys.sort()
@ -222,7 +218,7 @@ def print_jabber():
def set_jabber(server): def set_jabber(server):
"""Set the jabber server """Set the jabber server
server : 'olpc.collabora.co.uk' server : e.g. 'olpc.collabora.co.uk'
""" """
pro = profile.get_profile() pro = profile.get_profile()
pro.jabber_server = server pro.jabber_server = server
@ -243,11 +239,11 @@ def print_color():
print 'fill: color=%s hue=%s'%(color, hue) print 'fill: color=%s hue=%s'%(color, hue)
def set_color(stroke, fill, modstroke='medium', modfill='medium'): def set_color(stroke, fill, modstroke='medium', modfill='medium'):
"""Set the system color. """Set the system color by setting a fill and stroke color.
fill : 'red, orange, yellow, blue, purple' fill : [red, orange, yellow, blue, purple]
stroke : 'red, orange, yellow, blue, purple' stroke : [red, orange, yellow, blue, purple]
modstroke : 'dark, medium, light' hue stroke : [dark, medium, light] (optional)
modfill : ''dark, medium, light' hue fill : [dark, medium, light] (optional)
""" """
if modstroke not in _MODIFIERS or modfill not in _MODIFIERS: if modstroke not in _MODIFIERS or modfill not in _MODIFIERS:
@ -276,36 +272,56 @@ def print_nick():
def set_nick(nick): def set_nick(nick):
"""Set the nickname. """Set the nickname.
nick : 'erikos' nick : e.g. 'walter'
""" """
pro = profile.get_profile() pro = profile.get_profile()
pro.nick_name = nick pro.nick_name = nick
pro.save() pro.save()
def get_radio(state): def get_radio():
return '' 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() print get_radio()
def set_radio(state): def set_radio(state):
"""Turn Radio off """Turn Radio 'on' or 'off'
state : 'on/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': if state == 'on':
cmd = '/sbin/iwconfig eth0 txpower on' dbus.SystemBus().call_async(NM_SERVICE_NAME, NM_SERVICE_PATH,
handle = os.popen(cmd, 'r') NM_SERVICE_IFACE, 'wake', '', (),
print string.join(handle.readlines()) None, None)
handle.close()
elif state == 'off': elif state == 'off':
cmd = '/sbin/iwconfig eth0 txpower off' dbus.SystemBus().call_async(NM_SERVICE_NAME, NM_SERVICE_PATH,
handle = os.popen(cmd, 'r') NM_SERVICE_IFACE, 'sleep', '', (),
print string.join(handle.readlines()) None, None)
handle.close()
else: else:
print (_("Error in specified radio argument use on/off.")) 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(): 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") fd = open(_TIMEZONE_CONFIG, "r")
lines = fd.readlines() lines = fd.readlines()
fd.close() fd.close()
@ -331,12 +347,30 @@ def print_timezone():
print (_("Error in reading timezone")) print (_("Error in reading timezone"))
else: else:
print timezone 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): def set_timezone(timezone):
"""Set the system timezone """Set the system timezone
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) fromfile = os.path.join("/usr/share/zoneinfo/", timezone)
try: try:
shutil.copyfile(fromfile, "/etc/localtime") shutil.copyfile(fromfile, "/etc/localtime")
@ -358,20 +392,6 @@ def set_timezone(timezone):
fd.close() fd.close()
else: else:
print (_("Error timezone does not exist.")) 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): def _writeI18N(lang, sysfont):
path = '/etc/sysconfig/i18n' path = '/etc/sysconfig/i18n'
@ -418,11 +438,13 @@ def set_language(language):
"""Set the system language. """Set the system language.
languages : languages :
""" """
if not _check_for_superuser():
return
if language in _LANGUAGES: if language in _LANGUAGES:
_writeI18N(_LANGUAGES[language][0], _LANGUAGES[language][1]) _writeI18N(_LANGUAGES[language][0], _LANGUAGES[language][1])
else: else:
print (_("Sorry I do not speak \'%s\'.")%language) print (_("Sorry I do not speak \'%s\'.")%language)
# inilialize the docstrings for the timezone and language # inilialize the docstrings for the timezone and language
_initialize() _initialize()

View File

@ -47,8 +47,8 @@ IW_AUTH_CIPHER_TKIP = 0x00000004
IW_AUTH_CIPHER_CCMP = 0x00000008 IW_AUTH_CIPHER_CCMP = 0x00000008
IW_AUTH_CIPHER_WEP104 = 0x00000010 IW_AUTH_CIPHER_WEP104 = 0x00000010
IW_AUTH_KEY_MGMT_802_1X = 0x1 IW_AUTH_KEY_MGMT_802_1X = 0x1
IW_AUTH_KEY_MGMT_PSK = 0x2 IW_AUTH_KEY_MGMT_PSK = 0x2
def string_is_hex(key): def string_is_hex(key):
is_hex = True is_hex = True
@ -95,6 +95,12 @@ class KeyDialog(gtk.Dialog):
" the wireless network '%s'." % net.get_ssid()) " the wireless network '%s'." % net.get_ssid())
self.vbox.pack_start(label) 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 = gtk.Entry()
#self._entry.props.visibility = False #self._entry.props.visibility = False
self._entry.connect('changed', self._update_response_sensitivity) self._entry.connect('changed', self._update_response_sensitivity)
@ -103,14 +109,8 @@ class KeyDialog(gtk.Dialog):
self.vbox.set_spacing(6) self.vbox.set_spacing(6)
self.vbox.show_all() 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._update_response_sensitivity()
self._entry.grab_focus() self._entry.grab_focus()
self.set_has_separator(True)
def _entry_activate_cb(self, entry): def _entry_activate_cb(self, entry):
self.response(gtk.RESPONSE_OK) self.response(gtk.RESPONSE_OK)
@ -124,39 +124,70 @@ class KeyDialog(gtk.Dialog):
def get_callbacks(self): def get_callbacks(self):
return (self._async_cb, self._async_err_cb) return (self._async_cb, self._async_err_cb)
WEP_PASSPHRASE = 1
WEP_HEX = 2
WEP_ASCII = 3
class WEPKeyDialog(KeyDialog): class WEPKeyDialog(KeyDialog):
def __init__(self, net, async_cb, async_err_cb): def __init__(self, net, async_cb, async_err_cb):
KeyDialog.__init__(self, net, async_cb, async_err_cb) KeyDialog.__init__(self, net, async_cb, async_err_cb)
self.store = gtk.ListStore(str, int) # WEP key type
self.store.append(["Open System", IW_AUTH_ALG_OPEN_SYSTEM]) self.key_store = gtk.ListStore(str, int)
self.store.append(["Shared Key", IW_AUTH_ALG_SHARED_KEY]) 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() cell = gtk.CellRendererText()
self.combo.pack_start(cell, True) self.key_combo.pack_start(cell, True)
self.combo.add_attribute(cell, 'text', 0) self.key_combo.add_attribute(cell, 'text', 0)
self.combo.set_active(0) self.key_combo.set_active(0)
self.key_combo.connect('changed', self._key_combo_changed_cb)
self.hbox = gtk.HBox() hbox = gtk.HBox()
self.hbox.pack_start(gtk.Label(_("Authentication Type:"))) hbox.pack_start(gtk.Label(_("Key Type:")))
self.hbox.pack_start(self.combo) hbox.pack_start(self.key_combo)
self.hbox.show_all() hbox.show_all()
self.vbox.pack_start(hbox)
self.vbox.pack_start(self.hbox) # Key entry field
self.add_key_entry()
def create_security(self): # 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)
hbox = gtk.HBox()
hbox.pack_start(gtk.Label(_("Authentication Type:")))
hbox.pack_start(self.auth_combo)
hbox.show_all()
self.vbox.pack_start(hbox)
def _key_combo_changed_cb(self, widget):
self._update_response_sensitivity()
def _get_security(self):
key = self._entry.get_text() key = self._entry.get_text()
if key.startswith('$:'): it = self.key_combo.get_active_iter()
key = key[2:] (key_type, ) = self.key_store.get(it, 1)
elif key.startswith('s:') and ((len(key) - 2) in [5, 13]):
key = string_to_hex(key[2:])
else:
key = hash_passphrase(key)
it = self.combo.get_active_iter() if key_type == WEP_PASSPHRASE:
(auth_alg, ) = self.store.get(it, 1) key = hash_passphrase(key)
elif key_type == WEP_ASCII:
key = string_to_hex(key)
it = self.auth_combo.get_active_iter()
(auth_alg, ) = self.auth_store.get(it, 1)
we_cipher = None we_cipher = None
if len(key) == 26: if len(key) == 26:
@ -164,17 +195,43 @@ class WEPKeyDialog(KeyDialog):
elif len(key) == 10: elif len(key) == 10:
we_cipher = IW_AUTH_CIPHER_WEP40 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 from nminfo import Security
return Security.new_from_args(we_cipher, (key, auth_alg)) return Security.new_from_args(we_cipher, (key, auth_alg))
def _update_response_sensitivity(self, ignored=None): def _update_response_sensitivity(self, ignored=None):
# As the md5 passphrase can be of any length and has no indicator, we key = self._entry.get_text()
# cannot check for the validity of the input. it = self.key_combo.get_active_iter()
self.set_response_sensitive(gtk.RESPONSE_OK, True) (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): class WPAKeyDialog(KeyDialog):
def __init__(self, net, async_cb, async_err_cb): def __init__(self, net, async_cb, async_err_cb):
KeyDialog.__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 = gtk.ListStore(str, int)
self.store.append(["Automatic", NM_AUTH_TYPE_WPA_PSK_AUTO]) self.store.append(["Automatic", NM_AUTH_TYPE_WPA_PSK_AUTO])
@ -196,7 +253,7 @@ class WPAKeyDialog(KeyDialog):
self.vbox.pack_start(self.hbox) self.vbox.pack_start(self.hbox)
def create_security(self): def _get_security(self):
ssid = self.get_network().get_ssid() ssid = self.get_network().get_ssid()
key = self._entry.get_text() key = self._entry.get_text()
is_hex = string_is_hex(key) is_hex = string_is_hex(key)
@ -229,8 +286,18 @@ class WPAKeyDialog(KeyDialog):
if caps & NM_802_11_CAP_PROTO_WPA2: if caps & NM_802_11_CAP_PROTO_WPA2:
wpa_ver = IW_AUTH_WPA_VERSION_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 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): def _update_response_sensitivity(self, ignored=None):
key = self._entry.get_text() key = self._entry.get_text()
@ -269,7 +336,7 @@ class FakeNet(object):
def response_cb(widget, response_id): def response_cb(widget, response_id):
if response_id == gtk.RESPONSE_OK: if response_id == gtk.RESPONSE_OK:
print dialog.get_options() print dialog.print_security()
else: else:
print "canceled" print "canceled"
widget.hide() widget.hide()

View File

@ -172,7 +172,10 @@ class Shell(gobject.GObject):
home_model = self._model.get_home() home_model = self._model.get_home()
activity = home_model.get_active_activity() activity = home_model.get_active_activity()
if 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): def set_zoom_level(self, level):
if level == self._zoom_level: if level == self._zoom_level:

View File

@ -71,8 +71,6 @@ class KeyHandler(object):
self._key_grabber = KeyGrabber() self._key_grabber = KeyGrabber()
self._key_grabber.connect('key-pressed', self._key_grabber.connect('key-pressed',
self._key_pressed_cb) self._key_pressed_cb)
self._key_grabber.connect('key-released',
self._key_released_cb)
for key in _actions_table.keys(): for key in _actions_table.keys():
self._key_grabber.grab(key) self._key_grabber.grab(key)
@ -197,23 +195,3 @@ class KeyHandler(object):
return True return True
return False 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