예제 #1
0
파일: widgets.py 프로젝트: t-8ch/alot
    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')
        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) 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))
        focus_att = settings.get_theming_attribute('thread', 'summary_focus')
        line = urwid.AttrMap(urwid.Columns(cols, dividechars=1), attr,
                             focus_att)
        urwid.WidgetWrap.__init__(self, line)
예제 #2
0
    def rebuild(self):
        if self.isinitialized:
            focusposition = self.taglist.get_focus()[1]
        else:
            focusposition = 0
            self.isinitialized = True

        lines = list()
        displayedtags = sorted(filter(self.filtfun, self.tags),
                               key=unicode.lower)
        for (num, b) in enumerate(displayedtags):
            if (num % 2) == 0:
                attr = settings.get_theming_attribute('taglist', 'line_even')
            else:
                attr = settings.get_theming_attribute('taglist', 'line_odd')
            focus_att = settings.get_theming_attribute('taglist', 'line_focus')

            tw = TagWidget(b, attr, focus_att)
            rows = [('fixed', tw.width(), tw)]
            if tw.hidden:
                rows.append(urwid.Text(b + ' [hidden]'))
            elif tw.translated is not b:
                rows.append(urwid.Text('(%s)' % b))
            line = urwid.Columns(rows, dividechars=1)
            line = urwid.AttrMap(line, attr, focus_att)
            lines.append(line)

        self.taglist = urwid.ListBox(urwid.SimpleListWalker(lines))
        self.body = self.taglist

        self.taglist.set_focus(focusposition % len(displayedtags))
예제 #3
0
파일: widgets.py 프로젝트: laarmen/alot
    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')
        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) 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))
        focus_att = settings.get_theming_attribute('thread', 'summary_focus')
        line = urwid.AttrMap(urwid.Columns(cols, dividechars=1), attr,
                             focus_att)
        urwid.WidgetWrap.__init__(self, line)
예제 #4
0
    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 = BufferlineWidget(b)
            if (num % 2) == 0:
                attr = settings.get_theming_attribute('bufferlist',
                                                      'line_even')
            else:
                attr = settings.get_theming_attribute('bufferlist', 'line_odd')
            focus_att = settings.get_theming_attribute('bufferlist',
                                                       'line_focus')
            buf = urwid.AttrMap(line, attr, focus_att)
            num = urwid.Text('%3d:' % self.index_of(b))
            lines.append(urwid.Columns([('fixed', 4, num), buf]))
        self.bufferlist = urwid.ListBox(urwid.SimpleListWalker(lines))
        num_buffers = len(displayedbuffers)
        if focusposition is not None and num_buffers > 0:
            self.bufferlist.set_focus(focusposition % num_buffers)
        self.body = self.bufferlist
예제 #5
0
 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)
예제 #6
0
    def rebuild(self):
        displayed_widgets = []
        hidden = settings.get('envelope_headers_blacklist')
        # build lines
        lines = []
        for (k, vlist) in self.envelope.headers.items():
            if (k not in hidden) or self.all_headers:
                for value in vlist:
                    lines.append((k, value))

        # sign/encrypt lines
        if self.envelope.sign:
            description = 'Yes'
            sign_key = self.envelope.sign_key
            if sign_key is not None and len(sign_key.subkeys) > 0:
                description += ', with key ' + sign_key.uids[0].uid
            lines.append(('GPG sign', description))

        if self.envelope.encrypt:
            description = 'Yes'
            encrypt_keys = self.envelope.encrypt_keys.values()
            if len(encrypt_keys) == 1:
                description += ', with key '
            elif len(encrypt_keys) > 1:
                description += ', with keys '
            first_key = True
            for key in encrypt_keys:
                if key is not None:
                    if first_key:
                        first_key = False
                    else:
                        description += ', '
                    if len(key.subkeys) > 0:
                        description += key.uids[0].uid
            lines.append(('GPG encrypt', description))

        # add header list widget iff header values exists
        if lines:
            key_att = settings.get_theming_attribute('envelope', 'header_key')
            value_att = settings.get_theming_attribute('envelope',
                                                       'header_value')
            gaps_att = settings.get_theming_attribute('envelope', 'header')
            self.header_wgt = HeadersList(lines, key_att, value_att, gaps_att)
            displayed_widgets.append(self.header_wgt)

        # display attachments
        lines = []
        for a in self.envelope.attachments:
            lines.append(AttachmentWidget(a, selectable=False))
        if lines:
            self.attachment_wgt = urwid.Pile(lines)
            displayed_widgets.append(self.attachment_wgt)

        self.body_wgt = urwid.Text(self.envelope.body)
        displayed_widgets.append(self.body_wgt)
        self.body = urwid.ListBox(displayed_widgets)
