197 lines
6.7 KiB
Python
197 lines
6.7 KiB
Python
#!/usr/bin/python
|
|
# -*- coding: utf-8 -*-
|
|
|
|
"""
|
|
Primitivus: a SAT frontend
|
|
Copyright (C) 2009, 2010 Jérôme Poisson (goffi@goffi.org)
|
|
|
|
This program 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.
|
|
|
|
This program 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 this program. If not, see <http://www.gnu.org/licenses/>.
|
|
"""
|
|
|
|
import urwid
|
|
|
|
class Password(urwid.Edit):
|
|
|
|
def __init__(self, *args, **kwargs):
|
|
self.hidden_char=kwargs['hidden_char'] if kwargs.has_key('hidden_char') else '*'
|
|
self.__real_text=''
|
|
super(Password, self).__init__(*args, **kwargs)
|
|
|
|
def set_edit_text(self, text):
|
|
self.__real_text = text
|
|
hidden_txt = len(text)*'*'
|
|
super(Password, self).set_edit_text(hidden_txt)
|
|
|
|
def get_edit_text(self):
|
|
return self.__real_text
|
|
|
|
class SelectableText(urwid.FlowWidget):
|
|
signals = ['change']
|
|
|
|
def __init__(self, text, align='left'):
|
|
self.text=unicode(text)
|
|
self.align = align
|
|
self.__selected=False
|
|
|
|
def getValue(self):
|
|
return self.text
|
|
|
|
def setState(self, selected, invisible=False):
|
|
"""Change state
|
|
@param selected: boolean state value
|
|
@param invisible: don't emit change signal if True"""
|
|
assert(type(selected)==bool)
|
|
self.__selected=selected
|
|
if not invisible:
|
|
self._emit("change", self.__selected)
|
|
self._invalidate()
|
|
|
|
def getState(self):
|
|
return self.__selected
|
|
|
|
def selectable(self):
|
|
return True
|
|
|
|
def keypress(self, size, key):
|
|
if key==' ' or key=='enter':
|
|
self.setState(not self.__selected)
|
|
else:
|
|
return key
|
|
|
|
def rows(self,size,focus=False):
|
|
return self.display_widget(size, focus).rows(size, focus)
|
|
|
|
def render(self, size, focus=False):
|
|
return self.display_widget(size, focus).render(size, focus)
|
|
|
|
def display_widget(self, size, focus):
|
|
attr = 'selected' if self.__selected else 'default'
|
|
if focus:
|
|
attr+="_focus"
|
|
return urwid.Text((attr,self.text), align=self.align)
|
|
|
|
class List(urwid.WidgetWrap):
|
|
signals = ['change']
|
|
|
|
def __init__(self, options, style=[], align='left', on_state_change=None, user_data=None):
|
|
self.single = 'single' in style
|
|
self.align = align
|
|
|
|
if on_state_change:
|
|
urwid.connect_signal(self, 'change', on_state_change, user_data)
|
|
|
|
self.content = urwid.SimpleListWalker([])
|
|
self.list_box = urwid.ListBox(self.content)
|
|
self.changeValues(options)
|
|
|
|
def __onStateChange(self, widget, selected):
|
|
if self.single:
|
|
if not selected:
|
|
#if in single mode, it's forbidden to unselect a value
|
|
widget.setState(True, invisible=True)
|
|
return
|
|
else:
|
|
self.unselectAll(invisible=True)
|
|
widget.setState(True, invisible=True)
|
|
self._emit("change")
|
|
|
|
|
|
def unselectAll(self, invisible=False):
|
|
for widget in self.content:
|
|
if widget.getState():
|
|
widget.setState(False, invisible)
|
|
widget._invalidate()
|
|
|
|
def deleteValue(self, value):
|
|
"""Delete the first value equal to the param given"""
|
|
try:
|
|
self.content.remove(value)
|
|
except ValueError:
|
|
pass
|
|
|
|
def getValue(self):
|
|
"""Convenience method to get the value selected as a string in single mode, or None"""
|
|
values = self.getValues()
|
|
return values[0] if values else None
|
|
|
|
def getValues(self):
|
|
result = []
|
|
for widget in self.content:
|
|
if widget.getState():
|
|
result.append(widget.getValue())
|
|
return result
|
|
|
|
def changeValues(self, new_values):
|
|
"""Change all value in one shot"""
|
|
widgets = [SelectableText(option, self.align) for option in new_values]
|
|
for widget in widgets:
|
|
urwid.connect_signal(widget, 'change', self.__onStateChange)
|
|
self.content[:] = widgets
|
|
if self.single and new_values:
|
|
self.content[0].setState(True)
|
|
display_widget = urwid.BoxAdapter(self.list_box, min(len(new_values),5))
|
|
urwid.WidgetWrap.__init__(self, display_widget)
|
|
|
|
def selectValue(self, value):
|
|
self.unselectAll()
|
|
idx = 0
|
|
for widget in self.content:
|
|
if widget.getValue() == value:
|
|
widget.setState(True)
|
|
self.list_box.set_focus(idx)
|
|
return
|
|
idx+=1
|
|
|
|
class genericDialog(urwid.WidgetWrap):
|
|
|
|
def __init__(self, widgets_lst, title, style=[], **kwargs):
|
|
frame_header = urwid.AttrMap(urwid.Text(title,'center'),'title')
|
|
|
|
buttons = None
|
|
|
|
if "OK/CANCEL" in style:
|
|
buttons = [urwid.Button(_("Cancel"), kwargs['cancel_cb']),
|
|
urwid.Button(_("Ok"), kwargs['ok_cb'], kwargs['ok_value'])]
|
|
elif "YES/NO" in style:
|
|
buttons = [urwid.Button(_("Yes"), kwargs['yes_cb']),
|
|
urwid.Button(_("No"), kwargs['no_cb'], kwargs['yes_value'])]
|
|
if "OK" in style:
|
|
buttons = [urwid.Button(_("Ok"), kwargs['ok_cb'], kwargs['ok_value'])]
|
|
if buttons:
|
|
buttons_flow = urwid.GridFlow(buttons, max([len(button.get_label()) for button in buttons])+4, 1, 1, 'center')
|
|
widgets_lst.append(buttons_flow)
|
|
body_content = urwid.SimpleListWalker(widgets_lst)
|
|
frame_body = urwid.ListBox(body_content)
|
|
frame = urwid.Frame(frame_body, frame_header)
|
|
decorated_frame = urwid.LineBox(frame)
|
|
urwid.WidgetWrap.__init__(self, decorated_frame)
|
|
|
|
|
|
|
|
class InputDialog(genericDialog):
|
|
|
|
def __init__(self, title, instrucions, style=['OK/CANCEL'], **kwargs):
|
|
instr_wid = urwid.Text(instrucions+':')
|
|
edit_box = urwid.Edit()
|
|
genericDialog.__init__(self, [instr_wid,edit_box], title, style, ok_value=edit_box, **kwargs)
|
|
|
|
class ConfirmDialog(genericDialog):
|
|
|
|
def __init__(self, title, style=['YES/NO'], **kwargs):
|
|
genericDialog.__init__(self, [], title, style, yes_value=None, **kwargs)
|
|
|
|
class Alert(genericDialog):
|
|
|
|
def __init__(self, title, message, style=['OK'], **kwargs):
|
|
genericDialog.__init__(self, [urwid.Text(message, 'center')], title, style, ok_value=None, **kwargs)
|