[zimio & me] undo functionality in message text imput field. Fixes #4825
This commit is contained in:
parent
22576e9ebf
commit
e462beba42
|
@ -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,
|
||||
|
|
|
@ -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:
|
||||
|
|
Loading…
Reference in New Issue