[zimio & me] undo functionality in message text imput field. Fixes #4825

This commit is contained in:
Yann Leboulanger 2010-01-24 11:44:54 +01:00
parent 22576e9ebf
commit e462beba42
2 changed files with 51 additions and 2 deletions

View File

@ -230,7 +230,11 @@ class ChatControlBase(MessageControl, ChatCommandProcessor, CommandTools):
helpers.launch_browser_mailer('url', url)
def __init__(self, type_id, parent_win, widget_name, contact, acct,
resource = None):
resource=None):
# Undo needs this variable to know if space has been pressed.
# Initialize it to True so empty textview is saved in undo list
self.space_pressed = True
if resource is None:
# We very likely got a contact with a random resource.
# This is bad, we need the highest for caps etc.
@ -426,6 +430,11 @@ class ChatControlBase(MessageControl, ChatCommandProcessor, CommandTools):
spell.set_language(lang)
widget.set_active(True)
item = gtk.ImageMenuItem(gtk.STOCK_UNDO)
menu.prepend(item)
id_ = item.connect('activate', self.msg_textview.undo)
self.handlers[id_] = item
item = gtk.SeparatorMenuItem()
menu.prepend(item)
@ -586,6 +595,20 @@ class ChatControlBase(MessageControl, ChatCommandProcessor, CommandTools):
set_emoticons_menu_position, 1, 0)
def _on_message_textview_key_press_event(self, widget, event):
if event.keyval == gtk.keysyms.space:
self.space_pressed = True
elif (self.space_pressed or self.msg_textview.undo_pressed) and \
event.keyval not in (gtk.keysyms.Control_L, gtk.keysyms.Control_R) and \
not (event.keyval == gtk.keysyms.z and event.state & gtk.gdk.CONTROL_MASK):
# If the space key has been pressed and now it hasnt,
# we save the buffer into the undo list. But be carefull we're not
# pressiong Control again (as in ctrl+z)
_buffer = widget.get_buffer()
start_iter, end_iter = _buffer.get_bounds()
self.msg_textview.save_undo(_buffer.get_text(start_iter, end_iter))
self.space_pressed = False
# Ctrl [+ Shift] + Tab are not forwarded to notebook. We handle it here
if self.widget_name == 'groupchat_control':
if event.keyval not in (gtk.keysyms.ISO_Left_Tab, gtk.keysyms.Tab):
@ -608,7 +631,7 @@ class ChatControlBase(MessageControl, ChatCommandProcessor, CommandTools):
return False
def _on_message_textview_mykeypress_event(self, widget, event_keyval,
event_keymod):
event_keymod):
"""
When a key is pressed: if enter is pressed without the shift key, message
(if not empty) is sent and printed in the conversation
@ -665,6 +688,9 @@ class ChatControlBase(MessageControl, ChatCommandProcessor, CommandTools):
if send_message:
self.send_message(message, xhtml=xhtml) # send the message
elif event.keyval == gtk.keysyms.z: # CTRL+z
if event.state & gtk.gdk.CONTROL_MASK:
self.msg_textview.undo()
else:
# Give the control itself a chance to process
self.handle_message_textview_mykey_press(widget, event_keyval,

View File

@ -35,6 +35,7 @@ class MessageTextView(gtk.TextView):
Class for the message textview (where user writes new messages) for
chat/groupchat windows
"""
UNDO_LIMIT = 20
__gsignals__ = dict(
mykeypress = (gobject.SIGNAL_RUN_LAST | gobject.SIGNAL_ACTION,
None, # return value
@ -56,6 +57,10 @@ class MessageTextView(gtk.TextView):
self.set_pixels_above_lines(2)
self.set_pixels_below_lines(2)
# set undo list
self.undo_list = []
# needed to know if we undid something
self.undo_pressed = False
self.lang = None # Lang used for spell checking
_buffer = self.get_buffer()
self.begin_tags = {}
@ -287,6 +292,20 @@ class MessageTextView(gtk.TextView):
start, end = _buffer.get_bounds()
_buffer.delete(start, end)
def save_undo(self, text):
self.undo_list.append(text)
if len(self.undo_list) > self.UNDO_LIMIT:
del self.undo_list[0]
self.undo_pressed = False
def undo(self, widget=None):
"""
Undo text in the textview
"""
_buffer = self.get_buffer()
if self.undo_list:
_buffer.set_text(self.undo_list.pop())
self.undo_pressed = True
# We register depending on keysym and modifier some bindings
# but we also pass those as param so we can construct fake Event
@ -340,4 +359,8 @@ gtk.binding_entry_add_signal(MessageTextView, gtk.keysyms.KP_Enter,
gtk.gdk.CONTROL_MASK, 'mykeypress', int, gtk.keysyms.KP_Enter,
gtk.gdk.ModifierType, gtk.gdk.CONTROL_MASK)
# Ctrl + z
gtk.binding_entry_add_signal(MessageTextView, gtk.keysyms.z,
gtk.gdk.CONTROL_MASK, 'mykeypress', int, gtk.keysyms.z,
gtk.gdk.ModifierType, gtk.gdk.CONTROL_MASK)
# vim: se ts=3: