• Home
  • History
  • Annotate
  • Line#
  • Navigate
  • Raw
  • Download
  • only in /netgear-WNDR4500v2-V1.0.0.60_1.0.38/ap/gpl/timemachine/avahi-0.6.25/avahi-python/avahi-discover/
1"""
2 SimpleGladeApp.py
3 Module that provides an object oriented abstraction to pygtk and libglade.
4 Copyright (C) 2004 Sandino Flores Moreno
5"""
6
7# This library is free software; you can redistribute it and/or
8# modify it under the terms of the GNU Lesser General Public
9# License as published by the Free Software Foundation; either
10# version 2.1 of the License, or (at your option) any later version.
11#
12# This library is distributed in the hope that it will be useful,
13# but WITHOUT ANY WARRANTY; without even the implied warranty of
14# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
15# Lesser General Public License for more details.
16#
17# You should have received a copy of the GNU Lesser General Public
18# License along with this library; if not, write to the Free Software
19# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
20# USA
21
22import os
23import sys
24import re
25
26import tokenize
27import gtk
28import gtk.glade
29import weakref
30import inspect
31
32__version__ = "1.0"
33__author__ = 'Sandino "tigrux" Flores-Moreno'
34
35def bindtextdomain(app_name, locale_dir=None):
36    """
37    Bind the domain represented by app_name to the locale directory locale_dir.
38    It has the effect of loading translations, enabling applications for different
39    languages.
40
41    app_name:
42        a domain to look for translations, tipically the name of an application.
43
44    locale_dir:
45        a directory with locales like locale_dir/lang_isocode/LC_MESSAGES/app_name.mo
46        If omitted or None, then the current binding for app_name is used.
47    """
48    try:
49        import locale
50        import gettext
51        locale.setlocale(locale.LC_ALL, "")
52        gtk.glade.bindtextdomain(app_name, locale_dir)
53        gettext.install(app_name, locale_dir, unicode=1)
54    except (IOError,locale.Error), e:
55        print "Warning", app_name, e
56        __builtins__.__dict__["_"] = lambda x : x
57
58
59class SimpleGladeApp:
60
61    def __init__(self, path, root=None, domain=None, **kwargs):
62        """
63        Load a glade file specified by glade_filename, using root as
64        root widget and domain as the domain for translations.
65
66        If it receives extra named arguments (argname=value), then they are used
67        as attributes of the instance.
68
69        path:
70            path to a glade filename.
71            If glade_filename cannot be found, then it will be searched in the
72            same directory of the program (sys.argv[0])
73
74        root:
75            the name of the widget that is the root of the user interface,
76            usually a window or dialog (a top level widget).
77            If None or ommited, the full user interface is loaded.
78
79        domain:
80            A domain to use for loading translations.
81            If None or ommited, no translation is loaded.
82
83        **kwargs:
84            a dictionary representing the named extra arguments.
85            It is useful to set attributes of new instances, for example:
86                glade_app = SimpleGladeApp("ui.glade", foo="some value", bar="another value")
87            sets two attributes (foo and bar) to glade_app.
88        """
89        if os.path.isfile(path):
90            self.glade_path = path
91        else:
92            glade_dir = os.path.dirname( sys.argv[0] )
93            self.glade_path = os.path.join(glade_dir, path)
94        for key, value in kwargs.items():
95            try:
96                setattr(self, key, weakref.proxy(value) )
97            except TypeError:
98                setattr(self, key, value)
99        self.glade = None
100        self.install_custom_handler(self.custom_handler)
101        self.glade = self.create_glade(self.glade_path, root, domain)
102        if root:
103            self.main_widget = self.get_widget(root)
104        else:
105            self.main_widget = None
106        self.normalize_names()
107        self.add_callbacks(self)
108        self.new()
109
110    def __repr__(self):
111        class_name = self.__class__.__name__
112        if self.main_widget:
113            root = gtk.Widget.get_name(self.main_widget)
114            repr = '%s(path="%s", root="%s")' % (class_name, self.glade_path, root)
115        else:
116            repr = '%s(path="%s")' % (class_name, self.glade_path)
117        return repr
118
119    def new(self):
120        """
121        Method called when the user interface is loaded and ready to be used.
122        At this moment, the widgets are loaded and can be refered as self.widget_name
123        """
124        pass
125
126    def add_callbacks(self, callbacks_proxy):
127        """
128        It uses the methods of callbacks_proxy as callbacks.
129        The callbacks are specified by using:
130            Properties window -> Signals tab
131            in glade-2 (or any other gui designer like gazpacho).
132
133        Methods of classes inheriting from SimpleGladeApp are used as
134        callbacks automatically.
135
136        callbacks_proxy:
137            an instance with methods as code of callbacks.
138            It means it has methods like on_button1_clicked, on_entry1_activate, etc.
139        """
140        self.glade.signal_autoconnect(callbacks_proxy)
141
142    def normalize_names(self):
143        """
144        It is internally used to normalize the name of the widgets.
145        It means a widget named foo:vbox-dialog in glade
146        is refered self.vbox_dialog in the code.
147
148        It also sets a data "prefixes" with the list of
149        prefixes a widget has for each widget.
150        """
151        for widget in self.get_widgets():
152            widget_name = gtk.Widget.get_name(widget)
153            prefixes_name_l = widget_name.split(":")
154            prefixes = prefixes_name_l[ : -1]
155            widget_api_name = prefixes_name_l[-1]
156            widget_api_name = "_".join( re.findall(tokenize.Name, widget_api_name) )
157            gtk.Widget.set_name(widget, widget_api_name)
158            if hasattr(self, widget_api_name):
159                raise AttributeError("instance %s already has an attribute %s" % (self,widget_api_name))
160            else:
161                setattr(self, widget_api_name, widget)
162                if prefixes:
163                    gtk.Widget.set_data(widget, "prefixes", prefixes)
164
165    def add_prefix_actions(self, prefix_actions_proxy):
166        """
167        By using a gui designer (glade-2, gazpacho, etc)
168        widgets can have a prefix in theirs names
169        like foo:entry1 or foo:label3
170        It means entry1 and label3 has a prefix action named foo.
171
172        Then, prefix_actions_proxy must have a method named prefix_foo which
173        is called everytime a widget with prefix foo is found, using the found widget
174        as argument.
175
176        prefix_actions_proxy:
177            An instance with methods as prefix actions.
178            It means it has methods like prefix_foo, prefix_bar, etc.
179        """
180        prefix_s = "prefix_"
181        prefix_pos = len(prefix_s)
182
183        is_method = lambda t : callable( t[1] )
184        is_prefix_action = lambda t : t[0].startswith(prefix_s)
185        drop_prefix = lambda (k,w): (k[prefix_pos:],w)
186
187        members_t = inspect.getmembers(prefix_actions_proxy)
188        methods_t = filter(is_method, members_t)
189        prefix_actions_t = filter(is_prefix_action, methods_t)
190        prefix_actions_d = dict( map(drop_prefix, prefix_actions_t) )
191
192        for widget in self.get_widgets():
193            prefixes = gtk.Widget.get_data(widget, "prefixes")
194            if prefixes:
195                for prefix in prefixes:
196                    if prefix in prefix_actions_d:
197                        prefix_action = prefix_actions_d[prefix]
198                        prefix_action(widget)
199
200    def custom_handler(self,
201            glade, function_name, widget_name,
202            str1, str2, int1, int2):
203        """
204        Generic handler for creating custom widgets, internally used to
205        enable custom widgets (custom widgets of glade).
206
207        The custom widgets have a creation function specified in design time.
208        Those creation functions are always called with str1,str2,int1,int2 as
209        arguments, that are values specified in design time.
210
211        Methods of classes inheriting from SimpleGladeApp are used as
212        creation functions automatically.
213
214        If a custom widget has create_foo as creation function, then the
215        method named create_foo is called with str1,str2,int1,int2 as arguments.
216        """
217        try:
218            handler = getattr(self, function_name)
219            return handler(str1, str2, int1, int2)
220        except AttributeError:
221            return None
222
223    def gtk_widget_show(self, widget, *args):
224        """
225        Predefined callback.
226        The widget is showed.
227        Equivalent to widget.show()
228        """
229        widget.show()
230
231    def gtk_widget_hide(self, widget, *args):
232        """
233        Predefined callback.
234        The widget is hidden.
235        Equivalent to widget.hide()
236        """
237        widget.hide()
238
239    def gtk_widget_grab_focus(self, widget, *args):
240        """
241        Predefined callback.
242        The widget grabs the focus.
243        Equivalent to widget.grab_focus()
244        """
245        widget.grab_focus()
246
247    def gtk_widget_destroy(self, widget, *args):
248        """
249        Predefined callback.
250        The widget is destroyed.
251        Equivalent to widget.destroy()
252        """
253        widget.destroy()
254
255    def gtk_window_activate_default(self, window, *args):
256        """
257        Predefined callback.
258        The default widget of the window is activated.
259        Equivalent to window.activate_default()
260        """
261        widget.activate_default()
262
263    def gtk_true(self, *args):
264        """
265        Predefined callback.
266        Equivalent to return True in a callback.
267        Useful for stopping propagation of signals.
268        """
269        return True
270
271    def gtk_false(self, *args):
272        """
273        Predefined callback.
274        Equivalent to return False in a callback.
275        """
276        return False
277
278    def gtk_main_quit(self, *args):
279        """
280        Predefined callback.
281        Equivalent to self.quit()
282        """
283        self.quit()
284
285    def main(self):
286        """
287        Starts the main loop of processing events.
288        The default implementation calls gtk.main()
289
290        Useful for applications that needs a non gtk main loop.
291        For example, applications based on gstreamer needs to override
292        this method with gst.main()
293
294        Do not directly call this method in your programs.
295        Use the method run() instead.
296        """
297        gtk.main()
298
299    def quit(self):
300        """
301        Quit processing events.
302        The default implementation calls gtk.main_quit()
303
304        Useful for applications that needs a non gtk main loop.
305        For example, applications based on gstreamer needs to override
306        this method with gst.main_quit()
307        """
308        gtk.main_quit()
309
310    def run(self):
311        """
312        Starts the main loop of processing events checking for Control-C.
313
314        The default implementation checks wheter a Control-C is pressed,
315        then calls on_keyboard_interrupt().
316
317        Use this method for starting programs.
318        """
319        try:
320            self.main()
321        except KeyboardInterrupt:
322            self.on_keyboard_interrupt()
323
324    def on_keyboard_interrupt(self):
325        """
326        This method is called by the default implementation of run()
327        after a program is finished by pressing Control-C.
328        """
329        pass
330
331    def install_custom_handler(self, custom_handler):
332        gtk.glade.set_custom_handler(custom_handler)
333
334    def create_glade(self, glade_path, root, domain):
335        return gtk.glade.XML(self.glade_path, root, domain)
336
337    def get_widget(self, widget_name):
338        return self.glade.get_widget(widget_name)
339
340    def get_widgets(self):
341        return self.glade.get_widget_prefix("")
342