diff --git a/frontends/primitivus/custom_widgets.py b/frontends/primitivus/custom_widgets.py
new file mode 100644
index 00000000..7be8a234
--- /dev/null
+++ b/frontends/primitivus/custom_widgets.py
@@ -0,0 +1,179 @@
+#!/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 .
+"""
+
+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):
+ assert(options)
+ self.single = 'single' in style
+ self.align = align
+
+ if on_state_change:
+ urwid.connect_signal(self, 'change', on_state_change, user_data)
+
+ widgets = [SelectableText(option,align) for option in options]
+ for widget in widgets:
+ urwid.connect_signal(widget, 'change', self.__onStateChange)
+ self.content = urwid.SimpleListWalker(widgets)
+ self.list_box = urwid.ListBox(self.content)
+ if self.single:
+ self.content[0].setState(True)
+ display_widget = urwid.BoxAdapter(self.list_box, min(len(options),5))
+
+ urwid.WidgetWrap.__init__(self, display_widget)
+
+ 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 getValues(self):
+ result = []
+ for widget in self.content:
+ if widget.getState():
+ result.append(widget.getValue())
+ return result
+
+ def changeValues(self, new_values):
+ widgets = [SelectableText(self, option) for option in new_values]
+ self.content[:] = widgets
+
+ 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 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)
diff --git a/frontends/primitivus/primitivus b/frontends/primitivus/primitivus
index d425bf0e..a73181a4 100755
--- a/frontends/primitivus/primitivus
+++ b/frontends/primitivus/primitivus
@@ -51,7 +51,12 @@ logging.basicConfig(level=logging.CRITICAL, #TODO: configure it to put messages
###
const_APP_NAME = "Primitivus"
-const_PALETTE = [('title', 'black', 'light gray', 'standout,underline'),]
+const_PALETTE = [('title', 'black', 'light gray', 'standout,underline'),
+ ('selected', 'default', 'dark red'),
+ ('selected_focus', 'default,bold', 'dark red'),
+ ('default', 'default', 'default'),
+ ('default_focus', 'default,bold', 'default'),
+ ]
class PrimitivusApp(QuickApp):
@@ -70,6 +75,7 @@ class PrimitivusApp(QuickApp):
raise urwid.ExitMainLoop()
def __buildMainWidget(self):
+ #main_widget = urwid.Filler(ProfileManager(self))
main_widget = ProfileManager(self)
return main_widget
diff --git a/frontends/primitivus/profile_manager.py b/frontends/primitivus/profile_manager.py
index 6fe06bd1..a1420599 100644
--- a/frontends/primitivus/profile_manager.py
+++ b/frontends/primitivus/profile_manager.py
@@ -20,15 +20,81 @@ along with this program. If not, see .
"""
import urwid
+from custom_widgets import Password,List,InputDialog,ConfirmDialog
class ProfileManager(urwid.WidgetWrap):
def __init__(self, host):
self.host = host
+ #profiles list
profiles = self.host.bridge.getProfilesList()
- widgets = [urwid.Text(str(profiles))]
- content = urwid.SimpleListWalker(widgets)
- display_widget = urwid.Frame(urwid.ListBox(content),urwid.AttrMap(urwid.Text("Profile Manager",align='center'),'title'))
- urwid.WidgetWrap.__init__(self, display_widget)
+ profiles.sort()
+
+ #login & password box must be created before list because of onProfileChange
+ self.login_wid = urwid.Edit(_('Login:'),align='center')
+ self.pass_wid = Password(_('Password:'),align='center')
+
+ self.list_profile = List(profiles, style=['single'], align='center', on_state_change=self.onProfileChange)
+ #toto = urwid.Padding(urwid.Text('toto'), align='center')
+
+ #new & delete buttons
+ buttons = [urwid.Button(_("New"), self.onNewProfile),
+ urwid.Button(_("Delete"), self.onDeleteProfile)]
+ buttons_flow = urwid.GridFlow(buttons, max([len(button.get_label()) for button in buttons])+4, 1, 1, 'center')
+
+ #second part: login information:
+ divider = urwid.Divider('-')
+
+ #connect button
+ connect_button = urwid.Button(_("Connect"), self.onConnectProfile)
+
+ #we now build the widget
+ body_content = urwid.SimpleListWalker([buttons_flow,self.list_profile,divider,self.login_wid, self.pass_wid, connect_button])
+ frame_body = urwid.ListBox(body_content)
+ frame = urwid.Frame(frame_body,urwid.AttrMap(urwid.Text("Profile Manager",align='center'),'title'))
+ self.main_widget = urwid.LineBox(frame)
+ urwid.WidgetWrap.__init__(self, self.main_widget)
+
+ def __refillProfiles(self):
+ """Update the list of profiles"""
+ profiles = self.host.bridge.getProfilesList()
+ profiles.sort()
+ self.list_profile.changeValues(profiles)
+
+ def cancelDialog(self, button):
+ self._set_w(self.main_widget)
+
+ def newProfile(self, button, edit):
+ self._set_w(self.main_widget)
+ name = edit.get_edit_text()
+ self.host.bridge.createProfile(name)
+ self.__refillProfiles()
+ self.list_profile.selectValue(name)
+
+ def deleteProfile(self, button):
+ self._set_w(self.main_widget)
+ self.host.bridge.deleteProfile(self.list_profile.getValues()[0])
+ self.__refillProfiles()
+
+
+ def onNewProfile(self, e):
+ pop_up_widget = InputDialog(_("New profile"), _("Please enter a new profile name"), cancel_cb=self.cancelDialog, ok_cb=self.newProfile)
+ display_widget = urwid.Overlay(pop_up_widget, self.main_widget, 'center', ('relative', 40), 'middle', ('relative', 40))
+ self._set_w(display_widget)
+
+ def onDeleteProfile(self, e):
+ pop_up_widget = ConfirmDialog(_("Are you sure you want to delete the profile %s ?") % self.list_profile.getValues()[0], no_cb=self.cancelDialog, yes_cb=self.deleteProfile)
+ display_widget = urwid.Overlay(pop_up_widget, self.main_widget, 'center', ('relative', 40), 'middle', ('relative', 40))
+ self._set_w(display_widget)
+
+ def onProfileChange(self, list_wid):
+ profile_name = list_wid.getValues()[0]
+ jabberID = self.host.bridge.getParamA("JabberID", "Connection", profile_key=profile_name)
+ password = self.host.bridge.getParamA("Password", "Connection", profile_key=profile_name)
+ self.login_wid.set_edit_text(jabberID)
+ self.pass_wid.set_edit_text(password)
+
+ def onConnectProfile(self, button):
+ pass
diff --git a/frontends/wix/profile_manager.py b/frontends/wix/profile_manager.py
index cdac75b3..2589cace 100644
--- a/frontends/wix/profile_manager.py
+++ b/frontends/wix/profile_manager.py
@@ -138,7 +138,6 @@ class ProfileManager(wx.Panel):
old_pass = self.host.bridge.getParamA("Password", "Connection", profile_key=profile)
new_jid = self.login_jid.GetValue()
new_pass = self.login_pass.GetValue()
- print "old: %s, new: %s, old_pass: %s, new_pass: %s" % (old_jid, new_jid, old_pass, new_pass)
if old_jid != new_jid:
debug(_('Saving new JID and server'))
self.host.bridge.setParam("JabberID", new_jid, "Connection", profile)