Moved MessageControl into it's own file to avoid circular depency

This commit is contained in:
Travis Shirk 2006-01-02 02:12:34 +00:00
parent b239d4ff00
commit 4b59506c97
5 changed files with 166 additions and 105 deletions

View File

@ -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',

View File

@ -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,

View File

@ -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)

135
src/message_control.py Normal file
View File

@ -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)

View File

@ -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)