It works!
authorStefanos Harhalakis <v13@v13.gr>
Thu, 20 Jan 2011 22:51:11 +0000 (22:51 +0000)
committerStefanos Harhalakis <v13@v13.gr>
Thu, 20 Jan 2011 22:51:11 +0000 (22:51 +0000)
Fixed memory leak (hard one).
Fixed crash (hard one).
Implemented nice icon resizing.
Fixed backround drawing int config window.
Misc fixes.

src/apps.py
src/config.py
src/icon.py
src/icongrid.py
src/icons.py
src/iconw.py [new file with mode: 0644]
src/sig.py [new file with mode: 0644]
src/widget.py
src/win_config.py

index f078b04..1a7336f 100755 (executable)
@@ -31,6 +31,8 @@ from gettext import translation
 
 appdir="/usr/share/applications/hildon"
 
+apps={}
+
 def readOneFn(fn):
     global appdir
 
@@ -105,7 +107,7 @@ def readOne(name):
     return(ret)
 
 def scan():
-    global appdir
+    global appdir, apps
 
     files=os.listdir(appdir)
 
@@ -127,8 +129,15 @@ def scan():
        t=f[:-8]
        ret[t]=dt
 
+    apps=ret
+
     return(ret)
 
+def getLastScan():
+    global apps
+
+    return(apps)
+
 if __name__=="__main__":
     #locale.setlocale(locale.LC_ALL, '')
     print scan()
index ac61424..50ae471 100755 (executable)
@@ -54,7 +54,7 @@ def get_config_fn():
 
     return(ret)
 
-class Config:
+class Config(object):
     def __init__(self, id):
        self.id=id
 
@@ -92,6 +92,7 @@ class Config:
        self.iconpadding=12
        self.iconmargin=6
 
+    # Return the maximum grid size
     def getMaxSize(self):
        isf=self.getIconSizeFull()
        retx=int(800/isf)
@@ -99,6 +100,16 @@ class Config:
        maxsz=(retx, rety)
        return(maxsz)
 
+    # Return the maxmimum icon size
+    def getIconSizeRange(self):
+       return((48,128))
+
+    def getIconPaddingRange(self):
+       return((0,32))
+
+    def getIconMarginRange(self):
+       return((0,16))
+
     def getIconSize(self):
        return(self.iconsize)
 
@@ -339,5 +350,14 @@ class Config:
            print "config.init() not done"
            sys.exit(1)
 
+def dump(obj):
+    attrs=[attr for attr in dir(obj) if not callable(getattr(obj,attr))]
+
+    print "obj:", obj
+    for attr in attrs:
+       if attr=='__gdoc__' or attr=='__doc__':
+           continue
+       print "  ", attr, ":", getattr(obj, attr)
+
 # vim: set ts=8 sts=4 sw=4 noet formatoptions=r ai nocindent:
 
index 6c7e72b..c4ea529 100755 (executable)
@@ -34,7 +34,7 @@ import time
 from portrait import FremantleRotation
 import launcher
 from xdg.IconTheme import getIconPath
-
+from sig import Disconnector
 
 #import config
 import apps
@@ -72,14 +72,31 @@ def getIcon(name, iconsize):
 
     return(ret)
 
-class Icon(gobject.GObject):
+class Icon(Disconnector, gobject.GObject):
+#class Icon(gtk.Widget, Disconnector):
+
+    __v_t=(gobject.SIGNAL_RUN_FIRST | gobject.SIGNAL_ACTION,
+           gobject.TYPE_NONE, ())
+
+    gsignals={
+       'click':            __v_t,
+       'double-click':     __v_t,
+       'tripple-click':    __v_t,
+       'long-press':       __v_t,
+       }
+
+    __gsignals__=gsignals
+
     def __init__(self, isconfig, config):
-       self.__gobject_init__()
+#      self.__gobject_init__()
+       gobject.GObject.__init__(self)
+#      gtk.Widget.__init__(self)
+       Disconnector.__init__(self)
 
        self.isconfig=isconfig
        self.config=config
 
-       self.name=None
+       self.appname=None
        self.icon=None
         self.sicon=None
        self.lastpress=0
@@ -90,7 +107,7 @@ class Icon(gobject.GObject):
 
        self.presstime=0.25
 
-       self.window=None
+       self.window_=None
 
        self.clickcount=0
 
@@ -100,6 +117,12 @@ class Icon(gobject.GObject):
 
        self.draw_queued=False
 
+       #print "icon-init"
+
+    def __del__(self):
+       #print "icon-del"
+       pass
+
     def timePressed(self):
        """ return how much time a button is pressed """
        dt=time.time() - self.lastpress
@@ -113,11 +136,11 @@ class Icon(gobject.GObject):
 
     def setApp(self, dt):
        if dt==None:
-           self.name=None
+           self.appname=None
            self.icon=None
            self.sicon=None
        else:
-           self.name=dt['id']
+           self.appname=dt['id']
            self.icon=dt['icon2']
            self.sicon=None
        self.clearAnimationCache()
@@ -383,6 +406,7 @@ class Icon(gobject.GObject):
            self.clickcount+=1
            if self.clickcount==1:
                self.emit('click')
+#              print "emit click", self
            elif self.clickcount==2:
                self.emit('double-click')
            if self.clickcount==3:
@@ -390,18 +414,19 @@ class Icon(gobject.GObject):
                self.clickcount=0
        elif dt>self.presstime and dt<2:
            self.emit('long-press')
+#          print "Emit lp"
 
     def doCancel(self):
        self.ispressed=False
 
     def setWindow(self, window):
-       self.window=window
+       self.window_=window
 
     def invalidate(self, window=None):
        if window==None:
-           window=self.window
+           window=self.window_
        else:
-           self.window=window
+           self.window_=window
 
        if window==None:
            return
@@ -415,11 +440,11 @@ class Icon(gobject.GObject):
        rect=gdk.Rectangle(self.x, self.y, w, w)
        gdk.Window.invalidate_rect(window, rect, True)
 
-gobject.type_register(Icon)
-signals=['click', 'double-click', 'tripple-click', 'long-press']
-for s in signals:
-    gobject.signal_new(s, Icon, gobject.SIGNAL_RUN_FIRST,
-       gobject.TYPE_NONE, ())
+#gobject.type_register(Icon)
+#signals=['click', 'double-click', 'tripple-click', 'long-press']
+#for s in signals:
+#    gobject.signal_new(s, Icon, gobject.SIGNAL_RUN_FIRST | \
+#      gobject.SIGNAL_ACTION, gobject.TYPE_NONE, ())
 
 # vim: set ts=8 sts=4 sw=4 noet formatoptions=r ai nocindent:
 
index e90bd9d..96588d5 100755 (executable)
@@ -34,7 +34,7 @@ import time
 from portrait import FremantleRotation
 #from xdg.IconTheme import getIconPath
 
-#import config
+from config import dump
 import apps
 import icon
 from icon import Icon
@@ -46,10 +46,18 @@ from icons import Icons
 #
 #    return(ret)
 
+# IconGrid is the main class that implements tha drawing of the grid
+# However, since it will be used both by the desktop plugin and the
+# configuration window, it cannot derive either gtk.Widget or HomePluginItem.
+# It is created here in a way that will allow it to work on both cases
+# and it is inherited by appropriate classes (one for the plugin and one
+# for the config widget)
+
 #class IconGrid(gtk.Widget, FremantleRotation):
-class IconGrid(object):        #(gobject.GObject):
+class IconGrid:        #(gobject.GObject):
     def __init__(self, isconfig=False):
 #      self.__gobject_init__()
+#      gtk.Widget.__init__(self)
 
        self.init_done=False
 
@@ -72,19 +80,46 @@ class IconGrid(object):     #(gobject.GObject):
        # Duration of the rotation effect
        self.rotation_time=0.8
 
+#      print "ig-init"
+
+#    def __del__(self):
+#      print "ig-del"
+
     def do_realize(self, config):
+#      print "ig-realize"
        self.config=config
 
+       if self.icons!=None:
+           print
+           print
+           print
+           print "WTF??????????????????????"
+           print
+           print
+           print
+
        self.icons=Icons(self.isconfig, self.config)
+       #print "self:", self
+       #self.icons.set_parent(self)
        self.setMode('l')
        self.setSize(config.getMaxSize())
        self.reloadIcons()
 
+    def do_unrealize(self):
+#      print "ig-unrealize"
+       self.config=None
+       self.icons.finish()
+       self.icons=None
+       self.lasticon=None
+
     def connect(self, what, *args):
-       if what in icon.signals:
-           self.icons.connect(what, *args)
+       if what in Icon.gsignals.keys():
+           ret=self.icons.connect(what, *args)
        else:
-           super(IconGrid, self).connect(what, *args)
+           ret=gobject.GObject.connect(self, what, *args)
+           #ret=super(IconGrid, self).connect(what, *args)
+
+       return(ret)
 
     def setSize(self, size):
        self.size=size
@@ -96,7 +131,7 @@ class IconGrid(object):      #(gobject.GObject):
 
     def setMode(self, mode):
        if self.mode==mode:
-           print "same mode"
+#          print "same mode"
            return
 
        self.mode=mode
@@ -331,6 +366,7 @@ class IconGrid(object):     #(gobject.GObject):
 
     def reloadIcons(self):
        self.icons.load()
+       self.lasticon=None
 
 #    def on_orientation_changed(self, orientation):
 #      print "orch:", orientation
