summaryrefslogtreecommitdiff
path: root/alot/widgets/globals.py
diff options
context:
space:
mode:
authorPatrick Totzke <patricktotzke@gmail.com>2012-08-05 12:28:34 +0100
committerPatrick Totzke <patricktotzke@gmail.com>2012-08-10 13:03:39 +0100
commit14178c4e59850d4340e116ce29764cbd469c33be (patch)
tree3e0e47d32c88aeabf17b3250ef2aa5fe7c54fbbe /alot/widgets/globals.py
parent6c80ee5ecd23ec54604eab3ada0e2573e1757d89 (diff)
cleanup: split widgets.py and pep8/pyflakes fixes
Diffstat (limited to 'alot/widgets/globals.py')
-rw-r--r--alot/widgets/globals.py203
1 files changed, 203 insertions, 0 deletions
diff --git a/alot/widgets/globals.py b/alot/widgets/globals.py
new file mode 100644
index 00000000..96fec312
--- /dev/null
+++ b/alot/widgets/globals.py
@@ -0,0 +1,203 @@
+# Copyright (C) 2011-2012 Patrick Totzke <patricktotzke@gmail.com>
+# This file is released under the GNU GPL, version 3 or a later revision.
+# For further details see the COPYING file
+
+"""
+This contains alot-specific :ref:`urwid.Widgets` used in more than one mode.
+"""
+import urwid
+
+from alot.helper import string_decode
+from alot.settings import settings
+from alot.db.attachment import Attachment
+
+
+class AttachmentWidget(urwid.WidgetWrap):
+ """
+ one-line summary of an :class:`~alot.db.attachment.Attachment`.
+ """
+ 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 get_attachment(self):
+ return self.attachment
+
+ def selectable(self):
+ return self._selectable
+
+ def keypress(self, size, key):
+ return key
+
+
+class ChoiceWidget(urwid.Text):
+ def __init__(self, choices, callback, cancel=None, select=None):
+ self.choices = choices
+ self.callback = callback
+ self.cancel = cancel
+ self.select = select
+
+ items = []
+ for k, v in choices.items():
+ if v == select and select is not None:
+ items.append('[%s]:%s' % (k, v))
+ else:
+ items.append('(%s):%s' % (k, v))
+ urwid.Text.__init__(self, ' '.join(items))
+
+ def selectable(self):
+ return True
+
+ def keypress(self, size, key):
+ if key == 'select' and self.select is not None:
+ self.callback(self.select)
+ elif key == 'cancel' and self.cancel is not None:
+ self.callback(self.cancel)
+ elif key in self.choices:
+ self.callback(self.choices[key])
+ else:
+ return key
+
+
+class CompleteEdit(urwid.Edit):
+ def __init__(self, completer, on_exit, edit_text=u'',
+ history=None, **kwargs):
+ self.completer = completer
+ self.on_exit = on_exit
+ self.history = list(history) # we temporarily add stuff here
+ self.historypos = None
+
+ if not isinstance(edit_text, unicode):
+ edit_text = string_decode(edit_text)
+ self.start_completion_pos = len(edit_text)
+ self.completions = None
+ urwid.Edit.__init__(self, edit_text=edit_text, **kwargs)
+
+ def keypress(self, size, key):
+ # if we tabcomplete
+ if key in ['tab', 'shift tab'] and self.completer:
+ # if not already in completion mode
+ if not self.completions:
+ self.completions = [(self.edit_text, self.edit_pos)] + \
+ self.completer.complete(self.edit_text, self.edit_pos)
+ self.focus_in_clist = 1
+ else: # otherwise tab through results
+ if key == 'tab':
+ self.focus_in_clist += 1
+ else:
+ self.focus_in_clist -= 1
+ if len(self.completions) > 1:
+ ctext, cpos = self.completions[self.focus_in_clist %
+ len(self.completions)]
+ self.set_edit_text(ctext)
+ self.set_edit_pos(cpos)
+ else:
+ self.edit_pos += 1
+ if self.edit_pos >= len(self.edit_text):
+ self.edit_text += ' '
+ self.completions = None
+ elif key in ['up', 'down']:
+ if self.history:
+ if self.historypos is None:
+ self.history.append(self.edit_text)
+ self.historypos = len(self.history) - 1
+ if key == 'cursor up':
+ self.historypos = (self.historypos + 1) % len(self.history)
+ else:
+ self.historypos = (self.historypos - 1) % len(self.history)
+ self.set_edit_text(self.history[self.historypos])
+ elif key == 'select':
+ self.on_exit(self.edit_text)
+ elif key == 'cancel':
+ self.on_exit(None)
+ elif key == 'ctrl a':
+ self.set_edit_pos(0)
+ elif key == 'ctrl e':
+ self.set_edit_pos(len(self.edit_text))
+ else:
+ result = urwid.Edit.keypress(self, size, key)
+ self.completions = None
+ return result
+
+
+class HeadersList(urwid.WidgetWrap):
+ """ renders a pile of header values as key/value list """
+ 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 __str__(self):
+ return str(self.headers)
+
+ def _build_lines(self, lines):
+ max_key_len = 1
+ headerlines = []
+ #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((self.key_attr, key)))
+ valuew = urwid.Text((self.value_attr, value))
+ line = urwid.Columns([keyw, valuew])
+ headerlines.append(line)
+ return headerlines
+
+
+class TagWidget(urwid.AttrMap):
+ """
+ text widget that renders a tagstring.
+
+ It looks up the string it displays in the `tags` section
+ of the config as well as custom theme settings for its tag.
+ """
+ def __init__(self, tag, fallback_normal=None, fallback_focus=None):
+ self.tag = tag
+ representation = settings.get_tagstring_representation(tag,
+ fallback_normal,
+ fallback_focus)
+ self.translated = representation['translated']
+ self.hidden = self.translated == ''
+ self.txt = urwid.Text(self.translated, wrap='clip')
+ normal_att = representation['normal']
+ focus_att = representation['focussed']
+ self.attmaps = {'normal': normal_att, 'focus': focus_att}
+ urwid.AttrMap.__init__(self, self.txt, normal_att, focus_att)
+
+ def set_map(self, attrstring):
+ self.set_attr_map({None: self.attmaps[attrstring]})
+
+ def width(self):
+ # evil voodoo hotfix for double width chars that may
+ # lead e.g. to strings with length 1 that need width 2
+ return self.txt.pack()[0]
+
+ def selectable(self):
+ return True
+
+ def keypress(self, size, key):
+ return key
+
+ def get_tag(self):
+ return self.tag
+
+ def set_focussed(self):
+ self.set_attr_map(self.attmap['focus'])
+
+ def set_unfocussed(self):
+ self.set_attr_map(self.attmap['normal'])