예제 #7
0
파일: widgets.py 프로젝트: t-8ch/alot
 def __init__(self, tid, dbman):
     self.dbman = dbman
     #logging.debug('tid: %s' % tid)
     self.thread = dbman.get_thread(tid)
     #logging.debug('tid: %s' % self.thread)
     self.tag_widgets = []
     self.display_content = settings.get('display_content_in_threadline')
     self.rebuild()
     normal = settings.get_theming_attribute('search', 'thread')
     focussed = settings.get_theming_attribute('search', 'thread_focus')
     urwid.AttrMap.__init__(self, self.columns, normal, focussed)
예제 #8
0
파일: widgets.py 프로젝트: t-8ch/alot
 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)
예제 #9
0
파일: widgets.py 프로젝트: laarmen/alot
 def __init__(self, tid, dbman):
     self.dbman = dbman
     #logging.debug('tid: %s' % tid)
     self.thread = dbman.get_thread(tid)
     #logging.debug('tid: %s' % self.thread)
     self.tag_widgets = []
     self.display_content = settings.get('display_content_in_threadline')
     self.rebuild()
     normal = settings.get_theming_attribute('search', 'thread')
     focussed = settings.get_theming_attribute('search', 'thread_focus')
     urwid.AttrMap.__init__(self, self.columns, normal, focussed)
예제 #10
0
    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 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)
예제 #11
0
 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)
예제 #12
0
파일: ui.py 프로젝트: geier/alot
    def build_statusbar(self):
        """construct and return statusbar widget"""
        info = {}
        cb = self.current_buffer
        btype = None

        if cb is not None:
            info = cb.get_info()
            btype = cb.modename
            info['buffer_no'] = self.buffers.index(cb)
            info['buffer_type'] = btype
        info['total_messages'] = self.dbman.count_messages('*')
        info['pending_writes'] = len(self.dbman.writequeue)
        info['input_queue'] = ' '.join(self.input_queue)

        lefttxt = righttxt = u''
        if cb is not None:
            lefttxt, righttxt = settings.get(btype + '_statusbar', (u'', u''))
            lefttxt = string_decode(lefttxt, 'UTF-8')
            lefttxt = lefttxt.format(**info)
            righttxt = string_decode(righttxt, 'UTF-8')
            righttxt = righttxt.format(**info)

        footerleft = urwid.Text(lefttxt, align='left')
        pending_writes = len(self.dbman.writequeue)
        if pending_writes > 0:
            righttxt = ('|' * pending_writes) + ' ' + righttxt
        footerright = urwid.Text(righttxt, align='right')
        columns = urwid.Columns([
            footerleft,
            ('fixed', len(righttxt), footerright)])
        footer_att = settings.get_theming_attribute('global', 'footer')
        return urwid.AttrMap(columns, footer_att)
예제 #13
0
파일: ui.py 프로젝트: mturquette/alot
    def build_statusbar(self):
        """construct and return statusbar widget"""
        info = {}
        cb = self.current_buffer
        btype = None

        if cb is not None:
            info = cb.get_info()
            btype = cb.modename
            info["buffer_no"] = self.buffers.index(cb)
            info["buffer_type"] = btype
        info["total_messages"] = self.dbman.count_messages("*")
        info["pending_writes"] = len(self.dbman.writequeue)

        lefttxt = righttxt = u""
        if cb is not None:
            lefttxt, righttxt = settings.get(btype + "_statusbar", (u"", u""))
            lefttxt = string_decode(lefttxt, "UTF-8")
            lefttxt = lefttxt.format(**info)
            righttxt = string_decode(righttxt, "UTF-8")
            righttxt = righttxt.format(**info)

        footerleft = urwid.Text(lefttxt, align="left")
        pending_writes = len(self.dbman.writequeue)
        if pending_writes > 0:
            righttxt = ("|" * pending_writes) + " " + righttxt
        footerright = urwid.Text(righttxt, align="right")
        columns = urwid.Columns([footerleft, ("fixed", len(righttxt), footerright)])
        footer_att = settings.get_theming_attribute("global", "footer")
        return urwid.AttrMap(columns, footer_att)
예제 #14
0
파일: ui.py 프로젝트: t-8ch/alot
    def __init__(self, dbman, initialcmd):
        """
        :param dbman: :class:`~alot.db.DBManager`
        :param initialcmd: commandline applied after setting up interface
        :type initialcmd: str
        :param colourmode: determines which theme to chose
        :type colourmode: int in [1,16,256]
        """
        self.dbman = dbman

        colourmode = int(settings.get('colourmode'))
        logging.info('setup gui in %d colours' % colourmode)
        global_att = settings.get_theming_attribute('global', 'body')
        self.mainframe = urwid.Frame(urwid.SolidFill())
        self.mainframe_themed = urwid.AttrMap(self.mainframe, global_att)
        self.inputwrap = InputWrap(self, self.mainframe_themed)
        self.mainloop = urwid.MainLoop(self.inputwrap,
                handle_mouse=False,
                event_loop=urwid.TwistedEventLoop(),
                unhandled_input=self.unhandeled_input)
        self.mainloop.screen.set_terminal_properties(colors=colourmode)

        self.show_statusbar = settings.get('show_statusbar')
        self.notificationbar = None
        self.mode = 'global'
        self.commandprompthistory = []

        logging.debug('fire first command')
        self.apply_command(initialcmd)
        self.mainloop.run()
예제 #15
0
파일: ui.py 프로젝트: t-8ch/alot
    def build_statusbar(self):
        """construct and return statusbar widget"""
        info = {}
        cb = self.current_buffer
        btype = None

        if cb is not None:
            info = cb.get_info()
            btype = cb.modename
            info['buffer_no'] = self.buffers.index(cb)
            info['buffer_type'] = btype
        info['total_messages'] = self.dbman.count_messages('*')
        info['pending_writes'] = len(self.dbman.writequeue)

        lefttxt = righttxt = u''
        if cb is not None:
            lefttxt, righttxt = settings.get(btype + '_statusbar', (u'', u''))
            lefttxt = string_decode(lefttxt, 'UTF-8')
            lefttxt = lefttxt.format(**info)
            righttxt = string_decode(righttxt, 'UTF-8')
            righttxt = righttxt.format(**info)

        footerleft = urwid.Text(lefttxt, align='left')
        pending_writes = len(self.dbman.writequeue)
        if pending_writes > 0:
            righttxt = ('|' * pending_writes) + ' ' + righttxt
        footerright = urwid.Text(righttxt, align='right')
        columns = urwid.Columns([
            footerleft,
            ('fixed', len(righttxt), footerright)])
        footer_att = settings.get_theming_attribute('global', 'footer')
        return urwid.AttrMap(columns, footer_att)
예제 #16
0
 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)
예제 #17
0
파일: widgets.py 프로젝트: laarmen/alot
 def _build_lines(self, lines):
     max_key_len = 1
     headerlines = []
     key_att = settings.get_theming_attribute('thread', 'header_key')
     value_att = settings.get_theming_attribute('thread', 'header_value')
     #calc max length of key-string
     for key, value in lines:
         if len(key) > max_key_len:
             max_key_len = len(key)
     for key, value in lines:
         ##todo : even/odd
         keyw = ('fixed', max_key_len + 1,
                 urwid.Text((key_att, key)))
         valuew = urwid.Text((value_att, value))
         line = urwid.Columns([keyw, valuew])
         headerlines.append(line)
     return headerlines
예제 #18
0
파일: widgets.py 프로젝트: t-8ch/alot
 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)
예제 #19
0
파일: ui.py 프로젝트: t-8ch/alot
    def choice(self, message, choices={'y': 'yes', 'n': 'no'},
               select=None, cancel=None, msg_position='above'):
        """
        prompt user to make a choice

        :param message: string to display before list of choices
        :type message: unicode
        :param choices: dict of possible choices
        :type choices: dict: keymap->choice (both str)
        :param select: choice to return if enter/return is hit. Ignored if set
                       to `None`.
        :type select: str
        :param cancel: choice to return if escape is hit. Ignored if set to
                       `None`.
        :type cancel: str
        :param msg_position: determines if `message` is above or left of the
                             prompt. Must be `above` or `left`.
        :type msg_position: str
        :returns: a :class:`twisted.defer.Deferred`
        """
        assert select in choices.values() + [None]
        assert cancel in choices.values() + [None]
        assert msg_position in ['left', 'above']

        d = defer.Deferred()  # create return deferred
        oldroot = self.inputwrap.get_root()

        def select_or_cancel(text):
            self.inputwrap.set_root(oldroot)
            self.inputwrap.select_cancel_only = False
            d.callback(text)

        #set up widgets
        msgpart = urwid.Text(message)
        choicespart = widgets.ChoiceWidget(choices, callback=select_or_cancel,
                                           select=select, cancel=cancel)

        # build widget
        if msg_position == 'left':
            both = urwid.Columns(
                [
                    ('fixed', len(message), msgpart),
                    ('weight', 1, choicespart),
                ], dividechars=1)
        else:  # above
            both = urwid.Pile([msgpart, choicespart])
        att = settings.get_theming_attribute('global', 'prompt')
        both = urwid.AttrMap(both, att, att)

        # put promptwidget as overlay on main widget
        overlay = urwid.Overlay(both, oldroot,
                                ('fixed left', 0),
                                ('fixed right', 0),
                                ('fixed bottom', 1),
                                None)
        self.inputwrap.set_root(overlay)
        self.inputwrap.select_cancel_only = True
        return d  # return deferred
