Commit 1b995e4b authored by louiz’'s avatar louiz’

Data form support.

supported yet:
text-single, text-private, list-single, boolean

The interface is really ugly, but, well, it works
parent 33c69df1
......@@ -54,6 +54,7 @@ class Connection(sleekxmpp.ClientXMPP):
self.auto_authorize = None
if config.get('send_poezio_info', 'true') == 'true':
info = {'name':'poezio',
......@@ -42,6 +42,7 @@ import multiuserchat as muc
import tabs
import windows
from data_forms import DataFormsTab
from connection import connection
from config import config
from logger import logger
......@@ -159,6 +160,8 @@ class Core(object):
self.xmpp.add_event_handler("roster_update", self.on_roster_update)
self.xmpp.add_event_handler("changed_status", self.on_presence)
self.xmpp.add_event_handler("changed_subscription", self.on_changed_subscription)
self.xmpp.add_event_handler("message_xform", self.on_data_form)
self.information(_('Welcome to poezio!'))
......@@ -196,6 +199,21 @@ class Core(object):
def on_data_form(self, message):
When a data form is received
self.information('%s' % messsage)
def open_new_form(self, form, on_cancel, on_send, **kwargs):
Open a new tab containing the form
The callback are called with the completed form as parameter in
addition with kwargs
form_tab = DataFormsTab(self, form, on_cancel, on_send, kwargs)
self.add_tab(form_tab, True)
def on_got_offline(self, presence):
jid = presence['from']
contact = roster.get_contact_by_jid(jid.bare)
......@@ -334,7 +352,7 @@ class Core(object):
if not room.joined: # user in the room BEFORE us.
# ignore redondant presence message, see bug #1509
if from_nick not in [user.nick for user in room.users]:
new_user = User(from_nick, affiliation, show, status, role)
new_user = User(from_nick, affiliation, show, status, role, jid)
if from_nick == room.own_nick:
room.joined = True
......@@ -700,6 +718,7 @@ class Core(object):
This diff is collapsed.
......@@ -51,6 +51,7 @@ class Tab(object):
def __init__(self, core):
self.core = core # a pointer to core, to access its attributes (ugly?)
self._color_state = theme.COLOR_TAB_NORMAL
self.nb = Tab.number
Tab.number += 1
self.size = (self.height, self.width) = self.core.stdscr.getmaxyx()
......@@ -133,7 +134,7 @@ class Tab(object):
returns the color that should be used in the GlobalInfoBar
return theme.COLOR_TAB_NORMAL
return self._color_state
def set_color_state(self, color):
......@@ -160,13 +161,13 @@ class Tab(object):
called when this tab loses the focus.
self._color_state = theme.COLOR_TAB_NORMAL
def on_gain_focus(self):
called when this tab gains the focus.
self._color_state = theme.COLOR_TAB_CURRENT
def add_message(self):
......@@ -367,7 +368,8 @@ class MucTab(ChatTab):
self.commands['nick'] = (self.command_nick, _("Usage: /nick <nickname>\nNick: Change your nickname in the current room"), None)
self.commands['recolor'] = (self.command_recolor, _('Usage: /recolor\nRecolor: Re-assign a color to all participants of the current room, based on the last time they talked. Use this if the participants currently talking have too many identical colors.'), None)
self.commands['cycle'] = (self.command_cycle, _('Usage: /cycle [message]\nCycle: Leaves the current room and rejoin it immediately'), None)
self.commands['info'] = (self.command_info, _('Usage: /info <nickname>\nInfoDisplay some information about the user in the MUC: his/here role, affiliation, status and status message.'), None)
self.commands['info'] = (self.command_info, _('Usage: /info <nickname>\nInfo: Display some information about the user in the MUC: his/here role, affiliation, status and status message.'), None)
self.commands['configure'] = (self.command_configure, _('Usage: /configure\nConfigure: Configure the current room, through a form.'), None)
def scroll_user_list_up(self):
......@@ -388,9 +390,28 @@ class MucTab(ChatTab):
user = self.get_room().get_user_by_name(args[0])
if not user:
return self.core.information("Unknown user: %s" % args[0])
self.get_room().add_message("%s: show: %s, affiliation: %s, role: %s\n%s"% (args[0], or 'Available', user.role or 'None', user.affiliation or 'None', user.status))
self.get_room().add_message("%s%s: show: %s, affiliation: %s, role: %s\n%s"% (args[0], or 'Available', user.role or 'None', user.affiliation or 'None', user.status))
def command_configure(self, arg):
form = self.core.xmpp.plugin['xep_0045'].getRoomForm(self.get_name())
self.core.information('%s' % form)
self.core.open_new_form(form, self.cancel_config, self.send_config)
def cancel_config(self, form):
The user do not want to send his/her config, send an iq cancel
def send_config(self, form):
The user sends his/her config to the server
self.core.xmpp.plugin['xep_0045'].configureRoom(self.get_name(), form)
def command_cycle(self, arg):
if self.get_room().joined:
muc.leave_groupchat(self.core.xmpp, self.get_name(), self.get_room().own_nick, arg)
......@@ -36,11 +36,12 @@ class User(object):
keep trace of an user in a Room
def __init__(self, nick, affiliation, show, status, role):
def __init__(self, nick, affiliation, show, status, role, jid):
self.last_talked = datetime(1, 1, 1) # The oldest possible time
self.update(affiliation, show, status, role)
self.color = choice(theme.LIST_COLOR_NICKNAMES)
self.jid = jid
def update(self, affiliation, show, status, role):
self.affiliation = affiliation
......@@ -695,19 +695,24 @@ class Input(Win):
"KEY_BACKSPACE": self.key_backspace,
'^?': self.key_backspace,
self.text = ''
self.pos = 0 # cursor position
self.line_pos = 0 # position (in self.text) of
self.on_input = None # callback called on any key pressed
self.color = None # use this color on addstr
def set_color(self, color):
self.color = color
def is_empty(self):
return len(self.text) == 0
def resize(self, height, width, y, x, stdscr):
def resize(self, height, width, y, x, stdscr=None): # TODO remove stdscr
self._resize(height, width, y, x, stdscr)
self.addnstr(0, 0, self.text, self.width-1)
# self._win.erase()
# self.addnstr(0, 0, self.text, self.width-1)
def jump_word_left(self):
......@@ -960,8 +965,12 @@ class Input(Win):
def do_command(self, key, reset=True):
log.debug('do_command: %s\n' % key)
if key in self.key_func:
return self.key_func[key]()
res = self.key_func[key]()
if self.on_input:
return res
if not key or len(key) > 1:
return False # ignore non-handled keyboard shortcuts
......@@ -973,6 +982,8 @@ class Input(Win):
self.pos += len(key)
if reset:
if self.on_input:
return True
def get_text(self):
......@@ -987,8 +998,16 @@ class Input(Win):
with g_lock:
if self.color:
if self.color:
(y, x) = self._win.getyx()
size = self.width-x
self.addnstr(' '*size, size, curses.color_pair(self.color))
self.addstr(0, self.pos, '') # WTF, this works but .move() doesn't…
if self.color:
def refresh(self):
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment