Python-spe-users digest, Vol 1 #57 - 3 msgs

python-spe-users-request-tdrK/[email protected] Wed, 04 Jan 2006 12:00:14 +0100
Newsgroups gmane.comp.python.spe.user
Message-ID <[email protected]>
Send Python-spe-users mailing list submissions to
	[email protected]

To subscribe or unsubscribe via the World Wide Web, visit
	http://lists.berlios.de/mailman/listinfo/python-spe-users
or, via email, send a message with subject or body 'help' to
	[email protected]

You can reach the person managing the list at
	[email protected]

When replying, please edit your Subject line so it is more specific
than "Re: Contents of Python-spe-users digest..."


_______________________________________________
http://pythonide.stani.be
http://pythonide.stani.be/manual/html/manual.html
http://pythonide.stani.be/blog/sm_donate _______________________________________________


Today's Topics:

   1. Re: About spe... (SPE Stani's Python Editor)
   2. Re: SPE crashing (SPE Stani's Python Editor)
   3. Re: About SPE's web site (SPE Stani's Python Editor)

--__--__--

Message: 1
Date: Tue, 3 Jan 2006 23:59:54 +0100
From: "SPE Stani's Python Editor" <[email protected]>
To: "rparker-AwAV3ARgcMdWk0Htik3J/[email protected]" <rparker-AwAV3ARgcMdWk0Htik3J/[email protected]>
Cc: python-spe-users-tdrK/[email protected]
Subject: [spe-users] Re: About spe...
Reply-To: [email protected]

------=_Part_33456_20591593.1136329194110
Content-Type: text/plain; charset=ISO-8859-1
Content-Transfer-Encoding: quoted-printable
Content-Disposition: inline

On 12/29/05, rparker-AwAV3ARgcMdWk0Htik3J/[email protected] <rparker-AwAV3ARgcMdWk0Htik3J/[email protected]> wrote:
>
>
> Stani,
>
> I'm using SPE v0.8.1.c on Windows 2000 as a Python newbie. SPE seems like
> a really rich development environment with a plethora of options to choos=
e
> from. It looks like it took a great deal of work to write it.
>
> A few initial reactions:
>
> 1) Some of the ways of running a Python script can return on an error
> without giving the programmer time to read the error message. A lot of th=
ose
> console windows that pop up go away as soon as they head toward exiting. =
An
> error flashes by. It actually helps to have a slower machine if one wants=
 to
> read it.
>    "Run without arguments" seems to be the best choice for seeing the
> errors.


Your wish is my desire. The upcoming version of SPE will free you from thes=
e
sorrows: http://pythonide.stani.be/blog/index_html

2) The Winpdb needs a better way to see errors and general console output.
> It is a fancy looking debugger. But I want to see its console output. The
> separate seemingly console window doesn't show print statements on it.


I'll forward this to Nir Aides, please report further to him.

3) "Execute in shell" ought to be on the same pop-down list as the methods
> of running a program that are listed in the Tools pop-down list.


That's debatable. It executes code immediately in SPE, so I want discourage
that people use it for running programs. Edit deals with selected code and
moreover this menu is identical to the right click popup menu. I disagree.

4) Doing several  "Run without arguments" commands with exceptions in Pytho=
n
> (I'm debugging a lot of new source code) I get to the point where the "SP=
E
> MyFile.py - Press Ctrl+Break to stop" command window comes up with my
> directory but does not execute my program. Then when I try other ways of
> running they stop working too. I can still run WinPdb though. I have to e=
xit
> and restart SPE to get back the local execution capability.


Can you clarify? This might depend on your platform etc... Moreover I think
that the new version will solve this issue as well. If it doesn't please le=
t
me now. The new version is for next week hopefully.

Stani

--
http://pythonide.stani.be
http://pythonide.stani.be/screenshots
http://pythonide.stani.be/manual/html/manual.html

------=_Part_33456_20591593.1136329194110
Content-Type: text/html; charset=ISO-8859-1
Content-Transfer-Encoding: quoted-printable
Content-Disposition: inline

On 12/29/05, <b class=3D"gmail_sendername"><a href=3D"mailto:rparker@vetron=
ix.com">rparker-AwAV3ARgcMdWk0Htik3J/[email protected]</a></b> &lt;<a href=3D"mailto:rparker@vetronix=
.com">rparker-AwAV3ARgcMdWk0Htik3J/[email protected]</a>&gt; wrote:<div><span class=3D"gmail_quote"><=
/span>
<blockquote class=3D"gmail_quote" style=3D"border-left: 1px solid rgb(204, =
204, 204); margin: 0pt 0pt 0pt 0.8ex; padding-left: 1ex;">
<br><font face=3D"sans-serif" size=3D"2">Stani,</font>
<br>
<br><font face=3D"sans-serif" size=3D"2">I'm using SPE v0.8.1.c on Windows =
2000
as a Python newbie. SPE seems like a really rich development environment
with a plethora of options to choose from. It looks like it took a great
deal of work to write it.</font>
<br>
<br><font face=3D"sans-serif" size=3D"2">A few initial reactions:</font>
<br>
<br><font face=3D"sans-serif" size=3D"2">1) Some of the ways of running a P=
ython
script can return on an error without giving the programmer time to read
the error message. A lot of those console windows that pop up go away as
soon as they head toward exiting. An error flashes by. It actually helps
to have a slower machine if one wants to read it.</font>
<br><font face=3D"sans-serif" size=3D"2">&nbsp; &nbsp;&quot;Run without arg=
uments&quot;
seems to be the best choice for seeing the errors. </font></blockquote><div=
><br>
Your wish is my desire. The upcoming version of SPE will free you from thes=
e sorrows: <a href=3D"http://pythonide.stani.be/blog/index_html">http://pyt=
honide.stani.be/blog/index_html</a> <br>
</div><br><blockquote class=3D"gmail_quote" style=3D"border-left: 1px solid=
 rgb(204, 204, 204); margin: 0pt 0pt 0pt 0.8ex; padding-left: 1ex;"><font f=
ace=3D"sans-serif" size=3D"2">2) The Winpdb needs a better way to
see errors and general console output. It is a fancy looking debugger.
But I want to see its console output. The separate seemingly console window
doesn't show print statements on it. </font></blockquote><div><br>
I'll forward this to Nir Aides, please report further to him. <br>
</div><br><blockquote class=3D"gmail_quote" style=3D"border-left: 1px solid=
 rgb(204, 204, 204); margin: 0pt 0pt 0pt 0.8ex; padding-left: 1ex;"><font f=
ace=3D"sans-serif" size=3D"2">3) &quot;Execute in shell&quot; ought
to be on the same pop-down list as the methods of running a program that
are listed in the Tools pop-down list.</font></blockquote><div><br>
That's debatable. It executes code immediately in SPE, so I want
discourage that people use it for running programs. Edit deals with
selected code and moreover this menu is identical to the right click
popup menu. I disagree.<br>
</div><br><blockquote class=3D"gmail_quote" style=3D"border-left: 1px solid=
 rgb(204, 204, 204); margin: 0pt 0pt 0pt 0.8ex; padding-left: 1ex;"><font f=
ace=3D"sans-serif" size=3D"2">4) Doing several &nbsp;&quot;Run without
arguments&quot; commands with exceptions in Python (I'm debugging a lot
of new source code) I get to the point where the &quot;SPE MyFile.py -
Press Ctrl+Break to stop&quot; command window comes up with my directory
but does not execute my program. Then when I try other ways of running
they stop working too. I can still run WinPdb though. I have to exit and
restart SPE to get back the local execution capability.</font></blockquote>=
<div><br>
Can you clarify? This might depend on your platform etc... Moreover I
think that the new version will solve this issue as well. If it doesn't
please let me now. The new version is for next week hopefully.<br>
</div><br></div>Stani<br clear=3D"all"><br>-- <br><a href=3D"http://pythoni=
de.stani.be">http://pythonide.stani.be</a><br><a href=3D"http://pythonide.s=
tani.be/screenshots">http://pythonide.stani.be/screenshots</a><br><a href=
=3D"http://pythonide.stani.be/manual/html/manual.html">
http://pythonide.stani.be/manual/html/manual.html</a>

------=_Part_33456_20591593.1136329194110--

--__--__--

Message: 2
Date: Wed, 4 Jan 2006 00:34:24 +0100
From: "SPE Stani's Python Editor" <[email protected]>
To: Karlo Lozovina <[email protected]>
Cc: python-spe-users-tdrK/[email protected]
Subject: [spe-users] Re: SPE crashing
Reply-To: [email protected]

------=_Part_34203_29416001.1136331264404
Content-Type: text/plain; charset=ISO-8859-1
Content-Transfer-Encoding: quoted-printable
Content-Disposition: inline

