"Fossies" - the Fresh Open Source Software Archive 
Member "pysize-0.2/pysize/ui/gtk/gazpacho_loader/custom.py" (11 Mar 2007, 33937 Bytes) of package /linux/privat/old/pysize-0.2.tar.gz:
As a special service "Fossies" has tried to format the requested source page into HTML format using (guessed) Python source code syntax highlighting (style:
standard) with prefixed line numbers.
Alternatively you can here
view or
download the uninterpreted source code file.
1 # Copyright (C) 2005 Johan Dahlin
2 #
3 # This program is free software; you can redistribute it and/or
4 # modify it under the terms of the GNU Lesser General Public License
5 # as published by the Free Software Foundation; either version 2
6 # of the License, or (at your option) any later version.
7 #
8 # This program is distributed in the hope that it will be useful,
9 # but WITHOUT ANY WARRANTY; without even the implied warranty of
10 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 # GNU General Public License for more details.
12 #
13 # You should have received a copy of the GNU Lesser General Public License
14 # along with this program; if not, write to the Free Software
15 # Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
16
17 import gobject
18 import gtk
19 from gtk import gdk
20
21 def enumfromstring(value_name, pspec=None, enum=None):
22 if not value_name:
23 return 0
24
25 try:
26 value = int(value_name)
27 except ValueError:
28 if pspec:
29 enum_class = pspec.enum_class
30 if enum_class is None:
31 return 0
32 elif enum:
33 enum_class = enum
34 else:
35 raise ValueError("Need pspec or enm")
36
37 for value, enum in enum_class.__enum_values__.items():
38 if value_name in (enum.value_name, enum.value_nick):
39 return value
40
41 raise ValueError("Invalid enum value: %r" % value_name)
42
43 def flagsfromstring(value_name, pspec=None, flags=None):
44 if not value_name:
45 return 0
46
47 try:
48 return int(value_name)
49 except ValueError:
50 pass
51
52 value_names = [v.strip() for v in value_name.split('|')]
53
54 if pspec:
55 flags_class = pspec.flags_class
56 elif flags:
57 flags_class = flags
58 else:
59 raise ValueError("need pspec or flags")
60
61 flag_values = flags_class.__flags_values__
62 new_value = 0
63 for mask, flag in flag_values.items():
64 if (flag.value_names[0] in value_names or
65 flag.value_nicks[0] in value_names):
66 new_value |= mask
67
68 return new_value
69
70 def valuefromstringsimpletypes(gtype, string):
71 if gtype in (gobject.TYPE_CHAR, gobject.TYPE_UCHAR):
72 value = string[0]
73 elif gtype == gobject.TYPE_BOOLEAN:
74 value = str2bool(string)
75 elif gtype in (gobject.TYPE_INT, gobject.TYPE_UINT):
76 value = int(string)
77 elif gtype in (gobject.TYPE_LONG, gobject.TYPE_ULONG):
78 value = long(string)
79 elif gtype in (gobject.TYPE_FLOAT, gobject.TYPE_DOUBLE):
80 value = float(string)
81 elif gtype == gobject.TYPE_STRING:
82 value = string
83 elif gobject.type_is_a(gtype, gobject.TYPE_PYOBJECT):
84 value = string
85 elif gobject.type_is_a(gtype, gobject.GBoxed):
86 print 'TODO: boxed'
87 value = None
88 else:
89 raise TypeError("type %r is unknown" % gtype)
90
91 return value
92
93 def str2bool(value):
94 return value[0].lower() in ('t', 'y') or value == '1'
95
96 def get_child_pspec_from_name(gtype, name):
97 for pspec in gtk.container_class_list_child_properties(gtype):
98 if pspec.name == name:
99 return pspec
100
101 def get_pspec_from_name(gtype, name):
102 for pspec in gobject.list_properties(gtype):
103 if pspec.name == name:
104 return pspec
105
106 class AdapterMeta(type):
107 def __new__(mcs, name, bases, dict):
108 t = type.__new__(mcs, name, bases, dict)
109 t.add_adapter()
110 return t
111
112 class IObjectAdapter:
113 """This interface is used by the loader to build
114 a custom object.
115
116 object_type is a GType representing which type we can construct
117 """
118 object_type = None
119
120 def construct(self, name, properties):
121 """constructs a new type of type gtype
122 name: string representing the type name
123 gtype: gtype of the object to be constructed
124 properties: construct properties
125 """
126 pass
127
128 def add(self, gobj, child, properties, type):
129 """Adds a child to gobj with properties"""
130 pass
131
132 def get_properties(self, gtype, obj_id, properties):
133 pass
134
135 def set_properties(self, gobj, properties):
136 pass
137
138 def prop_set_NAME(self, widget, value_string):
139 """
140 Sets the property NAME for widget, note that you have to convert
141 from a string manully"""
142 pass
143
144 def find_internal_child(self, gobj, name):
145 """Returns an internal child"""
146
147 def get_internal_child_name(self, gobj, child):
148 """
149 Returns the name of a widget, as an internal child or None
150 if it cannot be found
151 """
152
153 class Adapter(object):
154 __metaclass__ = AdapterMeta
155 _adapters = []
156 _properties = {}
157
158 def __init__(self, build):
159 self._build = build
160
161 def get_raw_property(self, object, name):
162 object_id = object.get_data('gazpacho::object-id')
163 if not object_id in self._properties:
164 raise KeyError(object_id)
165 return self._properties[object_id][name]
166
167 def add_adapter(cls):
168 if cls.__name__ != 'Adapter':
169 cls._adapters.append(cls)
170 add_adapter = classmethod(add_adapter)
171
172 def get_adapters(cls):
173 return cls._adapters
174 get_adapters = classmethod(get_adapters)
175
176 class AdapterRegistry:
177 def __init__(self):
178 # GObject typename -> adapter instance
179 self._adapters = {}
180
181 for adapter in Adapter.get_adapters():
182 self.register_adapter(adapter)
183
184 def _add_adapter(self, name, adapter):
185 self._adapters[name] = adapter
186
187 def register_adapter(self, adapter):
188 adict = adapter.__dict__
189 # Do not register abstract adapters
190 if adict.has_key('object_type'):
191 object_type = adict.get('object_type')
192 if type(object_type) != tuple:
193 object_type = object_type,
194
195 for klass in object_type:
196 self._add_adapter(gobject.type_name(klass), adapter)
197 elif adict.has_key('object_name'):
198 self._add_adapter(adict.get('object_name'), adapter)
199
200 def get_adapter(self, gobj, type_name=None, build=None):
201 # Name is optional, for performance reasons we want
202 # to send it as often as we can, normally it's already
203 # known at the callsite.
204 if type_name == None:
205 type_name = gobject.type_name(gobj)
206 orig_name = type_name
207
208 while True:
209 adapter = self._adapters.get(type_name)
210 if adapter:
211 # Store a reference for the adapter, to make the
212 # next lookup faster
213 self._adapters[orig_name] = adapter
214 return adapter(build)
215
216 gobj = gobject.type_parent(gobj)
217 type_name = gobject.type_name(gobj)
218
219 class GObjectAdapter(Adapter):
220 object_type = gobject.GObject
221 child_names = []
222 def construct(self, name, gtype, properties):
223 # Due to a bug in gobject.new() we only send in construct
224 # only properties here, the rest are set normally
225 gobj = gobject.new(gtype, **properties)
226 return gobj
227
228 def get_properties(self, gtype, obj_id, properties):
229 return self._getproperties(gtype, obj_id, properties)
230
231 def set_properties(self, gobj, properties):
232 prop_names = []
233 for name, value in properties:
234 #print '%s.%s = %r' % (gobject.type_name(gobj), name, value)
235 func_name = 'prop_set_%s' % name.replace('-', '_')
236 func = getattr(self, func_name, None)
237 if func:
238 func(gobj, value)
239 else:
240 gobj.set_property(name, value)
241
242 prop_names.append(name)
243
244 gobj.set_data('gobject.changed_properties', prop_names)
245
246 def _getproperties(self, gtype, obj_id, properties, child=False):
247 if child:
248 get_pspec = get_child_pspec_from_name
249 else:
250 get_pspec = get_pspec_from_name
251
252 propdict = self._properties
253 if not propdict.has_key(obj_id):
254 props = propdict[obj_id] = {}
255 else:
256 props = propdict[obj_id]
257
258 construct = {}
259 normal = []
260 for prop in properties:
261 propname = prop.name.replace('_', '-')
262 #full = '%s::%s' % (gobject.type_name(gtype), propname)
263 props[prop.name] = prop.data
264 if hasattr(self, 'prop_set_%s' % prop.name):
265 normal.append((prop.name, prop.data))
266 continue
267
268 pspec = get_pspec(gtype, propname)
269 if not pspec:
270 print ('Unknown property: %s:%s (id %s)' %
271 (gobject.type_name(gtype),
272 prop.name,
273 obj_id))
274 continue
275
276 try:
277 value = self._valuefromstring(obj_id, pspec, prop.data)
278 except ValueError:
279 print ("Convertion failed for %s:%s (id %s), "
280 "expected %s but found %r" %
281 (gobject.type_name(gtype),
282 prop.name,
283 obj_id,
284 gobject.type_name(pspec.value_type),
285 prop.data))
286 continue
287
288 # Could not
289 if value is None:
290 continue
291
292 if pspec.flags & gobject.PARAM_CONSTRUCT_ONLY != 0:
293 construct[pspec.name] = value
294 else:
295 normal.append((pspec.name, value))
296
297 if child:
298 assert not construct
299 return normal
300
301 return construct, normal
302
303 def _valuefromstring(self, obj_id, pspec, string):
304 # This is almost a 1:1 copy of glade_xml_set_value_from_string from
305 # libglade.
306 prop_type = pspec.value_type
307
308 if (prop_type in (gobject.TYPE_INT, gobject.TYPE_UINT)
309 and gobject.type_name(pspec) == 'GParamUnichar'):
310 value = unicode(string and string[0] or "")
311 return value
312
313 try:
314 value = valuefromstringsimpletypes(prop_type, string)
315 except TypeError:
316 pass # it's ok if we fail so far, we'll try other types
317 else:
318 return value
319
320 if gobject.type_is_a(prop_type, gobject.TYPE_ENUM):
321 value = enumfromstring(string, pspec)
322 elif gobject.type_is_a(prop_type, gobject.TYPE_FLAGS):
323 value = flagsfromstring(string, pspec)
324 elif gobject.type_is_a(prop_type, gobject.GObject):
325 if gobject.type_is_a(prop_type, gtk.Adjustment):
326 value = gtk.Adjustment(0, 0, 100, 1, 10, 10)
327 (value.value, value.lower, value.upper,
328 value.step_increment, value.page_increment,
329 value.page_size) = map(float, string.split(' '))
330 elif gobject.type_is_a(prop_type, gdk.Pixbuf):
331 filename = self._build.find_resource(string)
332 value = None
333 if filename:
334 # XXX: Handle GError exceptions.
335 value = gdk.pixbuf_new_from_file(filename);
336 elif (gobject.type_is_a(gobject.GObject, prop_type) or
337 gobject.type_is_a(prop_type, gobject.GObject)):
338 value = self._build.get_widget(string)
339 if value is None:
340 self._build.add_delayed_property(obj_id, pspec, string)
341 else:
342 value = None
343 else:
344 raise AssertionError("type %r is unknown" % prop_type)
345
346 return value
347
348 def add(self, parent, child, properties, type):
349 raise NotImplementedError
350
351 def find_internal_child(self, gobj, name):
352 if name in self.child_names:
353 return getattr(gobj, name)
354
355 def get_internal_child_name(self, gobj, child):
356 for child_name in self.child_names:
357 if getattr(gobj, child_name) == child:
358 return child_name
359
360 class UIManagerAdapter(GObjectAdapter):
361 object_type = gtk.UIManager
362 def add(self, parent, child, properties, type):
363 parent.insert_action_group(child, 0)
364
365 class WidgetAdapter(GObjectAdapter):
366 object_type = gtk.Widget
367 def construct(self, name, gtype, properties):
368 widget = GObjectAdapter.construct(self, name, gtype, properties)
369 widget.set_name(name)
370 return widget
371
372 def prop_set_has_default(self, widget, value):
373 value = str2bool(value)
374 if value:
375 self._build._default_widget = widget
376
377 def prop_set_tooltip(self, widget, value):
378 if isinstance(widget, gtk.ToolItem):
379 # XXX: factor to separate Adapter
380 widget.set_tooltip(self._build._tooltips, value, None)
381 else:
382 self._build._tooltips.set_tip(widget, value, None)
383
384 def prop_set_visible(self, widget, value):
385 value = str2bool(value)
386 widget.set_data('gazpacho::visible', value)
387 widget.set_property('visible', value)
388
389 def prop_set_has_focus(self, widget, value):
390 value = str2bool(value)
391 if value:
392 self._build._focus_widget = widget
393 widget.set_data('gazpacho::has-focus', value)
394
395 def prop_set_is_focus(self, widget, value):
396 value = str2bool(value)
397 widget.set_data('gazpacho::is-focus', value)
398
399 def prop_set_sizegroup(self, widget, value):
400 widget.set_data('gazpacho::sizegroup', value)
401
402 def prop_set_response_id(self, widget, value):
403 widget.set_data('gazpacho::response-id', int(value))
404
405 class PythonWidgetAdapter(WidgetAdapter):
406 def construct(self, name, gtype, properties):
407 obj = self.object_type()
408 obj.set_name(name)
409 return obj
410
411 class ContainerAdapter(WidgetAdapter):
412 object_type = gtk.Container
413 def add(self, container, child, properties, type):
414 if not self._add_to_dialog(container, child):
415 container.add(child)
416
417 self._set_child_properties(container, child, properties)
418
419 def _add_to_dialog(self, parent, widget):
420 response_id = widget.get_data('gazpacho::response-id')
421 if response_id is not None:
422 dialog = None
423 while parent:
424 if isinstance(parent, gtk.Dialog):
425 dialog = parent
426 break
427 parent = parent.parent
428
429 if dialog:
430 # FIXME: Limit to action_area
431 dialog.add_action_widget(widget, response_id)
432
433 # Reset, the real properties will be set afterwards
434 widget.parent.set_child_packing(widget, True, True, 0,
435 gtk.PACK_START)
436 return True
437 return False
438
439 def _set_child_properties(self, container, child, properties):
440 properties = self._getproperties(type(container),
441 child.get_name(),
442 properties,
443 child=True)
444
445 for name, value in properties:
446 #print '%s.%s = %r (of %s)' % (child.get_name(), name, value,
447 # gobj.get_name())
448 container.child_set_property(child, name, value)
449
450 class ActionGroupAdapter(GObjectAdapter):
451 object_type = gtk.ActionGroup
452 def construct(self, name, gtype, properties):
453 if not properties.has_key('name'):
454 properties['name'] = name
455 return GObjectAdapter.construct(self, name, gtype, properties)
456
457 def add(self, parent, child, properties, type):
458 accel_key = child.get_data('accel_key')
459 if accel_key:
460 accel_path = "<Actions>/%s/%s" % (parent.get_property('name'),
461 child.get_name())
462 accel_mod = child.get_data('accel_mod')
463 gtk.accel_map_add_entry(accel_path, accel_key, accel_mod)
464 child.set_accel_path(accel_path)
465 child.set_accel_group(self._build.ensure_accel())
466 parent.add_action(child)
467
468 class ActionAdapter(GObjectAdapter):
469 object_type = gtk.Action
470 def construct(self, name, gtype, properties):
471 # Gazpacho doesn't save the name for actions
472 # So we have set it manually.
473 if not properties.has_key('name'):
474 properties['name'] = name
475
476 return GObjectAdapter.construct(self, name, gtype, properties)
477
478 def _set_accel(self, action, accel_key, accel_mod):
479 if not accel_key:
480 return
481
482 action.set_data('accel_key', accel_key)
483 action.set_data('accel_mod', accel_mod)
484
485 def prop_set_accelerator(self, action, value):
486 if not value:
487 return
488 self._set_accel(action, *gtk.accelerator_parse(value))
489
490 def prop_set_stock_id(self, action, value):
491 action.set_property('stock-id', value)
492
493 # Set the accelerator from the stock item, but only if it's
494 # not set already
495 if action.get_data('accel_key'):
496 return
497
498 # FIXME: Should we print a warning if it cannot be found
499 stock_item = gtk.stock_lookup(value)
500 if stock_item:
501 self._set_accel(action, stock_item[3], stock_item[2])
502
503 # This is for backwards compatibility
504 def prop_set_callback(self, action, value):
505 if value:
506 self._build.add_signal(action, 'activate', value)
507
508 class PixmapAdapter(WidgetAdapter):
509 object_type = gtk.Pixmap
510 def prop_set_build_insensitive(self, pixmap, value):
511 pixmap.set_build_insensitive(str2bool(value))
512
513 def prop_set_filename(self, pixmap, value):
514 filename = self._build.find_resource(value);
515 if not filename:
516 print 'No such a file or directory: %s' % value
517 return
518
519 try:
520 pb = gdk.pixbuf_new_from_file(filename)
521 except gobject.GError, e:
522 print 'Error loading pixmap: %s' % e.message
523 return
524 except TypeError, e:
525 print 'Error loading pixmap: %s' % e
526 return
527
528 pix, bit = pb.render_pixmap_and_mask(127)
529 pixmap.set(pix, bit)
530
531 class ProgressAdapter(WidgetAdapter):
532 object_type = gtk.Progress
533 def prop_set_format(self, progress, value):
534 progress.set_format_string(value)
535
536 class ButtonAdapter(ContainerAdapter):
537 object_type = gtk.Button
538
539 class OptionMenuAdapter(ButtonAdapter):
540 object_type = gtk.OptionMenu
541 def add(self, parent, child, properties, type):
542 if not isinstance(child, gtk.Menu):
543 print ("warning: the child of the option menu '%s' was "
544 "not a GtkMenu" % (child.get_name()))
545 return
546
547 parent.set_menu(child)
548 self._set_child_properties(parent, child, properties)
549
550 def prop_set_history(self, optionmenu, value):
551 optionmenu.set_history(int(value))
552
553 class EntryAdapter(WidgetAdapter):
554 object_type = gtk.Entry
555 def prop_set_invisible_char(self, entry, value):
556 entry.set_invisible_char(value.decode()[0])
557
558 class TextViewAdapter(ButtonAdapter):
559 object_type = gtk.TextView
560 def prop_set_text(self, textview, value):
561 buffer = gtk.TextBuffer()
562 buffer.set_text(value)
563 textview.set_buffer(buffer)
564
565 class CalendarAdapter(WidgetAdapter):
566 object_type = gtk.Calendar
567 def prop_set_display_options(self, calendar, value):
568 options = flagsfromstring(value, flags=gtk.CalendarDisplayOptions)
569 calendar.display_options(options)
570
571 class WindowAdapter(ContainerAdapter):
572 object_type = gtk.Window
573 def prop_set_wmclass_class(self, window, value):
574 window.set_wmclass(value, window.wmclass_class)
575
576 def prop_set_wmclass_name(self, window, value):
577 window.set_wmclass(value, window.wmclass_name)
578
579 def prop_set_type_hint(self, window, value):
580 window.set_data('gazpacho::type-hint',
581 enumfromstring(value, enum=gdk.WindowTypeHint))
582
583 class NotebookAdapter(ContainerAdapter):
584 object_type = gtk.Notebook
585 def add(self, notebook, child, properties, type):
586 tab_item = False
587 for propinfo in properties[:]:
588 if (propinfo.name == 'type' and
589 propinfo.data == 'tab'):
590 tab_item = True
591 properties.remove(propinfo)
592 break
593
594 if tab_item:
595 children = notebook.get_children()
596 body = notebook.get_nth_page(len(children) - 1)
597 notebook.set_tab_label(body, child)
598 else:
599 notebook.append_page(child)
600
601 self._set_child_properties(notebook, child, properties)
602
603 class ExpanderAdapter(ContainerAdapter):
604 object_type = gtk.Expander, gtk.Frame
605 def _get_label_item(self, properties):
606 for propinfo in properties[:]:
607 if (propinfo.name == 'type' and
608 propinfo.data == 'label_item'):
609 properties.remove(propinfo)
610 return True
611 return False
612
613 def add(self, expander, child, properties, type):
614 if self._build._version == 'libglade':
615 label_item = self._get_label_item(properties)
616 elif type == 'label_item':
617 label_item = True
618 else:
619 label_item = False
620
621 if label_item:
622 expander.set_label_widget(child)
623 else:
624 expander.add(child)
625
626 self._set_child_properties(expander, child, properties)
627
628 class MenuItemAdapter(ContainerAdapter):
629 object_type = gtk.MenuItem
630 def add(self, menuitem, child, properties, type):
631 if isinstance(child, gtk.Menu):
632 menuitem.set_submenu(child)
633 else:
634 print 'FIXME: Adding a %s to a %s' % (gobject.type_name(child),
635 gobject.type_name(self.object_type))
636 # GtkWarning: Attempting to add a widget with type GtkImage to a
637 # GtkImageMenuItem, but as a GtkBin subclass a GtkImageMenuItem
638 # can only contain one widget at a time; it already contains a
639 # widget of type GtkAccelLabel'
640 #menuitem.add(child)
641
642 self._set_child_properties(menuitem, child, properties)
643
644 def prop_set_label(self, menuitem, value):
645 child = menuitem.child
646
647 if not child:
648 child = gtk.AccelLabel("")
649 child.set_alignment(0.0, 0.5)
650 menuitem.add(child)
651 child.set_accel_widget(menuitem)
652 child.show()
653
654 if isinstance(child, gtk.Label):
655 child.set_text(value)
656
657 def prop_set_use_underline(self, menuitem, value):
658 child = menuitem.child
659
660 if not child:
661 child = gtk.AccelLabel("")
662 child.set_alignment(0.0, 0.5)
663 menuitem.add(child)
664 child.set_accel_widget(menuitem)
665 child.show()
666
667 if isinstance(child, gtk.Label):
668 child.set_use_underline(str2bool(value))
669
670 def prop_set_use_stock(self, menuitem, value):
671 child = menuitem.child
672
673 if not child:
674 child = gtk.AccelLabel("")
675 child.set_alignment(0.0, 0.5)
676 menuitem.add(child)
677 child.set_accel_widget(menuitem)
678 child.show()
679
680 value = str2bool(value)
681 if not isinstance(child, gtk.Label) or not value:
682 return
683
684 stock_id = child.get_label()
685
686 retval = gtk.stock_lookup(stock_id)
687 if retval:
688 _, label, modifier, keyval, _ = retval
689 # put in the stock image next to the text. Done before
690 # messing with the label child, so that stock_id doesn't
691 # become invalid.
692 if isinstance(menuitem, gtk.ImageMenuItem):
693 image = gtk.image_new_from_stock(stock_id, gtk.ICON_SIZE_MENU)
694 menuitem.set_image(image)
695 image.show()
696
697 child.set_text(label)
698 child.set_use_underline(True)
699
700 if keyval:
701 # This triggers a segfault on exit (pachi.glade), weird
702 menuitem.add_accelerator('activate',
703 self._build.ensure_accel(),
704 keyval, modifier,
705 gtk.ACCEL_VISIBLE)
706 else:
707 print "warning: could not look up stock id '%s'" % stock_id
708
709 class CheckMenuItemAdapter(MenuItemAdapter):
710 object_type = gtk.CheckMenuItem
711 def prop_set_always_show_toggle(self, check, value):
712 check.set_show_toggle(value)
713
714 class RadioMenuItemAdapter(MenuItemAdapter):
715 object_type = gtk.RadioMenuItem
716 def prop_set_group(self, radio, value):
717 group = self._build.get_widget(value)
718 if not group:
719 print "warning: Radio button group %s could not be found" % value
720 return
721
722 if group == radio:
723 print "Group is self, skipping."
724 return
725
726 radio.set_group(group.get_group()[0])
727
728 class ImageMenuItemAdapter(MenuItemAdapter):
729 object_type = gtk.ImageMenuItem
730 def find_internal_child(self, menuitem, childname):
731 if childname == 'image':
732 pl = menuitem.get_image()
733 if not pl:
734 pl = gtk.Image()
735 menuitem.set_image(pl)
736 return pl
737 return MenuItemAdapter.find_internal_child(self, menuitem, childname)
738
739 def get_internal_child_name(self, parent, child):
740 if parent.get_image() == child:
741 return 'image'
742 return MenuItemAdapter.get_internal_child_name(self, parent, child)
743
744 class ToolbarAdapter(ContainerAdapter):
745 object_type = gtk.Toolbar
746 def prop_set_tooltips(self, toolbar, value):
747 toolbar.set_tooltips(str2bool(value))
748
749 class StatusbarAdapter(ContainerAdapter):
750 object_type = gtk.Statusbar
751 def prop_set_has_resize_grip(self, status, value):
752 status.set_has_resize_grip(str2bool(value))
753
754 class RulerAdapter(WidgetAdapter):
755 object_type = gtk.Ruler
756 def prop_set_metric(self, ruler, value):
757 ruler.set_metric(enumfromstring(value,
758 enum=gtk.MetricType))
759
760 class ToolButtonAdapter(ContainerAdapter):
761 object_type = gtk.ToolButton
762 def prop_set_icon(self, toolbutton, value):
763 filename = self._build.find_resource(value)
764 if not filename:
765 print 'No such a file or directory: %s' % value
766 return
767
768 pb = gdk.pixbuf_new_from_file(filename)
769 if not pb:
770 print "warning: Couldn't find image file: %s" % value
771 return
772 image = gtk.Image()
773 image.set_from_pixbuf(pb)
774 image.show()
775 toolbutton.set_icon_widget(image)
776
777 class ToggleToolButtonAdapter(ToolButtonAdapter):
778 object_type = gtk.ToggleToolButton
779 def prop_set_active(self, toolbutton, value):
780 toolbutton.set_active(str2bool(value))
781
782 def combobox_set_content_from_string(combobox, value):
783 # If the "items" property is set, we create a simple model with just
784 # one column of text.
785 store = gtk.ListStore(str)
786 combobox.set_model(store)
787
788 # GtkComboBoxEntry creates the cell renderer itself, but we have to set
789 # the column containing the text.
790 if isinstance(combobox, gtk.ComboBoxEntry):
791 if combobox.get_text_column() == -1:
792 combobox.set_text_column(0)
793 else:
794 cell = gtk.CellRendererText()
795 combobox.pack_start(cell, True)
796 combobox.set_attributes(cell, text=0)
797
798 for part in value.split('\n'):
799 store.append([part])
800
801 active = combobox.get_data('gazpacho::active')
802 if active:
803 combobox.set_active(active)
804
805 class ComboBoxAdapter(ContainerAdapter):
806 # FIXME: Internal child: entry -> get_child()
807 object_type = gtk.ComboBox, gtk.ComboBoxEntry
808 def prop_set_items(self, combobox, value):
809 combobox_set_content_from_string(combobox, value)
810
811 def prop_set_active(self, combobox, value):
812 combobox.set_data('gazpacho::active', int(value))
813
814 # We don't need to set the actual property here, it's done in
815 # prop_set_items.
816
817 # FIXME: PyGTK does not expose vscrollbar and hscrollbar.
818 #
819 #class ScrolledWindowAdapter(WindowAdapter):
820 # child_names = ['vscrollbar', 'hscrollbar']
821 # object_type = gtk.ScrolledWindow
822 # def get_internal_child_name(self, parent, child):
823 # if parent.vscrollbar == child:
824 # return 'vscrollbar'
825 # elif parent.hscrollbar == child:
826 # return 'hscrollbar'
827 # return WindowAdapter.get_internal_child_name(self, parent, child)
828
829 class DialogAdapter(WindowAdapter):
830 child_names = ['vbox', 'action_area']
831 object_type = gtk.Dialog
832 def get_internal_child_name(self, parent, child):
833 if parent.vbox == child:
834 return 'vbox'
835 elif parent.action_area == child:
836 return 'action_area'
837 return WindowAdapter.get_internal_child_name(self, parent, child)
838
839 class ColorSelectionDialogAdapter(DialogAdapter):
840 child_names = DialogAdapter.child_names + ['ok_button',
841 'cancel_button',
842 'help_button',
843 'colorsel']
844 object_type = gtk.ColorSelectionDialog
845 def find_internal_child(self, gobj, name):
846 if name == 'color_selection':
847 return gobj.colorsel
848
849 return DialogAdapter.find_internal_child(self, gobj, name)
850
851 def get_internal_child_name(self, parent, child):
852 if parent.colorsel == child:
853 return 'color_selection'
854 return DialogAdapter.get_internal_child_name(self, parent, child)
855
856 class FontSelectionDialogAdapter(DialogAdapter):
857 object_type = gtk.FontSelectionDialog
858 child_names = DialogAdapter.child_names + ['ok_button',
859 'cancel_button',
860 'apply_button',
861 'fontsel']
862 def find_internal_child(self, gobj, name):
863 if name == 'font_selection':
864 return gobj.fontsel
865
866 return DialogAdapter.find_internal_child(self, gobj, name)
867
868 def get_internal_child_name(self, parent, child):
869 if parent.fontsel == child:
870 return 'font_selection'
871 return DialogAdapter.get_internal_child_name(self, parent, child)
872
873 class TreeViewAdapter(ContainerAdapter):
874 object_type = gtk.TreeView
875 def add(self, treeview, child, properties, type):
876 if not isinstance(child, gtk.TreeViewColumn):
877 raise TypeError("Children of GtkTreeView must be a "
878 "GtkTreeViewColumns, not %r" % child)
879
880 treeview.append_column(child)
881
882 # Don't chain to Container add since children are not widgets
883
884 class CellLayoutAdapter(GObjectAdapter):
885 def set_cell_renderer_attributes(self, gobj, cell_renderer, attributes):
886 raise NotImplementedError
887
888 class TreeViewColumnAdapter(CellLayoutAdapter):
889 object_type = gtk.TreeViewColumn
890
891 def construct(self, name, gtype, properties):
892 gobj = super(TreeViewColumnAdapter, self).construct(name, gtype,
893 properties)
894 gobj.name = name
895 return gobj
896
897 def add(self, column, child, properties, type):
898 if not isinstance(child, gtk.CellRenderer):
899 raise TypeError("Children of GtkTreeViewColumn must be a "
900 "GtkCellRenderers, not %r" % child)
901
902 expand = True
903 pack_start = True
904 for propinfo in properties[:]:
905 name = propinfo.name
906 if name == 'expand':
907 expand = str2bool(propinfo.data)
908 properties.remove(propinfo)
909 elif name == 'pack_start':
910 pack_start = str2bool(propinfo.data)
911 properties.remove(propinfo)
912 else:
913 raise AssertionError("Unknown property for "
914 "GtkTreeViewColumn: %s" % name)
915 if pack_start:
916 column.pack_start(child, expand)
917 else:
918 column.pack_end(child, expand)
919
920 def set_cell_renderer_attributes(self, column, cell_renderer, attributes):
921 for name, value in attributes.items():
922 column.add_attribute(cell_renderer, name, value)
923
924 # this is ugly but's the only way to retrieve the attributes later on
925 cell_renderer.set_data('gazpacho::attributes', attributes)
926
927 # Gross hack to make it possible to use FileChooserDialog on win32.
928 # See bug http://bugzilla.gnome.org/show_bug.cgi?id=314527
929 class FileChooserDialogHack(gtk.FileChooserDialog):
930 def get_children(self):
931 return []
932
933 class FileChooserDialogAdapter(DialogAdapter):
934 gobject.type_register(FileChooserDialogHack)
935
936 class ImageAdapter(WidgetAdapter):
937 object_type = gtk.Image
938 def prop_set_file(self, image, value):
939 newvalue = self._build.find_resource(value)
940 if newvalue:
941 image.set_property('file', newvalue)
942 image.set_data('image-file-name', value)
943
944 class ListStoreAdapter(GObjectAdapter):
945 object_type = gtk.ListStore
946
947 def construct(self, name, gtype, properties):
948 gobj = super(ListStoreAdapter, self).construct(name, gtype,
949 properties)
950 gobj.name = name
951 return gobj
952
953 def set_column_types(self, store, columns):
954 if columns:
955 types = [col.type for col in columns]
956 store.set_column_types(*types)
957
958 def fill(self, store, rows):
959 types = [store.get_column_type(i) for i in range(store.get_n_columns())]
960 for row_info in rows:
961 values = []
962 for col_info in row_info.cols:
963 gtype = types[col_info.id]
964 value = valuefromstringsimpletypes(gtype, col_info.data)
965 values.append(value)
966
967 store.append(values)
968
969 # Global registry
970 adapter_registry = AdapterRegistry()