# HG changeset patch # User Goffi # Date 1277969756 -28800 # Node ID e5ca221132801fbd59920692f6521bb538c24f9e # Parent f551e44adb253f0c69b2edf471212bd2ffca76f3 Primitivus: profile manager - new custom widgets: Password, List, GenericDialog, InputDialog, ConfirmationDialog diff -r f551e44adb25 -r e5ca22113280 frontends/primitivus/custom_widgets.py --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/frontends/primitivus/custom_widgets.py Thu Jul 01 15:35:56 2010 +0800 @@ -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 -r f551e44adb25 -r e5ca22113280 frontends/primitivus/primitivus --- a/frontends/primitivus/primitivus Wed Jun 30 14:24:24 2010 +0800 +++ b/frontends/primitivus/primitivus Thu Jul 01 15:35:56 2010 +0800 @@ -51,7 +51,12 @@ ### 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 @@ raise urwid.ExitMainLoop() def __buildMainWidget(self): + #main_widget = urwid.Filler(ProfileManager(self)) main_widget = ProfileManager(self) return main_widget diff -r f551e44adb25 -r e5ca22113280 frontends/primitivus/profile_manager.py --- a/frontends/primitivus/profile_manager.py Wed Jun 30 14:24:24 2010 +0800 +++ b/frontends/primitivus/profile_manager.py Thu Jul 01 15:35:56 2010 +0800 @@ -20,15 +20,81 @@ """ 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 -r f551e44adb25 -r e5ca22113280 frontends/wix/profile_manager.py --- a/frontends/wix/profile_manager.py Wed Jun 30 14:24:24 2010 +0800 +++ b/frontends/wix/profile_manager.py Thu Jul 01 15:35:56 2010 +0800 @@ -138,7 +138,6 @@ 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)