PEP8 white space and long line fixes

This commit is contained in:
Sascha Silbe 2009-08-25 21:12:40 +02:00
parent ecdaf6b795
commit c9e63eb8ea
50 changed files with 574 additions and 291 deletions

View File

@ -74,7 +74,9 @@ from sugar.session import XSMPClient
from sugar import wm from sugar import wm
# support deprecated imports # support deprecated imports
from sugar.activity.widgets import ActivityToolbar, EditToolbar, ActivityToolbox from sugar.activity.widgets import ActivityToolbar, EditToolbar
from sugar.activity.widgets import ActivityToolbox
_ = lambda msg: gettext.dgettext('sugar-toolkit', msg) _ = lambda msg: gettext.dgettext('sugar-toolkit', msg)
@ -86,17 +88,20 @@ J_DBUS_SERVICE = 'org.laptop.Journal'
J_DBUS_PATH = '/org/laptop/Journal' J_DBUS_PATH = '/org/laptop/Journal'
J_DBUS_INTERFACE = 'org.laptop.Journal' J_DBUS_INTERFACE = 'org.laptop.Journal'
class _ActivitySession(gobject.GObject): class _ActivitySession(gobject.GObject):
__gsignals__ = { __gsignals__ = {
'quit-requested': (gobject.SIGNAL_RUN_FIRST, gobject.TYPE_NONE, ([])), 'quit-requested': (gobject.SIGNAL_RUN_FIRST, gobject.TYPE_NONE, ([])),
'quit': (gobject.SIGNAL_RUN_FIRST, gobject.TYPE_NONE, ([])) 'quit': (gobject.SIGNAL_RUN_FIRST, gobject.TYPE_NONE, ([])),
} }
def __init__(self): def __init__(self):
gobject.GObject.__init__(self) gobject.GObject.__init__(self)
self._xsmp_client = XSMPClient() self._xsmp_client = XSMPClient()
self._xsmp_client.connect('quit-requested', self.__sm_quit_requested_cb) self._xsmp_client.connect('quit-requested',
self.__sm_quit_requested_cb)
self._xsmp_client.connect('quit', self.__sm_quit_cb) self._xsmp_client.connect('quit', self.__sm_quit_cb)
self._xsmp_client.startup() self._xsmp_client.startup()
@ -133,6 +138,7 @@ class _ActivitySession(gobject.GObject):
def __sm_quit_cb(self, client): def __sm_quit_cb(self, client):
self.emit('quit') self.emit('quit')
class Activity(Window, gtk.Container): class Activity(Window, gtk.Container):
"""This is the base Activity class that all other Activities derive from. """This is the base Activity class that all other Activities derive from.
This is where your activity starts. This is where your activity starts.
@ -160,12 +166,12 @@ class Activity(Window, gtk.Container):
2. Implement read_file() and write_file() 2. Implement read_file() and write_file()
Most activities revolve around creating and storing Journal entries. Most activities revolve around creating and storing Journal entries.
For example, Write: You create a document, it is saved to the Journal For example, Write: You create a document, it is saved to the
and then later you resume working on the document. Journal and then later you resume working on the document.
read_file() and write_file() will be called by sugar to tell your read_file() and write_file() will be called by sugar to tell your
Activity that it should load or save the document the user is working Activity that it should load or save the document the user is
on. working on.
3. Implement our Activity Toolbars. 3. Implement our Activity Toolbars.
The Toolbars are added to your Activity in step 1 (the toolbox), but The Toolbars are added to your Activity in step 1 (the toolbox), but
@ -177,9 +183,9 @@ class Activity(Window, gtk.Container):
okay, but you should really stop and think about why not!) You do okay, but you should really stop and think about why not!) You do
this with the ActivityToolbox(self) call in step 1. this with the ActivityToolbox(self) call in step 1.
Usually, you will also need the standard EditToolbar. This is the one Usually, you will also need the standard EditToolbar. This is the
which has the standard copy and paste buttons. You need to derive one which has the standard copy and paste buttons. You need to
your own EditToolbar class from sugar.EditToolbar: derive your own EditToolbar class from sugar.EditToolbar:
class EditToolbar(activity.EditToolbar): class EditToolbar(activity.EditToolbar):
... ...
@ -200,11 +206,12 @@ class Activity(Window, gtk.Container):
Hint: A good and simple Activity to learn from is the Read activity. To Hint: A good and simple Activity to learn from is the Read activity. To
create your own activity, you may want to copy it and use it as a template. create your own activity, you may want to copy it and use it as a template.
""" """
__gtype_name__ = 'SugarActivity' __gtype_name__ = 'SugarActivity'
__gsignals__ = { __gsignals__ = {
'shared': (gobject.SIGNAL_RUN_FIRST, gobject.TYPE_NONE, ([])), 'shared': (gobject.SIGNAL_RUN_FIRST, gobject.TYPE_NONE, ([])),
'joined': (gobject.SIGNAL_RUN_FIRST, gobject.TYPE_NONE, ([])) 'joined': (gobject.SIGNAL_RUN_FIRST, gobject.TYPE_NONE, ([])),
} }
def __init__(self, handle, create_jobject=True): def __init__(self, handle, create_jobject=True):
@ -368,8 +375,8 @@ class Activity(Window, gtk.Container):
The activity id is sort-of-like the unix process id (PID). However, The activity id is sort-of-like the unix process id (PID). However,
unlike PIDs it is only different for each new instance (with unlike PIDs it is only different for each new instance (with
create_jobject = True set) and stays the same everytime a user create_jobject = True set) and stays the same everytime a user
resumes an activity. This is also the identity of your Activity to other resumes an activity. This is also the identity of your Activity to
XOs for use when sharing. other XOs for use when sharing.
""" """
return self._activity_id return self._activity_id
@ -378,7 +385,8 @@ class Activity(Window, gtk.Container):
return os.environ['SUGAR_BUNDLE_ID'] return os.environ['SUGAR_BUNDLE_ID']
def set_canvas(self, canvas): def set_canvas(self, canvas):
"""Sets the 'work area' of your activity with the canvas of your choice. """Sets the 'work area' of your activity with the canvas of your
choice.
One commonly used canvas is gtk.ScrolledWindow One commonly used canvas is gtk.ScrolledWindow
""" """
@ -425,8 +433,8 @@ class Activity(Window, gtk.Container):
~/.sugar/default/MyActivityName/ ~/.sugar/default/MyActivityName/
Activities should ONLY save settings, user preferences and other data Activities should ONLY save settings, user preferences and other data
which isn't specific to a journal item here. If (meta-)data is in anyway which isn't specific to a journal item here. If (meta-)data is in
specific to a journal entry, it MUST be stored in the DataStore. anyway specific to a journal entry, it MUST be stored in the DataStore.
""" """
if os.environ.has_key('SUGAR_ACTIVITY_ROOT') and \ if os.environ.has_key('SUGAR_ACTIVITY_ROOT') and \
os.environ['SUGAR_ACTIVITY_ROOT']: os.environ['SUGAR_ACTIVITY_ROOT']:
@ -446,9 +454,10 @@ class Activity(Window, gtk.Container):
close it. close it.
Although not required, this is also a good time to read all meta-data: Although not required, this is also a good time to read all meta-data:
the file itself cannot be changed externally, but the title, description the file itself cannot be changed externally, but the title,
and other metadata['tags'] may change. So if it is important for you to description and other metadata['tags'] may change. So if it is
notice changes, this is the time to record the originals. important for you to notice changes, this is the time to record the
originals.
""" """
raise NotImplementedError raise NotImplementedError
@ -461,12 +470,13 @@ class Activity(Window, gtk.Container):
all document data to it. all document data to it.
Additionally, you should also write any metadata needed to resume your Additionally, you should also write any metadata needed to resume your
activity. For example, the Read activity saves the current page and zoom activity. For example, the Read activity saves the current page and
level, so it can display the page. zoom level, so it can display the page.
Note: Currently, the file_path *WILL* be different from the one you Note: Currently, the file_path *WILL* be different from the one you
received in file_read(). Even if you kept the file_path from file_read() received in file_read(). Even if you kept the file_path from
open until now, you must still write the entire file to this file_path. file_read() open until now, you must still write the entire file to
this file_path.
""" """
raise NotImplementedError raise NotImplementedError
@ -518,6 +528,7 @@ class Activity(Window, gtk.Container):
gtk.gdk.INTERP_BILINEAR) gtk.gdk.INTERP_BILINEAR)
preview_data = [] preview_data = []
def save_func(buf, data): def save_func(buf, data):
data.append(buf) data.append(buf)
@ -809,8 +820,10 @@ class Activity(Window, gtk.Container):
# DEPRECATED # DEPRECATED
_shared_activity = property(lambda self: self.shared_activity, None) _shared_activity = property(lambda self: self.shared_activity, None)
_session = None _session = None
def _get_session(): def _get_session():
global _session global _session
@ -819,14 +832,17 @@ def _get_session():
return _session return _session
def get_bundle_name(): def get_bundle_name():
"""Return the bundle name for the current process' bundle""" """Return the bundle name for the current process' bundle"""
return os.environ['SUGAR_BUNDLE_NAME'] return os.environ['SUGAR_BUNDLE_NAME']
def get_bundle_path(): def get_bundle_path():
"""Return the bundle path for the current process' bundle""" """Return the bundle path for the current process' bundle"""
return os.environ['SUGAR_BUNDLE_PATH'] return os.environ['SUGAR_BUNDLE_PATH']
def get_activity_root(): def get_activity_root():
"""Returns a path for saving Activity specific preferences, etc.""" """Returns a path for saving Activity specific preferences, etc."""
if os.environ.has_key('SUGAR_ACTIVITY_ROOT') and \ if os.environ.has_key('SUGAR_ACTIVITY_ROOT') and \
@ -835,6 +851,7 @@ def get_activity_root():
else: else:
raise RuntimeError("No SUGAR_ACTIVITY_ROOT set.") raise RuntimeError("No SUGAR_ACTIVITY_ROOT set.")
def show_object_in_journal(object_id): def show_object_in_journal(object_id):
bus = dbus.SessionBus() bus = dbus.SessionBus()
obj = bus.get_object(J_DBUS_SERVICE, J_DBUS_PATH) obj = bus.get_object(J_DBUS_SERVICE, J_DBUS_PATH)

View File

@ -54,6 +54,8 @@ try:
MAXFD = os.sysconf("SC_OPEN_MAX") MAXFD = os.sysconf("SC_OPEN_MAX")
except ValueError: except ValueError:
MAXFD = 256 MAXFD = 256
def _close_fds(): def _close_fds():
for i in xrange(3, MAXFD): for i in xrange(3, MAXFD):
try: try:
@ -62,6 +64,7 @@ def _close_fds():
except Exception: except Exception:
pass pass
def create_activity_id(): def create_activity_id():
"""Generate a new, unique ID for this activity""" """Generate a new, unique ID for this activity"""
pservice = presenceservice.get_instance() pservice = presenceservice.get_instance()
@ -84,6 +87,7 @@ def create_activity_id():
return act_id return act_id
raise RuntimeError("Cannot generate unique activity id.") raise RuntimeError("Cannot generate unique activity id.")
def get_environment(activity): def get_environment(activity):
environ = os.environ.copy() environ = os.environ.copy()
@ -111,10 +115,12 @@ def get_environment(activity):
environ['PATH'] = bin_path + ':' + environ['PATH'] environ['PATH'] = bin_path + ':' + environ['PATH']
if activity.get_path().startswith(env.get_user_activities_path()): if activity.get_path().startswith(env.get_user_activities_path()):
environ['SUGAR_LOCALEDIR'] = os.path.join(activity.get_path(), 'locale') environ['SUGAR_LOCALEDIR'] = os.path.join(activity.get_path(),
'locale')
return environ return environ
def get_command(activity, activity_id=None, object_id=None, uri=None): def get_command(activity, activity_id=None, object_id=None, uri=None):
if not activity_id: if not activity_id:
activity_id = create_activity_id() activity_id = create_activity_id()
@ -140,6 +146,7 @@ def get_command(activity, activity_id=None, object_id=None, uri=None):
return command return command
def open_log_file(activity): def open_log_file(activity):
i = 1 i = 1
while True: while True:
@ -158,6 +165,7 @@ def open_log_file(activity):
else: else:
raise e raise e
class ActivityCreationHandler(gobject.GObject): class ActivityCreationHandler(gobject.GObject):
"""Sugar-side activity creation interface """Sugar-side activity creation interface
@ -250,7 +258,7 @@ class ActivityCreationHandler(gobject.GObject):
'-u', pwd.getpwuid(os.getuid()).pw_name, '-u', pwd.getpwuid(os.getuid()).pw_name,
'-i', environ['SUGAR_BUNDLE_ID'], '-i', environ['SUGAR_BUNDLE_ID'],
'-e', environment_dir, '-e', environment_dir,
'--' '--',
] + command ] + command
for key, value in environ.items(): for key, value in environ.items():
@ -310,25 +318,29 @@ class ActivityCreationHandler(gobject.GObject):
logging.error('Datastore find failed %s', err) logging.error('Datastore find failed %s', err)
self._launch_activity() self._launch_activity()
def create(bundle, activity_handle=None): def create(bundle, activity_handle=None):
"""Create a new activity from its name.""" """Create a new activity from its name."""
if not activity_handle: if not activity_handle:
activity_handle = ActivityHandle() activity_handle = ActivityHandle()
return ActivityCreationHandler(bundle, activity_handle) return ActivityCreationHandler(bundle, activity_handle)
def create_with_uri(bundle, uri): def create_with_uri(bundle, uri):
"""Create a new activity and pass the uri as handle.""" """Create a new activity and pass the uri as handle."""
activity_handle = ActivityHandle(uri=uri) activity_handle = ActivityHandle(uri=uri)
return ActivityCreationHandler(bundle, activity_handle) return ActivityCreationHandler(bundle, activity_handle)
def create_with_object_id(bundle, object_id): def create_with_object_id(bundle, object_id):
"""Create a new activity and pass the object id as handle.""" """Create a new activity and pass the object id as handle."""
activity_handle = ActivityHandle(object_id=object_id) activity_handle = ActivityHandle(object_id=object_id)
return ActivityCreationHandler(bundle, activity_handle) return ActivityCreationHandler(bundle, activity_handle)
def _child_watch_cb(pid, condition, user_data):
# FIXME we use standalone method here instead of ActivityCreationHandler's # FIXME we use standalone method here instead of ActivityCreationHandler's
# member to have workaround code, see #1123 # member to have workaround code, see #1123
def _child_watch_cb(pid, condition, user_data):
environment_dir, log_file = user_data environment_dir, log_file = user_data
if environment_dir is not None: if environment_dir is not None:
subprocess.call(['/bin/rm', '-rf', environment_dir]) subprocess.call(['/bin/rm', '-rf', environment_dir])

View File

@ -19,11 +19,11 @@
STABLE. STABLE.
""" """
class ActivityHandle(object): class ActivityHandle(object):
"""Data structure storing simple activity metadata""" """Data structure storing simple activity metadata"""
def __init__(
self, activity_id=None, object_id=None, uri=None def __init__(self, activity_id=None, object_id=None, uri=None):
):
"""Initialise the handle from activity_id """Initialise the handle from activity_id
activity_id -- unique id for the activity to be activity_id -- unique id for the activity to be
@ -60,11 +60,10 @@ class ActivityHandle(object):
return result return result
def create_from_dict(handle_dict): def create_from_dict(handle_dict):
"""Create a handle from a dictionary of parameters""" """Create a handle from a dictionary of parameters"""
result = ActivityHandle( result = ActivityHandle(handle_dict['activity_id'],
handle_dict['activity_id'],
object_id = handle_dict.get('object_id'), object_id = handle_dict.get('object_id'),
uri = handle_dict.get('uri'), uri = handle_dict.get('uri'))
)
return result return result

View File

