class TriageColumn(AppColumn): label = trellis.attr('Triage') app_attr = trellis.attr('triage_status') def sort_key(self, entry): return entry.triage_section, entry.triage_position _triage_values = None @property def triage_values(self): if self._triage_values is None: triage_values = [] for iterable in TRIAGE_HOOK.query(): for value, name, hsv in iterable: triage_values.append((value, (name, hsv))) type(self)._triage_values = tuple(triage_values) return self._triage_values @trellis.modifier def action(self, selection): for app_entry in selection: old_value = app_entry.triage_section for index, value in enumerate(self.triage_values): if value[0] == old_value: if index + 1 < len(self.triage_values): new_value = self.triage_values[index + 1][0] else: new_value = self.triage_values[0][0] break else: new_value = self.triage_values[0][0] triage.Triage(app_entry._item).manual = new_value
class ModelCheckSync(trellis.Component): listener = trellis.attr() model = trellis.attr() @trellis.maintain def state(self): self.model.checked = self.listener.value
class ReminderColumn(AppColumn): label = trellis.attr('(( ))') app_attr = trellis.attr('event_reminder_combined') def sort_key(self, entry): return entry.triage_section, entry.triage_position _triage_values = None @trellis.modifier def action(self, selection): for app_entry in selection: old_value = app_entry.event_reminder_combined rlist = ReminderList(app_entry._item) if old_value == 'reminder': rlist.remove_all_reminders() else: trigger = getNow() if trigger.hour < 17: hour = 17 else: trigger += timedelta(days=1) hour = 8 trigger = trigger.replace(hour=hour, minute=0, second=0, microsecond=0) reminder = rlist.add_reminder() reminder.fixed_trigger = trigger
class TranslatableChoices(trellis.Component): keys = trellis.attr() translations = trellis.attr() @trellis.maintain def values(self): return [(k,self.translations[k]) for k in self.keys]
class ModelChoiceSync(trellis.Component): listener = trellis.attr() model = trellis.attr() @trellis.maintain def selection(self): self.model.selection = self.listener.value
class ChoiceModelSync(trellis.Component): view = trellis.attr() model = trellis.attr() listener = trellis.attr() @trellis.perform def update(self): try: # print 'syncing', self.model.enabled, self.model.selection, self.values[:] with self.view.Frozen(): self.view.Enabled = self.model.enabled self.view.Items = [val[1] for val in self.model.values] self.view.SetSelection(self.model.selection) #hack a size(?) event, roughly equivalent to the C function # implementation of UpdateVisibleHeight() #forces the list to not have a scrollbar (at least when going # from 4 to 5 items) self.view.Size = self.view.Size except Exception: if not wx.IsDestroyed(self.view): raise @trellis.maintain def selection(self): self.listener.value = self.model.selection
class PrefLink(trellis.Component): prefname = trellis.attr() value = trellis.attr() @trellis.make def init_value(self): def on_value_changed(src, attr, old, new): import wx @wx.CallAfter def update(): self.value = new from common import profile profile.prefs.add_observer(on_value_changed, self.prefname, obj = self) return self.value def go(self): return self.go or self.value != self.init_value go = trellis.maintain(go, initially=False) @trellis.perform def output_pref(self): if self.go: from gui.pref.prefcontrols import mark_pref if get_pref(self.prefname) != self.value: mark_pref(self.prefname, self.value)
class reset_check_AdvWatcher(trellis.Component): model = trellis.attr(None) view = trellis.attr(None) @trellis.perform def sync(self): selection = self.model.selection self.view.Check(selection > 0)
class Buddy(trellis.Component): name = trellis.attr() status = trellis.attr() status_msg = trellis.attr() log_size = trellis.attr() service = trellis.attr() def __repr__(self): return '<Buddy name:%(name)s, status:%(status)6s, status_msg:%(status_msg)8s, log_size:%(log_size)05d, service:%(service)s>' % \ dict((a,getattr(self, a)) for a in 'name status status_msg log_size service'.split())
class reset_checks_SortOptionWatcher(trellis.Component): model = trellis.attr(None) names = trellis.attr(None) view = trellis.attr(None) @trellis.perform def sync(self): model_keys = [v[0] for v in self.model.values] selection = self.model.selection for i, item in enumerate(self.view): if i < len(self.names): val_key = self.names[i][0] item.Check(val_key == model_keys[selection]) item.Enable(val_key in model_keys)
class SortOptionWatcher(trellis.Component): model = trellis.attr(None) @trellis.perform def print_selection(self): if self.model is not None: print 'selected', self.model.selection
class TimeZone(trellis.Component, context.Service): default = trellis.attr(ICUtzinfo.default) @trellis.perform def save_default(self): ICUtzinfo.setDefault(self.default) class _FloatingTZInfo(ICUtzinfo): def __init__(self): pass def utcoffset(self, dt): return TimeZone.default.utcoffset(dt) def dst(self, dt): return TimeZone.default.dst(dt) def __repr__(self): return "FloatingTZ(%r)" % (TimeZone.default,) floating = _FloatingTZInfo() def __getitem__(self, key): result = ICUtzinfo.getInstance(key) if result.tzid == 'GMT' and key != 'GMT': return None else: return result ### Helper constants pacific = ICUtzinfo.getInstance("US/Pacific") eastern = ICUtzinfo.getInstance("US/Eastern") utc = ICUtzinfo.getInstance("UTC")
class Viewer(trellis.Component): model = trellis.attr(None) @trellis.perform def view_it(self): if self.model is not None: pprint(list(self.model))
class watch(trellis.Component): w= trellis.attr() @trellis.perform def foo(self): print 'service:', self.w.service print 'status:', self.w.status print 'service_choices:', self.w.service_choices print 'status_choices:', self.w.status_choices
class Node(trellis.Component): title = trellis.attr("") def __repr__(self): return "<%s(%s)>" % (type(self).__name__, self.title) children = Many() parent = One(inverse=children)
class CheckModelSync(trellis.Component): view = trellis.attr() model = trellis.attr() listener = trellis.attr() @trellis.perform def update(self): try: with self.view.Frozen(): self.view.Enabled = self.model.enabled self.view.Value = self.model.checked except Exception: if not wx.IsDestroyed(self.view): raise @trellis.maintain def state(self): self.listener.value = self.model.checked
class Viewer(trellis.Component): """ A utility class, usually used to observe changes to a cell during doctests. This should probably eventually move to a Chandler-Debug plugin. """ component = trellis.attr(None) cell_name = trellis.attr(None) @trellis.compute def formatted_name(self): return self.cell_name @trellis.perform def view_it(self): value = getattr(self.component, self.cell_name, None) if None not in (self.component, self.cell_name, value): print "%s changed to: %s" % (self.formatted_name, value)
class Scheduled(trellis.Component): fire_date = trellis.attr(datetime.min.replace(tzinfo=TimeZone.floating)) callback = trellis.attr(lambda reminder: None) @trellis.compute def _when_to_fire(self): # We want to convert fire_date into an activity.Time object. # To do that, subtract from datetime.now delta_seconds = timestamp(self.fire_date) - nowTimestamp() if delta_seconds >= 0: return activity.Time[delta_seconds] else: return False @trellis.perform # @@@ can't be a perform because we don't know if # callback modifies the trellis or not def fire(self): if self._when_to_fire: self.callback(self)
class Merger(trellis.Component): input = trellis.make(list) key = trellis.attr() #attrgetter('name') @trellis.maintain def output(self): if len(self.input) > 1: return reduce(lambda *a, **k: merge(*a, **dict(key=self.key)), self.input) elif len(self.input): return self.input[0] else: return []
class Selection(trellis.Component): value = trellis.attr() choices = trellis.attr() selection = trellis.attr(None) enabled = trellis.attr() @trellis.maintain def last_set_selection(self): if self.selection is None: # print '--initialize', self.current_selection self.selection = self.current_selection return self.current_selection if self.current_selection == self.selection: # print '--match ext', self.selection return self.current_selection if self.current_selection == self.last_set_selection: # print '--match int' if self.selection >= 0: # print '--set int',self.selection self.current_selection = self.selection self.set_value(self.selection) return self.selection if self.selection == self.last_set_selection: # print '--set ext', self.current_selection self.selection = self.current_selection return self.current_selection # print '--returning', self.current_selection return self.current_selection @trellis.maintain def current_selection(self): if not self.enabled: return -1 if self.value in self.choices: return self.choices.index(self.value) return -1 def set_value(self, pos): self.value = self.choices[pos]
class Splitter(trellis.Component): input = trellis.make(list) basesort = trellis.attr() #NameSorter spliton = trellis.attr() #attrgetter('status') @trellis.maintain def output(self): # print "partitions running" if not self.input: return {} ret = dict() for b in self.input: stat = self.spliton(b) if stat not in ret: ret[stat] = n = self.basesort() else: n = ret[stat] n.input.append(b) # print len(ret), "partitions" return ret
class CV(trellis.Component): v = trellis.attr(False) s = trellis.make(trellis.Set, name='s') @trellis.maintain def maintain(self): if self.v: self.s.add(1) else: self.s.discard(1) @trellis.perform def perform(s): self.assertEqual(s.v, True)
class AppColumn(core.TableColumn): app_attr = trellis.attr(None) def __repr__(self): return '<%s "%s" (%s)>' % (self.__class__.__name__, self.label, self.app_attr) def get_value(self, entry): return getattr(entry, self.app_attr) @trellis.compute def bitmap(self): name = self.hints.get('header_icon') if name: return image.get_image(name, "Chandler_App") else: return None
class record_changes(trellis.Component): target = trellis.attr(None) def __init__(self, target): self.changes = [] trellis.Component.__init__(self, target=target) @trellis.perform def watch_target(self): self.changes.append((set(self.target), set(self.target.added), set(self.target.removed))) def __enter__(self): self.changes[:] = [] return self def __exit__(self, exc_type, exc_val, exc_tb): return False
class NoAccountEnabledCheckSync(trellis.Component): created_account = trellis.attr(False) def __init__(self, provider, component, check): super(NoAccountEnabledCheckSync, self).__init__() self.model = CheckModel() self.provider = provider self.component = component self.view_model = CheckSync(model = self.model, view = check) @trellis.maintain def update(self): if not self.model.value: return if self.created_account: return self.created_account = True # create account object, put it in the account manager acct = self.provider.get_component(self.component.type) profile.account_manager.add(acct, self.component.type[:2], ignore_on_rebuild=True) self.acct_to_model = EnabledAccountSync(model = self.model, view = acct)
class _Keyword(Entity): word = trellis.attr() items = trellis.make(trellis.Set) def __init__(self, word, **kwds): self.word = word super(_Keyword, self).__init__(**kwds) def __repr__(self): return "<Keyword: %s>" % self.word def add(self, item): ItemKeywords(item).keyword_strings.add(self.word) def remove(self, item): ItemKeywords(item).keyword_strings.remove(self.word) @trellis.compute def title(self): return "Tag: %s" % self.word @trellis.compute def well_known_name(self): return KEYWORD_PREFIX + self.word
except StopIteration, TypeError: pass # i.e. return None return self.selected_item def get_cell_value(self, (row, col)): """Get value at (row, col) in the table""" self.items.changes # introduce dependency?!?! try: item = self.items[row] column = self.columns[col] except IndexError: return None else: return column.get_value(item) visible_range_increments = trellis.attr(resetting_to=(0, 0, 0, 0)) @trellis.maintain(initially=(0, 0, 0, 0)) def visible_ranges(self): visible_ranges = tuple(old + delta for old, delta in zip(self.visible_ranges, self.visible_range_increments)) if self.visible_ranges != visible_ranges: self.set_visible_ranges(visible_ranges) return visible_ranges @trellis.make def observer(self): return collections.Observing(lookup_func=self.get_cell_value) @trellis.modifier def set_visible_ranges(self, (start_row, end_row, start_col, end_col)): keys = self.observer.keys
class ChoiceModel(trellis.Component): values = trellis.attr([]) selection = trellis.attr(0) enabled = trellis.attr(True)
class OptionLink(trellis.Component): parent = trellis.attr() this = trellis.attr() child = trellis.attr() dependant = trellis.attr(True) name = trellis.attr() @trellis.maintain def selected_val(self): try: return self.this.values[self.this.selection] except Exception: pass @trellis.make def orig_values(self): return self.this.values[:] @trellis.maintain def available_options(self): newvals = [ val for val in self.orig_values if val not in self.parent_vals or val[0] == 'none' ] return newvals @trellis.maintain def parent_vals(self): c = self parent_vals = [] while c.parent is not None: if c.parent.selected_val is not None: parent_vals.append(c.parent.selected_val) c = c.parent return parent_vals @trellis.maintain def enabled(self): if not self.dependant: return True if not self.parent: return True if not self.parent.enabled: return False if self.parent.selected_val is None or self.parent.selected_val[0] in [ 'none', 'name' ]: return False return True @trellis.maintain def keepenabled(self): self.this.enabled = self.enabled @trellis.maintain def sync_values(self): newvals = self.available_options if not self.enabled: self.this.selection = -1 self.this.values = [] return if self.this.selection > 0 and self.this.values and newvals: oldval = self.this.values[self.this.selection] if oldval in newvals: self.this.selection = newvals.index(oldval) else: self.this.selection = 0 elif not newvals: self.this.selection = -1 else: self.this.selection = 0 self.this.values = newvals
def _change_set(s, contents): s.clear() s.update(contents) single_item_selection = trellis.attr(True)
class CheckModel(trellis.Component): checked = trellis.attr(False) enabled = trellis.attr(True)
class ViewListenerModelSync(ListenerModelSync): view = trellis.attr()