@@ -351,6 +387,11 @@ class IconGridWidget(IconGrid, gtk.Widget):
 
        self.setSize(self.size)
 
+#      print "igw-init"
+
+#    def __del__(self):
+#      print "igw-del"
+
     def setSize(self, size):
        IconGrid.setSize(self, size)
 
@@ -360,12 +401,15 @@ class IconGridWidget(IconGrid, gtk.Widget):
        self.set_size_request(w, h)
 
     def reconfig(self):
+       self.clearBgCache()
+       self.clearAnimationCache()
        self.reloadIcons()
        self.setSize(self.size)
        self.icons.resizeMax()
        self.queue_draw()
 
     def do_realize(self):
+#      print "igw-realize"
        screen=self.get_screen()
        self.set_colormap(screen.get_rgba_colormap())
        self.set_app_paintable(True)
@@ -388,9 +432,21 @@ class IconGridWidget(IconGrid, gtk.Widget):
                | gdk.LEAVE_NOTIFY_MASK )
 
        self.window.set_user_data(self)
-       self.style.attach(self.window)
 
-#      self.style.set_background(self.window, gtk.STATE_NORMAL)
+       # No matter what the pygtk widget demo says, this is NOT CORRECT!!!
+       # Don't call style.attach(self.window) or else the program will crash
+       # after some time! It seems that there is a style already.
+       # If we want to use the style the we use get_style() instead.
+       # This one was very hard to solve. Thanks to gnome2-globalmenu guys.
+       # It was solved by looking the commit 2666:
+       # see:
+       # svn diff -r2665:2666 http://gnome2-globalmenu.googlecode.com/svn/trunk
+       # which solved cse 490:
+       # http://code.google.com/p/gnome2-globalmenu/issues/detail?id=490
+#      self.style.attach(self.window)
+       style=self.get_style()
+
+#      style.set_background(self.window, gtk.STATE_NORMAL)
        self.window.move_resize(*self.allocation)
 
 #      self.pixmap, mask = gtk.gdk.pixmap_create_from_xpm_d(
@@ -398,7 +454,6 @@ class IconGridWidget(IconGrid, gtk.Widget):
        
 #      self.gc = self.style.fg_gc[gtk.STATE_NORMAL]
 
-       #gtk.Widget.do_realize(self)
        #HomePluginItem.do_realize(self)
 
 #      screen=self.get_screen()
@@ -406,8 +461,24 @@ class IconGridWidget(IconGrid, gtk.Widget):
 #      self.set_app_paintable(True)
 
     def do_unrealize(self):
-       #self.window.set_user_data(None)
+#      print "igw-unrealize", self
+       IconGrid.do_unrealize(self)
        self.window.destroy()
+       self.window.set_user_data(None)
+
+    def do_expose_event(self, event):
+       cr=self.window.cairo_create()
+
+       cr.rectangle(event.area.x, event.area.y,
+           event.area.width, event.area.height)
+       cr.clip()
+
+       style=self.get_style()
+       col=style.bg[gtk.STATE_NORMAL]
+       cr.set_source_color(col)
+       cr.paint()
+
+       IconGrid.do_expose_event(self, event)
 
 #gobject.type_register(IconGrid)
 gobject.type_register(IconGridWidget)
index 8f2c189..808d922 100755 (executable)
@@ -26,8 +26,10 @@ __version__ = "$Id: 0.py 2265 2010-02-21 19:16:26Z v13 $"
 import apps
 import icon
 from icon import getIcon, Icon
+from sig import Disconnector
 
 import gobject
+import gtk
 
 class IconIter:
     def __init__(self, items):
@@ -41,9 +43,16 @@ class IconIter:
        ret=self.iter.next()
        return(ret)
 
-class Icons(gobject.GObject):
+class Icons(gobject.GObject, Disconnector):
+#class Icons(gtk.Widget, Disconnector):
+
+    #__gsignals__=Icon.gsignals
     def __init__(self, isconfig, config):
        self.__gobject_init__()
+       #gobject.GObject.__init__(self)
+       #gtk.Widget.__init__(self)
+       Disconnector.__init__(self)
+
        self.icons={}
        self.allicons={}
        self.size=0
@@ -51,13 +60,25 @@ class Icons(gobject.GObject):
        self.config=config
 
        # signal handlers
-       self.h={}
+       self.handlers={}
 
        self.maxsz=(0,0)
 
        # setup allicons
        self.resizeMax()
 
+#      print "icons-init"
+
+    def finish(self):
+       self.dis_finish()
+       return
+#      self.icons=None
+#      self.allicons=None
+#      print "icons-finish"
+
+#    def __del__(self):
+#      print "icons-del"
+
     def resizeMax(self):
        sz=self.maxsz
        maxsz=self.config.getMaxSize()