Hi Karlo,

I bumped into this myself, replace _spe/sm/wxp/realtime.py with this
version and let me know if it is fixed.

If for some reason you can't start up SPE anymore it is probably
caused by a problematic source file that SPE rejects. There is no need
to reinstall SPE in such case. Just remove the '.spe' folder in your
system user path:
- on Windows: C:\Documents and Settings\user_name\
- on Mac: /Users/user_name/
- on *unix (Ubuntu, ...): /home/user_name/

Try to find out which file causes the error. Please send the
problematic source file to me, so I can inspect what goes wrong and
solve the issue.

Stani

On 12/31/05, Karlo Lozovina <[email protected]> wrote:
> Hello there,
>
> I've been using SPE for a week or two, and as of today it won't work
> anymore :(. I've attached the --debug output, as well as the
> problematic .py file.
>
> I tried to fix the thing myself, but I'm still to green in wxPython
> and Python in general to do it, so, if you could look into it I would
> be most thankful.
>
> P.S.
> Tried reinstalling SPE, didn't help :(.
>
> Thanks in advance...
>
> --
> Karlo Lozovina - Mosor
>
>



--
http://pythonide.stani.be
http://pythonide.stani.be/screenshots
http://pythonide.stani.be/manual/html/manual.html

------=_Part_34203_29416001.1136331264404
Content-Type: text/x-python; name=realtime.py; charset=us-ascii
Content-Transfer-Encoding: 7bit
Content-Disposition: attachment; filename="realtime.py"

"""realtime.py | GPL - license | (c)2005 www.stani.be

This module provides two classes which enable to update only selectively parts
of a wx.TreeCtrl or a wx.ListCtrl. This makes fast/realtime updating possible
of only changed items instead of the whole tree or list.

These classes are used in SPE's sidebar:
- TreeCtrl for Explore
- ListCtrl for Todo & Index"""

#todo: Maybe self.deleted of Item is not necessary

import wx

WARNING = 'Warning: %s: please contact spe.stani.be at gmail.com'

class Item:
    backgroundColour    = (255,255,255)
    data                = None
    deleted             = False
    textColour          = (0,0,0)
    wx                  = None
    def reset(self):
        self._update    = [] #lists should be created for each instance separately
        self._updateAll = []
        
class Ctrl:
    _base                   = None
    def __init__(self):
        self.items  = {}

    def _createUniqueId(self,base,others=[],data=None):
        """Create unique id with data & index."""
        if data:
            try:
                dataId      = '|'+repr(data)
            except:
                dataId      = ''
        else:
            dataId          = ''
        id                  = ('%s%s|%%d'%(base,dataId)).encode('ascii','replace')
        nr                  = 0
        othersId            = [other.id for other in others]
        while id%nr in othersId:
            nr              += 1
        return id%nr
        
    def _deleteItem(self,item,fromItems=True):
        """Delete safely (not wx) item from self._items"""
        if item.wx != None and not item.deleted:
            self._wxDeleteItem(self,item.wx)
            item.wx = None
        if fromItems:
            item._delete()
            if self.items.has_key(item.id):
                del self.items[item.id]
            
    def _renewItem(self,item):
        """DeleteWx component and refresh update.
        This is used for an item which previously came earlier."""
        self._deleteItem(item, fromItems = False)
        item._update    = item._updateAll

    def _DeleteItem(self,item):
        """Indepedent delete wx item method (to be overwritten)."""
        
    def _insertItem(self,parent,children,index,text):
        """Inserts an item after a given one, used by self._update()
        (to be overwritten)"""
            
    def _prependItem(self,parent,text):
        """Inserts an item as the first one, used by self._update().
        (to be overwritten)"""
        
    def _update(self,parent,recursively=False):
        """Update (recursively) all children (Item) of parent(Item or List)."""
        children                = parent.children
        previousChildren        = parent.previousChildren
        for index, child in enumerate(children[:]):
            if child in previousChildren:
                #child exists already
                prevIndex       = previousChildren.index(child)
                abandoneds      = previousChildren[:prevIndex]
                abandoneds.reverse()
                for abandoned in abandoneds:
                    if abandoned in children:
                        #only remove wx attribute
                        self._renewItem(abandoned)
                    else:
                        #remove everything
                        self._DeleteItem(abandoned)
                previousChildren= previousChildren[prevIndex+1:]
            elif previousChildren and previousChildren[0] not in children:
                #child can be copied in existing, abandoned item
                empty_slot      = previousChildren[0]
                child           = children[index]\
                                = self._copyItemTo(child,empty_slot)
                previousChildren= previousChildren[1:]
            else:
                #child must be created
                if index>0:
                    child.wx        = self._insertItem(parent,children,index,child.text)
                else:
                    child.wx        = self._prependItem(parent,child.text)
            self._updateItem(child,index)
            #recursive on its children
            if recursively:
                self._update(child,True)
        for abandoned in previousChildren:
            self._DeleteItem(abandoned)
        parent.previousChildren = children
        
    def _updateItem(self,item,index=None):
        """Execute pending update actions of TreeItem"""
        for action in item._update:
            arguments = [self,item.wx]
            arguments.extend(action[1:])
            action[0](*arguments)

    def SetItemTextColour(self,item,color):
        """Sets the text colour of a TreeItem"""
        if item.textColour != color:
            item.textColour = color
            item._update.append((self._base.SetItemTextColour,color))
        item._updateAll.append((self._base.SetItemTextColour,color))
            
    def SetItemBackgroundColour(self,item,color):
        """Sets the background colour of a TreeItem"""
        if item.backgroundColour != color:
            item.backgroundColour = color
            item._update.append((self._base.SetItemBackgroundColour,color))
        item._updateAll.append((self._base.SetItemBackgroundColour,color))
            
class TreeItem(Item):
    """All the wx actions are handled by the Tree class."""
    bold = False
    
    def __init__(self,text,id):
        """self.wx holds the wx.TreeItemData"""
        self.id                 = id
        self.text               = text
        #
        self.previousChildren   = []
        self.image              = {}
        self.reset()
        
    def _delete(self):
        """When an item is removed its children are also removed recursively."""
        for child in self.children:
            if child.children:
                child._delete();
            child.deleted = True
        self.deleted    = True
        
    def reset(self):
        Item.reset(self)
        self.children           = []
        
class TreeCtrl(Ctrl,wx.TreeCtrl):
    
    _base   = wx.TreeCtrl
    
    def __init__(self,*args,**kwargs):
        Ctrl.__init__(self)
        wx.TreeCtrl.__init__(self,*args, **kwargs)
        self._DeleteItem    = self.Delete
        self._wxDeleteItem  = wx.TreeCtrl.Delete
        self._style         = kwargs['style']
        self._hideRoot      = self._style & wx.TR_HIDE_ROOT
        
    def _copyItemTo(self,frm,to):
        """Copy/steal wx control from an abandoned TreeItem to avoid creating a new wx control."""
        frm.wx  = to.wx
        if frm.data != to.data:
            frm._update.append((wx.TreeCtrl.SetPyData,frm.data))
        frm._updateAll.append((wx.TreeCtrl.SetPyData,frm.data))
        frm.previousChildren = to.previousChildren
        if frm.text != to.text:
            frm._update.append((wx.TreeCtrl.SetItemText,frm.text))
        frm._updateAll.append((wx.TreeCtrl.SetItemText,frm.text))
        return frm
        
    def _insertItem(self,parent,children,index,text):
        """Inserts an item after a given one."""
        return wx.TreeCtrl.InsertItem(self,parent.wx,children[index-1].wx,text)
    
    def _prependItem(self,parent,text):
        """Inserts an item as the first one."""
        return wx.TreeCtrl.PrependItem(self,parent.wx,text)

    def AddRoot(self,text):
        self.root           = TreeItem(text=text,id=text)
        self.items[text]    = self.root
        self.root.wx        = wx.TreeCtrl.AddRoot(self,text)
        if not self._hideRoot: 
            self.root._update.append((wx.TreeCtrl.Expand,))
        return self.root
        
    def AppendItem(self,parent,text,data=None):
        """Add data immediately, if the label is not unique. Be aware that that
        is a devation from wx.ListCtrl, if data is not wxTreeItemData.
        
        There are two possibilities that an item is appended to its parent
        - if already present, pick it up and update the text
        - if not, create one item"""
        if hasattr(data,'GetData'): data = data.GetData()
        pChildren           = parent.children
        id                  = self._createUniqueId(
                                base    = '%s|%s'%(parent.id,text),
                                others  = pChildren,
                                data    = data
                            )
        #get item
        if self.items.has_key(id):
            item            = self.items[id]
            item.reset()
        else:
            item            = self.items[id] = TreeItem(text=text,id=id)
        pChildren.append(item)
        #data
        if data != None:
            self.SetPyData(item,data)
        return item
        
    def Delete(self,item):
        """Delete item and all its children from the tree."""
        self._deleteItem(item)
        
    def Update(self):
        """Update only differences between current and previous state.
        This method MUST be called in the end otherwise there will be no visual
        change."""
        self._update(self.root,recursively=True)
        self._updateItem(self.root)
        
    def Collapse(self,item):
        """Collapse a TreeItem."""
        if wx.TreeCtrl.IsExpanded(self,item.wx):
            wx.TreeCtrl.Collapse(self,item.wx)
            
    def CollapseAndReset(self,item):
        """Remove children of a TreeItem, mostly used for self.root."""
        item.children = []
           
    def Expand(self,item):
        """Expands a TreeItem."""
        if not ((self._hideRoot and item == self.root) or wx.TreeCtrl.IsExpanded(self,item.wx)):
            wx.TreeCtrl.Expand(self,item.wx)
            
    def SetItemBold(self,item,bold=True):
        """Sets the background colour of a TreeItem"""
        if item.bold != bold:
            item.bold = bold
            item._update.append((wx.TreeCtrl.SetItemBold,bold))
        item._updateAll.append((wx.TreeCtrl.SetItemBold,bold))
        
    def SetItemImage(self,item,image,which=wx.TreeItemIcon_Normal):
        """Sets the image for a certain state (which) of a TreeItem"""
        if (not item.image.has_key(which)) or item.image[which] != image:
            item.image[which] = image
            item._update.append((wx.TreeCtrl.SetItemImage,image,which))
        item._updateAll.append((wx.TreeCtrl.SetItemImage,image,which))
        
    def SetItemText(self,item,text):
        """Sets the text of a TreeItem"""
        if item.text != text:
            item.text = text
            item._update.append((wx.TreeCtrl.SetItemText,text))
        item._updateAll.append((wx.TreeCtrl.SetItemText,text))
            
    def SetPyData(self,item,data):
        """Sets the py data of a TreeItem."""
        if item.data != data:
            item.data = data
            item._update.append((wx.TreeCtrl.SetPyData,data))
        item._updateAll.append((wx.TreeCtrl.SetPyData,data))

class ListItem(Item):
    def __init__(self,index,text,id):
        self.index              = index
        self.text               = text
        self.id                 = id
        #
        self.image              = None
        self.reset()
        
    def _delete(self):
        """Flag as deleted."""
        self.deleted    = True
        
class ListCtrl(Ctrl,wx.ListCtrl):

    _base = wx.ListCtrl
    
    def __init__(self,*args,**kwds):
        Ctrl.__init__(self)
        wx.ListCtrl.__init__(self,*args,**kwds)
        self._DeleteItem          = self.DeleteItem
        self._wxDeleteItem        = wx.ListCtrl.DeleteItem
        self.children           = []
        self.previousChildren   = []
        
    def _copyItemTo(self,frm,to):
        """Copy/steal wx control from an abandoned TreeItem to avoid creating a new wx control."""
        frm.wx  = to.wx
        if frm.data != to.data:
            frm._update.append((wx.ListCtrl.SetItemData,frm.data))
        frm._updateAll.append((wx.ListCtrl.SetItemData,frm.data))
        toText  = to.text
        for column, label in frm.text.items():
            if toText.has_key(column) and label != toText[column]:
                frm._update.append((wx.ListCtrl.SetStringItem,column,label))
            frm._updateAll.append((wx.ListCtrl.SetStringItem,column,label))
        return frm
        
    def _insertItem(self,parent,children,index,text):
        """Inserts an item after a given one."""
        return wx.ListCtrl.InsertStringItem(self,index,text[0])
        
    def _prependItem(self,parent,text):
        """Inserts an item as the first one."""
        return wx.ListCtrl.InsertStringItem(self,0,text[0])
        
    def _updateItem(self,item,index):
        """Same as Ctrl, but update also index."""
        item.wx = index
        Ctrl._updateItem(self,item,index)
        
    def DeleteAllItems(self):
        self.children = []
            
    def DeleteItem(self,item):
        """Delete item safely."""
        if item in self.children:
            self.children.remove(item)
        self._deleteItem(item)
    
    def InsertStringItem(self,index,label,data=None):
        """Add data immediately, if the label is not unique. Be aware that that
        is a devation from wx.ListCtrl
        
        There are two possibilities that an item is appended to its parent
        - if already present, pick it up and update the text
        - if not, create one item"""
        id                  = self._createUniqueId(
                                base    = label,
                                others  = self.children,
                                data    = data
                            )
        #get item
        if self.items.has_key(id):
            item            = self.items[id]
            item.reset()
        else:
            item            = self.items[id] = ListItem(index=index,text={0:label},id=id)
        self.children.append(item)
        #data
        if data != None:
            self.SetItemData(item,data)
        return item
        
    def InsertImageStringItem(self,index,label,imageIndex):
        item = self.InsertStringItem(index,label)
        self.SetItemImage(item,imageIndex)
        return item
        
    def SetItemImage(self,item,imageIndex):
        if item.image != imageIndex:
            item.image = imageIndex
            item._update.append((wx.ListCtrl.SetItemImage,imageIndex))
        item._updateAll.append((wx.ListCtrl.SetItemImage,imageIndex))
        
    def SetItemData(self,item,data):
        if item.data != data:
            item.data = data
            item._update.append((wx.ListCtrl.SetItemData,data))
        item._updateAll.append((wx.ListCtrl.SetItemData,data))
        
    def SetItemText(self,item,text):
        """Sets the text of a TreeItem"""
        if item.text != text:
            item.text = text
            item._update.append((wx.TreeCtrl.SetItemText,text))
        item._updateAll.append((wx.TreeCtrl.SetItemText,text))
            
    def SetStringItem(self,item,column,label):
        text                = item.text
        if not text.has_key(column) or text[column] != label:
            text[column]    = label
            item._update.append((wx.ListCtrl.SetStringItem,column,label))
        item._updateAll.append((wx.ListCtrl.SetStringItem,column,label))
                    
    def Update(self):
        """Update only differences between current and previous state.
        This method MUST be called in the end otherwise there will be no visual
        change."""
        self._update(self,recursively=False)



------=_Part_34203_29416001.1136331264404--

--__--__--

Message: 3
Date: Wed, 4 Jan 2006 01:04:31 +0100
From: "SPE Stani's Python Editor" <[email protected]>
To: Eduardo Gonzalez <[email protected]>
Cc: python-spe-users-tdrK/[email protected]
Subject: [spe-users] Re: About SPE's web site
Reply-To: [email protected]

On 12/31/05, Eduardo Gonzalez <[email protected]> wrote:
> I noticed that there was a pop-up ad on your website today.  I really
> don't like pop-up ads.  I would like to ask you to remove it from your
> site.  I have pop-up windows open in new tabs and the site I was sent
> to resized my whole browser window and moved it in a way that made it
> hard to resize it back.

I agree. I have no idea where they come from. They don't generate
income for SPE. I will try to find out. Before it was not like that
and I was never warned about this. I hope I can kill them.

> I have noticed an insane amount of advertising on your web site.  I'd
> say it has more advertisements and pleas for donations than any other
> open-source project I've ever seen.  Are these really necessary?  On
> average how much money do you get from these?

Unfortunately developing SPE takes an insane amount of my time for
which I am not financially rewarded. Not to mention the time it takes
to answer all the emails of which I get several a day. Let's keep it
simple: without ads the SPE project would be dead. The amount of
donations I get are unfortunately far to low. In that sense checking
advertisements of your interest is a way to donate without spending
your own money.
I hope a lot of SPE users prefer their IDE to continue to exist and
develop, rather than seeing the project to end. As I hate
advertisements myself, I am open for any suggestion which can provide
me with the necessary income to develop SPE in an alternative way. The
trick to offer the manual ad-free is just another trick to incite more
people to donate. Believe me, I would prefer if I could offer
everything for free without ads.
I'm afraid the Google TOS doesn't allow me to share the financial
details, but it should multiply by five to pay my time back..

Criticizing SPE for this issue is easy, to provide a solution is
another thing... If you have some constructive proposals, feel free to
continue this discussion on the spe-users list.

Stani

--
http://pythonide.stani.be
http://pythonide.stani.be/screenshots
http://pythonide.stani.be/manual/html/manual.html


--__--__--

_______________________________________________
Python-spe-users mailing list
[email protected]
http://lists.berlios.de/mailman/listinfo/python-spe-users


End of Python-spe-users Digest