Merge branch 'master' of git+ssh://dev.laptop.org/git/sugar
Conflicts: NEWS
This commit is contained in:
commit
b0c7a0546d
9
NEWS
9
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)
|
||||
|
@ -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
|
||||
|
||||
|
@ -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\
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
376
po/sugar.pot
Normal 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 ""
|
@ -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
|
@ -1,6 +1,4 @@
|
||||
SUBDIRS = hardware model view intro
|
||||
|
||||
bin_SCRIPTS = sugar-shell
|
||||
SUBDIRS = controlpanel hardware model view intro
|
||||
|
||||
sugardir = $(pkgdatadir)/shell
|
||||
sugar_PYTHON = \
|
||||
|
4
shell/controlpanel/Makefile.am
Normal file
4
shell/controlpanel/Makefile.am
Normal file
@ -0,0 +1,4 @@
|
||||
sugardir = $(pkgdatadir)/shell/controlpanel
|
||||
sugar_PYTHON = \
|
||||
__init__.py \
|
||||
control.py
|
16
shell/controlpanel/__init__.py
Normal file
16
shell/controlpanel/__init__.py
Normal 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
|
||||
|
@ -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()
|
||||
|
||||
|
@ -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)
|
||||
|
||||
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()
|
||||
|
@ -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:
|
||||
|
@ -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
|
||||
|
Loading…
Reference in New Issue
Block a user