thomasvs - in flumotion/trunk: . flumotion/ui
flumotion-commit at lists.fluendo.com
flumotion-commit at lists.fluendo.com
Mon Feb 26 22:45:09 CET 2007
Author: thomasvs
Date: Mon Feb 26 22:45:01 2007
New Revision: 4527
Modified:
flumotion/trunk/ChangeLog
flumotion/trunk/flumotion/ui/glade.py
Log:
* flumotion/ui/glade.py:
Some easy refactoring. Create a common GladeBacked class to
avoid repeating and diverging code. Remove an experimental
generator method that I can't find any callers of.
Document and comment.
Modified: flumotion/trunk/ChangeLog
==============================================================================
--- flumotion/trunk/ChangeLog (original)
+++ flumotion/trunk/ChangeLog Mon Feb 26 22:45:01 2007
@@ -1,3 +1,11 @@
+2007-02-26 Thomas Vander Stichele <thomas at apestaart dot org>
+
+ * flumotion/ui/glade.py:
+ Some easy refactoring. Create a common GladeBacked class to
+ avoid repeating and diverging code. Remove an experimental
+ generator method that I can't find any callers of.
+ Document and comment.
+
2007-02-23 Thomas Vander Stichele <thomas at apestaart dot org>
* data/Makefile.am:
Modified: flumotion/trunk/flumotion/ui/glade.py
==============================================================================
--- flumotion/trunk/flumotion/ui/glade.py (original)
+++ flumotion/trunk/flumotion/ui/glade.py Mon Feb 26 22:45:01 2007
@@ -31,6 +31,7 @@
from flumotion.common import log, pygobject
+# FIXME: what does this mean ?
# proc := module1.module2.moduleN.proc1().maybe_another_proc()
# -> eval proc1().maybe_another_proc() in module1.module2.moduleN
def flumotion_glade_custom_handler(xml, proc, name, *args):
@@ -64,30 +65,37 @@
w.set_name(name)
w.show()
return w
+# FIXME: what does this do ?
gtk.glade.set_custom_handler(flumotion_glade_custom_handler)
-class GladeWidget(gtk.VBox):
- '''
- Base class for composite widgets backed by glade interface definitions.
-
- Example:
- class MyWidget(GladeWidget):
- glade_file = 'my_glade_file.glade'
- ...
- gobject.type_register(MyWidget)
+class GladeBacked:
+ """
+ Base class for objects backed by glade interface definitions.
+ The glade file should have exactly one Window.
- Remember to chain up if you customize __init__().
- '''
-
+ @ivar glade_dir: directory where the glade file is stored
+ @type glade_dir: str
+ @ivar glade_file: filename of glade file containing the interface
+ @type glade_file: str
+ @ivar glade_typedict: GTK widget class name -> replacement widget class
+ see L{flumotion.ui.fgtk.WidgetMapping}
+ @type glade_typedict: dict of str -> class
+ @ivar widgets: widget name -> Widget
+ @type widgets: str -> gtk.Widget
+ """
glade_dir = configure.gladedir
glade_file = None
glade_typedict = None
+ widgets = None
+
+ _window = None # the gtk.Window of the glade file
def __init__(self):
- gtk.VBox.__init__(self)
+ self.widgets = {}
try:
- assert self.glade_file
+ assert self.glade_file, "%s.glade_file should be set" % \
+ self.__class__
file = os.path.join(self.glade_dir, self.glade_file)
if self.glade_typedict:
wtree = gtk.glade.XML(file, typedict=self.glade_typedict)
@@ -99,30 +107,61 @@
raise RuntimeError('Failed to load file %s from directory %s: %s'
% (self.glade_file, self.glade_dir, msg))
- win = None
for widget in wtree.get_widget_prefix(''):
wname = widget.get_name()
if isinstance(widget, gtk.Window):
- assert win == None
- win = widget
+ assert self._window == None, \
+ "glade file %s has more than one Window" % self.glade_file
+ self._window = widget
continue
+
+ assert not self.widgets.has_key(wname), \
+ "There is already a widget called %s" % wname
+
+ self.widgets[wname] = widget
- if hasattr(self, wname) and getattr(self, wname):
- raise AssertionError(
- "There is already an attribute called %s in %r" %
- (wname, self))
- setattr(self, wname, widget)
-
- assert win != None
- w = win.get_child()
- win.remove(w)
- self.add(w)
- win.destroy()
+ assert self._window != None, \
+ "glade file %s has no Window" % self.glade_file
+
+ # connect all signals
wtree.signal_autoconnect(self)
-pygobject.type_register(GladeWidget)
+class GladeWidget(gtk.VBox, GladeBacked):
+ '''
+ Base class for composite widgets backed by glade interface definitions.
+
+ The Window contents will be reparented to ourselves.
+ All widgets inside the Window will be available as attributes on the
+ object (dashes will be replaced with underscores).
+
+ Example:
+ class MyWidget(GladeWidget):
+ glade_file = 'my_glade_file.glade'
+ ...
+ gobject.type_register(MyWidget)
+
+ Remember to chain up if you customize __init__().
+
+ '''
+ def __init__(self):
+ GladeBacked.__init__(self)
+ gtk.VBox.__init__(self)
+
+ for name, widget in self.widgets.items():
+ # translate - to _ so we can access them as attributes
+ if name.find('-') > -1:
+ name = "_".join(name.split('-'))
+ setattr(self, name, widget)
+
+ # we reparent the contents of the window to ourselves
+ w = self._window.get_child()
+ self._window.remove(w)
+ self.add(w)
+ self._window.destroy()
+ self._window = None
+pygobject.type_register(GladeWidget)
-class GladeWindow(gobject.GObject):
+class GladeWindow(gobject.GObject, GladeBacked):
"""
Base class for dialogs or windows backed by glade interface definitions.
@@ -135,47 +174,23 @@
does *not* descend from GtkWindow, so you can't treat the resulting object
as a GtkWindow. The show, hide, destroy, and present methods are provided as
convenience wrappers.
- """
- glade_dir = configure.gladedir
- glade_file = None
- glade_typedict = None
+ @ivar window: the gtk Window
+ @type window: gtk.Window
+ """
interesting_signals = ()
-
window = None
def __init__(self, parent=None):
gobject.GObject.__init__(self)
- try:
- assert self.glade_file
- file = os.path.join(self.glade_dir, self.glade_file)
- if self.glade_typedict:
- wtree = gtk.glade.XML(file, typedict=self.glade_typedict)
- else:
- # pygtk 2.4 doesn't like typedict={} ?
- wtree = gtk.glade.XML(file)
- except RuntimeError, e:
- msg = log.getExceptionMessage(e)
- raise RuntimeError('Failed to load file %s from directory %s: %s'
- % (self.glade_file, self.glade_dir, msg))
+ GladeBacked.__init__(self)
- self.widgets = {}
- for widget in wtree.get_widget_prefix(''):
- wname = widget.get_name()
- if isinstance(widget, gtk.Window):
- assert self.window == None
- self.window = widget
-
- if wname in self.widgets:
- raise AssertionError("Two objects with same name (%s): %r %r"
- % (wname, self.widgets[wname], widget))
- self.widgets[wname] = widget
+ # make public
+ self.window = self._window
if parent:
self.window.set_transient_for(parent)
- wtree.signal_autoconnect(self)
-
self.__signals = {}
for name, widget in self.widgets.iteritems():
for prefix, signal in self.interesting_signals:
@@ -183,12 +198,18 @@
hid = self.connect_signal(name, signal)
self.__signals[(name, signal)] = hid
+ # have convenience methods acting on our window
self.show = self.window.show
self.hide = self.window.hide
self.present = self.window.present
+ def destroy(self):
+ self.window.destroy()
+ del self.window
+
def connect_signal(self, widget_name, signal):
- """Connect a conventionally-named signal handler.
+ """
+ Connect a conventionally-named signal handler.
For example:
connect_signal('window-foo', 'delete-event')
@@ -207,23 +228,4 @@
proc = lambda *x: getattr(self, attr)()
return self.widgets[widget_name].connect(signal, proc)
- # somewhat experimental decorator
- def with_blocked_signal(self, widget_name, signal):
- w = self.widgets[widget_name]
- hid = self.__signals[(widget_name, signal)]
- def blocker(proc):
- def blocked(*args, **kwargs):
- w.handler_block(hid)
- try:
- ret = proc(*args, **kwargs)
- finally:
- w.handler_unblock(hid)
- return ret
- return blocked
- return blocker
-
- def destroy(self):
- self.window.destroy()
- del self.window
-
pygobject.type_register(GladeWindow)
More information about the flumotion-commit
mailing list