@@ -75,7 +96,8 @@ class Icons(gobject.GObject):
            for x in xrange(sz[0]-maxsz[0]):
                for y in xrange(sz[1]):
                    k=(maxsz[0]+x,y)
-                   self.allicons.pop(k)
+                   t=self.allicons.pop(k)
+                   self.disconnect_one(t)
            sz=(maxsz[0], sz[1])
 
        # Create new entries in y
@@ -91,33 +113,36 @@ class Icons(gobject.GObject):
            for y in xrange(sz[1]-maxsz[1]):
                for x in xrange(sz[0]):
                    k=(x,y+maxsz[1])
-                   self.allicons.pop(k)
+                   t=self.allicons.pop(k)
+                   self.disconnect_one(t)
            sz=(sz[0], maxsz[1])
 
        self.maxsz=sz
 
     @classmethod
     def register_signals(cls):
-       signals=icon.signals
+       signals=Icon.gsignals
        for s in signals:
-           gobject.signal_new(s, cls, gobject.SIGNAL_RUN_FIRST,
-               gobject.TYPE_NONE, (Icon,))
+           ss=signals[s]
+           gobject.signal_new(s, cls, ss[0], ss[1], (Icon,))
+#          gobject.SIGNAL_RUN_FIRST,
+#              gobject.TYPE_NONE, (Icon,))
 
     def __iter__(self):
        return(IconIter(self.icons))
 
     def connect_one(self, which):
