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)
* 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)

View File

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

View File

@ -17,9 +17,14 @@
# Free Software Foundation, Inc., 59 Temple Place - Suite 330,
# 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():
print 'Usage: sugar-control [ option ] key [ args ... ] \n\

View File

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

View File

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

View File

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

View File

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

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
bin_SCRIPTS = sugar-shell
SUBDIRS = controlpanel hardware model view intro
sugardir = $(pkgdatadir)/shell
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 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,26 +189,17 @@ _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()
i = 0
@ -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()
@ -332,11 +348,29 @@ def print_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")
@ -359,20 +393,6 @@ def set_timezone(timezone):
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'
if os.access(path, os.R_OK) == 0:
@ -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()

View File

@ -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)
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(_("Key Type:")))
hbox.pack_start(self.key_combo)
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()
if key.startswith('$:'):
key = key[2:]
elif key.startswith('s:') and ((len(key) - 2) in [5, 13]):
key = string_to_hex(key[2:])
else:
key = hash_passphrase(key)
it = self.key_combo.get_active_iter()
(key_type, ) = self.key_store.get(it, 1)
it = self.combo.get_active_iter()
(auth_alg, ) = self.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.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()

View File

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

View File

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