~vorlon/ubuntu/saucy/gourmet/trunk

« back to all changes in this revision

Viewing changes to src/lib/gtk_extras/FauxActionGroups.py

  • Committer: Bazaar Package Importer
  • Author(s): Rolf Leggewie
  • Date: 2008-07-26 13:29:41 UTC
  • Revision ID: james.westby@ubuntu.com-20080726132941-6ldd73qmacrzz0bn
Tags: upstream-0.14.0
ImportĀ upstreamĀ versionĀ 0.14.0

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
#!/usr/bin/env python
 
2
import gtk.glade, gtk
 
3
from gourmet.gdebug import *
 
4
from gettext import gettext as _
 
5
from gettext import ngettext
 
6
 
 
7
# Here we have some classes that implement ActionGroups. This is
 
8
# somewhat ugly, but we're designing our interface in glade (which
 
9
# doesn't understand ActionGroups) and we still want to use this
 
10
# feature -- which lets us automatically associate multiple widgets
 
11
# with an action and have things like toggles just work.
 
12
 
 
13
class ActionTwoPointFourCompatability:
 
14
    """Provide functions that pygtk 2.4 fails to provide for the
 
15
    ActionGroup class.
 
16
 
 
17
    This class should be inherited from AFTER gtk.Action so that if
 
18
    the proper functions are available (i.e. > pygtk 2.6, we won't use
 
19
    these at all.
 
20
    """
 
21
    def set_visible (self, value):
 
22
        for w in self.get_proxies():
 
23
            if hasattr(w,'set_visible'): w.set_visible(value)
 
24
 
 
25
    def get_visible (self):
 
26
        for w in self.get_proxies():
 
27
            if hasattr(w,'get_visible'): return w.get_visible()
 
28
 
 
29
    def set_sensitive (self, value):
 
30
        for w in self.get_proxies():
 
31
            if hasattr(w,'set_sensitive'): w.set_sensitive(value)
 
32
 
 
33
    def get_sensitive (self):
 
34
        for w in self.get_proxies():
 
35
            if hasattr(w,'get_sensitive'): return w.get_sensitive()
 
36
 
 
37
 
 
38
class ToggleActionWithSeparators (gtk.ToggleAction,ActionTwoPointFourCompatability):
 
39
    """Create a ToggleAction which can include some separators.
 
40
 
 
41
    This allows us to make separators become visible/invisible in sync
 
42
    with controls for an action.
 
43
    
 
44
    This is much worse than the default UIManager way of handling
 
45
    separators automatically, but it works with glade as it is made at
 
46
    the moment.
 
47
    """
 
48
    def __init__ (self, *args, **kwargs):
 
49
        self.separators = []
 
50
        gtk.ToggleAction.__init__(self,*args,**kwargs)
 
51
 
 
52
    def add_separator (self, separator_widget):
 
53
        self.separators.append(separator_widget)
 
54
 
 
55
    def set_visible (self, *args, **kwargs):
 
56
        gtk.ToggleAction.set_visible(self,*args,**kwargs)
 
57
        if self.is_visible():
 
58
            for s in self.separators: s.set_visible(True)
 
59
        else:
 
60
            for s in self.separators: s.set_visible(False)
 
61
            
 
62
class ActionWithSeparators (gtk.Action,ActionTwoPointFourCompatability):
 
63
    """Create an Action which can include some separators.
 
64
 
 
65
    This allows us to make separators become visible/invisible in sync
 
66
    with controls for an action.
 
67
 
 
68
    This is much worse than the default UIManager way of handling
 
69
    separators automatically, but it works with glade as it is made at
 
70
    the moment.
 
71
    """
 
72
    def __init__ (self, *args, **kwargs):
 
73
        self.separators = []
 
74
        gtk.Action.__init__(self,*args,**kwargs)
 
75
 
 
76
    def add_separator (self, separator_widget):
 
77
        self.separators.append(separator_widget)
 
78
 
 
79
    def set_visible (self, *args, **kwargs):
 
80
        gtk.Action.set_visible(self,*args,**kwargs)
 
81
        if self.is_visible():
 
82
            for s in self.separators: s.set_visible(True)
 
83
        else:
 
84
            for s in self.separators: s.set_visible(False)
 
85
 
 
86
class ActionGroupWithSeparators (gtk.ActionGroup,ActionTwoPointFourCompatability):
 
87
    """Create an ActionGroup which can include some separators.
 
88
 
 
89
    This allows us to make separators become visible/invisible in sync
 
90
    with controls for an action.
 
91
 
 
92
    This is much worse than the default UIManager way of handling
 
93
    separators automatically, but it works with glade as it is made at
 
94
    the moment.
 
95
    """
 
96
    def __init__ (self, *args, **kwargs):
 