-       self.h[which]={
-           'longpress':    which.connect('long-press', self.signalLongpress),
-           'click':        which.connect('click', self.signalClick),
-           'tripple':      which.connect('tripple-click',
+       self.handlers[which]={
+           'longpress':    self.c(which, 'long-press', self.signalLongpress),
+           'click':        self.c(which, 'click', self.signalClick),
+           'tripple':      self.c(which, 'tripple-click',
                                self.signalTrippleClick)
            }
 
     def disconnect_one(self, which):
-       for i in self.h[which]:
-           which.disconnect(self.h[which][i])
-       self.h.pop(which)
+       for i in self.handlers[which]:
+           which.disconnect(self.handlers[which][i])
+       self.handlers.pop(which)
 #      which.disconnect(self.h[which]_longpress)
 #      which.disconnect(self.h_click)
 #      which.disconnect(self.h_tripple)
diff --git a/src/iconw.py b/src/iconw.py
new file mode 100644 (file)
index 0000000..f7f13e7
--- /dev/null
@@ -0,0 +1,125 @@
+#!/usr/bin/env python
+# coding=UTF-8
+# 
+# Copyright (C) 2010 Stefanos Harhalakis
+#
+# This file is part of wifieye.
+#
+# wifieye is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# wifieye is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with wifieye.  If not, see <http://www.gnu.org/licenses/>.
+#
+# $Id: 0.py 2265 2010-02-21 19:16:26Z v13 $
+
+__version__ = "$Id: 0.py 2265 2010-02-21 19:16:26Z v13 $"
+
+from icon import Icon, getIcon
+import apps
+
+import gtk
+import cairo
+from gtk import gdk
+import gobject
+
+class IconWidget(gtk.Widget):
+    def __init__(self, isconfig, config):
+       gtk.Widget.__init__(self)
+
+       self.config=config
+       self.icon=Icon(isconfig, config)
+
+    def getMaxIconSizeFull(self):
+       c=self.config
+       w=c.getIconSizeRange()[1] + 2*c.getIconPaddingRange()[1] + \
+           2*c.getIconMarginRange()[1]
+
+       return(w)
+
+    def resetSize(self):
+       w=self.getMaxIconSizeFull()
+       self.set_size_request(2*w, 2*w)
+
+    def do_realize(self):
+       screen=self.get_screen()
+       self.set_colormap(screen.get_rgba_colormap())
+       self.set_app_paintable(True)
+
+       self.set_flags(self.flags() | gtk.REALIZED)
+
+       self.window=gdk.Window(
+           self.get_parent_window(),
+           width=self.allocation.width,
+           height=self.allocation.height,
+           window_type=gdk.WINDOW_CHILD,
+           wclass=gdk.INPUT_OUTPUT,
+           event_mask=self.get_events() | gdk.EXPOSURE_MASK)
+
+       self.window.set_user_data(self)
+
+       self.window.move_resize(*self.allocation)
+
+#      style=self.get_style()
+#      style.set_background(self.window, gtk.STATE_NORMAL)
+#      self.gc=style.bg_gc[gtk.STATE_NORMAL]
+
+       self.icon.setWindow(self.window)
+       self.resetSize()
+
+    def do_unrealize(self):
+       self.window.destroy()
+       self.window.set_user_data(None)
+
+    def do_expose_event(self, event):
+       cr=self.window.cairo_create()
+
+       cr.rectangle(event.area.x, event.area.y,
+           event.area.width, event.area.height)
+
+       cr.clip()
+
+       cr.save()
+       # Paint the background
+       style=self.get_style()
+       col=style.bg[gtk.STATE_NORMAL]
+       cr.set_source_color(col)
+       cr.paint()
+
+       x2=self.config.getIconSizeFull()
+
+#      col=style.fg[gtk.STATE_ACTIVE]
+#      cr.set_source_color(col)
+#      #cr.set_source_rgba(0,1,1,0.5)
+#      cr.rectangle(1,1,x2+x2+2,x2+2)
+#      cr.stroke()
+#      cr.restore()
+
+       self.icon.draw(cr, 0, 0)
+       self.icon.draw(cr, x2, 0)
+       self.icon.draw(cr, 0, x2)
+       self.icon.draw(cr, x2, x2)
+
+    def setApp(self, app):
+       self.app=app
+       self.refresh()
+
+    def refresh(self):
+       if self.app!=None:
+           app=apps.readOne(self.app)
+           app['icon2']=getIcon(app['icon'], self.config.getIconSize())
+           self.icon.setApp(app)
+
+       self.queue_draw()
+
+gobject.type_register(IconWidget)
+
+# vim: set ts=8 sts=4 sw=4 noet formatoptions=r ai nocindent:
+
diff --git a/src/sig.py b/src/sig.py
new file mode 100644 (file)
index 0000000..f7cf115
--- /dev/null
@@ -0,0 +1,59 @@
+#!/usr/bin/env python
+# coding=UTF-8
+# 
+# Copyright (C) 2010 Stefanos Harhalakis
+#
+# This file is part of wifieye.
+#
+# wifieye is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# wifieye is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with wifieye.  If not, see <http://www.gnu.org/licenses/>.
+#
+# $Id: 0.py 2265 2010-02-21 19:16:26Z v13 $
+
+__version__ = "$Id: 0.py 2265 2010-02-21 19:16:26Z v13 $"
+
+import gtk
+
+class Disconnector(object):
+    def __init__(self):
+       self.chandles=[]
+       if isinstance(self, gtk.Widget):
+           self.c(self, 'delete-event', self.slotDiscDeleteEvent)
+
+    def c(self, obj, signal, slot, *args):
+       h=obj.connect(signal, slot, *args)
+       self.chandles.append((obj, h))
+
+       return(h)
+
+    def slotDiscDeleteEvent(self, sender, event):
+#      print "sig-delete-event"
+       self.dis_finish()
+       return(False)
+
+    def dis_finish(self, obj=None):
+       """ Disconnect all signals. If obj is specified the only disconnect
+       signals from that object """
+       for i in self.chandles:
+           if obj!=None and i[0]!=obj:
+               continue
+           #print i[0], i[1]
+           i[0].disconnect(i[1])
+       
+       if obj==None:
+           self.chandles=[]
+       else:
+           self.chandles=[a for a in self.chandles if a[0]!=obj]
+
+# vim: set ts=8 sts=4 sw=4 noet formatoptions=r ai nocindent:
+
index 56605d4..6fc1430 100755 (executable)
@@ -55,18 +55,20 @@ import config
 import apps
 from icon import Icon
 from icongrid import IconGrid
+from sig import Disconnector
 
 # Restore path
 sys.path=orig_path
 
 # IconGrid must be before HomePluginItem for its connect()
 # and do_button_*() to override those of HomePluginItem
-class DrlaunchPlugin(IconGrid, HomePluginItem, FremantleRotation):
+class DrlaunchPlugin(IconGrid, HomePluginItem, FremantleRotation, Disconnector):
     def __init__(self):
        IconGrid.__init__(self)
        HomePluginItem.__init__(self)
        FremantleRotation.__init__(self, 'DrlaunchPlugin',
            mode=FremantleRotation.AUTOMATIC, dontrotate=True)
+       Disconnector.__init__(self)
 
        self.winConfig=None
 
@@ -123,10 +125,10 @@ class DrlaunchPlugin(IconGrid, HomePluginItem, FremantleRotation):
        self.set_colormap(screen.get_rgba_colormap())
        self.set_app_paintable(True)
 
-       self.connect('show-settings', self.slot_show_settings)
-       self.connect('long-press', self.signalLongpress)
-       self.connect('click', self.signalClick)
-       self.connect('notify', self.signalNotify)
+       self.c(self, 'show-settings', self.slot_show_settings)
+       self.c(self, 'long-press', self.signalLongpress)
+       self.c(self, 'click', self.signalClick)
+       self.c(self, 'notify', self.signalNotify)
 
        HomePluginItem.do_realize(self)
 
@@ -153,27 +155,35 @@ class DrlaunchPlugin(IconGrid, HomePluginItem, FremantleRotation):
 
        s=WinConfig(self.get_config())
        s.show_all()
-       s.connect('destroy', self.slotConfigDestroy)
+       #s.c(s, 'delete-event', self.slotConfigDestroy)
+       self.c(s, 'delete-event', self.slotConfigDestroy)
+       #s.connect('destroy', self.slotConfigDestroy)
        self.winConfig=s
 
-    def slotConfigDestroy(self, sender):
-       self.winConfig=None
-
+    def slotConfigDestroy(self, sender, event):
+#      print "Sender:", sender
        dt=sender.getData()
 
-       config=self.get_config()
+       # Disconnect signals for that object in order to be deleted
+       self.dis_finish(self.winConfig)
+       #self.winConfig.finish()
+       #self.winConfig.destroy()
 
-       config.setSize(dt['size'])
-       config.setApps(dt['apps'])
-       config.setIndiv(dt['indiv'])
-       config.setLongpress(dt['longpress'])
-       config.setAnimate(dt['animate'])
-       config.setNoBg(dt['nobg'])
-       config.setThemeBg(dt['themebg'])
-       config.setIconSize(dt['iconsize'])
-       config.setIconPadding(dt['iconpadding'])
-       config.setIconMargin(dt['iconmargin'])
-       config.save()
+       self.winConfig=None
+
+       cfg=self.get_config()
+
+       cfg.setSize(dt['size'])
+       cfg.setApps(dt['apps'])
+       cfg.setIndiv(dt['indiv'])
+       cfg.setLongpress(dt['longpress'])
+       cfg.setAnimate(dt['animate'])
+       cfg.setNoBg(dt['nobg'])
+       cfg.setThemeBg(dt['themebg'])
+       cfg.setIconSize(dt['iconsize'])
+       cfg.setIconPadding(dt['iconpadding'])
+       cfg.setIconMargin(dt['iconmargin'])
+       cfg.save()
        
        # Resize widget
        self.setSize(dt['size'])
@@ -189,10 +199,14 @@ class DrlaunchPlugin(IconGrid, HomePluginItem, FremantleRotation):
 
        self.queue_draw()
 
+#      print "slot-config-destroy-end"
+
+       return(False)
+
     def handle_click(self, sender, icon):
        """ common handler for longpress and click """
-       if icon.name!=None and icon.name!='':
-           launcher.launch(icon.name)
+       if icon.appname!=None and icon.appname!='':
+           launcher.launch(icon.appname)
 
     def signalLongpress(self, sender, icon):
        self.handle_click(sender, icon)
index 472885e..4639e2b 100755 (executable)
@@ -35,9 +35,11 @@ from hildon import StackableWindow
 import config
 import apps
 from icon import Icon, getIcon
+from iconw import IconWidget
 from icongrid import IconGridWidget
 from about import DlgAbout
 from portrait import FremantleRotation
+from sig import Disconnector
 
 class DialogIconSize(gtk.Dialog):
     def __init__(self, config):
@@ -50,6 +52,14 @@ class DialogIconSize(gtk.Dialog):
 
        vbox=self.vbox
 
+       self.pa=hildon.PannableArea()
+       vbox.add(self.pa)
+       self.pa.set_property('mov-mode', hildon.MOVEMENT_MODE_VERT)
+
+       vbox=gtk.VBox()
+       self.pa.add_with_viewport(vbox)
+       self.pa.set_size_request(-1, 1000)
+
        self.labelDim=gtk.Label("koko")
        vbox.add(self.labelDim)
 
@@ -57,7 +67,7 @@ class DialogIconSize(gtk.Dialog):
        scale=gtk.HScale()
        scale.set_digits(0)
        scale.set_value_pos(gtk.POS_RIGHT)
-       scale.set_range(48,128)
+       scale.set_range(*self.config.getIconSizeRange())
        scale.set_increments(8, 16)
        self.scaleIconSize=scale
        vbox.add(scale)
@@ -70,7 +80,7 @@ class DialogIconSize(gtk.Dialog):
        scale=gtk.HScale()
        scale.set_digits(0)
        scale.set_value_pos(gtk.POS_RIGHT)
-       scale.set_range(2,16)
+       scale.set_range(*self.config.getIconPaddingRange())
        scale.set_increments(2,2)
        self.scaleIconPadding=scale
        vbox2.add(scale)
@@ -81,12 +91,16 @@ class DialogIconSize(gtk.Dialog):
        scale=gtk.HScale()
        scale.set_digits(0)
        scale.set_value_pos(gtk.POS_RIGHT)
-       scale.set_range(2,16)
+       scale.set_range(*self.config.getIconMarginRange())
        scale.set_increments(2,2)
        self.scaleIconMargin=scale
        vbox2.add(scale)
        hbox.add(vbox2)
 
+       self.icon=IconWidget(False, self.config)
+       self.icon.setApp('osso-addressbook')
+       vbox.add(self.icon)
+
        self.scaleIconSize.set_value(self.config.getIconSize())
        self.scaleIconPadding.set_value(self.config.getIconPadding())
        self.scaleIconMargin.set_value(self.config.getIconMargin())
@@ -138,6 +152,7 @@ class DialogIconSize(gtk.Dialog):
     def recalc(self):
        maxsz=self.config.getMaxSize()
        self.setWH(maxsz[0], maxsz[1])
+       self.icon.refresh()
 
     def getIconSize(self):
        return(self.scaleIconSize.get_value())
@@ -197,9 +212,10 @@ class DialogIconSize(gtk.Dialog):
        return(ret)
 
 
-class WinConfig(StackableWindow): #, FremantleRotation):
+class WinConfig(StackableWindow, Disconnector): #, FremantleRotation):
     def __init__(self, config, *args):
        StackableWindow.__init__(self)
+       Disconnector.__init__(self)
 #      FremantleRotation.__init__(self, "DrlaunchPlugin",
 #          mode=FremantleRotation.AUTOMATIC)
 
@@ -207,6 +223,13 @@ class WinConfig(StackableWindow): #, FremantleRotation):
 
        self.setupUi()
 
+#      h=self.c(self, 'delete-event', self.slotDeleteEvent)
+
+# This is a nice test. If it is displayed then the window is actually
+# destroyed and there is no memory leak
+#    def __del__(self):
+#      print "wc-del"
+
     def setupUi(self):
        """
        self.pa         Main Pannable Area
@@ -220,6 +243,8 @@ class WinConfig(StackableWindow): #, FremantleRotation):
 #      self.add(self.pa)
        self.pa.set_property('mov-mode', hildon.MOVEMENT_MODE_HORIZ)
 
+       self.add(self.pa)
+
 #1     hbox=gtk.HBox()
 #1     self.pa.add_with_viewport(hbox)
 
@@ -242,11 +267,10 @@ class WinConfig(StackableWindow): #, FremantleRotation):
        vbox.add(hbox2)
 
        self.butsSizeX=[]
-       self.butsSize=self.butsSizeX # For now
        for i in xrange(self.maxmaxsz[0]):
            but=hildon.GtkToggleButton(gtk.HILDON_SIZE_FINGER_HEIGHT)
            but.set_label("%s" % (i+1,))
-           but.connect('toggled', self.slotButtonSizeX, i)
+           self.c(but, 'toggled', self.slotButtonSizeX, i)
 
            self.butsSizeX.append(but)
 
@@ -262,7 +286,7 @@ class WinConfig(StackableWindow): #, FremantleRotation):
        for i in xrange(self.maxmaxsz[1]):
            but=hildon.GtkToggleButton(gtk.HILDON_SIZE_FINGER_HEIGHT)
            but.set_label("%s" % (i+1,))
-           but.connect('toggled', self.slotButtonSizeY, i)
+           self.c(but, 'toggled', self.slotButtonSizeY, i)
 
            self.butsSizeY.append(but)
 
@@ -280,7 +304,7 @@ class WinConfig(StackableWindow): #, FremantleRotation):
        but=hildon.CheckButton(
                gtk.HILDON_SIZE_AUTO_WIDTH | gtk.HILDON_SIZE_FINGER_HEIGHT)
        but.set_label("Rotate icons individually")
-       but.connect('toggled', self.slotButtonRotateIndividually)
+       self.c(but, 'toggled', self.slotButtonRotateIndividually)
        self.buttonRotateIndividually=but
        vbox.add(but)
 
@@ -308,14 +332,14 @@ class WinConfig(StackableWindow): #, FremantleRotation):
        but=hildon.CheckButton(
                gtk.HILDON_SIZE_AUTO_WIDTH | gtk.HILDON_SIZE_FINGER_HEIGHT)
        but.set_label("Theme background")
-       #but.connect('toggled', self.slotButtonNoBackground)
+       but.connect('toggled', self.slotButtonThemeBackground)
        self.buttonThemeBackground=but
        vbox.add(but)
 
        but=hildon.CheckButton(
                gtk.HILDON_SIZE_AUTO_WIDTH | gtk.HILDON_SIZE_FINGER_HEIGHT)
        but.set_label("No background")
-       but.connect('toggled', self.slotButtonNoBackground)
+       self.c(but, 'toggled', self.slotButtonNoBackground)
        self.buttonNoBackground=but
        vbox.add(but)
 
@@ -323,7 +347,7 @@ class WinConfig(StackableWindow): #, FremantleRotation):
                gtk.HILDON_SIZE_AUTO_WIDTH | gtk.HILDON_SIZE_FINGER_HEIGHT,
                hildon.BUTTON_ARRANGEMENT_VERTICAL)
        but.set_label("Adjust icon size")
-       but.connect('clicked', self.slotButtonIconSize)
+       self.c(but, 'clicked', self.slotButtonIconSize)
        self.buttonIconSize=but
        vbox.add(but)
 
@@ -332,7 +356,7 @@ class WinConfig(StackableWindow): #, FremantleRotation):
                gtk.HILDON_SIZE_AUTO_WIDTH | gtk.HILDON_SIZE_FINGER_HEIGHT,
                hildon.BUTTON_ARRANGEMENT_VERTICAL)
        but.set_title("About")
-       but.connect("clicked", self.slotButtonAbout)
+       self.c(but, "clicked", self.slotButtonAbout)
        vbox.add(but)
        self.buttonAbout=but
 
@@ -368,8 +392,6 @@ class WinConfig(StackableWindow): #, FremantleRotation):
        hbox.add(self.w_igw)
        self.pa.add_with_viewport(hbox)
 
-       self.add(self.pa)
-
        self.adjustMaxSize()
 
 #    def setupUi(self, orientation):
@@ -466,6 +488,10 @@ class WinConfig(StackableWindow): #, FremantleRotation):
        else:
            self.setLayoutLandscape()
 
+#    def slotDeleteEvent(self, sender, event):
+#      print "wc-del-event"
+#      return(False)
+
     def slotLongpress(self, sender, icon):
        self.doConfig(icon)
 
@@ -491,6 +517,10 @@ class WinConfig(StackableWindow): #, FremantleRotation):
        nobg=self.getNoBg()
        self.setNoBg(nobg)
 
+    def slotButtonThemeBackground(self, sender):
+       themebg=self.getThemeBg()
+       self.setThemeBg(themebg)
+
     def slotButtonAbout(self, sender):
        DlgAbout.present2(self)
 
@@ -512,17 +542,18 @@ class WinConfig(StackableWindow): #, FremantleRotation):
 
     def show_all(self):
        StackableWindow.show_all(self)
+#      return
        self.adjustMaxSize()
        self.queue_draw()
 
-    def slotScaleIconSzChange(self, sender):
-       return
-       self.config.setIconSize(self.getIconSize())
-       self.config.setIconMargin(self.getIconMargin())
-       self.config.setIconPadding(self.getIconPadding())
-       self.igw.reconfig()
-       self.adjustMaxSize()
-       self.queue_draw()
+#    def slotScaleIconSzChange(self, sender):
+#      return
+#      self.config.setIconSize(self.getIconSize())
+#      self.config.setIconMargin(self.getIconMargin())
+#      self.config.setIconPadding(self.getIconPadding())
+#      self.igw.reconfig()
+#      self.adjustMaxSize()
+#      self.queue_draw()
 
 #    def slotButtonLongpress(self, sender):
 #      but=self.buttonRequireLongpress
@@ -601,16 +632,23 @@ class WinConfig(StackableWindow): #, FremantleRotation):
 
     def getNoBg(self):
        ret=self.buttonNoBackground.get_active()
-
        return(ret)
 
     def setNoBg(self, nobg):
        self.buttonNoBackground.set_active(nobg)
 
        self.buttonThemeBackground.set_sensitive(not nobg)
+       self.config.setNoBg(nobg)
+       self.igw.reconfig()
+
+    def getThemeBg(self):
+       ret=self.buttonThemeBackground.get_active()
+       return(ret)
 
     def setThemeBg(self, themebg):
        self.buttonThemeBackground.set_active(themebg)
+       self.config.setThemeBg(themebg)
+       self.igw.reconfig()
 
     def doConfig(self, icon):
        aps=apps.scan()
@@ -638,7 +676,7 @@ class WinConfig(StackableWindow): #, FremantleRotation):
            if app==None:
                continue
            selector.append_text(app)
-           if icon.name!=None and aps[icon.name]['name']==app:
+           if icon.appname!=None and aps[icon.appname]['name']==app:
                idx=cnt
            cnt+=1
 
@@ -671,6 +709,12 @@ class WinConfig(StackableWindow): #, FremantleRotation):
 
        dialog.destroy()
 
+#    def finish(self):
+#      print "wc-finish"
+#      self.igw=None
+#
+#      self.dis_finish()
+
     def getData(self):
        szx=0
        szy=0
@@ -695,7 +739,7 @@ class WinConfig(StackableWindow): #, FremantleRotation):
            for y in xrange(sz[1]):
                ico=self.igw.get(x,y)
                k=(x,y)
-               wapps[k]=ico.name
+               wapps[k]=ico.appname
 
        indiv=self.buttonRotateIndividually.get_active()
        lp=self.buttonRequireLongpress.get_active()