Merge branch 'master' of git+ssh://dev.laptop.org/git/sugar
This commit is contained in:
commit
8fab49b64e
23
NEWS
23
NEWS
@ -1,3 +1,26 @@
|
||||
* #1984 Fix removing items from the clipboard. (tomeu)
|
||||
|
||||
Snapshot b83a9ec27d
|
||||
|
||||
* Fix font size on the XO. (marco)
|
||||
* Make developer console work again. (marco)
|
||||
* #2020 Use the new activity-stop icon. (marco)
|
||||
* #2002 Tooltips for the zoom levels. (marco)
|
||||
* #2018 Rename Save to Keep. (marco)
|
||||
* #2020 Rename Close to Stop. (marco)
|
||||
|
||||
Snapshot 42f0bcc48d
|
||||
|
||||
* Fix broken import which was preventing startup. (marco)
|
||||
|
||||
Snapshot 757b2b8ce6
|
||||
|
||||
* #2031: Do not die if battery properties are unavailable. (marco)
|
||||
* #1953: Retrieve friends' nicks from the profile. (tomeu)
|
||||
* #1720: Show the owner's buddy menu in the Groups view. (tomeu)
|
||||
|
||||
Snapshot aa6a024368
|
||||
|
||||
* #1825: Fix tab label padding. (marco)
|
||||
* #1823: Margin at the toolbar tabs bottom. (marco)
|
||||
* #1872, #1934: Hide palettes when closing activities or switching views. (tomeu)
|
||||
|
@ -3,6 +3,9 @@ import sys
|
||||
|
||||
from sugar.activity.bundle import Bundle
|
||||
|
||||
from dbus.mainloop.glib import DBusGMainLoop
|
||||
DBusGMainLoop(set_as_default=True)
|
||||
|
||||
bundle = Bundle(sys.argv[1])
|
||||
bundle.install()
|
||||
|
||||
|
@ -83,8 +83,8 @@ def cmd_build_snapshot():
|
||||
sugar_news += '%s - %s - %s\n\n' % (name, version, alphatag)
|
||||
|
||||
f = open('NEWS', 'r')
|
||||
for line in f.readline():
|
||||
if len(line) > 0:
|
||||
for line in f.readlines():
|
||||
if len(line.strip()) > 0:
|
||||
sugar_news += line
|
||||
else:
|
||||
break
|
||||
|
@ -7,4 +7,5 @@ shell/view/Shell.py
|
||||
shell/view/clipboardicon.py
|
||||
shell/view/home/HomeBox.py
|
||||
shell/view/home/MeshBox.py
|
||||
shell/view/devices/battery.py
|
||||
sugar/activity/activity.py
|
||||
|
@ -141,7 +141,7 @@ class Format:
|
||||
def get_data(self):
|
||||
return self._data
|
||||
|
||||
def _set_data(self, data):
|
||||
def set_data(self, data):
|
||||
self._data = data
|
||||
|
||||
def is_on_disk(self):
|
||||
|
@ -17,10 +17,16 @@
|
||||
import logging
|
||||
import os
|
||||
import shutil
|
||||
import urlparse
|
||||
import tempfile
|
||||
|
||||
import dbus
|
||||
import dbus.service
|
||||
|
||||
from sugar import env
|
||||
from sugar import util
|
||||
from sugar.objects import mime
|
||||
|
||||
from clipboardobject import ClipboardObject, Format
|
||||
|
||||
NAME_KEY = 'NAME'
|
||||
@ -52,34 +58,6 @@ class ClipboardService(dbus.service.Object):
|
||||
self._next_id += 1
|
||||
return self._next_id
|
||||
|
||||
def _handle_file_completed(self, cb_object):
|
||||
"""If the object is an on-disk file, and it's at 100%, and we care about
|
||||
it's file type, copy that file to $HOME and upate the clipboard object's
|
||||
data to point to the new location"""
|
||||
formats = cb_object.get_formats()
|
||||
if not len(formats) or len(formats) > 1:
|
||||
return
|
||||
|
||||
format = formats.values()[0]
|
||||
if not format.is_on_disk():
|
||||
return
|
||||
|
||||
if not len(cb_object.get_activity()):
|
||||
# no activity to handle this, don't autosave it
|
||||
return
|
||||
|
||||
# copy to homedir
|
||||
src = format.get_data()
|
||||
if not os.path.exists(src):
|
||||
logging.debug("File %s doesn't appear to exist" % src)
|
||||
return
|
||||
dst = os.path.join(os.path.expanduser("~"), os.path.basename(src))
|
||||
try:
|
||||
shutil.move(src, dst)
|
||||
format._set_data(dst)
|
||||
except IOError, e:
|
||||
logging.debug("Couldn't move file %s to %s: %s" % (src, dst, e))
|
||||
|
||||
# dbus methods
|
||||
@dbus.service.method(_CLIPBOARD_DBUS_INTERFACE,
|
||||
in_signature="s", out_signature="o")
|
||||
@ -96,11 +74,13 @@ class ClipboardService(dbus.service.Object):
|
||||
def add_object_format(self, object_path, format_type, data, on_disk):
|
||||
logging.debug('ClipboardService.add_object_format')
|
||||
cb_object = self._objects[str(object_path)]
|
||||
cb_object.add_format(Format(format_type, data, on_disk))
|
||||
|
||||
if on_disk:
|
||||
logging.debug('Added format of type ' + format_type + ' with path at ' + data)
|
||||
|
||||
if on_disk and cb_object.get_percent() == 100:
|
||||
new_uri = self._copy_file(data)
|
||||
cb_object.add_format(Format(format_type, new_uri, on_disk))
|
||||
logging.debug('Added format of type ' + format_type + ' with path at ' + new_uri)
|
||||
else:
|
||||
cb_object.add_format(Format(format_type, data, on_disk))
|
||||
logging.debug('Added in-memory format of type ' + format_type + '.')
|
||||
|
||||
self.object_state_changed(object_path, {NAME_KEY: cb_object.get_name(),
|
||||
@ -132,7 +112,10 @@ class ClipboardService(dbus.service.Object):
|
||||
cb_object.set_percent(percent)
|
||||
|
||||
if percent == 100:
|
||||
self._handle_file_completed(cb_object)
|
||||
for format_name, format in cb_object.get_formats().iteritems():
|
||||
if format.is_on_disk():
|
||||
new_uri = self._copy_file(format.get_data())
|
||||
format.set_data(new_uri)
|
||||
|
||||
self.object_state_changed(object_path, {NAME_KEY: cb_object.get_name(),
|
||||
PERCENT_KEY: percent,
|
||||
@ -183,6 +166,21 @@ class ClipboardService(dbus.service.Object):
|
||||
def object_state_changed(self, object_path, values):
|
||||
pass
|
||||
|
||||
def _copy_file(self, original_uri):
|
||||
uri = urlparse.urlparse(original_uri)
|
||||
path, file_name = os.path.split(uri.path)
|
||||
|
||||
root, ext = os.path.splitext(file_name)
|
||||
if not ext or ext == '.':
|
||||
mime_type = mime.get_for_file(uri.path)
|
||||
ext = '.' + mime.get_primary_extension(mime_type)
|
||||
|
||||
f, new_file_path = tempfile.mkstemp(ext, root)
|
||||
del f
|
||||
shutil.copyfile(uri.path, new_file_path)
|
||||
|
||||
return 'file://' + new_file_path
|
||||
|
||||
_instance = None
|
||||
|
||||
def get_instance():
|
||||
|
@ -4,5 +4,4 @@ sugar_PYTHON = \
|
||||
xo.py \
|
||||
cpu.py \
|
||||
system.py \
|
||||
battery.py \
|
||||
nandflash.py
|
||||
|
@ -1,99 +0,0 @@
|
||||
# Copyright (C) 2007, Eduardo Silva (edsiper@gmail.com).
|
||||
#
|
||||
# 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 gtk
|
||||
import gobject
|
||||
|
||||
from label import Label
|
||||
from graphics.box import BoxGraphic
|
||||
|
||||
class XO_Battery(gtk.Fixed):
|
||||
|
||||
def __init__(self):
|
||||
gtk.Fixed.__init__(self)
|
||||
|
||||
self._frame_text = 'Battery Status'
|
||||
self.frame = gtk.Frame(self._frame_text)
|
||||
self.set_border_width(10)
|
||||
|
||||
self._battery_charge = self._get_battery_status()
|
||||
|
||||
self._battery_box = BoxGraphic()
|
||||
self._battery_box.set_size_request(70, 150)
|
||||
self._battery_box.set_capacity(self._battery_charge)
|
||||
|
||||
fixed = gtk.Fixed();
|
||||
fixed.set_border_width(10)
|
||||
fixed.add(self._battery_box)
|
||||
|
||||
hbox = gtk.HBox(False, 0)
|
||||
hbox.pack_start(fixed, False, False, 4)
|
||||
|
||||
# Battery info
|
||||
table = gtk.Table(2, 2)
|
||||
table.set_border_width(5)
|
||||
table.set_col_spacings(7)
|
||||
table.set_row_spacings(7)
|
||||
|
||||
label_charge = Label('Charge: ' , Label.DESCRIPTION)
|
||||
self.label_charge_value = Label(str(self._battery_charge) + '%', Label.DESCRIPTION)
|
||||
|
||||
table.attach(label_charge, 0, 1, 0, 1)
|
||||
table.attach(self.label_charge_value, 1,2, 0,1)
|
||||
|
||||
# Charging
|
||||
"""
|
||||
hbox_charging = gtk.HBox(False, 2)
|
||||
l_charging = gtk.Label('Charging: ')
|
||||
l_charging.set_justify(gtk.JUSTIFY_LEFT)
|
||||
hbox_charging.pack_start(l_charging, False, False, 0)
|
||||
|
||||
self._label_charging = gtk.Label('No')
|
||||
self._label_charging.set_justify(gtk.JUSTIFY_LEFT)
|
||||
|
||||
hbox_charging.pack_start(self._label_charging, False, False, 0)
|
||||
"""
|
||||
|
||||
alignment = gtk.Alignment(0,0,0,0)
|
||||
alignment.add(table)
|
||||
|
||||
hbox.pack_start(alignment, False, False, 0)
|
||||
self.frame.add(hbox)
|
||||
self.add(self.frame)
|
||||
self.show_all()
|
||||
|
||||
def update_status(self):
|
||||
|
||||
new_charge = self._get_battery_status()
|
||||
frame_label = str(self._battery_charge) + '%'
|
||||
|
||||
if new_charge != self._battery_charge:
|
||||
self._battery_charge = self._get_battery_status()
|
||||
self.label_charge_value.set_text(frame_label)
|
||||
self._battery_box.set_capacity(self._battery_charge)
|
||||
|
||||
def _get_battery_status(self):
|
||||
battery_class_path = '/sys/class/battery/psu_0/'
|
||||
capacity_path = battery_class_path + 'capacity_percentage'
|
||||
try:
|
||||
f = open(capacity_path, 'r')
|
||||
val = f.read().split('\n')
|
||||
capacity = int(val[0])
|
||||
f.close()
|
||||
except:
|
||||
capacity = 0
|
||||
|
||||
return capacity
|
@ -23,7 +23,6 @@ import string
|
||||
|
||||
from cpu import XO_CPU
|
||||
from system import XO_System
|
||||
from battery import XO_Battery
|
||||
from nandflash import XO_NandFlash
|
||||
|
||||
class Interface:
|
||||
@ -40,11 +39,9 @@ class Interface:
|
||||
self.vbox.pack_start(xo_cpu, False, False, 0)
|
||||
|
||||
# Graphics: Battery Status, NandFlash
|
||||
self._xo_battery = XO_Battery()
|
||||
self._xo_nandflash = XO_NandFlash()
|
||||
|
||||
hbox = gtk.HBox(False, 2)
|
||||
hbox.pack_start(self._xo_battery, False, False, 0)
|
||||
hbox.pack_start(self._xo_nandflash, False, False, 0)
|
||||
|
||||
self.vbox.pack_start(hbox, False, False, 0)
|
||||
@ -54,7 +51,6 @@ class Interface:
|
||||
gobject.timeout_add(5000, self._update_components)
|
||||
|
||||
def _update_components(self):
|
||||
self._xo_battery.update_status()
|
||||
self._xo_nandflash.update_status()
|
||||
|
||||
return True
|
||||
|
@ -36,7 +36,7 @@ class BuddyModel(gobject.GObject):
|
||||
([gobject.TYPE_PYOBJECT]))
|
||||
}
|
||||
|
||||
def __init__(self, key=None, buddy=None):
|
||||
def __init__(self, key=None, buddy=None, nick=None):
|
||||
if (key and buddy) or (not key and not buddy):
|
||||
raise RuntimeError("Must specify only _one_ of key or buddy.")
|
||||
|
||||
@ -51,7 +51,6 @@ class BuddyModel(gobject.GObject):
|
||||
self._pservice = presenceservice.get_instance()
|
||||
|
||||
self._buddy = None
|
||||
self._nick = None
|
||||
|
||||
# If given just a key, try to get the buddy from the PS first
|
||||
if not buddy:
|
||||
@ -72,7 +71,7 @@ class BuddyModel(gobject.GObject):
|
||||
self._key = key
|
||||
# Set color to 'inactive'/'disconnected'
|
||||
self._set_color_from_string(_NOT_PRESENT_COLOR)
|
||||
self._name = "Unknown buddy"
|
||||
self._nick = nick
|
||||
|
||||
def _set_color_from_string(self, color_string):
|
||||
self._color = XoColor(color_string)
|
||||
|
@ -69,7 +69,7 @@ class Friends(gobject.GObject):
|
||||
# HACK: don't screw up on old friends files
|
||||
if len(key) < 20:
|
||||
continue
|
||||
buddy = BuddyModel(key=key)
|
||||
buddy = BuddyModel(key=key, nick=cp.get(key, 'nick'))
|
||||
self.add_friend(buddy)
|
||||
except Exception, exc:
|
||||
logging.error("Error parsing friends file: %s" % exc)
|
||||
|
@ -14,6 +14,8 @@
|
||||
# along with this program; if not, write to the Free Software
|
||||
# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
|
||||
import logging
|
||||
|
||||
import gobject
|
||||
import dbus
|
||||
|
||||
@ -45,9 +47,30 @@ class Device(device.Device):
|
||||
'org.freedesktop.Hal',
|
||||
udi)
|
||||
|
||||
self._level = self._battery.GetProperty(_LEVEL_PROP)
|
||||
self._charging = self._battery.GetProperty(_CHARGING_PROP)
|
||||
self._discharging = self._battery.GetProperty(_DISCHARGING_PROP)
|
||||
self._level = self._get_level()
|
||||
self._charging = self._get_charging()
|
||||
self._discharging = self._get_discharging()
|
||||
|
||||
def _get_level(self):
|
||||
try:
|
||||
return self._battery.GetProperty(_LEVEL_PROP)
|
||||
except dbus.DBusException:
|
||||
logging.error('Cannot access %s' % _LEVEL_PROP)
|
||||
return 0
|
||||
|
||||
def _get_charging(self):
|
||||
try:
|
||||
return self._battery.GetProperty(_CHARGING_PROP)
|
||||
except dbus.DBusException:
|
||||
logging.error('Cannot access %s' % _CHARGING_PROP)
|
||||
return False
|
||||
|
||||
def _get_discharging(self):
|
||||
try:
|
||||
return self._battery.GetProperty(_DISCHARGING_PROP)
|
||||
except dbus.DBusException:
|
||||
logging.error('Cannot access %s' % _DISCHARGING_PROP)
|
||||
return False
|
||||
|
||||
def do_get_property(self, pspec):
|
||||
if pspec.name == 'level':
|
||||
@ -63,11 +86,11 @@ class Device(device.Device):
|
||||
def _battery_changed(self, num_changes, changes_list):
|
||||
for change in changes_list:
|
||||
if change[0] == _LEVEL_PROP:
|
||||
self._level = self._battery.GetProperty(_LEVEL_PROP)
|
||||
self._level = self._get_level()
|
||||
self.notify('level')
|
||||
elif change[0] == _CHARGING_PROP:
|
||||
self._charging = self._battery.GetProperty(_CHARGING_PROP)
|
||||
self._charging = self._get_charging()
|
||||
self.notify('charging')
|
||||
elif change[0] == _DISCHARGING_PROP:
|
||||
self._discharging = self._battery.GetProperty(_DISCHARGING_PROP)
|
||||
self._discharging = self._get_discharging()
|
||||
self.notify('discharging')
|
||||
|
@ -56,6 +56,9 @@ class ShellService(dbus.service.Object):
|
||||
self._home_model.connect('active-activity-changed',
|
||||
self._cur_activity_changed_cb)
|
||||
|
||||
bundle_registry = bundleregistry.get_registry()
|
||||
bundle_registry.connect('bundle-added', self._bundle_added_cb)
|
||||
|
||||
bus = dbus.SessionBus()
|
||||
bus_name = dbus.service.BusName(_DBUS_SERVICE, bus=bus)
|
||||
dbus.service.Object.__init__(self, bus_name, _DBUS_PATH)
|
||||
@ -121,6 +124,10 @@ class ShellService(dbus.service.Object):
|
||||
|
||||
return result
|
||||
|
||||
@dbus.service.signal(_DBUS_ACTIVITY_REGISTRY_IFACE, signature="a{sv}")
|
||||
def ActivityAdded(self, activity_info):
|
||||
pass
|
||||
|
||||
@dbus.service.signal(_DBUS_OWNER_IFACE, signature="s")
|
||||
def ColorChanged(self, color):
|
||||
pass
|
||||
@ -158,3 +165,7 @@ class ShellService(dbus.service.Object):
|
||||
'icon': bundle.get_icon(),
|
||||
'service_name': bundle.get_service_name(),
|
||||
'path': bundle.get_path()}
|
||||
|
||||
def _bundle_added_cb(self, bundle_registry, bundle):
|
||||
self.ActivityAdded(self._bundle_to_dict(bundle))
|
||||
|
||||
|
@ -8,6 +8,6 @@ sugar_PYTHON = \
|
||||
FriendsBox.py \
|
||||
eventarea.py \
|
||||
frame.py \
|
||||
ZoomBox.py \
|
||||
overlaybox.py \
|
||||
framewindow.py
|
||||
framewindow.py \
|
||||
zoombox.py
|
||||
|
@ -13,16 +13,14 @@
|
||||
# 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 shutil
|
||||
|
||||
import os
|
||||
import logging
|
||||
import urlparse
|
||||
|
||||
import hippo
|
||||
import gtk
|
||||
|
||||
from sugar import util
|
||||
from sugar.objects import mime
|
||||
from view.clipboardicon import ClipboardIcon
|
||||
from sugar.clipboard import clipboardservice
|
||||
|
||||
@ -101,21 +99,10 @@ class ClipboardBox(hippo.CanvasBox):
|
||||
uris = selection.data.split('\n')
|
||||
if len(uris) > 1:
|
||||
raise NotImplementedError('Multiple uris in text/uri-list still not supported.')
|
||||
uri = urlparse.urlparse(uris[0])
|
||||
path, file_name = os.path.split(uri.path)
|
||||
|
||||
root, ext = os.path.splitext(file_name)
|
||||
if not ext or ext == '.':
|
||||
mime_type = mime.get_for_file(uri.path)
|
||||
file_name = root + '.' + mime.get_primary_extension(mime_type)
|
||||
|
||||
# Copy the file, as it will be deleted when the dnd operation finishes.
|
||||
new_file_path = os.path.join(path, 'cb' + file_name)
|
||||
shutil.copyfile(uri.path, new_file_path)
|
||||
|
||||
cb_service.add_object_format(object_id,
|
||||
selection.type,
|
||||
"file://" + new_file_path,
|
||||
uris[0],
|
||||
on_disk=True)
|
||||
else:
|
||||
cb_service.add_object_format(object_id,
|
||||
|
@ -27,7 +27,7 @@ from sugar.clipboard import clipboardservice
|
||||
|
||||
from view.frame.eventarea import EventArea
|
||||
from view.frame.ActivitiesBox import ActivitiesBox
|
||||
from view.frame.ZoomBox import ZoomBox
|
||||
from view.frame.zoombox import ZoomBox
|
||||
from view.frame.overlaybox import OverlayBox
|
||||
from view.frame.FriendsBox import FriendsBox
|
||||
from view.frame.framewindow import FrameWindow
|
||||
|
@ -14,10 +14,14 @@
|
||||
# along with this program; if not, write to the Free Software
|
||||
# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
|
||||
from gettext import gettext as _
|
||||
|
||||
import hippo
|
||||
|
||||
from sugar.graphics import color
|
||||
from sugar.graphics.palette import Palette
|
||||
from sugar.graphics.iconbutton import IconButton
|
||||
from frameinvoker import FrameCanvasInvoker
|
||||
|
||||
from model.shellmodel import ShellModel
|
||||
|
||||
@ -35,6 +39,11 @@ class ZoomBox(hippo.CanvasBox):
|
||||
ShellModel.ZOOM_MESH)
|
||||
self.append(icon)
|
||||
|
||||
palette = Palette(_('Neighborhood'))
|
||||
palette.props.invoker = FrameCanvasInvoker(icon)
|
||||
palette.set_group_id('frame')
|
||||
icon.set_palette(palette)
|
||||
|
||||
icon = IconButton(icon_name='theme:stock-zoom-friends',
|
||||
stroke_color=color.BLACK,
|
||||
fill_color=color.WHITE)
|
||||
@ -43,6 +52,11 @@ class ZoomBox(hippo.CanvasBox):
|
||||
ShellModel.ZOOM_FRIENDS)
|
||||
self.append(icon)
|
||||
|
||||
palette = Palette(_('Group'))
|
||||
palette.props.invoker = FrameCanvasInvoker(icon)
|
||||
palette.set_group_id('frame')
|
||||
icon.set_palette(palette)
|
||||
|
||||
icon = IconButton(icon_name='theme:stock-zoom-home',
|
||||
stroke_color=color.BLACK,
|
||||
fill_color=color.WHITE)
|
||||
@ -51,6 +65,11 @@ class ZoomBox(hippo.CanvasBox):
|
||||
ShellModel.ZOOM_HOME)
|
||||
self.append(icon)
|
||||
|
||||
palette = Palette(_('Home'))
|
||||
palette.props.invoker = FrameCanvasInvoker(icon)
|
||||
palette.set_group_id('frame')
|
||||
icon.set_palette(palette)
|
||||
|
||||
icon = IconButton(icon_name='theme:stock-zoom-activity',
|
||||
stroke_color=color.BLACK,
|
||||
fill_color=color.WHITE)
|
||||
@ -59,5 +78,10 @@ class ZoomBox(hippo.CanvasBox):
|
||||
ShellModel.ZOOM_ACTIVITY)
|
||||
self.append(icon)
|
||||
|
||||
palette = Palette(_('Activity'))
|
||||
palette.props.invoker = FrameCanvasInvoker(icon)
|
||||
palette.set_group_id('frame')
|
||||
icon.set_palette(palette)
|
||||
|
||||
def _level_clicked_cb(self, item, level):
|
||||
self._shell.set_zoom_level(level)
|
@ -19,9 +19,12 @@ import random
|
||||
import hippo
|
||||
import gobject
|
||||
|
||||
from sugar import profile
|
||||
from sugar.graphics.spreadlayout import SpreadLayout
|
||||
from sugar.graphics import units
|
||||
from view.home.MyIcon import MyIcon
|
||||
|
||||
from model.BuddyModel import BuddyModel
|
||||
from view.BuddyIcon import BuddyIcon
|
||||
from view.home.FriendView import FriendView
|
||||
|
||||
class FriendsBox(hippo.CanvasBox):
|
||||
@ -35,8 +38,10 @@ class FriendsBox(hippo.CanvasBox):
|
||||
self._layout = SpreadLayout()
|
||||
self.set_layout(self._layout)
|
||||
|
||||
self._my_icon = MyIcon(units.LARGE_ICON_SCALE)
|
||||
self._layout.add_center(self._my_icon)
|
||||
buddy_model = BuddyModel(key=profile.get_pubkey())
|
||||
self._owner_icon = BuddyIcon(shell, buddy_model)
|
||||
self._owner_icon.props.scale = units.LARGE_ICON_SCALE
|
||||
self._layout.add_center(self._owner_icon)
|
||||
|
||||
friends = self._shell.get_model().get_friends()
|
||||
|
||||
|
@ -64,11 +64,11 @@ class ActivityToolbar(gtk.Toolbar):
|
||||
self.insert(separator, -1)
|
||||
separator.show()
|
||||
|
||||
self.save = ToolButton('document-save')
|
||||
self.save.set_tooltip(_('Save'))
|
||||
self.save.connect('clicked', self._save_clicked_cb)
|
||||
self.insert(self.save, -1)
|
||||
self.save.show()
|
||||
self.keep = ToolButton('document-save')
|
||||
self.keep.set_tooltip(_('Keep'))
|
||||
self.keep.connect('clicked', self._keep_clicked_cb)
|
||||
self.insert(self.keep, -1)
|
||||
self.keep.show()
|
||||
|
||||
self.share = ToolButton('stock-share-mesh')
|
||||
self.share.set_tooltip(_('Share'))
|
||||
@ -83,21 +83,21 @@ class ActivityToolbar(gtk.Toolbar):
|
||||
self.insert(separator, -1)
|
||||
separator.show()
|
||||
|
||||
self.close = ToolButton('window-close')
|
||||
self.close.set_tooltip(_('Close'))
|
||||
self.close.connect('clicked', self._close_clicked_cb)
|
||||
self.insert(self.close, -1)
|
||||
self.close.show()
|
||||
self.stop = ToolButton('activity-stop')
|
||||
self.stop.set_tooltip(_('Stop'))
|
||||
self.stop.connect('clicked', self._stop_clicked_cb)
|
||||
self.insert(self.stop, -1)
|
||||
self.stop.show()
|
||||
|
||||
self._update_title_sid = None
|
||||
|
||||
def _share_clicked_cb(self, button):
|
||||
self._activity.share()
|
||||
|
||||
def _save_clicked_cb(self, button):
|
||||
def _keep_clicked_cb(self, button):
|
||||
self._activity.save()
|
||||
|
||||
def _close_clicked_cb(self, button):
|
||||
def _stop_clicked_cb(self, button):
|
||||
self._activity.close()
|
||||
self._activity.destroy()
|
||||
|
||||
|
@ -50,26 +50,22 @@ class _DefaultFileList(list):
|
||||
self.append(os.path.join('activity', name))
|
||||
|
||||
self.append('activity/activity.info')
|
||||
self.append('setup.py')
|
||||
|
||||
if os.path.isfile(_get_source_path('NEWS')):
|
||||
self.append('NEWS')
|
||||
|
||||
class _ManifestFileList(list):
|
||||
def __init__(self, manifest=None):
|
||||
class _ManifestFileList(_DefaultFileList):
|
||||
def __init__(self, manifest):
|
||||
_DefaultFileList.__init__(self)
|
||||
self.append(manifest)
|
||||
|
||||
f = open(manifest,'r')
|
||||
for line in f.readlines():
|
||||
stripped_line = line.strip()
|
||||
if stripped_line:
|
||||
if stripped_line and not stripped_line in self:
|
||||
self.append(stripped_line)
|
||||
f.close()
|
||||
|
||||
defaults = _DefaultFileList()
|
||||
for path in defaults:
|
||||
self.append(path)
|
||||
|
||||
def _extract_bundle(source_file, dest_dir):
|
||||
if not os.path.exists(dest_dir):
|
||||
os.mkdir(dest_dir)
|
||||
@ -270,8 +266,8 @@ def cmd_release(bundle_name, manifest):
|
||||
sugar_news += '%s - %d\n\n' % (bundle_name, version)
|
||||
|
||||
f = open(news_path,'r')
|
||||
for line in f.readline():
|
||||
if len(line) > 0:
|
||||
for line in f.readlines():
|
||||
if len(line.strip()) > 0:
|
||||
sugar_news += line
|
||||
else:
|
||||
break
|
||||
|
@ -15,6 +15,8 @@
|
||||
# Free Software Foundation, Inc., 59 Temple Place - Suite 330,
|
||||
# Boston, MA 02111-1307, USA.
|
||||
|
||||
import logging
|
||||
|
||||
import dbus
|
||||
|
||||
_SHELL_SERVICE = "org.laptop.Shell"
|
||||
@ -39,6 +41,11 @@ class ActivityRegistry(object):
|
||||
bus = dbus.SessionBus()
|
||||
bus_object = bus.get_object(_SHELL_SERVICE, _SHELL_PATH)
|
||||
self._registry = dbus.Interface(bus_object, _REGISTRY_IFACE)
|
||||
self._registry.connect_to_signal('ActivityAdded', self._activity_added_cb)
|
||||
|
||||
# Two caches fo saving some travel across dbus.
|
||||
self._service_name_to_activity_info = {}
|
||||
self._mime_type_to_activities = {}
|
||||
|
||||
def _convert_info_list(self, info_list):
|
||||
result = []
|
||||
@ -49,16 +56,33 @@ class ActivityRegistry(object):
|
||||
return result
|
||||
|
||||
def get_activity(self, service_name):
|
||||
if self._service_name_to_activity_info.has_key(service_name):
|
||||
return self._service_name_to_activity_info[service_name]
|
||||
|
||||
info_dict = self._registry.GetActivity(service_name)
|
||||
return _activity_info_from_dict(info_dict)
|
||||
activity_info = _activity_info_from_dict(info_dict)
|
||||
|
||||
self._service_name_to_activity_info[service_name] = activity_info
|
||||
return activity_info
|
||||
|
||||
def find_activity(self, name):
|
||||
info_list = self._registry.FindActivity(name)
|
||||
return self._convert_info_list(info_list)
|
||||
|
||||
def get_activities_for_type(self, mime_type):
|
||||
if self._mime_type_to_activities.has_key(mime_type):
|
||||
return self._mime_type_to_activities[mime_type]
|
||||
|
||||
info_list = self._registry.GetActivitiesForType(mime_type)
|
||||
return self._convert_info_list(info_list)
|
||||
activities = self._convert_info_list(info_list)
|
||||
|
||||
self._mime_type_to_activities[mime_type] = activities
|
||||
return activities
|
||||
|
||||
def _activity_added_cb(self, bundle):
|
||||
logging.debug('ActivityRegistry._activity_added_cb: flushing caches')
|
||||
self._service_name_to_activity_info.clear()
|
||||
self._mime_type_to_activities.clear()
|
||||
|
||||
_registry = None
|
||||
|
||||
|
@ -18,6 +18,10 @@
|
||||
import gtk
|
||||
import pango
|
||||
|
||||
def _get_screen_dpi():
|
||||
xft_dpi = gtk.settings_get_default().get_property('gtk-xft-dpi')
|
||||
return float(xft_dpi / 1024)
|
||||
|
||||
def _compute_zoom_factor():
|
||||
return gtk.gdk.screen_width() / 1200.0
|
||||
|
||||
@ -43,17 +47,21 @@ class Font(object):
|
||||
def get_pango_desc(self):
|
||||
return pango.FontDescription(self._desc)
|
||||
|
||||
_XO_DPI = 200.0
|
||||
|
||||
_FOCUS_LINE_WIDTH = 2
|
||||
_TAB_CURVATURE = 1
|
||||
|
||||
ZOOM_FACTOR = _compute_zoom_factor()
|
||||
|
||||
FONT_SIZE = _zoom(7 * 200 / 72.0)
|
||||
FONT_SIZE = _zoom(7 * _XO_DPI / _get_screen_dpi())
|
||||
FONT_NORMAL = Font('Bitstream Vera Sans %d' % FONT_SIZE)
|
||||
FONT_BOLD = Font('Bitstream Vera Sans bold %d' % FONT_SIZE)
|
||||
FONT_NORMAL_H = _compute_font_height(FONT_NORMAL)
|
||||
FONT_BOLD_H = _compute_font_height(FONT_BOLD)
|
||||
|
||||
TOOLBOX_SEPARATOR_HEIGHT = _zoom(9)
|
||||
TOOLBOX_HORIZONTAL_PADDING = _zoom(75)
|
||||
TOOLBOX_TAB_VBORDER = int((_zoom(36) - FONT_SIZE - _FOCUS_LINE_WIDTH) / 2)
|
||||
TOOLBOX_TAB_VBORDER = int((_zoom(36) - FONT_NORMAL_H - _FOCUS_LINE_WIDTH) / 2)
|
||||
TOOLBOX_TAB_HBORDER = _zoom(15) - _FOCUS_LINE_WIDTH - _TAB_CURVATURE
|
||||
TOOLBOX_TAB_LABEL_WIDTH = _zoom(150 - 15 * 2)
|
||||
|
@ -36,20 +36,39 @@ class ObjectType(object):
|
||||
self.name = name
|
||||
self.icon = icon
|
||||
self.mime_types = mime_types
|
||||
|
||||
self._type_id_to_type = {}
|
||||
self._mime_type_to_type = {}
|
||||
|
||||
class ObjectTypeRegistry(object):
|
||||
def __init__(self):
|
||||
bus = dbus.SessionBus()
|
||||
bus_object = bus.get_object(_SERVICE, _PATH)
|
||||
self._registry = dbus.Interface(bus_object, _IFACE)
|
||||
|
||||
# Two caches fo saving some travel across dbus.
|
||||
self._type_id_to_type = {}
|
||||
self._mime_type_to_type = {}
|
||||
|
||||
def get_type(self, type_id):
|
||||
if self._type_id_to_type.has_key(type_id):
|
||||
return self._type_id_to_type[type_id]
|
||||
|
||||
type_dict = self._registry.GetType(type_id)
|
||||
return _object_type_from_dict(type_dict)
|
||||
object_type = _object_type_from_dict(type_dict)
|
||||
|
||||
self._type_id_to_type[type_id] = object_type
|
||||
return object_type
|
||||
|
||||
def get_type_for_mime(self, mime_type):
|
||||
if self._mime_type_to_type.has_key(mime_type):
|
||||
return self._mime_type_to_type[mime_type]
|
||||
|
||||
type_dict = self._registry.GetTypeForMIME(mime_type)
|
||||
return _object_type_from_dict(type_dict)
|
||||
object_type = _object_type_from_dict(type_dict)
|
||||
|
||||
self._mime_type_to_type[mime_type] = object_type
|
||||
return object_type
|
||||
|
||||
_registry = None
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user