예제 #20
0
파일: ui.py 프로젝트: geier/alot
    def choice(self, message, choices={'y': 'yes', 'n': 'no'},
               select=None, cancel=None, msg_position='above'):
        """
        prompt user to make a choice.

        :param message: string to display before list of choices
        :type message: unicode
        :param choices: dict of possible choices
        :type choices: dict: keymap->choice (both str)
        :param select: choice to return if enter/return is hit. Ignored if set
                       to `None`.
        :type select: str
        :param cancel: choice to return if escape is hit. Ignored if set to
                       `None`.
        :type cancel: str
        :param msg_position: determines if `message` is above or left of the
                             prompt. Must be `above` or `left`.
        :type msg_position: str
        :rtype:  :class:`twisted.defer.Deferred`
        """
        assert select in choices.values() + [None]
        assert cancel in choices.values() + [None]
        assert msg_position in ['left', 'above']

        d = defer.Deferred()  # create return deferred
        oldroot = self.mainloop.widget

        def select_or_cancel(text):
            self.mainloop.widget = oldroot
            self._passall = False
            d.callback(text)

        # set up widgets
        msgpart = urwid.Text(message)
        choicespart = ChoiceWidget(choices, callback=select_or_cancel,
                                   select=select, cancel=cancel)

        # build widget
        if msg_position == 'left':
            both = urwid.Columns(
                [
                    ('fixed', len(message), msgpart),
                    ('weight', 1, choicespart),
                ], dividechars=1)
        else:  # above
            both = urwid.Pile([msgpart, choicespart])
        att = settings.get_theming_attribute('global', 'prompt')
        both = urwid.AttrMap(both, att, att)

        # put promptwidget as overlay on main widget
        overlay = urwid.Overlay(both, oldroot,
                                ('fixed left', 0),
                                ('fixed right', 0),
                                ('fixed bottom', 1),
                                None)
        self.mainloop.widget = overlay
        self._passall = True
        return d  # return deferred
예제 #21
0
파일: ui.py 프로젝트: fagga/alot
    def prompt(self, prefix, text=u'', completer=None, tab=0, history=[]):
        """
        prompt for text input.
        This returns a :class:`~twisted.defer.Deferred` that calls back with
        the input string.

        :param prefix: text to print before the input field
        :type prefix: str
        :param text: initial content of the input field
        :type text: str
        :param completer: completion object to use
        :type completer: :meth:`alot.completion.Completer`
        :param tab: number of tabs to press initially
                    (to select completion results)
        :type tab: int
        :param history: history to be used for up/down keys
        :type history: list of str
        :rtype: :class:`twisted.defer.Deferred`
        """
        d = defer.Deferred()  # create return deferred
        oldroot = self.mainloop.widget

        def select_or_cancel(text):
            # restore main screen and invoke callback
            # (delayed return) with given text
            self.mainloop.widget = oldroot
            self._passall = False
            d.callback(text)

        prefix = prefix + settings.get('prompt_suffix')

        #set up widgets
        leftpart = urwid.Text(prefix, align='left')
        editpart = CompleteEdit(completer, on_exit=select_or_cancel,
                                edit_text=text, history=history)

        for i in range(tab):  # hit some tabs
            editpart.keypress((0,), 'tab')

        # build promptwidget
        both = urwid.Columns(
            [
                ('fixed', len(prefix), leftpart),
                ('weight', 1, editpart),
            ])
        att = settings.get_theming_attribute('global', 'prompt')
        both = urwid.AttrMap(both, att)

        # put promptwidget as overlay on main widget
        overlay = urwid.Overlay(both, oldroot,
                                ('fixed left', 0),
                                ('fixed right', 0),
                                ('fixed bottom', 1),
                                None)
        self.mainloop.widget = overlay
        self._passall = True
        return d  # return deferred
예제 #22
0
파일: ui.py 프로젝트: lzap/alot
    def prompt(self, prefix, text=u'', completer=None, tab=0, history=[]):
        """
        prompt for text input.
        This returns a :class:`~twisted.defer.Deferred` that calls back with
        the input string.

        :param prefix: text to print before the input field
        :type prefix: str
        :param text: initial content of the input field
        :type text: str
        :param completer: completion object to use
        :type completer: :meth:`alot.completion.Completer`
        :param tab: number of tabs to press initially
                    (to select completion results)
        :type tab: int
        :param history: history to be used for up/down keys
        :type history: list of str
        :rtype: :class:`twisted.defer.Deferred`
        """
        d = defer.Deferred()  # create return deferred
        oldroot = self.mainloop.widget

        def select_or_cancel(text):
            # restore main screen and invoke callback
            # (delayed return) with given text
            self.mainloop.widget = oldroot
            self._passall = False
            d.callback(text)

        prefix = prefix + settings.get('prompt_suffix')

        # set up widgets
        leftpart = urwid.Text(prefix, align='left')
        editpart = CompleteEdit(completer, on_exit=select_or_cancel,
                                edit_text=text, history=history)

        for i in range(tab):  # hit some tabs
            editpart.keypress((0,), 'tab')

        # build promptwidget
        both = urwid.Columns(
            [
                ('fixed', len(prefix), leftpart),
                ('weight', 1, editpart),
            ])
        att = settings.get_theming_attribute('global', 'prompt')
        both = urwid.AttrMap(both, att)

        # put promptwidget as overlay on main widget
        overlay = urwid.Overlay(both, oldroot,
                                ('fixed left', 0),
                                ('fixed right', 0),
                                ('fixed bottom', 1),
                                None)
        self.mainloop.widget = overlay
        self._passall = True
        return d  # return deferred
예제 #23
0
파일: widgets.py 프로젝트: t-8ch/alot
    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:
            if key in mail:
                if key.lower() in ['cc', 'bcc', 'to']:
                    values = mail.get_all(key)
                    dvalues = [
                        decode_header(v, normalize=norm) for v in values
                    ]
                    lines.append((key, ', '.join(dvalues)))
                else:
                    for value in mail.get_all(key):
                        dvalue = decode_header(value, normalize=norm)
                        lines.append((key, dvalue))

        key_att = settings.get_theming_attribute('thread', 'header_key')
        value_att = settings.get_theming_attribute('thread', 'header_value')
        cols = [HeadersList(lines, key_att, value_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
예제 #24
0
    def rebuild(self):
        try:
            self.thread.refresh()
        except NonexistantObjectError:
            self.body = urwid.SolidFill()
            self.message_count = 0
            return

        self._tree = ThreadTree(self.thread)

        bars_att = settings.get_theming_attribute('thread', 'arrow_bars')
        heads_att = settings.get_theming_attribute('thread', 'arrow_heads')
        A = ArrowTree(self._tree,
                      indent=2,
                      childbar_offset=0,
                      arrow_tip_att=heads_att,
                      arrow_att=bars_att,
                      )
        self._nested_tree = NestedTree(A, interpret_covered=True)
        self.body = TreeBox(self._nested_tree)
        self.message_count = self.thread.get_total_messages()
예제 #25
0
    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:
            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))

        key_att = settings.get_theming_attribute("thread", "header_key")
        value_att = settings.get_theming_attribute("thread", "header_value")
        cols = [HeadersList(lines, key_att, value_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
예제 #26
0
파일: ui.py 프로젝트: mturquette/alot
    def choice(self, message, choices={"y": "yes", "n": "no"}, select=None, cancel=None, msg_position="above"):
        """
        prompt user to make a choice

        :param message: string to display before list of choices
        :type message: unicode
        :param choices: dict of possible choices
        :type choices: dict: keymap->choice (both str)
        :param select: choice to return if enter/return is hit. Ignored if set
                       to `None`.
        :type select: str
        :param cancel: choice to return if escape is hit. Ignored if set to
                       `None`.
        :type cancel: str
        :param msg_position: determines if `message` is above or left of the
                             prompt. Must be `above` or `left`.
        :type msg_position: str
        :returns: a :class:`twisted.defer.Deferred`
        """
        assert select in choices.values() + [None]
        assert cancel in choices.values() + [None]
        assert msg_position in ["left", "above"]

        d = defer.Deferred()  # create return deferred
        oldroot = self.inputwrap.get_root()

        def select_or_cancel(text):
            self.inputwrap.set_root(oldroot)
            self.inputwrap.select_cancel_only = False
            d.callback(text)

        # set up widgets
        msgpart = urwid.Text(message)
        choicespart = ChoiceWidget(choices, callback=select_or_cancel, select=select, cancel=cancel)

        # build widget
        if msg_position == "left":
            both = urwid.Columns([("fixed", len(message), msgpart), ("weight", 1, choicespart)], dividechars=1)
        else:  # above
            both = urwid.Pile([msgpart, choicespart])
        att = settings.get_theming_attribute("global", "prompt")
        both = urwid.AttrMap(both, att, att)

        # put promptwidget as overlay on main widget
        overlay = urwid.Overlay(both, oldroot, ("fixed left", 0), ("fixed right", 0), ("fixed bottom", 1), None)
        self.inputwrap.set_root(overlay)
        self.inputwrap.select_cancel_only = True
        return d  # return deferred
예제 #27
0
파일: ui.py 프로젝트: teythoon/alot
    def __init__(self, dbman, initialcmd):
        """
        :param dbman: :class:`~alot.db.DBManager`
        :param initialcmd: commandline applied after setting up interface
        :type initialcmd: str
        :param colourmode: determines which theme to chose
        :type colourmode: int in [1,16,256]
        """
        # store database manager
        self.dbman = dbman
        # define empty notification pile
        self._notificationbar = None
        # should we show a status bar?
        self._show_statusbar = settings.get("show_statusbar")
        # pass keypresses to the root widget and never interpret bindings
        self._passall = False
        # indicates "input lock": only focus move commands are interpreted
        self._locked = False
        self._unlock_callback = None  # will be called after input lock ended
        self._unlock_key = None  # key that ends input lock

        # alarm handle for callback that clears input queue (to cancel alarm)
        self._alarm = None

        # create root widget
        global_att = settings.get_theming_attribute("global", "body")
        mainframe = urwid.Frame(urwid.SolidFill())
        self.root_widget = urwid.AttrMap(mainframe, global_att)

        # set up main loop
        self.mainloop = urwid.MainLoop(
            self.root_widget,
            handle_mouse=False,
            event_loop=urwid.TwistedEventLoop(),
            unhandled_input=self._unhandeled_input,
            input_filter=self._input_filter,
        )

        # set up colours
        colourmode = int(settings.get("colourmode"))
        logging.info("setup gui in %d colours" % colourmode)
        self.mainloop.screen.set_terminal_properties(colors=colourmode)

        logging.debug("fire first command")
        self.apply_command(initialcmd)

        # start urwids mainloop
        self.mainloop.run()
예제 #28
0
파일: ui.py 프로젝트: fagga/alot
    def __init__(self, dbman, initialcmd):
        """
        :param dbman: :class:`~alot.db.DBManager`
        :param initialcmd: commandline applied after setting up interface
        :type initialcmd: str
        :param colourmode: determines which theme to chose
        :type colourmode: int in [1,16,256]
        """
        # store database manager
        self.dbman = dbman
        # define empty notification pile
        self._notificationbar = None
        # should we show a status bar?
        self._show_statusbar = settings.get('show_statusbar')
        # pass keypresses to the root widget and never interpret bindings
        self._passall = False
        # indicates "input lock": only focus move commands are interpreted
        self._locked = False
        self._unlock_callback = None  # will be called after input lock ended
        self._unlock_key = None  # key that ends input lock

        # alarm handle for callback that clears input queue (to cancel alarm)
        self._alarm = None

        # create root widget
        global_att = settings.get_theming_attribute('global', 'body')
        mainframe = urwid.Frame(urwid.SolidFill())
        self.root_widget = urwid.AttrMap(mainframe, global_att)

        # set up main loop
        self.mainloop = urwid.MainLoop(self.root_widget,
                                       handle_mouse=False,
                                       event_loop=urwid.TwistedEventLoop(),
                                       unhandled_input=self._unhandeled_input,
                                       input_filter=self._input_filter)

        # set up colours
        colourmode = int(settings.get('colourmode'))
        logging.info('setup gui in %d colours' % colourmode)
        self.mainloop.screen.set_terminal_properties(colors=colourmode)

        logging.debug('fire first command')
        self.apply_command(initialcmd)

        # start urwids mainloop
        self.mainloop.run()
예제 #29
0
파일: ui.py 프로젝트: mturquette/alot
    def prompt(self, prefix, text=u"", completer=None, tab=0, history=[]):
        """prompt for text input

        :param prefix: text to print before the input field
        :type prefix: str
        :param text: initial content of the input field
        :type text: str
        :param completer: completion object to use
        :type completer: :meth:`alot.completion.Completer`
        :param tab: number of tabs to press initially
                    (to select completion results)
        :type tab: int
        :param history: history to be used for up/down keys
        :type history: list of str
        :returns: a :class:`twisted.defer.Deferred`
        """
        d = defer.Deferred()  # create return deferred
        oldroot = self.inputwrap.get_root()

        def select_or_cancel(text):
            # restore main screen and invoke callback
            # (delayed return) with given text
            self.inputwrap.set_root(oldroot)
            self.inputwrap.select_cancel_only = False
            d.callback(text)

        prefix = prefix + settings.get("prompt_suffix")

        # set up widgets
        leftpart = urwid.Text(prefix, align="left")
        editpart = CompleteEdit(completer, on_exit=select_or_cancel, edit_text=text, history=history)

        for i in range(tab):  # hit some tabs
            editpart.keypress((0,), "tab")

        # build promptwidget
        both = urwid.Columns([("fixed", len(prefix), leftpart), ("weight", 1, editpart)])
        att = settings.get_theming_attribute("global", "prompt")
        both = urwid.AttrMap(both, att)

        # put promptwidget as overlay on main widget
        overlay = urwid.Overlay(both, oldroot, ("fixed left", 0), ("fixed right", 0), ("fixed bottom", 1), None)
        self.inputwrap.set_root(overlay)
        self.inputwrap.select_cancel_only = True
        return d  # return deferred
예제 #30
0
파일: ui.py 프로젝트: laarmen/alot
 def build_statusbar(self):
     """construct and return statusbar widget"""
     if self.current_buffer is not None:
         idx = self.buffers.index(self.current_buffer)
         lefttxt = '%d: %s' % (idx, self.current_buffer)
     else:
         lefttxt = '[no buffers]'
     footerleft = urwid.Text(lefttxt, align='left')
     righttxt = 'total messages: %d' % self.dbman.count_messages('*')
     pending_writes = len(self.dbman.writequeue)
     if pending_writes > 0:
         righttxt = ('|' * pending_writes) + ' ' + righttxt
     footerright = urwid.Text(righttxt, align='right')
     columns = urwid.Columns([
         footerleft,
         ('fixed', len(righttxt), footerright)])
     footer_att = settings.get_theming_attribute('global', 'footer')
     return urwid.AttrMap(columns, footer_att)
예제 #31
0
파일: widgets.py 프로젝트: laarmen/alot
 def _get_theme(self, component, focus=False):
     attr_key = 'thread_{0}'.format(component)
     if focus:
         attr_key += '_focus'
     return settings.get_theming_attribute('search', attr_key)
예제 #32
0
파일: widgets.py 프로젝트: laarmen/alot
 def __init__(self, msg):
     bodytxt = message.extract_body(msg)
     att = settings.get_theming_attribute('thread', 'body')
     urwid.AttrMap.__init__(self, urwid.Text(bodytxt), att)
예제 #33
0
파일: widgets.py 프로젝트: t-8ch/alot
 def _get_theme(self, component, focus=False):
     attr_key = 'thread_{0}'.format(component)
     if focus:
         attr_key += '_focus'
     return settings.get_theming_attribute('search', attr_key)
예제 #34
0
파일: widgets.py 프로젝트: t-8ch/alot
 def __init__(self, msg):
     bodytxt = message.extract_body(msg)
     att = settings.get_theming_attribute('thread', 'body')
     urwid.AttrMap.__init__(self, urwid.Text(bodytxt), att)
예제 #35
0
파일: ui.py 프로젝트: geier/alot
 def build_line(msg, prio):
     cols = urwid.Columns([urwid.Text(msg)])
     att = settings.get_theming_attribute('global', 'notify_' + prio)
     return urwid.AttrMap(cols, att)
예제 #36
0
파일: ui.py 프로젝트: geier/alot
    def __init__(self, dbman, initialcmdline):
        """
        :param dbman: :class:`~alot.db.DBManager`
        :param initialcmdline: commandline applied after setting up interface
        :type initialcmdline: str
        :param colourmode: determines which theme to chose
        :type colourmode: int in [1,16,256]
        """
        self.dbman = dbman
        """Database Manager (:class:`~alot.db.manager.DBManager`)"""
        self.buffers = []
        """list of active buffers"""
        self.current_buffer = None
        """points to currently active :class:`~alot.buffers.Buffer`"""
        self.db_was_locked = False
        """flag used to prevent multiple 'index locked' notifications"""
        self.mode = 'global'
        """interface mode identifier - type of current buffer"""
        self.commandprompthistory = []
        """history of the command line prompt"""
        self.input_queue = []
        """stores partial keyboard input"""
        self.last_commandline = None
        """saves the last executed commandline"""

        # define empty notification pile
        self._notificationbar = None
        # should we show a status bar?
        self._show_statusbar = settings.get('show_statusbar')
        # pass keypresses to the root widget and never interpret bindings
        self._passall = False
        # indicates "input lock": only focus move commands are interpreted
        self._locked = False
        self._unlock_callback = None  # will be called after input lock ended
        self._unlock_key = None  # key that ends input lock

        # alarm handle for callback that clears input queue (to cancel alarm)
        self._alarm = None

        # create root widget
        global_att = settings.get_theming_attribute('global', 'body')
        mainframe = urwid.Frame(urwid.SolidFill())
        self.root_widget = urwid.AttrMap(mainframe, global_att)

        # set up main loop
        self.mainloop = urwid.MainLoop(self.root_widget,
                                       handle_mouse=False,
                                       event_loop=urwid.TwistedEventLoop(),
                                       unhandled_input=self._unhandeled_input,
                                       input_filter=self._input_filter)

        # set up colours
        colourmode = int(settings.get('colourmode'))
        logging.info('setup gui in %d colours' % colourmode)
        self.mainloop.screen.set_terminal_properties(colors=colourmode)

        logging.debug('fire first command')
        self.apply_commandline(initialcmdline)

        # start urwids mainloop
        self.mainloop.run()
예제 #37
0
파일: ui.py 프로젝트: tlevine/alot
    def __init__(self, dbman, initialcmdline):
        """
        :param dbman: :class:`~alot.db.DBManager`
        :param initialcmdline: commandline applied after setting up interface
        :type initialcmdline: str
        :param colourmode: determines which theme to chose
        :type colourmode: int in [1,16,256]
        """
        self.dbman = dbman
        """Database Manager (:class:`~alot.db.manager.DBManager`)"""
        self.buffers = []
        """list of active buffers"""
        self.current_buffer = None
        """points to currently active :class:`~alot.buffers.Buffer`"""
        self.db_was_locked = False
        """flag used to prevent multiple 'index locked' notifications"""
        self.mode = 'global'
        """interface mode identifier - type of current buffer"""
        self.commandprompthistory = []
        """history of the command line prompt"""
        self.input_queue = []
        """stores partial keyboard input"""
        self.last_commandline = None
        """saves the last executed commandline"""

        # define empty notification pile
        self._notificationbar = None
        # should we show a status bar?
        self._show_statusbar = settings.get('show_statusbar')
        # pass keypresses to the root widget and never interpret bindings
        self._passall = False
        # indicates "input lock": only focus move commands are interpreted
        self._locked = False
        self._unlock_callback = None  # will be called after input lock ended
        self._unlock_key = None  # key that ends input lock

        # alarm handle for callback that clears input queue (to cancel alarm)
        self._alarm = None

        # create root widget
        global_att = settings.get_theming_attribute('global', 'body')
        mainframe = urwid.Frame(urwid.SolidFill())
        self.root_widget = urwid.AttrMap(mainframe, global_att)

        # set up main loop
        self.mainloop = urwid.MainLoop(self.root_widget,
                                       handle_mouse=False,
                                       event_loop=urwid.TwistedEventLoop(),
                                       unhandled_input=self._unhandeled_input,
                                       input_filter=self._input_filter)

        # set up colours
        colourmode = int(settings.get('colourmode'))
        logging.info('setup gui in %d colours' % colourmode)
        self.mainloop.screen.set_terminal_properties(colors=colourmode)

        logging.debug('fire first command')
        self.apply_commandline(initialcmdline)

        # start urwids mainloop
        self.mainloop.run()
예제 #38
0
파일: widgets.py 프로젝트: laarmen/alot
 def __init__(self, headerslist):
     self.headers = headerslist
     pile = urwid.Pile(self._build_lines(headerslist))
     att = settings.get_theming_attribute('thread', 'header')
     pile = urwid.AttrMap(pile, att)
     urwid.WidgetWrap.__init__(self, pile)
예제 #39
0
파일: ui.py 프로젝트: t-8ch/alot
 def build_line(msg, prio):
     cols = urwid.Columns([urwid.Text(msg)])
     att = settings.get_theming_attribute('global', 'notify_' + prio)
     return urwid.AttrMap(cols, att)