97
        self.separators = []
 
98
        gtk.ActionGroup.__init__(self,*args,**kwargs)
 
99
 
 
100
    def add_separator (self, separator_widget):
 
101
        self.separators.append(separator_widget)
 
102
 
 
103
    def set_visible (self, visible):
 
104
        gtk.ActionGroup.set_visible(self,visible)
 
105
        for s in self.separators:
 
106
            try:
 
107
                s.set_property('visible',visible)
 
108
            except:
 
109
                debug('no widget %s'%s,5)
 
110
 
 
111
class ActionManager:
 
112
    """This is a class to handle all Actions for a GUI
 
113
 
 
114
    This can be conveniently subclassed by any class handling the main
 
115
    GUI interactions.
 
116
 
 
117
    This class is made to be the glue between traditional glade and
 
118
    ActionManager kung-fu.
 
119
    """
 
120
    
 
121
    def __init__ (self, gladeobj, groups, callbacks):
 
122
        """Set up our ActionManager.
 
123
 
 
124
        gladeobj - Our route to glade stuff (created by
 
125
                   gtk.glade.XML('/path/to/glade')
 
126
 
 
127
        groups - a dictionary of group names and actions within them
 
128
                 actions are rather complicated...
 
129
 
 
130
                 actions are also dictionaries.
 
131
                 {'actionName' : [{'tooltip':...,'label':...,...},
 
132
                                  ['widgetName','widgetName','widgetName'...]
 
133
                                  ]},
 
134
 
 
135
                 If parameters 'label', 'stock-id' are not provided,
 
136
                 we will attempt to grab them from the first widget using methods
 
137
                 get_label() and  get_stock_id(). If we are unable, we will throw
 
138
                 an error, because you really do need a label. The solution is to
 
139
                 provide the label, or make the first widget in your list one that
 
140
                 supports these methods.
 
141
                 
 
142
        callbacks - an alist of action names and callbacks to be
 
143
                    called when the action is activated.
 
144
        """
 
145
        self.gladeobj = gladeobj
 
146
        self.groups = groups
 
147
        self.callbacks = callbacks
 
148
        self.action_groups = [self.init_group(gname, actions) for gname,actions in self.groups.items()]
 
149
        self.make_connections()
 
150
 
 
151
    def init_group (self, name, actions):
 
152
        setattr(self,name,ActionGroupWithSeparators(name))
 
153
        for a in actions:
 
154
            for n,ainfo in a.items():
 
155
                params,widgets = ainfo
 
156
                widg=None
 
157
                if not params.has_key('label'):
 
158
                    if not widg: widg = self.gladeobj.get_widget(widgets[0])
 
159
                    if not widg: raise "Can't find widget %s"%widgets[0]
 
160
                    label = widg.get_label()
 
161
                    params['label']=label
 
162
                if not params.has_key('stock-id'):
 
163
                    if not widg: widg = self.gladeobj.get_widget(widgets[0])
 
164
                    if not widg: raise "Can't find widget %s"%widgets[0]
 
165
                    stockid = widg.get_stock_id()
 
166
                    params['stock-id']=stockid
 
167
                if not params.has_key('tooltip'):
 
168
                    params['tooltip']=''
 
169
                widg = self.gladeobj.get_widget(widgets[0])
 
170
                try:
 
171
                    temp_connection=widg.connect('toggled',lambda *args: False)
 
172
                    widg.disconnect(temp_connection)                    
 
173
                except TypeError: #unknown signal name (i.e. not a toggle)
 
174
                    act = ActionWithSeparators(n,params['label'],params['tooltip'],params['stock-id'])
 
175
                else:
 
176
                    act = ToggleActionWithSeparators(n,params['label'],params['tooltip'],params['stock-id'])
 
177
                if params.has_key('separators'):
 
178
                    if type(params['separators']==str): params['separators']=[params['separators']]
 
179
                    act.separators=[self.gladeobj.get_widget(w) for w in params['separators']]
 
180
                    getattr(self,name).separators.extend(act.separators)
 
181
                for w in widgets:
 
182
                    ww = self.gladeobj.get_widget(w)
 
183
                    if ww:
 
184
                        act.connect_proxy(ww)
 
185
                    else:
 
186
                        debug('Widget %s does not exist!'%w,0)
 
187
                # create action as an attribute
 
188
                setattr(self,n,act)
 
189
                # attach to our ActionGroup                
 
190
                getattr(self,name).add_action(act)
 
191
        return getattr(self,name)
 
192
 
 
193
    def make_connections (self):
 
194
        for a,cb in self.callbacks:
 
195
            debug('connecting %s activate to %s'%(a,cb),5)
 
196
            getattr(self,a).connect('activate',cb)
 
197
 
 
198
 
 
199