# -*- coding: utf-8 -*- # This file is part of emesene. # # Emesene 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; either version 2 of the License, or # (at your option) any later version. # # emesene 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. # # You should have received a copy of the GNU General Public License # along with emesene; if not, write to the Free Software # Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA import gobject import Conversation import ConversationWindow class ConversationManager(gobject.GObject): '''This class handle a collection of conversations''' __gsignals__ = { # conversation, window 'new-conversation-ui' : (gobject.SIGNAL_RUN_LAST, gobject.TYPE_NONE, (gobject.TYPE_PYOBJECT,gobject.TYPE_PYOBJECT)), # conversation, window 'close-conversation-ui' : (gobject.SIGNAL_RUN_LAST, gobject.TYPE_NONE, (gobject.TYPE_PYOBJECT,gobject.TYPE_PYOBJECT)), # send conversation, message 'send-message' : (gobject.SIGNAL_RUN_LAST, gobject.TYPE_NONE, (gobject.TYPE_PYOBJECT,gobject.TYPE_STRING)), # receive conversation, (message params) 'receive-message' : (gobject.SIGNAL_RUN_LAST, gobject.TYPE_NONE, (gobject.TYPE_PYOBJECT,gobject.TYPE_STRING,gobject.TYPE_STRING,gobject.TYPE_STRING,gobject.TYPE_STRING,gobject.TYPE_STRING)), } def __init__(self, controller): '''Contructor''' gobject.GObject.__init__(self) self.controller = controller self.theme = controller.theme self.config = controller.config #list of (ConversationWindow, Conversation) tuples self.conversations = [] self.user = '' self.signals = [] sap = self.signals.append sap(self.config.connect('change::showHeader', self.updateUI)) sap(self.config.connect('change::showToolbar', self.updateUI)) sap(self.config.connect('change::showAvatars', self.updateUI)) sap(self.config.connect('change::showAvatarMine', self.updateUI)) sap(self.config.connect('change::showAvatarOther', self.updateUI)) sap(self.config.connect('change::showStatusBar', self.updateUI)) sap(self.config.connect('change::showTabCloseButton', self.updateUI)) sap(self.config.connect('change::showSendButton', self.updateUI)) self.controller.connect('preferences-changed', self.updateUI) def handleLogin(self, user): '''handle a new user login (close conversations or reconnect them, etc.)''' if self.user == user: # same user as previous, enable all open conversations self.enableAll() else: # another user logged in, close open conversations self.user = user self.closeAll() def updateUI(self, *args): for window, conversation in self.conversations: conversation.ui.update() def getOpenConversation(self, mail, switchboard = None): '''return (ConversationWindow, conversation) for this contact, or return None if there isn't a conversation open yet''' self.removeClosedWindows() for window, conversation in self.conversations: members = conversation.getMembers() if len(members) == 1 and members[0] == mail: return (window, conversation) elif len(members) > 1 and mail in members: # groupchat, check if it's with the same contacts if switchboard and len(switchboard.members) == len(members) and \ sorted(switchboard.members.keys()) == sorted(members): return (window, conversation) return None def removeClosedWindows(self): '''remove conversations for closed windows''' for window, conversation in self.conversations[:]: if window.closed or conversation.closed or \ (window.notOpen and conversation.getStatus() == 'closed'): self.emit('close-conversation-ui', conversation, window) self.conversations.remove((window, conversation)) def openConversation(self, msnp, mail, weStarted, switchboard=None): '''opens a new conversation and a new window or tab''' # create new switchboard if needed if switchboard is None: switchboard = msnp.newSwitchboard() switchboard.invite(mail) conversation = Conversation.Conversation(self.controller, switchboard) # add a tab if we use tabs and if there is a window open already useTabs = not self.config.user['windows'] if useTabs and len(self.conversations) > 0: # open a new tab window = self.conversations[0][0] window.openTab(conversation) if weStarted: window.present() else: # open a new window window = ConversationWindow.ConversationWindow(self.controller, conversation) # Gnome does not support calling iconify() before show() (?) # so we call it before and after, other WMs may support it... if not weStarted: #window.iconify() window.show() if not weStarted: #window.iconify() conversation.setWindow(window) window.set_icon(conversation.getWindowIcon()) self.conversations.append((window, conversation)) self.emit('new-conversation-ui', conversation, window) return window, conversation def newConversation(self, msnp, mail, switchboard, weStarted): '''Open a new conversation, or open an existing window or tab if switchboard is None we create the switchboard''' window = conversation = None result = self.getOpenConversation(mail, switchboard) if result is not None: # conversation open already window, conversation = result # set new switchboard if switchboard != None: conversation.setSwitchboard(switchboard) # show the current window and tab if weStarted: if not self.config.user['windows']: window.showTab(window.tabs.page_num(conversation.ui)) window.present() else: # open new conversation with this contact window, conversation = self.openConversation(msnp, mail, weStarted, switchboard) return window, conversation def do_send_message(self, conversation, message): '''Send message to conversation''' conversation.do_send_message(message) def do_receive_message(self, conversation, mail, nick, message, format, charset): '''Receive a message from''' conversation.do_receive_message(mail, nick, message, format, charset) def closeAll(self): '''close all the conversations''' for window, conversation in self.conversations: window.hide() self.conversations = [] def disableAll(self): '''close conversations and disable text input of conversation windows''' for window, conversation in self.conversations: conversation.ui.setInputEnabled(False) conversation.switchboard.leaveChat() def enableAll(self): '''reconnect conversations and re-enable text input''' for window, conversation in self.conversations: conversation.reconnect() conversation.ui.setInputEnabled(True)