def __init__(self, message, even=True): """ :param message: a message :type message: alot.db.Message :param even: even entry in a pile of messages? Used for theming. :type even: bool """ self.message = message self.even = even if even: attr = settings.get_theming_attribute('thread', 'summary', 'even') else: attr = settings.get_theming_attribute('thread', 'summary', 'odd') focus_att = settings.get_theming_attribute('thread', 'summary', 'focus') cols = [] sumstr = self.__str__() txt = urwid.Text(sumstr) cols.append(txt) thread_tags = message.get_thread().get_tags(intersection=True) outstanding_tags = set(message.get_tags()).difference(thread_tags) tag_widgets = [TagWidget(t, attr, focus_att) for t in outstanding_tags] tag_widgets.sort(tag_cmp, lambda tag_widget: tag_widget.translated) for tag_widget in tag_widgets: if not tag_widget.hidden: cols.append(('fixed', tag_widget.width(), tag_widget)) line = urwid.AttrMap(urwid.Columns(cols, dividechars=1), attr, focus_att) urwid.WidgetWrap.__init__(self, line)
def apply(self, ui): logging.debug('HELP') if self.commandname == 'bindings': text_att = settings.get_theming_attribute('help', 'text') title_att = settings.get_theming_attribute('help', 'title') section_att = settings.get_theming_attribute('help', 'section') # get mappings if ui.mode in settings._bindings: modemaps = dict(settings._bindings[ui.mode].items()) else: modemaps = {} is_scalar = lambda (k, v): k in settings._bindings.scalars globalmaps = dict(filter(is_scalar, settings._bindings.items())) # build table maxkeylength = len(max((modemaps).keys() + globalmaps.keys(), key=len)) keycolumnwidth = maxkeylength + 2 linewidgets = [] # mode specific maps if modemaps: linewidgets.append(urwid.Text((section_att, '\n%s-mode specific maps' % ui.mode))) for (k, v) in modemaps.items(): line = urwid.Columns([('fixed', keycolumnwidth, urwid.Text((text_att, k))), urwid.Text((text_att, v))]) linewidgets.append(line) # global maps linewidgets.append(urwid.Text((section_att, '\nglobal maps'))) for (k, v) in globalmaps.items(): if k not in modemaps: line = urwid.Columns( [('fixed', keycolumnwidth, urwid.Text((text_att, k))), urwid.Text((text_att, v))]) linewidgets.append(line) body = urwid.ListBox(linewidgets) ckey = 'cancel' titletext = 'Bindings Help (%s cancels)' % ckey box = widgets.DialogBox(body, titletext, bodyattr=text_att, titleattr=title_att) # put promptwidget as overlay on main widget overlay = urwid.Overlay(box, ui.mainframe, 'center', ('relative', 70), 'middle', ('relative', 70)) ui.show_as_root_until_keypress(overlay, 'cancel') else: logging.debug('HELP %s' % self.commandname) parser = commands.lookup_parser(self.commandname, ui.mode) if parser: ui.notify(parser.format_help(), block=True) else: ui.notify('command not known: %s' % self.commandname, priority='error')
def _get_source(self): if self._sourcetree is None: sourcetxt = self._message.get_email().as_string() att = settings.get_theming_attribute('thread', 'body') att_focus = settings.get_theming_attribute('thread', 'body_focus') self._sourcetree = TextlinesList(sourcetxt, att, att_focus) return self._sourcetree
def apply(self, ui): logging.debug('HELP') if self.commandname == 'bindings': text_att = settings.get_theming_attribute('help', 'text') title_att = settings.get_theming_attribute('help', 'title') section_att = settings.get_theming_attribute('help', 'section') # get mappings if ui.mode in settings._bindings: modemaps = dict(settings._bindings[ui.mode].items()) else: modemaps = {} is_scalar = lambda (k, v): k in settings._bindings.scalars globalmaps = dict(filter(is_scalar, settings._bindings.items())) # build table maxkeylength = len( max((modemaps).keys() + globalmaps.keys(), key=len)) keycolumnwidth = maxkeylength + 2 linewidgets = [] # mode specific maps if modemaps: txt = (section_att, '\n%s-mode specific maps' % ui.mode) linewidgets.append(urwid.Text(txt)) for (k, v) in modemaps.items(): line = urwid.Columns([('fixed', keycolumnwidth, urwid.Text((text_att, k))), urwid.Text((text_att, v))]) linewidgets.append(line) # global maps linewidgets.append(urwid.Text((section_att, '\nglobal maps'))) for (k, v) in globalmaps.items(): if k not in modemaps: line = urwid.Columns([('fixed', keycolumnwidth, urwid.Text((text_att, k))), urwid.Text((text_att, v))]) linewidgets.append(line) body = urwid.ListBox(linewidgets) titletext = 'Bindings Help (escape cancels)' box = DialogBox(body, titletext, bodyattr=text_att, titleattr=title_att) # put promptwidget as overlay on main widget overlay = urwid.Overlay(box, ui.root_widget, 'center', ('relative', 70), 'middle', ('relative', 70)) ui.show_as_root_until_keypress(overlay, 'esc') else: logging.debug('HELP %s' % self.commandname) parser = commands.lookup_parser(self.commandname, ui.mode) if parser: ui.notify(parser.format_help(), block=True) else: ui.notify('command not known: %s' % self.commandname, priority='error')
def construct_header_pile(self, headers=None, normalize=True): mail = self._message.get_email() if headers is None: headers = mail.keys() else: headers = [k for k in headers if k.lower() == 'tags' or k in mail] lines = [] for key in headers: if key in mail: if key.lower() in ['cc', 'bcc', 'to']: values = mail.get_all(key) values = [decode_header( v, normalize=normalize) for v in values] lines.append((key, ', '.join(values))) else: for value in mail.get_all(key): dvalue = decode_header(value, normalize=normalize) lines.append((key, dvalue)) elif key.lower() == 'tags': logging.debug('want tags header') values = [] for t in self._message.get_tags(): tagrep = settings.get_tagstring_representation(t) if t is not tagrep['translated']: t = '%s (%s)' % (tagrep['translated'], t) values.append(t) lines.append((key, ', '.join(values))) key_att = settings.get_theming_attribute('thread', 'header_key') value_att = settings.get_theming_attribute('thread', 'header_value') gaps_att = settings.get_theming_attribute('thread', 'header') return DictList(lines, key_att, value_att, gaps_att)
def __init__(self, message, even=False, folded=True, raw=False, all_headers=False, depth=0, bars_at=[]): """ :param message: the message to display :type message: alot.db.Message :param even: use messagesummary_even theme for summary :type even: bool :param folded: fold message initially :type folded: bool :param raw: show message source initially :type raw: bool :param all_headers: show all headers initially :type all_headers: bool :param depth: number of characters to shift content to the right :type depth: int :param bars_at: defines for each column of the indentation whether to use a vertical bar instead of a space. :type bars_at: list(bool) """ self.message = message self.mail = self.message.get_email() self.depth = depth self.bars_at = bars_at self.even = even self.folded = folded self.show_raw = raw self.show_all_headers = all_headers # define subwidgets that will be created on demand self.sumline = None self.headerw = None self.attachmentw = None self.bodyw = None self.sourcew = None # set available and to be displayed headers self._all_headers = list(set(self.mail.keys())) displayed = settings.get('displayed_headers') self._filtered_headers = [ k for k in displayed if k.lower() == 'tags' or k in self.mail ] self._displayed_headers = None bars = settings.get_theming_attribute('thread', 'arrow_bars') self.arrow_bars_att = bars heads = settings.get_theming_attribute('thread', 'arrow_heads') self.arrow_heads_att = heads logging.debug(self.arrow_heads_att) self.rebuild() # this will build self.pile urwid.WidgetWrap.__init__(self, self.pile)
def _get_body(self): if self._bodytree is None: bodytxt = extract_body(self._message.get_email()) if bodytxt: att = settings.get_theming_attribute('thread', 'body') att_focus = settings.get_theming_attribute( 'thread', 'body_focus') self._bodytree = TextlinesList(bodytxt, att, att_focus) return self._bodytree
def __init__(self, attachment, selectable=True): self._selectable = selectable self.attachment = attachment if not isinstance(attachment, Attachment): self.attachment = Attachment(self.attachment) att = settings.get_theming_attribute('thread', 'attachment') focus_att = settings.get_theming_attribute('thread', 'attachment_focus') widget = urwid.AttrMap(urwid.Text(self.attachment.__str__()), att, focus_att) urwid.WidgetWrap.__init__(self, widget)
def apply(self, ui): logging.debug("HELP") if self.commandname == "bindings": text_att = settings.get_theming_attribute("help", "text") title_att = settings.get_theming_attribute("help", "title") section_att = settings.get_theming_attribute("help", "section") # get mappings if ui.mode in settings._bindings: modemaps = dict(settings._bindings[ui.mode].items()) else: modemaps = {} is_scalar = lambda k_v: k_v[0] in settings._bindings.scalars globalmaps = dict(filter(is_scalar, settings._bindings.items())) # build table maxkeylength = len(max((modemaps).keys() + globalmaps.keys(), key=len)) keycolumnwidth = maxkeylength + 2 linewidgets = [] # mode specific maps if modemaps: txt = (section_att, "\n%s-mode specific maps" % ui.mode) linewidgets.append(urwid.Text(txt)) for (k, v) in modemaps.items(): line = urwid.Columns( [("fixed", keycolumnwidth, urwid.Text((text_att, k))), urwid.Text((text_att, v))] ) linewidgets.append(line) # global maps linewidgets.append(urwid.Text((section_att, "\nglobal maps"))) for (k, v) in globalmaps.items(): if k not in modemaps: line = urwid.Columns( [("fixed", keycolumnwidth, urwid.Text((text_att, k))), urwid.Text((text_att, v))] ) linewidgets.append(line) body = urwid.ListBox(linewidgets) titletext = "Bindings Help (escape cancels)" box = DialogBox(body, titletext, bodyattr=text_att, titleattr=title_att) # put promptwidget as overlay on main widget overlay = urwid.Overlay(box, ui.root_widget, "center", ("relative", 70), "middle", ("relative", 70)) ui.show_as_root_until_keypress(overlay, "esc") else: logging.debug("HELP %s" % self.commandname) parser = commands.lookup_parser(self.commandname, ui.mode) if parser: ui.notify(parser.format_help(), block=True) else: ui.notify("command not known: %s" % self.commandname, priority="error")
def __init__(self, message, even=False, folded=True, raw=False, all_headers=False, depth=0, bars_at=[]): """ :param message: the message to display :type message: alot.db.Message :param even: use messagesummary_even theme for summary :type even: bool :param folded: fold message initially :type folded: bool :param raw: show message source initially :type raw: bool :param all_headers: show all headers initially :type all_headers: bool :param depth: number of characters to shift content to the right :type depth: int :param bars_at: defines for each column of the indentation whether to use a vertical bar instead of a space. :type bars_at: list(bool) """ self.message = message self.mail = self.message.get_email() self.depth = depth self.bars_at = bars_at self.even = even self.folded = folded self.show_raw = raw self.show_all_headers = all_headers # define subwidgets that will be created on demand self.sumline = None self.headerw = None self.attachmentw = None self.bodyw = None self.sourcew = None # set available and to be displayed headers self._all_headers = list(set(self.mail.keys())) displayed = settings.get('displayed_headers') self._filtered_headers = [k for k in displayed if k.lower() == 'tags' or k in self.mail] self._displayed_headers = None bars = settings.get_theming_attribute('thread', 'arrow_bars') self.arrow_bars_att = bars heads = settings.get_theming_attribute('thread', 'arrow_heads') self.arrow_heads_att = heads logging.debug(self.arrow_heads_att) self.rebuild() # this will build self.pile urwid.WidgetWrap.__init__(self, self.pile)
def _get_header_widget(self): """creates/returns the widget that displays the mail header""" all_shown = (self._all_headers == self._displayed_headers) if self.headerw and (self.show_all_headers == all_shown): return self.headerw if self.show_all_headers: self._displayed_headers = self._all_headers else: self._displayed_headers = self._filtered_headers mail = self.message.get_email() # normalize values if only filtered list is shown norm = not (self._displayed_headers == self._all_headers) #build lines lines = [] for key in self._displayed_headers: logging.debug('want header: %s' % (key)) if key in mail: if key.lower() in ['cc', 'bcc', 'to']: values = mail.get_all(key) values = [decode_header(v, normalize=norm) for v in values] lines.append((key, ', '.join(values))) else: for value in mail.get_all(key): dvalue = decode_header(value, normalize=norm) lines.append((key, dvalue)) elif key.lower() == 'tags': logging.debug('want tags header') values = [] for t in self.message.get_tags(): tagrep = settings.get_tagstring_representation(t) if t is not tagrep['translated']: t = '%s (%s)' % (tagrep['translated'], t) values.append(t) lines.append((key, ', '.join(values))) key_att = settings.get_theming_attribute('thread', 'header_key') value_att = settings.get_theming_attribute('thread', 'header_value') gaps_att = settings.get_theming_attribute('thread', 'header') cols = [HeadersList(lines, key_att, value_att, gaps_att)] bc = list() if self.depth: cols.insert(0, self._get_spacer(self.bars_at[1:])) bc.append(0) cols.insert(1, self._get_arrowhead_aligner()) bc.append(1) self.headerw = urwid.Columns(cols, box_columns=bc) return self.headerw
def _get_theme(self, component, focus=False): path = ['search', 'threadline', component] if focus: path.append('focus') else: path.append('normal') return settings.get_theming_attribute(path)
def __init__(self, headerslist, key_attr, value_attr): self.headers = headerslist self.key_attr = key_attr self.value_attr = value_attr pile = urwid.Pile(self._build_lines(headerslist)) att = settings.get_theming_attribute('thread', 'header') pile = urwid.AttrMap(pile, att) urwid.WidgetWrap.__init__(self, pile)
def construct_header_pile(self, headers=None, normalize=True): mail = self._message.get_email() lines = [] if headers is None: # collect all header/value pairs in the order they appear headers = mail.keys() for key, value in mail.items(): dvalue = decode_header(value, normalize=normalize) lines.append((key, dvalue)) else: # only a selection of headers should be displayed. # use order of the `headers` parameter for key in headers: if key in mail: if key.lower() in ['cc', 'bcc', 'to']: values = mail.get_all(key) values = [ decode_header(v, normalize=normalize) for v in values ] lines.append((key, ', '.join(values))) else: for value in mail.get_all(key): dvalue = decode_header(value, normalize=normalize) lines.append((key, dvalue)) elif key.lower() == 'tags': logging.debug('want tags header') values = [] for t in self._message.get_tags(): tagrep = settings.get_tagstring_representation(t) if t is not tagrep['translated']: t = '%s (%s)' % (tagrep['translated'], t) values.append(t) lines.append((key, ', '.join(values))) # OpenPGP pseudo headers if mail[X_SIGNATURE_MESSAGE_HEADER]: lines.append(('PGP-Signature', mail[X_SIGNATURE_MESSAGE_HEADER])) key_att = settings.get_theming_attribute('thread', 'header_key') value_att = settings.get_theming_attribute('thread', 'header_value') gaps_att = settings.get_theming_attribute('thread', 'header') return DictList(lines, key_att, value_att, gaps_att)
def construct_header_pile(self, headers=None, normalize=True): mail = self._message.get_email() lines = [] if headers is None: # collect all header/value pairs in the order they appear headers = list(mail.keys()) for key, value in list(mail.items()): dvalue = decode_header(value, normalize=normalize) lines.append((key, dvalue)) else: # only a selection of headers should be displayed. # use order of the `headers` parameter for key in headers: if key in mail: if key.lower() in ['cc', 'bcc', 'to']: values = mail.get_all(key) values = [decode_header( v, normalize=normalize) for v in values] lines.append((key, ', '.join(values))) else: for value in mail.get_all(key): dvalue = decode_header(value, normalize=normalize) lines.append((key, dvalue)) elif key.lower() == 'tags': logging.debug('want tags header') values = [] for t in self._message.get_tags(): tagrep = settings.get_tagstring_representation(t) if t is not tagrep['translated']: t = '%s (%s)' % (tagrep['translated'], t) values.append(t) lines.append((key, ', '.join(values))) # OpenPGP pseudo headers if mail[X_SIGNATURE_MESSAGE_HEADER]: lines.append(('PGP-Signature', mail[X_SIGNATURE_MESSAGE_HEADER])) key_att = settings.get_theming_attribute('thread', 'header_key') value_att = settings.get_theming_attribute('thread', 'header_value') gaps_att = settings.get_theming_attribute('thread', 'header') return DictList(lines, key_att, value_att, gaps_att)
def replace_bodytext(self, txt): """display txt instead of current msg 'body'""" if txt: att = settings.get_theming_attribute('thread', 'body') att_focus = settings.get_theming_attribute('thread', 'body_focus') self._bodytree = TextlinesList(txt, att, att_focus)
def __init__(self, msg): bodytxt = message.extract_body(msg) att = settings.get_theming_attribute('thread', 'body') urwid.AttrMap.__init__(self, urwid.Text(bodytxt), att)
def __init__(self, message): self._message = message bodytxt = extract_body(message.get_email()) att = settings.get_theming_attribute('thread', 'body') urwid.AttrMap.__init__(self, urwid.Text(bodytxt), att)