[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)
|
helpers.launch_browser_mailer('url', url)
|
||||||
|
|
||||||
def __init__(self, type_id, parent_win, widget_name, contact, acct,
|
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:
|
if resource is None:
|
||||||
# We very likely got a contact with a random resource.
|
# We very likely got a contact with a random resource.
|
||||||
# This is bad, we need the highest for caps etc.
|
# This is bad, we need the highest for caps etc.
|
||||||
|
@ -426,6 +430,11 @@ class ChatControlBase(MessageControl, ChatCommandProcessor, CommandTools):
|
||||||
spell.set_language(lang)
|
spell.set_language(lang)
|
||||||
widget.set_active(True)
|
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()
|
item = gtk.SeparatorMenuItem()
|
||||||
menu.prepend(item)
|
menu.prepend(item)
|
||||||
|
|
||||||
|
@ -586,6 +595,20 @@ class ChatControlBase(MessageControl, ChatCommandProcessor, CommandTools):
|
||||||
set_emoticons_menu_position, 1, 0)
|
set_emoticons_menu_position, 1, 0)
|
||||||
|
|
||||||
def _on_message_textview_key_press_event(self, widget, event):
|
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
|
# Ctrl [+ Shift] + Tab are not forwarded to notebook. We handle it here
|
||||||
if self.widget_name == 'groupchat_control':
|
if self.widget_name == 'groupchat_control':
|
||||||
if event.keyval not in (gtk.keysyms.ISO_Left_Tab, gtk.keysyms.Tab):
|
if event.keyval not in (gtk.keysyms.ISO_Left_Tab, gtk.keysyms.Tab):
|
||||||
|
@ -608,7 +631,7 @@ class ChatControlBase(MessageControl, ChatCommandProcessor, CommandTools):
|
||||||
return False
|
return False
|
||||||
|
|
||||||
def _on_message_textview_mykeypress_event(self, widget, event_keyval,
|
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
|
When a key is pressed: if enter is pressed without the shift key, message
|
||||||
(if not empty) is sent and printed in the conversation
|
(if not empty) is sent and printed in the conversation
|
||||||
|
@ -665,6 +688,9 @@ class ChatControlBase(MessageControl, ChatCommandProcessor, CommandTools):
|
||||||
|
|
||||||
if send_message:
|
if send_message:
|
||||||
self.send_message(message, xhtml=xhtml) # send the 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:
|
else:
|
||||||
# Give the control itself a chance to process
|
# Give the control itself a chance to process
|
||||||
self.handle_message_textview_mykey_press(widget, event_keyval,
|
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
|
Class for the message textview (where user writes new messages) for
|
||||||
chat/groupchat windows
|
chat/groupchat windows
|
||||||
"""
|
"""
|
||||||
|
UNDO_LIMIT = 20
|
||||||
__gsignals__ = dict(
|
__gsignals__ = dict(
|
||||||
mykeypress = (gobject.SIGNAL_RUN_LAST | gobject.SIGNAL_ACTION,
|
mykeypress = (gobject.SIGNAL_RUN_LAST | gobject.SIGNAL_ACTION,
|
||||||
None, # return value
|
None, # return value
|
||||||
|
@ -56,6 +57,10 @@ class MessageTextView(gtk.TextView):
|
||||||
self.set_pixels_above_lines(2)
|
self.set_pixels_above_lines(2)
|
||||||
self.set_pixels_below_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
|
self.lang = None # Lang used for spell checking
|
||||||
_buffer = self.get_buffer()
|
_buffer = self.get_buffer()
|
||||||
self.begin_tags = {}
|
self.begin_tags = {}
|
||||||
|
@ -287,6 +292,20 @@ class MessageTextView(gtk.TextView):
|
||||||
start, end = _buffer.get_bounds()
|
start, end = _buffer.get_bounds()
|
||||||
_buffer.delete(start, end)
|
_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
|
# We register depending on keysym and modifier some bindings
|
||||||
# but we also pass those as param so we can construct fake Event
|
# 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.CONTROL_MASK, 'mykeypress', int, gtk.keysyms.KP_Enter,
|
||||||
gtk.gdk.ModifierType, gtk.gdk.CONTROL_MASK)
|
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:
|
# vim: se ts=3:
|
||||||
|
|
Loading…
Reference in New Issue