diff options
author | Patrick Totzke <patricktotzke@gmail.com> | 2011-10-13 14:36:56 +0100 |
---|---|---|
committer | Patrick Totzke <patricktotzke@gmail.com> | 2011-10-13 14:36:56 +0100 |
commit | 765fa19c38e5f5c9c60d8046bb6120b9fcdc7a79 (patch) | |
tree | ea14f04e59456bcfb9338fedf0ca484ad55d90d5 /alot/buffers.py | |
parent | c97102f22c1d19f0e67af878e720710a4cc592ae (diff) |
fix imports
Diffstat (limited to 'alot/buffers.py')
-rw-r--r-- | alot/buffers.py | 287 |
1 files changed, 287 insertions, 0 deletions
diff --git a/alot/buffers.py b/alot/buffers.py new file mode 100644 index 00000000..57fe9ecb --- /dev/null +++ b/alot/buffers.py @@ -0,0 +1,287 @@ +""" +This file is part of alot. + +Alot is free software: you can redistribute it and/or modify it +under the terms of the GNU General Public License as published by the +Free Software Foundation, either version 3 of the License, or (at your +option) any later version. + +Notmuch is distributed in the hope that it will be useful, but WITHOUT +ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License +for more details. + +You should have received a copy of the GNU General Public License +along with notmuch. If not, see <http://www.gnu.org/licenses/>. + +Copyright (C) 2011 Patrick Totzke <patricktotzke@gmail.com> +""" +import urwid +from notmuch.globals import NotmuchError + + +import widgets +import settings +import commands +from walker import IteratorWalker +from message import decode_header + + +class Buffer(object): + def __init__(self, ui, widget, name): + self.ui = ui + self.typename = name + self.body = widget + + def __str__(self): + return self.typename + + def render(self, size, focus=False): + return self.body.render(size, focus) + + def selectable(self): + return self.body.selectable() + + def rebuild(self): + pass + + def apply_command(self, cmd): + # call and store it directly for a local cmd history + self.ui.apply_command(cmd) + + def keypress(self, size, key): + return self.body.keypress(size, key) + + +class BufferlistBuffer(Buffer): + def __init__(self, ui, filtfun=None): + self.filtfun = filtfun + self.ui = ui + self.isinitialized = False + self.rebuild() + Buffer.__init__(self, ui, self.body, 'bufferlist') + + def index_of(self, b): + return self.ui.buffers.index(b) + + def rebuild(self): + if self.isinitialized: + focusposition = self.bufferlist.get_focus()[1] + else: + focusposition = 0 + self.isinitialized = True + + lines = list() + displayedbuffers = filter(self.filtfun, self.ui.buffers) + for (num, b) in enumerate(displayedbuffers): + line = widgets.BufferlineWidget(b) + if (num % 2) == 0: + attr = 'bufferlist_results_even' + else: + attr = 'bufferlist_results_odd' + buf = urwid.AttrMap(line, attr, 'bufferlist_focus') + num = urwid.Text('%3d:' % self.index_of(b)) + lines.append(urwid.Columns([('fixed', 4, num), buf])) + self.bufferlist = urwid.ListBox(urwid.SimpleListWalker(lines)) + self.bufferlist.set_focus(focusposition % len(displayedbuffers)) + self.body = self.bufferlist + + def get_selected_buffer(self): + (linewidget, pos) = self.bufferlist.get_focus() + bufferlinewidget = linewidget.get_focus().original_widget + return bufferlinewidget.get_buffer() + + +class EnvelopeBuffer(Buffer): + def __init__(self, ui, mail): + self.ui = ui + self.mail = mail + self.rebuild() + Buffer.__init__(self, ui, self.body, 'envelope') + + def __str__(self): + return "to: %s" % decode_header(self.mail['To']) + + def get_email(self): + return self.mail + + def set_email(self, mail): + self.mail = mail + self.rebuild() + + def rebuild(self): + displayed_widgets = [] + dh = settings.config.getstringlist('general', 'displayed_headers') + self.header_wgt = widgets.MessageHeaderWidget(self.mail, + displayed_headers=dh) + displayed_widgets.append(self.header_wgt) + + #display attachments + lines = [] + for part in self.mail.walk(): + if not part.is_multipart(): + if part.get_content_maintype() != 'text': + lines.append(widgets.AttachmentWidget(part, + selectable=False)) + self.attachment_wgt = urwid.Pile(lines) + displayed_widgets.append(self.attachment_wgt) + + self.body_wgt = widgets.MessageBodyWidget(self.mail) + displayed_widgets.append(self.body_wgt) + self.body = urwid.ListBox(displayed_widgets) + + +class SearchBuffer(Buffer): + threads = [] + + def __init__(self, ui, initialquery=''): + self.dbman = ui.dbman + self.ui = ui + self.querystring = initialquery + self.result_count = 0 + self.isinitialized = False + self.rebuild() + Buffer.__init__(self, ui, self.body, 'search') + + def __str__(self): + return '%s (%d threads)' % (self.querystring, self.result_count) + + def rebuild(self): + if self.isinitialized: + pass + #focusposition = self.threadlist.get_focus()[1] + else: + #focusposition = 0 + self.isinitialized = True + + self.result_count = self.dbman.count_messages(self.querystring) + try: + self.tids = self.dbman.search_thread_ids(self.querystring) + except NotmuchError: + self.ui.notify('malformed query string: %s' % self.querystring, + 'error') + self.tids = [] + self.threadlist = IteratorWalker(iter(self.tids), + widgets.ThreadlineWidget, + dbman=self.dbman) + self.listbox = urwid.ListBox(self.threadlist) + #self.threadlist.set_focus(focusposition) + self.body = self.listbox + + def debug(self): + self.ui.logger.debug(self.threadlist.lines) + + def get_selected_threadline(self): + (threadlinewidget, size) = self.threadlist.get_focus() + return threadlinewidget + + def get_selected_thread(self): + threadlinewidget = self.get_selected_threadline() + thread = None + if threadlinewidget: + thread = threadlinewidget.get_thread() + return thread + + +class ThreadBuffer(Buffer): + def __init__(self, ui, thread): + self.message_count = thread.get_total_messages() + self.thread = thread + self.rebuild() + Buffer.__init__(self, ui, self.body, 'thread') + + def __str__(self): + return '%s, (%d)' % (self.thread.get_subject(), self.message_count) + + def get_selected_thread(self): + return self.thread + + def _build_pile(self, acc, msg, parent, depth): + acc.append((parent, depth, msg)) + for reply in self.thread.get_replies_to(msg): + self._build_pile(acc, reply, msg, depth + 1) + + def rebuild(self): + self.thread.refresh() + # depth-first traversing the thread-tree, thereby + # 1) build a list of tuples (parentmsg, depth, message) in DF order + # 2) create a dict that counts no. of direct replies per message + messages = list() # accumulator for 1, + childcount = {None: 0} # accumulator for 2) + for msg, replies in self.thread.get_messages().items(): + childcount[msg] = len(replies) + # start with all toplevel msgs, then recursively call _build_pile + for msg in self.thread.get_toplevel_messages(): + self._build_pile(messages, msg, None, 0) + childcount[None] += 1 + + # go through list from 1) and pile up message widgets for all msgs. + # each one will be given its depth, if siblings follow and where to + # draw bars (siblings follow at lower depths) + msglines = list() + bars = [] + for (num, (p, depth, m)) in enumerate(messages): + bars = bars[:depth] + childcount[p] -= 1 + + bars.append(childcount[p] > 0) + mwidget = widgets.MessageWidget(m, even=(num % 2 == 0), + depth=depth, + bars_at=bars) + msglines.append(mwidget) + self.body = urwid.ListBox(msglines) + + def get_selection(self): + (messagewidget, size) = self.body.get_focus() + return messagewidget + + def get_selected_message(self): + messagewidget = self.get_selection() + return messagewidget.get_message() + + def get_message_widgets(self): + return self.body.body.contents + + def get_focus(self): + return self.body.get_focus() + + def unfold_matching(self, querystring): + for mw in self.get_message_widgets(): + msg = mw.get_message() + if msg.matches(querystring): + mw.fold(visible=True) + if 'unread' in msg.get_tags(): + msg.remove_tags(['unread']) + self.ui.apply_command(commands.globals.FlushCommand()) + + +class TagListBuffer(Buffer): + def __init__(self, ui, alltags=[], filtfun=None): + self.filtfun = filtfun + self.ui = ui + self.tags = alltags + self.isinitialized = False + self.rebuild() + Buffer.__init__(self, ui, self.body, 'taglist') + + def rebuild(self): + if self.isinitialized: + focusposition = self.taglist.get_focus()[1] + else: + focusposition = 0 + self.isinitialized = True + + lines = list() + displayedtags = filter(self.filtfun, self.tags) + for (num, b) in enumerate(displayedtags): + tw = widgets.TagWidget(b) + lines.append(urwid.Columns([('fixed', tw.width(), tw)])) + self.taglist = urwid.ListBox(urwid.SimpleListWalker(lines)) + self.body = self.taglist + + self.taglist.set_focus(focusposition % len(displayedtags)) + + def get_selected_tag(self): + (cols, pos) = self.taglist.get_focus() + tagwidget = cols.get_focus() + return tagwidget.get_tag() |