1# Terminator by Chris Jones <cmsj@tenshu.net>
2# GPL v2 only
3"""Simple management of Gtk Widget signal handlers"""
4
5from .util import dbg, err
6
7class Signalman(object):
8    """Class providing glib signal tracking and management"""
9
10    cnxids = None
11
12    def __init__(self):
13        """Class initialiser"""
14        self.cnxids = {}
15
16    def __del__(self):
17        """Class destructor. This is only used to check for stray signals"""
18        if len(list(self.cnxids.keys())) > 0:
19            dbg('Remaining signals: %s' % self.cnxids)
20
21    def new(self, widget, signal, handler, *args):
22        """Register a new signal on a widget"""
23        if widget not in self.cnxids:
24            dbg('creating new bucket for %s' % type(widget))
25            self.cnxids[widget] = {}
26
27        if signal in self.cnxids[widget]:
28            err('%s already has a handler for %s' % (id(widget), signal))
29
30        self.cnxids[widget][signal] = widget.connect(signal, handler, *args)
31        dbg('connected %s::%s to %s' % (type(widget), signal, handler))
32        return(self.cnxids[widget][signal])
33
34    def remove_signal(self, widget, signal):
35        """Remove a signal handler"""
36        if widget not in self.cnxids:
37            dbg('%s is not registered' % widget)
38            return
39        if signal not in self.cnxids[widget]:
40            dbg('%s not registered for %s' % (signal, type(widget)))
41            return
42        dbg('removing %s::%s' % (type(widget), signal))
43        widget.disconnect(self.cnxids[widget][signal])
44        del(self.cnxids[widget][signal])
45        if len(list(self.cnxids[widget].keys())) == 0:
46            dbg('no more signals for widget')
47            del(self.cnxids[widget])
48
49    def remove_widget(self, widget):
50        """Remove all signal handlers for a widget"""
51        if widget not in self.cnxids:
52            dbg('%s not registered' % widget)
53            return
54        signals = list(self.cnxids[widget].keys())
55        for signal in signals:
56            self.remove_signal(widget, signal)
57
58    def remove_all(self):
59        """Remove all signal handlers for all widgets"""
60        widgets = list(self.cnxids.keys())
61        for widget in widgets:
62            self.remove_widget(widget)
63
64