@ -24,10 +24,12 @@ import logging
import dbus import dbus
import dbus.service import dbus.service
_ACTIVITY_SERVICE_NAME = "org.laptop.Activity" _ACTIVITY_SERVICE_NAME = "org.laptop.Activity"
_ACTIVITY_SERVICE_PATH = "/org/laptop/Activity" _ACTIVITY_SERVICE_PATH = "/org/laptop/Activity"
_ACTIVITY_INTERFACE = "org.laptop.Activity" _ACTIVITY_INTERFACE = "org.laptop.Activity"
class ActivityService(dbus.service.Object): class ActivityService(dbus.service.Object):
"""Base dbus service object that each Activity uses to export dbus methods. """Base dbus service object that each Activity uses to export dbus methods.
@ -51,7 +53,7 @@ class ActivityService(dbus.service.Object):
activity_id = activity.get_id() activity_id = activity.get_id()
service_name = _ACTIVITY_SERVICE_NAME + activity_id service_name = _ACTIVITY_SERVICE_NAME + activity_id
object_path = _ACTIVITY_SERVICE_PATH + "/" + activity_id object_path = _ACTIVITY_SERVICE_PATH + '/' + activity_id
bus = dbus.SessionBus() bus = dbus.SessionBus()
bus_name = dbus.service.BusName(service_name, bus=bus) bus_name = dbus.service.BusName(service_name, bus=bus)
@ -79,4 +81,3 @@ class ActivityService(dbus.service.Object):
self._activity.get_document_path(async_cb, async_err_cb) self._activity.get_document_path(async_cb, async_err_cb)
except Exception, e: except Exception, e:
async_err_cb(e) async_err_cb(e)

View File

@ -34,9 +34,11 @@ from fnmatch import fnmatch
from sugar import env from sugar import env
from sugar.bundle.activitybundle import ActivityBundle from sugar.bundle.activitybundle import ActivityBundle
IGNORE_DIRS = ['dist', '.git'] IGNORE_DIRS = ['dist', '.git']
IGNORE_FILES = ['.gitignore', 'MANIFEST', '*.pyc', '*~', '*.bak', 'pseudo.po'] IGNORE_FILES = ['.gitignore', 'MANIFEST', '*.pyc', '*~', '*.bak', 'pseudo.po']
def list_files(base_dir, ignore_dirs=None, ignore_files=None): def list_files(base_dir, ignore_dirs=None, ignore_files=None):
result = [] result = []
@ -58,7 +60,9 @@ def list_files(base_dir, ignore_dirs=None, ignore_files=None):
return result return result
class Config(object): class Config(object):
def __init__(self, source_dir=None, dist_dir = None, dist_name = None): def __init__(self, source_dir=None, dist_dir = None, dist_name = None):
self.source_dir = source_dir or os.getcwd() self.source_dir = source_dir or os.getcwd()
self.dist_dir = dist_dir or os.path.join(self.source_dir, 'dist') self.dist_dir = dist_dir or os.path.join(self.source_dir, 'dist')
@ -90,7 +94,9 @@ class Config(object):
self.xo_name = '%s-%d.xo' % (self.bundle_name, self.version) self.xo_name = '%s-%d.xo' % (self.bundle_name, self.version)
self.tar_name = '%s-%d.tar.bz2' % (self.bundle_name, self.version) self.tar_name = '%s-%d.tar.bz2' % (self.bundle_name, self.version)
class Builder(object): class Builder(object):
def __init__(self, config): def __init__(self, config):
self.config = config self.config = config
@ -167,7 +173,9 @@ class Builder(object):
for line in manifest: for line in manifest:
f.write(line + "\n") f.write(line + "\n")
class Packager(object): class Packager(object):
def __init__(self, config): def __init__(self, config):
self.config = config self.config = config
self.package_path = None self.package_path = None
@ -175,7 +183,9 @@ class Packager(object):
if not os.path.exists(self.config.dist_dir): if not os.path.exists(self.config.dist_dir):
os.mkdir(self.config.dist_dir) os.mkdir(self.config.dist_dir)
class XOPackager(Packager): class XOPackager(Packager):
def __init__(self, builder): def __init__(self, builder):
Packager.__init__(self, builder.config) Packager.__init__(self, builder.config)
@ -200,7 +210,9 @@ class XOPackager(Packager):
bundle_zip.close() bundle_zip.close()
class SourcePackager(Packager): class SourcePackager(Packager):
def __init__(self, config): def __init__(self, config):
Packager.__init__(self, config) Packager.__init__(self, config)
self.package_path = os.path.join(self.config.dist_dir, self.package_path = os.path.join(self.config.dist_dir,
@ -224,6 +236,7 @@ class SourcePackager(Packager):
os.path.join(self.config.tar_root_dir, f)) os.path.join(self.config.tar_root_dir, f))
tar.close() tar.close()
class Installer(object): class Installer(object):
IGNORES = ['po/*', 'MANIFEST', 'AUTHORS'] IGNORES = ['po/*', 'MANIFEST', 'AUTHORS']
@ -261,6 +274,7 @@ class Installer(object):
shutil.copy(source, dest) shutil.copy(source, dest)
def cmd_dev(config, args): def cmd_dev(config, args):
'''Setup for development''' '''Setup for development'''
@ -280,6 +294,7 @@ def cmd_dev(config, args):
else: else:
print 'ERROR - A bundle with the same name is already installed.' print 'ERROR - A bundle with the same name is already installed.'
def cmd_dist_xo(config, args): def cmd_dist_xo(config, args):
'''Create a xo bundle package''' '''Create a xo bundle package'''
@ -290,6 +305,7 @@ def cmd_dist_xo(config, args):
packager = XOPackager(Builder(config)) packager = XOPackager(Builder(config))
packager.package() packager.package()
def cmd_fix_manifest(config, args): def cmd_fix_manifest(config, args):
'''Add missing files to the manifest''' '''Add missing files to the manifest'''
@ -300,6 +316,7 @@ def cmd_fix_manifest(config, args):
builder = Builder(config) builder = Builder(config)
builder.fix_manifest() builder.fix_manifest()
def cmd_dist_source(config, args): def cmd_dist_source(config, args):
'''Create a tar source package''' '''Create a tar source package'''
@ -310,6 +327,7 @@ def cmd_dist_source(config, args):
packager = SourcePackager(config) packager = SourcePackager(config)
packager.package() packager.package()
def cmd_install(config, args): def cmd_install(config, args):
'''Install the activity in the system''' '''Install the activity in the system'''
@ -324,6 +342,7 @@ def cmd_install(config, args):
installer = Installer(Builder(config)) installer = Installer(Builder(config))
installer.install(suboptions.prefix) installer.install(suboptions.prefix)
def cmd_genpot(config, args): def cmd_genpot(config, args):
'''Generate the gettext pot file''' '''Generate the gettext pot file'''
@ -362,6 +381,7 @@ def cmd_genpot(config, args):
if retcode: if retcode:
print 'ERROR - xgettext failed with return code %i.' % retcode print 'ERROR - xgettext failed with return code %i.' % retcode
def cmd_build(config, args): def cmd_build(config, args):
'''Build generated files''' '''Build generated files'''
@ -372,6 +392,7 @@ def cmd_build(config, args):
builder = Builder(config) builder = Builder(config)
builder.build() builder.build()
def print_commands(): def print_commands():
print 'Available commands:\n' print 'Available commands:\n'
@ -382,6 +403,7 @@ def print_commands():
print '\n(Type "./setup.py <command> --help" for help about a ' \ print '\n(Type "./setup.py <command> --help" for help about a ' \
'particular command\'s options.' 'particular command\'s options.'
def start(bundle_name=None): def start(bundle_name=None):
if bundle_name: if bundle_name:
logging.warn("bundle_name deprecated, now comes from activity.info") logging.warn("bundle_name deprecated, now comes from activity.info")
@ -397,5 +419,6 @@ def start(bundle_name=None):
except (KeyError, IndexError): except (KeyError, IndexError):
print_commands() print_commands()
if __name__ == '__main__': if __name__ == '__main__':
start() start()

View File

