diff --git a/src/chat_control.py b/src/chat_control.py
index ab31ebc10..27c76eeaa 100644
--- a/src/chat_control.py
+++ b/src/chat_control.py
@@ -28,6 +28,8 @@ from common import helpers
from message_control import MessageControl
from conversation_textview import ConversationTextview
from message_textview import MessageTextView
+from common.logger import Constants
+constants = Constants()
try:
import gtkspell
@@ -76,6 +78,8 @@ class ChatControlBase(MessageControl):
'underline_togglebutton'):
self.xml.get_widget(w).set_no_show_all(True)
+ self.widget.connect('key_press_event', self._on_keypress_event)
+
# Create textviews and connect signals
self.conv_textview = ConversationTextview(None) # FIXME: remove account arg
self.conv_textview.show_all()
@@ -83,22 +87,21 @@ class ChatControlBase(MessageControl):
self.conv_scrolledwindow.add(self.conv_textview)
self.conv_scrolledwindow.get_vadjustment().connect('value-changed',
self.on_conversation_vadjustment_value_changed)
- self.conv_textview.connect('key_press_event',
- self.on_conversation_textview_key_press_event)
# add MessageTextView to UI and connect signals
self.msg_scrolledwindow = self.xml.get_widget('message_scrolledwindow')
self.msg_textview = MessageTextView()
self.msg_textview.connect('mykeypress',
- self.on_message_textview_mykeypress_event)
+ self._on_message_textview_mykeypress_event)
self.msg_scrolledwindow.add(self.msg_textview)
self.msg_textview.connect('key_press_event',
- self.on_message_textview_key_press_event)
+ self._on_message_textview_key_press_event)
self.msg_textview.connect('size-request', self.size_request, self.xml)
self.update_font()
+
# the following vars are used to keep history of user's messages
self.sent_history = []
- self.sent_history_pos = -1
+ self.sent_history_pos = 0
self.typing_new = False
self.orig_msg = ''
@@ -143,34 +146,43 @@ class ChatControlBase(MessageControl):
banner_name_label.modify_fg(gtk.STATE_NORMAL, None)
- def on_conversation_textview_key_press_event(self, widget, event):
- '''Handle events from the ConversationTextview'''
- print "ChatControl.on_conversation_textview_key_press_event", event
+ def _on_keypress_event(self, widget, event):
if event.state & gtk.gdk.CONTROL_MASK:
- # CTRL + l|L
+ # CTRL + l|L: clear conv_textview
if event.keyval == gtk.keysyms.l or event.keyval == gtk.keysyms.L:
self.conv_textview.get_buffer().set_text('')
- # CTRL + v
+ return True
+ # CTRL + v: Paste into msg_textview
elif event.keyval == gtk.keysyms.v:
if not self.msg_textview.is_focus():
self.msg_textview.grab_focus()
+ # Paste into the msg textview
self.msg_textview.emit('key_press_event', event)
+ return False
- def on_message_textview_key_press_event(self, widget, event):
- print "ChatControl.on_message_textview_key_press_event", event
-
- if event.keyval == gtk.keysyms.Page_Down: # PAGE DOWN
- if event.state & gtk.gdk.SHIFT_MASK: # SHIFT + PAGE DOWN
- self.conv_textview.emit('key_press_event', event)
- elif event.keyval == gtk.keysyms.Page_Up: # PAGE UP
- if event.state & gtk.gdk.SHIFT_MASK: # SHIFT + PAGE UP
+ def _on_message_textview_key_press_event(self, widget, event):
+ print "_on_message_textview_key_press_event"
+ if event.state & gtk.gdk.SHIFT_MASK:
+ # SHIFT + PAGE_[UP|DOWN]: send to conv_textview
+ if event.keyval == gtk.keysyms.Page_Down or \
+ event.keyval == gtk.keysyms.Page_Up:
self.conv_textview.emit('key_press_event', event)
+ return True
+ elif event.state & gtk.gdk.CONTROL_MASK or \
+ (event.keyval == gtk.keysyms.Control_L) or \
+ (event.keyval == gtk.keysyms.Control_R):
+ # we pressed a control key or ctrl+sth: we don't block
+ # the event in order to let ctrl+c (copy text) and
+ # others do their default work
+ self.conv_textview.emit('key_press_event', event)
+ return False
- def on_message_textview_mykeypress_event(self, widget, event_keyval,
+ def _on_message_textview_mykeypress_event(self, widget, event_keyval,
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'''
+ print "ChatControlBase._on_message_textview_mykeypress_event"
# NOTE: handles mykeypress which is custom signal connected to this
# CB in new_tab(). for this singal see message_textview.py
@@ -189,11 +201,9 @@ class ChatControlBase(MessageControl):
if event.keyval == gtk.keysyms.Up:
if event.state & gtk.gdk.CONTROL_MASK: # Ctrl+UP
self.sent_messages_scroll('up', widget.get_buffer())
- return
elif event.keyval == gtk.keysyms.Down:
if event.state & gtk.gdk.CONTROL_MASK: # Ctrl+Down
self.sent_messages_scroll('down', widget.get_buffer())
- return
elif event.keyval == gtk.keysyms.Return or \
event.keyval == gtk.keysyms.KP_Enter: # ENTER
# NOTE: SHIFT + ENTER is not needed to be emulated as it is not
@@ -295,8 +305,8 @@ class ChatControlBase(MessageControl):
self.nb_unread += 1
if gajim.interface.systray_enabled and\
gajim.config.get('trayicon_notification_on_new_messages'):
- gajim.interface.systray.add_jid(jid, self.account, self.type)
- self.parent_win.redraw_tab(jid)
+ gajim.interface.systray.add_jid(jid, self.account, self.type_id)
+ self.parent_win.redraw_tab(self.contact)
self.show_title(urgent)
def toggle_emoticons(self):
@@ -419,7 +429,7 @@ class ChatControlBase(MessageControl):
gajim.interface.systray.remove_jid(jid,
self.account,
self.type)
- self.conv_textview.grab_focus()
+ self.msg_textview.grab_focus()
def bring_scroll_to_end(self, textview, diff_y = 0):
''' scrolls to the end of textview if end is not visible '''
@@ -539,9 +549,8 @@ class ChatControl(ChatControlBase):
xm = gtk.glade.XML(GTKGUI_GLADE, 'chat_control_popup_menu', APP)
xm.signal_autoconnect(self)
self.popup_menu = xm.get_widget('chat_control_popup_menu')
- xm = gtk.glade.XML(GTKGUI_GLADE, 'banner_eventbox', APP)
- xm.signal_autoconnect(self)
+ # Initialize drag-n-drop
self.TARGET_TYPE_URI_LIST = 80
self.dnd_list = [ ( 'text/uri-list', 0, self.TARGET_TYPE_URI_LIST ) ]
self.widget.connect('drag_data_received', self._on_drag_data_received)
@@ -558,8 +567,58 @@ class ChatControl(ChatControlBase):
# chatstate timers and state
self.reset_kbd_mouse_timeout_vars()
self._schedule_activity_timers()
+
+ # Hook up signals
+ # FIXME: This does not seem to be working
self.parent_win.window.connect('motion-notify-event',
self._on_window_motion_notify)
+ message_tv_buffer = self.msg_textview.get_buffer()
+ message_tv_buffer.connect('changed', self._on_message_tv_buffer_changed)
+
+ self.xml.get_widget('banner_eventbox').connect('button-press-event',
+ self._on_banner_eventbox_button_press_event)
+ self.xml.get_widget('banner_eventbox').connect('button-press-event',
+ self._on_banner_eventbox_button_press_event)
+ xm = gtk.glade.XML(GTKGUI_GLADE, 'avatar_eventbox', APP)
+ xm.signal_autoconnect(self)
+
+ if self.contact.jid in gajim.encrypted_chats[self.account]:
+ self.xml.get_widget('gpg_togglebutton').set_active(True)
+
+ # restore previous conversation
+ self.restore_conversation()
+
+ if gajim.awaiting_events[self.account].has_key(self.contact.jid):
+ self.read_queue()
+
+ def _on_avatar_eventbox_enter_notify_event(self, widget, event):
+ '''we enter the eventbox area so we under conditions add a timeout
+ to show a bigger avatar after 0.5 sec'''
+ jid = self.contact.jid
+ real_jid = gajim.get_real_jid_from_fjid(self.account, jid)
+ if not real_jid: # this can happend if we're in a moderate room
+ return
+ avatar_pixbuf = gtkgui_helpers.get_avatar_pixbuf_from_cache(real_jid)
+ if avatar_pixbuf in ('ask', None):
+ return
+ avatar_w = avatar_pixbuf.get_width()
+ avatar_h = avatar_pixbuf.get_height()
+
+ scaled_buf = self.xmls[jid].get_widget('avatar_image').get_pixbuf()
+ scaled_buf_w = scaled_buf.get_width()
+ scaled_buf_h = scaled_buf.get_height()
+
+ # do we have something bigger to show?
+ if avatar_w > scaled_buf_w or avatar_h > scaled_buf_h:
+ # wait for 0.5 sec in case we leave earlier
+ self.show_bigger_avatar_timeout_id = gobject.timeout_add(500,
+ self.show_bigger_avatar, widget)
+
+ def _on_avatar_eventbox_leave_notify_event(self, widget, event):
+ '''we left the eventbox area that holds the avatar img'''
+ # did we add a timeout? if yes remove it
+ if self.show_bigger_avatar_timeout_id is not None:
+ gobject.source_remove(self.show_bigger_avatar_timeout_id)
def save_var(self, jid):
gpg_enabled = self.xmls[jid].get_widget('gpg_togglebutton').get_active()
@@ -949,8 +1008,7 @@ class ChatControl(ChatControlBase):
def send_chatstate(self, state, contact = None):
''' sends OUR chatstate as STANDLONE chat state message (eg. no body)
- to jid only if new chatstate is different
- from the previous one
+ to contact only if new chatstate is different from the previous one
if jid is not specified, send to active tab'''
# JEP 85 does not allow resending the same chatstate
# this function checks for that and just returns so it's safe to call it
@@ -1058,7 +1116,7 @@ class ChatControl(ChatControlBase):
# update chatstate in tab for this chat
self.parent_win.redraw_tab(self.contact, self.contact.chatstate)
- def on_banner_eventbox_button_press_event(self, widget, event):
+ def _on_banner_eventbox_button_press_event(self, widget, event):
'''If right-clicked, show popup'''
if event.button == 3: # right click
self.parent_win.popup_menu(event)
@@ -1109,3 +1167,117 @@ class ChatControl(ChatControlBase):
if os.path.isfile(path): # is it file?
ft = gajim.interface.instances['file_transfers']
ft.send_file(self.account, self.contact, path)
+
+ def _on_message_tv_buffer_changed(self, textbuffer):
+ self.kbd_activity_in_last_5_secs = True
+ self.kbd_activity_in_last_30_secs = True
+ if textbuffer.get_char_count():
+ self.send_chatstate('composing', self.contact)
+ else:
+ self.send_chatstate('active', self.contact)
+
+ def restore_conversation(self):
+ jid = self.contact.jid
+ # don't restore lines if it's a transport
+ if gajim.jid_is_transport(jid):
+ return
+
+ # How many lines to restore and when to time them out
+ restore_how_many = gajim.config.get('restore_lines')
+ timeout = gajim.config.get('restore_timeout') # in minutes
+ # number of messages that are in queue and are already logged
+ pending_how_many = 0 # we want to avoid duplication
+
+ if gajim.awaiting_events[self.account].has_key(jid):
+ events = gajim.awaiting_events[self.account][jid]
+ for event in events:
+ if event[0] == 'chat':
+ pending_how_many += 1
+
+ rows = gajim.logger.get_last_conversation_lines(jid, restore_how_many,
+ pending_how_many, timeout)
+
+ for row in rows: # row[0] time, row[1] has kind, row[2] the message
+ if not row[2]: # message is empty, we don't print it
+ continue
+ if row[1] in (constants.KIND_CHAT_MSG_SENT,
+ constants.KIND_SINGLE_MSG_SENT):
+ kind = 'outgoing'
+ name = gajim.nicks[self.account]
+ elif row[1] in (constants.KIND_SINGLE_MSG_RECV,
+ constants.KIND_CHAT_MSG_RECV):
+ kind = 'incoming'
+ name = self.contact.name
+
+ tim = time.localtime(float(row[0]))
+
+ ChatControlBase.print_conversation_line(self, row[2], kind, name, tim,
+ ['small'],
+ ['small', 'restored_message'],
+ ['small', 'restored_message'],
+ False)
+ if len(rows):
+ self.conv_textview.print_empty_line()
+
+ def read_queue(self):
+ '''read queue and print messages containted in it'''
+ jid = self.contact.jid
+ l = gajim.awaiting_events[self.account][jid]
+
+ # Is it a pm ?
+ is_pm = False
+ room_jid, nick = gajim.get_room_and_nick_from_fjid(jid)
+ # FIXME: Accessing gc's, here?
+ gcs = gajim.interface.instances[self.account]['gc']
+ if gcs.has_key(room_jid):
+ is_pm = True
+ events_to_keep = []
+ for event in l:
+ typ = event[0]
+ if typ != 'chat':
+ events_to_keep.append(event)
+ continue
+ data = event[1]
+ kind = data[2]
+ if kind == 'error':
+ kind = 'status'
+ else:
+ kind = 'print_queue'
+ self.print_conversation(data[0], kind, tim = data[3],
+ encrypted = data[4], subject = data[1])
+
+ # remove from gc nb_unread if it's pm or from roster
+ if is_pm:
+ gcs[room_jid].nb_unread[room_jid] -= 1
+ else:
+ gajim.interface.roster.nb_unread -= 1
+
+ if is_pm:
+ gcs[room_jid].show_title()
+ else:
+ gajim.interface.roster.show_title()
+ # Keep only non-messages events
+ if len(events_to_keep):
+ gajim.awaiting_events[self.account][jid] = events_to_keep
+ else:
+ del gajim.awaiting_events[self.account][jid]
+ typ = 'chat' # Is it a normal chat or a pm ?
+ # reset to status image in gc if it is a pm
+ # FIXME: New data structure
+ gcs = gajim.interface.instances[self.account]['gc']
+ if gcs.has_key(room_jid):
+ gcs[room_jid].draw_all_roster()
+ typ = 'pm'
+
+ gajim.interface.roster.draw_contact(jid, self.account)
+ if gajim.interface.systray_enabled:
+ gajim.interface.systray.remove_jid(jid, self.account, typ)
+ if (self.contact.show == 'offline' or self.contact.show == 'error'):
+ showOffline = gajim.config.get('showoffline')
+ if not showOffline and typ == 'chat' and \
+ len(gajim.contacts[self.account][jid]) == 1:
+ gajim.interface.roster.really_remove_contact(self.contact,
+ self.account)
+ elif typ == 'pm':
+ gcs[room_jid].remove_contact(room_jid, nick)
+
diff --git a/src/gtkgui.glade b/src/gtkgui.glade
index bf6930382..0ff8766c3 100644
--- a/src/gtkgui.glade
+++ b/src/gtkgui.glade
@@ -19081,7 +19081,6 @@ Maybe I'll refactor later
True
True
False
-
@@ -19150,8 +19149,8 @@ Status message
True
False
False
-
-
+
+
diff --git a/src/message_control.py b/src/message_control.py
index 0d1d54809..27bdd9336 100644
--- a/src/message_control.py
+++ b/src/message_control.py
@@ -61,6 +61,12 @@ class MessageControl:
or inactive (state is False)'''
pass # Derived types MUST implement this method
+ def allow_shutdown(self):
+ '''Called to check is a control is allowed to shutdown.
+ If a control is not in a suitable shutdown state this method
+ should return False'''
+ # NOTE: Derived classes MAY implement this
+ return True
def shutdown(self):
# NOTE: Derived classes MUST implement this
assert(False)
@@ -92,12 +98,6 @@ class MessageControl:
def set_compact_view(self, state):
# NOTE: Derived classes MAY implement this
self.compact_view_current = state
- def allow_shutdown(self):
- '''Called to check is a control is allowed to shutdown.
- If a control is not in a suitable shutdown state this method
- should return False'''
- # NOTE: Derived classes MAY implement this
- return True
def save_var(self, jid):
'''When called, the derived type should serialize it's state in the form of a
@@ -107,6 +107,9 @@ class MessageControl:
def load_var(self, jid, var):
pass # Derived classes SHOULD implement this
+ def get_specific_unread(self, jid):
+ return 0
+
def send_message(self, message, keyID = '', type = 'chat', chatstate = None):
'''Send the given message to the active tab'''
# refresh timers
diff --git a/src/message_window.py b/src/message_window.py
index 887b4d748..a70788223 100644
--- a/src/message_window.py
+++ b/src/message_window.py
@@ -20,6 +20,7 @@ import gobject
import common
import gtkgui_helpers
import message_control
+from chat_control import ChatControlBase
from common import gajim
@@ -47,7 +48,12 @@ class MessageWindow:
# so this line adds that
#self.window.set_events(gtk.gdk.POINTER_MOTION_MASK)
self.alignment = self.xml.get_widget('alignment')
+
self.notebook = self.xml.get_widget('notebook')
+ self.notebook.connect('switch-page',
+ self._on_notebook_switch_page)
+ self.notebook.connect('key-press-event',
+ self._on_notebook_key_press)
# Remove the glade pages
while self.notebook.get_n_pages():
@@ -72,10 +78,6 @@ class MessageWindow:
else:
self.notebook.set_show_tabs(False)
self.notebook.set_show_border(gajim.config.get('tabs_border'))
- self.notebook.connect('switch-page',
- self._on_notebook_switch_page)
- self.notebook.connect('key-press-event',
- self._on_notebook_key_press)
# Connect event handling for this Window
self.window.connect('delete-event', self._on_window_delete)
@@ -92,6 +94,8 @@ class MessageWindow:
gajim.config.get('msgwin-width'),
gajim.config.get('msgwin-height'))
+ self.window.show_all()
+
def _on_window_focus(self, widget, event):
# window received focus, so if we had urgency REMOVE IT
# NOTE: we do not have to read the message (it maybe in a bg tab)
@@ -144,13 +148,9 @@ class MessageWindow:
self.alignment.set_property('top-padding', 2)
# Connect to keyboard events
- control.widget.connect('key_press_event',
- self.on_conversation_textview_key_press_event)
- # FIXME: need to get this event without access to message_textvier
- #control.widget.connect('mykeypress',
- # self.on_message_textview_mykeypress_event)
- control.widget.connect('key_press_event',
- self.on_message_textview_key_press_event)
+ if isinstance(control, ChatControlBase):
+ control.msg_textview.connect('mykeypress',
+ self._on_message_textview_mykeypress_event)
# Add notebook page and connect up to the tab's close button
xml = gtk.glade.XML(GTKGUI_GLADE, 'chat_tab_ebox', APP)
@@ -163,10 +163,11 @@ class MessageWindow:
self.redraw_tab(control.contact)
- self.show_title()
+ control.draw_widgets()
self.window.show_all()
# NOTE: we do not call set_control_active(True) since we don't know whether
# the tab is the active one.
+ self.show_title()
def on_tab_eventbox_button_press_event(self, widget, event, child):
if event.button == 3:
@@ -174,10 +175,8 @@ class MessageWindow:
self.notebook.set_current_page(n)
self.popup_menu(event)
- def on_message_textview_mykeypress_event(self, widget, event_keyval,
+ def _on_message_textview_mykeypress_event(self, widget, event_keyval,
event_keymod):
- # FIXME: Not called yet
- print "MessageWindow.on_message_textview_mykeypress_event:", event
# NOTE: handles mykeypress which is custom signal; see message_textview.py
# construct event instance from binding
@@ -186,26 +185,8 @@ class MessageWindow:
event.state = event_keymod
event.time = 0 # assign current time
- if event.keyval == gtk.keysyms.ISO_Left_Tab: # SHIFT + TAB
- if event.state & gtk.gdk.CONTROL_MASK: # CTRL + SHIFT + TAB
- self.notebook.emit('key_press_event', event)
- if event.keyval == gtk.keysyms.Tab:
- if event.state & gtk.gdk.CONTROL_MASK: # CTRL + TAB
- self.notebook.emit('key_press_event', event)
-
- def on_message_textview_key_press_event(self, widget, event):
- print "MessageWindow.on_message_textview_key_press_event:", event
- if event.keyval == gtk.keysyms.Page_Down: # PAGE DOWN
- if event.state & gtk.gdk.CONTROL_MASK: # CTRL + PAGE DOWN
- self.notebook.emit('key_press_event', event)
- elif event.keyval == gtk.keysyms.Page_Up: # PAGE UP
- if event.state & gtk.gdk.CONTROL_MASK: # CTRL + PAGE UP
- self.notebook.emit('key_press_event', event)
-
- def on_conversation_textview_key_press_event(self, widget, event):
- '''Do not block these events and send them to the notebook'''
- print "MessageWindow.on_conversation_textview_key_press_event:", event
if event.state & gtk.gdk.CONTROL_MASK:
+ # Tab switch bindings
if event.keyval == gtk.keysyms.Tab: # CTRL + TAB
self.notebook.emit('key_press_event', event)
elif event.keyval == gtk.keysyms.ISO_Left_Tab: # CTRL + SHIFT + TAB
@@ -283,6 +264,7 @@ class MessageWindow:
self.show_title()
def redraw_tab(self, contact, chatstate = None):
+ print self._controls
ctl = self._controls[contact.jid]
ctl.update_state()
@@ -430,7 +412,7 @@ class MessageWindow:
jid = ctl.contact.jid
if jid != self.get_active_jid():
item = gtk.ImageMenuItem(_('Switch to %s') %\
- self.names[jid])
+ ctl.contact.name)
img = gtk.image_new_from_stock(gtk.STOCK_JUMP_TO,
gtk.ICON_SIZE_MENU)
item.set_image(img)
@@ -450,24 +432,42 @@ class MessageWindow:
new_ctl.set_control_active(True)
def _on_notebook_key_press(self, widget, event):
+ print "MessageWindow._on_notebook_key_press event"
st = '1234567890' # alt+1 means the first tab (tab 0)
ctl = self.get_active_control()
- jid = ctl.jid
- if event.keyval == gtk.keysyms.Escape: # ESCAPE
- if ctl.type == TYPE_CHAT:
- self.remove_tab(jid)
+ contact = ctl.contact
+ jid = ctl.contact.jid
+
+ # MOD1 (ALT) mask
+ if event.state & gtk.gdk.MOD1_MASK:
+ # Tab switch bindings
+ if event.keyval == gtk.keysyms.Right: # ALT + RIGHT
+ new = self.notebook.get_current_page() + 1
+ if new >= self.notebook.get_n_pages():
+ new = 0
+ self.notebook.set_current_page(new)
+ elif event.keyval == gtk.keysyms.Left: # ALT + LEFT
+ new = self.notebook.get_current_page() - 1
+ if new < 0:
+ new = self.notebook.get_n_pages() - 1
+ self.notebook.set_current_page(new)
+ elif event.string and event.string in st and \
+ (event.state & gtk.gdk.MOD1_MASK): # ALT + 1,2,3..
+ self.notebook.set_current_page(st.index(event.string))
+ # Close tab bindings
+ elif event.keyval == gtk.keysyms.Escape: # ESCAPE
+ if ctl.type_id == message_control.TYPE_CHAT:
+ self.remove_tab(contact)
elif event.keyval == gtk.keysyms.F4 and \
(event.state & gtk.gdk.CONTROL_MASK): # CTRL + F4
- self.remove_tab(jid)
+ self.remove_tab(contact)
elif event.keyval == gtk.keysyms.w and \
(event.state & gtk.gdk.CONTROL_MASK): # CTRL + W
- self.remove_tab(jid)
- elif event.string and event.string in st and \
- (event.state & gtk.gdk.MOD1_MASK): # alt + 1,2,3..
- self.notebook.set_current_page(st.index(event.string))
+ self.remove_tab(contact)
elif event.keyval == gtk.keysyms.c and \
(event.state & gtk.gdk.MOD1_MASK): # alt + C toggles compact view
- ctl.set_compact_view(not self.compact_view_current_state)
+ ctl.set_compact_view(not ctl.compact_view_current)
+
# FIXME: Move this to ChatControlBase
elif event.keyval == gtk.keysyms.e and \
(event.state & gtk.gdk.MOD1_MASK): # alt + E opens emoticons menu
@@ -500,60 +500,6 @@ class MessageWindow:
# y -= (msg_tv.allocation.height / buf.get_line_count())
return (x, y, True) # push_in True
self.emoticons_menu.popup(None, None, set_emoticons_menu_position, 1, 0)
- # FIXME Move to ChatControlBase
- elif event.keyval == gtk.keysyms.Page_Down:
- if event.state & gtk.gdk.SHIFT_MASK: # SHIFT + PAGE DOWN
- conv_textview = self.conversation_textviews[jid]
- rect = conv_textview.get_visible_rect()
- iter = conv_textview.get_iter_at_location(rect.x,
- rect.y + rect.height)
- conv_textview.scroll_to_iter(iter, 0.1, True, 0, 0)
- # FIXME Move to ChatControlBase
- elif event.keyval == gtk.keysyms.Page_Up:
- if event.state & gtk.gdk.SHIFT_MASK: # SHIFT + PAGE UP
- conv_textview = self.conversation_textviews[jid]
- rect = conv_textview.get_visible_rect()
- iter = conv_textview.get_iter_at_location(rect.x, rect.y)
- conv_textview.scroll_to_iter(iter, 0.1, True, 0, 1)
- # FIXME Move to ChatControlBase
- elif event.keyval == gtk.keysyms.Up:
- if event.state & gtk.gdk.SHIFT_MASK: # SHIFT + UP
- conversation_scrolledwindow = self.xml.get_widget('conversation_scrolledwindow')
- conversation_scrolledwindow.emit('scroll-child',
- gtk.SCROLL_PAGE_BACKWARD, False)
- elif event.keyval == gtk.keysyms.ISO_Left_Tab: # SHIFT + TAB
- if event.state & gtk.gdk.CONTROL_MASK: # CTRL + SHIFT + TAB
- self.move_to_next_unread_tab(False)
- elif event.keyval == gtk.keysyms.Tab: # TAB
- if event.state & gtk.gdk.CONTROL_MASK: # CTRL + TAB
- self.move_to_next_unread_tab(True)
- # FIXME Move to ChatControlBase
- elif (event.keyval == gtk.keysyms.l or event.keyval == gtk.keysyms.L) \
- and event.state & gtk.gdk.CONTROL_MASK: # CTRL + L
- conv_textview = self.conversation_textviews[jid]
- conv_textview.get_buffer().set_text('')
- # FIXME Move to ChatControlBase
- elif event.keyval == gtk.keysyms.v and event.state & gtk.gdk.CONTROL_MASK:
- # CTRL + V
- msg_textview = self.message_textviews[jid]
- if not msg_textview.is_focus():
- msg_textview.grab_focus()
- msg_textview.emit('key_press_event', event)
- elif event.state & gtk.gdk.CONTROL_MASK or \
- (event.keyval == gtk.keysyms.Control_L) or \
- (event.keyval == gtk.keysyms.Control_R):
- # we pressed a control key or ctrl+sth: we don't block
- # the event in order to let ctrl+c (copy text) and
- # others do their default work
- pass
- # FIXME Move to ChatControlBase
- else: # it's a normal key press make sure message_textview has focus
- msg_textview = self.message_textviews[jid]
- if msg_textview.get_property('sensitive'):
- if not msg_textview.is_focus():
- msg_textview.grab_focus()
- msg_textview.emit('key_press_event', event)
-
################################################################################
class MessageWindowMgr:
@@ -581,7 +527,6 @@ class MessageWindowMgr:
def _new_window(self):
win = MessageWindow()
- win.window.show_all()
# we track the lifetime of this window
win.window.connect('destroy', self._on_window_destroy)
return win