예제 #1
0
class Observer(trellis.Component):
    observee = trellis.make(trellis.Set, writable=True)
    observations = trellis.make(list)

    @trellis.perform
    def observer(self):
        def map(iterable):
            return sorted(x.value for x in iterable)

        self.observations.append(map(self.observee))
        if self.observee.added:
            self.observations.append(("added", map(self.observee.added)))
        if self.observee.removed:
            self.observations.append(("removed", map(self.observee.removed)))
예제 #2
0
class NameSorter(trellis.Component):

    input = trellis.make(list)

    @trellis.maintain(optional=True)
    def output(self):
        #        print 'name output running', id(self)
        return sorted(self.input, key=lambda x: x.name)
예제 #3
0
class ReminderList(ItemAddOn):
    reminders = trellis.make(trellis.List)

    def add_reminder(self, **kwargs):
        reminder = Reminder(item=self._item, **kwargs)
        self.reminders.append(reminder)
        return reminder

    def remove_all_reminders(self):
        self.reminders[:] = []
예제 #4
0
파일: keyword.py 프로젝트: ra2003/chandler2
class ItemKeywords(ItemAddOn):
    keyword_strings = trellis.make(trellis.Set)

    @trellis.maintain
    def maintenance(self):
        """Observe keyword_strings, maintain inverse links from Keyword objects."""
        for word in self.keyword_strings.added:
            Keyword(word).items.add(self._item)
        for word in self.keyword_strings.removed:
            Keyword(word).items.remove(self._item)
예제 #5
0
파일: main.py 프로젝트: ra2003/chandler2
class ChandlerFrame(core.Frame):
    model = trellis.make(trellis.Set, writable=True)

    @trellis.maintain
    def sidebar(self):
        return sidebar.Sidebar(scope=self, model=self.model)

    @trellis.maintain
    def dashboard(self):
        return dashboard.Dashboard(scope=self, model=dashboard.AppEntryAggregate(input=self.sidebar.filtered_items))
예제 #6
0
class Sum(trellis.Component):
    sortfunc = lambda self, x: x
    input = trellis.make(dict)

    @trellis.maintain
    def output(self):
        return sum([
            self.input[k].output
            for k in sorted(self.input.keys(), key=self.sortfunc)
        ], [])
예제 #7
0
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 []
예제 #8
0
class DJoiner(trellis.Component):
    input = trellis.make(list)

    @trellis.maintain
    def output(self):
        d = defaultdict(list)
        for splitter in self.input:
            o = splitter.output
            for key, val in o.iteritems():
                d[key].append(val.output)
        for k, v in d.iteritems():
            d[k] = Merger(input=v, key=attrgetter('name'))
        return dict(d)
예제 #9
0
        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)
예제 #10
0
class ModificationRecipe(trellis.Component):
    # a dictionary of (AddOn, attr_name) keys, values override master
    changes = trellis.make(trellis.Dict)

    @trellis.modifier
    def make_change(self, add_on, name, value):
        key = (add_on, name)
        self.changes[key] = value

    @trellis.modifier
    def remove_change(self, add_on, name):
        key = (add_on, name)
        if key in self.changes:
            del self.changes[key]
예제 #11
0
파일: eim.py 프로젝트: ra2003/chandler2
class EIM(Extension):
    uuid = trellis.make(lambda x: uuid4())
    well_known_name = trellis.compute(lambda self: self._well_known_name)
    trellis.attrs(
        _well_known_name=None,
        ical_uid=None,
        ical_extra=None,
    )

    @trellis.modifier
    def add(self, name=None, **kw):
        super(EIM, self).add(**kw)
        if name is None:
            name = getattr(self._item, 'well_known_name', None)
        if name is not None:
            self._well_known_name = name
            set_item_for_name(name, self.item)
        set_item_for_uuid(self.uuid, self.item)
        return self
예제 #12
0
파일: __init__.py 프로젝트: sgricci/digsby
class BindingValueListener(protocols.Adapter, trellis.Component):
    protocols.advise(asAdapterForProtocols=[IBindableValue],
                     instancesProvide=[IValueListener])

    def __init__(self, subject):
        protocols.Adapter.__init__(self, subject)
        trellis.Component.__init__(self)
        #        self.value_changed()
        self.subject.bind(self.value_changed)

    def value_changed(self):
        self.value = self.get_value()

    def get_value(self):
        return self.subject.value

    value = trellis.make(rule=get_value,
                         writable=True,
                         optional=True,
                         name='value')
예제 #13
0
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
예제 #14
0
파일: keyword.py 프로젝트: ra2003/chandler2
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
예제 #15
0
        class C2(trellis.Component):
            c1 = trellis.make(C1, name='c1')

            @trellis.compute
            def calc(self):
                return self.c1.x
예제 #16
0
파일: main.py 프로젝트: ra2003/chandler2
class ChandlerApplication(runtime.Application):
    """The Chandler Application"""
    context.replaces(runtime.Application)
    sidebar_entries = trellis.make(trellis.Set, writable=True)

    top_level = trellis.make(trellis.Set)
예제 #17
0
파일: table.py 프로젝트: ra2003/chandler2
class TablePresentation(trellis.Component, wxGrid.PyGridTableBase):
    table = trellis.make(core.Table, writable=True)

    @trellis.perform
    def update_column_selection(self):
        for index, column in enumerate(self.table.columns):
            if column is self.table.sort_column:
                show_arrows = column.hints.get('sort_arrows', True)
                self.View.SetSelectedCol(index)
                self.View.SetUseColSortArrows(show_arrows)
                self.View.SetColSortAscending(self.table.items.reverse)
                break

    @trellis.perform
    def update_grid(self):
        view = self.GetView()

        view.BeginBatch()
        for start, end, newLen in self.table.items.changes:
            oldLen = end - start
            if newLen == oldLen:
                view.ProcessTableMessage(
                    wxGrid.GridTableMessage(
                        self, wxGrid.GRIDTABLE_REQUEST_VIEW_GET_VALUES, start,
                        oldLen))
            elif newLen > oldLen:
                if oldLen > 0:
                    view.ProcessTableMessage(
                        wxGrid.GridTableMessage(
                            self, wxGrid.GRIDTABLE_REQUEST_VIEW_GET_VALUES,
                            start, oldLen))
                view.ProcessTableMessage(
                    wxGrid.GridTableMessage(
                        self, wxGrid.GRIDTABLE_NOTIFY_ROWS_INSERTED,
                        start + oldLen, newLen - oldLen))
            else:
                view.ProcessTableMessage(
                    wxGrid.GridTableMessage(
                        self, wxGrid.GRIDTABLE_NOTIFY_ROWS_DELETED,
                        start + newLen, oldLen - newLen))
                if newLen > 0:
                    view.ProcessTableMessage(
                        wxGrid.GridTableMessage(
                            self, wxGrid.GRIDTABLE_REQUEST_VIEW_GET_VALUES,
                            start, newLen))

        for key in self.table.observer.changes:
            row, col = key
            if row < len(self.table.model):
                view.ProcessTableMessage(
                    wxGrid.GridTableMessage(
                        self, wxGrid.GRIDTABLE_REQUEST_VIEW_GET_VALUES, row,
                        1))

        view.EndBatch()

        for row in view.GetSelectedRows():
            index = self.RowToIndex(row)
            if not self.table.items[index] in self.table.selection:
                trellis.on_commit(view.DeselectRow, row)

        for index, item in enumerate(self.table.items):
            row = self.IndexToRow(index)
            if item in self.table.selection:
                trellis.on_commit(view.SelectRow, row, True)

    defaultRWAttribute = wxGrid.GridCellAttr()
    defaultROAttribute = wxGrid.GridCellAttr()
    defaultROAttribute.SetReadOnly(True)

    def __init__(self, grid, **kw):
        wxGrid.PyGridTableBase.__init__(self)
        trellis.Component.__init__(self, **kw)

        grid.SetTable(self, selmode=wxGrid.Grid.SelectRows)
        self.SetView(grid)

        if self.table.hints.get('column_headers'):
            grid.SetColLabelSize(wxGrid.GRID_DEFAULT_COL_LABEL_HEIGHT)
        else:
            grid.SetColLabelSize(0)

        for index, column in enumerate(self.table.columns or ()):
            grid.SetColLabelValue(index, column.label)
            width = column.hints.get('width', 120)
            grid.SetColMinimalWidth(index, width)
            grid.SetColSize(index, width)

            if EXTENDED_WX:
                scaleColumn = grid.GRID_COLUMN_SCALABLE if column.hints.get(
                    'scalable') else grid.GRID_COLUMN_NON_SCALABLE
                grid.ScaleColumn(index, scaleColumn)

        grid.Bind(wxGrid.EVT_GRID_RANGE_SELECT, self.OnRangeSelect)
        grid.Bind(wxGrid.EVT_GRID_LABEL_LEFT_CLICK, self.OnLabelLeftClicked)
        grid.Bind(wx.EVT_SIZE, self.OnSize)
        grid.Bind(wx.EVT_SCROLLWIN, self.OnScroll)

    def GetNumberRows(self):
        return len(self.table.items)

    def GetNumberCols(self):
        return len(self.table.columns)

    def RowToIndex(self, row):
        return row

    def IndexToRow(self, index):
        return index

    def RangeToIndex(self, startRow, endRow):
        """
        Translasted a row range in the grid to a row range in the collection
        """
        return self.RowToIndex(startRow), self.RowToIndex(endRow)

    def IsEmptyCell(self, row, col):
        return False

    def CanClick(self, row, col):
        column = self.table.columns[col]
        return column.action is not None

    def OnClick(self, row, col):
        selection = [self.table.items[self.RowToIndex(row)]]
        self.table.columns[col].action(selection)

    def TrackMouse(self, row, col):
        return True

    def GetToolTipString(self, row, col):
        pass

    def ReadOnly(self, row, col):
        return self.table.columns[col].set_text_value is None

    def GetValue(self, row, col):
        return self.table.get_cell_value((row, col))

    def SetValue(self, row, col, value):
        obj = self.table.items[self.RowToIndex(row)]
        self.table.columns[col].set_text_value(obj, value)

    def GetColLabelValue(self, col):
        return self.table.columns[col].label

    def GetColLabelBitmap(self, col):
        return getattr(self.table.columns[col], 'bitmap', None)

    _deselected_all = False

    def OnSize(self, event):
        event.Skip()
        # We have to do this because wx will send EVT_SIZE events from
        # other calls (e.g. View.EndBatch() in our performer)
        wx.CallAfter(self._update_visible)

    def OnScroll(self, event):
        event.Skip()
        wx.CallAfter(self._update_visible)

    @trellis.modifier
    def _update_visible(self):
        # We need the check on self.View because we call
        # this with a wx.CallAfter, and that call will proceed
        # even if the View has been torn down.
        if self.View:
            rect = self.View.GetClientRect()
            if rect.Height > 0 and rect.Width > 0:
                x, y = self.View.CalcUnscrolledPosition(rect.X, rect.Y)
                start_row = max(self.View.YToRow(y), 0)
                start_col = max(self.View.XToCol(x), 0)

                x, y = self.View.CalcUnscrolledPosition(
                    rect.Right, rect.Bottom)
                end_row = self.View.YToRow(y)
                end_col = self.View.XToCol(x)

                if end_row < 0: end_row = len(self.table.model)
                if end_col < 0: end_col = len(self.table.columns)

                vr = self.table.visible_ranges
                increments = (start_row - vr[0], (end_row - start_row) - vr[1],
                              start_col - vr[2], (end_col - start_col) - vr[3])

                self.table.visible_range_increments = increments

    def OnRangeSelect(self, event):
        """
        Synchronize the grid's selection back into the Table
        """
        firstRow = event.TopRow
        lastRow = event.BottomRow
        indexStart, indexEnd = self.RangeToIndex(firstRow, lastRow)
        selecting = event.Selecting()

        if (not selecting and firstRow == 0 and lastRow != 0
                and lastRow == self.GetNumberRows() - 1):
            # this is a special "deselection" event that the
            # grid sends us just before selecting another
            # single item. This happens just before a user
            # simply clicks from one item to another.
            self._deselected_all = True

            # [@@@] grant: Need to avoid broadcasting a
            # selection change in this case.
            event.Skip()
            return

        if selecting and self.table.single_item_selection:
            new_selection = self.table.items[indexEnd]
            if self.table.selected_item != new_selection:
                self.table.selected_item = new_selection
        else:
            items = set(self.table.items[index]
                        for index in xrange(indexStart, indexEnd + 1))

            if selecting:
                if self._deselected_all:
                    self.table.new_selection = items
                else:
                    items.difference_update(self.table.selection)
                    self.table.selection.update(items)
            else:
                self.table.selection.difference_update(items)

        if self._deselected_all:
            del self._deselected_all

        event.Skip()

    def SelectedRowRanges(self):
        # @@@ [grant] Move this (or something similar) to Table
        """
        Uses IndexRangeToRowRange to convert the selected indexes to
        selected rows
        """
        lastRow = None
        # This is O(N) tsk
        for index, item in enumerate(self.table.items):
            itemSelected = (item in self.table.selection)

            if itemSelected:
                if lastRow is None:
                    lastRow = self.IndexToRow(index)
                else:
                    pass
            elif lastRow is not None:
                yield lastRow, self.IndexToRow(index - 1)
                lastRow = None

        if lastRow is not None:
            yield lastRow, self.IndexToRow(len(self.table.items) - 1)

    def OnLabelLeftClicked(self, event):
        assert (event.GetRow() == -1
                )  # Currently Table only supports column headers
        column = self.table.columns[event.GetCol()]
        # A "receiver" style cell: it will take care of toggling
        # the sort, etc.
        self.table.select_column = column

    def GetTypeName(self, row, column):
        return self.table.columns[column].hints.get('type', 'String')

    def GetAttr(self, row, column, kind):
        attribute = super(TablePresentation, self).GetAttr(row, column, kind)
        if attribute is None:
            attribute = self.defaultROAttribute
            grid = self.GetView()

            if (not self.table.columns[column].hints.get('readonly', False)
                    and not self.ReadOnly(row, column)):
                attribute = self.defaultRWAttribute
            attribute.IncRef()
        return attribute