diff options
Diffstat (limited to 'chat')
-rw-r--r-- | chat/BuddyList.py | 121 | ||||
-rw-r--r-- | chat/Makefile.am | 11 | ||||
-rw-r--r-- | chat/SVGdraw.py | 1069 | ||||
-rw-r--r-- | chat/bubble.png | bin | 255 -> 0 bytes | |||
-rw-r--r-- | chat/bubbleOutline.png | bin | 284 -> 0 bytes | |||
-rwxr-xr-x | chat/chat.py | 409 | ||||
-rw-r--r-- | chat/richtext.py | 374 |
7 files changed, 0 insertions, 1984 deletions
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 <element>text</element> 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 <rubbish> 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)+'<![CDATA[') - for line in self.cdata.splitlines(): - f.write('\n'+'\t'*(level+2)+line) - 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+'</'+self.type+'>\n') - elif self.text: - f.write('</'+self.type+'>\n') - elif self.cdata: - f.write('\t'*level+'</'+self.type+'>\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="<tspan" - for key, attr in self._attributes.items(): - s+= ' %s="%s"' % (key,attr.value) - s+='>' - s+=self.text - s+='</tspan>' - return s - -class tref(SVGelement): - """tr=tref(link='',**args) - - a tref element can be used for referencing text by a link to its id. - usage: - tr=tref('#linktotext') - st=spannedtext() - st.addtref(tr) - t=text(3,5,st) - """ - def __init__(self,link,**args): - SVGelement.__init__(self,'tref',**args) - self.addAttribute(Attribute('href', link, 'xlink', xlinkNSRef)) - def __repr__(self): - s="<tref" - - for key, attr in self._attributes.items(): - s+= ' %s="%s"' % (key,attr.value) - s+='/>' - return s - -class spannedtext: - """st=spannedtext(textlist=[]) - - a spannedtext can be used for text which consists of text, tspan's and tref's - You can use it to add to a text element or path element. Don't add it directly - to a svg or a group element. - usage: - - ts=tspan('this text is bold') - ts.attributes['font-weight']='bold' - tr=tref('#linktotext') - tr.attributes['fill']='red' - st=spannedtext() - st.addtspan(ts) - st.addtref(tr) - st.addtext('This text is not bold') - t=text(3,5,st) - """ - def __init__(self,textlist=None): - if textlist==None: - self.textlist=[] - else: - self.textlist=textlist - def addtext(self,text=''): - self.textlist.append(text) - def addtspan(self,tspan): - self.textlist.append(tspan) - def addtref(self,tref): - self.textlist.append(tref) - def __repr__(self): - s="" - for element in self.textlist: - s+=str(element) - return s - -class rect(SVGelement): - """r=rect(width,height,x,y,fill,stroke,stroke_width,**args) - - a rectangle is defined by a width and height and a xy pair - """ - def __init__(self,x=None,y=None,width=None,height=None,fill=None,stroke=None,stroke_width=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,'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("<?xml version='1.0' encoding='UTF-8'?>\n") - xml.write("<!DOCTYPE svg PUBLIC \"-//W3C//DTD SVG 1.0//EN\" \"http://www.w3.org/TR/2001/REC-SVG-20010904/DTD/svg10.dtd \">\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 Binary files differdeleted file mode 100644 index 3d1503d..0000000 --- a/chat/bubble.png +++ /dev/null diff --git a/chat/bubbleOutline.png b/chat/bubbleOutline.png Binary files differdeleted file mode 100644 index 334ddca..0000000 --- a/chat/bubbleOutline.png +++ /dev/null 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 "<bold>" - elif name == "italic": - return "<italic>" - 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 "<link " + "href=\"" + address + "\">" - elif name == "link-address": - return "" - elif name.startswith("font-size-"): - tag_name = name.replace("font-size-", "", 1) - return "<font size=\"" + tag_name + "\">" - else: - return "<unknown>" - - def serialize_tag_end(self, tag): - name = tag.get_property("name") - if name == "bold": - return "</bold>" - elif name == "italic": - return "</italic>" - elif name == "link": - return "</link>" - elif name == "link-address": - return "" - elif name.startswith("font-size-"): - return "</font>" - else: - return "</unknown>" - - def serialize(self, buf): - self.buf = buf - - xml = "<richtext>" - - 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 += "</richtext>" - - 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 = "<richtext>" - - xml_string += "<bold><italic>Test</italic>one</bold>\n" - xml_string += "<bold><italic>Test two</italic></bold>" - xml_string += "<font size=\"xx-small\">Test three</font>" - xml_string += "<link href=\"http://www.gnome.org\">Test link</link>" - xml_string += "</richtext>" - - 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() |