From f6491e6afc2aaf3116d5d15bff4f63a79a7f89fd Mon Sep 17 00:00:00 2001 From: Marco Pesenti Gritti Date: Fri, 12 May 2006 06:32:03 +0000 Subject: Refactor the directory structure to match the packages --- diff --git a/Makefile.am b/Makefile.am index a3aa9e7..4fa44db 100644 --- a/Makefile.am +++ b/Makefile.am @@ -1,10 +1 @@ -SUBDIRS = chat browser shell - -bin_SCRIPTS = sugar - -sugardir = $(pythondir)/sugar -sugar_PYTHON = \ - __init__.py \ - sugar_globals.py - -EXTRA_DIST = sugar +SUBDIRS = sugar diff --git a/__init__.py b/__init__.py deleted file mode 100644 index e69de29..0000000 --- a/__init__.py +++ /dev/null diff --git a/browser/Makefile.am b/browser/Makefile.am deleted file mode 100644 index d55bbfa..0000000 --- a/browser/Makefile.am +++ /dev/null @@ -1,24 +0,0 @@ -sugardir = $(pythondir)/sugar -sugar_PYTHON = browser.py - -icondir = $(pkgdatadir) -icon_DATA = \ - fold.png \ - unfold.png - -# Dbus service file -servicedir = $(datadir)/dbus-1/services -service_in_files = com.redhat.Sugar.Browser.service.in -service_DATA = $(service_in_files:.service.in=.service) - -# Rule to make the service file with bindir expanded -$(service_DATA): $(service_in_files) Makefile - @sed -e "s|\@bindir\@|$(bindir)|" $< > $@ - -EXTRA_DIST = \ - $(service_in_files) \ - $(service_DATA) \ - $(icon_DATA) - -DISTCLEANFILES = \ - $(service_DATA) diff --git a/browser/browser.py b/browser/browser.py deleted file mode 100755 index a41b494..0000000 --- a/browser/browser.py +++ /dev/null @@ -1,289 +0,0 @@ -#!/usr/bin/env python - -import dbus -import dbus.service -import dbus.glib - -import pygtk -pygtk.require('2.0') -import gtk - -import geckoembed - -import sys - -try: - import activity - from sugar_globals import * -except ImportError: - from sugar import activity - from sugar.sugar_globals import * - -class AddressToolbar(gtk.Toolbar): - def __init__(self): - gtk.Toolbar.__init__(self) - - address_item = AddressItem(self.__open_address_cb) - self.insert(address_item, 0) - address_item.show() - - def __open_address_cb(self, address): - BrowserShell.get_instance().open_browser(address) - -class AddressItem(gtk.ToolItem): - def __init__(self, callback): - gtk.ToolItem.__init__(self) - - address_entry = AddressEntry(callback) - self.add(address_entry) - address_entry.show() - -class AddressEntry(gtk.HBox): - def __init__(self, callback): - gtk.HBox.__init__(self) - - self.callback = callback - self.folded = True - - label = gtk.Label("Open") - self.pack_start(label, False) - label.show() - - self.button = gtk.Button() - self.button.set_relief(gtk.RELIEF_NONE) - self.button.connect("clicked", self.__button_clicked_cb) - self.pack_start(self.button, False) - self.button.show() - - self.entry = gtk.Entry() - self.entry.connect("activate", self.__activate_cb) - self.pack_start(self.entry, False) - self.entry.show() - - self._update_folded_state() - - def _update_folded_state(self): - if self.folded: - image = gtk.Image() - image.set_from_file(data_dir + "/unfold.png") - self.button.set_image(image) - image.show() - - self.entry.hide() - else: - image = gtk.Image() - image.set_from_file(data_dir + "/fold.png") - self.button.set_image(image) - image.show() - - self.entry.show() - self.entry.grab_focus() - - def get_folded(self): - return self.folded - - def set_folded(self, folded): - self.folded = not self.folded - self._update_folded_state() - - def __button_clicked_cb(self, button): - self.set_folded(not self.get_folded()) - - def __activate_cb(self, entry): - self.callback(entry.get_text()) - self.set_folded(True) - -class NavigationToolbar(gtk.Toolbar): - def __init__(self, embed): - gtk.Toolbar.__init__(self) - self.embed = embed - - self.set_style(gtk.TOOLBAR_ICONS) - - self.back = gtk.ToolButton(gtk.STOCK_GO_BACK) - self.back.connect("clicked", self.__go_back_cb) - self.insert(self.back, -1) - self.back.show() - - self.forward = gtk.ToolButton(gtk.STOCK_GO_FORWARD) - self.forward.connect("clicked", self.__go_forward_cb) - self.insert(self.forward, -1) - self.forward.show() - - self.reload = gtk.ToolButton(gtk.STOCK_REFRESH) - self.reload.connect("clicked", self.__reload_cb) - self.insert(self.reload, -1) - self.reload.show() - - separator = gtk.SeparatorToolItem() - self.insert(separator, -1) - separator.show() - - share = gtk.ToolButton("Share") - share.connect("clicked", self.__share_cb) - self.insert(share, -1) - share.show() - - separator = gtk.SeparatorToolItem() - self.insert(separator, -1) - separator.show() - - address_item = AddressItem(self.__open_address_cb) - self.insert(address_item, -1) - address_item.show() - - self._update_sensitivity() - - self.embed.connect("location", self.__location_changed) - - def _update_sensitivity(self): - self.back.set_sensitive(self.embed.can_go_back()) - self.forward.set_sensitive(self.embed.can_go_forward()) - - def __go_back_cb(self, button): - self.embed.go_back() - - def __go_forward_cb(self, button): - self.embed.go_forward() - - def __reload_cb(self, button): - self.embed.reload() - - def __share_cb(self, button): - pass - - def __location_changed(self, embed): - self._update_sensitivity() - - def __open_address_cb(self, address): - self.embed.load_address(address) - -class BrowserActivity(activity.Activity): - def __init__(self, uri): - activity.Activity.__init__(self) - self.uri = uri - - def activity_on_connected_to_shell(self): - self.activity_set_ellipsize_tab(True) - self.activity_set_can_close(True) - self.activity_set_tab_text("Web Page") - self.activity_set_tab_icon_name("web-browser") - self.activity_show_icon(True) - - vbox = gtk.VBox() - - self.embed = geckoembed.Embed() - self.embed.connect("title", self.__title_cb) - vbox.pack_start(self.embed) - - self.embed.show() - self.embed.load_address(self.uri) - - nav_toolbar = NavigationToolbar(self.embed) - vbox.pack_start(nav_toolbar, False) - nav_toolbar.show() - - plug = self.activity_get_gtk_plug() - plug.add(vbox) - plug.show() - - vbox.show() - - def get_embed(self): - return self.embed - - def __title_cb(self, embed): - self.activity_set_tab_text(embed.get_title()) - - def activity_on_close_from_user(self): - self.activity_shutdown() - -class WebActivity(activity.Activity): - def __init__(self): - activity.Activity.__init__(self) - - def activity_on_connected_to_shell(self): - self.activity_set_tab_text("Web Browser") - self.activity_set_tab_icon_name("web-browser") - self.activity_show_icon(True) - - vbox = gtk.VBox() - - self.embed = geckoembed.Embed() - self.embed.connect("open-address", self.__open_address); - vbox.pack_start(self.embed) - self.embed.show() - - address_toolbar = AddressToolbar() - vbox.pack_start(address_toolbar, False) - address_toolbar.show() - - plug = self.activity_get_gtk_plug() - plug.add(vbox) - plug.show() - - vbox.show() - - self.embed.load_address("http://www.google.com") - - def __open_address(self, embed, uri, data=None): - if uri.startswith("http://www.google.com"): - return False - else: - BrowserShell.get_instance().open_browser(uri) - return True - - def activity_on_disconnected_from_shell(self): - gtk.main_quit() - gc.collect() - -class BrowserShell(dbus.service.Object): - instance = None - - def get_instance(): - if not BrowserShell.instance: - BrowserShell.instance = BrowserShell() - return BrowserShell.instance - - get_instance = staticmethod(get_instance) - - def __init__(self): - session_bus = dbus.SessionBus() - bus_name = dbus.service.BusName('com.redhat.Sugar.Browser', bus=session_bus) - object_path = '/com/redhat/Sugar/Browser' - - dbus.service.Object.__init__(self, bus_name, object_path) - - self.__browsers = [] - - def open_web_activity(self): - web_activity = WebActivity() - web_activity.activity_connect_to_shell() - - @dbus.service.method('com.redhat.Sugar.BrowserShell') - def get_links(self): - links = [] - for browser in self.__browsers: - embed = browser.get_embed() - link = {} - link['title'] = embed.get_title() - link['address'] = embed.get_address() - links.append(link) - return links - - @dbus.service.method('com.redhat.Sugar.BrowserShell') - def open_browser(self, uri): - browser = BrowserActivity(uri) - self.__browsers.append(browser) - browser.activity_connect_to_shell() - -def main(): - BrowserShell.get_instance().open_web_activity() - - try: - gtk.main() - except KeyboardInterrupt: - pass - -if __name__=="__main__": - main() diff --git a/browser/com.redhat.Sugar.Browser.service.in b/browser/com.redhat.Sugar.Browser.service.in deleted file mode 100644 index 654095a..0000000 --- a/browser/com.redhat.Sugar.Browser.service.in +++ /dev/null @@ -1,3 +0,0 @@ -[D-BUS Service] -Name=com.redhat.Sugar.Browser -Exec=@bindir@/sugar browser diff --git a/browser/fold.png b/browser/fold.png deleted file mode 100644 index cd4169b..0000000 --- a/browser/fold.png +++ /dev/null Binary files differ diff --git a/browser/unfold.png b/browser/unfold.png deleted file mode 100644 index f3f82fa..0000000 --- a/browser/unfold.png +++ /dev/null Binary files differ diff --git a/chat/BuddyList.py b/chat/BuddyList.py deleted file mode 100644 index d35fa84..0000000 --- a/chat/BuddyList.py +++ /dev/null @@ -1,121 +0,0 @@ -# -*- tab-width: 4; indent-tabs-mode: t -*- - -import presence -import avahi - -ACTION_BUDDY_ADDED = "added" -ACTION_BUDDY_REMOVED = "removed" - - -class Buddy(object): - def __init__(self, nick, realname, servicename, host, address, port, key=None): - self._nick = nick - self._realname = realname - self._servicename = servicename - self._key = key - self._host = host - self._address = str(address) - self._port = int(port) - self._chat = None - - def set_chat(self, chat): - self._chat = chat - - def chat(self): - return self._chat - - def nick(self): - return self._nick - - def realname(self): - return self._realname - - def servicename(self): - return self._servicename - - def host(self): - return self._host - - def address(self): - return self._address - - def port(self): - return self._port - - def key(self): - return self._key - -class BuddyList(object): - """ Manage a list of buddies """ - - def __init__(self, servicename): - self._listeners = [] - self._buddies = {} - self._servicename = servicename - self._pdiscovery = presence.PresenceDiscovery() - self._pdiscovery.add_service_listener(self._on_service_change) - - def start(self): - self._pdiscovery.start() - - def add_buddy_listener(self, listener): - self._listeners.append(listener) - - def _add_buddy(self, host, address, port, servicename, data): - # Ignore ourselves - if servicename == self._servicename: - return - - if len(data) > 0 and 'name' in data.keys(): - buddy = self._find_buddy_by_service_name(servicename) - if not buddy: - buddy = Buddy(data['name'], data['realname'], servicename, host, address, port) - self._buddies[data['name']] = buddy - self._notify_listeners(ACTION_BUDDY_ADDED, buddy) - - def _remove_buddy(self, buddy): - nick = buddy.nick() - self._notify_listeners(ACTION_BUDDY_REMOVED, buddy) - del self._buddies[nick] - - def _find_buddy_by_service_name(self, servicename): - for buddy in self._buddies.values(): - if buddy.servicename() == servicename: - return buddy - return None - - def find_buddy_by_address(self, address): - for buddy_name in self._buddies.keys(): - buddy = self._buddies[buddy_name] - if buddy.address() == address: - return buddy - return None - - def _notify_listeners(self, action, buddy): - for listener in self._listeners: - listener(action, buddy) - - def _on_service_change(self, action, interface, protocol, name, stype, domain, flags): - if stype != presence.OLPC_CHAT_SERVICE: - return - if action == presence.ACTION_SERVICE_NEW: - self._pdiscovery.resolve_service(interface, protocol, name, stype, domain, self._on_service_resolved) - elif action == presence.ACTION_SERVICE_REMOVED: - buddy = self._find_buddy_by_service_name(name) - if buddy: - self._remove_buddy(buddy) - - def _pair_to_dict(self, l): - res = {} - for el in l: - tmp = el.split('=', 1) - if len(tmp) > 1: - res[tmp[0]] = tmp[1] - else: - res[tmp[0]] = '' - return res - - def _on_service_resolved(self, interface, protocol, name, stype, domain, host, aprotocol, address, port, txt, flags): - data = self._pair_to_dict(avahi.txt_array_to_string_array(txt)) - self._add_buddy(host, address, port, name, data) - diff --git a/chat/Makefile.am b/chat/Makefile.am deleted file mode 100644 index 526e546..0000000 --- a/chat/Makefile.am +++ /dev/null @@ -1,11 +0,0 @@ -sugardir = $(pythondir)/sugar -sugar_PYTHON = \ - chat.py \ - richtext.py - -icondir = $(pkgdatadir) -icon_DATA = \ - bubble.png \ - bubbleOutline.png - -EXTRA_DIST = $(icon_DATA) diff --git a/chat/SVGdraw.py b/chat/SVGdraw.py deleted file mode 100644 index abcda11..0000000 --- a/chat/SVGdraw.py +++ /dev/null @@ -1,1069 +0,0 @@ -#!/usr/bin/env python -##Copyright (c) 2002, Fedor Baart & Hans de Wit (Stichting Farmaceutische Kengetallen) -##All rights reserved. -## -##Redistribution and use in source and binary forms, with or without modification, -##are permitted provided that the following conditions are met: -## -##Redistributions of source code must retain the above copyright notice, this -##list of conditions and the following disclaimer. -## -##Redistributions in binary form must reproduce the above copyright notice, -##this list of conditions and the following disclaimer in the documentation and/or -##other materials provided with the distribution. -## -##Neither the name of the Stichting Farmaceutische Kengetallen nor the names of -##its contributors may be used to endorse or promote products derived from this -##software without specific prior written permission. -## -##THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" -##AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -##IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE -##DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE -##FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL -##DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR -##SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER -##CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, -##OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -##OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -##Thanks to Gerald Rosennfellner for his help and useful comments. - -__doc__="""Use SVGdraw to generate your SVGdrawings. - -SVGdraw uses an object model drawing and a method toXML to create SVG graphics -by using easy to use classes and methods usualy you start by creating a drawing eg - - d=drawing() - #then you create a SVG root element - s=svg() - #then you add some elements eg a circle and add it to the svg root element - c=circle() - #you can supply attributes by using named arguments. - c=circle(fill='red',stroke='blue') - #or by updating the attributes attribute: - c.attributes['stroke-width']=1 - s.addElement(c) - #then you add the svg root element to the drawing - d.setSVG(s) - #and finaly you xmlify the drawing - d.toXml() - - -this results in the svg source of the drawing, which consists of a circle -on a white background. Its as easy as that;) -This module was created using the SVG specification of www.w3c.org and the -O'Reilly (www.oreilly.com) python books as information sources. A svg viewer -is available from www.adobe.com""" - -__version__="1.0" - -# there are two possibilities to generate svg: -# via a dom implementation and directly using text strings -# the latter is way faster (and shorter in coding) -# the former is only used in debugging svg programs -# maybe it will be removed alltogether after a while -# with the following variable you indicate whether to use the dom implementation -# Note that PyXML is required for using the dom implementation. -# It is also possible to use the standard minidom. But I didn't try that one. -# Anyway the text based approach is about 60 times faster than using the full dom implementation. -use_dom_implementation=0 - - -import exceptions -if use_dom_implementation<>0: - try: - from xml.dom import implementation - from xml.dom.ext import PrettyPrint - except: - raise exceptions.ImportError, "PyXML is required for using the dom implementation" -#The implementation is used for the creating the XML document. -#The prettyprint module is used for converting the xml document object to a xml file - -import sys -assert sys.version_info[0]>=2 -if sys.version_info[1]<2: - True=1 - False=0 - file=open - -sys.setrecursionlimit=50 -#The recursion limit is set conservative so mistakes like s=svg() s.addElement(s) -#won't eat up too much processor time. - -xlinkNSRef = "http://www.w3.org/1999/xlink" - -#the following code is pasted form xml.sax.saxutils -#it makes it possible to run the code without the xml sax package installed -#To make it possible to have in your text elements, it is necessary to escape the texts -def _escape(data, entities={}): - """Escape &, <, and > in a string of data. - - You can escape other strings of data by passing a dictionary as - the optional entities parameter. The keys and values must all be - strings; each key will be replaced with its corresponding value. - """ - data = data.replace("&", "&") - data = data.replace("<", "<") - data = data.replace(">", ">") - for chars, entity in entities.items(): - data = data.replace(chars, entity) - return data - -def _quoteattr(data, entities={}): - """Escape and quote an attribute value. - - Escape &, <, and > in a string of data, then quote it for use as - an attribute value. The \" character will be escaped as well, if - necessary. - - You can escape other strings of data by passing a dictionary as - the optional entities parameter. The keys and values must all be - strings; each key will be replaced with its corresponding value. - """ - data = _escape(data, entities) - if '"' in data: - if "'" in data: - data = '"%s"' % data.replace('"', """) - else: - data = "'%s'" % data - else: - data = '"%s"' % data - return data - - - -def _xypointlist(a): - """formats a list of xy pairs""" - s='' - for e in a: #this could be done more elegant - s+=str(e)[1:-1] +' ' - return s - -def _viewboxlist(a): - """formats a tuple""" - s='' - for e in a: - s+=str(e)+' ' - return s - -def _pointlist(a): - """formats a list of numbers""" - return str(a)[1:-1] - -class pathdata: - """class used to create a pathdata object which can be used for a path. - although most methods are pretty straightforward it might be useful to look at the SVG specification.""" - #I didn't test the methods below. - def __init__(self,x=None,y=None): - self.path=[] - if x is not None and y is not None: - self.path.append('M '+str(x)+' '+str(y)) - def closepath(self): - """ends the path""" - self.path.append('z') - def move(self,x,y): - """move to absolute""" - self.path.append('M '+str(x)+' '+str(y)) - def relmove(self,x,y): - """move to relative""" - self.path.append('m '+str(x)+' '+str(y)) - def line(self,x,y): - """line to absolute""" - self.path.append('L '+str(x)+' '+str(y)) - def relline(self,x,y): - """line to relative""" - self.path.append('l '+str(x)+' '+str(y)) - def hline(self,x): - """horizontal line to absolute""" - self.path.append('H'+str(x)) - def relhline(self,x): - """horizontal line to relative""" - self.path.append('h'+str(x)) - def vline(self,y): - """verical line to absolute""" - self.path.append('V'+str(y)) - def relvline(self,y): - """vertical line to relative""" - self.path.append('v'+str(y)) - def bezier(self,x1,y1,x2,y2,x,y): - """bezier with xy1 and xy2 to xy absolut""" - self.path.append('C'+str(x1)+','+str(y1)+' '+str(x2)+','+str(y2)+' '+str(x)+','+str(y)) - def relbezier(self,x1,y1,x2,y2,x,y): - """bezier with xy1 and xy2 to xy relative""" - self.path.append('c'+str(x1)+','+str(y1)+' '+str(x2)+','+str(y2)+' '+str(x)+','+str(y)) - def smbezier(self,x2,y2,x,y): - """smooth bezier with xy2 to xy absolut""" - self.path.append('S'+str(x2)+','+str(y2)+' '+str(x)+','+str(y)) - def relsmbezier(self,x2,y2,x,y): - """smooth bezier with xy2 to xy relative""" - self.path.append('s'+str(x2)+','+str(y2)+' '+str(x)+','+str(y)) - def qbezier(self,x1,y1,x,y): - """quadratic bezier with xy1 to xy absolut""" - self.path.append('Q'+str(x1)+','+str(y1)+' '+str(x)+','+str(y)) - def relqbezier(self,x1,y1,x,y): - """quadratic bezier with xy1 to xy relative""" - self.path.append('q'+str(x1)+','+str(y1)+' '+str(x)+','+str(y)) - def smqbezier(self,x,y): - """smooth quadratic bezier to xy absolut""" - self.path.append('T'+str(x)+','+str(y)) - def relsmqbezier(self,x,y): - """smooth quadratic bezier to xy relative""" - self.path.append('t'+str(x)+','+str(y)) - def ellarc(self,rx,ry,xrot,laf,sf,x,y): - """elliptival arc with rx and ry rotating with xrot using large-arc-flag and sweep-flag to xy absolut""" - self.path.append('A'+str(rx)+','+str(ry)+' '+str(xrot)+' '+str(laf)+' '+str(sf)+' '+str(x)+' '+str(y)) - def relellarc(self,rx,ry,xrot,laf,sf,x,y): - """elliptival arc with rx and ry rotating with xrot using large-arc-flag and sweep-flag to xy relative""" - self.path.append('a'+str(rx)+','+str(ry)+' '+str(xrot)+' '+str(laf)+' '+str(sf)+' '+str(x)+' '+str(y)) - def __repr__(self): - return ' '.join(self.path) - - -class Attribute: - def __init__(self, name, value, nsname=None, nsref=None): - self.name = name - self.value = value - self.nsname = nsname - self.nsref = nsref - -class SVGelement: - """SVGelement(type,attributes,elements,text,namespace,**args) - Creates a arbitrary svg element and is intended to be subclassed not used on its own. - This element is the base of every svg element it defines a class which resembles - a xml-element. The main advantage of this kind of implementation is that you don't - have to create a toXML method for every different graph object. Every element - consists of a type, attribute, optional subelements, optional text and an optional - namespace. Note the elements==None, if elements = None:self.elements=[] construction. - This is done because if you default to elements=[] every object has a reference - to the same empty list.""" - def __init__(self,type='',attributes=None,elements=None,text='',namespace='',cdata=None,**args): - self.type=type - self._attributes={} - if attributes: - for key, value in attributes.items(): - attr = Attribute(key, value) - self._attributes[key] = attr - self.elements=[] - if elements: - self.elements=elements - self.text=text - self.namespace=namespace - self.cdata=cdata - for key, value in args.items(): - attr = Attribute(key, value) - self._attributes[key] = attr - self._parent = None - - def addElement(self,SVGelement): - """adds an element to a SVGelement - - SVGelement.addElement(SVGelement) - """ - self.elements.append(SVGelement) - SVGelement.setParent(self) - - def setParent(self, parent): - self._parent = parent - - def addAttribute(self, attribute): - self._attributes[attribute.name] = attribute - - def toXml(self,level,f): - f.write('\t'*level) - f.write('<'+self.type) - if self.namespace: - f.write(' xmlns="'+ _escape(str(self.namespace))+'" ') - for attkey, attr in self._attributes.items(): - if attr.nsname: - f.write(' xmlns:'+_escape(str(attr.nsname))+'="'+_escape(str(attr.nsref))+'" ') - f.write(' '+_escape(str(attr.nsname))+':'+_escape(str(attkey))+'='+_quoteattr(str(attr.value))) - else: - f.write(' '+_escape(str(attkey))+'='+_quoteattr(str(attr.value))) - if self.elements or self.text or self.cdata: - f.write('>') - if self.elements: - f.write('\n') - for element in self.elements: - element.toXml(level+1,f) - if self.cdata: - f.write('\n'+'\t'*(level+1)+'\n') - if self.text: - if type(self.text)==type(''): #If the text is only text - f.write(_escape(str(self.text))) - else: #If the text is a spannedtext class - f.write(str(self.text)) - if self.elements: - f.write('\t'*level+'\n') - elif self.text: - f.write('\n') - elif self.cdata: - f.write('\t'*level+'\n') - else: - f.write('/>\n') - -class tspan(SVGelement): - """ts=tspan(text='',**args) - - a tspan element can be used for applying formatting to a textsection - usage: - ts=tspan('this text is bold') - ts.attributes['font-weight']='bold' - st=spannedtext() - st.addtspan(ts) - t=text(3,5,st) - """ - def __init__(self,text=None,**args): - SVGelement.__init__(self,'tspan',**args) - if self.text<>None: - self.text=text - def __repr__(self): - s="None: - raise ValueError, 'height is required' - if height<>None: - raise ValueError, 'width is required' - else: - raise ValueError, 'both height and width are required' - SVGelement.__init__(self,'rect',{'width':width,'height':height},**args) - if x<>None: - self.addAttribute(Attribute('x', x)) - if y<>None: - self.addAttribute(Attribute('y', y)) - if fill<>None: - self.addAttribute(Attribute('fill', fill)) - if stroke<>None: - self.addAttribute(Attribute('stroke', stroke)) - if stroke_width<>None: - self.addAttribute(Attribute('stroke-width', stroke_width)) - -class ellipse(SVGelement): - """e=ellipse(rx,ry,x,y,fill,stroke,stroke_width,**args) - - an ellipse is defined as a center and a x and y radius. - """ - def __init__(self,cx=None,cy=None,rx=None,ry=None,fill=None,stroke=None,stroke_width=None,**args): - if rx==None or ry== None: - if rx<>None: - raise ValueError, 'rx is required' - if ry<>None: - raise ValueError, 'ry is required' - else: - raise ValueError, 'both rx and ry are required' - SVGelement.__init__(self,'ellipse',{'rx':rx,'ry':ry},**args) - if cx<>None: - self.addAttribute(Attribute('cx', cx)) - if cy<>None: - self.addAttribute(Attribute('cy', cy)) - if fill<>None: - self.addAttribute(Attribute('fill', fill)) - if stroke<>None: - self.addAttribute(Attribute('stroke', stroke)) - if stroke_width<>None: - self.addAttribute(Attribute('stroke-width', stroke_width)) - - -class circle(SVGelement): - """c=circle(x,y,radius,fill,stroke,stroke_width,**args) - - The circle creates an element using a x, y and radius values eg - """ - def __init__(self,cx=None,cy=None,r=None,fill=None,stroke=None,stroke_width=None,**args): - if r==None: - raise ValueError, 'r is required' - SVGelement.__init__(self,'circle',{'r':r},**args) - if cx<>None: - self.addAttribute(Attribute('cx', cx)) - if cy<>None: - self.addAttribute(Attribute('cy', cy)) - if fill<>None: - self.addAttribute(Attribute('fill', fill)) - if stroke<>None: - self.addAttribute(Attribute('stroke', stroke)) - if stroke_width<>None: - self.addAttribute(Attribute('stroke-width', stroke_width)) - -class point(circle): - """p=point(x,y,color) - - A point is defined as a circle with a size 1 radius. It may be more efficient to use a - very small rectangle if you use many points because a circle is difficult to render. - """ - def __init__(self,x,y,fill='black',**args): - circle.__init__(self,x,y,1,fill,**args) - -class line(SVGelement): - """l=line(x1,y1,x2,y2,stroke,stroke_width,**args) - - A line is defined by a begin x,y pair and an end x,y pair - """ - def __init__(self,x1=None,y1=None,x2=None,y2=None,stroke=None,stroke_width=None,**args): - SVGelement.__init__(self,'line',**args) - if x1<>None: - self.addAttribute(Attribute('x1', x1)) - if y1<>None: - self.addAttribute(Attribute('y1', y1)) - if x2<>None: - self.addAttribute(Attribute('x2', x2)) - if y2<>None: - self.addAttribute(Attribute('y2', y2)) - if stroke_width<>None: - self.addAttribute(Attribute('stroke-width', stroke_width)) - if stroke<>None: - self.addAttribute(Attribute('stroke', stroke)) - -class polyline(SVGelement): - """pl=polyline([[x1,y1],[x2,y2],...],fill,stroke,stroke_width,**args) - - a polyline is defined by a list of xy pairs - """ - def __init__(self,points,fill=None,stroke=None,stroke_width=None,**args): - SVGelement.__init__(self,'polyline',{'points':_xypointlist(points)},**args) - if fill<>None: - self.addAttribute(Attribute('fill', fill)) - if stroke_width<>None: - self.addAttribute(Attribute('stroke-width', stroke_width)) - if stroke<>None: - self.addAttribute(Attribute('stroke', stroke)) - -class polygon(SVGelement): - """pl=polyline([[x1,y1],[x2,y2],...],fill,stroke,stroke_width,**args) - - a polygon is defined by a list of xy pairs - """ - def __init__(self,points,fill=None,stroke=None,stroke_width=None,**args): - SVGelement.__init__(self,'polygon',{'points':_xypointlist(points)},**args) - if fill<>None: - self.addAttribute(Attribute('fill', fill)) - if stroke_width<>None: - self.addAttribute(Attribute('stroke-width', stroke_width)) - if stroke<>None: - self.addAttribute(Attribute('stroke', stroke)) - -class path(SVGelement): - """p=path(path,fill,stroke,stroke_width,**args) - - a path is defined by a path object and optional width, stroke and fillcolor - """ - def __init__(self,pathdata,fill=None,stroke=None,stroke_width=None,id=None,**args): - SVGelement.__init__(self,'path',{'d':str(pathdata)},**args) - if stroke<>None: - self.addAttribute(Attribute('stroke', stroke)) - if fill<>None: - self.addAttribute(Attribute('fill', fill)) - if stroke_width<>None: - self.addAttribute(Attribute('stroke-width', stroke_width)) - if id<>None: - self.addAttribute(Attribute('id', id)) - - -class text(SVGelement): - """t=text(x,y,text,font_size,font_family,**args) - - a text element can bge used for displaying text on the screen - """ - def __init__(self,x=None,y=None,text=None,font_size=None,font_family=None,text_anchor=None,**args): - SVGelement.__init__(self,'text',**args) - if x<>None: - self.addAttribute(Attribute('x', x)) - if y<>None: - self.addAttribute(Attribute('y', y)) - if font_size<>None: - self.addAttribute(Attribute('font-size', font_size)) - if font_family<>None: - self.addAttribute(Attribute('font-family', font_family)) - if text<>None: - self.text=text - if text_anchor<>None: - self.addAttribute(Attribute('text-anchor', text_anchor)) - - -class textpath(SVGelement): - """tp=textpath(text,link,**args) - - a textpath places a text on a path which is referenced by a link. - """ - def __init__(self,link,text=None,**args): - SVGelement.__init__(self,'textPath',**args) - self.addAttribute(Attribute('href', link, 'xlink', xlinkNSRef)) - if text<>None: - self.text=text - -class pattern(SVGelement): - """p=pattern(x,y,width,height,patternUnits,**args) - - A pattern is used to fill or stroke an object using a pre-defined - graphic object which can be replicated ("tiled") at fixed intervals - in x and y to cover the areas to be painted. - """ - def __init__(self,x=None,y=None,width=None,height=None,patternUnits=None,**args): - SVGelement.__init__(self,'pattern',**args) - if x<>None: - self.addAttribute(Attribute('x', x)) - if y<>None: - self.addAttribute(Attribute('y', y)) - if width<>None: - self.addAttribute(Attribute('width', width)) - if height<>None: - self.addAttribute(Attribute('height', height)) - if patternUnits<>None: - self.addAttribute(Attribute('patternUnits', patternUnits)) - -class title(SVGelement): - """t=title(text,**args) - - a title is a text element. The text is displayed in the title bar - add at least one to the root svg element - """ - def __init__(self,text=None,**args): - SVGelement.__init__(self,'title',**args) - if text<>None: - self.text=text - -class description(SVGelement): - """d=description(text,**args) - - a description can be added to any element and is used for a tooltip - Add this element before adding other elements. - """ - def __init__(self,text=None,**args): - SVGelement.__init__(self,'desc',**args) - if text<>None: - self.text=text - -class lineargradient(SVGelement): - """lg=lineargradient(x1,y1,x2,y2,id,**args) - - defines a lineargradient using two xy pairs. - stop elements van be added to define the gradient colors. - """ - def __init__(self,x1=None,y1=None,x2=None,y2=None,id=None,**args): - SVGelement.__init__(self,'linearGradient',**args) - if x1<>None: - self.addAttribute(Attribute('x1', x1)) - if y1<>None: - self.addAttribute(Attribute('y1', y1)) - if x2<>None: - self.addAttribute(Attribute('x2', x2)) - if y2<>None: - self.addAttribute(Attribute('y2', y2)) - if id<>None: - self.addAttribute(Attribute('id', id)) - -class radialgradient(SVGelement): - """rg=radialgradient(cx,cy,r,fx,fy,id,**args) - - defines a radial gradient using a outer circle which are defined by a cx,cy and r and by using a focalpoint. - stop elements van be added to define the gradient colors. - """ - def __init__(self,cx=None,cy=None,r=None,fx=None,fy=None,id=None,**args): - SVGelement.__init__(self,'radialGradient',**args) - if cx<>None: - self.addAttribute(Attribute('cx', cx)) - if cy<>None: - self.addAttribute(Attribute('cy', cy)) - if r<>None: - self.addAttribute(Attribute('r', r)) - if fx<>None: - self.addAttribute(Attribute('fx', fx)) - if fy<>None: - self.addAttribute(Attribute('fy', fy)) - if id<>None: - self.addAttribute(Attribute('id', id)) - -class stop(SVGelement): - """st=stop(offset,stop_color,**args) - - Puts a stop color at the specified radius - """ - def __init__(self,offset,stop_color=None,**args): - SVGelement.__init__(self,'stop',{'offset':offset},**args) - if stop_color<>None: - self.addAttribute(Attribute('stop-color', stop_color)) - -class style(SVGelement): - """st=style(type,cdata=None,**args) - - Add a CDATA element to this element for defing in line stylesheets etc.. - """ - def __init__(self,type,cdata=None,**args): - SVGelement.__init__(self,'style',{'type':type},cdata=cdata, **args) - - -class image(SVGelement): - """im=image(url,width,height,x,y,**args) - - adds an image to the drawing. Supported formats are .png, .jpg and .svg. - """ - def __init__(self,url,x=None,y=None,width=None,height=None,**args): - if width==None or height==None: - if width<>None: - raise ValueError, 'height is required' - if height<>None: - raise ValueError, 'width is required' - else: - raise ValueError, 'both height and width are required' - SVGelement.__init__(self,'image',{'width':width,'height':height},**args) - self.addAttribute(Attribute('href', url, 'xlink', xlinkNSRef)) - if x<>None: - self.addAttribute(Attribute('x', x)) - if y<>None: - self.addAttribute(Attribute('y', y)) - -class cursor(SVGelement): - """c=cursor(url,**args) - - defines a custom cursor for a element or a drawing - """ - def __init__(self,url,**args): - SVGelement.__init__(self,'cursor',**args) - self.addAttribute(Attribute('href', url, 'xlink', xlinkNSRef)) - - -class marker(SVGelement): - """m=marker(id,viewbox,refX,refY,markerWidth,markerHeight,**args) - - defines a marker which can be used as an endpoint for a line or other pathtypes - add an element to it which should be used as a marker. - """ - def __init__(self,id=None,viewBox=None,refx=None,refy=None,markerWidth=None,markerHeight=None,**args): - SVGelement.__init__(self,'marker',**args) - if id<>None: - self.addAttribute(Attribute('id', id)) - if viewBox<>None: - self.addAttribute(Attribute('viewBox', _viewboxlist(viewBox))) - if refx<>None: - self.addAttribute(Attribute('refX', refx)) - if refy<>None: - self.addAttribute(Attribute('refY', refy)) - if markerWidth<>None: - self.addAttribute(Attribute('markerWidth', markerWidth)) - if markerHeight<>None: - self.addAttribute(Attribute('markerHeight', markerHeight)) - -class group(SVGelement): - """g=group(id,**args) - - a group is defined by an id and is used to contain elements - g.addElement(SVGelement) - """ - def __init__(self,id=None,**args): - SVGelement.__init__(self,'g',**args) - if id<>None: - self.addAttribute(Attribute('id', id)) - -class symbol(SVGelement): - """sy=symbol(id,viewbox,**args) - - defines a symbol which can be used on different places in your graph using - the use element. A symbol is not rendered but you can use 'use' elements to - display it by referencing its id. - sy.addElement(SVGelement) - """ - - def __init__(self,id=None,viewBox=None,**args): - SVGelement.__init__(self,'symbol',**args) - if id<>None: - self.addAttribute(Attribute('id', id)) - if viewBox<>None: - self.addAttribute(Attribute('viewBox', _viewboxlist(viewBox))) - -class defs(SVGelement): - """d=defs(**args) - - container for defining elements - """ - def __init__(self,**args): - SVGelement.__init__(self,'defs',**args) - -class switch(SVGelement): - """sw=switch(**args) - - Elements added to a switch element which are "switched" by the attributes - requiredFeatures, requiredExtensions and systemLanguage. - Refer to the SVG specification for details. - """ - def __init__(self,**args): - SVGelement.__init__(self,'switch',**args) - - -class use(SVGelement): - """u=use(link,x,y,width,height,**args) - - references a symbol by linking to its id and its position, height and width - """ - def __init__(self,link,x=None,y=None,width=None,height=None,**args): - SVGelement.__init__(self,'use',**args) - self.addAttribute(Attribute('href', link, 'xlink', xlinkNSRef)) - if x<>None: - self.addAttribute(Attribute('x', x)) - if y<>None: - self.addAttribute(Attribute('y', y)) - - if width<>None: - self.addAttribute(Attribute('width', width)) - if height<>None: - self.addAttribute(Attribute('height', height)) - - -class link(SVGelement): - """a=link(url,**args) - - a link is defined by a hyperlink. add elements which have to be linked - a.addElement(SVGelement) - """ - def __init__(self,link='',**args): - SVGelement.__init__(self,'a',**args) - self.addAttribute(Attribute('href', link, 'xlink', xlinkNSRef)) - -class view(SVGelement): - """v=view(id,**args) - - a view can be used to create a view with different attributes""" - def __init__(self,id=None,**args): - SVGelement.__init__(self,'view',**args) - if id<>None: - self.addAttribute(Attribute('id', id)) - -class script(SVGelement): - """sc=script(type,type,cdata,**args) - - adds a script element which contains CDATA to the SVG drawing - - """ - def __init__(self,type,cdata=None,**args): - SVGelement.__init__(self,'script',{'type':type},cdata=cdata,**args) - -class animate(SVGelement): - """an=animate(attribute,from,to,during,**args) - - animates an attribute. - """ - def __init__(self,attribute,fr=None,to=None,dur=None,**args): - SVGelement.__init__(self,'animate',{'attributeName':attribute},**args) - if fr<>None: - self.addAttribute(Attribute('from', fr)) - if to<>None: - self.addAttribute(Attribute('to', to)) - if dur<>None: - self.addAttribute(Attribute('dur', dur)) - -class animateMotion(SVGelement): - """an=animateMotion(pathdata,dur,**args) - - animates a SVGelement over the given path in dur seconds - """ - def __init__(self,pathdata,dur,**args): - SVGelement.__init__(self,'animateMotion',**args) - if pathdata<>None: - self.addAttribute(Attribute('path', str(pathdata))) - if dur<>None: - self.addAttribute(Attribute('dur', dur)) - -class animateTransform(SVGelement): - """antr=animateTransform(type,from,to,dur,**args) - - transform an element from and to a value. - """ - def __init__(self,type=None,fr=None,to=None,dur=None,**args): - SVGelement.__init__(self,'animateTransform',{'attributeName':'transform'},**args) - #As far as I know the attributeName is always transform - if type<>None: - self.addAttribute(Attribute('type', type)) - if fr<>None: - self.addAttribute(Attribute('from', fr)) - if to<>None: - self.addAttribute(Attribute('to', to)) - if dur<>None: - self.addAttribute(Attribute('dur', dur)) -class animateColor(SVGelement): - """ac=animateColor(attribute,type,from,to,dur,**args) - - Animates the color of a element - """ - def __init__(self,attribute,type=None,fr=None,to=None,dur=None,**args): - SVGelement.__init__(self,'animateColor',{'attributeName':attribute},**args) - if type<>None: - self.addAttribute(Attribute('type', type)) - if fr<>None: - self.addAttribute(Attribute('from', fr)) - if to<>None: - self.addAttribute(Attribute('to', to)) - if dur<>None: - self.addAttribute(Attribute('dur', dur)) -class set(SVGelement): - """st=set(attribute,to,during,**args) - - sets an attribute to a value for a - """ - def __init__(self,attribute,to=None,dur=None,**args): - SVGelement.__init__(self,'set',{'attributeName':attribute},**args) - if to<>None: - self.addAttribute(Attribute('to', to)) - if dur<>None: - self.addAttribute(Attribute('dur', dur)) - - - -class svg(SVGelement): - """s=svg(viewbox,width,height,**args) - - a svg or element is the root of a drawing add all elements to a svg element. - You can have different svg elements in one svg file - s.addElement(SVGelement) - - eg - d=drawing() - s=svg((0,0,100,100),'100%','100%') - c=circle(50,50,20) - s.addElement(c) - d.setSVG(s) - d.toXml() - """ - def __init__(self,viewBox=None, width=None, height=None,**args): - SVGelement.__init__(self,'svg',**args) - if viewBox<>None: - self.addAttribute(Attribute('viewBox', _viewboxlist(viewBox))) - if width<>None: - self.addAttribute(Attribute('width', width)) - if height<>None: - self.addAttribute(Attribute('height', height_)) - self.namespace="http://www.w3.org/2000/svg" - -class drawing: - """d=drawing() - - this is the actual SVG document. It needs a svg element as a root. - Use the addSVG method to set the svg to the root. Use the toXml method to write the SVG - source to the screen or to a file - d=drawing() - d.addSVG(svg) - d.toXml(optionalfilename) - """ - - def __init__(self): - self.svg=None - - def setSVG(self,svg): - self.svg=svg - #Voeg een element toe aan de grafiek toe. - - if use_dom_implementation==0: - def toXml(self, filename='',compress=False): - import cStringIO - xml=cStringIO.StringIO() - xml.write("\n") - xml.write("\n") - self.svg.toXml(0,xml) - if not filename: - if compress: - import gzip - f=cStringIO.StringIO() - zf=gzip.GzipFile(fileobj=f,mode='wb') - zf.write(xml.getvalue()) - zf.close() - f.seek(0) - return f.read() - else: - return xml.getvalue() - else: - if filename[-4:]=='svgz': - import gzip - f=gzip.GzipFile(filename=filename,mode="wb", compresslevel=9) - f.write(xml.getvalue()) - f.close() - else: - f=file(filename,'w') - f.write(xml.getvalue()) - f.close() - - else: - def toXml(self,filename='',compress=False): - """drawing.toXml() ---->to the screen - drawing.toXml(filename)---->to the file - writes a svg drawing to the screen or to a file - compresses if filename ends with svgz or if compress is true - """ - doctype = implementation.createDocumentType('svg',"-//W3C//DTD SVG 1.0//EN""",'http://www.w3.org/TR/2001/REC-SVG-20010904/DTD/svg10.dtd ') - - global root - #root is defined global so it can be used by the appender. Its also possible to use it as an arugument but - #that is a bit messy. - root=implementation.createDocument(None,None,doctype) - #Create the xml document. - global appender - def appender(element,elementroot): - """This recursive function appends elements to an element and sets the attributes - and type. It stops when alle elements have been appended""" - if element.namespace: - e=root.createElementNS(element.namespace,element.type) - else: - e=root.createElement(element.type) - if element.text: - textnode=root.createTextNode(element.text) - e.appendChild(textnode) - for attr in element.attributes.values(): #in element.attributes is supported from python 2.2 - if attr.nsname and attr.nsref: - e.setAttributeNS(attr.nsref, attr.nsname+":"+attr.name, str(attr.value)) - else: - e.setAttribute(attr.name,str(attr.value)) - if element.elements: - for el in element.elements: - e=appender(el,e) - elementroot.appendChild(e) - return elementroot - root=appender(self.svg,root) - if not filename: - import cStringIO - xml=cStringIO.StringIO() - PrettyPrint(root,xml) - if compress: - import gzip - f=cStringIO.StringIO() - zf=gzip.GzipFile(fileobj=f,mode='wb') - zf.write(xml.getvalue()) - zf.close() - f.seek(0) - return f.read() - else: - return xml.getvalue() - else: - try: - if filename[-4:]=='svgz': - import gzip - import cStringIO - xml=cStringIO.StringIO() - PrettyPrint(root,xml) - f=gzip.GzipFile(filename=filename,mode='wb',compresslevel=9) - f.write(xml.getvalue()) - f.close() - else: - f=open(filename,'w') - PrettyPrint(root,f) - f.close() - except: - print "Cannot write SVG file: " + filename - - def validate(self): - try: - import xml.parsers.xmlproc.xmlval - except: - raise exceptions.ImportError,'PyXml is required for validating SVG' - svg=self.toXml() - xv=xml.parsers.xmlproc.xmlval.XMLValidator() - try: - xv.feed(svg) - except: - raise "SVG is not well formed, see messages above" - else: - print "SVG well formed" - - -if __name__=='__main__': - - - d=drawing() - s=svg((0,0,100,100)) - r=rect(-100,-100,300,300,'cyan') - s.addElement(r) - - t=title('SVGdraw Demo') - s.addElement(t) - g=group('animations') - e=ellipse(0,0,5,2) - g.addElement(e) - c=circle(0,0,1,'red') - g.addElement(c) - pd=pathdata(0,-10) - for i in range(6): - pd.relsmbezier(10,5,0,10) - pd.relsmbezier(-10,5,0,10) - an=animateMotion(pd,10) - an.addAttribute(Attribute('rotate', 'auto-reverse')) - an.addAttribute(Attribute('repeatCount', "indefinite")) - g.addElement(an) - s.addElement(g) - for i in range(20,120,20): - u=use('#animations',i,0) - s.addElement(u) - for i in range(0,120,20): - for j in range(5,105,10): - c=circle(i,j,1,'red','black',.5) - s.addElement(c) - d.setSVG(s) - - print d.toXml() - diff --git a/chat/bubble.png b/chat/bubble.png deleted file mode 100644 index 3d1503d..0000000 --- a/chat/bubble.png +++ /dev/null Binary files differ diff --git a/chat/bubbleOutline.png b/chat/bubbleOutline.png deleted file mode 100644 index 334ddca..0000000 --- a/chat/bubbleOutline.png +++ /dev/null Binary files differ diff --git a/chat/chat.py b/chat/chat.py deleted file mode 100755 index 7423979..0000000 --- a/chat/chat.py +++ /dev/null @@ -1,409 +0,0 @@ -#!/usr/bin/python -t -# -*- tab-width: 4; indent-tabs-mode: t -*- - -import dbus -import dbus.service -import dbus.glib - -import pygtk -pygtk.require('2.0') -import gtk, gobject - -import sys - -try: - import activity - from Group import * - from StreamReader import * - from StreamWriter import * - from sugar_globals import * -except ImportError: - from sugar import activity - from sugar.Group import * - from sugar.sugar_globals import * - -import richtext - -CHAT_SERVICE_TYPE = "_olpc_chat._tcp" -CHAT_SERVICE_PORT = 6100 - -GROUP_CHAT_SERVICE_TYPE = "_olpc_group_chat._udp" -GROUP_CHAT_SERVICE_ADDRESS = "224.0.0.221" -GROUP_CHAT_SERVICE_PORT = 6200 - -class Chat(activity.Activity): - def __init__(self, controller): - self._controller = controller - activity.Activity.__init__(self) - - def activity_on_connected_to_shell(self): - self.activity_set_tab_text(self._act_name) - self._plug = self.activity_get_gtk_plug() - self._ui_setup(self._plug) - self._plug.show_all() - - def _create_chat(self): - chat_vbox = gtk.VBox() - chat_vbox.set_spacing(6) - - sw = gtk.ScrolledWindow() - sw.set_shadow_type(gtk.SHADOW_IN) - sw.set_policy(gtk.POLICY_NEVER, gtk.POLICY_ALWAYS) - self._chat_view = richtext.RichTextView() - self._chat_view.connect("link-clicked", self.__link_clicked_cb) - self._chat_view.set_editable(False) - self._chat_view.set_cursor_visible(False) - sw.add(self._chat_view) - self._chat_view.show() - chat_vbox.pack_start(sw) - sw.show() - - chat_view_sw = gtk.ScrolledWindow() - chat_view_sw.set_shadow_type(gtk.SHADOW_IN) - chat_view_sw.set_policy(gtk.POLICY_AUTOMATIC, gtk.POLICY_AUTOMATIC) - self._editor = richtext.RichTextView() - self._editor.connect("key-press-event", self.__key_press_event_cb) - self._editor.set_size_request(-1, 50) - chat_view_sw.add(self._editor) - self._editor.show() - - chat_vbox.pack_start(chat_view_sw, False) - chat_view_sw.show() - - return chat_vbox, self._editor.get_buffer() - - def _ui_setup(self, base): - vbox = gtk.VBox(False, 6) - - self._hbox = gtk.HBox(False, 12) - self._hbox.set_border_width(12) - - [chat_vbox, buffer] = self._create_chat() - self._hbox.pack_start(chat_vbox) - chat_vbox.show() - - vbox.pack_start(self._hbox) - self._hbox.show() - - toolbar = self._create_toolbar(buffer) - vbox.pack_start(toolbar, False) - toolbar.show() - - base.add(vbox) - vbox.show() - - def __link_clicked_cb(self, view, address): - self._browser_shell.open_browser(address) - - def __key_press_event_cb(self, text_view, event): - if event.keyval == gtk.keysyms.Return: - buf = text_view.get_buffer() - - serializer = richtext.RichTextSerializer() - text = serializer.serialize(buf) - self.send_message(text) - - buf.set_text("") - buf.place_cursor(buf.get_start_iter()) - - return True - - def _create_toolbar(self, rich_buf): - toolbar = richtext.RichTextToolbar(rich_buf) - - item = gtk.MenuToolButton(None, "Links") - item.set_menu(gtk.Menu()) - item.connect("show-menu", self.__show_link_menu_cb) - toolbar.insert(item, -1) - item.show() - - return toolbar - - def __link_activate_cb(self, item, link): - buf = self._editor.get_buffer() - buf.append_link(link['title'], link['address']) - - def __show_link_menu_cb(self, button): - menu = gtk.Menu() - - links = self._browser_shell.get_links() - - for link in links: - item = gtk.MenuItem(link['title'], False) - item.connect("activate", self.__link_activate_cb, link) - menu.append(item) - item.show() - - button.set_menu(menu) - - def activity_on_close_from_user(self): - print "act %d: in activity_on_close_from_user"%self.activity_get_id() - self.activity_shutdown() - - def activity_on_lost_focus(self): - print "act %d: in activity_on_lost_focus"%self.activity_get_id() - - def activity_on_got_focus(self): - print "act %d: in activity_on_got_focus"%self.activity_get_id() - self._controller.notify_activate(self) - - def recv_message(self, buddy, msg): - self._insert_rich_message(buddy.get_nick_name(), msg) - self._controller.notify_new_message(self, buddy) - - def _insert_rich_message(self, nick, msg): - buffer = self._chat_view.get_buffer() - aniter = buffer.get_end_iter() - buffer.insert(aniter, nick + ": ") - - serializer = richtext.RichTextSerializer() - serializer.deserialize(msg, buffer) - - aniter = buffer.get_end_iter() - buffer.insert(aniter, "\n") - - def _local_message(self, success, text): - if not success: - message = "Error: %s\n" % text - buffer = self._chat_view.get_buffer() - aniter = buffer.get_end_iter() - buffer.insert(aniter, message) - else: - owner = self._controller.get_group().get_owner() - self._insert_rich_message(owner.get_nick_name(), text) - -class BuddyChat(Chat): - def __init__(self, controller, buddy): - self._buddy = buddy - self._act_name = "Chat: %s" % buddy.get_nick_name() - Chat.__init__(self, controller) - - def _start(self): - group = self._controller.get_group() - buddy_name = self._buddy.get_service_name() - service = group.get_service(buddy_name, CHAT_SERVICE_TYPE) - self._stream_writer = StreamWriter(group, service) - - def activity_on_connected_to_shell(self): - Chat.activity_on_connected_to_shell(self) - self.activity_set_can_close(True) - self.activity_set_tab_icon_name("im") - self.activity_show_icon(True) - self._start() - - def recv_message(self, sender, msg): - Chat.recv_message(self, self._buddy, msg) - - def send_message(self, text): - if len(text) > 0: - self._stream_writer.write(text) - self._local_message(True, text) - - def activity_on_close_from_user(self): - Chat.activity_on_close_from_user(self) - del self._chats[self._buddy] - -class GroupChat(Chat): - - _MODEL_COL_NICK = 0 - _MODEL_COL_ICON = 1 - _MODEL_COL_BUDDY = 2 - - def __init__(self): - self._act_name = "Chat" - self._chats = {} - - bus = dbus.SessionBus() - proxy_obj = bus.get_object('com.redhat.Sugar.Browser', '/com/redhat/Sugar/Browser') - self._browser_shell = dbus.Interface(proxy_obj, 'com.redhat.Sugar.BrowserShell') - - Chat.__init__(self, self) - - def get_group(self): - return self._group - - def _start(self): - self._group = LocalGroup() - self._group.add_presence_listener(self._on_group_event) - self._group.join() - - name = self._group.get_owner().get_service_name() - service = Service(name, CHAT_SERVICE_TYPE, '', CHAT_SERVICE_PORT) - self._buddy_reader = StreamReader(self._group, service) - self._buddy_reader.set_listener(self._buddy_recv_message) - service.register(self._group) - - service = Service(name, GROUP_CHAT_SERVICE_TYPE, - GROUP_CHAT_SERVICE_ADDRESS, - GROUP_CHAT_SERVICE_PORT, True) - self._group.add_service(service) - - self._buddy_reader = StreamReader(self._group, service) - self._buddy_reader.set_listener(self.recv_message) - - self._stream_writer = StreamWriter(self._group, service) - - def _create_sidebar(self): - vbox = gtk.VBox(False, 6) - - label = gtk.Label("Who's around:") - label.set_alignment(0.0, 0.5) - vbox.pack_start(label, False) - label.show() - - self._buddy_list_model = gtk.ListStore(gobject.TYPE_STRING, gtk.gdk.Pixbuf, gobject.TYPE_PYOBJECT) - - self._pixbuf_active_chat = gtk.gdk.pixbuf_new_from_file(data_dir + "/bubbleOutline.png") - self._pixbuf_new_message = gtk.gdk.pixbuf_new_from_file(data_dir + "/bubble.png") - - sw = gtk.ScrolledWindow() - sw.set_shadow_type(gtk.SHADOW_IN) - sw.set_policy(gtk.POLICY_AUTOMATIC, gtk.POLICY_AUTOMATIC) - - self._buddy_list_view = gtk.TreeView(self._buddy_list_model) - self._buddy_list_view.set_headers_visible(False) - self._buddy_list_view.connect("cursor-changed", self._on_buddyList_buddy_selected) - self._buddy_list_view.connect("row-activated", self._on_buddyList_buddy_double_clicked) - - sw.set_size_request(120, -1) - sw.add(self._buddy_list_view) - self._buddy_list_view.show() - - renderer = gtk.CellRendererPixbuf() - column = gtk.TreeViewColumn("", renderer, pixbuf=self._MODEL_COL_ICON) - column.set_resizable(False) - column.set_expand(False); - self._buddy_list_view.append_column(column) - - renderer = gtk.CellRendererText() - column = gtk.TreeViewColumn("", renderer, text=self._MODEL_COL_NICK) - column.set_resizable(True) - column.set_sizing("GTK_TREE_VIEW_COLUMN_GROW_ONLY"); - column.set_expand(True); - self._buddy_list_view.append_column(column) - - vbox.pack_start(sw) - sw.show() - - return vbox - - def _ui_setup(self, base): - Chat._ui_setup(self, base) - - sidebar = self._create_sidebar() - self._hbox.pack_start(sidebar, False) - sidebar.show() - self._plug.show_all() - - def activity_on_connected_to_shell(self): - Chat.activity_on_connected_to_shell(self) - - self.activity_set_tab_icon_name("stock_help-chat") - self.activity_show_icon(True) - - aniter = self._buddy_list_model.append(None) - self._buddy_list_model.set(aniter, self._MODEL_COL_NICK, "Group", - self._MODEL_COL_ICON, self._pixbuf_active_chat, self._MODEL_COL_BUDDY, None) - self._start() - - def activity_on_disconnected_from_shell(self): - Chat.activity_on_disconnected_from_shell(self) - gtk.main_quit() - - def _on_buddyList_buddy_selected(self, widget, *args): - (model, aniter) = widget.get_selection().get_selected() - name = self._buddy_list_model.get(aniter, self._MODEL_COL_NICK) - print "Selected %s" % name - - def _on_buddyList_buddy_double_clicked(self, widget, *args): - """ Select the chat for this buddy or group """ - (model, aniter) = widget.get_selection().get_selected() - chat = None - buddy = self._buddy_list_model.get_value(aniter, self._MODEL_COL_BUDDY) - if buddy and not self._chats.has_key(buddy): - chat = BuddyChat(self, buddy) - self._chats[buddy] = chat - chat.activity_connect_to_shell() - - def _on_group_event(self, action, buddy): - if buddy.get_nick_name() == self._group.get_owner().get_nick_name(): - # Do not show ourself in the buddy list - pass - elif action == BUDDY_JOIN: - aniter = self._buddy_list_model.append(None) - self._buddy_list_model.set(aniter, self._MODEL_COL_NICK, buddy.get_nick_name(), - self._MODEL_COL_ICON, None, self._MODEL_COL_BUDDY, buddy) - elif action == BUDDY_LEAVE: - aniter = self._get_iter_for_buddy(buddy) - if aniter: - self._buddy_list_model.remove(aniter) - - def _get_iter_for_buddy(self, buddy): - aniter = self._buddy_list_model.get_iter_first() - while aniter: - list_buddy = self._buddy_list_model.get_value(aniter, self._MODEL_COL_BUDDY) - if buddy == list_buddy: - return aniter - aniter = self._buddy_list_model.iter_next(aniter) - - def notify_new_message(self, chat, buddy): - aniter = self._get_iter_for_buddy(buddy) - self._buddy_list_model.set(aniter, self._MODEL_COL_ICON, self._pixbuf_new_message) - - def notify_activate(self, chat): - aniter = self._get_iter_for_buddy(buddy) - self._buddy_list_model.set(aniter, self._MODEL_COL_ICON, self._pixbuf_active_chat) - - def send_message(self, text): - if len(text) > 0: - self._stream_writer.write(text) - self._local_message(True, text) - - def recv_message(self, buddy, msg): - if buddy: - self._insert_rich_message(buddy.get_nick_name(), msg) - self._controller.notify_new_message(self, None) - - def _buddy_recv_message(self, sender, msg): - if not self._chats.has_key(sender): - chat = BuddyChat(self, sender) - self._chats[sender] = chat - chat.activity_connect_to_shell() - else: - chat = self._chats[sender] - chat.recv_message(sender, msg) - -class ChatShell(dbus.service.Object): - instance = None - - def get_instance(): - if not ChatShell.instance: - ChatShell.instance = ChatShell() - return ChatShell.instance - - get_instance = staticmethod(get_instance) - - def __init__(self): - session_bus = dbus.SessionBus() - bus_name = dbus.service.BusName('com.redhat.Sugar.Chat', bus=session_bus) - object_path = '/com/redhat/Sugar/Chat' - - dbus.service.Object.__init__(self, bus_name, object_path) - - def open_group_chat(self): - group_chat = GroupChat() - group_chat.activity_connect_to_shell() - - @dbus.service.method('com.redhat.Sugar.ChatShell') - def send_message(self, message): - pass - -def main(): - ChatShell.get_instance().open_group_chat() - try: - gtk.main() - except KeyboardInterrupt: - pass - -if __name__ == "__main__": - main() diff --git a/chat/richtext.py b/chat/richtext.py deleted file mode 100644 index 0ac70b1..0000000 --- a/chat/richtext.py +++ /dev/null @@ -1,374 +0,0 @@ -#!/usr/bin/env python - -import pygtk -import gobject -pygtk.require('2.0') -import gtk -import pango -import xml.sax - -class RichTextView(gtk.TextView): - - __gsignals__ = { - 'link-clicked': (gobject.SIGNAL_RUN_FIRST, gobject.TYPE_NONE, - ([gobject.TYPE_STRING])) - } - - def __init__(self): - gtk.TextView.__init__(self, RichTextBuffer()) - self.connect("motion-notify-event", self.__motion_notify_cb) - self.connect("button-press-event", self.__button_press_cb) - self.__hover_link = False - - def _set_hover_link(self, hover_link): - if hover_link != self.__hover_link: - self.__hover_link = hover_link - display = self.get_toplevel().get_display() - child_window = self.get_window(gtk.TEXT_WINDOW_TEXT) - - if hover_link: - cursor = gtk.gdk.Cursor(display, gtk.gdk.HAND2) - else: - cursor = gtk.gdk.Cursor(display, gtk.gdk.XTERM) - - child_window.set_cursor(cursor) - gtk.gdk.flush() - - def __iter_is_link(self, it): - item = self.get_buffer().get_tag_table().lookup("link") - if item: - return it.has_tag(item) - return False - - def __get_event_iter(self, event): - return self.get_iter_at_location(int(event.x), int(event.y)) - - def __motion_notify_cb(self, widget, event): - if event.is_hint: - [x, y, state] = event.window.get_pointer(); - - it = self.__get_event_iter(event) - if it: - hover_link = self.__iter_is_link(it) - else: - hover_link = False - - self._set_hover_link(hover_link) - - def __button_press_cb(self, widget, event): - it = self.__get_event_iter(event) - if it and self.__iter_is_link(it): - buf = self.get_buffer() - address_tag = buf.get_tag_table().lookup("link-address") - - address_end = it.copy() - address_end.backward_to_tag_toggle(address_tag) - - address_start = address_end.copy() - address_start.backward_to_tag_toggle(address_tag) - - address = buf.get_text(address_start, address_end) - self.emit("link-clicked", address) - -class RichTextBuffer(gtk.TextBuffer): - def __init__(self): - gtk.TextBuffer.__init__(self) - - self.connect_after("insert-text", self.__insert_text_cb) - - self.__create_tags() - self.active_tags = [] - - def append_link(self, title, address): - it = self.get_iter_at_mark(self.get_insert()) - self.insert_with_tags_by_name(it, address, "link", "link-address") - self.insert_with_tags_by_name(it, title, "link") - - def apply_tag(self, tag_name): - self.active_tags.append(tag_name) - - bounds = self.get_selection_bounds() - if bounds: - [start, end] = bounds - self.apply_tag_by_name(tag_name, start, end) - - def unapply_tag(self, tag_name): - self.active_tags.remove(tag_name) - - bounds = self.get_selection_bounds() - if bounds: - [start, end] = bounds - self.remove_tag_by_name(tag_name, start, end) - - def __create_tags(self): - tag = self.create_tag("link") - tag.set_property("underline", pango.UNDERLINE_SINGLE) - tag.set_property("foreground", "#0000FF") - - tag = self.create_tag("link-address") - tag.set_property("invisible", True) - - tag = self.create_tag("bold") - tag.set_property("weight", pango.WEIGHT_BOLD) - - tag = self.create_tag("italic") - tag.set_property("style", pango.STYLE_ITALIC) - - tag = self.create_tag("font-size-xx-small") - tag.set_property("scale", pango.SCALE_XX_SMALL) - - tag = self.create_tag("font-size-x-small") - tag.set_property("scale", pango.SCALE_X_SMALL) - - tag = self.create_tag("font-size-small") - tag.set_property("scale", pango.SCALE_SMALL) - - tag = self.create_tag("font-size-large") - tag.set_property("scale", pango.SCALE_LARGE) - - tag = self.create_tag("font-size-x-large") - tag.set_property("scale", pango.SCALE_X_LARGE) - - tag = self.create_tag("font-size-xx-large") - tag.set_property("scale", pango.SCALE_XX_LARGE) - - def __insert_text_cb(self, widget, pos, text, length): - for tag in self.active_tags: - pos_end = pos.copy() - pos_end.backward_chars(length) - self.apply_tag_by_name(tag, pos, pos_end) - -class RichTextToolbar(gtk.Toolbar): - def __init__(self, buf): - gtk.Toolbar.__init__(self) - - self.buf = buf - - self.set_style(gtk.TOOLBAR_ICONS) - - self._font_size = "normal" - self._font_scales = [ "xx-small", "x-small", "small", \ - "normal", \ - "large", "x-large", "xx-large" ] - - item = gtk.ToggleToolButton(gtk.STOCK_BOLD) - item.connect("toggled", self.__toggle_style_cb, "bold") - self.insert(item, -1) - item.show() - - item = gtk.ToggleToolButton(gtk.STOCK_ITALIC) - item.connect("toggled", self.__toggle_style_cb, "italic") - self.insert(item, -1) - item.show() - - self._font_size_up = gtk.ToolButton(gtk.STOCK_GO_UP) - self._font_size_up.connect("clicked", self.__font_size_up_cb) - self.insert(self._font_size_up, -1) - self._font_size_up.show() - - self._font_size_down = gtk.ToolButton(gtk.STOCK_GO_DOWN) - self._font_size_down.connect("clicked", self.__font_size_down_cb) - self.insert(self._font_size_down, -1) - self._font_size_down.show() - - def _get_font_size_index(self): - return self._font_scales.index(self._font_size); - - def __toggle_style_cb(self, toggle, tag_name): - if toggle.get_active(): - self.buf.apply_tag(tag_name) - else: - self.buf.unapply_tag(tag_name) - - def _set_font_size(self, font_size): - if self._font_size != "normal": - self.buf.unapply_tag("font-size-" + self._font_size) - if font_size != "normal": - self.buf.apply_tag("font-size-" + font_size) - - self._font_size = font_size - - can_up = self._get_font_size_index() < len(self._font_scales) - 1 - can_down = self._get_font_size_index() > 0 - self._font_size_up.set_sensitive(can_up) - self._font_size_down.set_sensitive(can_down) - - def __font_size_up_cb(self, button): - index = self._get_font_size_index() - if index + 1 < len(self._font_scales): - self._set_font_size(self._font_scales[index + 1]) - - def __font_size_down_cb(self, button): - index = self._get_font_size_index() - if index > 0: - self._set_font_size(self._font_scales[index - 1]) - -class RichTextHandler(xml.sax.handler.ContentHandler): - def __init__(self, serializer, buf): - self.buf = buf - self.serializer = serializer - self.tags = [] - - def startElement(self, name, attrs): - if name != "richtext": - tag = self.serializer.deserialize_element(name, attrs) - self.tags.append(tag) - if name == "link": - self.href = attrs['href'] - - def characters(self, data): - start_it = it = self.buf.get_end_iter() - mark = self.buf.create_mark(None, start_it, True) - self.buf.insert(it, data) - start_it = self.buf.get_iter_at_mark(mark) - - for tag in self.tags: - self.buf.apply_tag_by_name(tag, start_it, it) - if tag == "link": - self.buf.insert_with_tags_by_name(start_it, self.href, - "link", "link-address") - - def endElement(self, name): - if name != "richtext": - self.tags.pop() - -class RichTextSerializer: - def __init__(self): - self._open_tags = [] - - def deserialize_element(self, el_name, attributes): - if el_name == "bold": - return "bold" - elif el_name == "italic": - return "italic" - elif el_name == "font": - return "font-size-" + attributes["size"] - elif el_name == "link": - return "link" - else: - return None - - def serialize_tag_start(self, tag, it): - name = tag.get_property("name") - if name == "bold": - return "" - elif name == "italic": - return "" - elif name == "link": - address_tag = self.buf.get_tag_table().lookup("link-address") - end = it.copy() - end.forward_to_tag_toggle(address_tag) - address = self.buf.get_text(it, end) - return "" - elif name == "link-address": - return "" - elif name.startswith("font-size-"): - tag_name = name.replace("font-size-", "", 1) - return "" - else: - return "" - - def serialize_tag_end(self, tag): - name = tag.get_property("name") - if name == "bold": - return "" - elif name == "italic": - return "" - elif name == "link": - return "" - elif name == "link-address": - return "" - elif name.startswith("font-size-"): - return "" - else: - return "" - - def serialize(self, buf): - self.buf = buf - - xml = "" - - next_it = buf.get_start_iter() - while not next_it.is_end(): - it = next_it.copy() - if not next_it.forward_to_tag_toggle(None): - next_it = buf.get_end_iter() - - tags_to_reopen = [] - - for tag in it.get_toggled_tags(False): - while 1: - open_tag = self._open_tags.pop() - xml += self.serialize_tag_end(tag) - if open_tag == tag: - break - tags_to_reopen.append(open_tag) - - for tag in tags_to_reopen: - self._open_tags.append(tag) - xml += self.serialize_tag_start(tag, it) - - for tag in it.get_toggled_tags(True): - self._open_tags.append(tag) - xml += self.serialize_tag_start(tag, it) - - xml += buf.get_text(it, next_it, False) - - if next_it.is_end(): - self._open_tags.reverse() - for tag in self._open_tags: - xml += self.serialize_tag_end(tag) - - xml += "" - - return xml - - def deserialize(self, xml_string, buf): - parser = xml.sax.make_parser() - handler = RichTextHandler(self, buf) - parser.setContentHandler(handler) - parser.feed(xml_string) - parser.close() - -def test_quit(window, rich_buf): - print RichTextSerializer().serialize(rich_buf) - gtk.main_quit() - -def link_clicked(view, address): - print "Link clicked " + address - -if __name__ == "__main__": - window = gtk.Window() - window.set_default_size(400, 300) - - vbox = gtk.VBox() - - view = RichTextView() - view.connect("link-clicked", link_clicked) - vbox.pack_start(view) - view.show() - - rich_buf = view.get_buffer() - - xml_string = "" - - xml_string += "Testone\n" - xml_string += "Test two" - xml_string += "Test three" - xml_string += "Test link" - xml_string += "" - - RichTextSerializer().deserialize(xml_string, rich_buf) - - toolbar = RichTextToolbar(rich_buf) - vbox.pack_start(toolbar, False) - toolbar.show() - - window.add(vbox) - vbox.show() - - window.show() - - window.connect("destroy", test_quit, rich_buf) - - gtk.main() diff --git a/configure.ac b/configure.ac index e391351..0828bda 100644 --- a/configure.ac +++ b/configure.ac @@ -17,9 +17,10 @@ AC_SUBST(PYGTK_LIBS) AC_OUTPUT([ Makefile -sugar_globals.py -browser/Makefile -chat/Makefile -shell/Makefile -shell/src/Makefile +sugar/Makefile +sugar/__installed__.py +sugar/browser/Makefile +sugar/chat/Makefile +sugar/p2p/Makefile +sugar/shell/Makefile ]) diff --git a/legacy/legacy.py b/legacy/legacy.py deleted file mode 100755 index 1dddd9e..0000000 --- a/legacy/legacy.py +++ /dev/null @@ -1,133 +0,0 @@ -#!/usr/bin/python -t -# -*- tab-width: 4; indent-tabs-mode: t -*- - -import dbus -import dbus.service -import dbus.glib - -import pygtk -pygtk.require('2.0') -import gtk, gobject - -import sys -import os -import pwd -import gc -import socket -import types -import select -import string -import time - -sys.path.append(os.getcwd()) -sys.path.append('../shell/example-activity/') -import activity - -XEPHYR_PATH = "/usr/bin/Xephyr" -MATCHBOX_PATH = "/usr/bin/matchbox-window-manager" - - -class LegacyActivity(activity.Activity): - - def __init__(self, args): - activity.Activity.__init__(self) - self._act_name = os.path.basename(args[1]) - self._display = 5 - self._args = args[1:] - self._act_pid = None - self._matchbox_pid = None - self._xephyr_pid = None - - def _xephyr_function(self, pid, condition, data=None): - print "Xephyr: PID: %d, condition: %s" % (pid, condition) - - def _matchbox_function(self, pid, condition, data=None): - print "WM: PID: %d, condition: %s" % (pid, condition) - - def _act_function(self, pid, condition, data=None): - print "ACT: PID: %d, condition: %s" % (pid, condition) - if condition == 0: - self._act_pid = None - gtk.main_quit() - - def __key_press_event_cb(self, widget, event): - print event - - def _start(self): - args = string.split("%s :%d -ac -parent %d -host-cursor" % (XEPHYR_PATH, self._display, self._plug.get_id())) - (self._xephyr_pid, a, b, c) = gobject.spawn_async(args, standard_output=sys.stdout, standard_error=sys.stderr) - self._xephyr_watch = gobject.child_watch_add(self._xephyr_pid, self._xephyr_function) - - envp = ["DISPLAY=:%d" % self._display] - envp.append("INPUTRC=/etc/inputrc") - envp.append("XMODIFIERS=@im=SCIM") - envp.append("GTK_IM_MODULE=scim") - try: - envp.append("LANG=%s" % os.environ['LANG']) - except: - envp.append("LANG=en_US.UTF-8") - - args = string.split("%s" % MATCHBOX_PATH) - (self._matchbox_pid, a, b, c) = gobject.spawn_async(args, envp=envp, standard_output=sys.stdout, standard_error=sys.stderr) - gobject.child_watch_add(self._matchbox_pid, self._matchbox_function) - - args = [os.path.abspath(self._args[0])] - for arg in self._args[1:]: - args.append(arg) - (self._act_pid, a, b, c) = gobject.spawn_async(args, envp=envp, standard_output=sys.stdout, standard_error=sys.stderr) - gobject.child_watch_add(self._act_pid, self._act_function) - - def activity_on_connected_to_shell(self): - print "act %d: in activity_on_connected_to_shell" % self.activity_get_id() - self.activity_set_tab_text(self._act_name) - self._plug = self.activity_get_gtk_plug() - self._plug.add_events(gtk.gdk.ALL_EVENTS_MASK) - self._plug.connect("key-press-event", self.__key_press_event_cb) - self._plug.show() - self._start() - self._plug.grab_focus() - - def activity_on_disconnected_from_shell(self): - print "act %d: in activity_on_disconnected_from_shell"%self.activity_get_id() - print "act %d: Shell disappeared..."%self.activity_get_id() - gc.collect() - - def activity_on_close_from_user(self): - print "act %d: in activity_on_close_from_user"%self.activity_get_id() - self.activity_shutdown() - - def activity_on_lost_focus(self): - print "act %d: in activity_on_lost_focus"%self.activity_get_id() - - def activity_on_got_focus(self): - print "act %d: in activity_on_got_focus"%self.activity_get_id() - self._plug.grab_focus() - - def cleanup(self): - try: - if self._act_pid: - os.kill(self._act_pid, 9) - time.sleep(0.2) - if self._xephyr_pid: - os.kill(self._xephyr_pid, 9) - time.sleep(0.2) - if self._matchbox_pid: - os.kill(self._matchbox_pid, 9) - time.sleep(0.2) - except OSError, e: - pass - - def run(self): - try: - gtk.main() - except KeyboardInterrupt: - pass - -def main(args): - app = LegacyActivity(args) - app.activity_connect_to_shell() - app.run() - app.cleanup() - -if __name__ == "__main__": - main(sys.argv) diff --git a/p2p/Buddy.py b/p2p/Buddy.py deleted file mode 100644 index 19d7c0e..0000000 --- a/p2p/Buddy.py +++ /dev/null @@ -1,34 +0,0 @@ -import pwd -import os - -from Service import * - -PRESENCE_SERVICE_TYPE = "_olpc_presence._tcp" -PRESENCE_SERVICE_PORT = 6000 - -class Buddy: - def __init__(self, service, nick_name): - self._service = service - self._nick_name = nick_name - - def get_service_name(self): - return self._service.get_name() - - def get_nick_name(self): - return self._nick_name - -class Owner(Buddy): - def __init__(self, group): - self._group = group - - nick = pwd.getpwuid(os.getuid())[0] - if not nick or not len(nick): - nick = "n00b" - - service = Service(nick, PRESENCE_SERVICE_TYPE, - '', PRESENCE_SERVICE_PORT) - - Buddy.__init__(self, service, nick) - - def register(self): - self._service.register(self._group) diff --git a/p2p/Group.py b/p2p/Group.py deleted file mode 100644 index dedbc1e..0000000 --- a/p2p/Group.py +++ /dev/null @@ -1,102 +0,0 @@ -import avahi - -import presence -from Buddy import * -from Service import * - -SERVICE_ADDED = "service_added" -SERVICE_REMOVED = "service_removed" - -BUDDY_JOIN = "buddy_join" -BUDDY_LEAVE = "buddy_leave" - -class Group: - def __init__(self): - self._service_listeners = [] - self._presence_listeners = [] - - def join(self, buddy): - pass - - def add_service_listener(self, listener): - self._service_listeners.append(listener) - - def add_presence_listener(self, listener): - self._presence_listeners.append(listener) - - def _notify_service_added(self, service): - for listener in self._service_listeners: - listener(SERVICE_ADDED, buddy) - - def _notify_service_removed(self, service): - for listener in self._service_listeners: - listener(SERVICE_REMOVED,buddy) - - def _notify_buddy_join(self, buddy): - for listener in self._presence_listeners: - listener(BUDDY_JOIN, buddy) - - def _notify_buddy_leave(self, buddy): - for listener in self._presence_listeners: - listener(BUDDY_LEAVE, buddy) - -class LocalGroup(Group): - def __init__(self): - Group.__init__(self) - - self._services = {} - self._buddies = {} - - self._pdiscovery = presence.PresenceDiscovery() - self._pdiscovery.add_service_listener(self._on_service_change) - self._pdiscovery.start() - - def get_owner(self): - return self._owner - - def add_service(self, service): - sid = (service.get_name(), service.get_type()) - self._services[sid] = service - self._notify_service_added(service) - - def remove_service(self, sid): - self._notify_service_removed(service) - del self._services[sid] - - def join(self): - self._owner = Owner(self) - self._owner.register() - - def get_service(self, name, stype): - return self._services[(name, stype)] - - def get_buddy(self, name): - return self._buddies[name] - - def _add_buddy(self, buddy): - bid = buddy.get_nick_name() - if not self._buddies.has_key(bid): - self._buddies[bid] = buddy - self._notify_buddy_join(buddy) - - def _remove_buddy(self, buddy): - self._notify_buddy_leave(buddy) - del self._buddies[buddy.get_nick_name()] - - def _on_service_change(self, action, interface, protocol, name, stype, domain, flags): - if action == presence.ACTION_SERVICE_NEW: - self._pdiscovery.resolve_service(interface, protocol, name, stype, domain, - self._on_service_resolved) - elif action == presence.ACTION_SERVICE_REMOVED: - if stype == PRESENCE_SERVICE_TYPE: - self._remove_buddy(name) - elif stype.startswith("_olpc"): - self.remove_service((name, stype)) - - def _on_service_resolved(self, interface, protocol, name, stype, domain, - host, aprotocol, address, port, txt, flags): - service = Service(name, stype, address, port) - if stype == PRESENCE_SERVICE_TYPE: - self._add_buddy(Buddy(service, name)) - elif stype.startswith("_olpc"): - self.add_service(service) diff --git a/p2p/Service.py b/p2p/Service.py deleted file mode 100644 index 50bbf86..0000000 --- a/p2p/Service.py +++ /dev/null @@ -1,31 +0,0 @@ -import presence - -class Service(object): - def __init__(self, name, stype, address, port, multicast=False): - self._name = name - self._stype = stype - self._address = str(address) - self._port = int(port) - self._multicast = multicast - - def get_name(self): - return self._name - - def get_type(self): - return self._stype - - def get_address(self): - return self._address - - def get_port(self): - return self._port - - def set_port(self, port): - self._port = port - - def is_multicast(self): - return self._multicast - - def register(self, group): - pannounce = presence.PresenceAnnounce() - pannounce.register_service(self._name, self._port, self._stype) diff --git a/p2p/StreamReader.py b/p2p/StreamReader.py deleted file mode 100644 index c108547..0000000 --- a/p2p/StreamReader.py +++ /dev/null @@ -1,51 +0,0 @@ -import network - -class StreamReaderRequestHandler(object): - def __init__(self, reader): - self._reader = reader - - def message(self, nick_name, message): - address = network.get_authinfo() - self._reader.recv(nick_name, message) - return True - -class StreamReader: - def __init__(self, group, service): - self._group = group - self._service = service - - if self._service.is_multicast(): - self._setup_multicast() - else: - self._setup_unicast() - - def set_listener(self, callback): - self._callback = callback - - def _setup_multicast(self): - address = self._service.get_address() - port = self._service.get_port() - server = network.GroupServer(address, port, self._recv_multicast) - server.start() - - def _setup_unicast(self): - started = False - tries = 10 - port = self._service.get_port() - while not started and tries > 0: - try: - p2p_server = network.GlibXMLRPCServer(("", port)) - p2p_server.register_instance(StreamReaderRequestHandler(self)) - started = True - except: - port = port + 1 - tries = tries - 1 - self._service.set_port(port) - - def _recv_multicast(self, msg): - [ nick_name, data ] = msg['data'].split(" |**| ", 2) - self.recv(nick_name, data) - - def recv(self, nick_name, data): - if nick_name != self._group.get_owner().get_nick_name(): - self._callback(self._group.get_buddy(nick_name), data) diff --git a/p2p/StreamWriter.py b/p2p/StreamWriter.py deleted file mode 100644 index f30801e..0000000 --- a/p2p/StreamWriter.py +++ /dev/null @@ -1,43 +0,0 @@ -import xmlrpclib -import traceback -import socket - -import network - -class StreamWriter: - def __init__(self, group, service): - self._group = group - self._service = service - self._address = self._service.get_address() - self._port = self._service.get_port() - - if self._service.is_multicast(): - self._setup_multicast() - else: - self._setup_unicast() - - def write(self, data): - if self._service.is_multicast(): - self._multicast_write(data) - else: - self._unicast_write(data) - - def _setup_unicast(self): - xmlrpc_addr = "http://%s:%d" % (self._address, self._port) - self._uclient = xmlrpclib.ServerProxy(xmlrpc_addr) - - def _unicast_write(self, data): - try: - nick_name = self._group.get_owner().get_nick_name() - self._uclient.message(nick_name, data) - return True - except (socket.error, xmlrpclib.Fault, xmlrpclib.ProtocolError), e: - traceback.print_exc() - return False - - def _setup_multicast(self): - self._mclient = network.GroupClient(self._address, self._port) - - def _multicast_write(self, data): - nick_name = self._group.get_owner().get_nick_name() - self._mclient.send_msg(nick_name + " |**| " + data) diff --git a/p2p/network.py b/p2p/network.py deleted file mode 100644 index c88ede6..0000000 --- a/p2p/network.py +++ /dev/null @@ -1,176 +0,0 @@ -# -*- tab-width: 4; indent-tabs-mode: t -*- - -import socket -import threading -import traceback -import select -import time -import xmlrpclib -import sys - -import gobject -import SimpleXMLRPCServer -import SocketServer - -__authinfos = {} - -def _add_authinfo(authinfo): - __authinfos[threading.currentThread()] = authinfo - -def get_authinfo(): - return __authinfos.get(threading.currentThread()) - -def _del_authinfo(): - del __authinfos[threading.currentThread()] - - -class GlibTCPServer(SocketServer.TCPServer): - """GlibTCPServer - - Integrate socket accept into glib mainloop. - """ - - allow_reuse_address = True - request_queue_size = 20 - - def __init__(self, server_address, RequestHandlerClass): - SocketServer.TCPServer.__init__(self, server_address, RequestHandlerClass) - self.socket.setblocking(0) # Set nonblocking - - # Watch the listener socket for data - gobject.io_add_watch(self.socket, gobject.IO_IN, self._handle_accept) - - def _handle_accept(self, source, condition): - if not (condition & gobject.IO_IN): - return True - self.handle_request() - return True - -class GlibXMLRPCRequestHandler(SimpleXMLRPCServer.SimpleXMLRPCRequestHandler): - """ GlibXMLRPCRequestHandler - - The stock SimpleXMLRPCRequestHandler and server don't allow any way to pass - the client's address and/or SSL certificate into the function that actually - _processes_ the request. So we have to store it in a thread-indexed dict. - """ - - def do_POST(self): - _add_authinfo(self.client_address) - try: - SimpleXMLRPCServer.SimpleXMLRPCRequestHandler.do_POST(self) - except socket.timeout: - pass - except socket.error, e: - print "Error (%s): socket error - '%s'" % (self.client_address, e) - except: - print "Error while processing POST:" - traceback.print_exc() - _del_authinfo() - -class GlibXMLRPCServer(GlibTCPServer, SimpleXMLRPCServer.SimpleXMLRPCDispatcher): - """GlibXMLRPCServer - - Use nonblocking sockets and handle the accept via glib rather than - blocking on accept(). - """ - - def __init__(self, addr, requestHandler=GlibXMLRPCRequestHandler, logRequests=1): - self.logRequests = logRequests - - SimpleXMLRPCServer.SimpleXMLRPCDispatcher.__init__(self) - GlibTCPServer.__init__(self, addr, requestHandler) - - def _marshaled_dispatch(self, data, dispatch_method = None): - """Dispatches an XML-RPC method from marshalled (XML) data. - - XML-RPC methods are dispatched from the marshalled (XML) data - using the _dispatch method and the result is returned as - marshalled data. For backwards compatibility, a dispatch - function can be provided as an argument (see comment in - SimpleXMLRPCRequestHandler.do_POST) but overriding the - existing method through subclassing is the prefered means - of changing method dispatch behavior. - """ - - params, method = xmlrpclib.loads(data) - - # generate response - try: - if dispatch_method is not None: - response = dispatch_method(method, params) - else: - response = self._dispatch(method, params) - # wrap response in a singleton tuple - response = (response,) - response = xmlrpclib.dumps(response, methodresponse=1) - except xmlrpclib.Fault, fault: - response = xmlrpclib.dumps(fault) - except: - print "Exception while processing request:" - traceback.print_exc() - - # report exception back to server - response = xmlrpclib.dumps( - xmlrpclib.Fault(1, "%s:%s" % (sys.exc_type, sys.exc_value)) - ) - - return response - -class GroupServer(object): - - _MAX_MSG_SIZE = 500 - - def __init__(self, address, port, data_cb): - self._address = address - self._port = port - self._data_cb = data_cb - - self._setup_listener() - - def _setup_listener(self): - # Listener socket - self._listen_sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) - - # Set some options to make it multicast-friendly - self._listen_sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1) - try: - self._listen_sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEPORT, 1) - except: - pass - self._listen_sock.setsockopt(socket.SOL_IP, socket.IP_MULTICAST_TTL, 20) - self._listen_sock.setsockopt(socket.SOL_IP, socket.IP_MULTICAST_LOOP, 1) - - def start(self): - # Set some more multicast options - self._listen_sock.bind(('', self._port)) - self._listen_sock.settimeout(2) - intf = socket.gethostbyname(socket.gethostname()) - self._listen_sock.setsockopt(socket.SOL_IP, socket.IP_MULTICAST_IF, socket.inet_aton(intf) + socket.inet_aton('0.0.0.0')) - self._listen_sock.setsockopt(socket.SOL_IP, socket.IP_ADD_MEMBERSHIP, socket.inet_aton(self._address) + socket.inet_aton('0.0.0.0')) - - # Watch the listener socket for data - gobject.io_add_watch(self._listen_sock, gobject.IO_IN, self._handle_incoming_data) - - def _handle_incoming_data(self, source, condition): - if not (condition & gobject.IO_IN): - return True - msg = {} - msg['data'], (msg['addr'], msg['port']) = source.recvfrom(self._MAX_MSG_SIZE) - if self._data_cb: - self._data_cb(msg) - return True - -class GroupClient(object): - - _MAX_MSG_SIZE = 500 - - def __init__(self, address, port): - self._address = address - self._port = port - - self._send_sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) - # Make the socket multicast-aware, and set TTL. - self._send_sock.setsockopt(socket.IPPROTO_IP, socket.IP_MULTICAST_TTL, 20) # Change TTL (=20) to suit - - def send_msg(self, data): - self._send_sock.sendto(data, (self._address, self._port)) diff --git a/p2p/presence.py b/p2p/presence.py deleted file mode 100644 index e16fc92..0000000 --- a/p2p/presence.py +++ /dev/null @@ -1,92 +0,0 @@ -# -*- tab-width: 4; indent-tabs-mode: t -*- - -import avahi, dbus, dbus.glib - -ACTION_SERVICE_NEW = 'new' -ACTION_SERVICE_REMOVED = 'removed' - -class PresenceDiscovery(object): - def __init__(self): - self.bus = dbus.SystemBus() - self.server = dbus.Interface(self.bus.get_object(avahi.DBUS_NAME, avahi.DBUS_PATH_SERVER), avahi.DBUS_INTERFACE_SERVER) - self._service_browsers = {} - self._service_type_browsers = {} - self._service_listeners = [] - - def add_service_listener(self, listener): - self._service_listeners.append(listener) - - def start(self): - # Always browse .local - self.browse_domain(avahi.IF_UNSPEC, avahi.PROTO_UNSPEC, "local") - db = dbus.Interface(self.bus.get_object(avahi.DBUS_NAME, self.server.DomainBrowserNew(avahi.IF_UNSPEC, avahi.PROTO_UNSPEC, "", avahi.DOMAIN_BROWSER_BROWSE, dbus.UInt32(0))), avahi.DBUS_INTERFACE_DOMAIN_BROWSER) - db.connect_to_signal('ItemNew', self.new_domain) - - def _error_handler(self, err): - print "Error resolving: %s" % err - - def resolve_service(self, interface, protocol, name, stype, domain, reply_handler, error_handler=None): - if not error_handler: - error_handler = self._error_handler - self.server.ResolveService(int(interface), int(protocol), name, stype, domain, avahi.PROTO_UNSPEC, dbus.UInt32(0), reply_handler=reply_handler, error_handler=error_handler) - - def new_service(self, interface, protocol, name, stype, domain, flags): -# print "Found service '%s' (%d) of type '%s' in domain '%s' on %i.%i." % (name, flags, stype, domain, interface, protocol) - for listener in self._service_listeners: - listener(ACTION_SERVICE_NEW, interface, protocol, name, stype, domain, flags) - - def remove_service(self, interface, protocol, name, stype, domain, flags): -# print "Service '%s' of type '%s' in domain '%s' on %i.%i disappeared." % (name, stype, domain, interface, protocol) - for listener in self._service_listeners: - listener(ACTION_SERVICE_REMOVED, interface, protocol, name, stype, domain, flags) - - def new_service_type(self, interface, protocol, stype, domain, flags): - # Are we already browsing this domain for this type? - if self._service_browsers.has_key((interface, protocol, stype, domain)): - return - -# print "Browsing for services of type '%s' in domain '%s' on %i.%i ..." % (stype, domain, interface, protocol) - - b = dbus.Interface(self.bus.get_object(avahi.DBUS_NAME, self.server.ServiceBrowserNew(interface, protocol, stype, domain, dbus.UInt32(0))), avahi.DBUS_INTERFACE_SERVICE_BROWSER) - b.connect_to_signal('ItemNew', self.new_service) - b.connect_to_signal('ItemRemove', self.remove_service) - - self._service_browsers[(interface, protocol, stype, domain)] = b - - def browse_domain(self, interface, protocol, domain): - # Are we already browsing this domain? - if self._service_type_browsers.has_key((interface, protocol, domain)): - return - -# print "Browsing domain '%s' on %i.%i ..." % (domain, interface, protocol) - - b = dbus.Interface(self.bus.get_object(avahi.DBUS_NAME, self.server.ServiceTypeBrowserNew(interface, protocol, domain, dbus.UInt32(0))), avahi.DBUS_INTERFACE_SERVICE_TYPE_BROWSER) - b.connect_to_signal('ItemNew', self.new_service_type) - - self._service_type_browsers[(interface, protocol, domain)] = b - - def new_domain(self,interface, protocol, domain, flags): - if domain != "local": - return - self.browse_domain(interface, protocol, domain) - - -class PresenceAnnounce(object): - def __init__(self): - self.bus = dbus.SystemBus() - self.server = dbus.Interface(self.bus.get_object(avahi.DBUS_NAME, avahi.DBUS_PATH_SERVER), avahi.DBUS_INTERFACE_SERVER) - self._hostname = None - - def register_service(self, rs_name, rs_port, rs_service, **kwargs): - g = dbus.Interface(self.bus.get_object(avahi.DBUS_NAME, self.server.EntryGroupNew()), avahi.DBUS_INTERFACE_ENTRY_GROUP) - if rs_name is None: - if self._hostname is None: - self._hostname = "%s:%s" % (self.server.GetHostName(), rs_port) - rs_name = self._hostname - - info = ["%s=%s" % (k,v) for k,v in kwargs.items()] - g.AddService(avahi.IF_UNSPEC, avahi.PROTO_UNSPEC, 0, rs_name, rs_service, - "", "", # domain, host (let the system figure it out) - dbus.UInt16(rs_port), info,) - g.Commit() - return g diff --git a/setup-run-from-source.sh b/setup-run-from-source.sh index 35559d2..bcb0084 100755 --- a/setup-run-from-source.sh +++ b/setup-run-from-source.sh @@ -1,9 +1,3 @@ #!/bin/sh -export PYTHONPATH=`pwd`/p2p - -# for activity.py -export PYTHONPATH=$PYTHONPATH:`pwd`/shell/src/ - -# for sugar_globals.py -export PYTHONPATH=$PYTHONPATH:`pwd`/ +export PYTHONPATH=`pwd` diff --git a/setup-run-from-source.tcsh b/setup-run-from-source.tcsh index 16d9df7..a59c1a9 100755 --- a/setup-run-from-source.tcsh +++ b/setup-run-from-source.tcsh @@ -1,9 +1,3 @@ #!/bin/tcsh -setenv PYTHONPATH `pwd`/p2p/ - -# for activity.py -setenv PYTHONPATH "$PYTHONPATH":`pwd`/shell/src/ - -# for sugar_globals.py -setenv PYTHONPATH "$PYTHONPATH":`pwd`/ +setenv PYTHONPATH `pwd` diff --git a/shell/Makefile.am b/shell/Makefile.am deleted file mode 100644 index af437a6..0000000 --- a/shell/Makefile.am +++ /dev/null @@ -1 +0,0 @@ -SUBDIRS = src diff --git a/shell/example-activity/example-activity.py b/shell/example-activity/example-activity.py deleted file mode 100755 index 05ce55a..0000000 --- a/shell/example-activity/example-activity.py +++ /dev/null @@ -1,82 +0,0 @@ -#!/usr/bin/python -# -*- tab-width: 4; indent-tabs-mode: t -*- - -import string - -import gc -import dbus -import dbus.service -import dbus.glib -import gobject -import pygtk -pygtk.require('2.0') -import gtk,sys - -import activity - -def my_exit(): - sys.exit(0) - -def deferred_exit(): - gobject.timeout_add(0, my_exit) - -################################################################################ - -class ExampleActivity(activity.Activity): - - def __init__(self, name): - self.name = name - - def entry_changed(self, entry): - self.activity_set_tab_text(entry.get_text()) - - def activity_on_connected_to_shell(self): - print "act %d: in activity_on_connected_to_shell"%self.activity_get_id() - - self.activity_set_tab_text(self.name) - - plug = self.activity_get_gtk_plug() - self.entry = gtk.Entry() - self.entry.set_text(self.name) - self.entry.connect("changed", self.entry_changed) - plug.add(self.entry) - plug.show_all() - - icon_theme = gtk.icon_theme_get_default() - pixbuf = icon_theme.load_icon("gnome-dev-cdrom", gtk.ICON_SIZE_MENU, gtk.ICON_LOOKUP_USE_BUILTIN) - self.activity_set_icon(pixbuf) - self.activity_show_icon(True) - - def activity_on_disconnected_from_shell(self): - print "act %d: in activity_on_disconnected_from_shell"%self.activity_get_id() - print "act %d: Shell disappeared..."%self.activity_get_id() - - gc.collect() - - def activity_on_close_from_user(self): - print "act %d: in activity_on_close_from_user"%self.activity_get_id() - self.activity_shutdown() - - def activity_on_lost_focus(self): - print "act %d: in activity_on_lost_focus"%self.activity_get_id() - - def activity_on_got_focus(self): - print "act %d: in activity_on_got_focus"%self.activity_get_id() - - def __del__(self): - print "in __del__ for ExampleActivity" - - -if len(sys.argv) != 2: - print "usage: example-activity.py " - sys.exit(1) - -gc.set_debug(gc.DEBUG_LEAK) - -example_activity = ExampleActivity(sys.argv[1]) -example_activity.activity_connect_to_shell() -example_activity = None - -gtk.main() - - diff --git a/shell/src/Makefile.am b/shell/src/Makefile.am deleted file mode 100644 index bdab0b7..0000000 --- a/shell/src/Makefile.am +++ /dev/null @@ -1,20 +0,0 @@ -sugardir = $(pythondir)/sugar -sugar_PYTHON = \ - activity.py \ - shell.py - -# Dbus service file -servicedir = $(datadir)/dbus-1/services -service_in_files = com.redhat.Sugar.Shell.service.in -service_DATA = $(service_in_files:.service.in=.service) - -# Rule to make the service file with bindir expanded -$(service_DATA): $(service_in_files) Makefile - @sed -e "s|\@bindir\@|$(bindir)|" $< > $@ - -EXTRA_DIST = \ - $(service_in_files) \ - $(service_DATA) - -DISTCLEANFILES = \ - $(service_DATA) diff --git a/shell/src/activity.py b/shell/src/activity.py deleted file mode 100644 index 6f1f3fc..0000000 --- a/shell/src/activity.py +++ /dev/null @@ -1,178 +0,0 @@ -# -*- tab-width: 4; indent-tabs-mode: t -*- - -import string - -import gc -import dbus -import dbus.service -import dbus.glib -import gobject -import pygtk -pygtk.require('2.0') -import gtk,sys - - -class Activity(dbus.service.Object): - """ Base Sugar activity object from which all other Activities should inherit """ - - def __init__(self): - pass - - def name_owner_changed(self, service_name, old_service_name, new_service_name): - #print "in name_owner_changed: svc=%s oldsvc=%s newsvc=%s"%(service_name, old_service_name, new_service_name) - if service_name == "com.redhat.Sugar.Shell" and new_service_name == "": - self.activity_on_disconnected_from_shell() - #elif service_name == "com.redhat.Sugar.Shell" and old_service_name == "": - # self.activity_on_shell_reappeared() - - def activity_connect_to_shell(self): - self.__bus = dbus.SessionBus() - - self.__bus.add_signal_receiver(self.name_owner_changed, dbus_interface = "org.freedesktop.DBus", signal_name = "NameOwnerChanged") - - self.__activity_container_object = self.__bus.get_object("com.redhat.Sugar.Shell", \ - "/com/redhat/Sugar/Shell/ActivityContainer") - self.__activity_container = dbus.Interface(self.__activity_container_object, \ - "com.redhat.Sugar.Shell.ActivityContainer") - - self.__activity_id = self.__activity_container.add_activity("") - self.__object_path = "/com/redhat/Sugar/Shell/Activities/%d"%self.__activity_id - - print "object_path = %s"%self.__object_path - - self.__activity_object = dbus.Interface(self.__bus.get_object("com.redhat.Sugar.Shell", self.__object_path), \ - "com.redhat.Sugar.Shell.ActivityHost") - self.__window_id = self.__activity_object.get_host_xembed_id() - - print "XEMBED window_id = %d"%self.__window_id - - self.__plug = gtk.Plug(self.__window_id) - - # Now let the Activity register a peer service so the Shell can poke it - self.__peer_service_name = "com.redhat.Sugar.Activity%d"%self.__activity_id - self.__peer_object_name = "/com/redhat/Sugar/Activity/%d"%self.__activity_id - self.__service = dbus.service.BusName(self.__peer_service_name, bus=self.__bus) - dbus.service.Object.__init__(self, self.__service, self.__peer_object_name) - - self.__activity_object.set_peer_service_name(self.__peer_service_name, self.__peer_object_name) - - self.activity_on_connected_to_shell() - - def activity_get_gtk_plug(self): - return self.__plug - - def activity_set_ellipsize_tab(self, ellipsize): - self.__activity_object.set_ellipsize_tab(ellipsize) - - @dbus.service.method("com.redhat.Sugar.Activity", \ - in_signature="", \ - out_signature="") - - def activity_set_can_close(self, can_close): - self.__activity_object.set_can_close(can_close) - - @dbus.service.method("com.redhat.Sugar.Activity", \ - in_signature="", \ - out_signature="") - - def activity_show_icon(self, show_icon): - self.__activity_object.set_tab_show_icon(show_icon) - - @dbus.service.method("com.redhat.Sugar.Activity", \ - in_signature="", \ - out_signature="") - - def activity_set_icon(self, pixbuf): - pixarray = [] - pixstr = pixbuf.get_pixels(); - for c in pixstr: - pixarray.append(c) - self.__activity_object.set_tab_icon(pixarray, \ - pixbuf.get_colorspace(), \ - pixbuf.get_has_alpha(), \ - pixbuf.get_bits_per_sample(), \ - pixbuf.get_width(), \ - pixbuf.get_height(), \ - pixbuf.get_rowstride()) - - @dbus.service.method("com.redhat.Sugar.Activity", \ - in_signature="", \ - out_signature="") - - def activity_set_tab_text(self, text): - self.__activity_object.set_tab_text(text) - - @dbus.service.method("com.redhat.Sugar.Activity", \ - in_signature="", \ - out_signature="") - - def activity_set_tab_icon_name(self, icon_name): - icon_theme = gtk.icon_theme_get_default() - icon_info = icon_theme.lookup_icon(icon_name, gtk.ICON_SIZE_MENU, 0) - pixbuf = icon_info.load_icon() - scaled_pixbuf = pixbuf.scale_simple(16, 16, gtk.gdk.INTERP_BILINEAR) - self.activity_set_icon(scaled_pixbuf) - - def lost_focus(self): - self.activity_on_lost_focus() - - @dbus.service.method("com.redhat.Sugar.Activity", \ - in_signature="", \ - out_signature="") - def got_focus(self): - self.activity_on_got_focus() - - - @dbus.service.method("com.redhat.Sugar.Activity", \ - in_signature="", \ - out_signature="") - def close_from_user(self): - self.activity_on_close_from_user() - - def activity_get_id(self): - return self.__activity_id - - - def __shutdown_reply_cb(self): - print "in __reply_cb" - - self.__plug.destroy() - self.__plug = None - - self.__bus = None - self.__activity_container_object = None - self.__activity_container = None - self.__activity_object = None - self.__service = None - - self.__bus.remove_signal_receiver(self.name_owner_changed, dbus_interface = "org.freedesktop.DBus", signal_name = "NameOwnerChanged") - - self.activity_on_disconnected_from_shell() - - - del self - - - - def __shutdown_error_cb(self, error): - print "in __error_cb" - - def activity_shutdown(self): - self.__activity_object.shutdown(reply_handler = self.__shutdown_reply_cb, error_handler = self.__shutdown_error_cb) - - # pure virtual methods - - def activity_on_connected_to_shell(self): - print "act %d: you need to override activity_on_connected_to_shell"%self.activity_get_id() - - def activity_on_disconnected_from_shell(self): - print "act %d: you need to override activity_on_disconnected_from_shell"%self.activity_get_id() - - def activity_on_close_from_user(self): - print "act %d: you need to override activity_on_close_from_user"%self.activity_get_id() - - def activity_on_lost_focus(self): - print "act %d: you need to override activity_on_lost_focus"%self.activity_get_id() - - def activity_on_got_focus(self): - print "act %d: you need to override activity_on_got_focus"%self.activity_get_id() diff --git a/shell/src/com.redhat.Sugar.Shell.service.in b/shell/src/com.redhat.Sugar.Shell.service.in deleted file mode 100644 index 2a069a1..0000000 --- a/shell/src/com.redhat.Sugar.Shell.service.in +++ /dev/null @@ -1,3 +0,0 @@ -[D-BUS Service] -Name=com.redhat.Sugar.Shell -Exec=@bindir@/sugar shell diff --git a/shell/src/shell.py b/shell/src/shell.py deleted file mode 100755 index d542307..0000000 --- a/shell/src/shell.py +++ /dev/null @@ -1,305 +0,0 @@ -#!/usr/bin/python -# -*- tab-width: 4; indent-tabs-mode: t -*- - -import string - -import dbus -import dbus.service -import dbus.glib -import gobject -import pygtk -pygtk.require('2.0') -import gtk -import pango - -activity_counter = 0 - -class ActivityHost(dbus.service.Object): - - def __init__(self, activity_container, activity_name): - global activity_counter - - self.activity_name = activity_name - self.ellipsize_tab = False - - self.activity_container = activity_container - - self.activity_id = activity_counter - activity_counter += 1 - - self.dbus_object_name = "/com/redhat/Sugar/Shell/Activities/%d"%self.activity_id - #print "object name = %s"%self.dbus_object_name - - dbus.service.Object.__init__(self, activity_container.service, self.dbus_object_name) - self.socket = gtk.Socket() - self.socket.set_data("sugar-activity", self) - self.socket.show() - - hbox = gtk.HBox(False, 4); - - self.tab_activity_image = gtk.Image() - self.tab_activity_image.set_from_stock(gtk.STOCK_CONVERT, gtk.ICON_SIZE_MENU) - hbox.pack_start(self.tab_activity_image) - #self.tab_activity_image.show() - - self.label_hbox = gtk.HBox(False, 4); - self.label_hbox.connect("style-set", self.__tab_label_style_set_cb) - hbox.pack_start(self.label_hbox) - - self.tab_label = gtk.Label(self.activity_name) - self.tab_label.set_single_line_mode(True) - self.tab_label.set_alignment(0.0, 0.5) - self.tab_label.set_padding(0, 0) - self.tab_label.show() - - close_image = gtk.Image() - close_image.set_from_stock (gtk.STOCK_CLOSE, gtk.ICON_SIZE_MENU) - close_image.show() - - self.tab_close_button = gtk.Button() - rcstyle = gtk.RcStyle(); - rcstyle.xthickness = rcstyle.ythickness = 0; - self.tab_close_button.modify_style (rcstyle); - self.tab_close_button.add(close_image) - self.tab_close_button.set_relief(gtk.RELIEF_NONE) - self.tab_close_button.set_focus_on_click(False) - self.tab_close_button.connect("clicked", self.tab_close_button_clicked) - - self.label_hbox.pack_start(self.tab_label) - self.label_hbox.pack_start(self.tab_close_button, False, False, 0) - self.label_hbox.show() - - hbox.show() - - notebook = self.activity_container.notebook - index = notebook.append_page(self.socket, hbox) - notebook.set_current_page(index) - - def __close_button_clicked_reply_cb(self): - pass - - def __close_button_clicked_error_cb(self, error): - pass - - def tab_close_button_clicked(self, button): - self.peer_service.close_from_user(reply_handler = self.__close_button_clicked_reply_cb, \ - error_handler = self.__close_button_clicked_error_cb) - - @dbus.service.method("com.redhat.Sugar.Shell.ActivityHost", \ - in_signature="", \ - out_signature="t") - def get_host_xembed_id(self): - window_id = self.socket.get_id() - #print "window_id = %d"%window_id - return window_id - - @dbus.service.method("com.redhat.Sugar.Shell.ActivityHost", \ - in_signature="ss", \ - out_signature="") - def set_peer_service_name(self, peer_service_name, peer_object_name): - #print "peer_service_name = %s, peer_object_name = %s"%(peer_service_name, peer_object_name) - self.__peer_service_name = peer_service_name - self.__peer_object_name = peer_object_name - self.peer_service = dbus.Interface(self.activity_container.bus.get_object( \ - self.__peer_service_name, self.__peer_object_name), \ - "com.redhat.Sugar.Activity") - - @dbus.service.method("com.redhat.Sugar.Shell.ActivityHost", \ - in_signature="b", \ - out_signature="") - def set_ellipsize_tab(self, ellipsize): - self.ellipsize_tab = True - self.update_tab_size() - - @dbus.service.method("com.redhat.Sugar.Shell.ActivityHost", \ - in_signature="b", \ - out_signature="") - def set_can_close(self, can_close): - if can_close: - self.tab_close_button.show() - else: - self.tab_close_button.hide() - - @dbus.service.method("com.redhat.Sugar.Shell.ActivityHost", \ - in_signature="b", \ - out_signature="") - def set_tab_show_icon(self, show_icon): - if show_icon: - self.tab_activity_image.show() - else: - self.tab_activity_image.hide() - - @dbus.service.method("com.redhat.Sugar.Shell.ActivityHost", \ - in_signature="s", \ - out_signature="") - def set_tab_text(self, text): - self.tab_label.set_text(text) - - @dbus.service.method("com.redhat.Sugar.Shell.ActivityHost", \ - in_signature="ayibiiii", \ - out_signature="") - def set_tab_icon(self, data, colorspace, has_alpha, bits_per_sample, width, height, rowstride): - #print "width=%d, height=%d"%(width, height) - #print " data = ", data - pixstr = "" - for c in data: - pixstr += chr(c) - - pixbuf = gtk.gdk.pixbuf_new_from_data(pixstr, colorspace, has_alpha, bits_per_sample, width, height, rowstride) - #print pixbuf - self.tab_activity_image.set_from_pixbuf(pixbuf) - - @dbus.service.method("com.redhat.Sugar.Shell.ActivityHost", \ - in_signature="", \ - out_signature="") - def shutdown(self): - #print "shutdown" - for owner, activity in self.activity_container.activities[:]: - if activity == self: - self.activity_container.activities.remove((owner, activity)) - - for i in range(self.activity_container.notebook.get_n_pages()): - child = self.activity_container.notebook.get_nth_page(i) - if child == self.socket: - #print "found child" - self.activity_container.notebook.remove_page(i) - break - - del self - - def get_host_activity_id(self): - return self.activity_id - - def get_object_path(self): - return self.dbus_object_name - - def update_tab_size(self): - if self.ellipsize_tab: - self.tab_label.set_ellipsize(pango.ELLIPSIZE_END) - - context = self.label_hbox.get_pango_context() - font_desc = self.label_hbox.style.font_desc - metrics = context.get_metrics(font_desc, context.get_language()) - char_width = metrics.get_approximate_digit_width() - [w, h] = self.__get_close_icon_size() - tab_width = 15 * pango.PIXELS(char_width) + 2 * w - self.label_hbox.set_size_request(tab_width, -1); - else: - self.tab_label.set_ellipsize(pango.ELLIPSIZE_NONE) - self.label_hbox.set_size_request(-1, -1) - - def __get_close_icon_size(self): - settings = self.label_hbox.get_settings() - return gtk.icon_size_lookup_for_settings(settings, gtk.ICON_SIZE_MENU) - - def __tab_label_style_set_cb(self, widget, previous_style): - [w, h] = self.__get_close_icon_size() - self.tab_close_button.set_size_request (w + 5, h + 2) - self.update_tab_size() - -class ActivityContainer(dbus.service.Object): - - def __init__(self, service, bus): - - self.activities = [] - - self.bus = bus - self.service = service - - dbus.service.Object.__init__(self, self.service, "/com/redhat/Sugar/Shell/ActivityContainer") - bus.add_signal_receiver(self.name_owner_changed, dbus_interface = "org.freedesktop.DBus", signal_name = "NameOwnerChanged") - - self.window = gtk.Window() - self.window.set_title("OLPC Sugar") - self.window.resize(640, 480) - self.window.set_geometry_hints(min_width = 640, max_width = 640, min_height = 480, max_height = 480) - self.notebook = gtk.Notebook() - - #tab_label = gtk.Label("My Laptop") - #empty_label = gtk.Label("This activity could launch other activities / be a help page") - #empty_label.show() - #self.notebook.append_page(empty_label, tab_label) - - self.notebook.show() - self.notebook.connect("switch-page", self.notebook_tab_changed) - self.window.add(self.notebook) - - self.window.connect("destroy", lambda w: gtk.main_quit()) - self.window.show() - - self.current_activity = None - - - def __focus_reply_cb(self): - pass - - def __focus_error_cb(self, error): - pass - - - def notebook_tab_changed(self, notebook, page, page_number): - #print "in notebook_tab_changed" - #print notebook.get_nth_page(page_number) - new_activity = notebook.get_nth_page(page_number).get_data("sugar-activity") - #print " Current activity: ", self.current_activity - #print " New activity: ", new_activity - - if self.current_activity != None: - if self.has_activity(self.current_activity): - self.current_activity.peer_service.lost_focus(reply_handler = self.__focus_reply_cb, error_handler = self.__focus_error_cb) - - self.current_activity = new_activity - - if self.current_activity != None: - if self.has_activity(self.current_activity): - self.current_activity.peer_service.got_focus(reply_handler = self.__focus_reply_cb, error_handler = self.__focus_error_cb) - - - def has_activity(self, activity_to_check_for): - for owner, activity in self.activities[:]: - if activity_to_check_for == activity: - return True - return False - - - def name_owner_changed(self, service_name, old_service_name, new_service_name): - #print "in name_owner_changed: svc=%s oldsvc=%s newsvc=%s"%(service_name, old_service_name, new_service_name) - for owner, activity in self.activities[:]: - if owner == old_service_name: - self.activities.remove((owner, activity)) - #self.__print_activities() - - - @dbus.service.method("com.redhat.Sugar.Shell.ActivityContainer", \ - in_signature="s", \ - out_signature="i", \ - sender_keyword="sender") - def add_activity(self, activity_name, sender): - #print "hello world, activity_name = '%s', sender = '%s'"%(activity_name, sender) - activity = ActivityHost(self, activity_name) - self.activities.append((sender, activity)) - - #self.__print_activities() - return activity.get_host_activity_id() - - def __print_activities(self): - print "__print_activities: %d activities registered"%len(self.activities) - i = 0 - for owner, activity in self.activities: - print " %d: owner=%s activity_object_name=%s"%(i, owner, activity.dbus_object_name) - i += 1 - - -def main(): - session_bus = dbus.SessionBus() - service = dbus.service.BusName("com.redhat.Sugar.Shell", bus=session_bus) - - activityContainer = ActivityContainer(service, session_bus) - - try: - gtk.main() - except KeyboardInterrupt: - pass - -if __name__=="__main__": - main() diff --git a/sugar b/sugar deleted file mode 100755 index 960971c..0000000 --- a/sugar +++ /dev/null @@ -1,28 +0,0 @@ -#!/usr/bin/python - -import sys -import os - -if len(sys.argv) == 1: - # FIXME Start a session - - # We are lucky and this - # currently behave as we want. - # The chat depends on the - # web browser, so both activities - # are spanned. But obviously we - # need something better. - - import sugar.chat - sugar.chat.main() -elif sys.argv[1] == 'shell': - import sugar.shell - sugar.shell.main() -elif sys.argv[1] == 'chat': - import sugar.chat - sugar.chat.main() -elif sys.argv[1] == 'browser': - import sugar.browser - sugar.browser.main() -else: - print "Unknown activity" diff --git a/sugar_globals.py.in b/sugar_globals.py.in deleted file mode 100644 index 97fd271..0000000 --- a/sugar_globals.py.in +++ /dev/null @@ -1 +0,0 @@ -data_dir = "@prefix@/share/sugar" -- cgit v0.9.1