def register_adapters(self): # labels self.adapt("expan", "label10") ad = Adapter(self.model, "toggle") ad.connect_widget(self.view["label_t1"], setter=lambda w,v: \ w.set_markup("<big><b>%i</b></big>" % v)) self.adapt(ad) self.adapt("toggle", "label_t2") # Before PyGTK 2.14 this will display the object ID instead of # something useful. self.adapt("color", "label_t3") self.adapt("url", "label_t4") self.adapt("spin", "label_t5") # controls self.adapt("expan", "expander1") self.adapt("toggle", "togglebutton1") self.adapt("toggle", "checkbutton1") self.adapt("color", "colorbutton1") self.adapt("url", "linkbutton1") self.adapt("spin", "spinbutton2") return
def __init__(self, model, prop_name, prop_read=None, prop_write=None, value_error=None, spurious=False): UserClassAdapter.__init__(self, model, prop_name, lambda c, i: c.__getitem__(i), lambda c, v, i: c.__setitem__(i, v), prop_read, prop_write, value_error, spurious) prop = Adapter._get_property(self) #prop = self._get_property() # bug fix reported by A. Dentella if not (hasattr(prop, "__getitem__") and hasattr(prop, "__setitem__")): # before giving up, unregisters itself as an observer # TODO also tear down Intermediate instances self.relieve_model(model) raise TypeError("Property " + self._prop_name + " is not a valid container") self._prop_is_map = isinstance(prop, dict) or \ isinstance(prop, ObsMapWrapper) # contained widgets self._idx2wid = {} self._wid2idx = {} self._widgets = None return
def __init__(self, model, prop_name, prop_read=None, prop_write=None, value_error=None, spurious=False): UserClassAdapter.__init__(self, model, prop_name, lambda c,i: c.__getitem__(i), lambda c,v,i: c.__setitem__(i,v), prop_read, prop_write, value_error, spurious) prop = Adapter._get_property(self) #prop = self._get_property() # bug fix reported by A. Dentella if not (hasattr(prop, "__getitem__") and hasattr(prop, "__setitem__")): # before giving up, unregisters itself as an observer # TODO also tear down Intermediate instances self.relieve_model(model) raise TypeError("Property " + self._prop_name + " is not a valid container") self._prop_is_map = isinstance(prop, dict) or \ isinstance(prop, ObsMapWrapper) # contained widgets self._idx2wid = {} self._wid2idx = {} self._widgets = None return
def register_adapters(self): # labels self.adapt("expan", "label10") ad = Adapter(self.model, "toggle") ad.connect_widget(self.view["label_t1"], setter=lambda w,v: \ w.set_markup("<big><b>%i</b></big>" % v)) self.adapt(ad) self.adapt("toggle", "label_t2") self.adapt("color", "label_t3") self.adapt("url", "label_t4") self.adapt("spin", "label_t5") # controls self.adapt("expan", "expander1") self.adapt("toggle", "togglebutton1") self.adapt("toggle", "checkbutton1") self.adapt("color", "colorbutton1") #self.adapt("url", "linkbutton1") ##This needs glade-3 self.adapt("spin", "spinbutton1") return
def testArguments(self): errors = [] def handle(adapter, name, value): errors.append((adapter, name, value)) adapter.update_widget() e = Adapter(self.m, "en1", prop_read=lambda v: v/2.0, prop_write=lambda v: float(v)*2, value_error=handle, prop_cast=False, ) e.connect_widget(self.v["entry1"]) l = Adapter(self.m, "en1") l.connect_widget(self.v["label1"], setter=lambda w, v: w.set_markup("<big><b>%.2f</b></big>" % v)) self.assertEqual("5.0", self.v["entry1"].get_text()) self.assertEqual("10.00", self.v["label1"].get_text()) self.v["entry1"].set_text("1") self.assertEqual("2.00", self.v["label1"].get_text()) self.v["button1"].clicked() self.assertEqual("1.5", self.v["entry1"].get_text()) self.assertEqual("3.00", self.v["label1"].get_text()) self.v["entry1"].set_text("?") self.assertEqual((e, "en1", "?"), errors[-1]) self.assertEqual("1.5", self.v["entry1"].get_text()) self.assertEqual("3.00", self.v["label1"].get_text())
def register_adapters(self): a1 = Adapter(self.model, "en1", prop_read=lambda v: v / 2.0, prop_write=lambda v: v * 2, value_error=self.handle) a1.connect_widget(self.view["entry1"]) self.adapt(a1) a2 = Adapter(self.model, "en1") a2.connect_widget( self.view["label1"], setter=lambda w, v: w.set_markup("<big><b>%.2f</b></big>" % v)) self.adapt(a2) self.e = a1 self.errors = []
def register_adapters(self): a1 = Adapter(self.model, "en1", prop_read=lambda v: v/2.0, prop_write=lambda v: v*2, value_error=self.handle) a1.connect_widget(self.view["entry1"]) self.adapt(a1) a2 = Adapter(self.model, "en1") a2.connect_widget(self.view["label1"], setter=lambda w,v: w.set_markup("<big><b>%.2f</b></big>" % v)) self.adapt(a2) self.e = a1 self.errors = []
def testArguments(self): errors = [] def handle(adapter, name, value): errors.append((adapter, name, value)) adapter.update_widget() e = Adapter( self.m, "en1", prop_read=lambda v: v / 2.0, prop_write=lambda v: float(v) * 2, value_error=handle, prop_cast=False, ) e.connect_widget(self.v["entry1"]) l = Adapter(self.m, "en1") l.connect_widget( self.v["label1"], setter=lambda w, v: w.set_markup("<big><b>%.2f</b></big>" % v)) self.assertEqual("5.0", self.v["entry1"].get_text()) self.assertEqual("10.00", self.v["label1"].get_text()) self.v["entry1"].set_text("1") self.assertEqual("2.00", self.v["label1"].get_text()) self.v["button1"].clicked() self.assertEqual("1.5", self.v["entry1"].get_text()) self.assertEqual("3.00", self.v["label1"].get_text()) self.v["entry1"].set_text("?") self.assertEqual((e, "en1", "?"), errors[-1]) self.assertEqual("1.5", self.v["entry1"].get_text()) self.assertEqual("3.00", self.v["label1"].get_text())
def __create_adapters__(self, prop_name, wid_name, flavour=None): """ Private service that looks at property and widgets types, and possibly creates one or more (best) fitting adapters that are returned as a list. ``flavour`` is optionally used when a particular flavour must be used when seraching in default adapters. """ res = [] wid = self.view[wid_name] if wid is None: raise ValueError("Widget '%s' not found" % wid_name) # Decides the type of adapters to be created. if isinstance(wid, Gtk.Calendar): # calendar creates three adapter for year, month and day ad = RoUserClassAdapter(self.model, prop_name, lambda d: d.year, lambda d,y: d.replace(year=y), spurious=self.accepts_spurious_change()) ad.connect_widget(wid, lambda c: c.get_date()[0], lambda c,y: c.select_month(c.get_date()[1], y), "day-selected", flavour=flavour) res.append(ad) # year ad = RoUserClassAdapter(self.model, prop_name, lambda d: d.month, lambda d,m: d.replace(month=m), spurious=self.accepts_spurious_change()) ad.connect_widget(wid, lambda c: c.get_date()[1]+1, lambda c,m: c.select_month(m-1, c.get_date()[0]), "day-selected", flavour=flavour) res.append(ad) # month ad = RoUserClassAdapter(self.model, prop_name, lambda d: d.day, lambda d,v: d.replace(day=v), spurious=self.accepts_spurious_change()) ad.connect_widget(wid, lambda c: c.get_date()[2], lambda c,d: c.select_day(d), "day-selected", flavour=flavour) res.append(ad) # day return res try: # tries with StaticContainerAdapter if "." in prop_name: raise TypeError ad = StaticContainerAdapter(self.model, prop_name, spurious=self.accepts_spurious_change()) ad.connect_widget(wid, flavours=flavour) res.append(ad) except TypeError as e: # falls back to a simple adapter ad = Adapter(self.model, prop_name, spurious=self.accepts_spurious_change()) ad.connect_widget(wid, flavour=flavour) res.append(ad) return res
def adapt(self, *args, **kwargs): """ There are five ways to call this: .. method:: adapt() :noindex: Take properties from the model for which ``adapt`` has not yet been called, match them to the view by name, and create adapters fitting for the respective widget type. That information comes from :mod:`gtkmvc3.adapters.default`. See :meth:`_find_widget_match` for name patterns. .. versionchanged:: 1.99.1 Allow incomplete auto-adaption, meaning properties for which no widget is found. .. method:: adapt(ad) :noindex: Keep track of manually created adapters for future ``adapt()`` calls. *ad* is an adapter instance already connected to a widget. .. method:: adapt(prop_name) :noindex: Like ``adapt()`` for a single property. *prop_name* is a string. .. method:: adapt(prop_name, wid_name) :noindex: Like ``adapt(prop_name)`` but without widget name matching. *wid_name* has to exist in the view. .. method:: adapt(prop_name, wid_name, gprop_name) :noindex: Like ``adapt(prop_name, wid_name)`` but without using default adapters. This is useful to adapt secondary properties like button sensitivity. *gprop_name* is a string naming a property of the widget. No cast is attempted, so *prop_name* must match its type exactly. .. versionadded:: 1.99.2 In all cases, optional keyword argument ``flavour=value`` can be used to specify a particular flavour from those available in :mod:`gtkmvc3.adapters.default` adapters. """ # checks arguments n = len(args) flavour = kwargs.get("flavour", None) if n==0: adapters = [] props = self.model.get_properties() # matches all properties not previoulsy adapter by the user: for prop_name in (p for p in props if p not in self.__user_props): try: wid_name = self._find_widget_match(prop_name) except TooManyCandidatesError as e: # multiple candidates, gives up raise e except ValueError as e: # no widgets found for given property, continue after emitting a warning if e.args: logger.warn(e[0]) else: logger.warn("No widget candidates match property '%s'" % prop_name) else: logger.debug("Auto-adapting property %s and widget %s" % \ (prop_name, wid_name)) adapters += self.__create_adapters__(prop_name, wid_name, flavour) elif n == 1: #one argument if isinstance(args[0], Adapter): adapters = (args[0],) elif isinstance(args[0], str): prop_name = args[0] wid_name = self._find_widget_match(prop_name) adapters = self.__create_adapters__(prop_name, wid_name, flavour) else: raise TypeError("Argument of adapt() must be either an " "Adapter or a string") elif n == 2: # two arguments if not (isinstance(args[0], str) and isinstance(args[1], str)): raise TypeError("Arguments of adapt() must be two strings") # retrieves both property and widget, and creates an adapter prop_name, wid_name = args adapters = self.__create_adapters__(prop_name, wid_name, flavour) elif n == 3: for arg in args: if not isinstance(arg, str): raise TypeError("names must be strings") prop_name, wid_name, gprop_name = args ad = Adapter(self.model, prop_name) ad.connect_widget(self.view[wid_name], getter=lambda w: w.get_property(gprop_name), setter=lambda w, v: w.set_property(gprop_name, v), signal='notify::%s' % gprop_name, flavour=flavour) adapters = [ad] else: raise TypeError( "adapt() takes at most three arguments (%i given)" % n) for ad in adapters: self.__adapters.append(ad) # remember properties added by the user if n > 0: self.__user_props.add(ad.get_property_name())