primitivus: Primitivus is now modal (vi-like behaviour):

- there are currently 3 modes: NORMAL, INSERTION and COMMAND
    - when a chat window is selected, INSERTION mode is set if possible
    - completion is managed according to mode. Currently only INSERTION mode do something
    - first command implementation: :quit
This commit is contained in:
Goffi 2012-10-21 16:40:19 +02:00
commit 4e1905c238
3 changed files with 49 additions and 14 deletions

View file

@ -107,6 +107,7 @@ class ContactList(urwid.WidgetWrap, QuickContactList):
widget.setState(widget.data == self.selected, invisible=True)
if self.selected in self.alert_jid:
self.alert_jid.remove(self.selected)
self.host.modeHint('INSERTION')
self.update()
self._emit('click')

View file

@ -66,6 +66,19 @@ class PrimitivusApp(QuickApp):
self.__saved_overlay = None
self.x_notify = Notify()
@property
def mode(self):
return self.editBar.mode
@mode.setter
def mode(self, value):
self.editBar.mode = value
def modeHint(self, value):
"""Change mode if make sens (i.e.: if there is nothing in the editBar"""
if not self.editBar.get_edit_text():
self.mode = value
def debug(self):
"""convenient method to reset screen and launch p(u)db"""
@ -160,6 +173,14 @@ class PrimitivusApp(QuickApp):
except AttributeError:
return input
def commandHandler(self, editBar):
#TODO: separate class with auto documentation (with introspection)
# and completion method
command = editBar.get_edit_text()
if command == 'quit':
self.onExit()
raise urwid.ExitMainLoop()
def __buildMenuRoller(self):
menu = sat_widgets.Menu(self.loop)
general = _("General")
@ -193,13 +214,23 @@ class PrimitivusApp(QuickApp):
self.contact_list = ContactList(self, on_click = self.contactSelected, on_change=lambda w: self.redraw())
#self.center_part = urwid.Columns([('weight',2,self.contact_list),('weight',8,Chat('',self))])
self.center_part = urwid.Columns([('weight',2,self.contact_list), ('weight',8,urwid.Filler(urwid.Text('')))])
self.editBar = sat_widgets.AdvancedEdit(u'> ')
self.editBar.setCompletionMethod(self._nick_completion)
modes = {None: ('NORMAL', ''),
'i': ('INSERTION','> '),
':': ('COMMAND',':')}
self.editBar = sat_widgets.ModalEdit(modes)
self.editBar.setCompletionMethod(self._text_completion)
urwid.connect_signal(self.editBar,'click',self.onTextEntered)
self.menu_roller = self.__buildMenuRoller()
self.main_widget = sat_widgets.FocusFrame(self.center_part, header=self.menu_roller, footer=self.editBar, focus_part='footer')
return self.main_widget
def _text_completion(self, text, completion_data, mode):
if mode == 'INSERTION':
return self._nick_completion(text, completion_data)
else:
return text
def _nick_completion(self, text, completion_data):
"""Completion method which complete pseudo in group chat
for params, see AdvancedEdit"""
@ -291,17 +322,20 @@ class PrimitivusApp(QuickApp):
def onTextEntered(self, editBar):
"""Called when text is entered in the main edit bar"""
contact = self.contact_list.getContact() ###Based on the fact that there is currently only one contact selectableat once
if contact:
chat = self.chat_wins[contact]
try:
self.sendMessage(contact,
editBar.get_edit_text(),
mess_type = "groupchat" if chat.type == 'group' else "chat",
profile_key=self.profile)
except:
self.notify(_("Error while sending message"))
editBar.set_edit_text('')
if self.mode == 'INSERTION':
contact = self.contact_list.getContact() ###Based on the fact that there is currently only one contact selectableat once
if contact:
chat = self.chat_wins[contact]
try:
self.sendMessage(contact,
editBar.get_edit_text(),
mess_type = "groupchat" if chat.type == 'group' else "chat",
profile_key=self.profile)
except:
self.notify(_("Error while sending message"))
editBar.set_edit_text('')
elif self.mode == 'COMMAND':
self.commandHandler(editBar)
def newMessage(self, from_jid, to_jid, msg, _type, extra, profile):
QuickApp.newMessage(self, from_jid, to_jid, msg, _type, extra, profile)

View file

@ -30,7 +30,7 @@ import sat_frontends.quick_frontend.constants
import gettext
gettext.install('sat_frontend', "../i18n", unicode=True)
class QuickApp():
class QuickApp(object):
"""This class contain the main methods needed for the frontend"""
def __init__(self, single_profile=True):