@ -30,17 +30,22 @@ from sugar.activity import activityhandle
from sugar.bundle.activitybundle import ActivityBundle from sugar.bundle.activitybundle import ActivityBundle
from sugar import logger from sugar import logger
def create_activity_instance(constructor, handle): def create_activity_instance(constructor, handle):
activity = constructor(handle) activity = constructor(handle)
activity.show() activity.show()
def get_single_process_name(bundle_id): def get_single_process_name(bundle_id):
return bundle_id return bundle_id
def get_single_process_path(bundle_id): def get_single_process_path(bundle_id):
return '/' + bundle_id.replace('.', '/') return '/' + bundle_id.replace('.', '/')
class SingleProcess(dbus.service.Object): class SingleProcess(dbus.service.Object):
def __init__(self, name_service, constructor): def __init__(self, name_service, constructor):
self.constructor = constructor self.constructor = constructor
@ -54,6 +59,7 @@ class SingleProcess(dbus.service.Object):
handle = activityhandle.create_from_dict(handle_dict) handle = activityhandle.create_from_dict(handle_dict)
create_activity_instance(self.constructor, handle) create_activity_instance(self.constructor, handle)
def main(): def main():
parser = OptionParser() parser = OptionParser()
parser.add_option("-b", "--bundle-id", dest="bundle_id", parser.add_option("-b", "--bundle-id", dest="bundle_id",

View File

@ -35,8 +35,10 @@ from sugar.graphics.canvastextview import CanvasTextView
from sugar.bundle.activitybundle import ActivityBundle from sugar.bundle.activitybundle import ActivityBundle
_ = lambda msg: gettext.dgettext('sugar-toolkit', msg) _ = lambda msg: gettext.dgettext('sugar-toolkit', msg)
def _get_icon_name(metadata): def _get_icon_name(metadata):
file_name = None file_name = None
@ -53,16 +55,17 @@ def _get_icon_name(metadata):
return file_name return file_name
class NamingToolbar(gtk.Toolbar): class NamingToolbar(gtk.Toolbar):
""" Toolbar of the naming alert """ Toolbar of the naming alert
""" """
__gtype_name__ = 'SugarNamingToolbar' __gtype_name__ = 'SugarNamingToolbar'
__gsignals__ = { __gsignals__ = {
'keep-clicked': (gobject.SIGNAL_RUN_FIRST, 'keep-clicked': (gobject.SIGNAL_RUN_FIRST, gobject.TYPE_NONE, ([])),
gobject.TYPE_NONE,
([]))
} }
def __init__(self): def __init__(self):
gtk.Toolbar.__init__(self) gtk.Toolbar.__init__(self)
@ -110,7 +113,9 @@ class NamingToolbar(gtk.Toolbar):
def __keep_button_clicked_cb(self, widget, data=None): def __keep_button_clicked_cb(self, widget, data=None):
self.emit('keep-clicked') self.emit('keep-clicked')
class FavoriteIcon(CanvasIcon): class FavoriteIcon(CanvasIcon):
def __init__(self, favorite): def __init__(self, favorite):
CanvasIcon.__init__(self, icon_name='emblem-favorite', CanvasIcon.__init__(self, icon_name='emblem-favorite',
box_width=style.GRID_CELL_SIZE * 3 / 5, box_width=style.GRID_CELL_SIZE * 3 / 5,
@ -149,7 +154,9 @@ class FavoriteIcon(CanvasIcon):
elif event.detail == hippo.MOTION_DETAIL_LEAVE: elif event.detail == hippo.MOTION_DETAIL_LEAVE:
icon.props.fill_color = style.COLOR_TRANSPARENT.get_svg() icon.props.fill_color = style.COLOR_TRANSPARENT.get_svg()
class NamingAlert(gtk.Window): class NamingAlert(gtk.Window):
__gtype_name__ = 'SugarNamingAlert' __gtype_name__ = 'SugarNamingAlert'
def __init__(self, activity, bundle_path): def __init__(self, activity, bundle_path):
@ -212,7 +219,8 @@ class NamingAlert(gtk.Window):
spacing=style.DEFAULT_SPACING) spacing=style.DEFAULT_SPACING)
body.append(header) body.append(header)
descriptions = hippo.CanvasBox(orientation=hippo.ORIENTATION_HORIZONTAL, descriptions = hippo.CanvasBox(
orientation=hippo.ORIENTATION_HORIZONTAL,
spacing=style.DEFAULT_SPACING * 3, spacing=style.DEFAULT_SPACING * 3,
padding_left=style.GRID_CELL_SIZE, padding_left=style.GRID_CELL_SIZE,
padding_right=style.GRID_CELL_SIZE, padding_right=style.GRID_CELL_SIZE,

View File

@ -29,6 +29,7 @@ from sugar.graphics.xocolor import XoColor
from sugar.graphics.icon import Icon from sugar.graphics.icon import Icon
from sugar.bundle.activitybundle import ActivityBundle from sugar.bundle.activitybundle import ActivityBundle
_ = lambda msg: gettext.dgettext('sugar-toolkit', msg) _ = lambda msg: gettext.dgettext('sugar-toolkit', msg)
@ -41,7 +42,9 @@ def _create_activity_icon():
icon = Icon(file=bundle.get_icon(), xo_color=color) icon = Icon(file=bundle.get_icon(), xo_color=color)
return icon return icon
class ActivityButton(ToolButton): class ActivityButton(ToolButton):
def __init__(self, activity, **kwargs): def __init__(self, activity, **kwargs):
ToolButton.__init__(self, **kwargs) ToolButton.__init__(self, **kwargs)
@ -55,7 +58,9 @@ class ActivityButton(ToolButton):
def __jobject_updated_cb(self, jobject): def __jobject_updated_cb(self, jobject):
self.props.tooltip = jobject['title'] self.props.tooltip = jobject['title']
class ActivityToolbarButton(ToolbarButton): class ActivityToolbarButton(ToolbarButton):
def __init__(self, activity, **kwargs): def __init__(self, activity, **kwargs):
toolbar = ActivityToolbar(activity, orientation_left=True) toolbar = ActivityToolbar(activity, orientation_left=True)
toolbar.stop.hide() toolbar.stop.hide()
@ -66,7 +71,9 @@ class ActivityToolbarButton(ToolbarButton):
self.set_icon_widget(icon) self.set_icon_widget(icon)
icon.show() icon.show()
class StopButton(ToolButton): class StopButton(ToolButton):
def __init__(self, activity, **kwargs): def __init__(self, activity, **kwargs):
ToolButton.__init__(self, 'activity-stop', **kwargs) ToolButton.__init__(self, 'activity-stop', **kwargs)
self.props.tooltip = _('Stop') self.props.tooltip = _('Stop')
@ -76,28 +83,38 @@ class StopButton(ToolButton):
def __stop_button_clicked_cb(self, button, activity): def __stop_button_clicked_cb(self, button, activity):
activity.close() activity.close()
class UndoButton(ToolButton): class UndoButton(ToolButton):
def __init__(self, **kwargs): def __init__(self, **kwargs):
ToolButton.__init__(self, 'edit-undo', **kwargs) ToolButton.__init__(self, 'edit-undo', **kwargs)
self.props.tooltip = _('Undo') self.props.tooltip = _('Undo')
self.props.accelerator = '<Ctrl>Q' self.props.accelerator = '<Ctrl>Q'
class RedoButton(ToolButton): class RedoButton(ToolButton):
def __init__(self, **kwargs): def __init__(self, **kwargs):
ToolButton.__init__(self, 'edit-redo', **kwargs) ToolButton.__init__(self, 'edit-redo', **kwargs)
self.props.tooltip = _('Redo') self.props.tooltip = _('Redo')
class CopyButton(ToolButton): class CopyButton(ToolButton):
def __init__(self, **kwargs): def __init__(self, **kwargs):
ToolButton.__init__(self, 'edit-copy', **kwargs) ToolButton.__init__(self, 'edit-copy', **kwargs)
self.props.tooltip = _('Copy') self.props.tooltip = _('Copy')
class PasteButton(ToolButton): class PasteButton(ToolButton):
def __init__(self, **kwargs): def __init__(self, **kwargs):
ToolButton.__init__(self, 'edit-paste', **kwargs) ToolButton.__init__(self, 'edit-paste', **kwargs)
self.props.tooltip = _('Paste') self.props.tooltip = _('Paste')
class ShareButton(RadioMenuButton): class ShareButton(RadioMenuButton):
def __init__(self, activity, **kwargs): def __init__(self, activity, **kwargs):
palette = RadioPalette() palette = RadioPalette()
@ -137,7 +154,9 @@ class ShareButton(RadioMenuButton):
finally: finally:
self.neighborhood.handler_unblock(self._neighborhood_handle) self.neighborhood.handler_unblock(self._neighborhood_handle)
class KeepButton(ToolButton): class KeepButton(ToolButton):
def __init__(self, activity, **kwargs): def __init__(self, activity, **kwargs):
ToolButton.__init__(self, **kwargs) ToolButton.__init__(self, **kwargs)
self.props.tooltip = _('Keep') self.props.tooltip = _('Keep')
@ -154,7 +173,9 @@ class KeepButton(ToolButton):
def __keep_button_clicked_cb(self, button, activity): def __keep_button_clicked_cb(self, button, activity):
activity.copy() activity.copy()
class TitleEntry(gtk.ToolItem): class TitleEntry(gtk.ToolItem):
def __init__(self, activity, **kwargs): def __init__(self, activity, **kwargs):
gtk.ToolItem.__init__(self) gtk.ToolItem.__init__(self)
self.set_expand(False) self.set_expand(False)
@ -195,6 +216,7 @@ class TitleEntry(gtk.ToolItem):
self._update_title_sid = None self._update_title_sid = None
return False return False
class ActivityToolbar(gtk.Toolbar): class ActivityToolbar(gtk.Toolbar):
"""The Activity toolbar with the Journal entry title, sharing, """The Activity toolbar with the Journal entry title, sharing,
Keep and Stop buttons Keep and Stop buttons
@ -202,6 +224,7 @@ class ActivityToolbar(gtk.Toolbar):
All activities should have this toolbar. It is easiest to add it to your All activities should have this toolbar. It is easiest to add it to your
Activity by using the ActivityToolbox. Activity by using the ActivityToolbox.
""" """
def __init__(self, activity, orientation_left=False): def __init__(self, activity, orientation_left=False):
gtk.Toolbar.__init__(self) gtk.Toolbar.__init__(self)
@ -232,6 +255,7 @@ class ActivityToolbar(gtk.Toolbar):
self.insert(self.stop, -1) self.insert(self.stop, -1)
self.stop.show() self.stop.show()
class EditToolbar(gtk.Toolbar): class EditToolbar(gtk.Toolbar):
"""Provides the standard edit toolbar for Activities. """Provides the standard edit toolbar for Activities.
@ -265,6 +289,7 @@ class EditToolbar(gtk.Toolbar):
# And make it visible: # And make it visible:
self._edit_toolbar.show() self._edit_toolbar.show()
""" """
def __init__(self): def __init__(self):
gtk.Toolbar.__init__(self) gtk.Toolbar.__init__(self)
@ -289,6 +314,7 @@ class EditToolbar(gtk.Toolbar):
self.insert(self.paste, -1) self.insert(self.paste, -1)
self.paste.show() self.paste.show()
class ActivityToolbox(Toolbox): class ActivityToolbox(Toolbox):
"""Creates the Toolbox for the Activity """Creates the Toolbox for the Activity
@ -307,6 +333,7 @@ class ActivityToolbox(Toolbox):
# And make it visible: # And make it visible:
toolbox.show() toolbox.show()
""" """
def __init__(self, activity): def __init__(self, activity):
Toolbox.__init__(self) Toolbox.__init__(self)

View File

@ -31,6 +31,7 @@ from sugar import util
from sugar.bundle.bundle import Bundle, \ from sugar.bundle.bundle import Bundle, \
MalformedBundleException, NotInstalledException MalformedBundleException, NotInstalledException
class ActivityBundle(Bundle): class ActivityBundle(Bundle):
"""A Sugar activity bundle """A Sugar activity bundle
@ -89,8 +90,8 @@ class ActivityBundle(Bundle):
return ret return ret
def _read_manifest(self): def _read_manifest(self):
"""return a list with the lines in MANIFEST, with invalid lines replaced """return a list with the lines in MANIFEST, with invalid lines
by empty lines. replaced by empty lines.
Since absolute order carries information on file history, it should Since absolute order carries information on file history, it should
be preserved. For instance, when renaming a file, you should leave be preserved. For instance, when renaming a file, you should leave
@ -251,10 +252,10 @@ class ActivityBundle(Bundle):
"""Get the activity bundle id""" """Get the activity bundle id"""
return self._bundle_id return self._bundle_id
# FIXME: this should return the icon data, not a filename, so that
# we don't need to create a temp file in the zip case
def get_icon(self): def get_icon(self):
"""Get the activity icon name""" """Get the activity icon name"""
# FIXME: this should return the icon data, not a filename, so that
# we don't need to create a temp file in the zip case
icon_path = os.path.join('activity', self._icon + '.svg') icon_path = os.path.join('activity', self._icon + '.svg')
if self._zip_file is None: if self._zip_file is None:
return os.path.join(self._path, icon_path) return os.path.join(self._path, icon_path)

View File

@ -26,24 +26,31 @@ import shutil
import StringIO import StringIO
import zipfile import zipfile
class AlreadyInstalledException(Exception): class AlreadyInstalledException(Exception):
pass pass
class NotInstalledException(Exception): class NotInstalledException(Exception):
pass pass
class InvalidPathException(Exception): class InvalidPathException(Exception):
pass pass
class ZipExtractException(Exception): class ZipExtractException(Exception):
pass pass
class RegistrationException(Exception): class RegistrationException(Exception):
pass pass
class MalformedBundleException(Exception): class MalformedBundleException(Exception):
pass pass
class Bundle(object): class Bundle(object):
"""A Sugar activity, content module, etc. """A Sugar activity, content module, etc.
@ -71,7 +78,7 @@ class Bundle(object):
# manifest = self._get_file(self._infodir + '/contents') # manifest = self._get_file(self._infodir + '/contents')
# if manifest is None: # if manifest is None:
# raise MalformedBundleException('No manifest file') # raise MalformedBundleException('No manifest file')
#
# signature = self._get_file(self._infodir + '/contents.sig') # signature = self._get_file(self._infodir + '/contents.sig')
# if signature is None: # if signature is None:
# raise MalformedBundleException('No signature file') # raise MalformedBundleException('No signature file')

View File

@ -29,6 +29,7 @@ from sugar import env
from sugar.bundle.bundle import Bundle, NotInstalledException, \ from sugar.bundle.bundle import Bundle, NotInstalledException, \
MalformedBundleException MalformedBundleException
class ContentBundle(Bundle): class ContentBundle(Bundle):
"""A Sugar content bundle """A Sugar content bundle
@ -78,8 +79,8 @@ class ContentBundle(Bundle):
try: try:
if int(version) != 1: if int(version) != 1:
raise MalformedBundleException( raise MalformedBundleException(
'Content bundle %s has unknown host_version number %s' % 'Content bundle %s has unknown host_version '
(self._path, version)) 'number %s' % (self._path, version))
except ValueError: except ValueError:
raise MalformedBundleException( raise MalformedBundleException(
'Content bundle %s has invalid host_version number %s' % 'Content bundle %s has invalid host_version number %s' %
@ -209,17 +210,17 @@ class ContentBundle(Bundle):
def get_start_uri(self): def get_start_uri(self):
return "file://" + urllib.pathname2url(self.get_start_path()) return "file://" + urllib.pathname2url(self.get_start_path())
def get_bundle_id(self):
# TODO treat ContentBundle in special way # TODO treat ContentBundle in special way
# needs rethinking while fixing ContentBundle support # needs rethinking while fixing ContentBundle support
def get_bundle_id(self):
if self._bundle_class is not None: if self._bundle_class is not None:
return self._bundle_class return self._bundle_class
else: else:
return self._global_name return self._global_name
def get_activity_version(self):
# TODO treat ContentBundle in special way # TODO treat ContentBundle in special way
# needs rethinking while fixing ContentBundle support # needs rethinking while fixing ContentBundle support
def get_activity_version(self):
return self._library_version return self._library_version
def is_installed(self): def is_installed(self):

View File

@ -29,10 +29,10 @@ import gobject
from sugar.datastore import dbus_helpers from sugar.datastore import dbus_helpers
from sugar import mime from sugar import mime
class DSMetadata(gobject.GObject): class DSMetadata(gobject.GObject):
__gsignals__ = { __gsignals__ = {
'updated': (gobject.SIGNAL_RUN_FIRST, gobject.TYPE_NONE, 'updated': (gobject.SIGNAL_RUN_FIRST, gobject.TYPE_NONE, ([])),
([]))
} }
def __init__(self, props=None): def __init__(self, props=None):
@ -80,7 +80,9 @@ class DSMetadata(gobject.GObject):
else: else:
return default return default
class DSObject(object): class DSObject(object):
def __init__(self, object_id, metadata=None, file_path=None): def __init__(self, object_id, metadata=None, file_path=None):
self.object_id = object_id self.object_id = object_id
self._metadata = metadata self._metadata = metadata
@ -129,13 +131,14 @@ class DSObject(object):
def __del__(self): def __del__(self):
if not self._destroyed: if not self._destroyed:
logging.warning('DSObject was deleted without cleaning up first. ' \ logging.warning('DSObject was deleted without cleaning up first. '
'Call DSObject.destroy() before disposing it.') 'Call DSObject.destroy() before disposing it.')
self.destroy() self.destroy()
def copy(self): def copy(self):
return DSObject(None, self._metadata.copy(), self._file_path) return DSObject(None, self._metadata.copy(), self._file_path)
def get(object_id): def get(object_id):
logging.debug('datastore.get') logging.debug('datastore.get')
metadata = dbus_helpers.get_properties(object_id) metadata = dbus_helpers.get_properties(object_id)
@ -144,12 +147,14 @@ def get(object_id):
# TODO: register the object for updates # TODO: register the object for updates
return ds_object return ds_object
def create(): def create():
metadata = DSMetadata() metadata = DSMetadata()
metadata['mtime'] = datetime.now().isoformat() metadata['mtime'] = datetime.now().isoformat()
metadata['timestamp'] = int(time.time()) metadata['timestamp'] = int(time.time())
return DSObject(object_id=None, metadata=metadata, file_path=None) return DSObject(object_id=None, metadata=metadata, file_path=None)
def write(ds_object, update_mtime=True, transfer_ownership=False, def write(ds_object, update_mtime=True, transfer_ownership=False,
reply_handler=None, error_handler=None, timeout=-1): reply_handler=None, error_handler=None, timeout=-1):
logging.debug('datastore.write') logging.debug('datastore.write')
@ -185,10 +190,12 @@ def write(ds_object, update_mtime=True, transfer_ownership=False,
# TODO: register the object for updates # TODO: register the object for updates
logging.debug('Written object %s to the datastore.', ds_object.object_id) logging.debug('Written object %s to the datastore.', ds_object.object_id)
def delete(object_id): def delete(object_id):
logging.debug('datastore.delete') logging.debug('datastore.delete')
dbus_helpers.delete(object_id) dbus_helpers.delete(object_id)
def find(query, sorting=None, limit=None, offset=None, properties=None, def find(query, sorting=None, limit=None, offset=None, properties=None,
reply_handler=None, error_handler=None): reply_handler=None, error_handler=None):
@ -217,6 +224,7 @@ def find(query, sorting=None, limit=None, offset=None, properties=None,
return objects, total_count return objects, total_count
def copy(jobject, mount_point): def copy(jobject, mount_point):
new_jobject = jobject.copy() new_jobject = jobject.copy()
@ -238,17 +246,22 @@ def copy(jobject, mount_point):
write(new_jobject) write(new_jobject)
def mount(uri, options, timeout=-1): def mount(uri, options, timeout=-1):
return dbus_helpers.mount(uri, options, timeout=timeout) return dbus_helpers.mount(uri, options, timeout=timeout)
def unmount(mount_point_id): def unmount(mount_point_id):
dbus_helpers.unmount(mount_point_id) dbus_helpers.unmount(mount_point_id)
def mounts(): def mounts():
return dbus_helpers.mounts() return dbus_helpers.mounts()
def complete_indexing(): def complete_indexing():
return dbus_helpers.complete_indexing() return dbus_helpers.complete_indexing()
def get_unique_values(key): def get_unique_values(key):
return dbus_helpers.get_unique_values(key) return dbus_helpers.get_unique_values(key)

View File

@ -31,6 +31,7 @@ DS_DBUS_PATH = "/org/laptop/sugar/DataStore"
_data_store = None _data_store = None
def _get_data_store(): def _get_data_store():
global _data_store global _data_store
@ -41,12 +42,14 @@ def _get_data_store():
DS_DBUS_INTERFACE) DS_DBUS_INTERFACE)
return _data_store return _data_store
def create(properties, filename, transfer_ownership=False): def create(properties, filename, transfer_ownership=False):
object_id = _get_data_store().create(dbus.Dictionary(properties), filename, object_id = _get_data_store().create(dbus.Dictionary(properties), filename,
transfer_ownership) transfer_ownership)
logging.debug('dbus_helpers.create: ' + object_id) logging.debug('dbus_helpers.create: ' + object_id)
return object_id return object_id
def update(uid, properties, filename, transfer_ownership=False, def update(uid, properties, filename, transfer_ownership=False,
reply_handler=None, error_handler=None, timeout=-1): reply_handler=None, error_handler=None, timeout=-1):
debug_props = properties.copy() debug_props = properties.copy()
@ -64,19 +67,23 @@ def update(uid, properties, filename, transfer_ownership=False,
_get_data_store().update(uid, dbus.Dictionary(properties), _get_data_store().update(uid, dbus.Dictionary(properties),
filename, transfer_ownership) filename, transfer_ownership)
def delete(uid): def delete(uid):
logging.debug('dbus_helpers.delete: %r', uid) logging.debug('dbus_helpers.delete: %r', uid)
_get_data_store().delete(uid) _get_data_store().delete(uid)
def get_properties(uid): def get_properties(uid):
logging.debug('dbus_helpers.get_properties: %s', uid) logging.debug('dbus_helpers.get_properties: %s', uid)
return _get_data_store().get_properties(uid, byte_arrays=True) return _get_data_store().get_properties(uid, byte_arrays=True)
def get_filename(uid): def get_filename(uid):
filename = _get_data_store().get_filename(uid) filename = _get_data_store().get_filename(uid)
logging.debug('dbus_helpers.get_filename: %s, %s', uid, filename) logging.debug('dbus_helpers.get_filename: %s, %s', uid, filename)
return filename return filename
def find(query, properties, reply_handler, error_handler): def find(query, properties, reply_handler, error_handler):
logging.debug('dbus_helpers.find: %r %r', query, properties) logging.debug('dbus_helpers.find: %r %r', query, properties)
if reply_handler and error_handler: if reply_handler and error_handler:
@ -86,19 +93,23 @@ def find(query, properties, reply_handler, error_handler):
else: else:
return _get_data_store().find(query, properties, byte_arrays=True) return _get_data_store().find(query, properties, byte_arrays=True)
def mount(uri, options, timeout=-1): def mount(uri, options, timeout=-1):
return _get_data_store().mount(uri, options, timeout=timeout) return _get_data_store().mount(uri, options, timeout=timeout)
def unmount(mount_point_id): def unmount(mount_point_id):
_get_data_store().unmount(mount_point_id) _get_data_store().unmount(mount_point_id)
def mounts(): def mounts():
return _get_data_store().mounts() return _get_data_store().mounts()
def get_unique_values(key): def get_unique_values(key):
return _get_data_store().get_uniquevaluesfor( return _get_data_store().get_uniquevaluesfor(
key, dbus.Dictionary({}, signature='ss')) key, dbus.Dictionary({}, signature='ss'))
def complete_indexing(): def complete_indexing():
return _get_data_store().complete_indexing() return _get_data_store().complete_indexing()

View File

@ -22,12 +22,14 @@ STABLE.
import os import os
def is_emulator(): def is_emulator():
if os.environ.has_key('SUGAR_EMULATOR'): if os.environ.has_key('SUGAR_EMULATOR'):
if os.environ['SUGAR_EMULATOR'] == 'yes': if os.environ['SUGAR_EMULATOR'] == 'yes':
return True return True
return False return False
def get_profile_path(path=None): def get_profile_path(path=None):
if os.environ.has_key('SUGAR_PROFILE'): if os.environ.has_key('SUGAR_PROFILE'):
profile_id = os.environ['SUGAR_PROFILE'] profile_id = os.environ['SUGAR_PROFILE']
@ -46,6 +48,7 @@ def get_profile_path(path=None):
else: else:
return base return base
def get_logs_path(path=None): def get_logs_path(path=None):
base = os.environ.get('SUGAR_LOGS_DIR', get_profile_path('logs')) base = os.environ.get('SUGAR_LOGS_DIR', get_profile_path('logs'))
if path != None: if path != None:
@ -53,8 +56,10 @@ def get_logs_path(path=None):
else: else:
return base return base
def get_user_activities_path(): def get_user_activities_path():
return os.path.expanduser('~/Activities') return os.path.expanduser('~/Activities')
def get_user_library_path(): def get_user_library_path():
return os.path.expanduser('~/Library') return os.path.expanduser('~/Library')

View File

@ -54,8 +54,10 @@ import math
from sugar.graphics import style from sugar.graphics import style
from sugar.graphics.icon import Icon from sugar.graphics.icon import Icon
_ = lambda msg: gettext.dgettext('sugar-toolkit', msg) _ = lambda msg: gettext.dgettext('sugar-toolkit', msg)
class Alert(gtk.EventBox): class Alert(gtk.EventBox):
""" """
UI interface for Alerts UI interface for Alerts
@ -78,17 +80,13 @@ class Alert(gtk.EventBox):
__gtype_name__ = 'SugarAlert' __gtype_name__ = 'SugarAlert'
__gsignals__ = { __gsignals__ = {
'response': (gobject.SIGNAL_RUN_FIRST, 'response': (gobject.SIGNAL_RUN_FIRST, gobject.TYPE_NONE, ([object])),
gobject.TYPE_NONE, ([object]))
} }
__gproperties__ = { __gproperties__ = {
'title' : (str, None, None, None, 'title': (str, None, None, None, gobject.PARAM_READWRITE),
gobject.PARAM_READWRITE), 'msg': (str, None, None, None, gobject.PARAM_READWRITE),
'msg' : (str, None, None, None, 'icon': (object, None, None, gobject.PARAM_WRITABLE),
gobject.PARAM_READWRITE),
'icon' : (object, None, None,
gobject.PARAM_WRITABLE)
} }
def __init__(self, **kwargs): def __init__(self, **kwargs):

View File

@ -26,10 +26,11 @@ import gobject
EASE_OUT_EXPO = 0 EASE_OUT_EXPO = 0
EASE_IN_EXPO = 1 EASE_IN_EXPO = 1
class Animator(gobject.GObject): class Animator(gobject.GObject):
__gsignals__ = { __gsignals__ = {
'completed': (gobject.SIGNAL_RUN_FIRST, 'completed': (gobject.SIGNAL_RUN_FIRST, gobject.TYPE_NONE, ([])),
gobject.TYPE_NONE, ([])),
} }
def __init__(self, duration, fps=20, easing=EASE_OUT_EXPO): def __init__(self, duration, fps=20, easing=EASE_OUT_EXPO):
@ -111,7 +112,9 @@ class Animator(gobject.GObject):
else: else:
return True return True
class Animation(object): class Animation(object):
def __init__(self, start, end): def __init__(self, start, end):
self.start = start self.start = start
self.end = end self.end = end

View File

@ -20,7 +20,9 @@ import hippo
from sugar.graphics import style from sugar.graphics import style
class CanvasTextView(hippo.CanvasWidget): class CanvasTextView(hippo.CanvasWidget):
def __init__(self, text, **kwargs): def __init__(self, text, **kwargs):
hippo.CanvasWidget.__init__(self, **kwargs) hippo.CanvasWidget.__init__(self, **kwargs)
self.text_view_widget = gtk.TextView() self.text_view_widget = gtk.TextView()

View File

@ -26,12 +26,15 @@ from sugar.graphics import style
from sugar.graphics.icon import Icon from sugar.graphics.icon import Icon
from sugar.graphics.palette import Palette, ToolInvoker, WidgetInvoker from sugar.graphics.palette import Palette, ToolInvoker, WidgetInvoker
_ = lambda msg: gettext.dgettext('sugar-toolkit', msg) _ = lambda msg: gettext.dgettext('sugar-toolkit', msg)
def get_svg_color_string(color): def get_svg_color_string(color):
return '#%.2X%.2X%.2X' % (color.red / 257, color.green / 257, return '#%.2X%.2X%.2X' % (color.red / 257, color.green / 257,
color.blue / 257) color.blue / 257)
class _ColorButton(gtk.Button): class _ColorButton(gtk.Button):
"""This is a ColorButton for Sugar. It is similar to the gtk.ColorButton, """This is a ColorButton for Sugar. It is similar to the gtk.ColorButton,
but does not have any alpha support. but does not have any alpha support.
@ -86,7 +89,8 @@ class _ColorButton(gtk.Button):
self._palette = _ColorPalette(color=self._color, self._palette = _ColorPalette(color=self._color,
primary_text=self._title) primary_text=self._title)
self._palette.connect('color-set', self.__palette_color_set_cb) self._palette.connect('color-set', self.__palette_color_set_cb)
self._palette.connect('notify::color', self.__palette_color_changed) self._palette.connect('notify::color', self.
__palette_color_changed)
return self._palette return self._palette
@ -192,8 +196,8 @@ class _ColorButton(gtk.Button):
getter=_get_accept_drag, getter=_get_accept_drag,
setter=_set_accept_drag) setter=_set_accept_drag)
# Drag and Drop
def __drag_begin_cb(self, widget, context): def __drag_begin_cb(self, widget, context):
# Drag and Drop
pixbuf = gtk.gdk.Pixbuf(gtk.gdk.COLORSPACE_RGB, True, 8, pixbuf = gtk.gdk.Pixbuf(gtk.gdk.COLORSPACE_RGB, True, 8,
style.SMALL_ICON_SIZE, style.SMALL_ICON_SIZE,
style.SMALL_ICON_SIZE) style.SMALL_ICON_SIZE)
@ -235,6 +239,7 @@ class _ColorPalette(Palette):
_BLUE = 2 _BLUE = 2
__gtype_name__ = 'SugarColorPalette' __gtype_name__ = 'SugarColorPalette'
# The color-set signal is emitted when the user is finished selecting # The color-set signal is emitted when the user is finished selecting
# a color. # a color.
__gsignals__ = {'color-set': (gobject.SIGNAL_RUN_FIRST, gobject.TYPE_NONE, __gsignals__ = {'color-set': (gobject.SIGNAL_RUN_FIRST, gobject.TYPE_NONE,
@ -300,8 +305,6 @@ class _ColorPalette(Palette):
return scale return scale
def _build_swatches(self): def _build_swatches(self):
for child in self._swatch_tray.get_children(): for child in self._swatch_tray.get_children():
child.destroy() child.destroy()
@ -384,7 +387,6 @@ class _ColorPalette(Palette):
color = gobject.property(type=object, getter=get_color, setter=set_color) color = gobject.property(type=object, getter=get_color, setter=set_color)
def _add_accelerator(tool_button): def _add_accelerator(tool_button):
if not tool_button.props.accelerator or not tool_button.get_toplevel() or \ if not tool_button.props.accelerator or not tool_button.get_toplevel() or \
not tool_button.child: not tool_button.child:
@ -403,17 +405,21 @@ def _add_accelerator(tool_button):
tool_button.child.add_accelerator('clicked', accel_group, keyval, mask, tool_button.child.add_accelerator('clicked', accel_group, keyval, mask,
gtk.ACCEL_LOCKED | gtk.ACCEL_VISIBLE) gtk.ACCEL_LOCKED | gtk.ACCEL_VISIBLE)
def _hierarchy_changed_cb(tool_button, previous_toplevel): def _hierarchy_changed_cb(tool_button, previous_toplevel):
_add_accelerator(tool_button) _add_accelerator(tool_button)
def setup_accelerator(tool_button): def setup_accelerator(tool_button):
_add_accelerator(tool_button) _add_accelerator(tool_button)
tool_button.connect('hierarchy-changed', _hierarchy_changed_cb) tool_button.connect('hierarchy-changed', _hierarchy_changed_cb)
class ColorToolButton(gtk.ToolItem):
# This not ideal. It would be better to subclass gtk.ToolButton, however # This not ideal. It would be better to subclass gtk.ToolButton, however
# the python bindings do not seem to be powerfull enough for that. # the python bindings do not seem to be powerfull enough for that.
# (As we need to change a variable in the class structure.) # (As we need to change a variable in the class structure.)
class ColorToolButton(gtk.ToolItem):
__gtype_name__ = 'SugarColorToolButton' __gtype_name__ = 'SugarColorToolButton'
__gsignals__ = {'color-set': (gobject.SIGNAL_RUN_FIRST, gobject.TYPE_NONE, __gsignals__ = {'color-set': (gobject.SIGNAL_RUN_FIRST, gobject.TYPE_NONE,
tuple())} tuple())}
@ -528,4 +534,3 @@ class ColorToolButton(gtk.ToolItem):
def __color_set_cb(self, widget): def __color_set_cb(self, widget):
self.emit('color-set') self.emit('color-set')

View File

@ -22,7 +22,9 @@ STABLE.
import gobject import gobject
import gtk import gtk
class ComboBox(gtk.ComboBox): class ComboBox(gtk.ComboBox):
__gtype_name__ = 'SugarComboBox' __gtype_name__ = 'SugarComboBox'
def __init__(self): def __init__(self):

View File

@ -22,7 +22,9 @@ STABLE.
import gtk import gtk
import hippo import hippo
class CanvasEntry(hippo.CanvasEntry): class CanvasEntry(hippo.CanvasEntry):
def set_background(self, color_spec): def set_background(self, color_spec):
""" """
Parameters Parameters

View File

@ -33,9 +33,12 @@ import cairo
from sugar.graphics.xocolor import XoColor from sugar.graphics.xocolor import XoColor
from sugar.util import LRU from sugar.util import LRU
_BADGE_SIZE = 0.45 _BADGE_SIZE = 0.45
class _SVGLoader(object): class _SVGLoader(object):
def __init__(self): def __init__(self):
self._cache = LRU(50) self._cache = LRU(50)
@ -61,20 +64,26 @@ class _SVGLoader(object):
import rsvg # XXX this is very slow! why? import rsvg # XXX this is very slow! why?
return rsvg.Handle(data=icon) return rsvg.Handle(data=icon)
class _IconInfo(object): class _IconInfo(object):
def __init__(self): def __init__(self):
self.file_name = None self.file_name = None
self.attach_x = 0 self.attach_x = 0
self.attach_y = 0 self.attach_y = 0
class _BadgeInfo(object): class _BadgeInfo(object):
def __init__(self): def __init__(self):
self.attach_x = 0 self.attach_x = 0
self.attach_y = 0 self.attach_y = 0
self.size = 0 self.size = 0
self.icon_padding = 0 self.icon_padding = 0
class _IconBuffer(object): class _IconBuffer(object):
_surface_cache = LRU(50) _surface_cache = LRU(50)
_loader = _SVGLoader() _loader = _SVGLoader()
@ -309,7 +318,9 @@ class _IconBuffer(object):
xo_color = property(_get_xo_color, _set_xo_color) xo_color = property(_get_xo_color, _set_xo_color)
class Icon(gtk.Image): class Icon(gtk.Image):
__gtype_name__ = 'SugarIcon' __gtype_name__ = 'SugarIcon'
def __init__(self, **kwargs): def __init__(self, **kwargs):
@ -510,7 +521,9 @@ class Icon(gtk.Image):
badge_name = gobject.property( badge_name = gobject.property(
type=str, getter=get_badge_name, setter=set_badge_name) type=str, getter=get_badge_name, setter=set_badge_name)
class CanvasIcon(hippo.CanvasBox, hippo.CanvasItem): class CanvasIcon(hippo.CanvasBox, hippo.CanvasItem):
__gtype_name__ = 'CanvasIcon' __gtype_name__ = 'CanvasIcon'
def __init__(self, **kwargs): def __init__(self, **kwargs):
@ -932,11 +945,13 @@ class CanvasIcon(hippo.CanvasBox, hippo.CanvasItem):
palette = property(get_palette, set_palette) palette = property(get_palette, set_palette)
class CellRendererIcon(gtk.GenericCellRenderer): class CellRendererIcon(gtk.GenericCellRenderer):
__gtype_name__ = 'SugarCellRendererIcon' __gtype_name__ = 'SugarCellRendererIcon'
__gsignals__ = { __gsignals__ = {
'clicked': (gobject.SIGNAL_RUN_FIRST, gobject.TYPE_NONE, [object]) 'clicked': (gobject.SIGNAL_RUN_FIRST, gobject.TYPE_NONE, [object]),
} }
def __init__(self, tree_view): def __init__(self, tree_view):
@ -1073,8 +1088,8 @@ class CellRendererIcon(gtk.GenericCellRenderer):
return False return False
def on_render(self, window, widget, background_area, cell_area, expose_area, def on_render(self, window, widget, background_area, cell_area,
flags): expose_area, flags):
has_prelit_colors = None not in [self._prelit_fill_color, has_prelit_colors = None not in [self._prelit_fill_color,
self._prelit_stroke_color] self._prelit_stroke_color]
if flags & gtk.CELL_RENDERER_PRELIT and has_prelit_colors and \ if flags & gtk.CELL_RENDERER_PRELIT and has_prelit_colors and \
@ -1100,6 +1115,7 @@ class CellRendererIcon(gtk.GenericCellRenderer):
cr.rectangle(expose_area) cr.rectangle(expose_area)
cr.paint() cr.paint()
def get_icon_state(base_name, perc, step=5): def get_icon_state(base_name, perc, step=5):
strength = round(perc / step) * step strength = round(perc / step) * step
icon_theme = gtk.icon_theme_get_default() icon_theme = gtk.icon_theme_get_default()
@ -1111,6 +1127,7 @@ def get_icon_state(base_name, perc, step=5):
strength = strength + step strength = strength + step
def get_icon_file_name(icon_name): def get_icon_file_name(icon_name):
icon_theme = gtk.icon_theme_get_default() icon_theme = gtk.icon_theme_get_default()
info = icon_theme.lookup_icon(icon_name, gtk.ICON_SIZE_LARGE_TOOLBAR, 0) info = icon_theme.lookup_icon(icon_name, gtk.ICON_SIZE_LARGE_TOOLBAR, 0)
@ -1119,4 +1136,3 @@ def get_icon_file_name(icon_name):
filename = info.get_filename() filename = info.get_filename()
del info del info
return filename return filename

View File

@ -25,6 +25,7 @@ from sugar.graphics.icon import _SVGLoader
ICON_ENTRY_PRIMARY = _sugarext.ICON_ENTRY_PRIMARY ICON_ENTRY_PRIMARY = _sugarext.ICON_ENTRY_PRIMARY
ICON_ENTRY_SECONDARY = _sugarext.ICON_ENTRY_SECONDARY ICON_ENTRY_SECONDARY = _sugarext.ICON_ENTRY_SECONDARY
class IconEntry(_sugarext.IconEntry): class IconEntry(_sugarext.IconEntry):
def __init__(self): def __init__(self):
@ -103,4 +104,3 @@ class IconEntry(_sugarext.IconEntry):
self.hide_clear_button() self.hide_clear_button()
else: else:
self.show_clear_button() self.show_clear_button()

View File

@ -27,7 +27,9 @@ import gtk
from sugar.graphics.icon import Icon from sugar.graphics.icon import Icon
class MenuItem(gtk.ImageMenuItem): class MenuItem(gtk.ImageMenuItem):
def __init__(self, text_label=None, icon_name=None, text_maxlen=60, def __init__(self, text_label=None, icon_name=None, text_maxlen=60,
xo_color=None, file_name=None): xo_color=None, file_name=None):
gobject.GObject.__init__(self) gobject.GObject.__init__(self)
@ -91,4 +93,3 @@ class MenuItem(gtk.ImageMenuItem):
accelerator = gobject.property(type=str, setter=set_accelerator, accelerator = gobject.property(type=str, setter=set_accelerator,
getter=get_accelerator) getter=get_accelerator)

View File

@ -27,13 +27,14 @@ STABLE.
import gtk import gtk
import gobject import gobject
class Notebook(gtk.Notebook): class Notebook(gtk.Notebook):
__gtype_name__ = 'SugarNotebook' __gtype_name__ = 'SugarNotebook'
__gproperties__ = { __gproperties__ = {
'can-close-tabs': (bool, None, None, False, 'can-close-tabs': (bool, None, None, False,
gobject.PARAM_READWRITE | gobject.PARAM_READWRITE | gobject.PARAM_CONSTRUCT_ONLY),
gobject.PARAM_CONSTRUCT_ONLY)
} }
def __init__(self, **kwargs): def __init__(self, **kwargs):

View File

@ -27,11 +27,14 @@ import dbus
from sugar.datastore import datastore from sugar.datastore import datastore
J_DBUS_SERVICE = 'org.laptop.Journal' J_DBUS_SERVICE = 'org.laptop.Journal'
J_DBUS_INTERFACE = 'org.laptop.Journal' J_DBUS_INTERFACE = 'org.laptop.Journal'
J_DBUS_PATH = '/org/laptop/Journal' J_DBUS_PATH = '/org/laptop/Journal'
class ObjectChooser(object): class ObjectChooser(object):
def __init__(self, title=None, parent=None, flags=None, buttons=None, def __init__(self, title=None, parent=None, flags=None, buttons=None,
what_filter=None): what_filter=None):
# For backwards compatibility: # For backwards compatibility:
@ -127,4 +130,3 @@ class ObjectChooser(object):
# Journal service disappeared from the bus # Journal service disappeared from the bus
self._response_code = gtk.RESPONSE_CANCEL self._response_code = gtk.RESPONSE_CANCEL
self._cleanup() self._cleanup()

View File

@ -39,16 +39,18 @@ from sugar import _sugarext
from sugar.graphics.palettewindow import MouseSpeedDetector, Invoker, \ from sugar.graphics.palettewindow import MouseSpeedDetector, Invoker, \
WidgetInvoker, CanvasInvoker, ToolInvoker, CellRendererInvoker WidgetInvoker, CanvasInvoker, ToolInvoker, CellRendererInvoker
class Palette(PaletteWindow): class Palette(PaletteWindow):
PRIMARY = 0 PRIMARY = 0
SECONDARY = 1 SECONDARY = 1
__gtype_name__ = 'SugarPalette' __gtype_name__ = 'SugarPalette'
# DEPRECATED: label is passed with the primary-text property, accel_path
# is set via the invoker property, and menu_after_content is not used
def __init__(self, label=None, accel_path=None, menu_after_content=False, def __init__(self, label=None, accel_path=None, menu_after_content=False,
text_maxlen=60, **kwargs): text_maxlen=60, **kwargs):
# DEPRECATED: label is passed with the primary-text property,
# accel_path is set via the invoker property, and menu_after_content
# is not used
self._primary_text = None self._primary_text = None
self._secondary_text = None self._secondary_text = None
@ -238,10 +240,9 @@ class Palette(PaletteWindow):
def get_secondary_text(self): def get_secondary_text(self):
return self._secondary_text return self._secondary_text
secondary_text = gobject.property(type=str, getter=get_secondary_text,
secondary_text = gobject.property(type=str,
getter=get_secondary_text,
setter=set_secondary_text) setter=set_secondary_text)
def _show_icon(self): def _show_icon(self):
self._label_alignment.set_padding(0, 0, 0, style.DEFAULT_SPACING) self._label_alignment.set_padding(0, 0, 0, style.DEFAULT_SPACING)
self._icon_box.show() self._icon_box.show()
@ -362,7 +363,9 @@ class Palette(PaletteWindow):
self._palette_state = state self._palette_state = state
class PaletteActionBar(gtk.HButtonBox): class PaletteActionBar(gtk.HButtonBox):
def add_action(self, label, icon_name=None): def add_action(self, label, icon_name=None):
button = gtk.Button(label) button = gtk.Button(label)
@ -374,11 +377,13 @@ class PaletteActionBar(gtk.HButtonBox):
self.pack_start(button) self.pack_start(button)
button.show() button.show()
class _Menu(_sugarext.Menu): class _Menu(_sugarext.Menu):
__gtype_name__ = 'SugarPaletteMenu' __gtype_name__ = 'SugarPaletteMenu'
__gsignals__ = { __gsignals__ = {
'item-inserted': (gobject.SIGNAL_RUN_FIRST, gobject.TYPE_NONE, ([])) 'item-inserted': (gobject.SIGNAL_RUN_FIRST, gobject.TYPE_NONE, ([])),
} }
def __init__(self, palette): def __init__(self, palette):
@ -410,7 +415,9 @@ class _Menu(_sugarext.Menu):
def do_deactivate(self): def do_deactivate(self):
self._palette.hide() self._palette.hide()
class _SecondaryAnimation(animator.Animation): class _SecondaryAnimation(animator.Animation):
def __init__(self, palette): def __init__(self, palette):
animator.Animation.__init__(self, 0.0, 1.0) animator.Animation.__init__(self, 0.0, 1.0)
self._palette = palette self._palette = palette
@ -418,4 +425,3 @@ class _SecondaryAnimation(animator.Animation):
def next_frame(self, current): def next_frame(self, current):
if current == 1.0: if current == 1.0:
self._palette.set_palette_state(Palette.SECONDARY) self._palette.set_palette_state(Palette.SECONDARY)

View File

@ -21,8 +21,10 @@ STABLE.
import gobject import gobject
_groups = {} _groups = {}
def get_group(group_id): def get_group(group_id):
if _groups.has_key(group_id): if _groups.has_key(group_id):
group = _groups[group_id] group = _groups[group_id]
@ -32,13 +34,14 @@ def get_group(group_id):
return group return group
class Group(gobject.GObject): class Group(gobject.GObject):
__gsignals__ = { __gsignals__ = {
'popup' : (gobject.SIGNAL_RUN_FIRST, 'popup': (gobject.SIGNAL_RUN_FIRST, gobject.TYPE_NONE, ([])),
gobject.TYPE_NONE, ([])), 'popdown': (gobject.SIGNAL_RUN_FIRST, gobject.TYPE_NONE, ([])),
'popdown' : (gobject.SIGNAL_RUN_FIRST,
gobject.TYPE_NONE, ([]))
} }
def __init__(self): def __init__(self):
gobject.GObject.__init__(self) gobject.GObject.__init__(self)
self._up = False self._up = False

View File

@ -31,8 +31,9 @@ from sugar.graphics import palettegroup
from sugar.graphics import animator from sugar.graphics import animator
from sugar.graphics import style from sugar.graphics import style
# Helper function to find the gap position and size of widget a
def _calculate_gap(a, b): def _calculate_gap(a, b):
"""Helper function to find the gap position and size of widget a"""
# Test for each side if the palette and invoker are # Test for each side if the palette and invoker are
# adjacent to each other. # adjacent to each other.
gap = True gap = True
@ -63,6 +64,7 @@ def _calculate_gap(a, b):
else: else:
return False return False
class MouseSpeedDetector(gobject.GObject): class MouseSpeedDetector(gobject.GObject):
__gsignals__ = { __gsignals__ = {
@ -125,17 +127,15 @@ class MouseSpeedDetector(gobject.GObject):
return True return True
class PaletteWindow(gtk.Window): class PaletteWindow(gtk.Window):
__gtype_name__ = 'SugarPaletteWindow' __gtype_name__ = 'SugarPaletteWindow'
__gsignals__ = { __gsignals__ = {
'popup' : (gobject.SIGNAL_RUN_FIRST, 'popup': (gobject.SIGNAL_RUN_FIRST, gobject.TYPE_NONE, ([])),
gobject.TYPE_NONE, ([])), 'popdown': (gobject.SIGNAL_RUN_FIRST, gobject.TYPE_NONE, ([])),
'popdown' : (gobject.SIGNAL_RUN_FIRST, 'activate': (gobject.SIGNAL_RUN_FIRST, gobject.TYPE_NONE, ([])),
gobject.TYPE_NONE, ([])),
'activate' : (gobject.SIGNAL_RUN_FIRST,
gobject.TYPE_NONE, ([]))
} }
def __init__(self, **kwargs): def __init__(self, **kwargs):
@ -401,7 +401,9 @@ class PaletteWindow(gtk.Window):
palette_state = property(get_palette_state) palette_state = property(get_palette_state)
class _PopupAnimation(animator.Animation): class _PopupAnimation(animator.Animation):
def __init__(self, palette): def __init__(self, palette):
animator.Animation.__init__(self, 0.0, 1.0) animator.Animation.__init__(self, 0.0, 1.0)
self._palette = palette self._palette = palette
@ -410,7 +412,9 @@ class _PopupAnimation(animator.Animation):
if current == 1.0: if current == 1.0:
self._palette.show() self._palette.show()
class _PopdownAnimation(animator.Animation): class _PopdownAnimation(animator.Animation):
def __init__(self, palette): def __init__(self, palette):
animator.Animation.__init__(self, 0.0, 1.0) animator.Animation.__init__(self, 0.0, 1.0)
self._palette = palette self._palette = palette
@ -419,27 +423,25 @@ class _PopdownAnimation(animator.Animation):
if current == 1.0: if current == 1.0:
self._palette.hide() self._palette.hide()
class Invoker(gobject.GObject): class Invoker(gobject.GObject):
__gtype_name__ = 'SugarPaletteInvoker' __gtype_name__ = 'SugarPaletteInvoker'
__gsignals__ = { __gsignals__ = {
'mouse-enter': (gobject.SIGNAL_RUN_FIRST, gobject.TYPE_NONE, ([])), 'mouse-enter': (gobject.SIGNAL_RUN_FIRST, gobject.TYPE_NONE, ([])),
'mouse-leave': (gobject.SIGNAL_RUN_FIRST, gobject.TYPE_NONE, ([])), 'mouse-leave': (gobject.SIGNAL_RUN_FIRST, gobject.TYPE_NONE, ([])),
'right-click': (gobject.SIGNAL_RUN_FIRST, gobject.TYPE_NONE, ([])), 'right-click': (gobject.SIGNAL_RUN_FIRST, gobject.TYPE_NONE, ([])),
'focus-out': (gobject.SIGNAL_RUN_FIRST, gobject.TYPE_NONE, ([])) 'focus-out': (gobject.SIGNAL_RUN_FIRST, gobject.TYPE_NONE, ([])),
} }
ANCHORED = 0 ANCHORED = 0
AT_CURSOR = 1 AT_CURSOR = 1
BOTTOM = [(0.0, 0.0, 0.0, 1.0), BOTTOM = [(0.0, 0.0, 0.0, 1.0), (-1.0, 0.0, 1.0, 1.0)]
(-1.0, 0.0, 1.0, 1.0)] RIGHT = [(0.0, 0.0, 1.0, 0.0), (0.0, -1.0, 1.0, 1.0)]
RIGHT = [(0.0, 0.0, 1.0, 0.0), TOP = [(0.0, -1.0, 0.0, 0.0), (-1.0, -1.0, 1.0, 0.0)]
(0.0, -1.0, 1.0, 1.0)] LEFT = [(-1.0, 0.0, 0.0, 0.0), (-1.0, -1.0, 0.0, 1.0)]
TOP = [(0.0, -1.0, 0.0, 0.0),
(-1.0, -1.0, 1.0, 0.0)]
LEFT = [(-1.0, 0.0, 0.0, 0.0),
(-1.0, -1.0, 0.0, 1.0)]
def __init__(self): def __init__(self):
gobject.GObject.__init__(self) gobject.GObject.__init__(self)
@ -531,8 +533,9 @@ class Invoker(gobject.GObject):
alignment = self.get_alignment(palette_dim) alignment = self.get_alignment(palette_dim)
rect = self._get_position_for_alignment(alignment, palette_dim) rect = self._get_position_for_alignment(alignment, palette_dim)
# In case our efforts to find an optimum place inside the screen failed, # In case our efforts to find an optimum place inside the screen
# just make sure the palette fits inside the screen if at all possible. # failed, just make sure the palette fits inside the screen if at all
# possible.
rect.x = max(0, rect.x) rect.x = max(0, rect.x)
rect.y = max(0, rect.y) rect.y = max(0, rect.y)
@ -642,7 +645,9 @@ class Invoker(gobject.GObject):
palette = gobject.property( palette = gobject.property(
type=object, setter=set_palette, getter=get_palette) type=object, setter=set_palette, getter=get_palette)
class WidgetInvoker(Invoker): class WidgetInvoker(Invoker):
def __init__(self, parent=None, widget=None): def __init__(self, parent=None, widget=None):
Invoker.__init__(self) Invoker.__init__(self)
@ -750,7 +755,9 @@ class WidgetInvoker(Invoker):
return self._widget return self._widget
widget = gobject.property(type=object, getter=_get_widget, setter=None) widget = gobject.property(type=object, getter=_get_widget, setter=None)
class CanvasInvoker(Invoker): class CanvasInvoker(Invoker):
def __init__(self, parent=None): def __init__(self, parent=None):
Invoker.__init__(self) Invoker.__init__(self)
@ -806,7 +813,9 @@ class CanvasInvoker(Invoker):
def get_toplevel(self): def get_toplevel(self):
return hippo.get_canvas_for_item(self._item).get_toplevel() return hippo.get_canvas_for_item(self._item).get_toplevel()
class ToolInvoker(WidgetInvoker): class ToolInvoker(WidgetInvoker):
def __init__(self, parent=None): def __init__(self, parent=None):
WidgetInvoker.__init__(self) WidgetInvoker.__init__(self)
@ -826,7 +835,9 @@ class ToolInvoker(WidgetInvoker):
else: else:
return self.LEFT + self.RIGHT return self.LEFT + self.RIGHT
class CellRendererInvoker(Invoker): class CellRendererInvoker(Invoker):
def __init__(self): def __init__(self):
Invoker.__init__(self) Invoker.__init__(self)
@ -910,14 +921,16 @@ class CellRendererInvoker(Invoker):
self.notify_mouse_leave() self.notify_mouse_leave()
def __button_release_event_cb(self, widget, event): def __button_release_event_cb(self, widget, event):
if event.button == 1 and self._point_in_cell_renderer(event.x, event.y): if event.button == 1 and self._point_in_cell_renderer(event.x,
event.y):
tree_view = self._tree_view tree_view = self._tree_view
path, column_, x_, y_ = tree_view.get_path_at_pos(int(event.x), path, column_, x_, y_ = tree_view.get_path_at_pos(int(event.x),
int(event.y)) int(event.y))
self._cell_renderer.emit('clicked', path) self._cell_renderer.emit('clicked', path)
# So the treeview receives it and knows a drag isn't going on # So the treeview receives it and knows a drag isn't going on
return False return False
if event.button == 3 and self._point_in_cell_renderer(event.x, event.y): if event.button == 3 and self._point_in_cell_renderer(event.x,
event.y):
self.notify_right_click() self.notify_right_click()
return True return True
else: else:
@ -951,4 +964,3 @@ class CellRendererInvoker(Invoker):
def get_default_position(self): def get_default_position(self):
return self.AT_CURSOR return self.AT_CURSOR

View File

@ -21,7 +21,10 @@ STABLE.
import gtk import gtk
class Panel(gtk.VBox): class Panel(gtk.VBox):
__gtype_name__ = 'SugarPanel' __gtype_name__ = 'SugarPanel'
def __init__(self): def __init__(self):
gtk.VBox.__init__(self) gtk.VBox.__init__(self)

View File

@ -20,7 +20,9 @@ import gtk
from sugar.graphics.toolbutton import ToolButton from sugar.graphics.toolbutton import ToolButton
from sugar.graphics.palette import Palette from sugar.graphics.palette import Palette
class RadioMenuButton(ToolButton): class RadioMenuButton(ToolButton):
def __init__(self, **kwargs): def __init__(self, **kwargs):
ToolButton.__init__(self, **kwargs) ToolButton.__init__(self, **kwargs)
self.selected_button = None self.selected_button = None
@ -44,7 +46,9 @@ class RadioMenuButton(ToolButton):
else: else:
self.palette.popup(immediate=True, state=Palette.SECONDARY) self.palette.popup(immediate=True, state=Palette.SECONDARY)
class RadioToolsButton(RadioMenuButton): class RadioToolsButton(RadioMenuButton):
def __init__(self, **kwargs): def __init__(self, **kwargs):
RadioMenuButton.__init__(self, **kwargs) RadioMenuButton.__init__(self, **kwargs)
@ -53,7 +57,9 @@ class RadioToolsButton(RadioMenuButton):
return return
self.selected_button.emit('clicked') self.selected_button.emit('clicked')
class RadioPalette(Palette): class RadioPalette(Palette):
def __init__(self, **kwargs): def __init__(self, **kwargs):
Palette.__init__(self, **kwargs) Palette.__init__(self, **kwargs)

View File

@ -27,11 +27,13 @@ from sugar.graphics.icon import Icon
from sugar.graphics.palette import Palette, ToolInvoker from sugar.graphics.palette import Palette, ToolInvoker
from sugar.graphics import toolbutton from sugar.graphics import toolbutton
class RadioToolButton(gtk.RadioToolButton): class RadioToolButton(gtk.RadioToolButton):
""" """
An implementation of a "push" button. An implementation of a "push" button.
""" """
__gtype_name__ = 'SugarRadioToolButton' __gtype_name__ = 'SugarRadioToolButton'
def __init__(self, **kwargs): def __init__(self, **kwargs):
@ -76,7 +78,8 @@ class RadioToolButton(gtk.RadioToolButton):
def get_tooltip(self): def get_tooltip(self):
return self._tooltip return self._tooltip
tooltip = gobject.property(type=str, setter=set_tooltip, getter=get_tooltip) tooltip = gobject.property(type=str, setter=set_tooltip,
getter=get_tooltip)
def set_accelerator(self, accelerator): def set_accelerator(self, accelerator):
""" """
@ -177,4 +180,3 @@ class RadioToolButton(gtk.RadioToolButton):
allocation.width, allocation.height) allocation.width, allocation.height)
gtk.RadioToolButton.do_expose_event(self, event) gtk.RadioToolButton.do_expose_event(self, event)

View File

@ -25,6 +25,7 @@ import hippo
from sugar.graphics import style from sugar.graphics import style
class CanvasRoundBox(hippo.CanvasBox, hippo.CanvasItem): class CanvasRoundBox(hippo.CanvasBox, hippo.CanvasItem):
__gtype_name__ = 'SugarRoundBox' __gtype_name__ = 'SugarRoundBox'

View File

@ -28,9 +28,11 @@ import logging
import gtk import gtk
import pango import pango
FOCUS_LINE_WIDTH = 2 FOCUS_LINE_WIDTH = 2
_TAB_CURVATURE = 1 _TAB_CURVATURE = 1
def _compute_zoom_factor(): def _compute_zoom_factor():
if os.environ.has_key('SUGAR_SCALING'): if os.environ.has_key('SUGAR_SCALING'):
try: try:
@ -41,7 +43,9 @@ def _compute_zoom_factor():
return 1.0 return 1.0
class Font(object): class Font(object):
def __init__(self, desc): def __init__(self, desc):
self._desc = desc self._desc = desc
@ -51,7 +55,9 @@ class Font(object):
def get_pango_desc(self): def get_pango_desc(self):
return pango.FontDescription(self._desc) return pango.FontDescription(self._desc)
class Color(object): class Color(object):
def __init__(self, color, alpha=1.0): def __init__(self, color, alpha=1.0):
self._r, self._g, self._b = self._html_to_rgb(color) self._r, self._g, self._b = self._html_to_rgb(color)
self._a = alpha self._a = alpha
@ -91,9 +97,11 @@ class Color(object):
else: else:
return self.get_html() return self.get_html()
def zoom(units): def zoom(units):
return int(ZOOM_FACTOR * units) return int(ZOOM_FACTOR * units)
ZOOM_FACTOR = _compute_zoom_factor() ZOOM_FACTOR = _compute_zoom_factor()
DEFAULT_SPACING = zoom(15) DEFAULT_SPACING = zoom(15)

View File

@ -25,7 +25,9 @@ import gtk
from sugar.graphics.icon import Icon from sugar.graphics.icon import Icon
from sugar.graphics.palette import Palette, ToolInvoker from sugar.graphics.palette import Palette, ToolInvoker
class ToggleToolButton(gtk.ToggleToolButton): class ToggleToolButton(gtk.ToggleToolButton):
__gtype_name__ = "SugarToggleToolButton" __gtype_name__ = "SugarToggleToolButton"
def __init__(self, named_icon=None): def __init__(self, named_icon=None):

View File

@ -24,7 +24,9 @@ from sugar.graphics.palette import PaletteWindow, ToolInvoker
from sugar.graphics.toolbutton import ToolButton from sugar.graphics.toolbutton import ToolButton
from sugar.graphics import palettegroup from sugar.graphics import palettegroup
class ToolbarButton(ToolButton): class ToolbarButton(ToolButton):
def __init__(self, page=None, **kwargs): def __init__(self, page=None, **kwargs):
ToolButton.__init__(self, **kwargs) ToolButton.__init__(self, **kwargs)
@ -132,7 +134,9 @@ class ToolbarButton(ToolButton):
gtk.ToolButton.do_expose_event(self, event) gtk.ToolButton.do_expose_event(self, event)
_paint_arrow(self, event, gtk.ARROW_UP) _paint_arrow(self, event, gtk.ARROW_UP)
class ToolbarBox(gtk.VBox): class ToolbarBox(gtk.VBox):
def __init__(self, padding=style.TOOLBOX_HORIZONTAL_PADDING): def __init__(self, padding=style.TOOLBOX_HORIZONTAL_PADDING):
gtk.VBox.__init__(self) gtk.VBox.__init__(self)
self.expanded_button = None self.expanded_button = None
@ -177,7 +181,9 @@ class ToolbarBox(gtk.VBox):
self.toolbar.parent.parent.modify_bg(state, color) self.toolbar.parent.parent.modify_bg(state, color)
self.toolbar.modify_bg(state, color) self.toolbar.modify_bg(state, color)
class _ToolbarPalette(PaletteWindow): class _ToolbarPalette(PaletteWindow):
def __init__(self, **kwargs): def __init__(self, **kwargs):
PaletteWindow.__init__(self, **kwargs) PaletteWindow.__init__(self, **kwargs)
self.toolbar_box = None self.toolbar_box = None
@ -232,7 +238,9 @@ class _ToolbarPalette(PaletteWindow):
if self._focus == 0: if self._focus == 0:
self.popdown(immediate=True) self.popdown(immediate=True)
class _Box(gtk.EventBox): class _Box(gtk.EventBox):
def __init__(self): def __init__(self):
gtk.EventBox.__init__(self) gtk.EventBox.__init__(self)
self.connect('expose-event', self.do_expose_event) self.connect('expose-event', self.do_expose_event)
@ -251,6 +259,7 @@ class _Box(gtk.EventBox):
alloc.width - style.FOCUS_LINE_WIDTH * 2, alloc.width - style.FOCUS_LINE_WIDTH * 2,
style.FOCUS_LINE_WIDTH) style.FOCUS_LINE_WIDTH)
def _setup_page(page_widget, color, hpad): def _setup_page(page_widget, color, hpad):
vpad = style.FOCUS_LINE_WIDTH vpad = style.FOCUS_LINE_WIDTH
page_widget.child.set_padding(vpad, vpad, hpad, hpad) page_widget.child.set_padding(vpad, vpad, hpad, hpad)
@ -264,6 +273,7 @@ def _setup_page(page_widget, color, hpad):
page_widget.modify_bg(gtk.STATE_NORMAL, color) page_widget.modify_bg(gtk.STATE_NORMAL, color)
page_widget.modify_bg(gtk.STATE_PRELIGHT, color) page_widget.modify_bg(gtk.STATE_PRELIGHT, color)
def _embody_page(box_class, widget): def _embody_page(box_class, widget):
widget.show() widget.show()
alignment = gtk.Alignment(0.0, 0.0, 1.0, 1.0) alignment = gtk.Alignment(0.0, 0.0, 1.0, 1.0)
@ -275,6 +285,7 @@ def _embody_page(box_class, widget):
box.show() box.show()
return box return box
def _paint_arrow(widget, event, arrow_type): def _paint_arrow(widget, event, arrow_type):
alloc = widget.allocation alloc = widget.allocation
x = alloc.x + alloc.width / 2 - style.TOOLBAR_ARROW_SIZE / 2 x = alloc.x + alloc.width / 2 - style.TOOLBAR_ARROW_SIZE / 2

View File

@ -25,13 +25,14 @@ import hippo
from sugar.graphics import style from sugar.graphics import style
class Toolbox(gtk.VBox): class Toolbox(gtk.VBox):
__gtype_name__ = 'SugarToolbox' __gtype_name__ = 'SugarToolbox'
__gsignals__ = { __gsignals__ = {
'current-toolbar-changed': (gobject.SIGNAL_RUN_FIRST, 'current-toolbar-changed': (gobject.SIGNAL_RUN_FIRST,
gobject.TYPE_NONE, gobject.TYPE_NONE, ([int])),
([int]))
} }
def __init__(self): def __init__(self):
@ -98,4 +99,3 @@ class Toolbox(gtk.VBox):
return self._notebook.get_current_page() return self._notebook.get_current_page()
current_toolbar = property(get_current_toolbar, set_current_toolbar) current_toolbar = property(get_current_toolbar, set_current_toolbar)

View File

@ -28,6 +28,7 @@ import gobject
from sugar.graphics.icon import Icon from sugar.graphics.icon import Icon
from sugar.graphics.palette import Palette, ToolInvoker from sugar.graphics.palette import Palette, ToolInvoker
def _add_accelerator(tool_button): def _add_accelerator(tool_button):
if not tool_button.props.accelerator or not tool_button.get_toplevel() or \ if not tool_button.props.accelerator or not tool_button.get_toplevel() or \
not tool_button.child: not tool_button.child:
@ -46,14 +47,18 @@ def _add_accelerator(tool_button):
tool_button.child.add_accelerator('clicked', accel_group, keyval, mask, tool_button.child.add_accelerator('clicked', accel_group, keyval, mask,
gtk.ACCEL_LOCKED | gtk.ACCEL_VISIBLE) gtk.ACCEL_LOCKED | gtk.ACCEL_VISIBLE)
def _hierarchy_changed_cb(tool_button, previous_toplevel): def _hierarchy_changed_cb(tool_button, previous_toplevel):
_add_accelerator(tool_button) _add_accelerator(tool_button)
def setup_accelerator(tool_button): def setup_accelerator(tool_button):
_add_accelerator(tool_button) _add_accelerator(tool_button)
tool_button.connect('hierarchy-changed', _hierarchy_changed_cb) tool_button.connect('hierarchy-changed', _hierarchy_changed_cb)
class ToolButton(gtk.ToolButton): class ToolButton(gtk.ToolButton):
__gtype_name__ = "SugarToolButton" __gtype_name__ = "SugarToolButton"
def __init__(self, icon_name=None, **kwargs): def __init__(self, icon_name=None, **kwargs):
@ -97,7 +102,8 @@ class ToolButton(gtk.ToolButton):
def get_tooltip(self): def get_tooltip(self):
return self._tooltip return self._tooltip
tooltip = gobject.property(type=str, setter=set_tooltip, getter=get_tooltip) tooltip = gobject.property(type=str, setter=set_tooltip,
getter=get_tooltip)
def set_accelerator(self, accelerator): def set_accelerator(self, accelerator):
self._accelerator = accelerator self._accelerator = accelerator

View File

@ -25,10 +25,11 @@ import gobject
from sugar.graphics.combobox import ComboBox from sugar.graphics.combobox import ComboBox
from sugar.graphics import style from sugar.graphics import style
class ToolComboBox(gtk.ToolItem): class ToolComboBox(gtk.ToolItem):
__gproperties__ = { __gproperties__ = {
'label-text' : (str, None, None, None, 'label-text': (str, None, None, None, gobject.PARAM_WRITABLE),
gobject.PARAM_WRITABLE),
} }
def __init__(self, combo=None, **kwargs): def __init__(self, combo=None, **kwargs):

View File

@ -27,17 +27,17 @@ from sugar.graphics.palette import ToolInvoker
from sugar.graphics.toolbutton import ToolButton from sugar.graphics.toolbutton import ToolButton
from sugar.graphics.icon import Icon from sugar.graphics.icon import Icon
_PREVIOUS_PAGE = 0 _PREVIOUS_PAGE = 0
_NEXT_PAGE = 1 _NEXT_PAGE = 1
class _TrayViewport(gtk.Viewport): class _TrayViewport(gtk.Viewport):
__gproperties__ = { __gproperties__ = {
'scrollable' : (bool, None, None, False, 'scrollable': (bool, None, None, False, gobject.PARAM_READABLE),
gobject.PARAM_READABLE), 'can-scroll-prev': (bool, None, None, False, gobject.PARAM_READABLE),
'can-scroll-prev' : (bool, None, None, False, 'can-scroll-next': (bool, None, None, False, gobject.PARAM_READABLE),
gobject.PARAM_READABLE),
'can-scroll-next' : (bool, None, None, False,
gobject.PARAM_READABLE),
} }
def __init__(self, orientation): def __init__(self, orientation):
@ -161,6 +161,7 @@ class _TrayViewport(gtk.Viewport):
class _TrayScrollButton(ToolButton): class _TrayScrollButton(ToolButton):
def __init__(self, icon_name, scroll_direction): def __init__(self, icon_name, scroll_direction):
ToolButton.__init__(self) ToolButton.__init__(self)
self._viewport = None self._viewport = None
@ -194,7 +195,6 @@ class _TrayScrollButton(ToolButton):
self._viewport_can_scroll_dir_changed_cb) self._viewport_can_scroll_dir_changed_cb)
self.set_sensitive(self._viewport.props.can_scroll_next) self.set_sensitive(self._viewport.props.can_scroll_next)
def _viewport_scrollable_changed_cb(self, viewport, pspec): def _viewport_scrollable_changed_cb(self, viewport, pspec):
self.props.visible = self._viewport.props.scrollable self.props.visible = self._viewport.props.scrollable
@ -211,19 +211,21 @@ class _TrayScrollButton(ToolButton):
viewport = property(fset=set_viewport) viewport = property(fset=set_viewport)
ALIGN_TO_START = 0 ALIGN_TO_START = 0
ALIGN_TO_END = 1 ALIGN_TO_END = 1
class HTray(gtk.HBox): class HTray(gtk.HBox):
__gtype_name__ = 'SugarHTray' __gtype_name__ = 'SugarHTray'
__gproperties__ = { __gproperties__ = {
'align': (int, None, None, 0, 1, ALIGN_TO_START, 'align': (int, None, None, 0, 1, ALIGN_TO_START,
gobject.PARAM_READWRITE | gobject.PARAM_READWRITE | gobject.PARAM_CONSTRUCT_ONLY),
gobject.PARAM_CONSTRUCT_ONLY), 'drag-active': (bool, None, None, False, gobject.PARAM_READWRITE),
'drag-active' : (bool, None, None, False,
gobject.PARAM_READWRITE)
} }
def __init__(self, **kwargs): def __init__(self, **kwargs):
self._drag_active = False self._drag_active = False
self.align = ALIGN_TO_START self.align = ALIGN_TO_START
@ -299,15 +301,15 @@ class HTray(gtk.HBox):
def scroll_to_item(self, item): def scroll_to_item(self, item):
self._viewport.scroll_to_item(item) self._viewport.scroll_to_item(item)
class VTray(gtk.VBox): class VTray(gtk.VBox):
__gtype_name__ = 'SugarVTray' __gtype_name__ = 'SugarVTray'
__gproperties__ = { __gproperties__ = {
'align': (int, None, None, 0, 1, ALIGN_TO_START, 'align': (int, None, None, 0, 1, ALIGN_TO_START,
gobject.PARAM_READWRITE | gobject.PARAM_READWRITE | gobject.PARAM_CONSTRUCT_ONLY),
gobject.PARAM_CONSTRUCT_ONLY), 'drag-active': (bool, None, None, False, gobject.PARAM_READWRITE),
'drag-active' : (bool, None, None, False,
gobject.PARAM_READWRITE)
} }
def __init__(self, **kwargs): def __init__(self, **kwargs):
@ -385,11 +387,15 @@ class VTray(gtk.VBox):
def scroll_to_item(self, item): def scroll_to_item(self, item):
self._viewport.scroll_to_item(item) self._viewport.scroll_to_item(item)
class TrayButton(ToolButton): class TrayButton(ToolButton):
def __init__(self, **kwargs): def __init__(self, **kwargs):
ToolButton.__init__(self, **kwargs) ToolButton.__init__(self, **kwargs)
class _IconWidget(gtk.EventBox): class _IconWidget(gtk.EventBox):
__gtype_name__ = "SugarTrayIconWidget" __gtype_name__ = "SugarTrayIconWidget"
def __init__(self, icon_name=None, xo_color=None): def __init__(self, icon_name=None, xo_color=None):
@ -413,7 +419,9 @@ class _IconWidget(gtk.EventBox):
def get_icon(self): def get_icon(self):
return self._icon return self._icon
class TrayIcon(gtk.ToolItem): class TrayIcon(gtk.ToolItem):
__gtype_name__ = "SugarTrayIcon" __gtype_name__ = "SugarTrayIcon"
def __init__(self, icon_name=None, xo_color=None): def __init__(self, icon_name=None, xo_color=None):
@ -458,4 +466,3 @@ class TrayIcon(gtk.ToolItem):
def get_icon(self): def get_icon(self):
return self._icon_widget.get_icon() return self._icon_widget.get_icon()
icon = property(get_icon, None) icon = property(get_icon, None)

View File

@ -26,8 +26,10 @@ import warnings
from sugar.graphics.icon import Icon from sugar.graphics.icon import Icon
_UNFULLSCREEN_BUTTON_VISIBILITY_TIMEOUT = 2 _UNFULLSCREEN_BUTTON_VISIBILITY_TIMEOUT = 2
class UnfullscreenButton(gtk.Window): class UnfullscreenButton(gtk.Window):
def __init__(self): def __init__(self):
@ -77,7 +79,9 @@ class UnfullscreenButton(gtk.Window):
def _screen_size_changed_cb(self, screen): def _screen_size_changed_cb(self, screen):
self._reposition() self._reposition()
class Window(gtk.Window): class Window(gtk.Window):
def __init__(self, **args): def __init__(self, **args):
self._enable_fullscreen_mode = True self._enable_fullscreen_mode = True
@ -263,8 +267,7 @@ class Window(gtk.Window):
return self._enable_fullscreen_mode return self._enable_fullscreen_mode
enable_fullscreen_mode = gobject.property(type=object, enable_fullscreen_mode = gobject.property(type=object,
setter=set_enable_fullscreen_mode, setter=set_enable_fullscreen_mode, getter=get_enable_fullscreen_mode)
getter=get_enable_fullscreen_mode)
# DEPRECATED # DEPRECATED

View File

@ -204,6 +204,7 @@ colors = [
['#BCCDFF', '#AC32FF'], \ ['#BCCDFF', '#AC32FF'], \
] ]
def _parse_string(color_string): def _parse_string(color_string):
if color_string == 'white': if color_string == 'white':
return ['#ffffff', '#414141'] return ['#ffffff', '#414141']
@ -216,10 +217,13 @@ def _parse_string(color_string):
else: else:
return None return None
def is_valid(color_string): def is_valid(color_string):
return (_parse_string(color_string) != None) return (_parse_string(color_string) != None)
class XoColor: class XoColor:
def __init__(self, color_string=None): def __init__(self, color_string=None):
if color_string == None or not is_valid(color_string): if color_string == None or not is_valid(color_string):
n = int(random.random() * (len(colors) - 1)) n = int(random.random() * (len(colors) - 1))
@ -242,6 +246,7 @@ class XoColor:
def to_string(self): def to_string(self):
return '%s,%s' % (self.stroke, self.fill) return '%s,%s' % (self.stroke, self.fill)
if __name__ == "__main__": if __name__ == "__main__":
import sys import sys
import re import re

View File

@ -29,14 +29,18 @@ import gobject
import SimpleHTTPServer import SimpleHTTPServer
import SocketServer import SocketServer
__authinfos = {} __authinfos = {}
def _add_authinfo(authinfo): def _add_authinfo(authinfo):
__authinfos[threading.currentThread()] = authinfo __authinfos[threading.currentThread()] = authinfo
def get_authinfo(): def get_authinfo():
return __authinfos.get(threading.currentThread()) return __authinfos.get(threading.currentThread())
def _del_authinfo(): def _del_authinfo():
del __authinfos[threading.currentThread()] del __authinfos[threading.currentThread()]
@ -172,6 +176,7 @@ class ChunkedGlibHTTPRequestHandler(SimpleHTTPServer.SimpleHTTPRequestHandler):
self.end_headers() self.end_headers()
return f return f
class GlibURLDownloader(gobject.GObject): class GlibURLDownloader(gobject.GObject):
"""Grabs a URL in chunks, returning to the mainloop after each chunk""" """Grabs a URL in chunks, returning to the mainloop after each chunk"""
@ -181,7 +186,7 @@ class GlibURLDownloader(gobject.GObject):
'error': (gobject.SIGNAL_RUN_FIRST, gobject.TYPE_NONE, 'error': (gobject.SIGNAL_RUN_FIRST, gobject.TYPE_NONE,
([gobject.TYPE_PYOBJECT])), ([gobject.TYPE_PYOBJECT])),
'progress': (gobject.SIGNAL_RUN_FIRST, gobject.TYPE_NONE, 'progress': (gobject.SIGNAL_RUN_FIRST, gobject.TYPE_NONE,
([gobject.TYPE_PYOBJECT])) ([gobject.TYPE_PYOBJECT])),
} }
CHUNK_SIZE = 4096 CHUNK_SIZE = 4096

View File

@ -26,8 +26,10 @@ import dbus
import gobject import gobject
import telepathy import telepathy
_logger = logging.getLogger('sugar.presence.activity') _logger = logging.getLogger('sugar.presence.activity')
class Activity(gobject.GObject): class Activity(gobject.GObject):
"""UI interface for an Activity in the presence service """UI interface for an Activity in the presence service
@ -175,10 +177,10 @@ class Activity(gobject.GObject):
elif pspec.name == "private": elif pspec.name == "private":
return self._private return self._private
# FIXME: need an asynchronous API to set these properties, particularly
# 'private'
def do_set_property(self, pspec, val): def do_set_property(self, pspec, val):
"""Set a particular property in our property dictionary""" """Set a particular property in our property dictionary"""
# FIXME: need an asynchronous API to set these properties,
# particularly 'private'
if pspec.name == "name": if pspec.name == "name":
self._activity.SetProperties({'name': val}) self._activity.SetProperties({'name': val})
self._name = val self._name = val

View File

@ -24,6 +24,7 @@ import gobject
import gtk import gtk
import dbus import dbus
class Buddy(gobject.GObject): class Buddy(gobject.GObject):
"""UI interface for a Buddy in the presence service """UI interface for a Buddy in the presence service
@ -40,9 +41,9 @@ class Buddy(gobject.GObject):
'icon': (XXX pixel data for an icon?) 'icon': (XXX pixel data for an icon?)
See __gproperties__ See __gproperties__
""" """
__gsignals__ = { __gsignals__ = {
'icon-changed': (gobject.SIGNAL_RUN_FIRST, gobject.TYPE_NONE, 'icon-changed': (gobject.SIGNAL_RUN_FIRST, gobject.TYPE_NONE, ([])),
([])),
'joined-activity': (gobject.SIGNAL_RUN_FIRST, gobject.TYPE_NONE, 'joined-activity': (gobject.SIGNAL_RUN_FIRST, gobject.TYPE_NONE,
([gobject.TYPE_PYOBJECT])), ([gobject.TYPE_PYOBJECT])),
'left-activity': (gobject.SIGNAL_RUN_FIRST, gobject.TYPE_NONE, 'left-activity': (gobject.SIGNAL_RUN_FIRST, gobject.TYPE_NONE,

View File

@ -63,13 +63,12 @@ class PresenceService(gobject.GObject):
([gobject.TYPE_PYOBJECT])), ([gobject.TYPE_PYOBJECT])),
'activity-shared': (gobject.SIGNAL_RUN_FIRST, gobject.TYPE_NONE, 'activity-shared': (gobject.SIGNAL_RUN_FIRST, gobject.TYPE_NONE,
([gobject.TYPE_PYOBJECT, gobject.TYPE_PYOBJECT, ([gobject.TYPE_PYOBJECT, gobject.TYPE_PYOBJECT,
gobject.TYPE_PYOBJECT])) gobject.TYPE_PYOBJECT])),
} }
_PS_BUDDY_OP = DBUS_PATH + "/Buddies/" _PS_BUDDY_OP = DBUS_PATH + "/Buddies/"
_PS_ACTIVITY_OP = DBUS_PATH + "/Activities/" _PS_ACTIVITY_OP = DBUS_PATH + "/Activities/"
def __init__(self, allow_offline_iface=True): def __init__(self, allow_offline_iface=True):
"""Initialise the service and attempt to connect to events """Initialise the service and attempt to connect to events
""" """
@ -98,6 +97,7 @@ class PresenceService(gobject.GObject):
self._get_ps() self._get_ps()
_ps_ = None _ps_ = None
def _get_ps(self): def _get_ps(self):
"""Retrieve dbus interface to PresenceService """Retrieve dbus interface to PresenceService
@ -123,17 +123,16 @@ class PresenceService(gobject.GObject):
self._bus.get_object(DBUS_SERVICE, self._bus.get_object(DBUS_SERVICE,
DBUS_PATH, DBUS_PATH,
follow_name_owner_changes=True), follow_name_owner_changes=True),
DBUS_INTERFACE DBUS_INTERFACE)
)
except dbus.exceptions.DBusException, err: except dbus.exceptions.DBusException, err:
_logger.error( _logger.error(
"""Failure retrieving %r interface from """Failure retrieving %r interface from
the D-BUS service %r %r: %s""", the D-BUS service %r %r: %s""",
DBUS_INTERFACE, DBUS_SERVICE, DBUS_PATH, err DBUS_INTERFACE, DBUS_SERVICE, DBUS_PATH, err)
)
if self._allow_offline_iface: if self._allow_offline_iface:
return _OfflineInterface() return _OfflineInterface()
raise RuntimeError("Failed to connect to the presence service.") raise RuntimeError('Failed to connect to the presence '
'service.')
else: else:
self._ps_ = ps self._ps_ = ps
ps.connect_to_signal('BuddyAppeared', ps.connect_to_signal('BuddyAppeared',
@ -150,11 +149,9 @@ class PresenceService(gobject.GObject):
self._private_invitation_cb) self._private_invitation_cb)
return self._ps_ return self._ps_
_ps = property( _ps = property(_get_ps, None, None,
_get_ps, None, None,
"""DBUS interface to the PresenceService """DBUS interface to the PresenceService
(services/presence/presenceservice)""" (services/presence/presenceservice)""")
)
def _new_object(self, object_path): def _new_object(self, object_path):
"""Turn new object path into (cached) Buddy/Activity instance """Turn new object path into (cached) Buddy/Activity instance
@ -207,7 +204,8 @@ class PresenceService(gobject.GObject):
return False return False
def _buddy_appeared_cb(self, op): def _buddy_appeared_cb(self, op):
"""Callback for dbus event (forwards to method to emit GObject event)""" """Callback for dbus event (forwards to method to emit GObject
event)"""
gobject.idle_add(self._emit_buddy_appeared_signal, op) gobject.idle_add(self._emit_buddy_appeared_signal, op)
def _emit_buddy_disappeared_signal(self, object_path): def _emit_buddy_disappeared_signal(self, object_path):
@ -218,9 +216,9 @@ class PresenceService(gobject.GObject):
obj = self._objcache[object_path] obj = self._objcache[object_path]
self.emit('buddy-disappeared', obj) self.emit('buddy-disappeared', obj)
# We cannot maintain the object in the cache because that would keep # We cannot maintain the object in the cache because that would
# a lot of objects from being collected. That includes UI objects # keep a lot of objects from being collected. That includes UI
# due to signals using strong references. # objects due to signals using strong references.
# If we want to cache some despite the memory usage increase, # If we want to cache some despite the memory usage increase,
# we could use a LRU cache limited to some value. # we could use a LRU cache limited to some value.
del self._objcache[object_path] del self._objcache[object_path]
@ -229,7 +227,8 @@ class PresenceService(gobject.GObject):
return False return False
def _buddy_disappeared_cb(self, object_path): def _buddy_disappeared_cb(self, object_path):
"""Callback for dbus event (forwards to method to emit GObject event)""" """Callback for dbus event (forwards to method to emit GObject
event)"""
gobject.idle_add(self._emit_buddy_disappeared_signal, object_path) gobject.idle_add(self._emit_buddy_disappeared_signal, object_path)
def _emit_activity_invitation_signal(self, activity_path, buddy_path, def _emit_activity_invitation_signal(self, activity_path, buddy_path,
@ -240,7 +239,8 @@ class PresenceService(gobject.GObject):
return False return False
def _activity_invitation_cb(self, activity_path, buddy_path, message): def _activity_invitation_cb(self, activity_path, buddy_path, message):
"""Callback for dbus event (forwards to method to emit GObject event)""" """Callback for dbus event (forwards to method to emit GObject
event)"""
gobject.idle_add(self._emit_activity_invitation_signal, activity_path, gobject.idle_add(self._emit_activity_invitation_signal, activity_path,
buddy_path, message) buddy_path, message)
@ -252,7 +252,8 @@ class PresenceService(gobject.GObject):
return False return False
def _private_invitation_cb(self, bus_name, connection, channel, chan_type): def _private_invitation_cb(self, bus_name, connection, channel, chan_type):
"""Callback for dbus event (forwards to method to emit GObject event)""" """Callback for dbus event (forwards to method to emit GObject
event)"""
gobject.idle_add(self._emit_private_invitation_signal, bus_name, gobject.idle_add(self._emit_private_invitation_signal, bus_name,
connection, channel, chan_type) connection, channel, chan_type)
@ -262,7 +263,8 @@ class PresenceService(gobject.GObject):
return False return False
def _activity_appeared_cb(self, object_path): def _activity_appeared_cb(self, object_path):
"""Callback for dbus event (forwards to method to emit GObject event)""" """Callback for dbus event (forwards to method to emit GObject
event)"""
gobject.idle_add(self._emit_activity_appeared_signal, object_path) gobject.idle_add(self._emit_activity_appeared_signal, object_path)
def _emit_activity_disappeared_signal(self, object_path): def _emit_activity_disappeared_signal(self, object_path):
@ -271,7 +273,8 @@ class PresenceService(gobject.GObject):
return False return False
def _activity_disappeared_cb(self, object_path): def _activity_disappeared_cb(self, object_path):
"""Callback for dbus event (forwards to method to emit GObject event)""" """Callback for dbus event (forwards to method to emit GObject
event)"""
gobject.idle_add(self._emit_activity_disappeared_signal, object_path) gobject.idle_add(self._emit_activity_disappeared_signal, object_path)
def get(self, object_path): def get(self, object_path):
@ -288,11 +291,9 @@ class PresenceService(gobject.GObject):
""" """
try: try:
resp = self._ps.GetActivities() resp = self._ps.GetActivities()
except dbus.exceptions.DBusException, err: except dbus.exceptions.DBusException:
_logger.warn( _logger.exception('Unable to retrieve activity list from '
"""Unable to retrieve activity list from presence service: %s""" 'presence service')
% err
)
return [] return []
else: else:
acts = [] acts = []
@ -311,10 +312,8 @@ class PresenceService(gobject.GObject):
if error_handler: if error_handler:
error_handler(e) error_handler(e)
else: else:
_logger.warn( _logger.warn('Unable to retrieve activity-list from presence '
"""Unable to retrieve activity-list from presence service: %s""" 'service: %s', e)
% e
)
def get_activities_async(self, reply_handler=None, error_handler=None): def get_activities_async(self, reply_handler=None, error_handler=None):
"""Retrieve set of all activities from service asyncronously """Retrieve set of all activities from service asyncronously
@ -331,7 +330,6 @@ class PresenceService(gobject.GObject):
error_handler=lambda e: \ error_handler=lambda e: \
self._get_activities_error_cb(error_handler, e)) self._get_activities_error_cb(error_handler, e))
def get_activity(self, activity_id, warn_if_none=True): def get_activity(self, activity_id, warn_if_none=True):
"""Retrieve single Activity object for the given unique id """Retrieve single Activity object for the given unique id
@ -357,11 +355,9 @@ class PresenceService(gobject.GObject):
""" """
try: try:
resp = self._ps.GetBuddies() resp = self._ps.GetBuddies()
except dbus.exceptions.DBusException, err: except dbus.exceptions.DBusException:
_logger.warn( _logger.exception('Unable to retrieve buddy-list from presence '
"""Unable to retrieve buddy-list from presence service: %s""" 'service')
% err
)
return [] return []
else: else:
buddies = [] buddies = []
@ -380,10 +376,8 @@ class PresenceService(gobject.GObject):
if error_handler: if error_handler:
error_handler(e) error_handler(e)
else: else:
_logger.warn( _logger.warn('Unable to retrieve buddy-list from presence '
"""Unable to retrieve buddy-list from presence service: %s""" 'service: %s', e)
% e
)
def get_buddies_async(self, reply_handler=None, error_handler=None): def get_buddies_async(self, reply_handler=None, error_handler=None):
"""Retrieve set of all buddies from service asyncronously """Retrieve set of all buddies from service asyncronously
@ -411,12 +405,9 @@ class PresenceService(gobject.GObject):
""" """
try: try:
buddy_op = self._ps.GetBuddyByPublicKey(dbus.ByteArray(key)) buddy_op = self._ps.GetBuddyByPublicKey(dbus.ByteArray(key))
except dbus.exceptions.DBusException, err: except dbus.exceptions.DBusException:
_logger.warn( _logger.exception('Unable to retrieve buddy handle for %r from '
"""Unable to retrieve buddy handle 'presence service', key)
for %r from presence service: %s"""
% key, err
)
return None return None
return self._new_object(buddy_op) return self._new_object(buddy_op)
@ -450,12 +441,9 @@ class PresenceService(gobject.GObject):
"""Retrieves the laptop "owner" Buddy object.""" """Retrieves the laptop "owner" Buddy object."""
try: try:
owner_op = self._ps.GetOwner() owner_op = self._ps.GetOwner()
except dbus.exceptions.DBusException, err: except dbus.exceptions.DBusException:
_logger.warn( _logger.exception('Unable to retrieve local user/owner from '
"""Unable to retrieve local user/owner 'presence service')
from presence service: %s"""
% err
)
raise RuntimeError("Could not get owner object.") raise RuntimeError("Could not get owner object.")
return self._new_object(owner_op) return self._new_object(owner_op)
@ -526,6 +514,7 @@ class PresenceService(gobject.GObject):
return bus_name, object_path return bus_name, object_path
class _OfflineInterface(object): class _OfflineInterface(object):
"""Offline-presence-service interface """Offline-presence-service interface
@ -535,33 +524,33 @@ class _OfflineInterface( object ):
XXX we could likely return a "MockOwner" object reasonably XXX we could likely return a "MockOwner" object reasonably
easily, but would it be worth it? easily, but would it be worth it?
""" """
def raiseException(self, *args, **named): def raiseException(self, *args, **named):
"""Raise dbus.exceptions.DBusException""" """Raise dbus.exceptions.DBusException"""
raise dbus.exceptions.DBusException( raise dbus.exceptions.DBusException('PresenceService Interface not '
"""PresenceService Interface not available""" 'available')
)
GetActivities = raiseException GetActivities = raiseException
GetActivityById = raiseException GetActivityById = raiseException
GetBuddies = raiseException GetBuddies = raiseException
GetBuddyByPublicKey = raiseException GetBuddyByPublicKey = raiseException
GetOwner = raiseException GetOwner = raiseException
GetPreferredConnection = raiseException GetPreferredConnection = raiseException
def ShareActivity(
self, actid, atype, name, properties, def ShareActivity(self, actid, atype, name, properties, reply_handler,
reply_handler, error_handler, error_handler):
):
"""Pretend to share and fail...""" """Pretend to share and fail..."""
exc = IOError( exc = IOError('Unable to share activity as PresenceService is not '
"""Unable to share activity as PresenceService 'currently available')
is not currenly available"""
)
return error_handler(exc) return error_handler(exc)
class _MockPresenceService(gobject.GObject): class _MockPresenceService(gobject.GObject):
"""Test fixture allowing testing of items that use PresenceService """Test fixture allowing testing of items that use PresenceService
See PresenceService for usage and purpose See PresenceService for usage and purpose
""" """
__gsignals__ = { __gsignals__ = {
'buddy-appeared': (gobject.SIGNAL_RUN_FIRST, gobject.TYPE_NONE, 'buddy-appeared': (gobject.SIGNAL_RUN_FIRST, gobject.TYPE_NONE,
([gobject.TYPE_PYOBJECT])), ([gobject.TYPE_PYOBJECT])),
@ -575,7 +564,7 @@ class _MockPresenceService(gobject.GObject):
'activity-appeared': (gobject.SIGNAL_RUN_FIRST, gobject.TYPE_NONE, 'activity-appeared': (gobject.SIGNAL_RUN_FIRST, gobject.TYPE_NONE,
([gobject.TYPE_PYOBJECT])), ([gobject.TYPE_PYOBJECT])),
'activity-disappeared': (gobject.SIGNAL_RUN_FIRST, gobject.TYPE_NONE, 'activity-disappeared': (gobject.SIGNAL_RUN_FIRST, gobject.TYPE_NONE,
([gobject.TYPE_PYOBJECT])) ([gobject.TYPE_PYOBJECT])),
} }
def __init__(self): def __init__(self):
@ -599,11 +588,13 @@ class _MockPresenceService(gobject.GObject):
def share_activity(self, activity, properties=None): def share_activity(self, activity, properties=None):
return None return None
_ps = None _ps = None
def get_instance(allow_offline_iface=False): def get_instance(allow_offline_iface=False):
"""Retrieve this process' view of the PresenceService""" """Retrieve this process' view of the PresenceService"""
global _ps global _ps
if not _ps: if not _ps:
_ps = PresenceService(allow_offline_iface) _ps = PresenceService(allow_offline_iface)
return _ps return _ps

View File

@ -34,10 +34,10 @@ logger = logging.getLogger('telepathy.tubeconn')
class TubeConnection(Connection): class TubeConnection(Connection):
# pylint: disable-msg=W0212
# Confused by __new__
def __new__(cls, conn, tubes_iface, tube_id, address=None, def __new__(cls, conn, tubes_iface, tube_id, address=None,
group_iface=None, mainloop=None): group_iface=None, mainloop=None):
# pylint: disable-msg=W0212
# Confused by __new__
if address is None: if address is None:
address = tubes_iface.GetDBusTubeAddress(tube_id) address = tubes_iface.GetDBusTubeAddress(tube_id)
self = super(TubeConnection, cls).__new__(cls, address, self = super(TubeConnection, cls).__new__(cls, address,
@ -58,9 +58,9 @@ class TubeConnection(Connection):
return self return self
def _on_get_self_handle_reply(self, handle):
# pylint: disable-msg=W0201 # pylint: disable-msg=W0201
# Confused by __new__ # Confused by __new__
def _on_get_self_handle_reply(self, handle):
self.self_handle = handle self.self_handle = handle
match = self._tubes_iface.connect_to_signal('DBusNamesChanged', match = self._tubes_iface.connect_to_signal('DBusNamesChanged',
self._on_dbus_names_changed) self._on_dbus_names_changed)

View File

@ -29,8 +29,10 @@ from sugar import env
from sugar import util from sugar import util
from sugar.graphics.xocolor import XoColor from sugar.graphics.xocolor import XoColor
_profile = None _profile = None
class Profile(object): class Profile(object):
"""Local user's current options/profile information """Local user's current options/profile information
@ -46,6 +48,7 @@ class Profile(object):
pubkey -- public ssh key pubkey -- public ssh key
privkey_hash -- SHA has of the child's public key privkey_hash -- SHA has of the child's public key
""" """
def __init__(self, path): def __init__(self, path):
self._pubkey = None self._pubkey = None
self._privkey_hash = None self._privkey_hash = None
@ -194,6 +197,7 @@ class Profile(object):
fd.write(text) fd.write(text)
fd.close() fd.close()
def get_profile(): def get_profile():
global _profile global _profile
@ -203,14 +207,17 @@ def get_profile():
return _profile return _profile
def get_nick_name(): def get_nick_name():
client = gconf.client_get_default() client = gconf.client_get_default()
return client.get_string("/desktop/sugar/user/nick") return client.get_string("/desktop/sugar/user/nick")
def get_color(): def get_color():
client = gconf.client_get_default() client = gconf.client_get_default()
color = client.get_string("/desktop/sugar/user/color") color = client.get_string("/desktop/sugar/user/color")
return XoColor(color) return XoColor(color)
def get_pubkey(): def get_pubkey():
return get_profile().pubkey return get_profile().pubkey

View File

@ -23,11 +23,15 @@ import os
from sugar import _sugarext from sugar import _sugarext
class XSMPClient(_sugarext.SMClientXSMP): class XSMPClient(_sugarext.SMClientXSMP):
def __init__(self): def __init__(self):
_sugarext.SMClientXSMP.__init__(self) _sugarext.SMClientXSMP.__init__(self)
class SessionManager(object): class SessionManager(object):
def __init__(self): def __init__(self):
address = _sugarext.xsmp_init() address = _sugarext.xsmp_init()
os.environ['SESSION_MANAGER'] = address os.environ['SESSION_MANAGER'] = address

View File

@ -31,8 +31,10 @@ import logging
import atexit import atexit
import traceback import traceback
_ = lambda msg: gettext.dgettext('sugar-toolkit', msg) _ = lambda msg: gettext.dgettext('sugar-toolkit', msg)
def printable_hash(in_hash): def printable_hash(in_hash):
"""Convert binary hash data into printable characters.""" """Convert binary hash data into printable characters."""
printable = "" printable = ""
@ -40,12 +42,14 @@ def printable_hash(in_hash):
printable = printable + binascii.b2a_hex(char) printable = printable + binascii.b2a_hex(char)
return printable return printable
def sha_data(data): def sha_data(data):
"""sha1 hash some bytes.""" """sha1 hash some bytes."""
sha_hash = hashlib.sha1() sha_hash = hashlib.sha1()
sha_hash.update(data) sha_hash.update(data)
return sha_hash.digest() return sha_hash.digest()
def unique_id(data = ''): def unique_id(data = ''):
"""Generate a likely-unique ID for whatever purpose """Generate a likely-unique ID for whatever purpose
@ -66,6 +70,7 @@ def unique_id(data = ''):
ACTIVITY_ID_LEN = 40 ACTIVITY_ID_LEN = 40
def is_hex(s): def is_hex(s):
try: try:
int(s, 16) int(s, 16)
@ -74,6 +79,7 @@ def is_hex(s):
return True return True
def validate_activity_id(actid): def validate_activity_id(actid):
"""Validate an activity ID.""" """Validate an activity ID."""
if not isinstance(actid, (str, unicode)): if not isinstance(actid, (str, unicode)):
@ -84,6 +90,7 @@ def validate_activity_id(actid):
return False return False
return True return True
def set_proc_title(title): def set_proc_title(title):
"""Sets the process title so ps and top show more """Sets the process title so ps and top show more
descriptive names. This does not modify argv[0] descriptive names. This does not modify argv[0]
@ -106,13 +113,17 @@ def set_proc_title(title):
except Exception: except Exception:
return False return False
class Node(object): class Node(object):
__slots__ = ['prev', 'next', 'me'] __slots__ = ['prev', 'next', 'me']
def __init__(self, prev, me): def __init__(self, prev, me):
self.prev = prev self.prev = prev
self.me = me self.me = me
self.next = None self.next = None
class LRU: class LRU:
""" """
Implementation of a length-limited O(1) LRU queue. Implementation of a length-limited O(1) LRU queue.
@ -120,20 +131,24 @@ class LRU:
http://pype.sourceforge.net http://pype.sourceforge.net
Copyright 2003 Josiah Carlson. Copyright 2003 Josiah Carlson.
""" """
# pylint: disable-msg=W0102,W0612
def __init__(self, count, pairs=[]): def __init__(self, count, pairs=[]):
# pylint: disable-msg=W0102,W0612
self.count = max(count, 1) self.count = max(count, 1)
self.d = {} self.d = {}
self.first = None self.first = None
self.last = None self.last = None
for key, value in pairs: for key, value in pairs:
self[key] = value self[key] = value
def __contains__(self, obj): def __contains__(self, obj):
return obj in self.d return obj in self.d
def __getitem__(self, obj): def __getitem__(self, obj):
a = self.d[obj].me a = self.d[obj].me
self[a[0]] = a[1] self[a[0]] = a[1]
return a[1] return a[1]
def __setitem__(self, obj, val): def __setitem__(self, obj, val):
if obj in self.d: if obj in self.d:
del self[obj] del self[obj]
@ -155,6 +170,7 @@ class LRU:
a.next = None a.next = None
del self.d[a.me[0]] del self.d[a.me[0]]
del a del a
def __delitem__(self, obj): def __delitem__(self, obj):
nobj = self.d[obj] nobj = self.d[obj]
if nobj.prev: if nobj.prev:
@ -166,26 +182,32 @@ class LRU:
else: else:
self.last = nobj.prev self.last = nobj.prev
del self.d[obj] del self.d[obj]
def __iter__(self): def __iter__(self):
cur = self.first cur = self.first
while cur != None: while cur != None:
cur2 = cur.next cur2 = cur.next
yield cur.me[1] yield cur.me[1]
cur = cur2 cur = cur2
def iteritems(self): def iteritems(self):
cur = self.first cur = self.first
while cur != None: while cur != None:
cur2 = cur.next cur2 = cur.next
yield cur.me yield cur.me
cur = cur2 cur = cur2
def iterkeys(self): def iterkeys(self):
return iter(self.d) return iter(self.d)
def itervalues(self): def itervalues(self):
for i, j in self.iteritems(): for i, j in self.iteritems():
yield j yield j
def keys(self): def keys(self):
return self.d.keys() return self.d.keys()
units = [['%d year', '%d years', 356 * 24 * 60 * 60], units = [['%d year', '%d years', 356 * 24 * 60 * 60],
['%d month', '%d months', 30 * 24 * 60 * 60], ['%d month', '%d months', 30 * 24 * 60 * 60],
['%d week', '%d weeks', 7 * 24 * 60 * 60], ['%d week', '%d weeks', 7 * 24 * 60 * 60],
@ -210,9 +232,11 @@ ELAPSED = _('%s ago')
# strings need to be used, then we need to call ngettext() in a fake way so # strings need to be used, then we need to call ngettext() in a fake way so
# xgettext will pick them up as plurals. # xgettext will pick them up as plurals.
def ngettext(singular, plural, n): def ngettext(singular, plural, n):
pass pass
# TRANS: Relative dates (eg. 1 month and 5 days). # TRANS: Relative dates (eg. 1 month and 5 days).
ngettext('%d year', '%d years', 1) ngettext('%d year', '%d years', 1)
ngettext('%d month', '%d months', 1) ngettext('%d month', '%d months', 1)
@ -225,9 +249,11 @@ del ngettext
# End of plurals hack # End of plurals hack
# gettext perfs hack (#7959) # gettext perfs hack (#7959)
_i18n_timestamps_cache = LRU(60) _i18n_timestamps_cache = LRU(60)
def timestamp_to_elapsed_string(timestamp, max_levels=2): def timestamp_to_elapsed_string(timestamp, max_levels=2):
levels = 0 levels = 0
time_period = '' time_period = ''
@ -265,9 +291,12 @@ def timestamp_to_elapsed_string(timestamp, max_levels=2):
return ELAPSED % time_period return ELAPSED % time_period
_tracked_paths = {} _tracked_paths = {}
class TempFilePath(str): class TempFilePath(str):
def __new__(cls, path=None): def __new__(cls, path=None):
if path is None: if path is None:
fd, path = tempfile.mkstemp() fd, path = tempfile.mkstemp()
@ -293,6 +322,7 @@ class TempFilePath(str):
else: else:
_tracked_paths[self] -= 1 _tracked_paths[self] -= 1
def _cleanup_temp_files(): def _cleanup_temp_files():
logging.debug('_cleanup_temp_files') logging.debug('_cleanup_temp_files')
for path in _tracked_paths.keys(): for path in _tracked_paths.keys():

View File

@ -21,6 +21,7 @@ UNSTABLE. Used only internally by Activity and jarabe.
import gtk import gtk
def get_activity_id(wnck_window): def get_activity_id(wnck_window):
window = gtk.gdk.window_foreign_new(wnck_window.get_xid()) window = gtk.gdk.window_foreign_new(wnck_window.get_xid())
prop_info = window.property_get('_SUGAR_ACTIVITY_ID', 'STRING') prop_info = window.property_get('_SUGAR_ACTIVITY_ID', 'STRING')
@ -29,6 +30,7 @@ def get_activity_id(wnck_window):
else: else:
return prop_info[2] return prop_info[2]
def get_bundle_id(wnck_window): def get_bundle_id(wnck_window):
window = gtk.gdk.window_foreign_new(wnck_window.get_xid()) window = gtk.gdk.window_foreign_new(wnck_window.get_xid())
prop_info = window.property_get('_SUGAR_BUNDLE_ID', 'STRING') prop_info = window.property_get('_SUGAR_BUNDLE_ID', 'STRING')
@ -37,10 +39,12 @@ def get_bundle_id(wnck_window):
else: else:
return prop_info[2] return prop_info[2]
def set_activity_id(window, activity_id): def set_activity_id(window, activity_id):
window.property_change('_SUGAR_ACTIVITY_ID', 'STRING', 8, window.property_change('_SUGAR_ACTIVITY_ID', 'STRING', 8,
gtk.gdk.PROP_MODE_REPLACE, activity_id) gtk.gdk.PROP_MODE_REPLACE, activity_id)
def set_bundle_id(window, bundle_id): def set_bundle_id(window, bundle_id):
window.property_change('_SUGAR_BUNDLE_ID', 'STRING', 8, window.property_change('_SUGAR_BUNDLE_ID', 'STRING', 8,
gtk.gdk.PROP_MODE_REPLACE, bundle_id) gtk.gdk.PROP_MODE_REPLACE, bundle_id)