# Copyright (C) 2009, Tutorius.org # Copyright (C) 2009, Vincent Vinet # # This program 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 2 of the License, or # (at your option) any later version. # # This program 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 this program; if not, write to the Free Software # Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA """ Utility classes and functions that are gtk related """ import gtk def activity(activity=None, singleton=[]): if activity: singleton.append(activity) return singleton[0] def find_widget(base, target_fqdn): """Find a widget by digging into a parent widget's children tree @param base the parent widget @param target_fqdn fqdn-style target object name @return widget found The object should normally be the activity widget, as it is the root widget for activities. The target_fqdn is a dot separated list of indexes used in widget.get_children and should start with a 0 which is the base widget itself, Example Usage: find_widget(activity,"0.0.0.1.0.0.2") """ path = target_fqdn.split(".") #We select the first object and pop the first zero obj = base path.pop(0) while len(path) > 0: try: obj = obj.get_children()[int(path.pop(0))] except: break return obj EVENTS = [ "focus", "button-press-event", "enter-notify-event", "leave-notify-event", "key-press-event", "text-selected", "clicked", ] IGNORED_WIDGETS = [ "GtkVBox", "GtkHBox", "GtkAlignment", "GtkNotebook", "GtkButton", "GtkToolItem", "GtkToolbar", ] def register_signals_numbered(target, handler, prefix="0", max_depth=None): """ Recursive function to register event handlers on an target and it's children. The event handler is called with an extra argument which is a two-tuple containing the signal name and the FQDN-style name of the target that triggered the event. This function registers all of the events listed in EVENTS Example arg tuple added: ("focus", "1.1.2") Side effects: -Handlers connected on the various targets @param target the target to recurse on @param handler the handler function to connect @param prefix name prepended to the target name to form a chain @param max_depth maximum recursion depth, None for infinity @returns list of (object, handler_id) """ ret = [] #Gtk Containers have a get_children() function if hasattr(target, "get_children") and \ hasattr(target.get_children, "__call__"): children = target.get_children() for i in range(len(children)): child = children[i] if max_depth is None or max_depth > 0: #Recurse with a prefix on all children pre = ".".join( \ [p for p in (prefix, str(i)) if not p is None] ) if max_depth is None: dep = None else: dep = max_depth - 1 ret+=register_signals_numbered(child, handler, pre, dep) #register events on the target if a widget XXX necessary to check this? if isinstance(target, gtk.Widget): for sig in EVENTS: try: ret.append( \ (target, target.connect(sig, handler, (sig, prefix) ))\ ) except TypeError: pass return ret def register_signals(target, handler, prefix=None, max_depth=None): """ Recursive function to register event handlers on an target and it's children. The event handler is called with an extra argument which is a two-tuple containing the signal name and the FQDN-style name of the target that triggered the event. This function registers all of the events listed in EVENTS and omits widgets with a name matching IGNORED_WIDGETS from the name hierarchy. Example arg tuple added: ("focus", "Activity.Toolbox.Bold") Side effects: -Handlers connected on the various targets @param target the target to recurse on @param handler the handler function to connect @param prefix name prepended to the target name to form a chain @param max_depth maximum recursion depth, None for infinity @returns list of (object, handler_id) """ ret = [] #Gtk Containers have a get_children() function if hasattr(target, "get_children") and \ hasattr(target.get_children, "__call__"): for child in target.get_children(): if max_depth is None or max_depth > 0: #Recurse with a prefix on all children pre = ".".join( \ [p for p in (prefix, target.get_name()) \ if not (p is None or p in IGNORED_WIDGETS)] \ ) if max_depth is None: dep = None else: dep = max_depth - 1 ret += register_signals(child, handler, pre, dep) name = ".".join( \ [p for p in (prefix, target.get_name()) \ if not (p is None or p in IGNORED_WIDGETS)] \ ) #register events on the target if a widget XXX necessary to check this? if isinstance(target, gtk.Widget): for sig in EVENTS: try: ret.append( \ (target, target.connect(sig, handler, (sig, name) )) \ ) except TypeError: pass return ret