Moved MessageControl into it's own file to avoid circular depency
This commit is contained in:
parent
b239d4ff00
commit
4b59506c97
|
@ -20,12 +20,12 @@ import gtk.glade
|
||||||
import pango
|
import pango
|
||||||
import gobject
|
import gobject
|
||||||
import gtkgui_helpers
|
import gtkgui_helpers
|
||||||
import message_window
|
import message_control
|
||||||
import dialogs
|
import dialogs
|
||||||
|
|
||||||
from common import gajim
|
from common import gajim
|
||||||
from common import helpers
|
from common import helpers
|
||||||
from message_window import MessageControl
|
from message_control import MessageControl
|
||||||
from conversation_textview import ConversationTextview
|
from conversation_textview import ConversationTextview
|
||||||
from message_textview import MessageTextView
|
from message_textview import MessageTextView
|
||||||
|
|
||||||
|
@ -406,7 +406,7 @@ class ChatControlBase(MessageControl):
|
||||||
################################################################################
|
################################################################################
|
||||||
class ChatControl(ChatControlBase):
|
class ChatControl(ChatControlBase):
|
||||||
'''A control for standard 1-1 chat'''
|
'''A control for standard 1-1 chat'''
|
||||||
TYPE_ID = 'chat'
|
TYPE_ID = message_control.TYPE_CHAT
|
||||||
|
|
||||||
def __init__(self, parent_win, contact, acct):
|
def __init__(self, parent_win, contact, acct):
|
||||||
ChatControlBase.__init__(self, self.TYPE_ID, parent_win, 'chat_child_vbox',
|
ChatControlBase.__init__(self, self.TYPE_ID, parent_win, 'chat_child_vbox',
|
||||||
|
|
|
@ -17,6 +17,7 @@ import gtk.glade
|
||||||
import pango
|
import pango
|
||||||
import gobject
|
import gobject
|
||||||
import gtkgui_helpers
|
import gtkgui_helpers
|
||||||
|
import message_control
|
||||||
|
|
||||||
from common import gajim
|
from common import gajim
|
||||||
from chat_control import ChatControl
|
from chat_control import ChatControl
|
||||||
|
@ -25,7 +26,7 @@ from conversation_textview import ConversationTextview
|
||||||
from message_textview import MessageTextView
|
from message_textview import MessageTextView
|
||||||
|
|
||||||
class PrivateChatControl(ChatControl):
|
class PrivateChatControl(ChatControl):
|
||||||
TYPE_ID = 'pm'
|
TYPE_ID = message_control.TYPE_PM
|
||||||
|
|
||||||
def __init__(self, parent_win, contact, acct):
|
def __init__(self, parent_win, contact, acct):
|
||||||
ChatControl.__init__(self, parent_win, contact, acct)
|
ChatControl.__init__(self, parent_win, contact, acct)
|
||||||
|
@ -33,7 +34,7 @@ class PrivateChatControl(ChatControl):
|
||||||
self.display_name = _('Private char')
|
self.display_name = _('Private char')
|
||||||
|
|
||||||
class GroupchatControl(ChatControlBase):
|
class GroupchatControl(ChatControlBase):
|
||||||
TYPE_ID = 'gc'
|
TYPE_ID = message_control.TYPE_GC
|
||||||
|
|
||||||
def __init__(self, parent_win, contact, acct):
|
def __init__(self, parent_win, contact, acct):
|
||||||
ChatControlBase.__init__(self, self.TYPE_ID, parent_win,
|
ChatControlBase.__init__(self, self.TYPE_ID, parent_win,
|
||||||
|
|
|
@ -1184,6 +1184,7 @@ current room topic.') % command, room_jid)
|
||||||
nick = model[iter][C_NICK].decode('utf-8')
|
nick = model[iter][C_NICK].decode('utf-8')
|
||||||
room_jid = self.get_active_jid()
|
room_jid = self.get_active_jid()
|
||||||
fjid = gajim.construct_fjid(room_jid, nick) # 'fake' jid
|
fjid = gajim.construct_fjid(room_jid, nick) # 'fake' jid
|
||||||
|
# FIXME
|
||||||
if not gajim.interface.instances[self.account]['chats'].has_key(fjid):
|
if not gajim.interface.instances[self.account]['chats'].has_key(fjid):
|
||||||
gc_c = gajim.contacts.get_gc_contact(self.account, room_jid, nick)
|
gc_c = gajim.contacts.get_gc_contact(self.account, room_jid, nick)
|
||||||
c = gajim.contacts.contact_from_gc_contact(gc_c)
|
c = gajim.contacts.contact_from_gc_contact(gc_c)
|
||||||
|
@ -1493,6 +1494,7 @@ current room topic.') % command, room_jid)
|
||||||
no_queue = False
|
no_queue = False
|
||||||
|
|
||||||
# We print if window is opened
|
# We print if window is opened
|
||||||
|
# FIXME
|
||||||
if gajim.interface.instances[self.account]['chats'].has_key(fjid):
|
if gajim.interface.instances[self.account]['chats'].has_key(fjid):
|
||||||
chat_win = gajim.interface.instances[self.account]['chats'][fjid]
|
chat_win = gajim.interface.instances[self.account]['chats'][fjid]
|
||||||
chat_win.print_conversation(msg, fjid, tim = tim)
|
chat_win.print_conversation(msg, fjid, tim = tim)
|
||||||
|
@ -1627,6 +1629,7 @@ current room topic.') % command, room_jid)
|
||||||
if len(path) == 2:
|
if len(path) == 2:
|
||||||
nick = model[iter][C_NICK].decode('utf-8')
|
nick = model[iter][C_NICK].decode('utf-8')
|
||||||
fjid = gajim.construct_fjid(room_jid, nick)
|
fjid = gajim.construct_fjid(room_jid, nick)
|
||||||
|
# FIXME
|
||||||
if not gajim.interface.instances[self.account]['chats'].has_key(fjid):
|
if not gajim.interface.instances[self.account]['chats'].has_key(fjid):
|
||||||
gc_c = gajim.contacts.get_gc_contact(self.account, room_jid,
|
gc_c = gajim.contacts.get_gc_contact(self.account, room_jid,
|
||||||
nick)
|
nick)
|
||||||
|
@ -1671,6 +1674,7 @@ current room topic.') % command, room_jid)
|
||||||
room_jid = self.get_active_jid()
|
room_jid = self.get_active_jid()
|
||||||
nick = model[iter][C_NICK].decode('utf-8')
|
nick = model[iter][C_NICK].decode('utf-8')
|
||||||
jid = gajim.construct_fjid(room_jid, nick)
|
jid = gajim.construct_fjid(room_jid, nick)
|
||||||
|
# FIXME
|
||||||
if not gajim.interface.instances[self.account]['chats'].has_key(jid):
|
if not gajim.interface.instances[self.account]['chats'].has_key(jid):
|
||||||
gc_c = gajim.contacts.get_gc_contact(self.account, room_jid, nick)
|
gc_c = gajim.contacts.get_gc_contact(self.account, room_jid, nick)
|
||||||
gajim.interface.roster.new_chat(gc_c, self.account)
|
gajim.interface.roster.new_chat(gc_c, self.account)
|
||||||
|
|
|
@ -0,0 +1,135 @@
|
||||||
|
## message_control.py
|
||||||
|
##
|
||||||
|
## Copyright (C) 2005-2006 Travis Shirk <travis@pobox.com>
|
||||||
|
##
|
||||||
|
## This program is free software; you can redistribute it and/or modify
|
||||||
|
## it under the terms of the GNU General Public License as published
|
||||||
|
## by the Free Software Foundation; version 2 only.
|
||||||
|
##
|
||||||
|
## This program is distributed in the hope that it will be useful,
|
||||||
|
## but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
## GNU General Public License for more details.
|
||||||
|
##
|
||||||
|
import gtk
|
||||||
|
import gtk.glade
|
||||||
|
import pango
|
||||||
|
import gobject
|
||||||
|
import common
|
||||||
|
import gtkgui_helpers
|
||||||
|
|
||||||
|
from common import gajim
|
||||||
|
|
||||||
|
# Derived types MUST register their type IDs here if custom behavor is required
|
||||||
|
TYPE_CHAT = 'chat'
|
||||||
|
TYPE_GC = 'gc'
|
||||||
|
TYPE_PM = 'pm'
|
||||||
|
|
||||||
|
####################
|
||||||
|
# FIXME: Can't this stuff happen once?
|
||||||
|
from common import i18n
|
||||||
|
_ = i18n._
|
||||||
|
APP = i18n.APP
|
||||||
|
|
||||||
|
GTKGUI_GLADE = 'gtkgui.glade'
|
||||||
|
####################
|
||||||
|
|
||||||
|
class MessageControl(gtk.VBox):
|
||||||
|
'''An abstract base widget that can embed in the gtk.Notebook of a MessageWindow'''
|
||||||
|
|
||||||
|
def __init__(self, type_id, parent_win, widget_name, display_name, contact, account):
|
||||||
|
gtk.VBox.__init__(self)
|
||||||
|
|
||||||
|
self.type_id = type_id
|
||||||
|
self.parent_win = parent_win
|
||||||
|
self.widget_name = widget_name
|
||||||
|
self.display_name = display_name
|
||||||
|
self.contact = contact
|
||||||
|
self.account = account
|
||||||
|
self.compact_view_always = False
|
||||||
|
self.compact_view_current = False
|
||||||
|
self.nb_unread = 0
|
||||||
|
self.print_time_timeout_id = None
|
||||||
|
|
||||||
|
self.xml = gtk.glade.XML(GTKGUI_GLADE, widget_name, APP)
|
||||||
|
self.widget = self.xml.get_widget(widget_name)
|
||||||
|
# Autoconnect glade signals
|
||||||
|
self.xml.signal_autoconnect(self)
|
||||||
|
|
||||||
|
def shutdown(self):
|
||||||
|
# NOTE: Derived classes MUST implement this
|
||||||
|
assert(False)
|
||||||
|
def draw_widgets(self):
|
||||||
|
pass # NOTE: Derived classes SHOULD implement this
|
||||||
|
def repaint_themed_widgets(self, theme):
|
||||||
|
pass # NOTE: Derived classes SHOULD implement this
|
||||||
|
def update_state(self):
|
||||||
|
pass # NOTE: Derived classes SHOULD implement this
|
||||||
|
def toggle_emoticons(self):
|
||||||
|
pass # NOTE: Derived classes MAY implement this
|
||||||
|
def update_font(self):
|
||||||
|
pass # NOTE: Derived classes SHOULD implement this
|
||||||
|
def update_tags(self):
|
||||||
|
pass # NOTE: Derived classes SHOULD implement this
|
||||||
|
def print_time_timeout(self, arg):
|
||||||
|
# NOTE: Derived classes SHOULD implement this
|
||||||
|
if self.print_time_timeout_id:
|
||||||
|
gobject.source_remove(self.print_time_timeout_id)
|
||||||
|
del self.print_time_timeout_id
|
||||||
|
return False
|
||||||
|
def markup_tab_label(self, label_str, chatstate):
|
||||||
|
# NOTE: Derived classes SHOULD implement this
|
||||||
|
# Reurn a markup'd label and optional gtk.Color
|
||||||
|
return (label_str, None)
|
||||||
|
def prepare_context_menu(self):
|
||||||
|
# NOTE: Derived classes SHOULD implement this
|
||||||
|
return None
|
||||||
|
def set_compact_view(self, state):
|
||||||
|
# NOTE: Derived classes MAY implement this
|
||||||
|
self.compact_view_current = state
|
||||||
|
def check_delete(self):
|
||||||
|
'''Called when a window has been asked to delete itself. If a control is
|
||||||
|
not in a suitable shutdown state this method should return True to halt
|
||||||
|
the delete'''
|
||||||
|
# NOTE: Derived classes MAY implement this
|
||||||
|
return False
|
||||||
|
|
||||||
|
def send_message(self, message, keyID = '', type = 'chat', chatstate = None):
|
||||||
|
'''Send the given message to the active tab'''
|
||||||
|
# refresh timers
|
||||||
|
self.reset_kbd_mouse_timeout_vars()
|
||||||
|
|
||||||
|
jid = self.contact.jid
|
||||||
|
# Send and update history
|
||||||
|
gajim.connections[self.account].send_message(jid, message, keyID,
|
||||||
|
type = type, chatstate = chatstate)
|
||||||
|
|
||||||
|
def position_menu_under_button(self, menu):
|
||||||
|
#FIXME: BUG http://bugs.gnome.org/show_bug.cgi?id=316786
|
||||||
|
# pass btn instance when this bug is over
|
||||||
|
button = self.button_clicked
|
||||||
|
# here I get the coordinates of the button relative to
|
||||||
|
# window (self.window)
|
||||||
|
button_x, button_y = button.allocation.x, button.allocation.y
|
||||||
|
|
||||||
|
# now convert them to X11-relative
|
||||||
|
window_x, window_y = self.parent_win.get_origin()
|
||||||
|
x = window_x + button_x
|
||||||
|
y = window_y + button_y
|
||||||
|
|
||||||
|
menu_width, menu_height = menu.size_request()
|
||||||
|
|
||||||
|
## should we pop down or up?
|
||||||
|
if (y + button.allocation.height + menu_height
|
||||||
|
< gtk.gdk.screen_height()):
|
||||||
|
# now move the menu below the button
|
||||||
|
y += button.allocation.height
|
||||||
|
else:
|
||||||
|
# now move the menu above the button
|
||||||
|
y -= menu_height
|
||||||
|
|
||||||
|
|
||||||
|
# push_in is True so all the menuitems are always inside screen
|
||||||
|
push_in = True
|
||||||
|
return (x, y, push_in)
|
||||||
|
|
|
@ -19,6 +19,7 @@ import gobject
|
||||||
|
|
||||||
import common
|
import common
|
||||||
import gtkgui_helpers
|
import gtkgui_helpers
|
||||||
|
import message_control
|
||||||
|
|
||||||
from common import gajim
|
from common import gajim
|
||||||
|
|
||||||
|
@ -71,6 +72,7 @@ class MessageWindow:
|
||||||
# Connect event handling for this Window
|
# Connect event handling for this Window
|
||||||
self.window.connect('delete-event', self._on_window_delete)
|
self.window.connect('delete-event', self._on_window_delete)
|
||||||
self.window.connect('destroy', self._on_window_destroy)
|
self.window.connect('destroy', self._on_window_destroy)
|
||||||
|
self.window.connect('focus-in-event', self._on_window_focus)
|
||||||
|
|
||||||
# Restore previous window position
|
# Restore previous window position
|
||||||
if gajim.config.get('saveposition'):
|
if gajim.config.get('saveposition'):
|
||||||
|
@ -84,6 +86,24 @@ class MessageWindow:
|
||||||
|
|
||||||
self.window.show_all()
|
self.window.show_all()
|
||||||
|
|
||||||
|
def _on_window_focus(self, widget, event):
|
||||||
|
# FIXME:
|
||||||
|
print "_on_window_focus"
|
||||||
|
# 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)
|
||||||
|
# to remove urgency hint so this functions does that
|
||||||
|
if gtk.gtk_version >= (2, 8, 0) and gtk.pygtk_version >= (2, 8, 0):
|
||||||
|
if widget.props.urgency_hint:
|
||||||
|
widget.props.urgency_hint = False
|
||||||
|
|
||||||
|
ctl = self.get_active_control()
|
||||||
|
# Undo "unread" state display, etc.
|
||||||
|
if ctl.type_id == message_control.TYPE_GC:
|
||||||
|
self.redraw_tab(ctl.contact, 'active')
|
||||||
|
else:
|
||||||
|
# NOTE: we do not send any chatstate to preserve inactive, gone, etc.
|
||||||
|
self.redraw_tab(ctl.contact)
|
||||||
|
|
||||||
def _on_window_delete(self, win, event):
|
def _on_window_delete(self, win, event):
|
||||||
# Make sure all controls are okay with being deleted
|
# Make sure all controls are okay with being deleted
|
||||||
for ctl in self._controls.values():
|
for ctl in self._controls.values():
|
||||||
|
@ -363,6 +383,7 @@ class MessageWindow:
|
||||||
self.notebook.get_n_pages() - 1)
|
self.notebook.get_n_pages() - 1)
|
||||||
|
|
||||||
|
|
||||||
|
################################################################################
|
||||||
class MessageWindowMgr:
|
class MessageWindowMgr:
|
||||||
'''A manager and factory for MessageWindow objects'''
|
'''A manager and factory for MessageWindow objects'''
|
||||||
|
|
||||||
|
@ -452,103 +473,3 @@ class MessageWindowMgr:
|
||||||
for c in w.controls():
|
for c in w.controls():
|
||||||
yield c
|
yield c
|
||||||
|
|
||||||
class MessageControl(gtk.VBox):
|
|
||||||
'''An abstract base widget that can embed in the gtk.Notebook of a MessageWindow'''
|
|
||||||
|
|
||||||
def __init__(self, type_id, parent_win, widget_name, display_name, contact, account):
|
|
||||||
gtk.VBox.__init__(self)
|
|
||||||
|
|
||||||
self.type_id = type_id
|
|
||||||
self.parent_win = parent_win
|
|
||||||
self.widget_name = widget_name
|
|
||||||
self.display_name = display_name
|
|
||||||
self.contact = contact
|
|
||||||
self.account = account
|
|
||||||
self.compact_view_always = False
|
|
||||||
self.compact_view_current = False
|
|
||||||
self.nb_unread = 0
|
|
||||||
self.print_time_timeout_id = None
|
|
||||||
|
|
||||||
self.xml = gtk.glade.XML(GTKGUI_GLADE, widget_name, APP)
|
|
||||||
self.widget = self.xml.get_widget(widget_name)
|
|
||||||
# Autoconnect glade signals
|
|
||||||
self.xml.signal_autoconnect(self)
|
|
||||||
|
|
||||||
def shutdown(self):
|
|
||||||
# NOTE: Derived classes MUST implement this
|
|
||||||
assert(False)
|
|
||||||
def draw_widgets(self):
|
|
||||||
pass # NOTE: Derived classes SHOULD implement this
|
|
||||||
def repaint_themed_widgets(self, theme):
|
|
||||||
pass # NOTE: Derived classes SHOULD implement this
|
|
||||||
def update_state(self):
|
|
||||||
pass # NOTE: Derived classes SHOULD implement this
|
|
||||||
def toggle_emoticons(self):
|
|
||||||
pass # NOTE: Derived classes MAY implement this
|
|
||||||
def update_font(self):
|
|
||||||
pass # NOTE: Derived classes SHOULD implement this
|
|
||||||
def update_tags(self):
|
|
||||||
pass # NOTE: Derived classes SHOULD implement this
|
|
||||||
def print_time_timeout(self, arg):
|
|
||||||
# NOTE: Derived classes SHOULD implement this
|
|
||||||
if self.print_time_timeout_id:
|
|
||||||
gobject.source_remove(self.print_time_timeout_id)
|
|
||||||
del self.print_time_timeout_id
|
|
||||||
return False
|
|
||||||
def markup_tab_label(self, label_str, chatstate):
|
|
||||||
# NOTE: Derived classes SHOULD implement this
|
|
||||||
# Reurn a markup'd label and optional gtk.Color
|
|
||||||
return (label_str, None)
|
|
||||||
def prepare_context_menu(self):
|
|
||||||
# NOTE: Derived classes SHOULD implement this
|
|
||||||
return None
|
|
||||||
def set_compact_view(self, state):
|
|
||||||
# NOTE: Derived classes MAY implement this
|
|
||||||
self.compact_view_current = state
|
|
||||||
def check_delete(self):
|
|
||||||
'''Called when a window has been asked to delete itself. If a control is
|
|
||||||
not in a suitable shutdown state this method should return True to halt
|
|
||||||
the delete'''
|
|
||||||
# NOTE: Derived classes MAY implement this
|
|
||||||
return False
|
|
||||||
|
|
||||||
def send_message(self, message, keyID = '', type = 'chat', chatstate = None):
|
|
||||||
'''Send the given message to the active tab'''
|
|
||||||
# refresh timers
|
|
||||||
self.reset_kbd_mouse_timeout_vars()
|
|
||||||
|
|
||||||
jid = self.contact.jid
|
|
||||||
# Send and update history
|
|
||||||
gajim.connections[self.account].send_message(jid, message, keyID,
|
|
||||||
type = type, chatstate = chatstate)
|
|
||||||
|
|
||||||
def position_menu_under_button(self, menu):
|
|
||||||
#FIXME: BUG http://bugs.gnome.org/show_bug.cgi?id=316786
|
|
||||||
# pass btn instance when this bug is over
|
|
||||||
button = self.button_clicked
|
|
||||||
# here I get the coordinates of the button relative to
|
|
||||||
# window (self.window)
|
|
||||||
button_x, button_y = button.allocation.x, button.allocation.y
|
|
||||||
|
|
||||||
# now convert them to X11-relative
|
|
||||||
window_x, window_y = self.parent_win.get_origin()
|
|
||||||
x = window_x + button_x
|
|
||||||
y = window_y + button_y
|
|
||||||
|
|
||||||
menu_width, menu_height = menu.size_request()
|
|
||||||
|
|
||||||
## should we pop down or up?
|
|
||||||
if (y + button.allocation.height + menu_height
|
|
||||||
< gtk.gdk.screen_height()):
|
|
||||||
# now move the menu below the button
|
|
||||||
y += button.allocation.height
|
|
||||||
else:
|
|
||||||
# now move the menu above the button
|
|
||||||
y -= menu_height
|
|
||||||
|
|
||||||
|
|
||||||
# push_in is True so all the menuitems are always inside screen
|
|
||||||
push_in = True
|
|
||||||
return (x, y, push_in)
|
|
||||||
|
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue