summaryrefslogtreecommitdiff
path: root/alot/widgets
diff options
context:
space:
mode:
authorAnton Khirnov <anton@khirnov.net>2021-01-17 13:18:15 +0100
committerAnton Khirnov <anton@khirnov.net>2021-01-17 13:18:15 +0100
commit8f0f494ab0e621573eb6f941663891119b5c555b (patch)
treed9e70cbd47895c5dd7774402b4533235ccefefe6 /alot/widgets
parentaafbf031108a1328671deb658bf7d220d3e42f8b (diff)
widgets/thread: allow forcing inline display of selected attachment types
Diffstat (limited to 'alot/widgets')
-rw-r--r--alot/widgets/thread.py53
1 files changed, 40 insertions, 13 deletions
diff --git a/alot/widgets/thread.py b/alot/widgets/thread.py
index 455815f4..8f07432e 100644
--- a/alot/widgets/thread.py
+++ b/alot/widgets/thread.py
@@ -97,7 +97,7 @@ class _MIMEPartWidget(urwid.WidgetWrap):
c.cycle_alt()
class _CryptPartWidget(_MIMEPartWidget):
- def __init__(self, mime_tree, alternative_pref):
+ def __init__(self, mime_tree, alternative_pref, force_inline_types):
children = None
# handle broken crypto parts where we could not get the payload
@@ -138,7 +138,7 @@ class _CryptPartWidget(_MIMEPartWidget):
text_parts.append('crypto processing error: ' + mime_tree.crypt_error)
attr_name = 'crypt_invalid'
- child = _render_mime_tree(mime_tree.children[0], alternative_pref) \
+ child = _render_mime_tree(mime_tree.children[0], alternative_pref, force_inline_types) \
or _EmptyPartWidget()
attr = settings.get_theming_attribute('thread', attr_name)
body_wgt = urwid.AttrMap(urwid.LineBox(child, title = ':'.join(text_parts)), attr)
@@ -247,6 +247,8 @@ class _TextPart(_MIMEPartWidget):
_QUOTE_CHARS = '>|:}#'
_QUOTE_REGEX = '(([ \t]*[{quote_chars}])+)'.format(quote_chars = _QUOTE_CHARS)
+ _body_placeholder = None
+
_max_level = None
_lines = None
_fold = None
@@ -282,7 +284,20 @@ class _TextPart(_MIMEPartWidget):
self._lines, self._fold, self._max_level = \
self._parse_quotes(text, attr_text, attrs_quote)
- super().__init__(urwid.Text(''))
+ self._body_placeholder = urwid.WidgetPlaceholder(urwid.Text(''))
+
+ # decorate inline-forced attachments with a linebox
+ if part.attachment:
+ title = 'attachment %s' % part.content_type
+ fname = part.attachment.get_filename()
+ if fname:
+ title += ': %s' % fname
+
+ wgt = urwid.LineBox(self._body_placeholder, title = title)
+ else:
+ wgt = self._body_placeholder
+
+ super().__init__(wgt)
def _parse_quotes(self, text, attr_text, attrs_quote):
"""
@@ -385,7 +400,7 @@ class _TextPart(_MIMEPartWidget):
self._fold_context)
if len(markup_lines) == 0:
markup_lines = ['']
- self._w = urwid.Text(markup_lines)
+ self._body_placeholder.original_widget = urwid.Text(markup_lines)
self._fold_level = val
class _EmptyPartWidget(_MIMEPartWidget):
@@ -393,10 +408,10 @@ class _EmptyPartWidget(_MIMEPartWidget):
body_wgt = urwid.Text('<<< No displayable content >>>', align = 'center')
super().__init__(body_wgt)
-def _handle_multipart(mime_tree, alternative_pref):
+def _handle_multipart(mime_tree, alternative_pref, force_inline_types):
children = []
for child in mime_tree.children:
- ch = _render_mime_tree(child, alternative_pref)
+ ch = _render_mime_tree(child, alternative_pref, force_inline_types)
if ch is not None and not isinstance(ch, _EmptyPartWidget):
children.append(ch)
@@ -408,19 +423,30 @@ def _handle_multipart(mime_tree, alternative_pref):
return _MultiAltWidget(children, mime_tree.children, alternative_pref)
return _MultiMixedWidget(children)
-def _render_mime_tree(mime_tree, alternative_pref):
+def _render_mime_tree(mime_tree, alternative_pref, force_inline_types):
# handle encrypted/signed parts
if mime_tree.is_signed or mime_tree.is_encrypted:
- return _CryptPartWidget(mime_tree, alternative_pref)
+ return _CryptPartWidget(mime_tree, alternative_pref, force_inline_types)
if mime_tree.children is not None:
# multipart MIME parts
- return _handle_multipart(mime_tree, alternative_pref)
+ return _handle_multipart(mime_tree, alternative_pref, force_inline_types)
- # no children - this is a leaf node
- # skip attachment parts
+ ## no children - this is a leaf node
+ # skip attachment parts, unless they are of a user-specified type
if mime_tree.attachment:
- return None
+ force_inline = False
+
+ for t in force_inline_types:
+ maintype, _, subtype = t.partition('/')
+
+ if (maintype == mime_tree.content_maintype and
+ (subtype == mime_tree.content_subtype or subtype == '*')):
+ force_inline = True
+ break
+
+ if not force_inline:
+ return None
# try rendering the message
text = mime_tree.render_str()
@@ -533,6 +559,7 @@ class MessageWidget(urwid.WidgetWrap):
"""
self._message = message
+ force_inline_types = settings.get('thread_force_inline_mimetypes')
if settings.get('prefer_plaintext'):
alternative_pref = 'text/plain'
else:
@@ -542,7 +569,7 @@ class MessageWidget(urwid.WidgetWrap):
self._source_wgt = _RawMessageWidget(message.as_bytes())
self._attach_wgt = self._get_attachments()
- self._body_wgt = _render_mime_tree(message.body, alternative_pref)
+ self._body_wgt = _render_mime_tree(message.body, alternative_pref, force_inline_types)
if self._body_wgt is None:
self._body_wgt = _EmptyPartWidget()